mirror of
https://github.com/bitwarden/browser
synced 2026-01-06 10:33:57 +00:00
[Captcha] Failed login attempts (#698)
* [Captcha] Failed login attempts * Fix logIn.strategy test * Updated with the stark majority of requested changes * Fix typo * Unused import
This commit is contained in:
@@ -13,7 +13,10 @@ export abstract class AuthService {
|
||||
logIn: (
|
||||
credentials: ApiLogInCredentials | PasswordLogInCredentials | SsoLogInCredentials
|
||||
) => Promise<AuthResult>;
|
||||
logInTwoFactor: (twoFactor: TokenRequestTwoFactor) => Promise<AuthResult>;
|
||||
logInTwoFactor: (
|
||||
twoFactor: TokenRequestTwoFactor,
|
||||
captchaResponse: string
|
||||
) => Promise<AuthResult>;
|
||||
logOut: (callback: () => void) => void;
|
||||
makePreloginKey: (masterPassword: string, email: string) => Promise<SymmetricCryptoKey>;
|
||||
authingWithApiKey: () => boolean;
|
||||
|
||||
@@ -27,6 +27,7 @@ import { IdentityTwoFactorResponse } from "../../models/response/identityTwoFact
|
||||
|
||||
export abstract class LogInStrategy {
|
||||
protected abstract tokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest;
|
||||
protected captchaBypassToken: string = null;
|
||||
|
||||
constructor(
|
||||
protected cryptoService: CryptoService,
|
||||
@@ -44,7 +45,10 @@ export abstract class LogInStrategy {
|
||||
credentials: ApiLogInCredentials | PasswordLogInCredentials | SsoLogInCredentials
|
||||
): Promise<AuthResult>;
|
||||
|
||||
async logInTwoFactor(twoFactor: TokenRequestTwoFactor): Promise<AuthResult> {
|
||||
async logInTwoFactor(
|
||||
twoFactor: TokenRequestTwoFactor,
|
||||
captchaResponse: string = null
|
||||
): Promise<AuthResult> {
|
||||
this.tokenRequest.setTwoFactor(twoFactor);
|
||||
return this.startLogIn();
|
||||
}
|
||||
@@ -152,6 +156,7 @@ export abstract class LogInStrategy {
|
||||
const result = new AuthResult();
|
||||
result.twoFactorProviders = response.twoFactorProviders2;
|
||||
this.twoFactorService.setProviders(response);
|
||||
this.captchaBypassToken = response.captchaToken ?? null;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,11 @@ import { StateService } from "../../abstractions/state.service";
|
||||
import { TokenService } from "../../abstractions/token.service";
|
||||
import { TwoFactorService } from "../../abstractions/twoFactor.service";
|
||||
import { HashPurpose } from "../../enums/hashPurpose";
|
||||
import { AuthResult } from "../../models/domain/authResult";
|
||||
import { PasswordLogInCredentials } from "../../models/domain/logInCredentials";
|
||||
import { SymmetricCryptoKey } from "../../models/domain/symmetricCryptoKey";
|
||||
import { PasswordTokenRequest } from "../../models/request/identityToken/passwordTokenRequest";
|
||||
import { TokenRequestTwoFactor } from "../../models/request/identityToken/tokenRequest";
|
||||
|
||||
import { LogInStrategy } from "./logIn.strategy";
|
||||
|
||||
@@ -59,6 +61,14 @@ export class PasswordLogInStrategy extends LogInStrategy {
|
||||
await this.cryptoService.setKeyHash(this.localHashedPassword);
|
||||
}
|
||||
|
||||
async logInTwoFactor(
|
||||
twoFactor: TokenRequestTwoFactor,
|
||||
captchaResponse: string
|
||||
): Promise<AuthResult> {
|
||||
this.tokenRequest.captchaResponse = captchaResponse ?? this.captchaBypassToken;
|
||||
return super.logInTwoFactor(twoFactor);
|
||||
}
|
||||
|
||||
async logIn(credentials: PasswordLogInCredentials) {
|
||||
const { email, masterPassword, captchaToken, twoFactor } = credentials;
|
||||
|
||||
|
||||
@@ -115,16 +115,19 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
return result;
|
||||
}
|
||||
|
||||
async logInTwoFactor(twoFactor: TokenRequestTwoFactor): Promise<AuthResult> {
|
||||
async logInTwoFactor(
|
||||
twoFactor: TokenRequestTwoFactor,
|
||||
captchaResponse: string
|
||||
): Promise<AuthResult> {
|
||||
if (this.logInStrategy == null) {
|
||||
throw new Error(this.i18nService.t("sessionTimeout"));
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await this.logInStrategy.logInTwoFactor(twoFactor);
|
||||
const result = await this.logInStrategy.logInTwoFactor(twoFactor, captchaResponse);
|
||||
|
||||
// Only clear state if 2FA token has been accepted, otherwise we need to be able to try again
|
||||
if (!result.requiresTwoFactor) {
|
||||
if (!result.requiresTwoFactor && !result.requiresCaptcha) {
|
||||
this.clearState();
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user