diff --git a/package.json b/package.json index 0c161e19..6b50b10e 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "cors": "^2.8.5", "cron": "^2.3.1", "express": "^4.18.2", + "file-type-checker": "^1.0.8", "fp-ts": "^2.16.1", "jsonwebtoken": "^9.0.0", "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.94", diff --git a/src/app/middlewares/CustomerHandler/FileHandler.ts b/src/app/middlewares/CustomerHandler/FileHandler.ts index 6c3acfc2..b511260d 100644 --- a/src/app/middlewares/CustomerHandler/FileHandler.ts +++ b/src/app/middlewares/CustomerHandler/FileHandler.ts @@ -6,18 +6,24 @@ import { NextFunction, Request, Response } from "express"; import Container from "typedi"; import { EDocumentStatus } from "@prisma/client"; import CustomersService from "@Services/super-admin/CustomersService/CustomersService"; +import fileTypeChecker from "file-type-checker"; +/** + * @description Middleware to handle security on access to files + * 1. Check if customer has access to the file + * 2. Check if file is a valid file + * 3. Check if customer can access or update the targeted document + */ export default async function fileHandler(req: Request, response: Response, next: NextFunction) { const customerId = req.body.user.customerId; const customerEmail = req.body.user.email; const uid = req.path && req.path.split("/")[5]; const file: string | undefined = req.body["q"]; + const mimetypes = ["application/pdf", "image/png", "image/jpeg", "image/webp"]; - if (req.file && req.file.mimetype !== "application/pdf" && req.file.mimetype !== "image/png" && req.file.mimetype !== "image/jpeg") { - response.status(HttpCodes.BAD_REQUEST).send("File type not supported"); - return; - } - + /** + * @description Check if customer has access to the file + */ if (uid) { const fileService = Container.get(FilesService); const file = await fileService.getByUidWithDocument(uid); @@ -25,21 +31,40 @@ export default async function fileHandler(req: Request, response: Response, next response.status(HttpCodes.NOT_FOUND).send("File not found"); return; } + if (file.document.depositor_uid != customerId) { const customerService = Container.get(CustomersService); - const customers = await customerService.get({where: {contact: { email: customerEmail}}}); + const customers = await customerService.get({ where: { contact: { email: customerEmail } } }); if (customers && !customers.find((customer) => customer.uid === file.document.depositor_uid)) { response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor"); return; } } - if (req.method === "PUT") { - if (file.document.document_status === EDocumentStatus.VALIDATED) { - response.status(HttpCodes.BAD_REQUEST).send("Cannot update a validated document"); - return; - } + + next(); + return; + } + + /** + * @description Check if file is a valid file + */ + if (req.file) { + const infos = fileTypeChecker.detectFile(req.file!.buffer); + + if (req.file.mimetype !== infos?.mimeType) { + response.status(HttpCodes.BAD_REQUEST).send(`Corrupted file, detected :${infos?.mimeType}, but extension is ${req.file?.mimetype}`); + return; + } + + if (!infos?.mimeType || mimetypes.indexOf(infos?.mimeType) === -1) { + response.status(HttpCodes.BAD_REQUEST).send("File type not supported"); + return; } } + + /** + * @description Check if customer can access or update the targeted document + */ if (file) { const fileEntity = File.hydrate(JSON.parse(file)); const documentService = Container.get(DocumentsService); @@ -50,7 +75,7 @@ export default async function fileHandler(req: Request, response: Response, next } if (documentFound.depositor_uid != customerId) { const customerService = Container.get(CustomersService); - const customers = await customerService.get({where: {contact: { email: customerEmail}}}); + const customers = await customerService.get({ where: { contact: { email: customerEmail } } }); if (customers && !customers.find((customer) => customer.uid === documentFound.depositor_uid)) { response.status(HttpCodes.UNAUTHORIZED).send("Not authorized with this depositor"); return; diff --git a/src/entries/App.ts b/src/entries/App.ts index c69734e0..a07dcc81 100644 --- a/src/entries/App.ts +++ b/src/entries/App.ts @@ -25,7 +25,7 @@ const storage = multer.memoryStorage(); middlwares: [ cors({ origin: "*" }), multer({ storage: storage, limits: { fileSize: 32000000 } }).single("file"), //32 MB maximum - bodyParser.json({ limit: "35mb"}), + bodyParser.json({ limit: "35mb" }), bodyParser.urlencoded({ extended: true, limit: "35mb", parameterLimit: 50000 }), ], errorHandler,