mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
fix(login): [PM-20587] Fix unawaited calls to set login email
* Await setting login email in state. * Changed to get email state within the component. * Added null filter * PM-20587 - LoginViaAuthRequest component - update initStandardAuthRequestFlow to correctly retrieve data from active account. --------- Co-authored-by: Jared Snider <jsnider@bitwarden.com>
This commit is contained in:
@@ -284,7 +284,6 @@ export class LoginDecryptionOptionsComponent implements OnInit {
|
||||
}
|
||||
|
||||
protected async approveFromOtherDevice() {
|
||||
this.loginEmailService.setLoginEmail(this.email);
|
||||
await this.router.navigate(["/login-with-device"]);
|
||||
}
|
||||
|
||||
@@ -297,7 +296,6 @@ export class LoginDecryptionOptionsComponent implements OnInit {
|
||||
}
|
||||
|
||||
protected async requestAdminApproval() {
|
||||
this.loginEmailService.setLoginEmail(this.email);
|
||||
await this.router.navigate(["/admin-approval-requested"]);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common";
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { IsActiveMatchOptions, Router, RouterModule } from "@angular/router";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
import { Observable, filter, firstValueFrom, map, merge, race, take, timer } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import {
|
||||
@@ -178,7 +178,26 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy {
|
||||
private async initStandardAuthRequestFlow(): Promise<void> {
|
||||
this.flow = Flow.StandardAuthRequest;
|
||||
|
||||
this.email = (await firstValueFrom(this.loginEmailService.loginEmail$)) || undefined;
|
||||
// For a standard flow, we can get the user's email from two different places:
|
||||
// 1. The loginEmailService, which is the email that the user is trying to log in with. This is cleared
|
||||
// when the user logs in successfully. We can use this when the user is using Login with Device.
|
||||
// 2. With TDE Login with Another Device, the user is already logged in and we just need to get
|
||||
// a decryption key, so we can use the active account's email.
|
||||
const activeAccountEmail$: Observable<string | undefined> =
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.email));
|
||||
const loginEmail$: Observable<string | null> = this.loginEmailService.loginEmail$;
|
||||
|
||||
// Use merge as we want to get the first value from either observable.
|
||||
const firstEmail$ = merge(loginEmail$, activeAccountEmail$).pipe(
|
||||
filter((e): e is string => !!e), // convert null/undefined to false and filter out so we narrow type to string
|
||||
take(1), // complete after first value
|
||||
);
|
||||
|
||||
const emailRetrievalTimeout$ = timer(2500).pipe(map(() => undefined as undefined));
|
||||
|
||||
// Wait for either the first email or the timeout to occur so we can proceed
|
||||
// neither above observable will complete, so we have to add a timeout
|
||||
this.email = await firstValueFrom(race(firstEmail$, emailRetrievalTimeout$));
|
||||
|
||||
if (!this.email) {
|
||||
await this.handleMissingEmail();
|
||||
|
||||
@@ -539,7 +539,7 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
// If we load an email into the form, we need to initialize it for the login process as well
|
||||
// so that other login components can use it.
|
||||
// We do this here as it's possible that a user doesn't edit the email field before submitting.
|
||||
this.loginEmailService.setLoginEmail(storedEmail);
|
||||
await this.loginEmailService.setLoginEmail(storedEmail);
|
||||
} else {
|
||||
this.formGroup.controls.rememberEmail.setValue(false);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export class PasswordHintComponent implements OnInit {
|
||||
};
|
||||
|
||||
protected async cancel() {
|
||||
this.loginEmailService.setLoginEmail(this.email);
|
||||
await this.loginEmailService.setLoginEmail(this.email);
|
||||
await this.router.navigate(["login"]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user