1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-20 03:13:55 +00:00
Files
browser/libs/angular/src/auth/guards/lock.guard.ts
Bernd Schoolmann 7a24a538a4 [PM-23072] Remove legacy key support in auth code (#15350)
* Remove legacy key support in auth code

* Fix tests
2025-07-23 22:29:44 +02:00

80 lines
3.2 KiB
TypeScript

import { inject } from "@angular/core";
import {
ActivatedRouteSnapshot,
CanActivateFn,
Router,
RouterStateSnapshot,
} from "@angular/router";
import { firstValueFrom } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
import { VaultTimeoutSettingsService } from "@bitwarden/common/key-management/vault-timeout";
import { KeyService } from "@bitwarden/key-management";
/**
* Only allow access to this route if the vault is locked.
* If TDE is enabled then the user must also have had a user key at some point.
* Otherwise reject navigation.
*
* TODO: This should return Observable<boolean | UrlTree> once we can remove all the promises
*/
export function lockGuard(): CanActivateFn {
return async (
activatedRouteSnapshot: ActivatedRouteSnapshot,
routerStateSnapshot: RouterStateSnapshot,
) => {
const authService = inject(AuthService);
const keyService = inject(KeyService);
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
const router = inject(Router);
const userVerificationService = inject(UserVerificationService);
const vaultTimeoutSettingsService = inject(VaultTimeoutSettingsService);
const accountService = inject(AccountService);
const activeUser = await firstValueFrom(accountService.activeAccount$);
// If no active user, redirect to root:
// scenario context: user logs out on lock screen and app will reload lock comp without active user
if (!activeUser) {
return router.createUrlTree(["/"]);
}
const authStatus = await firstValueFrom(authService.authStatusFor$(activeUser.id));
if (authStatus !== AuthenticationStatus.Locked) {
return router.createUrlTree(["/"]);
}
// if user can't lock, they can't access the lock screen
const canLock = await vaultTimeoutSettingsService.canLock(activeUser.id);
if (!canLock) {
return false;
}
// User is authN and in locked state.
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
// Create special exception which allows users to go from the login-initiated page to the lock page for the approve w/ MP flow
// The MP check is necessary to prevent direct manual navigation from other locked state pages for users who don't have a MP
if (
activatedRouteSnapshot.queryParams["from"] === "login-initiated" &&
tdeEnabled &&
(await userVerificationService.hasMasterPassword())
) {
return true;
}
// If authN user with TDE directly navigates to lock, reject that navigation
const everHadUserKey = await firstValueFrom(keyService.everHadUserKey$(activeUser.id));
if (tdeEnabled && !everHadUserKey) {
return false;
}
return true;
};
}