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,7 +1,7 @@
export enum AuthenticationType {
Password = 0,
Sso = 1,
UserApi = 2,
UserApiKey = 2,
AuthRequest = 3,
WebAuthn = 4,
}

View File

@@ -1,3 +1,5 @@
import { Jsonify } from "type-fest";
import { DeviceType } from "../../../../enums";
import { PlatformUtilsService } from "../../../../platform/abstractions/platform-utils.service";
@@ -13,4 +15,8 @@ export class DeviceRequest {
this.identifier = appId;
this.pushToken = null;
}
static fromJSON(json: Jsonify<DeviceRequest>) {
return Object.assign(Object.create(DeviceRequest.prototype), json);
}
}

View File

@@ -34,4 +34,13 @@ export class PasswordTokenRequest extends TokenRequest implements CaptchaProtect
alterIdentityTokenHeaders(headers: Headers) {
headers.set("Auth-Email", Utils.fromUtf8ToUrlB64(this.email));
}
static fromJSON(json: any) {
return Object.assign(Object.create(PasswordTokenRequest.prototype), json, {
device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
twoFactor: json.twoFactor
? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
: undefined,
});
}
}

View File

@@ -23,4 +23,13 @@ export class SsoTokenRequest extends TokenRequest {
return obj;
}
static fromJSON(json: any) {
return Object.assign(Object.create(SsoTokenRequest.prototype), json, {
device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
twoFactor: json.twoFactor
? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
: undefined,
});
}
}

View File

@@ -21,4 +21,13 @@ export class UserApiTokenRequest extends TokenRequest {
return obj;
}
static fromJSON(json: any) {
return Object.assign(Object.create(UserApiTokenRequest.prototype), json, {
device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
twoFactor: json.twoFactor
? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
: undefined,
});
}
}

View File

@@ -1,6 +1,7 @@
import { WebAuthnLoginAssertionResponseRequest } from "../../../services/webauthn-login/request/webauthn-login-assertion-response.request";
import { DeviceRequest } from "./device.request";
import { TokenTwoFactorRequest } from "./token-two-factor.request";
import { TokenRequest } from "./token.request";
export class WebAuthnLoginTokenRequest extends TokenRequest {
@@ -22,4 +23,14 @@ export class WebAuthnLoginTokenRequest extends TokenRequest {
return obj;
}
static fromJSON(json: any) {
return Object.assign(Object.create(WebAuthnLoginTokenRequest.prototype), json, {
deviceResponse: WebAuthnLoginAssertionResponseRequest.fromJSON(json.deviceResponse),
device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
twoFactor: json.twoFactor
? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
: undefined,
});
}
}

View File

@@ -54,7 +54,7 @@ export class AnonymousHubService implements AnonymousHubServiceAbstraction {
}
private async ProcessNotification(notification: NotificationResponse) {
await this.loginStrategyService.authResponsePushNotification(
await this.loginStrategyService.sendAuthRequestPushNotification(
notification.payload as AuthRequestPushNotification,
);
}

View File

@@ -1,3 +1,5 @@
import { Jsonify } from "type-fest";
import { Utils } from "../../../../platform/misc/utils";
import { WebAuthnLoginResponseRequest } from "./webauthn-login-response.request";
@@ -27,4 +29,8 @@ export class WebAuthnLoginAssertionResponseRequest extends WebAuthnLoginResponse
userHandle: Utils.fromBufferToUrlB64(credential.response.userHandle),
};
}
static fromJSON(json: Jsonify<WebAuthnLoginAssertionResponseRequest>) {
return Object.assign(Object.create(WebAuthnLoginAssertionResponseRequest.prototype), json);
}
}

View File

@@ -27,6 +27,7 @@ export const PROVIDERS_DISK = new StateDefinition("providers", "disk");
export const ACCOUNT_MEMORY = new StateDefinition("account", "memory");
export const SSO_DISK = new StateDefinition("ssoLogin", "disk");
export const LOGIN_STRATEGY_MEMORY = new StateDefinition("loginStrategy", "memory");
// Autofill