mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 06:43:35 +00:00
Auth/pm 8882/Add TDE Logging (#9673)
* Added logging behind feature flag. * Added default for new flag. * Additional logging changes. * Consolidated log messages. * Removed unneccessary log. * Fixed test error. * Fixed linting. * Fixed constructor on test. * Updated to remove flag * Moved service. * Added logging to redirect guard.
This commit is contained in:
@@ -6,6 +6,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
|||||||
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
|
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
|
||||||
export interface RedirectRoutes {
|
export interface RedirectRoutes {
|
||||||
loggedIn: string;
|
loggedIn: string;
|
||||||
@@ -32,6 +33,7 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
|
|||||||
const authService = inject(AuthService);
|
const authService = inject(AuthService);
|
||||||
const cryptoService = inject(CryptoService);
|
const cryptoService = inject(CryptoService);
|
||||||
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
|
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
|
||||||
|
const logService = inject(LogService);
|
||||||
const router = inject(Router);
|
const router = inject(Router);
|
||||||
|
|
||||||
const authStatus = await authService.getAuthStatus();
|
const authStatus = await authService.getAuthStatus();
|
||||||
@@ -49,6 +51,12 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
|
|||||||
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
|
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
|
||||||
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);
|
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);
|
||||||
if (authStatus === AuthenticationStatus.Locked && tdeEnabled && !everHadUserKey) {
|
if (authStatus === AuthenticationStatus.Locked && tdeEnabled && !everHadUserKey) {
|
||||||
|
logService.info(
|
||||||
|
"Sending user to TDE decryption options. AuthStatus is %s. TDE support is %s. Ever had user key is %s.",
|
||||||
|
AuthenticationStatus[authStatus],
|
||||||
|
tdeEnabled,
|
||||||
|
everHadUserKey,
|
||||||
|
);
|
||||||
return router.createUrlTree([routes.notDecrypted], { queryParams: route.queryParams });
|
return router.createUrlTree([routes.notDecrypted], { queryParams: route.queryParams });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
|||||||
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
|
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only allow access to this route if the vault is locked and has never been decrypted.
|
* Only allow access to this route if the vault is locked and has never been decrypted.
|
||||||
@@ -23,15 +24,30 @@ export function tdeDecryptionRequiredGuard(): CanActivateFn {
|
|||||||
const authService = inject(AuthService);
|
const authService = inject(AuthService);
|
||||||
const cryptoService = inject(CryptoService);
|
const cryptoService = inject(CryptoService);
|
||||||
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
|
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
|
||||||
|
const logService = inject(LogService);
|
||||||
const router = inject(Router);
|
const router = inject(Router);
|
||||||
|
|
||||||
const authStatus = await authService.getAuthStatus();
|
const authStatus = await authService.getAuthStatus();
|
||||||
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
|
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
|
||||||
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);
|
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);
|
||||||
|
|
||||||
|
// We need to determine if we should bypass the decryption options and send the user to the vault.
|
||||||
|
// The ONLY time that we want to send a user to the decryption options is when:
|
||||||
|
// 1. The user's auth status is Locked, AND
|
||||||
|
// 2. TDE is enabled, AND
|
||||||
|
// 3. The user has never had a user key in state since last logout.
|
||||||
|
// The inverse of this is when we should send the user to the vault.
|
||||||
if (authStatus !== AuthenticationStatus.Locked || !tdeEnabled || everHadUserKey) {
|
if (authStatus !== AuthenticationStatus.Locked || !tdeEnabled || everHadUserKey) {
|
||||||
return router.createUrlTree(["/"]);
|
return router.createUrlTree(["/"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logService.info(
|
||||||
|
"Sending user to TDE decryption options. AuthStatus is %s. TDE support is %s. Ever had user key is %s.",
|
||||||
|
AuthenticationStatus[authStatus],
|
||||||
|
tdeEnabled,
|
||||||
|
everHadUserKey,
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,12 +87,16 @@ export class SsoLoginStrategy extends LoginStrategy {
|
|||||||
|
|
||||||
data.userEnteredEmail = credentials.email;
|
data.userEnteredEmail = credentials.email;
|
||||||
|
|
||||||
|
const deviceRequest = await this.buildDeviceRequest();
|
||||||
|
|
||||||
|
this.logService.info("Logging in with appId %s.", deviceRequest.identifier);
|
||||||
|
|
||||||
data.tokenRequest = new SsoTokenRequest(
|
data.tokenRequest = new SsoTokenRequest(
|
||||||
credentials.code,
|
credentials.code,
|
||||||
credentials.codeVerifier,
|
credentials.codeVerifier,
|
||||||
credentials.redirectUrl,
|
credentials.redirectUrl,
|
||||||
await this.buildTwoFactor(credentials.twoFactor, credentials.email),
|
await this.buildTwoFactor(credentials.twoFactor, credentials.email),
|
||||||
await this.buildDeviceRequest(),
|
deviceRequest,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cache.next(data);
|
this.cache.next(data);
|
||||||
@@ -195,12 +199,18 @@ export class SsoLoginStrategy extends LoginStrategy {
|
|||||||
|
|
||||||
// Note: TDE and key connector are mutually exclusive
|
// Note: TDE and key connector are mutually exclusive
|
||||||
if (userDecryptionOptions?.trustedDeviceOption) {
|
if (userDecryptionOptions?.trustedDeviceOption) {
|
||||||
|
this.logService.info("Attempting to set user key with approved admin auth request.");
|
||||||
|
|
||||||
|
// Try to use the user key from an approved admin request if it exists.
|
||||||
|
// Using it will clear it from state and future requests will use the device key.
|
||||||
await this.trySetUserKeyWithApprovedAdminRequestIfExists(userId);
|
await this.trySetUserKeyWithApprovedAdminRequestIfExists(userId);
|
||||||
|
|
||||||
const hasUserKey = await this.cryptoService.hasUserKey(userId);
|
const hasUserKey = await this.cryptoService.hasUserKey(userId);
|
||||||
|
|
||||||
// Only try to set user key with device key if admin approval request was not successful
|
// Only try to set user key with device key if admin approval request was not successful.
|
||||||
if (!hasUserKey) {
|
if (!hasUserKey) {
|
||||||
|
this.logService.info("Attempting to set user key with device key.");
|
||||||
|
|
||||||
await this.trySetUserKeyWithDeviceKey(tokenResponse, userId);
|
await this.trySetUserKeyWithDeviceKey(tokenResponse, userId);
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
@@ -275,11 +285,27 @@ export class SsoLoginStrategy extends LoginStrategy {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const trustedDeviceOption = tokenResponse.userDecryptionOptions?.trustedDeviceOption;
|
const trustedDeviceOption = tokenResponse.userDecryptionOptions?.trustedDeviceOption;
|
||||||
|
|
||||||
|
if (!trustedDeviceOption) {
|
||||||
|
this.logService.error("Unable to set user key due to missing trustedDeviceOption.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const deviceKey = await this.deviceTrustService.getDeviceKey(userId);
|
const deviceKey = await this.deviceTrustService.getDeviceKey(userId);
|
||||||
const encDevicePrivateKey = trustedDeviceOption?.encryptedPrivateKey;
|
const encDevicePrivateKey = trustedDeviceOption?.encryptedPrivateKey;
|
||||||
const encUserKey = trustedDeviceOption?.encryptedUserKey;
|
const encUserKey = trustedDeviceOption?.encryptedUserKey;
|
||||||
|
|
||||||
if (!deviceKey || !encDevicePrivateKey || !encUserKey) {
|
if (!deviceKey || !encDevicePrivateKey || !encUserKey) {
|
||||||
|
if (!deviceKey) {
|
||||||
|
await this.logService.warning("Unable to set user key due to missing device key.");
|
||||||
|
}
|
||||||
|
if (!encDevicePrivateKey) {
|
||||||
|
await this.logService.warning(
|
||||||
|
"Unable to set user key due to missing encrypted device private key.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!encUserKey) {
|
||||||
|
await this.logService.warning("Unable to set user key due to missing encrypted user key.");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user