fixed #6
This commit is contained in:
parent
8d9aca03f8
commit
eeb0770459
4 changed files with 46 additions and 14 deletions
|
@ -40,7 +40,7 @@ line = readlineSync.prompt([options])
|
||||||
```
|
```
|
||||||
|
|
||||||
Readies readline for input from the user, putting the current `setPrompt` options on a new line, giving the user a new spot to write.
|
Readies readline for input from the user, putting the current `setPrompt` options on a new line, giving the user a new spot to write.
|
||||||
If `{noEchoBack: true}` is specified to `options`, echo back is avoided. It is used to hide the password which is typed by user on screen. *See [Note](#note) for security.*
|
If `{noEchoBack: true}` is specified to `options`, echo back is avoided. It is used to hide the password which is typed by user on screen.
|
||||||
|
|
||||||
### question
|
### question
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ line = readlineSync.question([query[, options]])
|
||||||
|
|
||||||
Displays the `query` to the user, and then returns the user's response after it has been typed.
|
Displays the `query` to the user, and then returns the user's response after it has been typed.
|
||||||
`query` is converted to string (i.e. `toString` method is called) before it is displayed every time.
|
`query` is converted to string (i.e. `toString` method is called) before it is displayed every time.
|
||||||
If `{noEchoBack: true}` is specified to `options`, echo back is avoided. It is used to hide the password which is typed by user on screen. *See [Note](#note) for security.*
|
If `{noEchoBack: true}` is specified to `options`, echo back is avoided. It is used to hide the password which is typed by user on screen.
|
||||||
|
|
||||||
### setEncoding
|
### setEncoding
|
||||||
|
|
||||||
|
@ -104,9 +104,8 @@ try {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
+ If `options.noEchoBack` is used, the text that input by user is saved to temporary file (e.g. `/tmp/readline-sync.stdout`). This file is removed immediately after reading is done, but you have to be careful about it because this text is *plain*. Removing the file might fail, or the file might be peeped before it is removed.
|
|
||||||
|
|
||||||
## Release History
|
## Release History
|
||||||
|
* 2014-07-13 v0.4.3 fixed #6: Crypto input data.
|
||||||
* 2014-07-12 v0.4.2 `setPrompt()` and `setEncoding()` return current value.
|
* 2014-07-12 v0.4.2 `setPrompt()` and `setEncoding()` return current value.
|
||||||
* 2014-07-12 v0.4.1 `setPrompt()` and `question()` accept the value which is not string too (e.g. number, Date, Object, etc.).
|
* 2014-07-12 v0.4.1 `setPrompt()` and `question()` accept the value which is not string too (e.g. number, Date, Object, etc.).
|
||||||
* 2014-07-12 v0.4.0 Add `options.noEchoBack`.
|
* 2014-07-12 v0.4.0 Add `options.noEchoBack`.
|
||||||
|
|
16
lib/encrypt.js
Normal file
16
lib/encrypt.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
var algorithmCipher = 'aes-256-cbc',
|
||||||
|
cipher = require('crypto').createCipher(algorithmCipher, process.argv[2]),
|
||||||
|
stdin = process.stdin,
|
||||||
|
stdout = process.stdout,
|
||||||
|
crypted = '';
|
||||||
|
|
||||||
|
stdin.resume();
|
||||||
|
stdin.setEncoding('utf8');
|
||||||
|
stdin.on('data', function(d) {
|
||||||
|
crypted += cipher.update(d, 'utf8', 'hex');
|
||||||
|
});
|
||||||
|
stdin.on('end', function() {
|
||||||
|
stdout.write(crypted + cipher.final('hex'), 'binary', function() {
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
});
|
|
@ -8,14 +8,18 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var promptText = '> ',
|
var
|
||||||
encoding = 'utf8',
|
|
||||||
BUF_SIZE = 256,
|
BUF_SIZE = 256,
|
||||||
|
ALGORITHM_CIPHER = 'aes-256-cbc',
|
||||||
|
ALGORITHM_HASH = 'sha256',
|
||||||
|
|
||||||
|
promptText = '> ',
|
||||||
|
encoding = 'utf8',
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
stdin = process.stdin,
|
stdin = process.stdin,
|
||||||
stdout = process.stdout,
|
stdout = process.stdout,
|
||||||
buffer = new Buffer(BUF_SIZE),
|
buffer = new Buffer(BUF_SIZE),
|
||||||
useShell = true, print, tempdir;
|
useShell = true, print, tempdir, salt = 0;
|
||||||
|
|
||||||
function _readlineSync(display, options) {
|
function _readlineSync(display, options) {
|
||||||
var input = '', rsize, err;
|
var input = '', rsize, err;
|
||||||
|
@ -78,18 +82,29 @@ function _readlineShell(noEchoBack) {
|
||||||
pathStdout = getTempfile('readline-sync.stdout'),
|
pathStdout = getTempfile('readline-sync.stdout'),
|
||||||
pathStatus = getTempfile('readline-sync.status'),
|
pathStatus = getTempfile('readline-sync.status'),
|
||||||
pathDone = getTempfile('readline-sync.done'),
|
pathDone = getTempfile('readline-sync.done'),
|
||||||
optEchoBack = noEchoBack ? ' noechoback' : '';
|
optEchoBack = noEchoBack ? ' noechoback' : '',
|
||||||
|
crypto = require('crypto'), shasum, decipher, password;
|
||||||
|
|
||||||
|
shasum = crypto.createHash(ALGORITHM_HASH);
|
||||||
|
shasum.update('' + process.pid + (salt++) + Math.random());
|
||||||
|
password = shasum.digest('hex');
|
||||||
|
decipher = crypto.createDecipher(ALGORITHM_CIPHER, password);
|
||||||
|
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
// The quote (") is escaped by node before parsed by shell. Then use ENV{Q}.
|
// The quote (") is escaped by node before parsed by shell. Then use ENV{Q}.
|
||||||
shellPath = 'cmd.exe';
|
shellPath = 'cmd.exe';
|
||||||
args = ['/V:ON', '/S', '/C',
|
args = ['/V:ON', '/S', '/C',
|
||||||
'%Q%' + __dirname + '\\read.bat%Q%' + optEchoBack + ' >%Q%' + pathStdout +
|
'%Q%' + __dirname + '\\read.bat%Q%' + optEchoBack +
|
||||||
'%Q% & (echo !ERRORLEVEL!)>%Q%' + pathStatus + '%Q% & (echo 1)>%Q%' + pathDone + '%Q%'];
|
' |%Q%' + process.execPath + '%Q% %Q%' + __dirname + '\\encrypt.js%Q% %Q%' + password + '%Q%' +
|
||||||
|
' >%Q%' + pathStdout + '%Q%' +
|
||||||
|
' & (echo !ERRORLEVEL!)>%Q%' + pathStatus + '%Q% & (echo 1)>%Q%' + pathDone + '%Q%'];
|
||||||
} else {
|
} else {
|
||||||
shellPath = '/bin/sh';
|
shellPath = '/bin/sh';
|
||||||
args = ['-c', '(' + shellPath + ' "' + __dirname + '/read.sh"' + optEchoBack + ') >"' + pathStdout +
|
args = ['-c',
|
||||||
'"; echo $? >"' + pathStatus + '"; echo 1 >"' + pathDone + '"'];
|
'(' + shellPath + ' "' + __dirname + '/read.sh"' + optEchoBack + ')' +
|
||||||
|
' |"' + process.execPath + '" "' + __dirname + '/encrypt.js" "' + password + '"' +
|
||||||
|
' >"' + pathStdout + '";' +
|
||||||
|
' echo $? >"' + pathStatus + '"; echo 1 >"' + pathDone + '"'];
|
||||||
}
|
}
|
||||||
|
|
||||||
stdin.pause(); // re-start in child process
|
stdin.pause(); // re-start in child process
|
||||||
|
@ -99,7 +114,9 @@ function _readlineShell(noEchoBack) {
|
||||||
if (fs.readFileSync(pathDone, {encoding: encoding}).trim() === '1') { break; }
|
if (fs.readFileSync(pathDone, {encoding: encoding}).trim() === '1') { break; }
|
||||||
}
|
}
|
||||||
if (fs.readFileSync(pathStatus, {encoding: encoding}).trim() === '0') {
|
if (fs.readFileSync(pathStatus, {encoding: encoding}).trim() === '0') {
|
||||||
shellStdout = fs.readFileSync(pathStdout, {encoding: encoding});
|
shellStdout =
|
||||||
|
decipher.update(fs.readFileSync(pathStdout, {encoding: 'binary'}), 'hex', encoding) +
|
||||||
|
decipher.final(encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.unlinkSync(pathStdout);
|
fs.unlinkSync(pathStdout);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "readline-sync",
|
"name": "readline-sync",
|
||||||
"description": "Synchronous Readline",
|
"description": "Synchronous Readline",
|
||||||
"version": "0.4.2",
|
"version": "0.4.3",
|
||||||
"homepage": "https://github.com/anseki/readline-sync",
|
"homepage": "https://github.com/anseki/readline-sync",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "anseki"
|
"name": "anseki"
|
||||||
|
|
Loading…
Reference in a new issue