1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-08-27 23:31:41 +02:00

[PM-6426] Implementing sessionTimeout for LoginStrategyService using TaskSchedulerService

This commit is contained in:
Cesar Gonzalez 2024-04-01 12:08:16 -05:00
parent 1965d0e048
commit 752df0612d
No known key found for this signature in database
GPG Key ID: 3381A5457F8CCECF
7 changed files with 30 additions and 12 deletions

View File

@ -54,6 +54,10 @@ import {
stateServiceFactory,
StateServiceInitOptions,
} from "../../../platform/background/service-factories/state-service.factory";
import {
taskSchedulerServiceFactory,
TaskSchedulerServiceInitOptions,
} from "../../../platform/background/service-factories/task-scheduler-service.factory";
import {
passwordStrengthServiceFactory,
PasswordStrengthServiceInitOptions,
@ -99,7 +103,8 @@ export type LoginStrategyServiceInitOptions = LoginStrategyServiceFactoryOptions
AuthRequestServiceInitOptions &
UserDecryptionOptionsServiceInitOptions &
GlobalStateProviderInitOptions &
BillingAccountProfileStateServiceInitOptions;
BillingAccountProfileStateServiceInitOptions &
TaskSchedulerServiceInitOptions;
export function loginStrategyServiceFactory(
cache: { loginStrategyService?: LoginStrategyServiceAbstraction } & CachedServices,
@ -131,6 +136,7 @@ export function loginStrategyServiceFactory(
await internalUserDecryptionOptionServiceFactory(cache, opts),
await globalStateProviderFactory(cache, opts),
await billingAccountProfileStateServiceFactory(cache, opts),
await taskSchedulerServiceFactory(cache, opts),
),
);
}

View File

@ -36,9 +36,9 @@ import { openUnlockPopout } from "../../auth/popup/utils/auth-popout-window";
import { autofillSettingsServiceFactory } from "../../autofill/background/service_factories/autofill-settings-service.factory";
import { eventCollectionServiceFactory } from "../../background/service-factories/event-collection-service.factory";
import { Account } from "../../models/account";
import { browserTaskSchedulerServiceFactory } from "../../platform/background/service-factories/browser-task-scheduler-service.factory";
import { CachedServices } from "../../platform/background/service-factories/factory-options";
import { stateServiceFactory } from "../../platform/background/service-factories/state-service.factory";
import { taskSchedulerServiceFactory } from "../../platform/background/service-factories/task-scheduler-service.factory";
import { BrowserApi } from "../../platform/browser/browser-api";
import { passwordGenerationServiceFactory } from "../../tools/background/service_factories/password-generation-service.factory";
import {
@ -117,7 +117,7 @@ export class ContextMenuClickedHandler {
const generatePasswordToClipboardCommand = new GeneratePasswordToClipboardCommand(
await passwordGenerationServiceFactory(cachedServices, serviceOptions),
await autofillSettingsServiceFactory(cachedServices, serviceOptions),
await browserTaskSchedulerServiceFactory(cachedServices, serviceOptions),
await taskSchedulerServiceFactory(cachedServices, serviceOptions),
);
const autofillCommand = new AutofillTabCommand(

View File

@ -613,6 +613,7 @@ export default class MainBackground {
this.userDecryptionOptionsService,
this.globalStateProvider,
this.billingAccountProfileStateService,
this.taskSchedulerService,
);
this.ssoLoginService = new SsoLoginService(this.stateProvider);

View File

@ -4,15 +4,15 @@ import { CachedServices, factory, FactoryOptions } from "./factory-options";
import { logServiceFactory, LogServiceInitOptions } from "./log-service.factory";
import { stateProviderFactory, StateProviderInitOptions } from "./state-provider.factory";
type BrowserTaskSchedulerServiceFactoryOptions = FactoryOptions;
type TaskSchedulerServiceFactoryOptions = FactoryOptions;
export type BrowserTaskSchedulerServiceInitOptions = BrowserTaskSchedulerServiceFactoryOptions &
export type TaskSchedulerServiceInitOptions = TaskSchedulerServiceFactoryOptions &
LogServiceInitOptions &
StateProviderInitOptions;
export function browserTaskSchedulerServiceFactory(
export function taskSchedulerServiceFactory(
cache: { browserTaskSchedulerService?: BrowserTaskSchedulerService } & CachedServices,
opts: BrowserTaskSchedulerServiceInitOptions,
opts: TaskSchedulerServiceInitOptions,
): Promise<BrowserTaskSchedulerService> {
return factory(
cache,

View File

@ -12,9 +12,9 @@ import {
passwordGenerationServiceFactory,
PasswordGenerationServiceInitOptions,
} from "../../tools/background/service_factories/password-generation-service.factory";
import { browserTaskSchedulerServiceFactory } from "../background/service-factories/browser-task-scheduler-service.factory";
import { CachedServices } from "../background/service-factories/factory-options";
import { logServiceFactory } from "../background/service-factories/log-service.factory";
import { taskSchedulerServiceFactory } from "../background/service-factories/task-scheduler-service.factory";
import { BrowserApi } from "../browser/browser-api";
export const onCommandListener = async (command: string, tab: chrome.tabs.Tab) => {
@ -103,7 +103,7 @@ const doGeneratePasswordToClipboard = async (tab: chrome.tabs.Tab): Promise<void
const command = new GeneratePasswordToClipboardCommand(
await passwordGenerationServiceFactory(cache, options),
await autofillSettingsServiceFactory(cache, options),
await browserTaskSchedulerServiceFactory(cache, options),
await taskSchedulerServiceFactory(cache, options),
);
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises

View File

@ -376,6 +376,7 @@ const safeProviders: SafeProvider[] = [
InternalUserDecryptionOptionsServiceAbstraction,
GlobalStateProvider,
BillingAccountProfileStateService,
TaskSchedulerService,
],
}),
safeProvider({

View File

@ -31,7 +31,9 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { TaskSchedulerService } from "@bitwarden/common/platform/abstractions/task-scheduler.service";
import { KdfType } from "@bitwarden/common/platform/enums";
import { ScheduledTaskNames } from "@bitwarden/common/platform/enums/scheduled-task-name.enum";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { GlobalState, GlobalStateProvider } from "@bitwarden/common/platform/state";
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
@ -63,7 +65,7 @@ import {
const sessionTimeoutLength = 2 * 60 * 1000; // 2 minutes
export class LoginStrategyService implements LoginStrategyServiceAbstraction {
private sessionTimeout: unknown;
private sessionTimeout: number | NodeJS.Timeout;
private currentAuthnTypeState: GlobalState<AuthenticationType | null>;
private loginStrategyCacheState: GlobalState<CacheData | null>;
private loginStrategyCacheExpirationState: GlobalState<Date | null>;
@ -101,6 +103,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
protected userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction,
protected stateProvider: GlobalStateProvider,
protected billingAccountProfileStateService: BillingAccountProfileStateService,
protected taskSchedulerService: TaskSchedulerService,
) {
this.currentAuthnTypeState = this.stateProvider.get(CURRENT_LOGIN_STRATEGY_KEY);
this.loginStrategyCacheState = this.stateProvider.get(CACHE_KEY);
@ -300,12 +303,19 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction {
await this.loginStrategyCacheExpirationState.update(
(_) => new Date(Date.now() + sessionTimeoutLength),
);
this.sessionTimeout = setTimeout(() => this.clearCache(), sessionTimeoutLength);
this.sessionTimeout = await this.taskSchedulerService.setTimeout(
() => this.clearCache(),
sessionTimeoutLength,
ScheduledTaskNames.loginStrategySessionTimeout,
);
}
private async clearSessionTimeout(): Promise<void> {
await this.loginStrategyCacheExpirationState.update((_) => null);
this.sessionTimeout = null;
await this.taskSchedulerService.clearScheduledTask({
taskName: ScheduledTaskNames.loginStrategySessionTimeout,
timeoutId: this.sessionTimeout,
});
}
private async isSessionValid(): Promise<boolean> {