mirror of
https://github.com/bitwarden/browser
synced 2025-12-22 03:03:43 +00:00
[PM-5255, PM-3339] Refactor login strategy to use state providers (#7821)
* add key definition and StrategyData classes * use state providers for login strategies * serialize login data for cache * use state providers for auth request notification * fix registrations * add docs to abstraction * fix sso strategy * fix password login strategy tests * fix base login strategy tests * fix user api login strategy tests * PM-3339 add tests for admin auth request in sso strategy * fix auth request login strategy tests * fix webauthn login strategy tests * create login strategy state * use barrel file in common/spec * test login strategy cache deserialization * use global state provider * add test for login strategy service * fix auth request storage * add recursive prototype checking and json deserializers to nested objects * fix CLI * Create wrapper for login strategy cache * use behavior subjects in strategies instead of global state * rename userApi to userApiKey * pr feedback * fix tests * fix deserialization tests * fix tests --------- Co-authored-by: rr-bw <102181210+rr-bw@users.noreply.github.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||
@@ -36,16 +38,21 @@ import {
|
||||
AuthRequestLoginCredentials,
|
||||
WebAuthnLoginCredentials,
|
||||
} from "../models/domain/login-credentials";
|
||||
import { CacheData } from "../services/login-strategies/login-strategy.state";
|
||||
|
||||
type IdentityResponse = IdentityTokenResponse | IdentityTwoFactorResponse | IdentityCaptchaResponse;
|
||||
|
||||
export abstract class LoginStrategy {
|
||||
protected abstract tokenRequest:
|
||||
export abstract class LoginStrategyData {
|
||||
tokenRequest:
|
||||
| UserApiTokenRequest
|
||||
| PasswordTokenRequest
|
||||
| SsoTokenRequest
|
||||
| WebAuthnLoginTokenRequest;
|
||||
protected captchaBypassToken: string = null;
|
||||
captchaBypassToken?: string;
|
||||
}
|
||||
|
||||
export abstract class LoginStrategy {
|
||||
protected abstract cache: BehaviorSubject<LoginStrategyData>;
|
||||
|
||||
constructor(
|
||||
protected cryptoService: CryptoService,
|
||||
@@ -59,6 +66,8 @@ export abstract class LoginStrategy {
|
||||
protected twoFactorService: TwoFactorService,
|
||||
) {}
|
||||
|
||||
abstract exportCache(): CacheData;
|
||||
|
||||
abstract logIn(
|
||||
credentials:
|
||||
| UserApiLoginCredentials
|
||||
@@ -72,7 +81,9 @@ export abstract class LoginStrategy {
|
||||
twoFactor: TokenTwoFactorRequest,
|
||||
captchaResponse: string = null,
|
||||
): Promise<AuthResult> {
|
||||
this.tokenRequest.setTwoFactor(twoFactor);
|
||||
const data = this.cache.value;
|
||||
data.tokenRequest.setTwoFactor(twoFactor);
|
||||
this.cache.next(data);
|
||||
const [authResult] = await this.startLogIn();
|
||||
return authResult;
|
||||
}
|
||||
@@ -80,7 +91,8 @@ export abstract class LoginStrategy {
|
||||
protected async startLogIn(): Promise<[AuthResult, IdentityResponse]> {
|
||||
this.twoFactorService.clearSelectedProvider();
|
||||
|
||||
const response = await this.apiService.postIdentityToken(this.tokenRequest);
|
||||
const tokenRequest = this.cache.value.tokenRequest;
|
||||
const response = await this.apiService.postIdentityToken(tokenRequest);
|
||||
|
||||
if (response instanceof IdentityTwoFactorResponse) {
|
||||
return [await this.processTwoFactorResponse(response), response];
|
||||
@@ -195,9 +207,7 @@ export abstract class LoginStrategy {
|
||||
|
||||
// The keys comes from different sources depending on the login strategy
|
||||
protected abstract setMasterKey(response: IdentityTokenResponse): Promise<void>;
|
||||
|
||||
protected abstract setUserKey(response: IdentityTokenResponse): Promise<void>;
|
||||
|
||||
protected abstract setPrivateKey(response: IdentityTokenResponse): Promise<void>;
|
||||
|
||||
// Old accounts used master key for encryption. We are forcing migrations but only need to
|
||||
@@ -221,7 +231,7 @@ export abstract class LoginStrategy {
|
||||
result.twoFactorProviders = response.twoFactorProviders2;
|
||||
|
||||
this.twoFactorService.setProviders(response);
|
||||
this.captchaBypassToken = response.captchaToken ?? null;
|
||||
this.cache.next({ ...this.cache.value, captchaBypassToken: response.captchaToken ?? null });
|
||||
result.ssoEmail2FaSessionToken = response.ssoEmail2faSessionToken;
|
||||
result.email = response.email;
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user