mirror of
https://github.com/bitwarden/browser
synced 2026-02-24 08:33:29 +00:00
* feat(user-decryption-options) [PM-26413]: Update UserDecryptionOptionsService and tests to use UserId-only APIs. * feat(user-decryption-options) [PM-26413]: Update InternalUserDecryptionOptionsService call sites to use UserId-only API. * feat(user-decryption-options) [PM-26413] Update userDecryptionOptions$ call sites to use the UserId-only API. * feat(user-decryption-options) [PM-26413]: Update additional call sites. * feat(user-decryption-options) [PM-26413]: Update dependencies and an additional call site. * feat(user-verification-service) [PM-26413]: Replace where allowed by unrestricted imports invocation of UserVerificationService.hasMasterPassword (deprecated) with UserDecryptionOptions.hasMasterPasswordById$. Additional work to complete as tech debt tracked in PM-27009. * feat(user-decryption-options) [PM-26413]: Update for non-null strict adherence. * feat(user-decryption-options) [PM-26413]: Update type safety and defensive returns. * chore(user-decryption-options) [PM-26413]: Comment cleanup. * feat(user-decryption-options) [PM-26413]: Update tests. * feat(user-decryption-options) [PM-26413]: Standardize null-checking on active account id for new API consumption. * feat(vault-timeout-settings-service) [PM-26413]: Add test cases to illustrate null active account from AccountService. * fix(fido2-user-verification-service-spec) [PM-26413]: Update test harness to use FakeAccountService. * fix(downstream-components) [PM-26413]: Prefer use of the getUserId operator in all authenticated contexts for user id provided to UserDecryptionOptionsService. --------- Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com>
101 lines
3.8 KiB
TypeScript
101 lines
3.8 KiB
TypeScript
import { Component, OnInit, OnDestroy } from "@angular/core";
|
|
import { firstValueFrom, lastValueFrom, map, Observable, Subject, takeUntil } from "rxjs";
|
|
|
|
import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common";
|
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
|
import { DialogService } from "@bitwarden/components";
|
|
|
|
import { HeaderModule } from "../../../layouts/header/header.module";
|
|
import { SharedModule } from "../../../shared";
|
|
import { PurgeVaultComponent } from "../../../vault/settings/purge-vault.component";
|
|
|
|
import { ChangeEmailComponent } from "./change-email.component";
|
|
import { DangerZoneComponent } from "./danger-zone.component";
|
|
import { DeauthorizeSessionsComponent } from "./deauthorize-sessions.component";
|
|
import { DeleteAccountDialogComponent } from "./delete-account-dialog.component";
|
|
import { ProfileComponent } from "./profile.component";
|
|
import { SetAccountVerifyDevicesDialogComponent } from "./set-account-verify-devices-dialog.component";
|
|
|
|
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
|
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
|
@Component({
|
|
templateUrl: "account.component.html",
|
|
imports: [
|
|
SharedModule,
|
|
HeaderModule,
|
|
ProfileComponent,
|
|
ChangeEmailComponent,
|
|
DangerZoneComponent,
|
|
],
|
|
})
|
|
export class AccountComponent implements OnInit, OnDestroy {
|
|
private destroy$ = new Subject<void>();
|
|
|
|
showChangeEmail$: Observable<boolean> = new Observable();
|
|
showPurgeVault$: Observable<boolean> = new Observable();
|
|
showDeleteAccount$: Observable<boolean> = new Observable();
|
|
verifyNewDeviceLogin: boolean = true;
|
|
|
|
constructor(
|
|
private accountService: AccountService,
|
|
private dialogService: DialogService,
|
|
private userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
|
private organizationService: OrganizationService,
|
|
) {}
|
|
|
|
async ngOnInit() {
|
|
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
|
|
|
const userIsManagedByOrganization$ = this.organizationService
|
|
.organizations$(userId)
|
|
.pipe(
|
|
map((organizations) => organizations.some((o) => o.userIsManagedByOrganization === true)),
|
|
);
|
|
|
|
const hasMasterPassword$ = this.userDecryptionOptionsService.hasMasterPasswordById$(userId);
|
|
|
|
this.showChangeEmail$ = hasMasterPassword$;
|
|
|
|
this.showPurgeVault$ = userIsManagedByOrganization$.pipe(
|
|
map((userIsManagedByOrganization) => !userIsManagedByOrganization),
|
|
);
|
|
|
|
this.showDeleteAccount$ = userIsManagedByOrganization$.pipe(
|
|
map((userIsManagedByOrganization) => !userIsManagedByOrganization),
|
|
);
|
|
|
|
this.accountService.accountVerifyNewDeviceLogin$
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe((verifyDevices) => {
|
|
this.verifyNewDeviceLogin = verifyDevices;
|
|
});
|
|
}
|
|
|
|
deauthorizeSessions = async () => {
|
|
const dialogRef = DeauthorizeSessionsComponent.open(this.dialogService);
|
|
await lastValueFrom(dialogRef.closed);
|
|
};
|
|
|
|
purgeVault = async () => {
|
|
const dialogRef = PurgeVaultComponent.open(this.dialogService);
|
|
await lastValueFrom(dialogRef.closed);
|
|
};
|
|
|
|
deleteAccount = async () => {
|
|
const dialogRef = DeleteAccountDialogComponent.open(this.dialogService);
|
|
await lastValueFrom(dialogRef.closed);
|
|
};
|
|
|
|
setNewDeviceLoginProtection = async () => {
|
|
const dialogRef = SetAccountVerifyDevicesDialogComponent.open(this.dialogService);
|
|
await lastValueFrom(dialogRef.closed);
|
|
};
|
|
|
|
ngOnDestroy() {
|
|
this.destroy$.next();
|
|
this.destroy$.complete();
|
|
}
|
|
}
|