clients/apps/browser/src/background/idle.background.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

95 lines
3.3 KiB
TypeScript

import { firstValueFrom } from "rxjs";
import { LockService, LogoutService } from "@bitwarden/auth/common";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import {
VaultTimeoutAction,
VaultTimeoutService,
VaultTimeoutSettingsService,
VaultTimeoutStringType,
} from "@bitwarden/common/key-management/vault-timeout";
import { ServerNotificationsService } from "@bitwarden/common/platform/server-notifications";
import { UserId } from "@bitwarden/user-core";
const IdleInterval = 60 * 5; // 5 minutes
export default class IdleBackground {
private idle: typeof chrome.idle | typeof browser.idle | null;
private idleTimer: null | number | NodeJS.Timeout = null;
private idleState = "active";
constructor(
private vaultTimeoutService: VaultTimeoutService,
private serverNotificationsService: ServerNotificationsService,
private accountService: AccountService,
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
private lockService: LockService,
private logoutService: LogoutService,
) {
this.idle = chrome.idle || (browser != null ? browser.idle : null);
}
init() {
if (!this.idle) {
return;
}
const idleHandler = (newState: string) => {
if (newState === "active") {
this.serverNotificationsService.reconnectFromActivity();
} else {
this.serverNotificationsService.disconnectFromInactivity();
}
};
if (this.idle.onStateChanged && this.idle.setDetectionInterval) {
this.idle.setDetectionInterval(IdleInterval);
this.idle.onStateChanged.addListener(idleHandler);
} else {
this.pollIdle(idleHandler);
}
if (this.idle.onStateChanged) {
this.idle.onStateChanged.addListener(
async (newState: `${chrome.idle.IdleState}` | browser.idle.IdleState) => {
if (newState === "locked") {
// Need to check if any of the current users have their timeout set to `onLocked`
const allUsers = await firstValueFrom(this.accountService.accounts$);
for (const userId in allUsers) {
// If the screen is locked or the screensaver activates
const timeout = await firstValueFrom(
this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(userId),
);
if (timeout === VaultTimeoutStringType.OnLocked) {
// On System Lock vault timeout option
const action = await firstValueFrom(
this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(userId),
);
if (action === VaultTimeoutAction.LogOut) {
await this.logoutService.logout(userId as UserId, "vaultTimeout");
} else {
await this.lockService.lock(userId as UserId);
}
}
}
}
},
);
}
}
private pollIdle(handler: (newState: string) => void) {
if (this.idleTimer != null) {
globalThis.clearTimeout(this.idleTimer);
this.idleTimer = null;
}
void this.idle?.queryState(IdleInterval, (state: string) => {
if (state !== this.idleState) {
this.idleState = state;
handler(state);
}
this.idleTimer = globalThis.setTimeout(() => this.pollIdle(handler), 5000);
});
}
}