1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-02-19 01:51:27 +01:00

PM-3369 - TDE - Persist user's choice to trust device to state when user ma… (#6000)

* PM-3369 - Persist user's choice to trust device to state when user makes choice + persist previous choices out of state

* PM-3369 - Must set trust device in state on load if it's never been set before

* PM-3369 - Refactor BaseLoginDecOptions to properly set trust device choice in state on load

* Update libs/angular/src/auth/components/base-login-decryption-options.component.ts

Co-authored-by: Jake Fink <jfink@bitwarden.com>

---------

Co-authored-by: Jake Fink <jfink@bitwarden.com>
This commit is contained in:
Jared Snider 2023-08-10 13:15:57 -04:00 committed by GitHub
parent ab11de9883
commit 2fe93e37df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 10 deletions

View File

@ -93,11 +93,15 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
async ngOnInit() {
this.loading = true;
this.setupRememberDeviceValueChanges();
// Persist user choice from state if it exists
await this.setRememberDeviceDefaultValue();
try {
const accountDecryptionOptions: AccountDecryptionOptions =
await this.stateService.getAccountDecryptionOptions();
// TODO: verify that this doesn't also pick up key connector users... can key connector users even get here?
// see sso-login.strategy - to determine if a user is new or not it just checks if there is a key on the token response..
// can we check if they have a user key or master key in crypto service? Would that be sufficient?
if (
@ -108,8 +112,6 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
// - User does not have admin approval (i.e. has not enrolled into admin reset)
// - AND does not have a master password
// TODO: discuss how this doesn't make any sense to show here
this.loadNewUserData();
} else {
this.loadUntrustedDeviceData(accountDecryptionOptions);
@ -138,6 +140,25 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
}
}
private async setRememberDeviceDefaultValue() {
const rememberDeviceFromState = await this.deviceTrustCryptoService.getShouldTrustDevice();
const rememberDevice = rememberDeviceFromState ?? true;
this.rememberDevice.setValue(rememberDevice);
}
private setupRememberDeviceValueChanges() {
this.rememberDevice.valueChanges
.pipe(
switchMap((value) =>
defer(() => this.deviceTrustCryptoService.setShouldTrustDevice(value))
),
takeUntil(this.destroy$)
)
.subscribe();
}
async loadNewUserData() {
const autoEnrollStatus$ = defer(() =>
this.stateService.getUserSsoOrganizationIdentifier()
@ -215,20 +236,16 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
return;
}
await this.deviceTrustCryptoService.setShouldTrustDevice(this.rememberDevice.value);
this.loginService.setEmail(this.data.userEmail);
this.router.navigate(["/login-with-device"]);
}
async requestAdminApproval() {
await this.deviceTrustCryptoService.setShouldTrustDevice(this.rememberDevice.value);
this.loginService.setEmail(this.data.userEmail);
this.router.navigate(["/admin-approval-requested"]);
}
async approveWithMasterPassword() {
await this.deviceTrustCryptoService.setShouldTrustDevice(this.rememberDevice.value);
this.router.navigate(["/lock"], { queryParams: { from: "login-initiated" } });
}

View File

@ -7,7 +7,7 @@ export abstract class DeviceTrustCryptoServiceAbstraction {
* @description Retrieves the users choice to trust the device which can only happen after decryption
* Note: this value should only be used once and then reset
*/
getShouldTrustDevice: () => Promise<boolean>;
getShouldTrustDevice: () => Promise<boolean | null>;
setShouldTrustDevice: (value: boolean) => Promise<void>;
trustDeviceIfRequired: () => Promise<void>;

View File

@ -1367,7 +1367,7 @@ export class StateService<
await this.saveAccount(account, options);
}
async getShouldTrustDevice(options?: StorageOptions): Promise<boolean> {
async getShouldTrustDevice(options?: StorageOptions): Promise<boolean | null> {
options = this.reconcileOptions(options, await this.defaultOnDiskLocalOptions());
if (options?.userId == null) {
@ -1376,7 +1376,7 @@ export class StateService<
const account = await this.getAccount(options);
return account?.settings?.trustDeviceChoiceForDecryption ?? false;
return account?.settings?.trustDeviceChoiceForDecryption ?? null;
}
async setShouldTrustDevice(value: boolean, options?: StorageOptions): Promise<void> {