1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 07:43:35 +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:
Jake Fink
2024-03-12 14:19:50 -04:00
committed by GitHub
parent 6b1da67f3a
commit a0e0637bb6
35 changed files with 1414 additions and 362 deletions

View File

@@ -1,3 +1,6 @@
import { BehaviorSubject } from "rxjs";
import { Jsonify } from "type-fest";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
@@ -13,13 +16,26 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { UserApiLoginCredentials } from "../models/domain/login-credentials";
import { CacheData } from "../services/login-strategies/login-strategy.state";
import { LoginStrategy } from "./login.strategy";
import { LoginStrategy, LoginStrategyData } from "./login.strategy";
export class UserApiLoginStrategyData implements LoginStrategyData {
tokenRequest: UserApiTokenRequest;
captchaBypassToken: string;
static fromJSON(obj: Jsonify<UserApiLoginStrategyData>): UserApiLoginStrategyData {
return Object.assign(new UserApiLoginStrategyData(), obj, {
tokenRequest: UserApiTokenRequest.fromJSON(obj.tokenRequest),
});
}
}
export class UserApiLoginStrategy extends LoginStrategy {
tokenRequest: UserApiTokenRequest;
protected cache: BehaviorSubject<UserApiLoginStrategyData>;
constructor(
data: UserApiLoginStrategyData,
cryptoService: CryptoService,
apiService: ApiService,
tokenService: TokenService,
@@ -43,15 +59,18 @@ export class UserApiLoginStrategy extends LoginStrategy {
stateService,
twoFactorService,
);
this.cache = new BehaviorSubject(data);
}
override async logIn(credentials: UserApiLoginCredentials) {
this.tokenRequest = new UserApiTokenRequest(
const data = new UserApiLoginStrategyData();
data.tokenRequest = new UserApiTokenRequest(
credentials.clientId,
credentials.clientSecret,
await this.buildTwoFactor(),
await this.buildDeviceRequest(),
);
this.cache.next(data);
const [authResult] = await this.startLogIn();
return authResult;
@@ -84,7 +103,15 @@ export class UserApiLoginStrategy extends LoginStrategy {
protected async saveAccountInformation(tokenResponse: IdentityTokenResponse) {
await super.saveAccountInformation(tokenResponse);
await this.stateService.setApiKeyClientId(this.tokenRequest.clientId);
await this.stateService.setApiKeyClientSecret(this.tokenRequest.clientSecret);
const tokenRequest = this.cache.value.tokenRequest;
await this.stateService.setApiKeyClientId(tokenRequest.clientId);
await this.stateService.setApiKeyClientSecret(tokenRequest.clientSecret);
}
exportCache(): CacheData {
return {
userApiKey: this.cache.value,
};
}
}