From 48ffd0b5d674c110a51f6601bbfc24ab0768240d Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Mon, 2 Sep 2024 09:31:10 -0700 Subject: [PATCH] handle submit routing (web) --- apps/web/src/app/core/core.module.ts | 3 +- .../src/auth/components/login.component.ts | 1 + .../src/services/jslib-services.module.ts | 2 +- .../auth/src/angular/login/login.component.ts | 48 +++++++++++++++++-- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index e771ef2a163..45ae3a357f6 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -57,6 +57,7 @@ import { ThemeStateService, } from "@bitwarden/common/platform/theming/theme-state.service"; import { VaultTimeout, VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type"; +import { ToastService } from "@bitwarden/components"; import { PolicyListService } from "../admin-console/core/policy-list.service"; import { WebSetPasswordJitService, WebRegistrationFinishService, WebLoginService } from "../auth"; @@ -211,7 +212,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: LoginService, useClass: WebLoginService, - deps: [], + deps: [I18nServiceAbstraction, ToastService], }), ]; diff --git a/libs/angular/src/auth/components/login.component.ts b/libs/angular/src/auth/components/login.component.ts index e76d02016a8..078492f6a9e 100644 --- a/libs/angular/src/auth/components/login.component.ts +++ b/libs/angular/src/auth/components/login.component.ts @@ -193,6 +193,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, // eslint-disable-next-line @typescript-eslint/no-floating-promises this.onSuccessfulLogin(); } + if (this.onSuccessfulLoginNavigate != null) { // 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 diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 52825274b56..bc4ca8fa05a 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1302,7 +1302,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: LoginService, useClass: DefaultLoginService, - deps: [], + deps: [I18nServiceAbstraction, ToastService], }), ]; diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts index f0a964e8d6b..b65d579b7b6 100644 --- a/libs/auth/src/angular/login/login.component.ts +++ b/libs/auth/src/angular/login/login.component.ts @@ -11,6 +11,8 @@ import { PasswordLoginCredentials, RegisterRouteService, } from "@bitwarden/auth/common"; +import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { PolicyData } from "@bitwarden/common/admin-console/models/data/policy.data"; 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"; @@ -22,6 +24,8 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; +import { UserId } from "@bitwarden/common/types/guid"; import { AsyncActionsModule, ButtonModule, @@ -93,7 +97,9 @@ export class LoginComponentV2 implements OnInit, OnDestroy { private loginService: LoginService, private loginStrategyService: LoginStrategyServiceAbstraction, private ngZone: NgZone, + private passwordStrengthService: PasswordStrengthServiceAbstraction, private platformUtilsService: PlatformUtilsService, + private policyService: InternalPolicyService, private registerRouteService: RegisterRouteService, private router: Router, private toastService: ToastService, @@ -170,17 +176,51 @@ export class LoginComponentV2 implements OnInit, OnDestroy { if (this.handleCaptchaRequired(response)) { return; - } else if (await this.handleMigrateEncryptionKey(response)) { + } else if (await this.loginService.handleMigrateEncryptionKey(response)) { return; } else if (response.requiresTwoFactor) { - // code ... + await this.router.navigate(["2fa"]); } else if (response.forcePasswordReset != ForceSetPasswordReason.None) { - // code ... + this.loginEmailService.clearValues(); + await this.router.navigate(["update-temp-password"]); } else { - // code ... + // Web specific (start) + await this.goAfterLogIn(response.userId); + // Web specific (end) } }; + protected async goAfterLogIn(userId: UserId) { + const masterPassword = this.formGroup.value.masterPassword; + + // Check master password against policy + if (this.enforcedPasswordPolicyOptions != null) { + const strengthResult = this.passwordStrengthService.getPasswordStrength( + masterPassword, + this.formGroup.value.email, + ); + const masterPasswordScore = strengthResult == null ? null : strengthResult.score; + + // If invalid, save policies and require update + if ( + !this.policyService.evaluateMasterPassword( + masterPasswordScore, + masterPassword, + this.enforcedPasswordPolicyOptions, + ) + ) { + const policiesData: { [id: string]: PolicyData } = {}; + this.policies.map((p) => (policiesData[p.id] = PolicyData.fromPolicy(p))); + await this.policyService.replace(policiesData, userId); + await this.router.navigate(["update-password"]); + return; + } + } + + this.loginEmailService.clearValues(); + await this.router.navigate(["vault"]); + } + protected async setupCaptcha() { const env = await firstValueFrom(this.environmentService.environment$); const webVaultUrl = env.getWebVaultUrl();