1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-18 02:41:15 +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, stateServiceFactory,
StateServiceInitOptions, StateServiceInitOptions,
} from "../../../platform/background/service-factories/state-service.factory"; } from "../../../platform/background/service-factories/state-service.factory";
import {
taskSchedulerServiceFactory,
TaskSchedulerServiceInitOptions,
} from "../../../platform/background/service-factories/task-scheduler-service.factory";
import { import {
passwordStrengthServiceFactory, passwordStrengthServiceFactory,
PasswordStrengthServiceInitOptions, PasswordStrengthServiceInitOptions,
@ -99,7 +103,8 @@ export type LoginStrategyServiceInitOptions = LoginStrategyServiceFactoryOptions
AuthRequestServiceInitOptions & AuthRequestServiceInitOptions &
UserDecryptionOptionsServiceInitOptions & UserDecryptionOptionsServiceInitOptions &
GlobalStateProviderInitOptions & GlobalStateProviderInitOptions &
BillingAccountProfileStateServiceInitOptions; BillingAccountProfileStateServiceInitOptions &
TaskSchedulerServiceInitOptions;
export function loginStrategyServiceFactory( export function loginStrategyServiceFactory(
cache: { loginStrategyService?: LoginStrategyServiceAbstraction } & CachedServices, cache: { loginStrategyService?: LoginStrategyServiceAbstraction } & CachedServices,
@ -131,6 +136,7 @@ export function loginStrategyServiceFactory(
await internalUserDecryptionOptionServiceFactory(cache, opts), await internalUserDecryptionOptionServiceFactory(cache, opts),
await globalStateProviderFactory(cache, opts), await globalStateProviderFactory(cache, opts),
await billingAccountProfileStateServiceFactory(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 { autofillSettingsServiceFactory } from "../../autofill/background/service_factories/autofill-settings-service.factory";
import { eventCollectionServiceFactory } from "../../background/service-factories/event-collection-service.factory"; import { eventCollectionServiceFactory } from "../../background/service-factories/event-collection-service.factory";
import { Account } from "../../models/account"; 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 { CachedServices } from "../../platform/background/service-factories/factory-options";
import { stateServiceFactory } from "../../platform/background/service-factories/state-service.factory"; 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 { BrowserApi } from "../../platform/browser/browser-api";
import { passwordGenerationServiceFactory } from "../../tools/background/service_factories/password-generation-service.factory"; import { passwordGenerationServiceFactory } from "../../tools/background/service_factories/password-generation-service.factory";
import { import {
@ -117,7 +117,7 @@ export class ContextMenuClickedHandler {
const generatePasswordToClipboardCommand = new GeneratePasswordToClipboardCommand( const generatePasswordToClipboardCommand = new GeneratePasswordToClipboardCommand(
await passwordGenerationServiceFactory(cachedServices, serviceOptions), await passwordGenerationServiceFactory(cachedServices, serviceOptions),
await autofillSettingsServiceFactory(cachedServices, serviceOptions), await autofillSettingsServiceFactory(cachedServices, serviceOptions),
await browserTaskSchedulerServiceFactory(cachedServices, serviceOptions), await taskSchedulerServiceFactory(cachedServices, serviceOptions),
); );
const autofillCommand = new AutofillTabCommand( const autofillCommand = new AutofillTabCommand(

View File

@ -613,6 +613,7 @@ export default class MainBackground {
this.userDecryptionOptionsService, this.userDecryptionOptionsService,
this.globalStateProvider, this.globalStateProvider,
this.billingAccountProfileStateService, this.billingAccountProfileStateService,
this.taskSchedulerService,
); );
this.ssoLoginService = new SsoLoginService(this.stateProvider); 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 { logServiceFactory, LogServiceInitOptions } from "./log-service.factory";
import { stateProviderFactory, StateProviderInitOptions } from "./state-provider.factory"; import { stateProviderFactory, StateProviderInitOptions } from "./state-provider.factory";
type BrowserTaskSchedulerServiceFactoryOptions = FactoryOptions; type TaskSchedulerServiceFactoryOptions = FactoryOptions;
export type BrowserTaskSchedulerServiceInitOptions = BrowserTaskSchedulerServiceFactoryOptions & export type TaskSchedulerServiceInitOptions = TaskSchedulerServiceFactoryOptions &
LogServiceInitOptions & LogServiceInitOptions &
StateProviderInitOptions; StateProviderInitOptions;
export function browserTaskSchedulerServiceFactory( export function taskSchedulerServiceFactory(
cache: { browserTaskSchedulerService?: BrowserTaskSchedulerService } & CachedServices, cache: { browserTaskSchedulerService?: BrowserTaskSchedulerService } & CachedServices,
opts: BrowserTaskSchedulerServiceInitOptions, opts: TaskSchedulerServiceInitOptions,
): Promise<BrowserTaskSchedulerService> { ): Promise<BrowserTaskSchedulerService> {
return factory( return factory(
cache, cache,

View File

@ -12,9 +12,9 @@ import {
passwordGenerationServiceFactory, passwordGenerationServiceFactory,
PasswordGenerationServiceInitOptions, PasswordGenerationServiceInitOptions,
} from "../../tools/background/service_factories/password-generation-service.factory"; } 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 { CachedServices } from "../background/service-factories/factory-options";
import { logServiceFactory } from "../background/service-factories/log-service.factory"; 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"; import { BrowserApi } from "../browser/browser-api";
export const onCommandListener = async (command: string, tab: chrome.tabs.Tab) => { 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( const command = new GeneratePasswordToClipboardCommand(
await passwordGenerationServiceFactory(cache, options), await passwordGenerationServiceFactory(cache, options),
await autofillSettingsServiceFactory(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. // 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 // eslint-disable-next-line @typescript-eslint/no-floating-promises

View File

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