mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
refactor(core): should not guard sso authentication flow (#6394)
should not guard mfa and profile fulfillment for the sso authentication flow
This commit is contained in:
parent
902e620e84
commit
5024182986
2 changed files with 64 additions and 4 deletions
|
@ -247,10 +247,17 @@ export default class ExperienceInteraction {
|
|||
* Validate the interaction verification records against the sign-in experience and user MFA settings.
|
||||
* The interaction is verified if at least one user enabled MFA verification record is present and verified.
|
||||
*
|
||||
* @throws — RequestError with 404 if the if the user is not identified or not found
|
||||
* @remarks
|
||||
* - EnterpriseSso verified interaction does not require MFA verification.
|
||||
*
|
||||
* @throws {RequestError} with 404 if the if the user is not identified or not found
|
||||
* @throws {RequestError} with 403 if the mfa verification is required but not verified
|
||||
*/
|
||||
public async guardMfaVerificationStatus() {
|
||||
if (this.hasVerifiedSsoIdentity) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await this.getIdentifiedUser();
|
||||
const mfaSettings = await this.signInExperienceValidator.getMfaSettings();
|
||||
const mfaValidator = new MfaValidator(mfaSettings, user);
|
||||
|
@ -338,13 +345,17 @@ export default class ExperienceInteraction {
|
|||
await this.profile.validateAvailability();
|
||||
|
||||
// Profile fulfilled
|
||||
if (!this.hasVerifiedSsoIdentity) {
|
||||
await this.profile.assertUserMandatoryProfileFulfilled();
|
||||
}
|
||||
|
||||
// Revalidate the new MFA data if any
|
||||
await this.mfa.checkAvailability();
|
||||
|
||||
// MFA fulfilled
|
||||
if (!this.hasVerifiedSsoIdentity) {
|
||||
await this.mfa.assertUserMandatoryMfaFulfilled();
|
||||
}
|
||||
|
||||
const { socialIdentity, enterpriseSsoIdentity, ...rest } = this.profile.data;
|
||||
const { mfaSkipped, mfaVerifications } = this.mfa.toUserMfaVerifications();
|
||||
|
@ -534,6 +545,12 @@ export default class ExperienceInteraction {
|
|||
return verificationRecord?.identifier.value === value && verificationRecord.isVerified;
|
||||
}
|
||||
|
||||
private get hasVerifiedSsoIdentity() {
|
||||
const ssoVerificationRecord = this.verificationRecords.get(VerificationType.EnterpriseSso);
|
||||
|
||||
return Boolean(ssoVerificationRecord?.isVerified);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the interaction storage.
|
||||
*/
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { MfaFactor, SignInIdentifier } from '@logto/schemas';
|
||||
import { generateStandardId } from '@logto/shared';
|
||||
|
||||
import { deleteUser, getUser } from '#src/api/admin-user.js';
|
||||
import { createUserMfaVerification, deleteUser, getUser } from '#src/api/admin-user.js';
|
||||
import { updateSignInExperience } from '#src/api/sign-in-experience.js';
|
||||
import { SsoConnectorApi } from '#src/api/sso-connector.js';
|
||||
import { signInWithEnterpriseSso } from '#src/helpers/experience/index.js';
|
||||
import { enableMandatoryMfaWithTotp } from '#src/helpers/sign-in-experience.js';
|
||||
import { generateNewUser } from '#src/helpers/user.js';
|
||||
import { devFeatureTest, generateEmail } from '#src/utils.js';
|
||||
|
||||
|
@ -78,4 +80,45 @@ devFeatureTest.describe('enterprise sso sign-in and sign-up', () => {
|
|||
|
||||
await deleteUser(userId);
|
||||
});
|
||||
|
||||
describe('should not check mfa and profile fulfillment for the enterprise sso authentication flow', () => {
|
||||
const email = generateEmail(domain);
|
||||
const enterpriseSsoIdentityId = generateStandardId();
|
||||
const userIdMap = new Map<string, string>();
|
||||
|
||||
beforeAll(async () => {
|
||||
await updateSignInExperience({
|
||||
signUp: { identifiers: [SignInIdentifier.Username], password: true, verify: false },
|
||||
});
|
||||
await enableMandatoryMfaWithTotp();
|
||||
});
|
||||
|
||||
it('should successfully sign-up with enterprise sso without profile and mfa fulfillment', async () => {
|
||||
const userId = await signInWithEnterpriseSso(
|
||||
ssoConnectorApi.firstConnectorId!,
|
||||
{
|
||||
sub: enterpriseSsoIdentityId,
|
||||
email,
|
||||
email_verified: true,
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
userIdMap.set('ssoUser', userId);
|
||||
});
|
||||
|
||||
it('should successfully sign-in with enterprise sso without mfa validation', async () => {
|
||||
const userId = userIdMap.get('ssoUser')!;
|
||||
|
||||
await createUserMfaVerification(userId, MfaFactor.TOTP);
|
||||
|
||||
await signInWithEnterpriseSso(ssoConnectorApi.firstConnectorId!, {
|
||||
sub: enterpriseSsoIdentityId,
|
||||
email,
|
||||
email_verified: true,
|
||||
});
|
||||
|
||||
await deleteUser(userId);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue