Logo

dev-resources.site

for different kinds of informations.

How to validate uploaded files in Node JS

Published at
3/26/2022
Categories
node
javascript
webdev
multer
Author
thesameeric
Categories
4 categories in total
node
open
javascript
open
webdev
open
multer
open
Author
11 person written this
thesameeric
open
How to validate uploaded files in Node JS

In this note, we'll look at how we can handle file validation and compression in Node JS.
If you have a better way of handling validation or compression, please drop it in the comment section.
In most cases, files are parsed in a Node JS server using either Multer, busboy, or Formidable.
While the content used in this writeup uses Multer, it can easily apply to any system.

File validation
Files in Node JS are usually in JSON format. The format for files is one of the two shown below.

// If memory storage is used
{
  fieldname: 'image',
  originalname: 'image.png',
  encoding: '7bit',
  mimetype: 'image/png',
  buffer: <Buffer bytes>,
  size: 25471
}

// If the file is stored locally
{
  fieldname: 'image',
  originalname: 'Meta1.png',
  encoding: '7bit',
  mimetype: 'image/png',
  destination: 'uploads/',
  filename: 'ed84692635f46d86c4be044f4acca667',
  path: 'uploads/ed84692635f46d86c4be044f4acca667',
  size: 25471
}
Enter fullscreen mode Exit fullscreen mode

The fields we will use for validation are originalname, mimetype, and size fields.

Checking the file extension.

We will use a bitwise right shift operator coupled with some inbuilt JS functions to get the file extension.

const file_extension = image.originalname.slice(
    ((image.originalname.lastIndexOf('.') - 1) >>> 0) + 2
);
Enter fullscreen mode Exit fullscreen mode

The above method has proven to work for 98% of cases, including misspelt filenames, i.e. image.png.png, photo.jpeg.jeg.

Since we now have the file extension, we can check to see if it's valid.

// Array of allowed files
const array_of_allowed_files = ['png', 'jpeg', 'jpg', 'gif'];

// Get the extension of the uploaded file
const file_extension = image.originalname.slice(
    ((image.originalname.lastIndexOf('.') - 1) >>> 0) + 2
);

// Check if the uploaded file is allowed
if (!array_of_allowed_files.includes(file_extension)) {
  throw Error('Invalid file');
}
Enter fullscreen mode Exit fullscreen mode

Checking only the file extension is not practical since anyone can edit a file name and change the extension, i.e. I can easily change a file name from todo-list.docx to todo-list.png.

For this reason, we will also need to check the mimetype of the file to ensure it's an image. We will follow a similar approach in doing this.

const array_of_allowed_file_types = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];
if (!array_of_allowed_file_types.includes(image.memetype)) {
  throw Error('Invalid file');
}
Enter fullscreen mode Exit fullscreen mode

combining the two checks, we'll have;

// Array of allowed files
const array_of_allowed_files = ['png', 'jpeg', 'jpg', 'gif'];
const array_of_allowed_file_types = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];

// Get the extension of the uploaded file
const file_extension = image.originalname.slice(
    ((image.originalname.lastIndexOf('.') - 1) >>> 0) + 2
);

// Check if the uploaded file is allowed
if (!array_of_allowed_files.includes(file_extension) || !array_of_allowed_file_types.includes(image.memetype)) {
  throw Error('Invalid file');
}
Enter fullscreen mode Exit fullscreen mode

Checking file size

To check the file size, we use the size field. The size is usually given in bytes, so we have to convert it to the desired format for our evaluation. In our case, we converted it to MB.

// Allowed file size in mb
const allowed_file_size = 2;
if ((image.size / (1024 * 1024)) > allowed_file_size) {                  
  throw Error('File too large');
}
Enter fullscreen mode Exit fullscreen mode

Putting the above validations together, a typical middleware in express to validate uploaded files will look like the code below

export const auth = (req, res, next) => {
    const image = req.file;
    // Array of allowed files
    const array_of_allowed_files = ['png', 'jpeg', 'jpg', 'gif'];
    const array_of_allowed_file_types = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];
    // Allowed file size in mb
    const allowed_file_size = 2;
    // Get the extension of the uploaded file
    const file_extension = image.originalname.slice(
        ((image.originalname.lastIndexOf('.') - 1) >>> 0) + 2
    );

    // Check if the uploaded file is allowed
    if (!array_of_allowed_files.includes(file_extension) || !array_of_allowed_file_types.includes(image.memetype)) {
        throw Error('Invalid file');
    }

    if ((image.size / (1024 * 1024)) > allowed_file_size) {                  
       throw Error('File too large');
    }
    return next();
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

File validation is very important. Although this writeup made use of images, and a single file upload, it can easily be modified to work for other file types. Adding it inside a loop, it can validate an array of files as well.
The codes has been bundled up into an NPM package that can easily be integrated. follow the link to find it. Fileguard.

multer Article's
30 articles in total
Favicon
Mastering Image Uploads in Node.js: A Beginner-to-Advanced Guide with Multer and Cloudinary
Favicon
Mastering Image Uploads with Multer, Firebase, and Express in Node.js
Favicon
File-Type Validation in Multer is NOT SAFE🙃
Favicon
Simplify File Uploads with @fluidjs/multer-cloudinary in Express.js
Favicon
How to Upload an Excel File in Node.js Using Express and Multer
Favicon
How to Upload a File in nodejs: A step by step guide
Favicon
Understanding the File Upload Middleware with Cloudinary in Node.js
Favicon
OPTICAL CHARACTER RECOGNITION USING NODE JS AND TESSERACT OCR ENGINE
Favicon
Upload image files with Multer
Favicon
Upload File to S3 Using NestJS Application
Favicon
The easiest way of uploading image and audio files together using Multer, Cloudinary, and Node.js.
Favicon
Uploading and Managing Images with Node.js, Multer, and Cloudinary: A Comprehensive Guide
Favicon
Unexpected end of form when sending form data with Postman- Multer
Favicon
How do i use multer's upload.array(fieldname[, maxCount]) for a nested object inside a mongoose subdocument
Favicon
The file melting Multer with NodeJS and Express
Favicon
Error: Multipart: Boundary not found
Favicon
How to validate uploaded files in Node JS
Favicon
Single and multiple images upload and remove from Cloudinary using Node JS, Multer, MongoDB
Favicon
How To Upload Files With Multer Node.js and Express
Favicon
Nodejs Express RestAPI – Upload/Import CSV File to MySQL – using Fast-CSV & Multer
Favicon
Nodejs Express RestAPI – Upload/Import Excel file/data to MongoDB – using Convert-Excel-to-Json + Multer
Favicon
Nodejs Express RestAPI – Upload/Import Excel File to MySQL – using Read-Excel-File & Multer
Favicon
Node JS Resize Image Upload Using Multer Sharp With Example
Favicon
Nodejs Express RestAPI – Upload/Import CSV file/data to MongoDB – using CsvToJson + Multer
Favicon
NodeJS/Express – Upload/Download MultiparFile to MySQL – Multer + Sequelize + JQuery Ajax + Bootstrap
Favicon
NodeJS/Express – RestAPI to Upload Multipart File to MySQL using Multer + Sequelize ORM
Favicon
NodeJS/Express – Upload/Download MultiparFile to MySQL – Multer + Sequelize + JQuery Ajax + Bootstrap
Favicon
Implementing Multer Storage Engine in TypeScript
Favicon
How To Upload Multiple files to Cloudinary in Nodejs using Promise.all
Favicon
Multer - Build RestAPI to upload a MultipartFile to NodeJS/Express

Featured ones: