Skip to content

Commit

Permalink
fix(experience): fix the email/phone identifier conflict handling log…
Browse files Browse the repository at this point in the history
…ic during user registration

fix the email/phone identifier conflict handling logic during user registration
  • Loading branch information
simeng-li committed Feb 14, 2025
1 parent e7accfd commit 67597aa
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 26 deletions.
29 changes: 29 additions & 0 deletions .changeset/loud-beds-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
"@logto/experience": patch
---

fix the email/phone identifier conflict handling logic during user registration.

When a user attempts to register with an email/phone that already exists:

### Previous Behavior

"Sign in instead" modal will be shown when:

- The email/phone identifier has been verified through a verification code validation
- Identifier type (email/phone) was enabled in sign-in methods

This caused an issue when:

- Only password authentication method was enabled in the sign-in method settings.
- When users clicked "Sign in instead" action button, the API call will throw an sign-in method not enabled error. Which is confusing for the user.

Expected behavior: Show the "Email/phone already exists" error modal directly. If only password authentication is enabled. User should not be able to sign in with email/phone directly.

### Fixed Behavior

Shows the "Sign in instead" modal if:

- The email/phone identifier type is enabled in the sign-in method settings and the verification code is enabled for the identifier.

Otherwise, shows the "Email/phone already exists" error modal directly.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const useRegisterFlowCodeVerification = (
const navigate = useNavigate();
const redirectTo = useGlobalRedirectTo();

const { signInMode } = useSieMethods();
const { signInMode, signInMethods } = useSieMethods();

const handleError = useErrorHandler();

Expand All @@ -56,7 +56,10 @@ const useRegisterFlowCodeVerification = (
const { type, value } = identifier;

// Should not redirect user to sign-in if is register-only mode
if (signInMode === SignInMode.Register) {
if (
signInMode === SignInMode.Register ||
!signInMethods.find(({ identifier }) => identifier === type)?.verificationCode
) {
void showIdentifierErrorAlert(IdentifierErrorType.IdentifierAlreadyExists, type, value);

return;
Expand Down Expand Up @@ -87,17 +90,18 @@ const useRegisterFlowCodeVerification = (
},
});
}, [
handleError,
identifier,
navigate,
redirectTo,
signInMode,
signInMethods,
show,
t,
showIdentifierErrorAlert,
preSignInErrorHandler,
signInMode,
signInWithIdentifierAsync,
t,
verificationId,
handleError,
preSignInErrorHandler,
redirectTo,
navigate,
]);

const errorHandlers = useMemo<ErrorHandlers>(
Expand Down
38 changes: 20 additions & 18 deletions packages/experience/src/hooks/use-sie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,27 @@ import { type VerificationCodeIdentifier } from '@/types';

export const useSieMethods = () => {
const { experienceSettings } = useContext(PageContext);
const socialSignInSettings = experienceSettings?.socialSignIn ?? {};
const { identifiers, password, verify } = experienceSettings?.signUp ?? {};
const { password, verify } = experienceSettings?.signUp ?? {};

return {
signUpMethods: identifiers ?? [],
signUpSettings: { password, verify },
signInMethods:
experienceSettings?.signIn.methods.filter(
// Filter out empty settings
({ password, verificationCode }) => password || verificationCode
) ?? [],
socialSignInSettings,
socialConnectors: experienceSettings?.socialConnectors ?? [],
ssoConnectors: experienceSettings?.ssoConnectors ?? [],
signInMode: experienceSettings?.signInMode,
forgotPassword: experienceSettings?.forgotPassword,
customContent: experienceSettings?.customContent,
singleSignOnEnabled: experienceSettings?.singleSignOnEnabled,
};
return useMemo(
() => ({
signUpMethods: experienceSettings?.signUp.identifiers ?? [],
signUpSettings: { password, verify },
signInMethods:
experienceSettings?.signIn.methods.filter(
// Filter out empty settings
({ password, verificationCode }) => password || verificationCode
) ?? [],
socialSignInSettings: experienceSettings?.socialSignIn ?? {},
socialConnectors: experienceSettings?.socialConnectors ?? [],
ssoConnectors: experienceSettings?.ssoConnectors ?? [],
signInMode: experienceSettings?.signInMode,
forgotPassword: experienceSettings?.forgotPassword,
customContent: experienceSettings?.customContent,
singleSignOnEnabled: experienceSettings?.singleSignOnEnabled,
}),
[experienceSettings, password, verify]
);
};

export const usePasswordPolicy = () => {
Expand Down

0 comments on commit 67597aa

Please sign in to comment.