From 25207c2858ca9135f37e9ad5a49e29742362caaa Mon Sep 17 00:00:00 2001 From: Daniel James Smith Date: Tue, 30 Aug 2022 22:30:43 +0200 Subject: [PATCH] Extract settings related methods into VaultTimeoutSettingsService (#3419) * Extract into new VaultTimeoutSettingsService * Ensure new service is instantiated and registered for DI * Create vaultTimeoutSettingsServiceFactory * Fix VaultTimeoutServiceFactory * Remove any and use void instead --- .../browser/src/background/main.background.ts | 16 +++- .../vault-timeout-service.factory.ts | 14 ++-- .../vault-timeout-settings-service.factory.ts | 37 +++++++++ .../src/popup/accounts/lock.component.ts | 3 + .../src/popup/services/services.module.ts | 6 ++ .../src/popup/settings/settings.component.ts | 14 ++-- apps/cli/src/bw.ts | 12 ++- .../src/app/accounts/lock.component.ts | 3 + .../src/app/accounts/settings.component.ts | 12 +-- apps/desktop/src/app/app.component.ts | 4 +- apps/web/src/app/accounts/lock.component.ts | 3 + .../src/app/settings/preferences.component.ts | 8 +- libs/angular/src/components/lock.component.ts | 6 +- .../src/services/jslib-services.module.ts | 15 +++- .../vaultTimeout/vaultTimeout.service.ts | 5 -- .../vaultTimeoutSettings.service.ts | 7 ++ .../vaultTimeout/vaultTimeout.service.ts | 80 ++---------------- .../vaultTimeoutSettings.service.ts | 82 +++++++++++++++++++ 18 files changed, 214 insertions(+), 113 deletions(-) create mode 100644 apps/browser/src/background/service_factories/vault-timeout-settings-service.factory.ts create mode 100644 libs/common/src/abstractions/vaultTimeout/vaultTimeoutSettings.service.ts create mode 100644 libs/common/src/services/vaultTimeout/vaultTimeoutSettings.service.ts diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 6934b06130..cab48c0bc5 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -35,6 +35,7 @@ import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/abstrac import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { UsernameGenerationService as UsernameGenerationServiceAbstraction } from "@bitwarden/common/abstractions/usernameGeneration.service"; import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { AuthenticationStatus } from "@bitwarden/common/enums/authenticationStatus"; import { CipherRepromptType } from "@bitwarden/common/enums/cipherRepromptType"; import { CipherType } from "@bitwarden/common/enums/cipherType"; @@ -74,6 +75,7 @@ import { TwoFactorService } from "@bitwarden/common/services/twoFactor.service"; import { UserVerificationApiService } from "@bitwarden/common/services/userVerification/userVerification-api.service"; import { UserVerificationService } from "@bitwarden/common/services/userVerification/userVerification.service"; import { UsernameGenerationService } from "@bitwarden/common/services/usernameGeneration.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vaultTimeout/vaultTimeoutSettings.service"; import { WebCryptoFunctionService } from "@bitwarden/common/services/webCryptoFunction.service"; import { BrowserApi } from "../browser/browserApi"; @@ -126,6 +128,7 @@ export default class MainBackground { folderService: InternalFolderServiceAbstraction; collectionService: CollectionServiceAbstraction; vaultTimeoutService: VaultTimeoutServiceAbstraction; + vaultTimeoutSettingsService: VaultTimeoutSettingsServiceAbstraction; syncService: SyncServiceAbstraction; passwordGenerationService: PasswordGenerationServiceAbstraction; totpService: TotpServiceAbstraction; @@ -348,6 +351,13 @@ export default class MainBackground { this.i18nService ); + this.vaultTimeoutSettingsService = new VaultTimeoutSettingsService( + this.cryptoService, + this.tokenService, + this.policyService, + this.stateService + ); + this.vaultTimeoutService = new VaultTimeoutService( this.cipherService, this.folderService, @@ -356,14 +366,14 @@ export default class MainBackground { this.platformUtilsService, this.messagingService, this.searchService, - this.tokenService, - this.policyService, this.keyConnectorService, this.stateService, this.authService, + this.vaultTimeoutSettingsService, lockedCallback, logoutCallback ); + this.providerService = new ProviderService(this.stateService); this.syncService = new SyncService( this.apiService, @@ -625,7 +635,7 @@ export default class MainBackground { this.collectionService.clear(userId), this.policyService.clear(userId), this.passwordGenerationService.clear(userId), - this.vaultTimeoutService.clear(userId), + this.vaultTimeoutSettingsService.clear(userId), this.keyConnectorService.clear(), this.vaultFilterService.clear(), ]); diff --git a/apps/browser/src/background/service_factories/vault-timeout-service.factory.ts b/apps/browser/src/background/service_factories/vault-timeout-service.factory.ts index a6c305f369..3029b94f00 100644 --- a/apps/browser/src/background/service_factories/vault-timeout-service.factory.ts +++ b/apps/browser/src/background/service_factories/vault-timeout-service.factory.ts @@ -20,13 +20,15 @@ import { platformUtilsServiceFactory, PlatformUtilsServiceInitOptions, } from "./platform-utils-service.factory"; -import { policyServiceFactory, PolicyServiceInitOptions } from "./policy-service.factory"; import { searchServiceFactory, SearchServiceInitOptions } from "./search-service.factory"; import { stateServiceFactory as stateServiceFactory, StateServiceInitOptions, } from "./state-service.factory"; -import { tokenServiceFactory, TokenServiceInitOptions } from "./token-service.factory"; +import { + vaultTimeoutSettingsServiceFactory, + VaultTimeoutSettingsServiceInitOptions, +} from "./vault-timeout-settings-service.factory"; type VaultTimeoutServiceFactoryOptions = FactoryOptions & { vaultTimeoutServiceOptions: { @@ -43,11 +45,10 @@ export type VaultTimeoutServiceInitOptions = VaultTimeoutServiceFactoryOptions & PlatformUtilsServiceInitOptions & MessagingServiceInitOptions & SearchServiceInitOptions & - TokenServiceInitOptions & - PolicyServiceInitOptions & KeyConnectorServiceInitOptions & StateServiceInitOptions & - AuthServiceInitOptions; + AuthServiceInitOptions & + VaultTimeoutSettingsServiceInitOptions; export function vaultTimeoutServiceFactory( cache: { vaultTimeoutService?: AbstractVaultTimeoutService } & CachedServices, @@ -66,11 +67,10 @@ export function vaultTimeoutServiceFactory( await platformUtilsServiceFactory(cache, opts), await messagingServiceFactory(cache, opts), await searchServiceFactory(cache, opts), - await tokenServiceFactory(cache, opts), - await policyServiceFactory(cache, opts), await keyConnectorServiceFactory(cache, opts), await stateServiceFactory(cache, opts), await authServiceFactory(cache, opts), + await vaultTimeoutSettingsServiceFactory(cache, opts), opts.vaultTimeoutServiceOptions.lockedCallback, opts.vaultTimeoutServiceOptions.loggedOutCallback ) diff --git a/apps/browser/src/background/service_factories/vault-timeout-settings-service.factory.ts b/apps/browser/src/background/service_factories/vault-timeout-settings-service.factory.ts new file mode 100644 index 0000000000..0d8ed149b8 --- /dev/null +++ b/apps/browser/src/background/service_factories/vault-timeout-settings-service.factory.ts @@ -0,0 +1,37 @@ +import { VaultTimeoutSettingsService as AbstractVaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vaultTimeout/vaultTimeoutSettings.service"; + +import { cryptoServiceFactory, CryptoServiceInitOptions } from "./crypto-service.factory"; +import { CachedServices, factory, FactoryOptions } from "./factory-options"; +import { policyServiceFactory, PolicyServiceInitOptions } from "./policy-service.factory"; +import { + stateServiceFactory as stateServiceFactory, + StateServiceInitOptions, +} from "./state-service.factory"; +import { tokenServiceFactory, TokenServiceInitOptions } from "./token-service.factory"; + +type VaultTimeoutSettingsServiceFactoryOptions = FactoryOptions; + +export type VaultTimeoutSettingsServiceInitOptions = VaultTimeoutSettingsServiceFactoryOptions & + CryptoServiceInitOptions & + TokenServiceInitOptions & + PolicyServiceInitOptions & + StateServiceInitOptions; + +export function vaultTimeoutSettingsServiceFactory( + cache: { vaultTimeoutSettingsService?: AbstractVaultTimeoutSettingsService } & CachedServices, + opts: VaultTimeoutSettingsServiceInitOptions +): Promise { + return factory( + cache, + "vaultTimeoutSettingsService", + opts, + async () => + new VaultTimeoutSettingsService( + await cryptoServiceFactory(cache, opts), + await tokenServiceFactory(cache, opts), + await policyServiceFactory(cache, opts), + await stateServiceFactory(cache, opts) + ) + ); +} diff --git a/apps/browser/src/popup/accounts/lock.component.ts b/apps/browser/src/popup/accounts/lock.component.ts index 63360da43c..c288a54a65 100644 --- a/apps/browser/src/popup/accounts/lock.component.ts +++ b/apps/browser/src/popup/accounts/lock.component.ts @@ -14,6 +14,7 @@ import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUti import { StateService } from "@bitwarden/common/abstractions/state.service"; import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { AuthenticationStatus } from "@bitwarden/common/enums/authenticationStatus"; import { BiometricErrors, BiometricErrorTypes } from "../../models/biometricErrors"; @@ -37,6 +38,7 @@ export class LockComponent extends BaseLockComponent { messagingService: MessagingService, cryptoService: CryptoService, vaultTimeoutService: VaultTimeoutService, + vaultTimeoutSettingsService: VaultTimeoutSettingsService, environmentService: EnvironmentService, stateService: StateService, apiService: ApiService, @@ -53,6 +55,7 @@ export class LockComponent extends BaseLockComponent { messagingService, cryptoService, vaultTimeoutService, + vaultTimeoutSettingsService, environmentService, stateService, apiService, diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index e4449d964a..c070db6087 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -48,6 +48,7 @@ import { TwoFactorService } from "@bitwarden/common/abstractions/twoFactor.servi import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { UsernameGenerationService } from "@bitwarden/common/abstractions/usernameGeneration.service"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { AuthService } from "@bitwarden/common/services/auth.service"; import { ConsoleLogService } from "@bitwarden/common/services/consoleLog.service"; import { SearchService } from "@bitwarden/common/services/search.service"; @@ -237,6 +238,11 @@ function getBgService(service: keyof MainBackground) { useFactory: getBgService("userVerificationService"), deps: [], }, + { + provide: VaultTimeoutSettingsService, + useFactory: getBgService("vaultTimeoutSettingsService"), + deps: [], + }, { provide: VaultTimeoutService, useFactory: getBgService("vaultTimeoutService"), diff --git a/apps/browser/src/popup/settings/settings.component.ts b/apps/browser/src/popup/settings/settings.component.ts index a01479c36c..029812ba49 100644 --- a/apps/browser/src/popup/settings/settings.component.ts +++ b/apps/browser/src/popup/settings/settings.component.ts @@ -12,6 +12,7 @@ import { MessagingService } from "@bitwarden/common/abstractions/messaging.servi import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { DeviceType } from "@bitwarden/common/enums/deviceType"; import { BrowserApi } from "../../browser/browserApi"; @@ -57,6 +58,7 @@ export class SettingsComponent implements OnInit { private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, private vaultTimeoutService: VaultTimeoutService, + private vaultTimeoutSettingsService: VaultTimeoutSettingsService, public messagingService: MessagingService, private router: Router, private environmentService: EnvironmentService, @@ -95,7 +97,7 @@ export class SettingsComponent implements OnInit { { name: this.i18nService.t("logOut"), value: "logOut" }, ]; - let timeout = await this.vaultTimeoutService.getVaultTimeout(); + let timeout = await this.vaultTimeoutSettingsService.getVaultTimeout(); if (timeout != null) { if (timeout === -2 && !showOnLocked) { timeout = -1; @@ -111,11 +113,11 @@ export class SettingsComponent implements OnInit { const action = await this.stateService.getVaultTimeoutAction(); this.vaultTimeoutAction = action == null ? "lock" : action; - const pinSet = await this.vaultTimeoutService.isPinLockSet(); + const pinSet = await this.vaultTimeoutSettingsService.isPinLockSet(); this.pin = pinSet[0] || pinSet[1]; this.supportsBiometric = await this.platformUtilsService.supportsBiometric(); - this.biometric = await this.vaultTimeoutService.isBiometricLockSet(); + this.biometric = await this.vaultTimeoutSettingsService.isBiometricLockSet(); this.enableAutoBiometricsPrompt = !(await this.stateService.getDisableAutoBiometricsPrompt()); this.showChangeMasterPass = !(await this.keyConnectorService.getUsesKeyConnector()); } @@ -148,7 +150,7 @@ export class SettingsComponent implements OnInit { this.previousVaultTimeout = this.vaultTimeout.value; - await this.vaultTimeoutService.setVaultTimeoutOptions( + await this.vaultTimeoutSettingsService.setVaultTimeoutOptions( this.vaultTimeout.value, this.vaultTimeoutAction ); @@ -187,7 +189,7 @@ export class SettingsComponent implements OnInit { } this.vaultTimeoutAction = newValue; - await this.vaultTimeoutService.setVaultTimeoutOptions( + await this.vaultTimeoutSettingsService.setVaultTimeoutOptions( this.vaultTimeout.value, this.vaultTimeoutAction ); @@ -205,7 +207,7 @@ export class SettingsComponent implements OnInit { this.pin = await ref.onClosedPromise(); } else { await this.cryptoService.clearPinProtectedKey(); - await this.vaultTimeoutService.clear(); + await this.vaultTimeoutSettingsService.clear(); } } diff --git a/apps/cli/src/bw.ts b/apps/cli/src/bw.ts index 0edc6f34da..a168182ddc 100644 --- a/apps/cli/src/bw.ts +++ b/apps/cli/src/bw.ts @@ -47,6 +47,7 @@ import { TwoFactorService } from "@bitwarden/common/services/twoFactor.service"; import { UserVerificationApiService } from "@bitwarden/common/services/userVerification/userVerification-api.service"; import { UserVerificationService } from "@bitwarden/common/services/userVerification/userVerification.service"; import { VaultTimeoutService } from "@bitwarden/common/services/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vaultTimeout/vaultTimeoutSettings.service"; import { CliPlatformUtilsService } from "@bitwarden/node/cli/services/cliPlatformUtils.service"; import { ConsoleLogService } from "@bitwarden/node/cli/services/consoleLog.service"; import { NodeApiService } from "@bitwarden/node/services/nodeApi.service"; @@ -82,6 +83,7 @@ export class Main { folderService: InternalFolderService; collectionService: CollectionService; vaultTimeoutService: VaultTimeoutService; + vaultTimeoutSettingsService: VaultTimeoutSettingsService; syncService: SyncService; passwordGenerationService: PasswordGenerationService; totpService: TotpService; @@ -273,6 +275,13 @@ export class Main { const lockedCallback = async () => await this.cryptoService.clearStoredKey(KeySuffixOptions.Auto); + this.vaultTimeoutSettingsService = new VaultTimeoutSettingsService( + this.cryptoService, + this.tokenService, + this.policyService, + this.stateService + ); + this.vaultTimeoutService = new VaultTimeoutService( this.cipherService, this.folderService, @@ -281,11 +290,10 @@ export class Main { this.platformUtilsService, this.messagingService, this.searchService, - this.tokenService, - this.policyService, this.keyConnectorService, this.stateService, this.authService, + this.vaultTimeoutSettingsService, lockedCallback, null ); diff --git a/apps/desktop/src/app/accounts/lock.component.ts b/apps/desktop/src/app/accounts/lock.component.ts index 86940fb430..ff136aa982 100644 --- a/apps/desktop/src/app/accounts/lock.component.ts +++ b/apps/desktop/src/app/accounts/lock.component.ts @@ -15,6 +15,7 @@ import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUti import { StateService } from "@bitwarden/common/abstractions/state.service"; import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; const BroadcasterSubscriptionId = "LockComponent"; @@ -34,6 +35,7 @@ export class LockComponent extends BaseLockComponent { messagingService: MessagingService, cryptoService: CryptoService, vaultTimeoutService: VaultTimeoutService, + vaultTimeoutSettingsService: VaultTimeoutSettingsService, environmentService: EnvironmentService, stateService: StateService, apiService: ApiService, @@ -51,6 +53,7 @@ export class LockComponent extends BaseLockComponent { messagingService, cryptoService, vaultTimeoutService, + vaultTimeoutSettingsService, environmentService, stateService, apiService, diff --git a/apps/desktop/src/app/accounts/settings.component.ts b/apps/desktop/src/app/accounts/settings.component.ts index 0a514f42d5..24c1ba576f 100644 --- a/apps/desktop/src/app/accounts/settings.component.ts +++ b/apps/desktop/src/app/accounts/settings.component.ts @@ -9,7 +9,7 @@ import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; -import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { DeviceType } from "@bitwarden/common/enums/deviceType"; import { StorageLocation } from "@bitwarden/common/enums/storageLocation"; import { ThemeType } from "@bitwarden/common/enums/themeType"; @@ -76,7 +76,7 @@ export class SettingsComponent implements OnInit { constructor( private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, - private vaultTimeoutService: VaultTimeoutService, + private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private stateService: StateService, private messagingService: MessagingService, private cryptoService: CryptoService, @@ -184,7 +184,7 @@ export class SettingsComponent implements OnInit { this.saveVaultTimeoutOptions(); }); - const pinSet = await this.vaultTimeoutService.isPinLockSet(); + const pinSet = await this.vaultTimeoutSettingsService.isPinLockSet(); this.pin = pinSet[0] || pinSet[1]; // Account preferences @@ -195,7 +195,7 @@ export class SettingsComponent implements OnInit { this.clearClipboard = await this.stateService.getClearClipboard(); this.minimizeOnCopyToClipboard = await this.stateService.getMinimizeOnCopyToClipboard(); this.supportsBiometric = await this.platformUtilsService.supportsBiometric(); - this.biometric = await this.vaultTimeoutService.isBiometricLockSet(); + this.biometric = await this.vaultTimeoutSettingsService.isBiometricLockSet(); this.biometricText = await this.stateService.getBiometricText(); this.autoPromptBiometrics = !(await this.stateService.getNoAutoPromptBiometrics()); this.autoPromptBiometricsText = await this.stateService.getNoAutoPromptBiometricsText(); @@ -246,7 +246,7 @@ export class SettingsComponent implements OnInit { this.previousVaultTimeout = this.vaultTimeout.value; - await this.vaultTimeoutService.setVaultTimeoutOptions( + await this.vaultTimeoutSettingsService.setVaultTimeoutOptions( this.vaultTimeout.value, this.vaultTimeoutAction ); @@ -265,7 +265,7 @@ export class SettingsComponent implements OnInit { } if (!this.pin) { await this.cryptoService.clearPinProtectedKey(); - await this.vaultTimeoutService.clear(); + await this.vaultTimeoutSettingsService.clear(); } } diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index 4365eaf57a..0541e5493c 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -36,6 +36,7 @@ import { StateService } from "@bitwarden/common/abstractions/state.service"; import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction"; import { SystemService } from "@bitwarden/common/abstractions/system.service"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { AuthenticationStatus } from "@bitwarden/common/enums/authenticationStatus"; import { CipherType } from "@bitwarden/common/enums/cipherType"; @@ -114,6 +115,7 @@ export class AppComponent implements OnInit, OnDestroy { private sanitizer: DomSanitizer, private ngZone: NgZone, private vaultTimeoutService: VaultTimeoutService, + private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private cryptoService: CryptoService, private logService: LogService, private messagingService: MessagingService, @@ -471,7 +473,7 @@ export class AppComponent implements OnInit, OnDestroy { this.folderService.clear(userBeingLoggedOut), this.collectionService.clear(userBeingLoggedOut), this.passwordGenerationService.clear(userBeingLoggedOut), - this.vaultTimeoutService.clear(userBeingLoggedOut), + this.vaultTimeoutSettingsService.clear(userBeingLoggedOut), this.policyService.clear(userBeingLoggedOut), this.keyConnectorService.clear(), ]); diff --git a/apps/web/src/app/accounts/lock.component.ts b/apps/web/src/app/accounts/lock.component.ts index 8bb65794aa..0aed1fb0ea 100644 --- a/apps/web/src/app/accounts/lock.component.ts +++ b/apps/web/src/app/accounts/lock.component.ts @@ -12,6 +12,7 @@ import { MessagingService } from "@bitwarden/common/abstractions/messaging.servi import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { RouterService } from "../core"; @@ -27,6 +28,7 @@ export class LockComponent extends BaseLockComponent { messagingService: MessagingService, cryptoService: CryptoService, vaultTimeoutService: VaultTimeoutService, + vaultTimeoutSettingsService: VaultTimeoutSettingsService, environmentService: EnvironmentService, private routerService: RouterService, stateService: StateService, @@ -42,6 +44,7 @@ export class LockComponent extends BaseLockComponent { messagingService, cryptoService, vaultTimeoutService, + vaultTimeoutSettingsService, environmentService, stateService, apiService, diff --git a/apps/web/src/app/settings/preferences.component.ts b/apps/web/src/app/settings/preferences.component.ts index a3a314305d..c96a1368fe 100644 --- a/apps/web/src/app/settings/preferences.component.ts +++ b/apps/web/src/app/settings/preferences.component.ts @@ -6,7 +6,7 @@ import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; -import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { ThemeType } from "@bitwarden/common/enums/themeType"; import { Utils } from "@bitwarden/common/misc/utils"; @@ -33,7 +33,7 @@ export class PreferencesComponent implements OnInit { constructor( private stateService: StateService, private i18nService: I18nService, - private vaultTimeoutService: VaultTimeoutService, + private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private platformUtilsService: PlatformUtilsService, private messagingService: MessagingService, private themingService: AbstractThemingService @@ -70,7 +70,7 @@ export class PreferencesComponent implements OnInit { } async ngOnInit() { - this.vaultTimeout.setValue(await this.vaultTimeoutService.getVaultTimeout()); + this.vaultTimeout.setValue(await this.vaultTimeoutSettingsService.getVaultTimeout()); this.vaultTimeoutAction = await this.stateService.getVaultTimeoutAction(); this.enableFavicons = !(await this.stateService.getDisableFavicon()); this.enableGravatars = await this.stateService.getEnableGravitars(); @@ -93,7 +93,7 @@ export class PreferencesComponent implements OnInit { return; } - await this.vaultTimeoutService.setVaultTimeoutOptions( + await this.vaultTimeoutSettingsService.setVaultTimeoutOptions( this.vaultTimeout.value, this.vaultTimeoutAction ); diff --git a/libs/angular/src/components/lock.component.ts b/libs/angular/src/components/lock.component.ts index 6419148737..d00127ae96 100644 --- a/libs/angular/src/components/lock.component.ts +++ b/libs/angular/src/components/lock.component.ts @@ -13,6 +13,7 @@ import { MessagingService } from "@bitwarden/common/abstractions/messaging.servi import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { HashPurpose } from "@bitwarden/common/enums/hashPurpose"; import { KeySuffixOptions } from "@bitwarden/common/enums/keySuffixOptions"; import { Utils } from "@bitwarden/common/misc/utils"; @@ -49,6 +50,7 @@ export class LockComponent implements OnInit, OnDestroy { protected messagingService: MessagingService, protected cryptoService: CryptoService, protected vaultTimeoutService: VaultTimeoutService, + protected vaultTimeoutSettingsService: VaultTimeoutSettingsService, protected environmentService: EnvironmentService, protected stateService: StateService, protected apiService: ApiService, @@ -262,13 +264,13 @@ export class LockComponent implements OnInit, OnDestroy { } private async load() { - this.pinSet = await this.vaultTimeoutService.isPinLockSet(); + this.pinSet = await this.vaultTimeoutSettingsService.isPinLockSet(); this.pinLock = (this.pinSet[0] && (await this.stateService.getDecryptedPinProtected()) != null) || this.pinSet[1]; this.supportsBiometric = await this.platformUtilsService.supportsBiometric(); this.biometricLock = - (await this.vaultTimeoutService.isBiometricLockSet()) && + (await this.vaultTimeoutSettingsService.isBiometricLockSet()) && ((await this.cryptoService.hasKeyStored(KeySuffixOptions.Biometric)) || !this.platformUtilsService.supportsSecureStorage()); this.biometricText = await this.stateService.getBiometricText(); diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index d8645d81e6..ab51488ffe 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -54,6 +54,7 @@ import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/abstrac import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { UsernameGenerationService as UsernameGenerationServiceAbstraction } from "@bitwarden/common/abstractions/usernameGeneration.service"; import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { StateFactory } from "@bitwarden/common/factories/stateFactory"; import { Account } from "@bitwarden/common/models/domain/account"; import { GlobalState } from "@bitwarden/common/models/domain/globalState"; @@ -96,6 +97,7 @@ import { UserVerificationApiService } from "@bitwarden/common/services/userVerif import { UserVerificationService } from "@bitwarden/common/services/userVerification/userVerification.service"; import { UsernameGenerationService } from "@bitwarden/common/services/usernameGeneration.service"; import { VaultTimeoutService } from "@bitwarden/common/services/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vaultTimeout/vaultTimeoutSettings.service"; import { WebCryptoFunctionService } from "@bitwarden/common/services/webCryptoFunction.service"; import { AuthGuard } from "../guards/auth.guard"; @@ -344,6 +346,16 @@ export const LOG_MAC_FAILURES = new InjectionToken("LOG_MAC_FAILURES"); useClass: SettingsService, deps: [StateServiceAbstraction], }, + { + provide: VaultTimeoutSettingsServiceAbstraction, + useClass: VaultTimeoutSettingsService, + deps: [ + CryptoServiceAbstraction, + TokenServiceAbstraction, + PolicyServiceAbstraction, + StateServiceAbstraction, + ], + }, { provide: VaultTimeoutServiceAbstraction, useClass: VaultTimeoutService, @@ -355,11 +367,10 @@ export const LOG_MAC_FAILURES = new InjectionToken("LOG_MAC_FAILURES"); PlatformUtilsServiceAbstraction, MessagingServiceAbstraction, SearchServiceAbstraction, - TokenServiceAbstraction, - PolicyServiceAbstraction, KeyConnectorServiceAbstraction, StateServiceAbstraction, AuthServiceAbstraction, + VaultTimeoutSettingsServiceAbstraction, LOCKED_CALLBACK, LOGOUT_CALLBACK, ], diff --git a/libs/common/src/abstractions/vaultTimeout/vaultTimeout.service.ts b/libs/common/src/abstractions/vaultTimeout/vaultTimeout.service.ts index 4fb474fd03..6baadfc033 100644 --- a/libs/common/src/abstractions/vaultTimeout/vaultTimeout.service.ts +++ b/libs/common/src/abstractions/vaultTimeout/vaultTimeout.service.ts @@ -2,9 +2,4 @@ export abstract class VaultTimeoutService { checkVaultTimeout: () => Promise; lock: (userId?: string) => Promise; logOut: (userId?: string) => Promise; - setVaultTimeoutOptions: (vaultTimeout: number, vaultTimeoutAction: string) => Promise; - getVaultTimeout: () => Promise; - isPinLockSet: () => Promise<[boolean, boolean]>; - isBiometricLockSet: () => Promise; - clear: (userId?: string) => Promise; } diff --git a/libs/common/src/abstractions/vaultTimeout/vaultTimeoutSettings.service.ts b/libs/common/src/abstractions/vaultTimeout/vaultTimeoutSettings.service.ts new file mode 100644 index 0000000000..7e819df6b9 --- /dev/null +++ b/libs/common/src/abstractions/vaultTimeout/vaultTimeoutSettings.service.ts @@ -0,0 +1,7 @@ +export abstract class VaultTimeoutSettingsService { + setVaultTimeoutOptions: (vaultTimeout: number, vaultTimeoutAction: string) => Promise; + getVaultTimeout: (userId?: string) => Promise; + isPinLockSet: () => Promise<[boolean, boolean]>; + isBiometricLockSet: () => Promise; + clear: (userId?: string) => Promise; +} diff --git a/libs/common/src/services/vaultTimeout/vaultTimeout.service.ts b/libs/common/src/services/vaultTimeout/vaultTimeout.service.ts index 3d6f8758a7..f4a9e0330c 100644 --- a/libs/common/src/services/vaultTimeout/vaultTimeout.service.ts +++ b/libs/common/src/services/vaultTimeout/vaultTimeout.service.ts @@ -6,13 +6,11 @@ import { FolderService } from "../../abstractions/folder/folder.service.abstract import { KeyConnectorService } from "../../abstractions/keyConnector.service"; import { MessagingService } from "../../abstractions/messaging.service"; import { PlatformUtilsService } from "../../abstractions/platformUtils.service"; -import { PolicyService } from "../../abstractions/policy/policy.service.abstraction"; import { SearchService } from "../../abstractions/search.service"; import { StateService } from "../../abstractions/state.service"; -import { TokenService } from "../../abstractions/token.service"; import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "../../abstractions/vaultTimeout/vaultTimeout.service"; +import { VaultTimeoutSettingsService } from "../../abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { AuthenticationStatus } from "../../enums/authenticationStatus"; -import { PolicyType } from "../../enums/policyType"; export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { private inited = false; @@ -25,11 +23,10 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { protected platformUtilsService: PlatformUtilsService, private messagingService: MessagingService, private searchService: SearchService, - private tokenService: TokenService, - private policyService: PolicyService, private keyConnectorService: KeyConnectorService, private stateService: StateService, private authService: AuthService, + private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private lockedCallback: (userId?: string) => Promise = null, private loggedOutCallback: (expired: boolean, userId?: string) => Promise = null ) {} @@ -69,11 +66,11 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { } if (await this.keyConnectorService.getUsesKeyConnector()) { - const pinSet = await this.isPinLockSet(); + const pinSet = await this.vaultTimeoutSettingsService.isPinLockSet(); const pinLock = (pinSet[0] && (await this.stateService.getDecryptedPinProtected()) != null) || pinSet[1]; - if (!pinLock && !(await this.isBiometricLockSet())) { + if (!pinLock && !(await this.vaultTimeoutSettingsService.isBiometricLockSet())) { await this.logOut(userId); } } @@ -107,73 +104,6 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { } } - async setVaultTimeoutOptions(timeout: number, action: string): Promise { - await this.stateService.setVaultTimeout(timeout); - - // We swap these tokens from being on disk for lock actions, and in memory for logout actions - // Get them here to set them to their new location after changing the timeout action and clearing if needed - const token = await this.tokenService.getToken(); - const refreshToken = await this.tokenService.getRefreshToken(); - const clientId = await this.tokenService.getClientId(); - const clientSecret = await this.tokenService.getClientSecret(); - - const currentAction = await this.stateService.getVaultTimeoutAction(); - if ((timeout != null || timeout === 0) && action === "logOut" && action !== currentAction) { - // if we have a vault timeout and the action is log out, reset tokens - await this.tokenService.clearToken(); - } - - await this.stateService.setVaultTimeoutAction(action); - - await this.tokenService.setToken(token); - await this.tokenService.setRefreshToken(refreshToken); - await this.tokenService.setClientId(clientId); - await this.tokenService.setClientSecret(clientSecret); - - await this.cryptoService.toggleKey(); - } - - async isPinLockSet(): Promise<[boolean, boolean]> { - const protectedPin = await this.stateService.getProtectedPin(); - const pinProtectedKey = await this.stateService.getEncryptedPinProtected(); - return [protectedPin != null, pinProtectedKey != null]; - } - - async isBiometricLockSet(): Promise { - return await this.stateService.getBiometricUnlock(); - } - - async getVaultTimeout(userId?: string): Promise { - const vaultTimeout = await this.stateService.getVaultTimeout({ userId: userId }); - - if ( - await this.policyService.policyAppliesToUser(PolicyType.MaximumVaultTimeout, null, userId) - ) { - const policy = await this.policyService.getAll(PolicyType.MaximumVaultTimeout, userId); - // Remove negative values, and ensure it's smaller than maximum allowed value according to policy - let timeout = Math.min(vaultTimeout, policy[0].data.minutes); - - if (vaultTimeout == null || timeout < 0) { - timeout = policy[0].data.minutes; - } - - // We really shouldn't need to set the value here, but multiple services relies on this value being correct. - if (vaultTimeout !== timeout) { - await this.stateService.setVaultTimeout(timeout, { userId: userId }); - } - - return timeout; - } - - return vaultTimeout; - } - - async clear(userId?: string): Promise { - await this.stateService.setEverBeenUnlocked(false, { userId: userId }); - await this.stateService.setDecryptedPinProtected(null, { userId: userId }); - await this.stateService.setProtectedPin(null, { userId: userId }); - } - private async shouldLock(userId: string): Promise { const authStatus = await this.authService.getAuthStatus(userId); if ( @@ -183,7 +113,7 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { return false; } - const vaultTimeout = await this.getVaultTimeout(userId); + const vaultTimeout = await this.vaultTimeoutSettingsService.getVaultTimeout(userId); if (vaultTimeout == null || vaultTimeout < 0) { return false; } diff --git a/libs/common/src/services/vaultTimeout/vaultTimeoutSettings.service.ts b/libs/common/src/services/vaultTimeout/vaultTimeoutSettings.service.ts new file mode 100644 index 0000000000..4d8b9e0d08 --- /dev/null +++ b/libs/common/src/services/vaultTimeout/vaultTimeoutSettings.service.ts @@ -0,0 +1,82 @@ +import { CryptoService } from "../../abstractions/crypto.service"; +import { PolicyService } from "../../abstractions/policy/policy.service.abstraction"; +import { StateService } from "../../abstractions/state.service"; +import { TokenService } from "../../abstractions/token.service"; +import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../abstractions/vaultTimeout/vaultTimeoutSettings.service"; +import { PolicyType } from "../../enums/policyType"; + +export class VaultTimeoutSettingsService implements VaultTimeoutSettingsServiceAbstraction { + constructor( + private cryptoService: CryptoService, + private tokenService: TokenService, + private policyService: PolicyService, + private stateService: StateService + ) {} + + async setVaultTimeoutOptions(timeout: number, action: string): Promise { + await this.stateService.setVaultTimeout(timeout); + + // We swap these tokens from being on disk for lock actions, and in memory for logout actions + // Get them here to set them to their new location after changing the timeout action and clearing if needed + const token = await this.tokenService.getToken(); + const refreshToken = await this.tokenService.getRefreshToken(); + const clientId = await this.tokenService.getClientId(); + const clientSecret = await this.tokenService.getClientSecret(); + + const currentAction = await this.stateService.getVaultTimeoutAction(); + if ((timeout != null || timeout === 0) && action === "logOut" && action !== currentAction) { + // if we have a vault timeout and the action is log out, reset tokens + await this.tokenService.clearToken(); + } + + await this.stateService.setVaultTimeoutAction(action); + + await this.tokenService.setToken(token); + await this.tokenService.setRefreshToken(refreshToken); + await this.tokenService.setClientId(clientId); + await this.tokenService.setClientSecret(clientSecret); + + await this.cryptoService.toggleKey(); + } + + async isPinLockSet(): Promise<[boolean, boolean]> { + const protectedPin = await this.stateService.getProtectedPin(); + const pinProtectedKey = await this.stateService.getEncryptedPinProtected(); + return [protectedPin != null, pinProtectedKey != null]; + } + + async isBiometricLockSet(): Promise { + return await this.stateService.getBiometricUnlock(); + } + + async getVaultTimeout(userId?: string): Promise { + const vaultTimeout = await this.stateService.getVaultTimeout({ userId: userId }); + + if ( + await this.policyService.policyAppliesToUser(PolicyType.MaximumVaultTimeout, null, userId) + ) { + const policy = await this.policyService.getAll(PolicyType.MaximumVaultTimeout, userId); + // Remove negative values, and ensure it's smaller than maximum allowed value according to policy + let timeout = Math.min(vaultTimeout, policy[0].data.minutes); + + if (vaultTimeout == null || timeout < 0) { + timeout = policy[0].data.minutes; + } + + // We really shouldn't need to set the value here, but multiple services relies on this value being correct. + if (vaultTimeout !== timeout) { + await this.stateService.setVaultTimeout(timeout, { userId: userId }); + } + + return timeout; + } + + return vaultTimeout; + } + + async clear(userId?: string): Promise { + await this.stateService.setEverBeenUnlocked(false, { userId: userId }); + await this.stateService.setDecryptedPinProtected(null, { userId: userId }); + await this.stateService.setProtectedPin(null, { userId: userId }); + } +}