Gaurav Kumar
Gaurav Kumar

Reputation: 57

Node.js/Express: Validating multipart/form-data with Joi before Multer S3 upload

I'm having an issue with the order of middleware in my Express route for file uploads to AWS S3. I need to validate the request body (specifically a folderPath parameter) before uploading files, but the validation is failing when placed before the file upload middleware.

userRouter.js

userRoutes.post("/upload-images-test", 
    validateJwtToken,
    validateRequest(userValidators.uploadFileSchema), // Fails here with "folderPath is required"
    fileUploadMiddleware.uploadImages,
    (req, res) => {
        // Handle response
    }
);

requestValidator.js

export const validateRequest = (schema, property = 'body') => {
    return (req, res, next) => {
        const { error, value } = schema.validate(req[property]);
        if (error) {
            return res.status(400).json({ error: error.details[0].message });
        }
        req[property] = value;
        next();
    };
};

fileUpoad.js

const s3Storage = multerS3({
    s3: s3Client,
    bucket: process.env.AWS_BUCKET_NAME,
    key: (req, file, cb) => {
        const userId = req.user.id;
        const folderPath = req.body.folderPath || "/";
        const uploadPath = `users/${userId}${folderPath}`;
        cb(null, `${uploadPath}${Date.now()}-${file.originalname}`);
    },
    // ... other configurations
});

const uploadImagesMulter = multer({
    storage: s3Storage,
    fileFilter: filter(["image/"]),
    limits: { fileSize: fileSizeLimit, files: maxFiles }
}).array("images", maxFiles);

export const uploadImages = (req, res, next) => {
    console.warn(`UserID: ${req.user.id}`);
    console.warn(`Req body: ${JSON.stringify(req.body)}`);
    uploadImagesMulter(req, res, (err) => {
        console.warn(`Inside uploadImagesMulter`);
        if (err) {
            // log req headers
            console.warn(`Req headers: ${JSON.stringify(req.headers)}`);
            console.error(err);
            return res.status(400).json({ error: err.message });
        }
        if (!req.files || req.files.length === 0) {
            return res.status(400).json({ error: "At least one image is required" });
        }
        if (req.files.length > maxFiles) {
            return res.status(400).json({ error: `Only ${maxFiles} images are allowed` });
        }
        next();
    });
}

The issue:

  1. When I put validateRequest before fileUploadMiddleware.uploadImages, I get "folderPath is required" error even though I'm sending the field in the form data
  2. If I put validateRequest after fileUploadMiddleware.uploadImages, it works fine, but I want to validate the request before uploading files to S3 to save bandwidth and storage.

Question: How can I properly validate the multipart/form-data fields with Joi before processing the file upload with Multer S3? I specifically need to validate the folderPath parameter before allowing any files to be uploaded to AWS S3.

Upvotes: 1

Views: 47

Answers (0)

Related Questions