fix: always offer MFA+passkey enrollment, separate availability from enforcement
Two fundamental fixes: - user.missing_mfa now triggers MfaEnrollmentError (enroll UI) instead of MfaRequiredError (verify UI). Users without MFA were shown a TOTP code prompt they couldn't fill. - Logto MFA factors always set to [Totp, WebAuthn, BackupCode] with UserControlled policy on startup. Availability is always-on for all users. The vendor auth policy controls enforcement (via MfaEnforcementFilter), not what Logto offers during sign-in. - Removed syncMfaConfigToLogto from VendorAuthPolicyController — vendor policy changes no longer modify Logto's sign-in experience. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -99,13 +99,13 @@ export async function signIn(identifier: string, password: string): Promise<stri
|
||||
const result = await trySubmit();
|
||||
if (result.ok) return result.redirectTo;
|
||||
|
||||
// MFA already enrolled — user must verify (show TOTP input)
|
||||
if (result.code === 'user.missing_mfa' || result.code === 'session.mfa.require_mfa_verification') {
|
||||
// MFA already enrolled — user must verify (show TOTP/passkey input)
|
||||
if (result.code === 'session.mfa.require_mfa_verification') {
|
||||
throw new MfaRequiredError();
|
||||
}
|
||||
|
||||
// MFA not enrolled — offer enrollment (passkey / TOTP)
|
||||
if (result.status === 422 && result.code.includes('mfa')) {
|
||||
if (result.code === 'user.missing_mfa' || (result.status === 422 && result.code.includes('mfa'))) {
|
||||
throw new MfaEnrollmentError();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user