typescriptnestjs

How can I validate a file type using Nestjs Pipes and FileTypeValidator


I have implemented a simple Nestjs route inside of an controller with a file upload. The file is handled with Multer. Since its porpuse is to edit a profile picture of a user I need to validate the file to be an image. However for some reason I can't get it running with the FileTypeValidator. The uploaded file is being denied each time.

@UseInterceptors(
  FileInterceptor('file', {
    storage: MulterService.getStorage((req, file, cb) => {
      const filename = `${uuidv4()}`;
      const extension = path.parse(file.originalname).ext;

      cb(null, `${filename}${extension}`);
    }, MulterService.destinations.profilePictures),
  })
)
@Post('profile-picture')
editProfilePicture(
  @UploadedFile(
    new ParseFilePipe({
      validators: [new FileTypeValidator({ fileType: 'png' })],
      // png files always denied
      // /\^(jpeg|jpg|png|gif)$/ regex isn't working either
    })
  )
  file: Express.Multer.File
): Promise<User> {
  // ...
}

Solution

  • It turns out the "fileType" passed to the FileValidator is actually a mime type and not just an extension.

    Here are the matches from extension to mime types

    The good news is that, using a regex, you can match any parts of the mime type, and, usually, all image mime types begin with image/

    So if you just want to accept images, but all images, maybe the following should work

    @UploadedFile(
        new ParseFilePipe({
          validators: [
            new MaxFileSizeValidator({ maxSize: max size of file in bytes }),
            new FileTypeValidator({ fileType: /^image/ }),
          ],
        }),
      )
      file: Express.Multer.File
    

    The ^ at the start, is to make sure to match a mime type beginning with image and not just one that happens to have image elsewhere.

    Let me know if it works.