mirror of
https://github.com/bitwarden/browser.git
synced 2024-10-30 08:10:34 +01:00
two-step login prompts
This commit is contained in:
parent
9ce758e859
commit
e3eea736ed
11
package-lock.json
generated
11
package-lock.json
generated
@ -19,6 +19,12 @@
|
||||
"integrity": "sha512-MFFKFv2X4iZy/NFl1m1E8uwE1CR96SGwJjgHma09PLtqOWoj3nqeJHMG+P/EuJGVLvC2I6MdQRQsr4TcRduIow==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/readline-sync": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/readline-sync/-/readline-sync-1.4.3.tgz",
|
||||
"integrity": "sha512-YP9NVli96E+qQLAF2db+VjnAUEeZcFVg4YnMgr8kpDUFwQBnj31rPLOVHmazbKQhaIkJ9cMHsZhpKdzUeL0KTg==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
|
||||
@ -3186,6 +3192,11 @@
|
||||
"set-immediate-shim": "1.0.1"
|
||||
}
|
||||
},
|
||||
"readline-sync": {
|
||||
"version": "1.4.9",
|
||||
"resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz",
|
||||
"integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No="
|
||||
},
|
||||
"regex-not": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
||||
|
@ -35,6 +35,7 @@
|
||||
"devDependencies": {
|
||||
"@types/commander": "^2.12.2",
|
||||
"@types/node": "^10.0.8",
|
||||
"@types/readline-sync": "^1.4.3",
|
||||
"clean-webpack-plugin": "^0.1.17",
|
||||
"copy-webpack-plugin": "^4.2.0",
|
||||
"cross-env": "^5.1.4",
|
||||
@ -49,6 +50,7 @@
|
||||
"commander": "2.15.1",
|
||||
"node-fetch": "2.1.2",
|
||||
"node-forge": "0.7.1",
|
||||
"node-localstorage": "1.3.1"
|
||||
"node-localstorage": "1.3.1",
|
||||
"readline-sync": "1.4.9"
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import * as program from 'commander';
|
||||
import * as readline from 'readline-sync';
|
||||
|
||||
import { AuthResult } from 'jslib/models/domain/authResult';
|
||||
|
||||
@ -10,9 +11,57 @@ export class LoginCommand {
|
||||
constructor(private authService: AuthService) { }
|
||||
|
||||
async run(email: string, password: string, cmd: program.Command) {
|
||||
if (email == null || email === '') {
|
||||
email = readline.question('Email Address: ');
|
||||
}
|
||||
if (email == null || email.trim() === '') {
|
||||
return Response.badRequest('Email address is required.');
|
||||
}
|
||||
if (email.indexOf('@') === -1) {
|
||||
return Response.badRequest('Email address is invalid.');
|
||||
}
|
||||
|
||||
if (password == null || password === '') {
|
||||
password = readline.question('Master Password: ', {
|
||||
hideEchoBack: true,
|
||||
mask: '*',
|
||||
});
|
||||
}
|
||||
if (password == null || password === '') {
|
||||
return Response.badRequest('Master password is required.');
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await this.authService.logIn(email, password);
|
||||
// TODO: 2FA
|
||||
const response = await this.authService.logIn(email, password);
|
||||
if (response.twoFactor) {
|
||||
let selectedProvider: any = null;
|
||||
const twoFactorProviders = this.authService.getSupportedTwoFactorProviders(null);
|
||||
if (twoFactorProviders.length === 0) {
|
||||
return Response.badRequest('No providers available for this client.');
|
||||
}
|
||||
|
||||
if (twoFactorProviders.length === 1) {
|
||||
selectedProvider = twoFactorProviders[0];
|
||||
} else {
|
||||
const options = twoFactorProviders.map((p) => p.name);
|
||||
const i = readline.keyInSelect(options, 'Two-step login method: ', { cancel: 'Cancel' });
|
||||
if (i < 0) {
|
||||
return Response.error('Login failed.');
|
||||
}
|
||||
selectedProvider = twoFactorProviders[i];
|
||||
}
|
||||
|
||||
const twoFactorToken = readline.question('Two-step login token for ' + selectedProvider.name + ': ');
|
||||
if (twoFactorToken == null || twoFactorToken === '') {
|
||||
return Response.badRequest('Token is required.');
|
||||
}
|
||||
|
||||
const twoFactorResponse = await this.authService.logInTwoFactor(selectedProvider.type,
|
||||
twoFactorToken, false);
|
||||
if (twoFactorResponse.twoFactor) {
|
||||
return Response.error('Login failed.');
|
||||
}
|
||||
}
|
||||
return Response.success();
|
||||
} catch (e) {
|
||||
return Response.error(e);
|
||||
|
@ -46,6 +46,20 @@ export class Program {
|
||||
// TODO
|
||||
});
|
||||
|
||||
program
|
||||
.command('lock')
|
||||
.description('Lock the vault and destroy the current session token.')
|
||||
.action((cmd) => {
|
||||
// TODO
|
||||
});
|
||||
|
||||
program
|
||||
.command('unlock <password>')
|
||||
.description('Unlock the vault and obtain a new session token.')
|
||||
.action((cmd) => {
|
||||
// TODO
|
||||
});
|
||||
|
||||
program
|
||||
.command('sync')
|
||||
.description('Sync user\'s vault from server.')
|
||||
@ -117,7 +131,12 @@ export class Program {
|
||||
}
|
||||
|
||||
private processResponse(response: Response, cmd: program.Command) {
|
||||
if (response.success) {
|
||||
if (!response.success) {
|
||||
process.stdout.write(chalk.redBright(response.message));
|
||||
process.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.data != null) {
|
||||
if (response.data.object === 'string') {
|
||||
process.stdout.write((response.data as StringResponse).data);
|
||||
@ -130,10 +149,6 @@ export class Program {
|
||||
}
|
||||
}
|
||||
process.exit();
|
||||
} else {
|
||||
process.stdout.write(chalk.redBright(response.message));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private printJson(obj: any, cmd: program.Command) {
|
||||
|
Loading…
Reference in New Issue
Block a user