152 lines
3.5 KiB
JavaScript
152 lines
3.5 KiB
JavaScript
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
|
|
};
|