mirror of
https://github.com/bitwarden/browser
synced 2026-02-05 11:13:44 +00:00
When a locked vault is unlocked displays correctly (#15612)
* When a locked vault is unlocked displays correctly * Keep old behavior while checking for recently unlocked vault * Revert the electron-builder * Simplify by using a simple redirect when vault unlocked * Remove single use of `userSelectedCipher` * Add a guard clause to unlock * Revert to original spacing * Add reactive guard to unlock vault * Fix for passkey picker closing prematurely * Remove unneeded root navigation in ensureUnlockedVault * Fix vault not unlocking
This commit is contained in:
@@ -47,6 +47,7 @@ import { LockComponent } from "@bitwarden/key-management-ui";
|
||||
import { maxAccountsGuardFn } from "../auth/guards/max-accounts.guard";
|
||||
import { SetPasswordComponent } from "../auth/set-password.component";
|
||||
import { UpdateTempPasswordComponent } from "../auth/update-temp-password.component";
|
||||
import { reactiveUnlockVaultGuard } from "../autofill/guards/reactive-vault-guard";
|
||||
import { Fido2CreateComponent } from "../autofill/modal/credentials/fido2-create.component";
|
||||
import { Fido2ExcludedCiphersComponent } from "../autofill/modal/credentials/fido2-excluded-ciphers.component";
|
||||
import { Fido2VaultComponent } from "../autofill/modal/credentials/fido2-vault.component";
|
||||
@@ -296,7 +297,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "lock",
|
||||
canActivate: [lockGuard()],
|
||||
canActivate: [lockGuard(), reactiveUnlockVaultGuard],
|
||||
data: {
|
||||
pageIcon: Icons.LockIcon,
|
||||
pageTitle: {
|
||||
|
||||
42
apps/desktop/src/autofill/guards/reactive-vault-guard.ts
Normal file
42
apps/desktop/src/autofill/guards/reactive-vault-guard.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { inject } from "@angular/core";
|
||||
import { CanActivateFn, Router } from "@angular/router";
|
||||
import { combineLatest, map, switchMap, distinctUntilChanged } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
|
||||
import { DesktopSettingsService } from "../../platform/services/desktop-settings.service";
|
||||
|
||||
/**
|
||||
* Reactive route guard that redirects to the unlocked vault.
|
||||
* Redirects to vault when unlocked in main window.
|
||||
*/
|
||||
export const reactiveUnlockVaultGuard: CanActivateFn = () => {
|
||||
const router = inject(Router);
|
||||
const authService = inject(AuthService);
|
||||
const accountService = inject(AccountService);
|
||||
const desktopSettingsService = inject(DesktopSettingsService);
|
||||
|
||||
return combineLatest([accountService.activeAccount$, desktopSettingsService.modalMode$]).pipe(
|
||||
switchMap(([account, modalMode]) => {
|
||||
if (!account) {
|
||||
return [true];
|
||||
}
|
||||
|
||||
// Monitor when the vault has been unlocked.
|
||||
return authService.authStatusFor$(account.id).pipe(
|
||||
distinctUntilChanged(),
|
||||
map((authStatus) => {
|
||||
// If vault is unlocked and we're not in modal mode, redirect to vault
|
||||
if (authStatus === AuthenticationStatus.Unlocked && !modalMode?.isModalModeActive) {
|
||||
return router.createUrlTree(["/vault"]);
|
||||
}
|
||||
|
||||
// Otherwise keep user on the lock screen
|
||||
return true;
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
};
|
||||
@@ -145,12 +145,15 @@ export class Fido2CreateComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async closeModal(): Promise<void> {
|
||||
await this.router.navigate(["/"]);
|
||||
await this.desktopSettingsService.setModalMode(false);
|
||||
await this.accountService.setShowHeader(true);
|
||||
|
||||
if (this.session) {
|
||||
this.session.notifyConfirmCreateCredential(false);
|
||||
this.session.confirmChosenCipher(null);
|
||||
}
|
||||
|
||||
await this.router.navigate(["/"]);
|
||||
}
|
||||
|
||||
private initializeCiphersObservable(rpid: string): void {
|
||||
|
||||
@@ -69,8 +69,10 @@ describe("Fido2ExcludedCiphersComponent", () => {
|
||||
|
||||
await component.closeModal();
|
||||
|
||||
expect(mockDesktopSettingsService.setModalMode).toHaveBeenCalledWith(false);
|
||||
expect(mockAccountService.setShowHeader).toHaveBeenCalledWith(true);
|
||||
expect(mockSession.notifyConfirmCreateCredential).toHaveBeenCalledWith(false);
|
||||
expect(mockSession.confirmChosenCipher).toHaveBeenCalledWith(null);
|
||||
expect(mockRouter.navigate).toHaveBeenCalledWith(["/"]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,11 +64,17 @@ export class Fido2ExcludedCiphersComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async closeModal(): Promise<void> {
|
||||
await this.router.navigate(["/"]);
|
||||
// Clean up modal state
|
||||
await this.desktopSettingsService.setModalMode(false);
|
||||
await this.accountService.setShowHeader(true);
|
||||
|
||||
// Clean up session state
|
||||
if (this.session) {
|
||||
this.session.notifyConfirmCreateCredential(false);
|
||||
this.session.confirmChosenCipher(null);
|
||||
}
|
||||
|
||||
// Navigate away
|
||||
await this.router.navigate(["/"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,9 @@ export class Fido2VaultComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async closeModal(): Promise<void> {
|
||||
await this.desktopSettingsService.setModalMode(false);
|
||||
await this.accountService.setShowHeader(true);
|
||||
|
||||
if (this.session) {
|
||||
this.session.notifyConfirmCreateCredential(false);
|
||||
this.session.confirmChosenCipher(null);
|
||||
@@ -127,8 +130,6 @@ export class Fido2VaultComponent implements OnInit, OnDestroy {
|
||||
this.logService.error("Failed to load ciphers", error);
|
||||
});
|
||||
});
|
||||
|
||||
await this.closeModal();
|
||||
}
|
||||
|
||||
private async validateCipherAccess(cipher: CipherView): Promise<boolean> {
|
||||
|
||||
@@ -338,8 +338,8 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi
|
||||
// make the cipherIds available to the UI.
|
||||
this.availableCipherIdsSubject.next(existingCipherIds);
|
||||
|
||||
await this.accountService.setShowHeader(false);
|
||||
await this.showUi("/fido2-excluded", this.windowObject.windowXy, false);
|
||||
await this.accountService.setShowHeader(true);
|
||||
}
|
||||
|
||||
async ensureUnlockedVault(): Promise<void> {
|
||||
@@ -362,6 +362,10 @@ export class DesktopFido2UserInterfaceSession implements Fido2UserInterfaceSessi
|
||||
this.logService.warning("Error while waiting for vault to unlock", error);
|
||||
}
|
||||
|
||||
if (status2 === AuthenticationStatus.Unlocked) {
|
||||
await this.router.navigate(["/"]);
|
||||
}
|
||||
|
||||
if (status2 !== AuthenticationStatus.Unlocked) {
|
||||
await this.hideUi();
|
||||
throw new Error("Vault is not unlocked");
|
||||
|
||||
Reference in New Issue
Block a user