mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-01-18 10:46:34 +00:00
Merge pull request #242 from resin-io/jviotti/feature/us-pw-login
Implement user/password login with 2FA support
This commit is contained in:
commit
ec72f93480
@ -1,52 +1,65 @@
|
||||
(function() {
|
||||
var Promise, _, events, form, open, resin, url, validEmail, visuals;
|
||||
var Promise, _, events, form, helpers, resin, visuals;
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
open = Promise.promisify(require('open'));
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
url = require('url');
|
||||
|
||||
resin = require('resin-sdk');
|
||||
|
||||
form = require('resin-cli-form');
|
||||
|
||||
visuals = require('resin-cli-visuals');
|
||||
|
||||
validEmail = require('valid-email');
|
||||
|
||||
events = require('resin-cli-events');
|
||||
|
||||
helpers = require('../utils/helpers');
|
||||
|
||||
exports.login = {
|
||||
signature: 'login [token]',
|
||||
signature: 'login',
|
||||
description: 'login to resin.io',
|
||||
help: 'Use this command to login to your resin.io account.\n\nTo login, you need your token, which is accesible from the preferences page.\n\nExamples:\n\n $ resin login\n $ resin login "eyJ0eXAiOiJKV1Qi..."',
|
||||
help: 'Use this command to login to your resin.io account.\n\nExamples:\n\n $ resin login',
|
||||
options: [
|
||||
{
|
||||
signature: 'email',
|
||||
parameter: 'email',
|
||||
description: 'email',
|
||||
alias: ['e', 'u']
|
||||
}, {
|
||||
signature: 'password',
|
||||
parameter: 'password',
|
||||
description: 'password',
|
||||
alias: 'p'
|
||||
}
|
||||
],
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
return resin.settings.get('dashboardUrl').then(function(dashboardUrl) {
|
||||
return url.resolve(dashboardUrl, '/preferences');
|
||||
}).then(function(preferencesUrl) {
|
||||
if (params.token != null) {
|
||||
return params.token;
|
||||
return form.run([
|
||||
{
|
||||
message: 'Email:',
|
||||
name: 'email',
|
||||
type: 'input',
|
||||
validate: helpers.validateEmail
|
||||
}, {
|
||||
message: 'Password:',
|
||||
name: 'password',
|
||||
type: 'password'
|
||||
}
|
||||
], {
|
||||
override: options
|
||||
}).then(resin.auth.login).then(resin.auth.twoFactor.isPassed).then(function(isTwoFactorAuthPassed) {
|
||||
if (isTwoFactorAuthPassed) {
|
||||
return;
|
||||
}
|
||||
console.info("To login to the Resin CLI, you need your unique token, which is accesible from\nthe preferences page at " + preferencesUrl + "\n\nAttempting to open a browser at that location...");
|
||||
return open(preferencesUrl)["catch"](function() {
|
||||
return console.error("Unable to open a web browser in the current environment.\nPlease visit " + preferencesUrl + " manually.");
|
||||
}).then(function() {
|
||||
return form.ask({
|
||||
message: 'What\'s your token? (visible in the preferences page)',
|
||||
message: 'Two factor auth challenge:',
|
||||
name: 'code',
|
||||
type: 'input'
|
||||
}).then(resin.auth.twoFactor.challenge)["catch"](function() {
|
||||
return resin.auth.logout().then(function() {
|
||||
throw new Error('Invalid two factor authentication code');
|
||||
});
|
||||
});
|
||||
}).then(resin.auth.loginWithToken).then(function(token) {
|
||||
return resin.auth.isLoggedIn().then(function(isLoggedIn) {
|
||||
if (isLoggedIn) {
|
||||
return token;
|
||||
}
|
||||
throw new Error('Authentication failed');
|
||||
});
|
||||
}).then(resin.auth.whoami).tap(function(username) {
|
||||
console.info("Successfully logged in as: " + username);
|
||||
return events.send('user.login');
|
||||
@ -76,12 +89,7 @@
|
||||
message: 'Email:',
|
||||
name: 'email',
|
||||
type: 'input',
|
||||
validate: function(input) {
|
||||
if (!validEmail(input)) {
|
||||
return 'Email is not valid';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
validate: helpers.validateEmail
|
||||
}, {
|
||||
message: 'Username:',
|
||||
name: 'username',
|
||||
|
@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var Promise, _, capitano, chalk, child_process, os;
|
||||
var Promise, _, capitano, chalk, child_process, os, validEmail;
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
@ -15,12 +15,21 @@
|
||||
|
||||
chalk = require('chalk');
|
||||
|
||||
validEmail = require('valid-email');
|
||||
|
||||
exports.getGroupDefaults = function(group) {
|
||||
return _.chain(group).get('options').map(function(question) {
|
||||
return [question.name, question["default"]];
|
||||
}).object().value();
|
||||
};
|
||||
|
||||
exports.validateEmail = function(input) {
|
||||
if (!validEmail(input)) {
|
||||
return 'Email is not valid';
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.getOperatingSystem = function() {
|
||||
var platform;
|
||||
platform = os.platform();
|
||||
|
@ -1,55 +1,60 @@
|
||||
Promise = require('bluebird')
|
||||
open = Promise.promisify(require('open'))
|
||||
_ = require('lodash')
|
||||
url = require('url')
|
||||
resin = require('resin-sdk')
|
||||
form = require('resin-cli-form')
|
||||
visuals = require('resin-cli-visuals')
|
||||
validEmail = require('valid-email')
|
||||
events = require('resin-cli-events')
|
||||
helpers = require('../utils/helpers')
|
||||
|
||||
exports.login =
|
||||
signature: 'login [token]'
|
||||
signature: 'login'
|
||||
description: 'login to resin.io'
|
||||
help: '''
|
||||
Use this command to login to your resin.io account.
|
||||
|
||||
To login, you need your token, which is accesible from the preferences page.
|
||||
|
||||
Examples:
|
||||
|
||||
$ resin login
|
||||
$ resin login "eyJ0eXAiOiJKV1Qi..."
|
||||
'''
|
||||
options: [
|
||||
{
|
||||
signature: 'email'
|
||||
parameter: 'email'
|
||||
description: 'email'
|
||||
alias: [ 'e', 'u' ]
|
||||
}
|
||||
{
|
||||
signature: 'password'
|
||||
parameter: 'password'
|
||||
description: 'password'
|
||||
alias: 'p'
|
||||
}
|
||||
]
|
||||
primary: true
|
||||
action: (params, options, done) ->
|
||||
resin.settings.get('dashboardUrl').then (dashboardUrl) ->
|
||||
return url.resolve(dashboardUrl, '/preferences')
|
||||
.then (preferencesUrl) ->
|
||||
return params.token if params.token?
|
||||
|
||||
console.info """
|
||||
To login to the Resin CLI, you need your unique token, which is accesible from
|
||||
the preferences page at #{preferencesUrl}
|
||||
|
||||
Attempting to open a browser at that location...
|
||||
"""
|
||||
|
||||
open(preferencesUrl).catch ->
|
||||
console.error """
|
||||
Unable to open a web browser in the current environment.
|
||||
Please visit #{preferencesUrl} manually.
|
||||
"""
|
||||
.then ->
|
||||
form.ask
|
||||
message: 'What\'s your token? (visible in the preferences page)'
|
||||
form.run [
|
||||
message: 'Email:'
|
||||
name: 'email'
|
||||
type: 'input'
|
||||
|
||||
.then(resin.auth.loginWithToken)
|
||||
.then (token) ->
|
||||
resin.auth.isLoggedIn().then (isLoggedIn) ->
|
||||
return token if isLoggedIn
|
||||
throw new Error('Authentication failed')
|
||||
validate: helpers.validateEmail
|
||||
,
|
||||
message: 'Password:'
|
||||
name: 'password'
|
||||
type: 'password'
|
||||
],
|
||||
override: options
|
||||
.then(resin.auth.login)
|
||||
.then(resin.auth.twoFactor.isPassed)
|
||||
.then (isTwoFactorAuthPassed) ->
|
||||
return if isTwoFactorAuthPassed
|
||||
return form.ask
|
||||
message: 'Two factor auth challenge:'
|
||||
name: 'code'
|
||||
type: 'input'
|
||||
.then(resin.auth.twoFactor.challenge)
|
||||
.catch ->
|
||||
resin.auth.logout().then ->
|
||||
throw new Error('Invalid two factor authentication code')
|
||||
.then(resin.auth.whoami)
|
||||
.tap (username) ->
|
||||
console.info("Successfully logged in as: #{username}")
|
||||
@ -95,11 +100,7 @@ exports.signup =
|
||||
message: 'Email:'
|
||||
name: 'email'
|
||||
type: 'input'
|
||||
validate: (input) ->
|
||||
if not validEmail(input)
|
||||
return 'Email is not valid'
|
||||
|
||||
return true
|
||||
validate: helpers.validateEmail
|
||||
,
|
||||
message: 'Username:'
|
||||
name: 'username'
|
||||
|
@ -5,6 +5,7 @@ _.str = require('underscore.string')
|
||||
child_process = require('child_process')
|
||||
os = require('os')
|
||||
chalk = require('chalk')
|
||||
validEmail = require('valid-email')
|
||||
|
||||
exports.getGroupDefaults = (group) ->
|
||||
return _.chain(group)
|
||||
@ -14,6 +15,12 @@ exports.getGroupDefaults = (group) ->
|
||||
.object()
|
||||
.value()
|
||||
|
||||
exports.validateEmail = (input) ->
|
||||
if not validEmail(input)
|
||||
return 'Email is not valid'
|
||||
|
||||
return true
|
||||
|
||||
exports.getOperatingSystem = ->
|
||||
platform = os.platform()
|
||||
platform = 'osx' if platform is 'darwin'
|
||||
|
@ -48,7 +48,6 @@
|
||||
"mkdirp": "~0.5.0",
|
||||
"nplugm": "^3.0.0",
|
||||
"npm": "^2.13.0",
|
||||
"open": "0.0.5",
|
||||
"resin-cli-errors": "^1.0.0",
|
||||
"resin-cli-events": "^1.0.2",
|
||||
"resin-cli-form": "^1.3.0",
|
||||
@ -58,7 +57,7 @@
|
||||
"resin-image": "^1.1.4",
|
||||
"resin-image-manager": "^3.2.2",
|
||||
"resin-pine": "^1.3.0",
|
||||
"resin-sdk": "^3.0.0",
|
||||
"resin-sdk": "^4.0.0",
|
||||
"resin-settings-client": "^3.1.0",
|
||||
"resin-vcs": "^2.0.0",
|
||||
"rimraf": "^2.4.3",
|
||||
|
Loading…
Reference in New Issue
Block a user