1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-19 09:43:23 +00:00

move auth request notification to service (#8451)

- cleanup hanging promises
This commit is contained in:
Jake Fink
2024-03-28 09:34:21 -04:00
committed by GitHub
parent 37735436d1
commit bd6b3266d4
11 changed files with 57 additions and 133 deletions

View File

@@ -1,7 +1,12 @@
import { Observable } from "rxjs";
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response";
import { UserKey, MasterKey } from "@bitwarden/common/types/key";
export abstract class AuthRequestServiceAbstraction {
/** Emits an auth request id when an auth request has been approved. */
authRequestPushNotification$: Observable<string>;
/**
* Approve or deny an auth request.
* @param approve True to approve, false to deny.
@@ -54,4 +59,11 @@ export abstract class AuthRequestServiceAbstraction {
pubKeyEncryptedMasterKeyHash: string,
privateKey: ArrayBuffer,
) => Promise<{ masterKey: MasterKey; masterKeyHash: string }>;
/**
* Handles incoming auth request push notifications.
* @param notification push notification.
* @remark We should only be receiving approved push notifications to prevent enumeration.
*/
abstract sendAuthRequestPushNotification: (notification: AuthRequestPushNotification) => void;
}

View File

@@ -4,7 +4,6 @@ import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response";
import { MasterKey } from "@bitwarden/common/types/key";
import {
@@ -21,10 +20,6 @@ export abstract class LoginStrategyServiceAbstraction {
* Emits null if the session has timed out.
*/
currentAuthType$: Observable<AuthenticationType | null>;
/**
* Emits when an auth request has been approved.
*/
authRequestPushNotification$: Observable<string>;
/**
* If the login strategy uses the email address of the user, this
* will return it. Otherwise, it will return null.
@@ -77,10 +72,6 @@ export abstract class LoginStrategyServiceAbstraction {
* Creates a master key from the provided master password and email.
*/
makePreloginKey: (masterPassword: string, email: string) => Promise<MasterKey>;
/**
* Sends a notification to {@link LoginStrategyServiceAbstraction.authRequestPushNotification}
*/
sendAuthRequestPushNotification: (notification: AuthRequestPushNotification) => Promise<void>;
/**
* Sends a response to an auth request.
*/

View File

@@ -1,6 +1,9 @@
import { Observable, Subject } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PasswordlessAuthRequest } from "@bitwarden/common/auth/models/request/passwordless-auth.request";
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
@@ -11,6 +14,9 @@ import { MasterKey, UserKey } from "@bitwarden/common/types/key";
import { AuthRequestServiceAbstraction } from "../../abstractions/auth-request.service.abstraction";
export class AuthRequestService implements AuthRequestServiceAbstraction {
private authRequestPushNotificationSubject = new Subject<string>();
authRequestPushNotification$: Observable<string>;
constructor(
private appIdService: AppIdService,
private cryptoService: CryptoService,
@@ -126,4 +132,10 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
masterKeyHash,
};
}
sendAuthRequestPushNotification(notification: AuthRequestPushNotification): void {
if (notification.id != null) {
this.authRequestPushNotificationSubject.next(notification.id);
}
}
}

View File

@@ -1,7 +1,6 @@
import {
combineLatestWith,
distinctUntilChanged,
filter,
firstValueFrom,
map,
Observable,
@@ -23,7 +22,6 @@ import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { PreloginRequest } from "@bitwarden/common/models/request/prelogin.request";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
@@ -81,8 +79,6 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
>;
currentAuthType$: Observable<AuthenticationType | null>;
// TODO: move to auth request service
authRequestPushNotification$: Observable<string>;
constructor(
protected cryptoService: CryptoService,
@@ -114,9 +110,6 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
);
this.currentAuthType$ = this.currentAuthnTypeState.state$;
this.authRequestPushNotification$ = this.authRequestPushNotificationState.state$.pipe(
filter((id) => id != null),
);
this.loginStrategy$ = this.currentAuthnTypeState.state$.pipe(
distinctUntilChanged(),
combineLatestWith(this.loginStrategyCacheState.state$),
@@ -256,13 +249,6 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
return await this.cryptoService.makeMasterKey(masterPassword, email, kdf, kdfConfig);
}
// TODO move to auth request service
async sendAuthRequestPushNotification(notification: AuthRequestPushNotification): Promise<void> {
if (notification.id != null) {
await this.authRequestPushNotificationState.update((_) => notification.id);
}
}
// TODO: move to auth request service
async passwordlessLogin(
id: string,