node-formidable / formidable

The most used, flexible, fast and streaming parser for multipart form data. Supports uploading to serverless environments, AWS S3, Azure, GCP or the filesystem. Used in production.
MIT License
7k stars 680 forks source link

Formidable V2 Filter issue #941

Closed devalp-pro closed 1 year ago

devalp-pro commented 1 year ago

Support plan

Context

What are you trying to achieve or the steps to reproduce?

When I attached a file as png or another type. The formidable filter option returns false. In this false case formidable.parse() method does not give the form error invalid file type. variable formError always return null or undefined even if filter is false.

 const allowedMimeTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];

                const formData = new formidable.IncomingForm({
                    keepExtensions: true,
                    allowEmptyFiles: false,
                    multiples: false,
                    filter(part) {
                        if (part && part.mimetype) {
                            return allowedMimeTypes.includes(part.mimetype);
                        }
                        return false;
                    },
                    uploadDir: "uploads/resume",
                    filename(name, ext, part, form) {
                        var currentTimeStamp = Math.floor(Date.now() / 1000);
                        return `resume_${currentTimeStamp}${ext}`;
                    },
                });

return new Promise((accept, reject) => {

                    formData.parse(req, (fromError, fields, files) => {
                        try {
                            if (fromError) {
                                const { resume } = files;

                                if ((resume as unknown as PersistentFile)) {
                                    const fileDetail = JSON.parse(JSON.stringify(resume));
                                    if (fileDetail) {
                                        fs.rmSync(fileDetail.filepath, { force: true });
                                    }
                                }

                                const response: ApiResponse<undefined | null> = { status: false, message: fromError, data: null };
                                return reject(res.status(500).json(response));
                            }

                            const response: ApiResponse<undefined | null> = { status: true, message: "Success", data: null };
                            return accept(res.status(200).json(response));

                        } catch (exception) {
                            const { resume } = files;
                            if ((resume as unknown as PersistentFile)) {
                                const fileDetails = JSON.parse(JSON.stringify(resume));
                                if (fileDetails.lenght > 0) {
                                    fs.rmSync(fileDetails[0].filepath, { force: true });
                                }
                            }
                            // console.error(exception);
                            const response: ApiResponse<undefined | null> = { status: false, message: `${exception}`, data: null };
                            return reject(res.status(500).json(response));
                        }

                    });
                });

What was the result you got?

formData.parse(req, (fromError, fields, files) => {})

fromError always return null or undefined even if formData filter option returns false.

What result did you expect?

fromError returns a valid file type filter error.

GrosSacASac commented 1 year ago

Behaves like Array.filter: Returning false will simply ignore the file and go to the next.

use form.emit('error') inside filter to make form.parse error (formData.emit('error') in your case)

GrosSacASac commented 1 year ago

I also recommend you to slugify ext as it is user input and may contain invalid characters

                    return `resume_${currentTimeStamp}${slugify(ext)}`;