'Get password from input using node.js
How to get password from input using node.js? Which means you should not output password entered in console.
Solution 1:[1]
Update 2015 Dec 13: readline has replaced process.stdin and node_stdio was removed from Node 0.5.10.
var BACKSPACE = String.fromCharCode(127);
// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
    if (prompt) {
      process.stdout.write(prompt);
    }
    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');
    var password = '';
    stdin.on('data', function (ch) {
        ch = ch.toString('utf8');
        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        case BACKSPACE:
            password = password.slice(0, password.length - 1);
            process.stdout.clearLine();
            process.stdout.cursorTo(0);
            process.stdout.write(prompt);
            process.stdout.write(password.split('').map(function () {
              return '*';
            }).join(''));
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}
getPassword('Password: ', (ok, password) => { console.log([ok, password]) } );
Solution 2:[2]
You can use the read module (disclosure: written by me) for this:
In your shell:
npm install read
Then in your JS:
var read = require('read')
read({ prompt: 'Password: ', silent: true }, function(er, password) {
  console.log('Your password is: %s', password)
})
Solution 3:[3]
To do this I found this excellent Google Group post
Which contains the following snippet:
var stdin = process.openStdin()
  , stdio = process.binding("stdio")
stdio.setRawMode()
var password = ""
stdin.on("data", function (c) {
  c = c + ""
  switch (c) {
    case "\n": case "\r": case "\u0004":
      stdio.setRawMode(false)
      console.log("you entered: "+password)
      stdin.pause()
      break
    case "\u0003":
      process.exit()
      break
    default:
      password += c
      break
  }
})
Solution 4:[4]
Here is my tweaked version of nailer's from above, updated to get a callback and for node 0.8 usage:
/**
 * Get a password from stdin.
 *
 * Adapted from <http://stackoverflow.com/a/10357818/122384>.
 *
 * @param prompt {String} Optional prompt. Default 'Password: '.
 * @param callback {Function} `function (cancelled, password)` where
 *      `cancelled` is true if the user aborted (Ctrl+C).
 *
 * Limitations: Not sure if backspace is handled properly.
 */
function getPassword(prompt, callback) {
    if (callback === undefined) {
        callback = prompt;
        prompt = undefined;
    }
    if (prompt === undefined) {
        prompt = 'Password: ';
    }
    if (prompt) {
        process.stdout.write(prompt);
    }
    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');
    var password = '';
    stdin.on('data', function (ch) {
        ch = ch + "";
        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}
Solution 5:[5]
How to use read without a callback
With async/await, we can get rid of the annoying callback with the following standard pattern:
const readCb = require('read')
async function read(opts) {
  return new Promise((resolve, reject) => {
    readCb(opts, (err, line) => {
      if (err) {
        reject(err)
      } else {
        resolve(line)
      }
    })
  })
}
;(async () => {
  const password = await read({ prompt: 'Password: ', silent: true })
  console.log(password)
})()
The annoyance is that then you have to propagate async/await to the entire call stack, but it is generally the way to go, as it clearly marks what is async or not.
Tested on "read": "1.0.7", Node.js v14.17.0.
TODO how to prevent EAGAIN error if you try to use stdin again later with fs.readFileSync(0)?
Both read and https://stackoverflow.com/a/10357818/895245 cause future attempts to read from stdin with fs.readFileSync(0) to break with EAGAIN. Not sure how to fix that. Reproduction:
const fs = require('fs')
const readCb = require('read')
async function read(opts) {
  return new Promise((resolve, reject) => {
    readCb(opts, (err, line) => {
      resolve([err, line])
    })
  })
}
;(async () => {
  const [err, password] = await read({ prompt: 'Password: ', silent: true })
  console.log(password)
  console.log(fs.readFileSync(0).toString())
})()
or:
#!/usr/bin/env node
const fs = require('fs')
var BACKSPACE = String.fromCharCode(127);
// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
    if (prompt) {
      process.stdout.write(prompt);
    }
    var stdin = process.stdin;
    stdin.resume();
    stdin.setRawMode(true);
    stdin.resume();
    stdin.setEncoding('utf8');
    var password = '';
    stdin.on('data', function (ch) {
        ch = ch.toString('utf8');
        switch (ch) {
        case "\n":
        case "\r":
        case "\u0004":
            // They've finished typing their password
            process.stdout.write('\n');
            stdin.setRawMode(false);
            stdin.pause();
            callback(false, password);
            break;
        case "\u0003":
            // Ctrl-C
            callback(true);
            break;
        case BACKSPACE:
            password = password.slice(0, password.length - 1);
            process.stdout.clearLine();
            process.stdout.cursorTo(0);
            process.stdout.write(prompt);
            process.stdout.write(password.split('').map(function () {
              return '*';
            }).join(''));
            break;
        default:
            // More passsword characters
            process.stdout.write('*');
            password += ch;
            break;
        }
    });
}
async function read(opts) {
  return new Promise((resolve, reject) => {
    getPassword(opts, (err, line) => {
      resolve([err, line])
    })
  })
}
;(async () => {
  const [err, password] = await read('Password: ')
  console.log(password)
  console.log(fs.readFileSync(0).toString())
})()
Error:
fs.js:614
  handleErrorFromBinding(ctx);
  ^
Error: EAGAIN: resource temporarily unavailable, read
    at Object.readSync (fs.js:614:3)
    at tryReadSync (fs.js:383:20)
    at Object.readFileSync (fs.js:420:19)
    at /home/ciro/test/main.js:70:18
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  errno: -11,
  syscall: 'read',
  code: 'EAGAIN'
}
Asked at: https://github.com/npm/read/issues/39
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Ciro Santilli Путлер Капут å…四事 | 
| Solution 2 | xehpuk | 
| Solution 3 | Alfred | 
| Solution 4 | |
| Solution 5 | 
