Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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> {
  // ...
}
like image 786
Behemoth Avatar asked Oct 26 '25 05:10

Behemoth


2 Answers

If this/\.(jpg|jpeg|png)$/ will not work use this'.(png|jpeg|jpg)'

@UploadedFile(
    new ParseFilePipe({
      validators: [
        new MaxFileSizeValidator({ maxSize: max size of file in bytes }),
        new FileTypeValidator({ fileType: '.(png|jpeg|jpg)' }),
      ],
    }),
  )
  file: Express.Multer.File
like image 65
Piyush Kacha Avatar answered Oct 28 '25 19:10

Piyush Kacha


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.

like image 45
Triup Lauro Avatar answered Oct 28 '25 20:10

Triup Lauro