From fb7335b927c252605eb08cfaf671ffd758ec8a87 Mon Sep 17 00:00:00 2001 From: Pasi Niemi Date: Fri, 8 May 2020 17:38:28 +0300 Subject: [PATCH] Enable alternative ways for settings passwords (#101) * Enable alternative ways for settings passwords: * the environment variable BW_PASSWORD * prefix the command line argument with "file:" and the password will read from the first line of that file * prefix the command line argument with "env:" and the password will be read from that environment variable * Appveyor fixes * Switch to using command options for password file and password env * Lowercase options --- src/cli/commands/login.command.ts | 23 ++++++++++++++++------- src/misc/nodeUtils.ts | 13 +++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/cli/commands/login.command.ts b/src/cli/commands/login.command.ts index f08c0fa6c0..f900c0e0b1 100644 --- a/src/cli/commands/login.command.ts +++ b/src/cli/commands/login.command.ts @@ -14,6 +14,8 @@ import { Response } from '../models/response'; import { MessageResponse } from '../models/response/messageResponse'; +import { NodeUtils } from '../../misc/nodeUtils'; + export class LoginCommand { protected validatedParams: () => Promise; protected success: () => Promise; @@ -38,14 +40,21 @@ export class LoginCommand { return Response.badRequest('Email address is invalid.'); } - if ((password == null || password === '') && canInteract) { - const answer: inquirer.Answers = await inquirer.createPromptModule({ output: process.stderr })({ - type: 'password', - name: 'password', - message: 'Master password:', - }); - password = answer.password; + if (password == null || password === '') { + if (cmd.passwordfile) { + password = await NodeUtils.readFirstLine(cmd.passwordfile); + } else if (cmd.passwordenv && process.env[cmd.passwordenv]) { + password = process.env[cmd.passwordenv]; + } else if (canInteract) { + const answer: inquirer.Answers = await inquirer.createPromptModule({ output: process.stderr })({ + type: 'password', + name: 'password', + message: 'Master password:', + }); + password = answer.password; + } } + if (password == null || password === '') { return Response.badRequest('Master password is required.'); } diff --git a/src/misc/nodeUtils.ts b/src/misc/nodeUtils.ts index ee12c74459..f5e216c43f 100644 --- a/src/misc/nodeUtils.ts +++ b/src/misc/nodeUtils.ts @@ -1,5 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; +import * as readline from 'readline'; export class NodeUtils { static mkdirpSync(targetDir: string, mode = '700', relative = false, relativeDir: string = null) { @@ -13,4 +14,16 @@ export class NodeUtils { return dir; }, initialDir); } + static readFirstLine(fileName: string) { + return new Promise((resolve, reject) => { + const readStream = fs.createReadStream(fileName, {encoding: 'utf8'}); + const readInterface = readline.createInterface(readStream); + readInterface + .on('line', (line) => { + readStream.close(); + resolve(line); + }) + .on('error', (err) => reject(err)); + }); + } }