const multer = require('multer'); const path = require('path'); const fs = require('fs'); const { v4: uuidv4 } = require('uuid'); // Ensure upload directories exist const ensureUploadDirs = () => { const dirs = [ 'uploads/documents', 'uploads/avatars', 'uploads/kyc', 'uploads/temp' ]; dirs.forEach(dir => { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } }); }; ensureUploadDirs(); // File filter function const fileFilter = (allowedTypes) => { return (req, file, cb) => { const fileExtension = path.extname(file.originalname).toLowerCase(); const allowedExtensions = allowedTypes.map(type => `.${type}`); if (allowedExtensions.includes(fileExtension)) { cb(null, true); } else { cb(new Error(`File type not allowed. Allowed types: ${allowedTypes.join(', ')}`), false); } }; }; // Storage configuration const createStorage = (uploadPath) => { return multer.diskStorage({ destination: (req, file, cb) => { cb(null, uploadPath); }, filename: (req, file, cb) => { const uniqueSuffix = uuidv4(); const fileExtension = path.extname(file.originalname); cb(null, `${uniqueSuffix}${fileExtension}`); } }); }; // Document upload (KYC, contracts, etc.) const documentUpload = multer({ storage: createStorage('uploads/documents'), limits: { fileSize: parseInt(process.env.MAX_FILE_SIZE) || 5 * 1024 * 1024, // 5MB files: 10 }, fileFilter: fileFilter(['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png']) }); // Avatar upload const avatarUpload = multer({ storage: createStorage('uploads/avatars'), limits: { fileSize: 2 * 1024 * 1024, // 2MB files: 1 }, fileFilter: fileFilter(['jpg', 'jpeg', 'png', 'gif']) }); // KYC document upload const kycUpload = multer({ storage: createStorage('uploads/kyc'), limits: { fileSize: parseInt(process.env.MAX_FILE_SIZE) || 5 * 1024 * 1024, // 5MB files: 5 }, fileFilter: fileFilter(['pdf', 'jpg', 'jpeg', 'png']) }); // Generic file upload const genericUpload = multer({ storage: createStorage('uploads/temp'), limits: { fileSize: parseInt(process.env.MAX_FILE_SIZE) || 5 * 1024 * 1024, // 5MB files: 5 }, fileFilter: fileFilter(['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png', 'txt', 'csv', 'xlsx']) }); // File validation middleware const validateFile = (req, res, next) => { if (!req.file && !req.files) { return res.status(400).json({ success: false, message: 'No file uploaded' }); } next(); }; // File cleanup utility const cleanupFile = (filePath) => { try { if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); console.log(`File deleted: ${filePath}`); } } catch (error) { console.error(`Error deleting file ${filePath}:`, error); } }; // File info extractor const extractFileInfo = (file) => { return { originalName: file.originalname, filename: file.filename, path: file.path, size: file.size, mimetype: file.mimetype, uploadedAt: new Date() }; }; // Multiple file info extractor const extractMultipleFileInfo = (files) => { if (Array.isArray(files)) { return files.map(extractFileInfo); } // Handle multer's field-based file object const result = {}; Object.keys(files).forEach(fieldName => { result[fieldName] = files[fieldName].map(extractFileInfo); }); return result; }; module.exports = { documentUpload, avatarUpload, kycUpload, genericUpload, validateFile, cleanupFile, extractFileInfo, extractMultipleFileInfo, ensureUploadDirs };