import multer from 'multer'; import path from 'path'; import fs from 'fs'; // Upload directory const UPLOAD_DIR = process.env.NODE_ENV === 'production' ? '/app/uploads/messenger-files' : path.join(process.cwd(), 'uploads', 'messenger-files'); // Create directory if not exists try { if (!fs.existsSync(UPLOAD_DIR)) { fs.mkdirSync(UPLOAD_DIR, { recursive: true }); } } catch (error) { console.error('Messenger file upload directory creation failed:', error); } // File storage config const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, UPLOAD_DIR); }, filename: (req, file, cb) => { try { file.originalname = file.originalname.normalize('NFC'); const uniqueId = Date.now() + '-' + Math.round(Math.random() * 1e9); const ext = path.extname(file.originalname); cb(null, `${uniqueId}${ext}`); } catch (error) { console.error('Filename processing error:', error); cb(null, `${Date.now()}-${Math.round(Math.random() * 1e9)}_error.tmp`); } }, }); // File filter - block dangerous extensions const fileFilter = (req: any, file: Express.Multer.File, cb: multer.FileFilterCallback) => { try { file.originalname = file.originalname.normalize('NFC'); } catch (error) { // ignore normalization failure } const dangerousExtensions = ['.exe', '.bat', '.cmd', '.sh', '.ps1', '.msi']; const ext = path.extname(file.originalname).toLowerCase(); if (dangerousExtensions.includes(ext)) { cb(new Error(`Security: ${ext} files are not allowed.`)); return; } cb(null, true); }; export const uploadMessengerFile = multer({ storage, fileFilter, limits: { fileSize: 20 * 1024 * 1024, // 20MB files: 10, }, });