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.
This commit is contained in:
@@ -5,18 +5,28 @@ const fileService = require('./fileService');
|
||||
const { successResponse } = require('../../utils/apiResponse');
|
||||
const AppError = require('../../utils/AppError');
|
||||
|
||||
const pickUploadedFile = (req) => {
|
||||
if (req.file) return req.file;
|
||||
if (Array.isArray(req.files) && req.files.length) return req.files[0];
|
||||
if (req.files && typeof req.files === 'object') {
|
||||
return req.files.file?.[0]
|
||||
|| req.files['filepond-image']?.[0]
|
||||
|| Object.values(req.files).flat().find(Boolean)
|
||||
|| null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
exports.uploadTemp = catchAsync(async (req, res, next) => {
|
||||
if (!req.file) {
|
||||
const uploaded = pickUploadedFile(req);
|
||||
if (!uploaded) {
|
||||
return next(new AppError('FILE_REQUIRED'));
|
||||
}
|
||||
|
||||
const result = await fileService.uploadTempFile(
|
||||
req.file.buffer,
|
||||
req.file.originalname,
|
||||
req.file.mimetype
|
||||
);
|
||||
const result = await fileService.uploadTempFile(uploaded);
|
||||
|
||||
return successResponse(res, 201, 'File uploaded to temp bucket successfully', result);
|
||||
// 200 matches the working FilePond Node.js uploader (2xx is required)
|
||||
return successResponse(res, 200, 'File uploaded to temp bucket successfully', result);
|
||||
});
|
||||
|
||||
exports.getSignedUrl = catchAsync(async (req, res, next) => {
|
||||
@@ -27,6 +37,20 @@ exports.getSignedUrl = catchAsync(async (req, res, next) => {
|
||||
return successResponse(res, 200, 'Temporary presigned URL generated successfully', result);
|
||||
});
|
||||
|
||||
exports.streamFile = catchAsync(async (req, res, next) => {
|
||||
const key = req.query.key || req.params.filename;
|
||||
const bucket = req.query.bucket;
|
||||
|
||||
if (!key) {
|
||||
return next(new AppError('VALIDATION_FAILED', null, 'Filename is required'));
|
||||
}
|
||||
|
||||
const { buffer, contentType } = await fileService.getFileContent(key, bucket);
|
||||
res.set('Content-Type', contentType);
|
||||
res.set('Cache-Control', 'private, max-age=60');
|
||||
return res.status(200).send(buffer);
|
||||
});
|
||||
|
||||
exports.deleteFile = catchAsync(async (req, res, next) => {
|
||||
const { filename } = req.params;
|
||||
const { bucket } = req.query;
|
||||
|
||||
Reference in New Issue
Block a user