mirror of https://github.com/laurent22/joplin.git
CLI: Handling of password prompt
parent
92b857d83b
commit
e44975622a
|
@ -80,8 +80,8 @@ class AppGui {
|
||||||
await this.renderer_.renderRoot();
|
await this.renderer_.renderRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt(initialText = '', promptString = ':') {
|
prompt(initialText = '', promptString = ':', options = null) {
|
||||||
return this.widget('statusBar').prompt(initialText, promptString);
|
return this.widget('statusBar').prompt(initialText, promptString, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
stdoutMaxWidth() {
|
stdoutMaxWidth() {
|
||||||
|
|
|
@ -144,13 +144,15 @@ class Application extends BaseApplication {
|
||||||
message += ' (' + options.answers.join('/') + ')';
|
message += ' (' + options.answers.join('/') + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
let answer = await this.gui().prompt('', message + ' ');
|
let answer = await this.gui().prompt('', message + ' ', options);
|
||||||
|
|
||||||
if (options.type === 'boolean') {
|
if (options.type === 'boolean') {
|
||||||
if (answer === null) return false; // Pressed ESCAPE
|
if (answer === null) return false; // Pressed ESCAPE
|
||||||
if (!answer) answer = options.answers[0];
|
if (!answer) answer = options.answers[0];
|
||||||
let positiveIndex = options.booleanAnswerDefault == 'y' ? 0 : 1;
|
let positiveIndex = options.booleanAnswerDefault == 'y' ? 0 : 1;
|
||||||
return answer.toLowerCase() === options.answers[positiveIndex].toLowerCase();
|
return answer.toLowerCase() === options.answers[positiveIndex].toLowerCase();
|
||||||
|
} else {
|
||||||
|
return answer;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -275,7 +277,7 @@ class Application extends BaseApplication {
|
||||||
dummyGui() {
|
dummyGui() {
|
||||||
return {
|
return {
|
||||||
isDummy: () => { return true; },
|
isDummy: () => { return true; },
|
||||||
prompt: (initialText = '', promptString = '') => { return cliUtils.prompt(initialText, promptString); },
|
prompt: (initialText = '', promptString = '', options = null) => { return cliUtils.prompt(initialText, promptString, options); },
|
||||||
showConsole: () => {},
|
showConsole: () => {},
|
||||||
maximizeConsole: () => {},
|
maximizeConsole: () => {},
|
||||||
stdout: (text) => { console.info(text); },
|
stdout: (text) => { console.info(text); },
|
||||||
|
|
|
@ -178,38 +178,39 @@ cliUtils.promptConfirm = function(message, answers = null) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cliUtils.promptInput = function(message) {
|
|
||||||
const readline = require('readline');
|
|
||||||
|
|
||||||
const rl = readline.createInterface({
|
|
||||||
input: process.stdin,
|
|
||||||
output: process.stdout
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
rl.question(message + ' ', (answer) => {
|
|
||||||
rl.close();
|
|
||||||
resolve(answer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: initialText is there to have the same signature as statusBar.prompt() so that
|
// Note: initialText is there to have the same signature as statusBar.prompt() so that
|
||||||
// it can be a drop-in replacement, however initialText is not used (and cannot be
|
// it can be a drop-in replacement, however initialText is not used (and cannot be
|
||||||
// with readline.question?).
|
// with readline.question?).
|
||||||
cliUtils.prompt = function(initialText = '', promptString = ':') {
|
cliUtils.prompt = function(initialText = '', promptString = ':', options = null) {
|
||||||
|
if (!options) options = {};
|
||||||
|
|
||||||
const readline = require('readline');
|
const readline = require('readline');
|
||||||
|
const Writable = require('stream').Writable;
|
||||||
|
|
||||||
|
const mutableStdout = new Writable({
|
||||||
|
write: function(chunk, encoding, callback) {
|
||||||
|
if (!this.muted)
|
||||||
|
process.stdout.write(chunk, encoding);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const rl = readline.createInterface({
|
const rl = readline.createInterface({
|
||||||
input: process.stdin,
|
input: process.stdin,
|
||||||
output: process.stdout
|
output: mutableStdout,
|
||||||
|
terminal: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
mutableStdout.muted = false;
|
||||||
|
|
||||||
rl.question(promptString, (answer) => {
|
rl.question(promptString, (answer) => {
|
||||||
rl.close();
|
rl.close();
|
||||||
|
if (!!options.secure) this.stdout_('');
|
||||||
resolve(answer);
|
resolve(answer);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mutableStdout.muted = !!options.secure;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
const { BaseCommand } = require('./base-command.js');
|
||||||
|
const { app } = require('./app.js');
|
||||||
|
const { _ } = require('lib/locale.js');
|
||||||
|
const { Folder } = require('lib/models/folder.js');
|
||||||
|
const { importEnex } = require('lib/import-enex');
|
||||||
|
const { filename, basename } = require('lib/path-utils.js');
|
||||||
|
const { cliUtils } = require('./cli-utils.js');
|
||||||
|
|
||||||
|
class Command extends BaseCommand {
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
return 'encrypt-config <command>';
|
||||||
|
}
|
||||||
|
|
||||||
|
description() {
|
||||||
|
return _('Manages encryption configuration.');
|
||||||
|
}
|
||||||
|
|
||||||
|
async action(args) {
|
||||||
|
// init
|
||||||
|
// change-password
|
||||||
|
|
||||||
|
if (args.command === 'init') {
|
||||||
|
const password = await this.prompt(_('Enter master password:'), { type: 'string', secure: true });
|
||||||
|
this.logger().info(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Command;
|
|
@ -41,6 +41,7 @@ class StatusBarWidget extends BaseWidget {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ('cursorPosition' in options) this.promptState_.cursorPosition = options.cursorPosition;
|
if ('cursorPosition' in options) this.promptState_.cursorPosition = options.cursorPosition;
|
||||||
|
if ('secure' in options) this.promptState_.secure = options.secure;
|
||||||
|
|
||||||
this.promptState_.promise = new Promise((resolve, reject) => {
|
this.promptState_.promise = new Promise((resolve, reject) => {
|
||||||
this.promptState_.resolve = resolve;
|
this.promptState_.resolve = resolve;
|
||||||
|
@ -111,6 +112,7 @@ class StatusBarWidget extends BaseWidget {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ('cursorPosition' in this.promptState_) options.cursorPosition = this.promptState_.cursorPosition;
|
if ('cursorPosition' in this.promptState_) options.cursorPosition = this.promptState_.cursorPosition;
|
||||||
|
if (this.promptState_.secure) options.echoChar = true;
|
||||||
|
|
||||||
this.inputEventEmitter_ = this.term.inputField(options, (error, input) => {
|
this.inputEventEmitter_ = this.term.inputField(options, (error, input) => {
|
||||||
let resolveResult = null;
|
let resolveResult = null;
|
||||||
|
|
Loading…
Reference in New Issue