diff --git a/libs/angular/src/auth/components/sso.component.spec.ts b/libs/angular/src/auth/components/sso.component.spec.ts index 894232af44..6d81b3d61e 100644 --- a/libs/angular/src/auth/components/sso.component.spec.ts +++ b/libs/angular/src/auth/components/sso.component.spec.ts @@ -352,7 +352,7 @@ describe("SsoComponent", () => { describe("Given Trusted Device Encryption is enabled, user doesn't need to set a MP, and forcePasswordReset is required", () => { [ ForceResetPasswordReason.AdminForcePasswordReset, - ForceResetPasswordReason.WeakMasterPassword, + // ForceResetPasswordReason.WeakMasterPassword, -- not possible in SSO flow as set client side ].forEach((forceResetPasswordReason) => { const reasonString = ForceResetPasswordReason[forceResetPasswordReason]; let authResult; @@ -449,7 +449,7 @@ describe("SsoComponent", () => { describe("Force Master Password Reset scenarios", () => { [ ForceResetPasswordReason.AdminForcePasswordReset, - ForceResetPasswordReason.WeakMasterPassword, + // ForceResetPasswordReason.WeakMasterPassword, -- not possible in SSO flow as set client side ].forEach((forceResetPasswordReason) => { const reasonString = ForceResetPasswordReason[forceResetPasswordReason]; diff --git a/libs/angular/src/auth/components/sso.component.ts b/libs/angular/src/auth/components/sso.component.ts index 7e6aca7ec0..c52902d49a 100644 --- a/libs/angular/src/auth/components/sso.component.ts +++ b/libs/angular/src/auth/components/sso.component.ts @@ -226,9 +226,9 @@ export class SsoComponent { return await this.handleChangePasswordRequired(orgIdentifier); } - // Users can be forced to reset their password via an admin or org policy - // disallowing weak passwords - if (authResult.forcePasswordReset !== ForceResetPasswordReason.None) { + // Users enrolled in admin acct recovery can be forced to set a new password after + // having the admin set a temp password for them + if (authResult.forcePasswordReset == ForceResetPasswordReason.AdminForcePasswordReset) { return await this.handleForcePasswordReset(orgIdentifier); } diff --git a/libs/angular/src/auth/components/two-factor.component.ts b/libs/angular/src/auth/components/two-factor.component.ts index 9a6352283a..b87f79a8c4 100644 --- a/libs/angular/src/auth/components/two-factor.component.ts +++ b/libs/angular/src/auth/components/two-factor.component.ts @@ -282,8 +282,10 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI return await this.handleChangePasswordRequired(orgIdentifier); } - // Users can be forced to reset their password via an admin or org policy - // disallowing weak passwords + // Users can be forced to reset their password via an admin or org policy disallowing weak passwords + // Note: this is different from SSO component login flow as a user can + // login with MP and then have to pass 2FA to finish login and we can actually + // evaluate if they have a weak password at this time. if (authResult.forcePasswordReset !== ForceResetPasswordReason.None) { return await this.handleForcePasswordReset(orgIdentifier); } diff --git a/libs/common/src/auth/login-strategies/login.strategy.ts b/libs/common/src/auth/login-strategies/login.strategy.ts index 6e51f21501..96855a3410 100644 --- a/libs/common/src/auth/login-strategies/login.strategy.ts +++ b/libs/common/src/auth/login-strategies/login.strategy.ts @@ -153,6 +153,7 @@ export abstract class LogInStrategy { const result = new AuthResult(); result.resetMasterPassword = response.resetMasterPassword; + // Convert boolean to enum if (response.forcePasswordReset) { result.forcePasswordReset = ForceResetPasswordReason.AdminForcePasswordReset; } diff --git a/libs/common/src/auth/login-strategies/sso-login.strategy.ts b/libs/common/src/auth/login-strategies/sso-login.strategy.ts index 09dbca72fe..328dda527a 100644 --- a/libs/common/src/auth/login-strategies/sso-login.strategy.ts +++ b/libs/common/src/auth/login-strategies/sso-login.strategy.ts @@ -14,6 +14,7 @@ import { DeviceTrustCryptoServiceAbstraction } from "../abstractions/device-trus import { KeyConnectorService } from "../abstractions/key-connector.service"; import { TokenService } from "../abstractions/token.service"; import { TwoFactorService } from "../abstractions/two-factor.service"; +import { ForceResetPasswordReason } from "../models/domain/force-reset-password-reason"; import { SsoLogInCredentials } from "../models/domain/log-in-credentials"; import { SsoTokenRequest } from "../models/request/identity-token/sso-token.request"; import { IdentityTokenResponse } from "../models/response/identity-token.response"; @@ -73,6 +74,11 @@ export class SsoLogInStrategy extends LogInStrategy { this.email = ssoAuthResult.email; this.ssoEmail2FaSessionToken = ssoAuthResult.ssoEmail2FaSessionToken; + // Auth guard currently handles redirects for this. + if (ssoAuthResult.forcePasswordReset == ForceResetPasswordReason.AdminForcePasswordReset) { + await this.stateService.setForcePasswordResetReason(ssoAuthResult.forcePasswordReset); + } + return ssoAuthResult; } diff --git a/libs/common/src/auth/models/domain/force-reset-password-reason.ts b/libs/common/src/auth/models/domain/force-reset-password-reason.ts index c70a4cb33c..99e461c2ea 100644 --- a/libs/common/src/auth/models/domain/force-reset-password-reason.ts +++ b/libs/common/src/auth/models/domain/force-reset-password-reason.ts @@ -1,3 +1,7 @@ +/* + * This enum is used to determine if a user should be forced to reset their password + * on login (server flag) or unlock via MP (client evaluation). + */ export enum ForceResetPasswordReason { /** * A password reset should not be forced. @@ -6,12 +10,14 @@ export enum ForceResetPasswordReason { /** * Occurs when an organization admin forces a user to reset their password. + * Communicated via server flag. */ AdminForcePasswordReset, /** * Occurs when a user logs in / unlocks their vault with a master password that does not meet an organization's * master password policy that is enforced on login/unlock. + * Only set client side b/c server can't evaluate MP. */ WeakMasterPassword, }