From 19acf12900130fa26d27cde784cb82cda914c1ef Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Mon, 2 Sep 2024 08:50:38 -0700 Subject: [PATCH] add handleMigrateEncryptionKey to default and web service --- .../core/services/login/web-login.service.ts | 12 ++++- .../src/auth/components/login.component.ts | 3 +- .../angular/login/default-login.service.ts | 23 ++++++++++ .../src/angular/login/login.component.html | 2 +- .../auth/src/angular/login/login.component.ts | 46 ++++++++++++++++++- libs/auth/src/angular/login/login.service.ts | 3 ++ 6 files changed, 83 insertions(+), 6 deletions(-) diff --git a/apps/web/src/app/auth/core/services/login/web-login.service.ts b/apps/web/src/app/auth/core/services/login/web-login.service.ts index 6af1d4f041..f7747a1361 100644 --- a/apps/web/src/app/auth/core/services/login/web-login.service.ts +++ b/apps/web/src/app/auth/core/services/login/web-login.service.ts @@ -1,11 +1,12 @@ import { inject } from "@angular/core"; -import { UrlTree } from "@angular/router"; +import { Router, UrlTree } from "@angular/router"; import { firstValueFrom } from "rxjs"; import { DefaultLoginService, LoginService, PasswordPolicies } from "@bitwarden/auth/angular"; import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; +import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { flagEnabled } from "../../../../../utils/flags"; @@ -17,6 +18,7 @@ export class WebLoginService extends DefaultLoginService implements LoginService logService = inject(LogService); policyApiService = inject(PolicyApiServiceAbstraction); policyService = inject(InternalPolicyService); + router = inject(Router); routerService = inject(RouterService); getShowPasswordlessFlag(): boolean { @@ -67,4 +69,12 @@ export class WebLoginService extends DefaultLoginService implements LoginService }; } } + + override async handleMigrateEncryptionKey(result: AuthResult): Promise { + if (!result.requiresEncryptionKeyMigration) { + return false; + } + await this.router.navigate(["migrate-legacy-encryption"]); + return true; + } } diff --git a/libs/angular/src/auth/components/login.component.ts b/libs/angular/src/auth/components/login.component.ts index ae971e8a28..e76d02016a 100644 --- a/libs/angular/src/auth/components/login.component.ts +++ b/libs/angular/src/auth/components/login.component.ts @@ -332,8 +332,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, await this.loginEmailService.saveEmailSettings(); } - // Legacy accounts used the master key to encrypt data. Migration is required - // but only performed on web + // Legacy accounts used the master key to encrypt data. Migration is required but only performed on web protected async handleMigrateEncryptionKey(result: AuthResult): Promise { if (!result.requiresEncryptionKeyMigration) { return false; diff --git a/libs/auth/src/angular/login/default-login.service.ts b/libs/auth/src/angular/login/default-login.service.ts index 5874d57c5b..0a8ef12dbf 100644 --- a/libs/auth/src/angular/login/default-login.service.ts +++ b/libs/auth/src/angular/login/default-login.service.ts @@ -1,8 +1,17 @@ import { UrlTree } from "@angular/router"; +import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { ToastService } from "@bitwarden/components"; + import { LoginService, PasswordPolicies } from "./login.service"; export class DefaultLoginService implements LoginService { + constructor( + protected i18nService: I18nService, + protected toastService: ToastService, + ) {} + getShowPasswordlessFlag(): boolean { return null; } @@ -14,4 +23,18 @@ export class DefaultLoginService implements LoginService { async getOrgPolicies(): Promise { return null; } + + // Legacy accounts used the master key to encrypt data. Migration is required but only performed on web + async handleMigrateEncryptionKey(result: AuthResult): Promise { + if (!result.requiresEncryptionKeyMigration) { + return false; + } + + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccured"), + message: this.i18nService.t("encryptionKeyMigrationRequired"), + }); + return true; + } } diff --git a/libs/auth/src/angular/login/login.component.html b/libs/auth/src/angular/login/login.component.html index c12dcedb71..88149289b4 100644 --- a/libs/auth/src/angular/login/login.component.html +++ b/libs/auth/src/angular/login/login.component.html @@ -1,4 +1,4 @@ -
+ diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts index 700b744926..f0a964e8d6 100644 --- a/libs/auth/src/angular/login/login.component.ts +++ b/libs/auth/src/angular/login/login.component.ts @@ -5,11 +5,17 @@ import { ActivatedRoute, Router, RouterModule } from "@angular/router"; import { first, firstValueFrom, Subject, take, takeUntil } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { LoginEmailServiceAbstraction, RegisterRouteService } from "@bitwarden/auth/common"; +import { + LoginEmailServiceAbstraction, + LoginStrategyServiceAbstraction, + PasswordLoginCredentials, + RegisterRouteService, +} from "@bitwarden/auth/common"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction"; import { CaptchaIFrame } from "@bitwarden/common/auth/captcha-iframe"; +import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; import { ClientType } from "@bitwarden/common/enums"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; @@ -85,6 +91,7 @@ export class LoginComponentV2 implements OnInit, OnDestroy { private i18nService: I18nService, private loginEmailService: LoginEmailServiceAbstraction, private loginService: LoginService, + private loginStrategyService: LoginStrategyServiceAbstraction, private ngZone: NgZone, private platformUtilsService: PlatformUtilsService, private registerRouteService: RegisterRouteService, @@ -137,7 +144,42 @@ export class LoginComponentV2 implements OnInit, OnDestroy { this.destroy$.complete(); } - submit = async () => {}; + submit = async (showToast: boolean): Promise => { + const data = this.formGroup.value; + + await this.setupCaptcha(); + + this.formGroup.markAllAsTouched(); + + // Web specific (start) + if (this.formGroup.invalid && !showToast) { + return; + } + // Web specific (end) + + const credentials = new PasswordLoginCredentials( + data.email, + data.masterPassword, + this.captchaToken, + null, + ); + + const response = await this.loginStrategyService.logIn(credentials); + + await this.saveEmailSettings(); + + if (this.handleCaptchaRequired(response)) { + return; + } else if (await this.handleMigrateEncryptionKey(response)) { + return; + } else if (response.requiresTwoFactor) { + // code ... + } else if (response.forcePasswordReset != ForceSetPasswordReason.None) { + // code ... + } else { + // code ... + } + }; protected async setupCaptcha() { const env = await firstValueFrom(this.environmentService.environment$); diff --git a/libs/auth/src/angular/login/login.service.ts b/libs/auth/src/angular/login/login.service.ts index 9c9e59d5dd..50391486c9 100644 --- a/libs/auth/src/angular/login/login.service.ts +++ b/libs/auth/src/angular/login/login.service.ts @@ -2,6 +2,7 @@ import { UrlTree } from "@angular/router"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; +import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; export interface PasswordPolicies { policies: Policy[]; @@ -10,6 +11,8 @@ export interface PasswordPolicies { } export abstract class LoginService { + handleMigrateEncryptionKey: (result: AuthResult) => Promise; + // Web specific getShowPasswordlessFlag: () => boolean; getOrgPolicies: () => Promise;