|
|
|
|
@ -24,6 +24,7 @@ import {
@@ -24,6 +24,7 @@ import {
|
|
|
|
|
PasswordLogInCredentials, |
|
|
|
|
SsoLogInCredentials, |
|
|
|
|
} from "jslib-common/models/domain/logInCredentials"; |
|
|
|
|
import { TokenRequestTwoFactor } from "jslib-common/models/request/identityToken/tokenRequest"; |
|
|
|
|
import { TwoFactorEmailRequest } from "jslib-common/models/request/twoFactorEmailRequest"; |
|
|
|
|
import { UpdateTempPasswordRequest } from "jslib-common/models/request/updateTempPasswordRequest"; |
|
|
|
|
import { ErrorResponse } from "jslib-common/models/response/errorResponse"; |
|
|
|
|
@ -69,6 +70,8 @@ export class LoginCommand {
@@ -69,6 +70,8 @@ export class LoginCommand {
|
|
|
|
|
let clientId: string = null; |
|
|
|
|
let clientSecret: string = null; |
|
|
|
|
|
|
|
|
|
let selectedProvider: any = null; |
|
|
|
|
|
|
|
|
|
if (options.apikey != null) { |
|
|
|
|
const apiIdentifiers = await this.apiIdentifiers(); |
|
|
|
|
clientId = apiIdentifiers.clientId; |
|
|
|
|
@ -177,39 +180,17 @@ export class LoginCommand {
@@ -177,39 +180,17 @@ export class LoginCommand {
|
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
if (response.captchaSiteKey) { |
|
|
|
|
const badCaptcha = Response.badRequest( |
|
|
|
|
"Your authentication request appears to be coming from a bot\n" + |
|
|
|
|
"Please use your API key to validate this request and ensure BW_CLIENTSECRET is correct, if set.\n" + |
|
|
|
|
"(https://bitwarden.com/help/cli-auth-challenges)" |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
const captchaClientSecret = await this.apiClientSecret(true); |
|
|
|
|
if (Utils.isNullOrWhitespace(captchaClientSecret)) { |
|
|
|
|
return badCaptcha; |
|
|
|
|
} |
|
|
|
|
const credentials = new PasswordLogInCredentials(email, password); |
|
|
|
|
const handledResponse = await this.handleCaptchaRequired(twoFactor, credentials); |
|
|
|
|
|
|
|
|
|
const secondResponse = await this.authService.logIn( |
|
|
|
|
new PasswordLogInCredentials(email, password, captchaClientSecret, { |
|
|
|
|
provider: twoFactorMethod, |
|
|
|
|
token: twoFactorToken, |
|
|
|
|
remember: false, |
|
|
|
|
}) |
|
|
|
|
); |
|
|
|
|
response = secondResponse; |
|
|
|
|
} catch (e) { |
|
|
|
|
if ( |
|
|
|
|
(e instanceof ErrorResponse || e.constructor.name === "ErrorResponse") && |
|
|
|
|
(e as ErrorResponse).message.includes("Captcha is invalid") |
|
|
|
|
) { |
|
|
|
|
return badCaptcha; |
|
|
|
|
} else { |
|
|
|
|
throw e; |
|
|
|
|
} |
|
|
|
|
// Error Response
|
|
|
|
|
if (handledResponse instanceof Response) { |
|
|
|
|
return handledResponse; |
|
|
|
|
} else { |
|
|
|
|
response = handledResponse; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (response.requiresTwoFactor) { |
|
|
|
|
let selectedProvider: any = null; |
|
|
|
|
const twoFactorProviders = this.twoFactorService.getSupportedProviders(null); |
|
|
|
|
if (twoFactorProviders.length === 0) { |
|
|
|
|
return Response.badRequest("No providers available for this client."); |
|
|
|
|
@ -276,11 +257,30 @@ export class LoginCommand {
@@ -276,11 +257,30 @@ export class LoginCommand {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
response = await this.authService.logInTwoFactor({ |
|
|
|
|
response = await this.authService.logInTwoFactor( |
|
|
|
|
{ |
|
|
|
|
provider: selectedProvider.type, |
|
|
|
|
token: twoFactorToken, |
|
|
|
|
remember: false, |
|
|
|
|
}, |
|
|
|
|
null |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (response.captchaSiteKey) { |
|
|
|
|
const twoFactorRequest: TokenRequestTwoFactor = { |
|
|
|
|
provider: selectedProvider.type, |
|
|
|
|
token: twoFactorToken, |
|
|
|
|
remember: false, |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
const handledResponse = await this.handleCaptchaRequired(twoFactorRequest); |
|
|
|
|
|
|
|
|
|
// Error Response
|
|
|
|
|
if (handledResponse instanceof Response) { |
|
|
|
|
return handledResponse; |
|
|
|
|
} else { |
|
|
|
|
response = handledResponse; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (response.requiresTwoFactor) { |
|
|
|
|
@ -435,6 +435,48 @@ export class LoginCommand {
@@ -435,6 +435,48 @@ export class LoginCommand {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private async handleCaptchaRequired( |
|
|
|
|
twoFactorRequest: TokenRequestTwoFactor, |
|
|
|
|
credentials: PasswordLogInCredentials = null |
|
|
|
|
): Promise<AuthResult | Response> { |
|
|
|
|
const badCaptcha = Response.badRequest( |
|
|
|
|
"Your authentication request has been flagged and will require user interaction to proceed.\n" + |
|
|
|
|
"Please use your API key to validate this request and ensure BW_CLIENTSECRET is correct, if set.\n" + |
|
|
|
|
"(https://bitwarden.com/help/cli-auth-challenges)" |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
const captchaClientSecret = await this.apiClientSecret(true); |
|
|
|
|
if (Utils.isNullOrWhitespace(captchaClientSecret)) { |
|
|
|
|
return badCaptcha; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let authResultResponse: AuthResult = null; |
|
|
|
|
if (credentials != null) { |
|
|
|
|
credentials.captchaToken = captchaClientSecret; |
|
|
|
|
credentials.twoFactor = twoFactorRequest; |
|
|
|
|
authResultResponse = await this.authService.logIn(credentials); |
|
|
|
|
} else { |
|
|
|
|
authResultResponse = await this.authService.logInTwoFactor( |
|
|
|
|
twoFactorRequest, |
|
|
|
|
captchaClientSecret |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return authResultResponse; |
|
|
|
|
} catch (e) { |
|
|
|
|
if ( |
|
|
|
|
e instanceof ErrorResponse || |
|
|
|
|
(e.constructor.name === "ErrorResponse" && |
|
|
|
|
(e as ErrorResponse).message.includes("Captcha is invalid")) |
|
|
|
|
) { |
|
|
|
|
return badCaptcha; |
|
|
|
|
} else { |
|
|
|
|
return Response.error(e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private getPasswordStrengthUserInput() { |
|
|
|
|
let userInput: string[] = []; |
|
|
|
|
const atPosition = this.email.indexOf("@"); |
|
|
|
|
|