Created
September 25, 2020 07:22
-
-
Save zillwc/c8e05d4301e70adda7c4ea8e8dd9625e to your computer and use it in GitHub Desktop.
Module to prompt for masked input and test against predicates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const stdout = process.stdout; | |
| const stdin = process.stdin; | |
| module.exports = (specifiedPromptString = 'input', predicateFns = []) => | |
| new Promise((resolve, reject) => { | |
| const prompt = specifiedPromptString.endsWith(': ') ? '' : specifiedPromptString + ': '; | |
| const predicates = Array.isArray(predicateFns) ? predicateFns : [predicateFns]; | |
| stdout.write(prompt); | |
| stdin.setRawMode(true); | |
| stdin.resume(); | |
| stdin.setEncoding('utf-8'); | |
| let input = ''; | |
| function enter() { | |
| stdin.removeListener('data', inputHandler); | |
| stdin.setRawMode(false); | |
| stdin.pause(); | |
| // checking against specified predicates | |
| try { | |
| for (let i = 0; i < predicates.length; i++) { | |
| if (typeof predicates[i] === 'function') { | |
| predicates[i](input); | |
| } | |
| } | |
| } catch (err) { | |
| // give back user input only if in debug | |
| if (process.env.NODE_DEBUG) { | |
| err.input = input; | |
| } | |
| return reject(err); | |
| } | |
| return resolve(input); | |
| } | |
| function ctrlc() { | |
| stdin.removeListener('data', inputHandler); | |
| stdin.setRawMode(false); | |
| stdin.pause(); | |
| return reject('User exited prompt with ctrl-c'); | |
| } | |
| function newchar(c) { | |
| input += c; | |
| } | |
| function backspace() { | |
| input = input.slice(0, input.length - 1); | |
| } | |
| function inputHandler(data, key) { | |
| const c = data; | |
| switch (c) { | |
| case '\u0004': // Ctrl-d | |
| case '\r': | |
| case '\n': | |
| return enter(); | |
| case '\u0003': // Ctrl-c | |
| return ctrlc(); | |
| default: | |
| // backspace | |
| if (c.charCodeAt(0) === 8) return backspace(); | |
| else return newchar(c); | |
| } | |
| } | |
| stdin.on('data', inputHandler); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const maskedPrompt = require('./masked-prompt.js'); | |
| // make sure password is at least 8 characters in length | |
| const ensureProperLength = (input) => { | |
| if (input.length < 8) { | |
| throw new Error('Password must be at least 8 characters'); | |
| } | |
| }; | |
| // make sure password contains at least 1 upper case character | |
| const ensureCapitalLetter = (input) => { | |
| const isUpperCase = (chr) => | |
| /[A-Z]|[\u0080-\u024F]/.test(chr) && chr === chr.toUpperCase(); | |
| let counter = 0; | |
| for (c of input) { | |
| if (isUpperCase(c)) { | |
| counter++; | |
| } | |
| } | |
| if (counter === 0) { | |
| throw new Error('Password should contain at least one capital letter'); | |
| } | |
| }; | |
| const passwordRules = [ ensureProperLength, ensureCapitalLetter ]; | |
| maskedPrompt('Password', passwordRules) | |
| .then((passwd) => { | |
| console.log(`\nUser password: ${passwd}`); | |
| }) | |
| .catch(console.error); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment