diff --git a/src/abstractions/state.service.ts b/src/abstractions/state.service.ts new file mode 100644 index 00000000..96cf7655 --- /dev/null +++ b/src/abstractions/state.service.ts @@ -0,0 +1,10 @@ +import { StateService as BaseStateService } from "jslib-common/abstractions/state.service"; + +import { StorageOptions } from "jslib-common/models/domain/storageOptions"; + +import { Account } from "src/models/account"; + +export abstract class StateService extends BaseStateService { + getRememberEmail: (options?: StorageOptions) => Promise; + setRememberEmail: (value: boolean, options?: StorageOptions) => Promise; +} diff --git a/src/app/accounts/login.component.ts b/src/app/accounts/login.component.ts index c87002e1..8169f6a7 100644 --- a/src/app/accounts/login.component.ts +++ b/src/app/accounts/login.component.ts @@ -12,7 +12,8 @@ import { LogService } from "jslib-common/abstractions/log.service"; import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service"; import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service"; import { PolicyService } from "jslib-common/abstractions/policy.service"; -import { StateService } from "jslib-common/abstractions/state.service"; + +import { StateService } from "../../abstractions/state.service"; import { LoginComponent as BaseLoginComponent } from "jslib-angular/components/login.component"; @@ -30,7 +31,6 @@ export class LoginComponent extends BaseLoginComponent { router: Router, i18nService: I18nService, private route: ActivatedRoute, - stateService: StateService, platformUtilsService: PlatformUtilsService, environmentService: EnvironmentService, passwordGenerationService: PasswordGenerationService, @@ -38,7 +38,8 @@ export class LoginComponent extends BaseLoginComponent { private apiService: ApiService, private policyService: PolicyService, logService: LogService, - ngZone: NgZone + ngZone: NgZone, + protected stateService: StateService ) { super( authService, @@ -78,6 +79,7 @@ export class LoginComponent extends BaseLoginComponent { }); } await super.ngOnInit(); + this.rememberEmail = await this.stateService.getRememberEmail(); }); const invite = await this.stateService.getOrganizationInvitation(); @@ -115,4 +117,12 @@ export class LoginComponent extends BaseLoginComponent { this.router.navigate([this.successRoute]); } } + + async submit() { + await this.stateService.setRememberEmail(this.rememberEmail); + if (!this.rememberEmail) { + await this.stateService.setRememberedEmail(null); + } + await super.submit(); + } } diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts index 6ffeb0dd..3982ffcb 100644 --- a/src/app/services/services.module.ts +++ b/src/app/services/services.module.ts @@ -7,6 +7,7 @@ import { I18nService } from "../../services/i18n.service"; import { MemoryStorageService } from "../../services/memoryStorage.service"; import { PasswordRepromptService } from "../../services/passwordReprompt.service"; import { StateService } from "../../services/state.service"; +import { StateMigrationService } from "../../services/stateMigration.service"; import { WebPlatformUtilsService } from "../../services/webPlatformUtils.service"; import { EventService } from "./event.service"; @@ -24,7 +25,6 @@ import { ContainerService } from "jslib-common/services/container.service"; import { CryptoService } from "jslib-common/services/crypto.service"; import { EventService as EventLoggingService } from "jslib-common/services/event.service"; import { ImportService } from "jslib-common/services/import.service"; -import { StateMigrationService } from "jslib-common/services/stateMigration.service"; import { VaultTimeoutService } from "jslib-common/services/vaultTimeout.service"; import { ApiService as ApiServiceAbstraction } from "jslib-common/abstractions/api.service"; @@ -46,7 +46,7 @@ import { MessagingService as MessagingServiceAbstraction } from "jslib-common/ab import { NotificationsService as NotificationsServiceAbstraction } from "jslib-common/abstractions/notifications.service"; import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "jslib-common/abstractions/passwordReprompt.service"; import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "jslib-common/abstractions/platformUtils.service"; -import { StateService as StateServiceAbstraction } from "jslib-common/abstractions/state.service"; +import { StateService as BaseStateServiceAbstraction } from "jslib-common/abstractions/state.service"; import { StateMigrationService as StateMigrationServiceAbstraction } from "jslib-common/abstractions/stateMigration.service"; import { StorageService as StorageServiceAbstraction } from "jslib-common/abstractions/storage.service"; import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "jslib-common/abstractions/vaultTimeout.service"; @@ -59,6 +59,8 @@ import { GlobalState } from "../../models/globalState"; import { GlobalStateFactory } from "jslib-common/factories/globalStateFactory"; import { StateFactory } from "jslib-common/factories/stateFactory"; +import { StateService as StateServiceAbstraction } from "../../abstractions/state.service"; + export function initFactory( window: Window, environmentService: EnvironmentServiceAbstraction, @@ -215,6 +217,10 @@ export function initFactory( StateMigrationServiceAbstraction, ], }, + { + provide: BaseStateServiceAbstraction, + useExisting: StateServiceAbstraction, + }, { provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService, diff --git a/src/models/globalState.ts b/src/models/globalState.ts index 620c1124..1acce71e 100644 --- a/src/models/globalState.ts +++ b/src/models/globalState.ts @@ -4,4 +4,5 @@ import { GlobalState as BaseGlobalState } from "jslib-common/models/domain/globa export class GlobalState extends BaseGlobalState { theme?: ThemeType = ThemeType.Light; + rememberEmail: boolean = true; } diff --git a/src/services/state.service.ts b/src/services/state.service.ts index a46a7fe5..885d5b01 100644 --- a/src/services/state.service.ts +++ b/src/services/state.service.ts @@ -1,13 +1,36 @@ import { StateService as BaseStateService } from "jslib-common/services/state.service"; import { Account } from "../models/account"; +import { GlobalState } from "../models/globalState"; -import { StateService as StateServiceAbstraction } from "jslib-common/abstractions/state.service"; +import { StateService as StateServiceAbstraction } from "../abstractions/state.service"; -export class StateService extends BaseStateService implements StateServiceAbstraction { +import { StorageOptions } from "jslib-common/models/domain/storageOptions"; + +export class StateService + extends BaseStateService + implements StateServiceAbstraction +{ async addAccount(account: Account) { // Apply web overides to default account values account = new Account(account); await super.addAccount(account); } + + async getRememberEmail(options?: StorageOptions) { + return ( + await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskLocalOptions())) + )?.rememberEmail; + } + + async setRememberEmail(value: boolean, options?: StorageOptions): Promise { + const globals = await this.getGlobals( + this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()) + ); + globals.rememberEmail = value; + await this.saveGlobals( + globals, + this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()) + ); + } } diff --git a/src/services/stateMigration.service.ts b/src/services/stateMigration.service.ts new file mode 100644 index 00000000..f30082a2 --- /dev/null +++ b/src/services/stateMigration.service.ts @@ -0,0 +1,11 @@ +import { StateMigrationService as BaseStateMigrationService } from "jslib-common/services/stateMigration.service"; +import { GlobalState } from "../models/globalState"; + +export class StateMigrationService extends BaseStateMigrationService { + protected async migrationStateFrom1To2(): Promise { + await super.migrateStateFrom1To2(); + const globals = (await this.get("global")) ?? this.globalStateFactory.create(); + globals.rememberEmail = (await this.get("rememberEmail")) ?? globals.rememberEmail; + await this.set("global", globals); + } +} diff --git a/tsconfig.json b/tsconfig.json index 9f48584f..0174deba 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,5 +13,10 @@ "preserveWhitespaces": true }, "files": ["src/app/polyfills.ts", "src/app/main.ts", "bitwarden_license/src/app/main.ts"], - "include": ["src/connectors/*.ts", "src/models/*.ts", "src/services/*.ts"] + "include": [ + "src/connectors/*.ts", + "src/models/*.ts", + "src/services/*.ts", + "src/abstractions/*.ts" + ] }