Merge branch 'staging' into dev

This commit is contained in:
Maxime Lalo 2023-05-11 22:51:16 +02:00
commit b44f5f5a64
6 changed files with 61 additions and 42 deletions

View File

@ -42,5 +42,5 @@ COPY --from=builder --chown=lecoffreuser leCoffre/src/common/databases ./src/com
USER lecoffreuser USER lecoffreuser
CMD ["npm", "run", "api:start"] CMD ["npm", "run", "start"]
EXPOSE 3001 EXPOSE 3001

View File

@ -42,19 +42,28 @@ export default class FilesController extends ApiController {
/** /**
* @description Get a specific File by uid * @description Get a specific File by uid
*/ */
@Get("/api/v1/super-admin/files/upload/:uid") @Get("/api/v1/super-admin/files/download/:uid")
protected async getFileData(req: Request, response: Response) { protected async download(req: Request, response: Response) {
const uid = req.params["uid"];
if (!uid) {
this.httpBadRequest(response, "uid not found");
return;
}
try { try {
const uid = req.params["uid"]; const fileInfo = await this.filesService.download(uid);
if (!uid) {
throw new Error("No uid provided"); if (!fileInfo) {
this.httpNotFoundRequest(response);
return;
} }
const file = await this.filesService.updload(uid); const type = fileInfo.file.file_name.split(".").pop();
if (type?.toLowerCase() === "pdf") response.setHeader("Content-Type", "application/pdf");
this.httpSuccess(response, file); response.setHeader("Content-Disposition", `inline; filename=${encodeURIComponent(fileInfo.file.file_name)}`);
this.httpSuccess(response, fileInfo.buffer);
} catch (error) { } catch (error) {
this.httpBadRequest(response, error); this.httpInternalError(response);
return; return;
} }
} }
@ -66,23 +75,22 @@ export default class FilesController extends ApiController {
@Post("/api/v1/super-admin/files") @Post("/api/v1/super-admin/files")
protected async post(req: Request, response: Response) { protected async post(req: Request, response: Response) {
try { try {
//get file //get file
if(!req.file) throw new Error('No file provided') if (!req.file) throw new Error("No file provided");
//init File resource with request body values //init File resource with request body values
const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"])); const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"]));
//validate File //validate File
await validateOrReject(fileEntity, { groups: ["createFile"] }); await validateOrReject(fileEntity, { groups: ["createFile"] });
//call service to get prisma entity //call service to get prisma entity
const prismaEntityCreated = await this.filesService.create(fileEntity, req.file); const prismaEntityCreated = await this.filesService.create(fileEntity, req.file);
const document: Document = await this.documentService.getByUid(fileEntity.document!.uid!) const document: Document = await this.documentService.getByUid(fileEntity.document!.uid!);
document.document_status = "DEPOSITED"; document.document_status = "DEPOSITED";
await this.documentService.update(document.uid!, document); await this.documentService.update(document.uid!, document);
//Hydrate ressource with prisma entity //Hydrate ressource with prisma entity
const fileEntityCreated = File.hydrate<File>(prismaEntityCreated, { const fileEntityCreated = File.hydrate<File>(prismaEntityCreated, {
strategy: "excludeAll", strategy: "excludeAll",
@ -135,19 +143,24 @@ export default class FilesController extends ApiController {
try { try {
const uid = req.params["uid"]; const uid = req.params["uid"];
if (!uid) { if (!uid) {
throw new Error("No uid provided"); this.httpBadRequest(response, "No uid provided");
return;
} }
//call service to get prisma entity //call service to get prisma entity
const fileEntity: Files = await this.filesService.delete(uid); const fileEntity = await this.filesService.deleteKeyAndArchive(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//Hydrate ressource with prisma entity //Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" }); const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
//success //success
this.httpSuccess(response, file); this.httpSuccess(response, file);
} catch (error) { } catch (error) {
this.httpBadRequest(response, error); this.httpInternalError(response);
return; return;
} }
} }
@ -160,18 +173,24 @@ export default class FilesController extends ApiController {
try { try {
const uid = req.params["uid"]; const uid = req.params["uid"];
if (!uid) { if (!uid) {
throw new Error("No uid provided"); this.httpBadRequest(response, "No uid provided");
return;
} }
const fileEntity = await this.filesService.getByUid(uid); const fileEntity = await this.filesService.getByUid(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//Hydrate ressource with prisma entity //Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" }); const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
//success //success
this.httpSuccess(response, file); this.httpSuccess(response, file);
} catch (error) { } catch (error) {
this.httpBadRequest(response, error); this.httpInternalError(response);
return; return;
} }
} }

View File

@ -58,9 +58,9 @@ export default class FilesRepository extends BaseRepository {
} }
/** /**
* @description : Delete a file * @description : Delete a file key and archive
*/ */
public async delete(uid: string): Promise<Files> { public async deleteKeyAndArchive(uid: string): Promise<Files> {
return this.model.update({ return this.model.update({
where: { where: {
uid: uid, uid: uid,
@ -75,17 +75,12 @@ export default class FilesRepository extends BaseRepository {
/** /**
* @description : Find unique file * @description : Find unique file
*/ */
public async findOneByUid(uid: string): Promise<Files> { public async findOneByUid(uid: string): Promise<Files | null> {
const fileEntity = await this.model.findUnique({ const fileEntity = await this.model.findUnique({
where: { where: {
uid: uid, uid: uid,
}, },
}); });
if (!fileEntity) {
throw new Error("File not found");
}
return fileEntity; return fileEntity;
} }
} }

View File

@ -24,7 +24,7 @@ export default abstract class BaseController {
return this.httpResponse(response, HttpCodes.NOT_FOUND, responseData); return this.httpResponse(response, HttpCodes.NOT_FOUND, responseData);
} }
protected httpInternaleError(response: Response, responseData: IResponseData = "http Internal Server Error") { protected httpInternalError(response: Response, responseData: IResponseData = "http Internal Server Error") {
return this.httpResponse(response, HttpCodes.INTERNAL_ERROR, responseData); return this.httpResponse(response, HttpCodes.INTERNAL_ERROR, responseData);
} }

View File

@ -8,7 +8,10 @@ import bodyParser from "body-parser";
// import TezosLink from "@Common/databases/TezosLink"; // import TezosLink from "@Common/databases/TezosLink";
import errorHandler from "@App/middlewares/ErrorHandler"; import errorHandler from "@App/middlewares/ErrorHandler";
import { BackendVariables } from "@Common/config/variables/Variables"; import { BackendVariables } from "@Common/config/variables/Variables";
import fileHandler from "@App/middlewares/FileHandler"; //import fileHandler from "@App/middlewares/FileHandler";
import multer from "multer";
const storage = multer.memoryStorage();
(async () => { (async () => {
try { try {
@ -23,7 +26,7 @@ import fileHandler from "@App/middlewares/FileHandler";
label, label,
port: parseInt(port), port: parseInt(port),
rootUrl, rootUrl,
middlwares: [cors({ origin: "*" }), fileHandler, bodyParser.urlencoded({ extended: true }), bodyParser.json()], middlwares: [cors({ origin: "*" }), multer({storage:storage}).single('file'), bodyParser.urlencoded({ extended: true }), bodyParser.json()],
errorHandler, errorHandler,
}); });

View File

@ -39,12 +39,12 @@ export default class FilesService extends BaseService {
* @description : view a file * @description : view a file
* @throws {Error} If file cannot be deleted * @throws {Error} If file cannot be deleted
*/ */
public async updload(uid: string) { public async download(uid: string) {
const file = await this.filesRepository.findOneByUid(uid); const file = await this.filesRepository.findOneByUid(uid);
if (!file.key) throw new Error("file deleted"); if (!file?.key) return null;
const fileResult = await fetch(file.file_path); const fileResult = await fetch(file.file_path);
const fileContent = await fileResult.arrayBuffer(); const fileContent = await fileResult.arrayBuffer();
return await this.cryptoService.decrypt(Buffer.from(fileContent), file.key); return {file: file, buffer: await this.cryptoService.decrypt(Buffer.from(fileContent), file.key)};
} }
/** /**
@ -53,8 +53,9 @@ export default class FilesService extends BaseService {
*/ */
public async create(file: File, fileData: Express.Multer.File) { public async create(file: File, fileData: Express.Multer.File) {
const key = v4(); const key = v4();
fileData.mimetype;
fileData.size;
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key); const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
//const encryptedFileName = await this.cryptoService.encrypt(Buffer.from(fileData.originalname, 'utf-8'), key);
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname); const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
file.file_name = fileData.originalname; //encryptedFileName.toString('utf-8') file.file_name = fileData.originalname; //encryptedFileName.toString('utf-8')
file.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash); file.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
@ -71,18 +72,19 @@ export default class FilesService extends BaseService {
} }
/** /**
* @description : Delete a file * @description : Delete a file key and archive
* @throws {Error} If file cannot be deleted * @throws {Error} If file key cannot be deleted or archived
*/ */
public async delete(uid: string) { public async deleteKeyAndArchive(uid: string) {
try { try {
const fileToUnpin = await this.filesRepository.findOneByUid(uid); const fileToUnpin = await this.filesRepository.findOneByUid(uid);
const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length); if(!fileToUnpin) return null;
await this.ipfsService.unpinFile(fileHash); const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length);
await this.ipfsService.unpinFile(fileHash);
} catch(error) { } catch(error) {
console.error(error); console.error(error);
} }
return this.filesRepository.delete(uid); return this.filesRepository.deleteKeyAndArchive(uid);
} }
} }