Files
gameno-api/components/files/fileRoutes.js
T
kavehhn 1ef54ad414 fix: stream FilePond uploads to S3 and proxy private file previews
Disk-based multer plus an authenticated content endpoint match the working Node.js uploader and avoid browser signed-URL failures on SeaweedFS.
2026-08-15 18:46:26 +03:30

61 lines
2.1 KiB
JavaScript

// /components/files/fileRoutes.js
const fs = require('fs');
const path = require('path');
const express = require('express');
const multer = require('multer');
const fileController = require('./fileController');
const { validateGetSignedUrl } = require('./fileValidator');
const authMiddleware = require('../../middlewares/authMiddleware');
const perm = require('../../middlewares/permissionMiddleware');
const { PERMISSIONS } = require('../../constants/permissions');
const AppError = require('../../utils/AppError');
const router = express.Router();
const uploadDir = path.resolve(process.cwd(), 'uploads');
fs.mkdirSync(uploadDir, { recursive: true });
const ALLOWED_MIME = new Set([
'image/jpeg',
'image/png',
'image/webp',
'image/gif',
'application/pdf'
]);
const fileFilter = (req, file, cb) => {
if (ALLOWED_MIME.has(file.mimetype)) {
cb(null, true);
return;
}
cb(new AppError('UNSUPPORTED_FILE_TYPE'), false);
};
// Disk storage (same pattern as the working Node.js FilePond uploader), then stream to S3
const upload = multer({
dest: uploadDir,
fileFilter,
limits: { fileSize: 25 * 1024 * 1024 }
});
const uploadFilepond = upload.fields([
{ name: 'file', maxCount: 1 },
{ name: 'filepond-image', maxCount: 1 }
]);
router.use(authMiddleware);
// User Scope
router.post('/user/upload-temp', perm.requires(PERMISSIONS.FILES_UPLOAD), uploadFilepond, fileController.uploadTemp);
router.get('/user/signed-url/:filename', perm.requires(PERMISSIONS.FILES_READ), validateGetSignedUrl, fileController.getSignedUrl);
router.get('/user/content', perm.requires(PERMISSIONS.FILES_READ), fileController.streamFile);
// Admin Scope
router.post('/admin/upload-temp', perm.requires(PERMISSIONS.FILES_UPLOAD), uploadFilepond, fileController.uploadTemp);
router.get('/admin/signed-url/:filename', perm.requires(PERMISSIONS.FILES_READ), validateGetSignedUrl, fileController.getSignedUrl);
router.get('/admin/content', perm.requires(PERMISSIONS.FILES_READ), fileController.streamFile);
router.delete('/admin/delete/:filename', perm.requires(PERMISSIONS.FILES_DELETE), fileController.deleteFile);
module.exports = router;