LocationAPI/src/middlewares/upload.js

82 lines
2.2 KiB
JavaScript

import multer from 'multer';
import path from 'path';
import fs from 'fs';
import crypto from 'crypto';
import config from '../config/index.js';
const uploadDir = path.resolve(process.cwd(), config.uploadDir);
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true });
}
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const userPath = req.body?.path || ''; //optional path from request body
const normalizedUserPath = path.normalize(userPath).replace(/^(\.\.[\/\\])+/, '');
const targetPath = path.join(uploadDir, normalizedUserPath);
if (!targetPath.startsWith(uploadDir)) {
return cb(new Error('Invalid path.'));
}
// Crea el directorio si no existe
if (!fs.existsSync(targetPath)) {
fs.mkdirSync(targetPath, { recursive: true });
}
cb(null, targetPath);
},
filename: (req, file, cb) => {
const randomName = crypto.randomBytes(16).toString('hex');
const ext = path.extname(file.originalname);
cb(null, randomName + ext);
}
});
const fileFilter = (req, file, cb) => {
const allowedExtensions = /jpeg|jpg|png|gif/;
const allowedMimeTypes = /image\/jpeg|image\/jpg|image\/png|image\/gif/;
const extname = allowedExtensions.test(path.extname(file.originalname).toLowerCase());
const mimetype = allowedMimeTypes.test(file.mimetype);
if (extname && mimetype) {
cb(null, true);
} else {
cb(new multer.MulterError('LIMIT_UNEXPECTED_FILE', file.fieldname));
}
};
const multerUpload = multer({
storage,
fileFilter,
limits: { fileSize: 1024 * 1024 * 1024 } // 1GB
});
const uploadMiddleware = (fieldName, multiple = false) => (req, res, next) => {
const uploader = multiple ? multerUpload.array(fieldName) : multerUpload.single(fieldName);
uploader(req, res, (err) => {
if (err instanceof multer.MulterError) {
return res.status(400).json({ error: err.message });
} else if (err) {
return res.status(500).json({ error: 'Internal server error during file upload.' });
}
if (!multiple && !req.file) {
return res.status(400).json({ error: `No file uploaded under field "${fieldName}"` });
}
const result = req.file
next(result);
});
};
export {
fileFilter,
uploadMiddleware
};