Video: admin gets 1GB upload limit (users stay at 200MB)

- Two multer instances: uploadUser (200MB) and uploadAdmin (1GB)
- uploadMiddleware checks session role before picking handler
- Error message shows correct limit per role
This commit is contained in:
treamz 2026-03-22 12:03:12 +03:00
parent a0c8622a7d
commit 1657c5f0a0

View File

@ -10,20 +10,27 @@ const router = express.Router();
const UPLOADS_DIR = path.join(__dirname, '..', 'uploads'); const UPLOADS_DIR = path.join(__dirname, '..', 'uploads');
const DOWNLOADS_DIR = path.join(__dirname, '..', 'downloads'); const DOWNLOADS_DIR = path.join(__dirname, '..', 'downloads');
const MAX_FILE_SIZE = 200 * 1024 * 1024; // 200MB const MAX_FILE_SIZE = 200 * 1024 * 1024; // 200MB for users
const MAX_FILE_SIZE_ADMIN = 1024 * 1024 * 1024; // 1GB for admin
const upload = multer({ function videoFileFilter(req, file, cb) {
dest: UPLOADS_DIR, const valid = ['video/mp4', 'video/webm', 'video/quicktime', 'video/x-msvideo', 'video/x-matroska', 'video/mpeg', 'video/3gpp', 'video/ogg'];
limits: { fileSize: MAX_FILE_SIZE }, if (valid.includes(file.mimetype) || file.originalname.match(/\.(mp4|webm|mov|avi|mkv|mpeg|mpg|3gp|ogg|flv|wmv)$/i)) {
fileFilter: (req, file, cb) => { cb(null, true);
const valid = ['video/mp4', 'video/webm', 'video/quicktime', 'video/x-msvideo', 'video/x-matroska', 'video/mpeg', 'video/3gpp', 'video/ogg']; } else {
if (valid.includes(file.mimetype) || file.originalname.match(/\.(mp4|webm|mov|avi|mkv|mpeg|mpg|3gp|ogg|flv|wmv)$/i)) { cb(new Error('Неподдерживаемый формат видео'));
cb(null, true); }
} else { }
cb(new Error('Неподдерживаемый формат видео'));
} const uploadUser = multer({ dest: UPLOADS_DIR, limits: { fileSize: MAX_FILE_SIZE }, fileFilter: videoFileFilter });
}, const uploadAdmin = multer({ dest: UPLOADS_DIR, limits: { fileSize: MAX_FILE_SIZE_ADMIN }, fileFilter: videoFileFilter });
});
// Pick multer based on user role
function uploadMiddleware(req, res, next) {
const isAdmin = req.session && req.session.user && req.session.user.role === 'admin';
const handler = isAdmin ? uploadAdmin.single('video') : uploadUser.single('video');
handler(req, res, next);
}
const limiter = rateLimit({ windowMs: 60000, max: 10, message: { error: 'Слишком много запросов' } }); const limiter = rateLimit({ windowMs: 60000, max: 10, message: { error: 'Слишком много запросов' } });
@ -93,7 +100,7 @@ router.get('/', (req, res) => {
}); });
// Upload and get info // Upload and get info
router.post('/upload', limiter, upload.single('video'), async (req, res) => { router.post('/upload', limiter, uploadMiddleware, async (req, res) => {
if (!req.file) return res.status(400).json({ error: 'Файл не загружен' }); if (!req.file) return res.status(400).json({ error: 'Файл не загружен' });
try { try {
@ -236,7 +243,11 @@ router.get('/download/:filename', (req, res) => {
// Multer error handler // Multer error handler
router.use((err, req, res, next) => { router.use((err, req, res, next) => {
if (err instanceof multer.MulterError) { if (err instanceof multer.MulterError) {
if (err.code === 'LIMIT_FILE_SIZE') return res.status(413).json({ error: 'Файл слишком большой. Максимум 200MB.' }); if (err.code === 'LIMIT_FILE_SIZE') {
const isAdmin = req.session && req.session.user && req.session.user.role === 'admin';
const limit = isAdmin ? '1 GB' : '200 MB';
return res.status(413).json({ error: 'Файл слишком большой. Максимум ' + limit + '.' });
}
return res.status(400).json({ error: err.message }); return res.status(400).json({ error: err.message });
} }
if (err) return res.status(400).json({ error: err.message }); if (err) return res.status(400).json({ error: err.message });