diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 1487fdd5a9..340b7c39f2 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -850,6 +850,7 @@ export default class MainBackground { this.autofillSettingsService, this.vaultTimeoutSettingsService, this.biometricStateService, + this.taskSchedulerService, ); // Other fields diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index fbeabca462..21fced2e1a 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -66,6 +66,7 @@ import { GlobalState } from "@bitwarden/common/platform/models/domain/global-sta import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; import { ContainerService } from "@bitwarden/common/platform/services/container.service"; import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner"; +import { TaskSchedulerService } from "@bitwarden/common/platform/services/task-scheduler.service"; import { WebCryptoFunctionService } from "@bitwarden/common/platform/services/web-crypto-function.service"; import { DerivedStateProvider, @@ -97,6 +98,7 @@ import BrowserLocalStorageService from "../../platform/services/browser-local-st import BrowserMessagingPrivateModePopupService from "../../platform/services/browser-messaging-private-mode-popup.service"; import BrowserMessagingService from "../../platform/services/browser-messaging.service"; import { BrowserStateService } from "../../platform/services/browser-state.service"; +import { BrowserTaskSchedulerService } from "../../platform/services/browser-task-scheduler.service"; import I18nService from "../../platform/services/i18n.service"; import { ForegroundPlatformUtilsService } from "../../platform/services/platform-utils/foreground-platform-utils.service"; import { ForegroundDerivedStateProvider } from "../../platform/state/foreground-derived-state.provider"; @@ -464,6 +466,14 @@ const safeProviders: SafeProvider[] = [ useClass: UserNotificationSettingsService, deps: [StateProvider], }), + safeProvider({ + provide: TaskSchedulerService, + useExisting: BrowserTaskSchedulerService, + }), + safeProvider({ + provide: BrowserTaskSchedulerService, + deps: [LogService, StateProvider], + }), ]; @NgModule({ diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 84932ce7d9..3b38092bd7 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -45,6 +45,7 @@ import { GlobalState } from "@bitwarden/common/platform/models/domain/global-sta import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service"; import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner"; import { SystemService } from "@bitwarden/common/platform/services/system.service"; +import { TaskSchedulerService } from "@bitwarden/common/platform/services/task-scheduler.service"; import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/state"; // eslint-disable-next-line import/no-restricted-paths -- Implementation for memory storage import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service"; @@ -168,6 +169,7 @@ const safeProviders: SafeProvider[] = [ AutofillSettingsServiceAbstraction, VaultTimeoutSettingsService, BiometricStateService, + TaskSchedulerService, ], }), safeProvider({ @@ -247,6 +249,10 @@ const safeProviders: SafeProvider[] = [ provide: DesktopAutofillSettingsService, deps: [StateProvider], }), + safeProvider({ + provide: TaskSchedulerService, + deps: [], + }), ]; @NgModule({ diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index a31d5141c4..c9c888a009 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -147,6 +147,7 @@ import { MigrationRunner } from "@bitwarden/common/platform/services/migration-r import { NoopNotificationsService } from "@bitwarden/common/platform/services/noop-notifications.service"; import { StateService } from "@bitwarden/common/platform/services/state.service"; import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider"; +import { TaskSchedulerService } from "@bitwarden/common/platform/services/task-scheduler.service"; import { ValidationService } from "@bitwarden/common/platform/services/validation.service"; import { WebCryptoFunctionService } from "@bitwarden/common/platform/services/web-crypto-function.service"; import { @@ -1069,6 +1070,10 @@ const safeProviders: SafeProvider[] = [ useClass: DefaultOrganizationManagementPreferencesService, deps: [StateProvider], }), + safeProvider({ + provide: TaskSchedulerService, + deps: [], + }), ]; function encryptServiceFactory( diff --git a/libs/common/src/platform/services/system.service.ts b/libs/common/src/platform/services/system.service.ts index d19390c45e..dc20beef82 100644 --- a/libs/common/src/platform/services/system.service.ts +++ b/libs/common/src/platform/services/system.service.ts @@ -9,7 +9,9 @@ import { MessagingService } from "../abstractions/messaging.service"; import { PlatformUtilsService } from "../abstractions/platform-utils.service"; import { StateService } from "../abstractions/state.service"; import { SystemService as SystemServiceAbstraction } from "../abstractions/system.service"; +import { TaskSchedulerService } from "../abstractions/task-scheduler.service"; import { BiometricStateService } from "../biometrics/biometric-state.service"; +import { ScheduledTaskNames } from "../enums/scheduled-task-name.enum"; import { Utils } from "../misc/utils"; export class SystemService implements SystemServiceAbstraction { @@ -25,6 +27,7 @@ export class SystemService implements SystemServiceAbstraction { private autofillSettingsService: AutofillSettingsServiceAbstraction, private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private biometricStateService: BiometricStateService, + private taskSchedulerService: TaskSchedulerService, ) {} async startProcessReload(authService: AuthService): Promise { @@ -94,25 +97,25 @@ export class SystemService implements SystemServiceAbstraction { } async clearClipboard(clipboardValue: string, timeoutMs: number = null): Promise { - if (this.clearClipboardTimeout != null) { - clearTimeout(this.clearClipboardTimeout); - this.clearClipboardTimeout = null; - } + let taskTimeoutInMs = timeoutMs; + await this.taskSchedulerService.clearScheduledTask({ + taskName: ScheduledTaskNames.systemClearClipboardTimeout, + timeoutId: this.clearClipboardTimeout, + }); if (Utils.isNullOrWhitespace(clipboardValue)) { return; } - const clearClipboardDelay = await firstValueFrom( - this.autofillSettingsService.clearClipboardDelay$, - ); - - if (clearClipboardDelay == null) { - return; + if (!taskTimeoutInMs) { + const clearClipboardDelayInSeconds = await firstValueFrom( + this.autofillSettingsService.clearClipboardDelay$, + ); + taskTimeoutInMs = clearClipboardDelayInSeconds ? clearClipboardDelayInSeconds * 1000 : null; } - if (timeoutMs == null) { - timeoutMs = clearClipboardDelay * 1000; + if (!taskTimeoutInMs) { + return; } this.clearClipboardTimeoutFunction = async () => { @@ -122,9 +125,11 @@ export class SystemService implements SystemServiceAbstraction { } }; - this.clearClipboardTimeout = setTimeout(async () => { - await this.clearPendingClipboard(); - }, timeoutMs); + this.clearClipboardTimeout = this.taskSchedulerService.setTimeout( + () => this.clearPendingClipboard(), + taskTimeoutInMs, + ScheduledTaskNames.systemClearClipboardTimeout, + ); } async clearPendingClipboard() {