1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 00:03:56 +00:00

[PM-6426] Create TaskSchedulerService and update long lived timeouts in the extension to leverage the new service (#8566)

* [PM-6426] Create TaskSchedulerService and update usage of long lived timeouts

* [PM-6426] Implementing nextSync timeout using TaskScheduler

* [PM-6426] Implementing systemClearClipboard using TaskScheduler

* [PM-6426] Fixing race condition with setting/unsetting active alarms

* [PM-6426] Implementing clear clipboard call on generatePasswordToClipboard with the TaskSchedulerService

* [PM-6426] Implementing abortTimeout for Fido2ClientService using TaskSchedulerService

* [PM-6426] Implementing reconnect timer timeout for NotificationService using the TaskSchedulerService

* [PM-6426] Implementing reconnect timer timeout for NotificationService using the TaskSchedulerService

* [PM-6426] Implementing sessionTimeout for LoginStrategyService using TaskSchedulerService

* [PM-6426] Implementing eventUploadInterval using TaskScheduler

* [PM-6426] Adding jest tests for the base TaskSchedulerService class

* [PM-6426] Updating jest tests for GeneratePasswordToClipboardCommand

* [PM-6426] Setting up the full sync process as an interval rather than a timeout

* [PM-6426] Renaming the scheduleNextSync alarm name

* [PM-6426] Fixing dependency references in services.module.ts

* [PM-6426] Adding jest tests for added BrowserApi methods

* [PM-6426] Refactoring small detail for how we identify the clear clipboard timeout in SystemService

* [PM-6426] Ensuring that we await clearing an established scheduled task for the notification service

* [PM-6426] Changing the name of the state definition for the TaskScheduler

* [PM-6426] Implementing jest tests for the BrowserTaskSchedulerService

* [PM-6426] Implementing jest tests for the BrowserTaskSchedulerService

* [PM-6426] Adding jest tests for the base TaskSchedulerService class

* [PM-6426] Finalizing jest tests for BrowserTaskScheduler class

* [PM-6426] Finalizing documentation on BrowserTaskSchedulerService

* [PM-6426] Fixing jest test for LoginStrategyService

* [PM-6426] Implementing compatibility for the browser.alarms api

* [PM-6426] Fixing how we check for the browser alarms api

* [PM-6426] Adding jest tests to the BrowserApi implementation

* [PM-6426] Aligning the implementation with our code guidelines for Angular components

* [PM-6426] Fixing jest tests and lint errors

* [PM-6426] Moving alarms api calls out of BrowserApi and structuring them within the BrowserTaskSchedulerService

* [PM-6426] Reworking implementation to register handlers separately from the call to those handlers

* [PM-6426] Adjusting how we register the fullSync scheduled task

* [PM-6426] Implementing approach for incorporating the user UUID when setting task handlers

* [PM-6426] Attempting to re-work implementation to facilitate userId-spcific alarms

* [PM-6426] Refactoring smaller details of the implementation

* [PM-6426] Working through the details of the implementation and setting up final refinments

* [PM-6426] Fixing some issues surrounding duplicate alarms triggering

* [PM-6426] Adjusting name for generate password to clipboard command task name

* [PM-6426] Fixing generate password to clipboard command jest tests

* [PM-6426] Working through jest tests and implementing a method to guard against setting a task without having a registered callback

* [PM-6426] Working through jest tests and implementing a method to guard against setting a task without having a registered callback

* [PM-6426] Implementing methodology for having a fallback to setTimeout if the browser context is lost in some manner

* [PM-6426] Working through jest tests

* [PM-6426] Working through jest tests

* [PM-6426] Working through jest tests

* [PM-6426] Working through jest tests

* [PM-6426] Finalizing stepped setInterval implementation

* [PM-6426] Implementing Jest tests for DefaultTaskSchedulerService

* [PM-6426] Adjusting jest tests

* [PM-6426] Adjusting jest tests

* [PM-6426] Adjusting jest tests

* [PM-6426] Fixing issues identified in code review

* [PM-6426] Fixing issues identified in code review

* [PM-6426] Removing user-based alarms and fixing an issue found with setting steppedd alarm interavals

* [PM-6426] Removing user-based alarms and fixing an issue found with setting steppedd alarm interavals

* [PM-6426] Fixing issue with typing information on a test

* [PM-6426] Using the getUpperBoundDelayInMinutes method to handle setting stepped alarms and setTimeout fallbacks

* [PM-6426] Removing the potential for the TaskScheduler to be optional

* [PM-6426] Reworking implementation to leverage subscription based deregistration of alarms

* [PM-6426] Fixing jest tests

* [PM-6426] Implementing foreground and background task scheduler services to avoid duplication of task scheudlers and to have the background setup as a fallback to the poopup tasks

* [PM-6426] Implementing foreground and background task scheduler services to avoid duplication of task scheudlers and to have the background setup as a fallback to the poopup tasks

* [PM-6426] Merging main into branch

* [PM-6426] Fixing issues with the CLI Service Container implementation

* [PM-6426] Reworking swallowed promises to contain a catch statement allow us to debug potential issues with registrations of alarms

* [PM-6426] Adding jest tests to the ForegroundTaskSchedulerService and the BackgroundTaskSchedulerService

* [PM-6426] Adding jest tests to the ForegroundTaskSchedulerService and the BackgroundTaskSchedulerService

* [PM-6426] Adding jest tests to the ForegroundTaskSchedulerService and the BackgroundTaskSchedulerService

* [PM-6426] Adding jest tests to the ForegroundTaskSchedulerService and the BackgroundTaskSchedulerService

* [PM-6426] Adjusting implementation based on code review feedback

* [PM-6426] Reworking file structure

* [PM-6426] Reworking file structure

* [PM-6426] Adding comments to provide clarity on how the login strategy cache experiation state is used

* [PM-6426] Catching and logging erorrs that appear from methods that return a promise within VaultTimeoutService
This commit is contained in:
Cesar Gonzalez
2024-07-15 10:32:30 -05:00
committed by GitHub
parent 5fcf4bbd10
commit 974162b1a4
39 changed files with 1854 additions and 283 deletions

View File

@@ -27,6 +27,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { KdfType } from "@bitwarden/common/platform/enums";
import { TaskSchedulerService } from "@bitwarden/common/platform/scheduling";
import {
FakeAccountService,
FakeGlobalState,
@@ -72,6 +73,7 @@ describe("LoginStrategyService", () => {
let billingAccountProfileStateService: MockProxy<BillingAccountProfileStateService>;
let vaultTimeoutSettingsService: MockProxy<VaultTimeoutSettingsService>;
let kdfConfigService: MockProxy<KdfConfigService>;
let taskSchedulerService: MockProxy<TaskSchedulerService>;
let stateProvider: FakeGlobalStateProvider;
let loginStrategyCacheExpirationState: FakeGlobalState<Date | null>;
@@ -103,6 +105,7 @@ describe("LoginStrategyService", () => {
stateProvider = new FakeGlobalStateProvider();
vaultTimeoutSettingsService = mock<VaultTimeoutSettingsService>();
kdfConfigService = mock<KdfConfigService>();
taskSchedulerService = mock<TaskSchedulerService>();
sut = new LoginStrategyService(
accountService,
@@ -129,6 +132,7 @@ describe("LoginStrategyService", () => {
billingAccountProfileStateService,
vaultTimeoutSettingsService,
kdfConfigService,
taskSchedulerService,
);
loginStrategyCacheExpirationState = stateProvider.getFake(CACHE_EXPIRATION_KEY);

View File

@@ -5,6 +5,7 @@ import {
map,
Observable,
shareReplay,
Subscription,
} from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@@ -37,6 +38,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { KdfType } from "@bitwarden/common/platform/enums/kdf-type.enum";
import { TaskSchedulerService, ScheduledTaskNames } from "@bitwarden/common/platform/scheduling";
import { GlobalState, GlobalStateProvider } from "@bitwarden/common/platform/state";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction";
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
@@ -69,7 +71,7 @@ import {
const sessionTimeoutLength = 2 * 60 * 1000; // 2 minutes
export class LoginStrategyService implements LoginStrategyServiceAbstraction {
private sessionTimeout: unknown;
private sessionTimeoutSubscription: Subscription;
private currentAuthnTypeState: GlobalState<AuthenticationType | null>;
private loginStrategyCacheState: GlobalState<CacheData | null>;
private loginStrategyCacheExpirationState: GlobalState<Date | null>;
@@ -111,6 +113,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
protected billingAccountProfileStateService: BillingAccountProfileStateService,
protected vaultTimeoutSettingsService: VaultTimeoutSettingsService,
protected kdfConfigService: KdfConfigService,
protected taskSchedulerService: TaskSchedulerService,
) {
this.currentAuthnTypeState = this.stateProvider.get(CURRENT_LOGIN_STRATEGY_KEY);
this.loginStrategyCacheState = this.stateProvider.get(CACHE_KEY);
@@ -118,6 +121,10 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
this.authRequestPushNotificationState = this.stateProvider.get(
AUTH_REQUEST_PUSH_NOTIFICATION_KEY,
);
this.taskSchedulerService.registerTaskHandler(
ScheduledTaskNames.loginStrategySessionTimeout,
() => this.clearCache(),
);
this.currentAuthType$ = this.currentAuthnTypeState.state$;
this.loginStrategy$ = this.currentAuthnTypeState.state$.pipe(
@@ -268,15 +275,23 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
private async startSessionTimeout(): Promise<void> {
await this.clearSessionTimeout();
// This Login Strategy Cache Expiration State value set here is used to clear the cache on re-init
// of the application in the case where the timeout is terminated due to a closure of the application
// window. The browser extension popup in particular is susceptible to this concern, as the user
// is almost always likely to close the popup window before the session timeout is reached.
await this.loginStrategyCacheExpirationState.update(
(_) => new Date(Date.now() + sessionTimeoutLength),
);
this.sessionTimeout = setTimeout(() => this.clearCache(), sessionTimeoutLength);
this.sessionTimeoutSubscription = this.taskSchedulerService.setTimeout(
ScheduledTaskNames.loginStrategySessionTimeout,
sessionTimeoutLength,
);
}
private async clearSessionTimeout(): Promise<void> {
await this.loginStrategyCacheExpirationState.update((_) => null);
this.sessionTimeout = null;
this.sessionTimeoutSubscription?.unsubscribe();
}
private async isSessionValid(): Promise<boolean> {
@@ -284,6 +299,9 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
if (cache == null) {
return false;
}
// If the Login Strategy Cache Expiration State value is less than the current
// datetime stamp, then the cache is invalid and should be cleared.
const expiration = await firstValueFrom(this.loginStrategyCacheExpirationState.state$);
if (expiration != null && expiration < new Date()) {
await this.clearCache();