implented multer to offer endpoints for upload and retrieval of images
This commit is contained in:
parent
31540d4d4b
commit
24f1ca4350
|
|
@ -0,0 +1,80 @@
|
|||
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) => {
|
||||
let userPath = req.body.path || '';
|
||||
|
||||
userPath = path.normalize(userPath).replace(/^(\.\.[\/\\])+/, '');
|
||||
|
||||
const targetPath = path.join(uploadDir, userPath);
|
||||
|
||||
if (!targetPath.startsWith(uploadDir)) {
|
||||
return cb(new Error('Invalid path.'));
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
|
@ -15,7 +15,7 @@ import {
|
|||
sendOkResponse,
|
||||
sendResponseNoContent,
|
||||
} from '../utils/responses.js'
|
||||
import { latitudeRange, longitudeRange, uuid, varChar } from '../validators/expressValidator/customValidators.js'
|
||||
import { json, latitudeRange, longitudeRange, uuid, varChar } from '../validators/expressValidator/customValidators.js'
|
||||
import { integerRange } from '../validators/expressValidator/customValidators.js'
|
||||
import {payloadExpressValidator} from '../validators/expressValidator/payloadExpressValidator.js'
|
||||
import { authorizePermission, setToken, authenticateToken, refreshAuthenticate} from '../middlewares/auth.js'
|
||||
|
|
@ -86,8 +86,8 @@ export default(config) => {
|
|||
(req, res, next) => indexController(req, res, next),
|
||||
(result, req, res, next) => addLinks(result, req, res, next, hasAddLinks, linkRoutes),
|
||||
(result, req, res, _) => sendOkResponse(result, req, res)
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
// User Routes
|
||||
/**
|
||||
* @name get/users
|
||||
|
|
@ -974,7 +974,8 @@ export default(config) => {
|
|||
varChar('address').optional({ nullable: true, values: 'falsy' }),
|
||||
varChar('description').optional({ nullable: true, values: 'falsy' }),
|
||||
latitudeRange('latitude'),
|
||||
longitudeRange('longitude')
|
||||
longitudeRange('longitude'),
|
||||
json('images').optional({ nullable: true, values: 'falsy' }),
|
||||
],
|
||||
(req, res, next) => payloadExpressValidator(req, res, next, config),
|
||||
(req, res, next) => insertPlaceController(req, res, next, config),
|
||||
|
|
@ -1012,7 +1013,8 @@ export default(config) => {
|
|||
varChar('address').optional({ nullable: true, values: 'falsy' }),
|
||||
varChar('description').optional({ nullable: true, values: 'falsy' }),
|
||||
latitudeRange('latitude').optional({ nullable: false, values: 'falsy' }),
|
||||
longitudeRange('longitude').optional({nullable: false, values: 'falsy'})
|
||||
longitudeRange('longitude').optional({nullable: false, values: 'falsy'}),
|
||||
json('images').optional({ nullable: true, values: 'falsy' }),
|
||||
],
|
||||
(req, res, next) => payloadExpressValidator(req, res, next, config),
|
||||
(req, res, next) => modifyPlaceController(req, res, next, config),
|
||||
|
|
@ -1221,6 +1223,7 @@ export default(config) => {
|
|||
uuid('user_uuid'),
|
||||
uuid('report_type_uuid').optional({ nullable: false, values: 'falsy' }),
|
||||
integerRange('rating', {min: 1, max: 3}),
|
||||
json('images').optional({ nullable: true, values: 'falsy' }),
|
||||
varChar('description').optional({ nullable: true, values: 'falsy' }),
|
||||
],
|
||||
(req, res, next) => payloadExpressValidator(req, res, next, config),
|
||||
|
|
@ -1258,6 +1261,7 @@ export default(config) => {
|
|||
uuid('user_uuid').optional({ nullable: false, values: 'falsy' }),
|
||||
uuid('report_type_uuid').optional({ nullable: false, values: 'falsy' }),
|
||||
integerRange('rating', {min: 1, max: 3}).optional({ nullable: false, values: 'falsy' }),
|
||||
json('images').optional({ nullable: true, values: 'falsy' }),
|
||||
varChar('description').optional({ nullable: true, values: 'falsy' }),
|
||||
],
|
||||
(req, res, next) => payloadExpressValidator(req, res, next, config),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
import { uploadMiddleware } from '../middlewares/upload.js'; // tu middleware multer
|
||||
import { Router } from 'express'
|
||||
|
||||
export default(config) => {
|
||||
/**
|
||||
* Express router to mount user related functions on.
|
||||
* @type {Object}
|
||||
* @const
|
||||
* @namespace placeRouter
|
||||
*/
|
||||
const router = Router()
|
||||
const hasAddLinks = config.environment !== 'production'
|
||||
|
||||
// Single file upload route
|
||||
router.post(
|
||||
'/upload',
|
||||
uploadMiddleware('file'),
|
||||
(result, req, res, next) => addLinks(result, req, res, next, hasAddLinks, linkRoutes),
|
||||
(result, req, res, _) => sendOkResponse(result, req, res));
|
||||
|
||||
// Multiple file upload route
|
||||
router.post(
|
||||
'/upload-multiple',
|
||||
uploadMiddleware('file', true),
|
||||
(result, req, res, next) => addLinks(result, req, res, next, hasAddLinks, linkRoutes),
|
||||
(result, req, res, _) => sendOkResponse(result, req, res)
|
||||
)
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue