import multer from "multer"; import crypto from "crypto"; import path from "path"; import fs from "fs"; import response from "../../response.js"; const memoryStorage = multer.memoryStorage(); const fileFilter = (req, file, cb) => { const ext = path.extname(file.originalname).toLowerCase(); if (ext === ".png" || ext === ".jpg" || ext === ".jpeg") { cb(null, true); } else { cb( new Error( "Invalid file type, only .png, .jpg, and .jpeg files are allowed!" ), false ); } }; const upload = multer({ storage: memoryStorage, fileFilter, limits: { fileSize: 5 * 1024 * 1024 }, }).fields([{ name: "PICTURE", maxCount: 1 }]); const handleUpload = (req, res, next) => { upload(req, res, (err) => { if (err) { return response(400, null, err.message, res); } const files = req.files; const PICTURE = files?.PICTURE ? files.PICTURE[0] : null; try { let validFiles = true; let errorMessages = []; if (PICTURE && PICTURE.size > 5 * 1024 * 1024) { validFiles = false; PICTURE.buffer = null; errorMessages.push("Picture file exceeds the size limit of 5MB"); } if (validFiles) { req.filesToSave = { PICTURE }; next(); } else { clearFileBuffers({ PICTURE }); return response(400, null, errorMessages.join(", "), res); } } catch (error) { console.log(error); clearFileBuffers(file); return response(500, null, "Internal Server Error", res); } }); }; export const clearFileBuffers = (files) => { for (const file of Object.values(files)) { if (file && file.buffer) { file.buffer = null; } } }; export const saveFileToDisk = (file, userId, userName) => { const ext = path.extname(file.originalname); const hash = crypto .createHash("md5") .update( userId + userName + file.originalname + file.buffer.length.toString() ) .digest("hex"); const filename = `user-${hash}${ext}`; const folderPath = path.join("public/uploads/avatar"); if (!fs.existsSync(folderPath)) { fs.mkdirSync(folderPath, { recursive: true }); } const filepath = path.join(folderPath, filename); fs.writeFileSync(filepath, file.buffer); return filename; }; export default handleUpload;