1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-17 09:59:41 +00:00
Files
browser/libs/angular/src/auth/guards/lock.guard.ts
Jake Fink 43f5423e78 [PM-12606] Move Vault Timeout and Vault Timeout Settings to KM (#13405)
* move vault timeout and vault timeout settings to km

* move browser vault timeout service to km

* fix cli import

* fix imports

* fix some relative imports

* use relative imports within common

* fix imports

* fix new imports

* Fix new imports

* fix spec imports
2025-02-28 09:55:03 -05:00

95 lines
3.8 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 { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { ClientType } from "@bitwarden/common/enums";
import { VaultTimeoutSettingsService } from "@bitwarden/common/key-management/vault-timeout";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
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 platformUtilService = inject(PlatformUtilsService);
const messagingService = inject(MessagingService);
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;
}
// If legacy user on web, redirect to migration page
if (await keyService.isLegacyUser()) {
if (platformUtilService.getClientType() === ClientType.Web) {
return router.createUrlTree(["migrate-legacy-encryption"]);
}
// Log out legacy users on other clients
messagingService.send("logout");
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$);
if (tdeEnabled && !everHadUserKey) {
return false;
}
return true;
};
}