Wednesday, September 12, 2018

How 'chmod' Works In Node.js

Everyone experienced with a Linux environment should be familiar with the chmod command. Whether you're an administrator setting permissions for your users or a developer creating files through your Node.js server, this simple command will help you protect your restricted files from any unauthorized user.

In this blog post, I hope to cover the difference between chmod and fchmod and how they can be used in Node.js to work with your server.


chmod vs fchmod

To use these commands in Node.js, you must access them through the File System module's API.

The chmod and fchmod functions ran on a Node.js server are actually calls to the Linux versions by the same names. In standard Node.js fashion, the chmod commands are executed asynchronously and therefore require a callback function to be used as a parameter. Apart from the callback, the other two parameters of the functions remain the same.

The two commands follow a similar syntax. The only differences being chmod using a path to a file while fchmod using a file descriptor.


// chmod.js
// fs.chmod(path,mode,callback)
// path <string, Buffer, or URL>
// mode <integer>
// callback <Function> => err <Error>

const fs = require('fs');
fs.chmod('private.txt', 0o740, (err) => {
if (err) throw err;
  console.log('[chmod] Success');
});


// fchmod.js
// fs.fchmod(fd,mode,callback)
// fd <integer>
// mode <integer>
// callback <Function> => err <Error>

const fs = require('fs');
fs.open('private.txt', 'r', (err, fd) => {
  if (err) throw err;
  fs.fchmod(fd, 0o740, (err) => {
    if (err) throw err;
    console.log('[fchmod] Success');
  });
});


Note

If you use fs.open to create a file, you can also set the permissions inline by using the optional mode parameter. For example:

fs.open('newfile.txt', 'a', 0o740, (err, fd) => {...});


Promises

With the introduction of Promises into Node.js, v10.0.0 provided us with a Promise version of using the chmod command asynchronously.

// chmodPromises.js
// fsPromises.chmod(path,mode)
// path <string, Buffer, or URL>
// mode <integer>

const fs = require('fs');
const fsPromises = fs.promises;
fsPromises.chmod('private.txt', 0o740)
  .then(() => console.log('[chmod Promises] Success'));


Synchronization

Since both functions run asynchronously, you may run into a bit of trouble if you need them to run synchronously. Node.js provides a synchronous alternative to both functions. To run chmod and fchmod synchronously, you can use the fs.chmodSync and fs.fchmodSync commands respectively. These commands, being synchronous, do not require a callback function. Any error checking will have to be done manually.


// chmodSync.js
// fs.chmodSync(path,mode)
// path <string, Buffer, or URL>
// mode <integer>

const fs = require('fs');
fs.chmodSync('private.txt', 0o740);
console.log('[chmodSync] Success');


// fchmodSync.js
// fs.fchmodSync(fd,mode)
// fd <integer>
// mode <integer>

const fs = require('fs');
fs.open('private.txt', 'r', (err, fd) => {
  if (err) throw err;
  fs.fchmod(fd, 0o740);
  console.log('[fchmodSync] Success');
});


Note

Node.js provides a few alternatives to how to input a file mode for the chmod and fchmod commands. The file system provides you with a few constants to use in place of manually inputing octal numbers.

Constant Octal
fs.constants.S_IRUSR 0o400
fs.constants.S_IWUSR 0o200
fs.constants.S_IXUSR 0o100
fs.constants.S_IRGRP 0o40
fs.constants.S_IWGRP 0o20
fs.constants.S_IXGRP 0o10
fs.constants.S_IROTH 0o4
fs.constants.S_IWOTH 0o2
fs.constants.S_IXOTH 0o1

No comments:

Post a Comment