question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using form.onPart() to validate file type/name and then form.parse to receive the file

See original GitHub issue

Should I be able to use form.onPart() along with form.parse() in order to

form.onPart(): test for valid file types and return validation message if that fails or continue on to…

form.parse(): parse the file if the validation in form.onPart() passes?

I can’t seem to find the right way to do this.

CONTROLLER:

class {
  public initializeRoutes() {
    this.router.post(
      '/file',
      this.uploadFile,
    );
  }
  formidableOptions = {
    encoding: 'utf-8',
    keepExtensions: true,
    // 3 mb for news image and attachments. override otherwise
    maxFileSize: 3 * 1024 * 1024,
  };

  uploadFile = (req: Request, res: Response) => {
    const typeValidationMessage = 'Please choose a JPEG, GIF, PDF or DOC file.';

    const form = formidable(this.formidableOptions);

    form.onPart = (part: { filename: any; mime: any }) => {
      let isValid = true;
      if (part.filename || part.mime) {
        if (part.filename) {
          isValid =
            isValid && !AttachmentValidator.isInvalidFileName(part.filename);
        }

        if (part.mime) {
          isValid =
            isValid && !AttachmentValidator.isInvalidFileType(part.mime);
        }
        if (!isValid) {
          return res.status(400).json({ message: typeValidationMessage });
        }
      }
    };

    try {
      UploadService.upload(
        req,
        // onSuccess callback
        async (fileLocation: string, originalName: string) => {
          try {
            await C3DistributionService.sendAttachment(
              fileLocation,
              originalName,
            );
          } catch (error) {
            this.logger.error(error);
            return res.status(500).json({ message: error.message });
          } finally {
            // try catch swallow in case only the delete tmp file (unlinkSync) fails
            try {
              fs.unlinkSync(fileLocation);
            } catch (error) {
              this.logger.error(error);
            }
          }
          return res.status(201).send();
        },
        // onFail callback
        () => {
          return res.status(500).json({
            message: 'unexpected error from upload service callback run',
          });
        },
      );
    } catch (error) {
      this.logger.error(error);
      return res.status(500).json({ message: error.message });
    }
  };
}

SERVICE/formidable parse wrapper:

const formidableOptions = {
  encoding: 'utf-8',
  uploadDir: UPLOAD_DIR,
  keepExtensions: true,
  // 3 mb for news image and attachments. override otherwise
  maxFileSize: 3 * 1024 * 1024,
};

const UploadService = {
  upload: (req: Request, onSuccess?: Function, onFail?: Function): void => {
    ensureTmpFilePath();

    const form = formidable(formidableOptions);

    form.parse(req, (err: any, fields: any, files: { files: File }) => {
      if (err) {
        logger.error('formidable err: %j', err);
        if (onFail) {
          onFail();
        }
      } else if (onSuccess) {
        onSuccess(files.files.path, files.files.name);
      }
    });
  },
};

_Originally posted by @droddy in https://github.com/node-formidable/formidable/issues/387#issuecomment-620767478_ EDIT: SYNTAX highlighting

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
FlorentinThcommented, May 1, 2020

@droddy multer let you do this also, you have a nice fileFilter function that let you control each file before they are uploaded. Also if you want to check more seriously the type of file users of yours are uploading I suggest using multer configured with an in memory storage, then in the callback that can be directly set in your middleware, you can verify the magic number of files thanks to a package like file-type and if they satisfy your requirements, write them to the disk simply through fs.writeFile since you have access to the buffer of the file inside multer’s callback.

@tunnckoCore integrate all of this in a nice v2 of formidable should be pretty formidable 😊

PS: I’m not promoting anything here, just give you some options to complete what you want.

2reactions
droddycommented, Apr 29, 2020

Thanks! I’ll give it a shot.

I think I’m about to try to become a contributor BTW! I think I could help improve documentation for a start.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Developers - Using form.onPart() to validate file type/name and then ...
Using form.onPart() to validate file type/name and then form.parse to receive the file ... form.onPart(): test for valid file types and return validation...
Read more >
Processing a file then uploading it : nodejs / formidable
I'm using the npm package formidable to: Check the content of a file; If the content satisfies the condition, the file upload can...
Read more >
How to Change the Allowed File Types in the File Upload ...
Enter the allowed file extensions in the File Types field. form-builder-file-upload-types-min.png. Separate each file type with a comma. Don' ...
Read more >
21.3.8 Tax Exempt/Government Entities (TEGE ... - IRS
This form is not used to request copies of Forms 990, 990-EZ, 990-PF or 990-T received in 2017 or later, only use this...
Read more >
MagicDraw UserManual.pdf - No Magic, Inc
MagicDraw configuration files location 43 ... Predefined Validation Suites 460 ... Cameo Team Server forms a base for integrating different models from ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found