1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 16:53:34 +00:00

two-step login prompts

This commit is contained in:
Kyle Spearrin
2018-05-15 14:21:42 -04:00
parent 9ce758e859
commit e3eea736ed
4 changed files with 94 additions and 17 deletions

View File

@@ -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);

View File

@@ -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,23 +131,24 @@ export class Program {
}
private processResponse(response: Response, cmd: program.Command) {
if (response.success) {
if (response.data != null) {
if (response.data.object === 'string') {
process.stdout.write((response.data as StringResponse).data);
} else if (response.data.object === 'list') {
this.printJson((response.data as ListResponse).data, cmd);
} else if (response.data.object === 'template') {
this.printJson((response.data as TemplateResponse).template, cmd);
} else {
this.printJson(response.data, cmd);
}
}
process.exit();
} else {
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);
} else if (response.data.object === 'list') {
this.printJson((response.data as ListResponse).data, cmd);
} else if (response.data.object === 'template') {
this.printJson((response.data as TemplateResponse).template, cmd);
} else {
this.printJson(response.data, cmd);
}
}
process.exit();
}
private printJson(obj: any, cmd: program.Command) {