1
0
mirror of https://github.com/bitwarden/browser synced 2026-03-02 11:31:44 +00:00
Files
browser/libs/common/src/key-management/services/default-process-reload.service.ts
Bernd Schoolmann 3125f679d3 [PM-25206] Inject service instead of passing as param (#16801)
* Inject service instead of passing as param

* [PM-25206] Move locking logic to LockService (#16802)

* Move locking logic to lock service

* Fix tests

* Fix CLI

* Fix test

* FIx safari build

* Update call to lock service

* Remove locked callback

* Clean up lock service logic

* Add tests

* Fix cli build

* Add extension lock service

* Fix cli build

* Fix build

* Undo ac changes

* Undo ac changes

* Run prettier

* Fix build

* Remove duplicate call

* [PM-25206] Remove VaultTimeoutService lock logic (#16804)

* Move consumers off of vaulttimeoutsettingsservice lock

* Fix build

* Fix build

* Fix build

* Fix firefox build

* Fix test

* Fix ts strict errors

* Fix ts strict error

* Undo AC changes

* Cleanup

* Fix

* Fix missing service
2025-11-05 17:11:34 +01:00

126 lines
4.6 KiB
TypeScript

// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { firstValueFrom, map, timeout } from "rxjs";
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports
import { BiometricStateService } from "@bitwarden/key-management";
import { AccountService } from "../../auth/abstractions/account.service";
import { AuthService } from "../../auth/abstractions/auth.service";
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
import {
VaultTimeoutAction,
VaultTimeoutSettingsService,
} from "../../key-management/vault-timeout";
import { LogService } from "../../platform/abstractions/log.service";
import { MessagingService } from "../../platform/abstractions/messaging.service";
import { UserId } from "../../types/guid";
import { ProcessReloadServiceAbstraction } from "../abstractions/process-reload.service";
import { PinServiceAbstraction } from "../pin/pin.service.abstraction";
export class DefaultProcessReloadService implements ProcessReloadServiceAbstraction {
private reloadInterval: any = null;
constructor(
private pinService: PinServiceAbstraction,
private messagingService: MessagingService,
private reloadCallback: () => Promise<void> = null,
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
private biometricStateService: BiometricStateService,
private accountService: AccountService,
private logService: LogService,
private authService: AuthService,
) {}
async startProcessReload(): Promise<void> {
const accounts = await firstValueFrom(this.accountService.accounts$);
if (accounts != null) {
const keys = Object.keys(accounts);
if (keys.length > 0) {
for (const userId of keys) {
let status = await firstValueFrom(this.authService.authStatusFor$(userId as UserId));
status = await this.authService.getAuthStatus(userId);
if (status === AuthenticationStatus.Unlocked) {
this.logService.info(
"[Process Reload Service] User unlocked, preventing process reload",
);
return;
}
}
}
}
// A reloadInterval has already been set and is executing
if (this.reloadInterval != null) {
return;
}
// If there is an active user, check if they have a pinKeyEncryptedUserKeyEphemeral. If so, prevent process reload upon lock.
const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id;
if (userId != null) {
if ((await this.pinService.getPinLockType(userId)) === "EPHEMERAL") {
this.logService.info(
"[Process Reload Service] Ephemeral pin active, preventing process reload",
);
return;
}
}
this.cancelProcessReload();
await this.executeProcessReload();
}
private async executeProcessReload() {
const biometricLockedFingerprintValidated = await firstValueFrom(
this.biometricStateService.fingerprintValidated$,
);
if (!biometricLockedFingerprintValidated) {
clearInterval(this.reloadInterval);
this.reloadInterval = null;
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(
map((a) => a?.id),
timeout(500),
),
);
// Replace current active user if they will be logged out on reload
if (activeUserId != null) {
const timeoutAction = await firstValueFrom(
this.vaultTimeoutSettingsService
.getVaultTimeoutActionByUserId$(activeUserId)
.pipe(timeout(500)), // safety feature to avoid this call hanging and stopping process reload from clearing memory
);
if (timeoutAction === VaultTimeoutAction.LogOut) {
const nextUser = await firstValueFrom(
this.accountService.nextUpAccount$.pipe(map((account) => account?.id ?? null)),
);
await this.accountService.switchAccount(nextUser);
}
}
this.messagingService.send("reloadProcess");
if (this.reloadCallback != null) {
await this.reloadCallback();
}
return;
} else {
this.logService.info(
"[Process Reload Service] Desktop ipc fingerprint validated, preventing process reload",
);
}
if (this.reloadInterval == null) {
this.reloadInterval = setInterval(async () => await this.executeProcessReload(), 1000);
}
}
cancelProcessReload(): void {
if (this.reloadInterval != null) {
clearInterval(this.reloadInterval);
this.reloadInterval = null;
}
}
}