promptHidden: function (message, callback) { var d = qutil.convert(callback), value = ''; function onKeyPress(c, key) { if (key && key.ctrl && c === 'c') { process.exit(); } else if (c === '\r' || c === '\n' || c === '\u0004') { //End of input, finish up. process.stdin.removeListener('keypress', onKeyPress); tty.setRawMode(false); process.stdin.pause(); d.resolve(value); } else if (c === '\x7f' || c === '\x08') { //A backspace/delete character, remove a char //from the value. value = value.slice(0, -1); } else { value += c; } } tty.setRawMode(true); process.stdin.on('keypress', onKeyPress); process.stdin.resume(); process.stdout.write(message + ' ', 'utf8'); return d.promise; },
untar: function (fileName, callback, errback) { var flags = 'xf', dirName = path.dirname(fileName), d = qutil.convert(callback, errback), command; //If a .gz file add z to the flags. if (gzRegExp.test(fileName)) { flags = 'z' + flags; } command = 'tar -' + flags + ' ' + fileName; if (dirName) { command += ' -C ' + dirName; } exec(command, function (error, stdout, stderr) { if (error) { d.reject(error); } else { d.resolve(); } } ); return d.promise; }
prompt: function (message, callback) { var d = qutil.convert(callback); function onData(data) { data = (data || '').toString().trim(); process.stdin.pause(); d.resolve(data); } process.stdin.once('data', onData); process.stdin.resume(); process.stdout.write(message + ' ', 'utf8'); return d.promise; },
fetch: function(options, callback, errback) { var d = qutil.convert(callback, errback), v = options.v, localConfig = voloConfig.getLocal(), name; //If already have a token, wrap it up. if (localConfig[configKey]) { d.resolve(localConfig[configKey]); return d.promise; } function log(msg) { if (!options.silent) { console.log(msg); } } log('Log in to GitHub to complete action ' + '(your password is not saved. It is sent over ' + 'SSL to GitHub and converted to an OAuth token)'); v.prompt('GitHub user name:') .then(function (promptName) { name = promptName; return v.promptHidden('GitHub password:'******'\nContacting GitHub...'); var basicAuth = new Buffer(name + ':' + pw) .toString('base64'), requestBody = JSON.stringify({ scopes: authConfig.scopes, note: authConfig.note, note_url: authConfig.noteUrl }), urlParts = url.parse(authConfig.domain + authConfig.authPath), req; urlParts.method = 'POST'; req = https.request(urlParts, function (res) { var body = '', hasError; if (res.statusCode === 401) { v.prompt('Incorrect GitHub user name or password. Retry [y]?') .then(function (answer) { answer = answer && answer.toLowerCase(); if (!answer || answer.indexOf('y') === 0) { d.resolve(auth.fetch(options)); } else { d.resolve(); } }) .fail(d); return; } else if (res.statusCode !== 201) { log('GitHub responded with error status: ' + res.statusCode); d.resolve(); return; } res.setEncoding('utf8'); res.on('data', function (chunk) { body += chunk; }); res.on('error', function (err) { hasError = true; log('GitHub responded with error: ' + err.toString()); d.resolve(); }); res.on('end', function () { var config = voloConfig.getLocal(); if (!hasError) { body = JSON.parse(body); config[configKey] = { user: name, token: body.token, scopes: authConfig.scopes }; v.prompt('Save OAuth token for later use [y]?') .then(function (save) { save = save && save.toLowerCase(); if (!save || save === 'y' || save === 'yes') { var saveLocation = voloConfig.saveLocal(); if (saveLocation) { log('Token saved in ' + saveLocation); } } return config[configKey]; }) .then(d.resolve, d.reject); } }); }); req.setHeader('Authorization', 'Basic ' + basicAuth); req.setHeader('Content-Type', 'application/json; charset=UTF-8'); req.setHeader('Content-Length', requestBody.length); req.end(requestBody); }).fail(d); return d.promise; }