From 9585a3826abd1bfc523a25e556b8c9af715bb26c Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Thu, 19 Dec 2024 18:31:16 -0500 Subject: [PATCH 01/12] wip --- packages/clerk-js/src/ui/common/redirects.ts | 12 +++++-- .../src/ui/components/SignIn/SignIn.tsx | 16 ++++++---- .../components/SignUp/SignUpEmailLinkCard.tsx | 9 +++--- .../components/SignUp/SignUpSocialButtons.tsx | 5 +-- .../src/ui/components/SignUp/SignUpStart.tsx | 6 ++-- .../src/ui/contexts/components/SignIn.ts | 31 ++++++++++++++++--- .../src/ui/contexts/components/SignUp.ts | 27 ++++++++++++++++ packages/clerk-js/src/ui/types.ts | 2 ++ 8 files changed, 84 insertions(+), 24 deletions(-) diff --git a/packages/clerk-js/src/ui/common/redirects.ts b/packages/clerk-js/src/ui/common/redirects.ts index 347b45bf9a2..f8bfaf6a365 100644 --- a/packages/clerk-js/src/ui/common/redirects.ts +++ b/packages/clerk-js/src/ui/common/redirects.ts @@ -1,8 +1,8 @@ import { buildURL } from '../../utils/url'; import type { SignInContextType, SignUpContextType, UserProfileContextType } from './../contexts'; -const SSO_CALLBACK_PATH_ROUTE = '/sso-callback'; -const MAGIC_LINK_VERIFY_PATH_ROUTE = '/verify'; +export const SSO_CALLBACK_PATH_ROUTE = '/sso-callback'; +export const MAGIC_LINK_VERIFY_PATH_ROUTE = '/verify'; export function buildEmailLinkRedirectUrl( ctx: SignInContextType | SignUpContextType | UserProfileContextType, @@ -43,7 +43,13 @@ type BuildRedirectUrlParams = { endpoint: string; }; -const buildRedirectUrl = ({ routing, authQueryString, baseUrl, path, endpoint }: BuildRedirectUrlParams): string => { +export const buildRedirectUrl = ({ + routing, + authQueryString, + baseUrl, + path, + endpoint, +}: BuildRedirectUrlParams): string => { // If a routing strategy is not provided, default to hash routing // All routing strategies know how to convert a hash-based url to their own format // Example: navigating from a hash-based to a path-based component, diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx index ea783fc013d..de8722f918f 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx @@ -2,7 +2,9 @@ import { useClerk } from '@clerk/shared/react'; import type { SignInModalProps, SignInProps } from '@clerk/types'; import React from 'react'; +import { normalizeRoutingOptions } from '../../../utils/normalizeRoutingOptions'; import { SignInEmailLinkFlowComplete, SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard'; +import type { SignUpContextType } from '../../contexts'; import { SignInContext, SignUpContext, @@ -145,14 +147,16 @@ function SignInRoutes(): JSX.Element { function SignInRoot() { const signInContext = useSignInContext(); + const normalizedProps = { + componentName: 'SignUp', + ...signInContext.__experimental?.combinedProps, + emailLinkRedirectUrl: signInContext.emailLinkRedirectUrl, + ssoCallbackUrl: signInContext.ssoCallbackUrl, + ...normalizeRoutingOptions({ routing: signInContext?.routing, path: signInContext?.path }), + } as SignUpContextType; return ( - + ); diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx index a5b701e4c93..b1a9aec6c0d 100644 --- a/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/SignUpEmailLinkCard.tsx @@ -3,8 +3,7 @@ import type { SignUpResource } from '@clerk/types'; import React from 'react'; import { EmailLinkStatusCard } from '../../common'; -import { buildEmailLinkRedirectUrl } from '../../common/redirects'; -import { useCoreSignUp, useEnvironment, useSignUpContext } from '../../contexts'; +import { useCoreSignUp, useSignUpContext } from '../../contexts'; import { Flow, localizationKeys, useLocalizations } from '../../customizables'; import { VerificationLinkCard } from '../../elements'; import { useCardState } from '../../elements/contexts'; @@ -19,7 +18,6 @@ export const SignUpEmailLinkCard = () => { const signUpContext = useSignUpContext(); const { afterSignUpUrl } = signUpContext; const card = useCardState(); - const { displayConfig } = useEnvironment(); const { navigate } = useRouter(); const { setActive } = useClerk(); const [showVerifyModal, setShowVerifyModal] = React.useState(false); @@ -36,7 +34,9 @@ export const SignUpEmailLinkCard = () => { }; const startEmailLinkVerification = () => { - return startEmailLinkFlow({ redirectUrl: buildEmailLinkRedirectUrl(signUpContext, displayConfig.signUpUrl) }) + return startEmailLinkFlow({ + redirectUrl: signUpContext.emailLinkRedirectUrl, + }) .then(res => handleVerificationResult(res)) .catch(err => { handleError(err, [], card.setError); @@ -52,6 +52,7 @@ export const SignUpEmailLinkCard = () => { } else { await completeSignUpFlow({ signUp: su, + continuePath: '../continue', verifyEmailPath: '../verify-email-address', verifyPhonePath: '../verify-phone-number', handleComplete: () => setActive({ session: su.createdSessionId, redirectUrl: afterSignUpUrl }), diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx index 9ae045a8a6b..c662d072572 100644 --- a/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/SignUpSocialButtons.tsx @@ -2,9 +2,7 @@ import { useClerk } from '@clerk/shared/react'; import type { OAuthStrategy } from '@clerk/types'; import React from 'react'; -import { buildSSOCallbackURL } from '../../common/redirects'; import { useCoreSignUp, useSignUpContext } from '../../contexts'; -import { useEnvironment } from '../../contexts/EnvironmentContext'; import { useCardState } from '../../elements'; import type { SocialButtonsProps } from '../../elements/SocialButtons'; import { SocialButtons } from '../../elements/SocialButtons'; @@ -17,10 +15,9 @@ export const SignUpSocialButtons = React.memo((props: SignUpSocialButtonsProps) const clerk = useClerk(); const { navigate } = useRouter(); const card = useCardState(); - const { displayConfig } = useEnvironment(); const ctx = useSignUpContext(); const signUp = useCoreSignUp(); - const redirectUrl = buildSSOCallbackURL(ctx, displayConfig.signUpUrl); + const redirectUrl = ctx.ssoCallbackUrl; const redirectUrlComplete = ctx.afterSignUpUrl || '/'; const { continueSignUp = false, ...rest } = props; diff --git a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx index 3f000a1fe53..879c48034e0 100644 --- a/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx +++ b/packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { ERROR_CODES, SIGN_UP_MODES } from '../../../core/constants'; import { getClerkQueryParam, removeClerkQueryParam } from '../../../utils/getClerkQueryParam'; -import { buildSSOCallbackURL, withRedirectToAfterSignUp } from '../../common'; +import { withRedirectToAfterSignUp } from '../../common'; import { SignInContext, useCoreSignUp, useEnvironment, useOptions, useSignUpContext } from '../../contexts'; import { descriptors, Flex, Flow, localizationKeys, useAppearance, useLocalizations } from '../../customizables'; import { @@ -34,7 +34,7 @@ function _SignUpStart(): JSX.Element { const status = useLoadingStatus(); const signUp = useCoreSignUp(); const { showOptionalFields } = useAppearance().parsedLayout; - const { userSettings, displayConfig } = useEnvironment(); + const { userSettings } = useEnvironment(); const { navigate } = useRouter(); const { attributes } = userSettings; const { setActive } = useClerk(); @@ -234,7 +234,7 @@ function _SignUpStart(): JSX.Element { card.setLoading(); card.setError(undefined); - const redirectUrl = buildSSOCallbackURL(ctx, displayConfig.signUpUrl); + const redirectUrl = ctx.ssoCallbackUrl; const redirectUrlComplete = ctx.afterSignUpUrl || '/'; return signUp diff --git a/packages/clerk-js/src/ui/contexts/components/SignIn.ts b/packages/clerk-js/src/ui/contexts/components/SignIn.ts index e089e0f1b9c..7af4515690d 100644 --- a/packages/clerk-js/src/ui/contexts/components/SignIn.ts +++ b/packages/clerk-js/src/ui/contexts/components/SignIn.ts @@ -4,6 +4,7 @@ import { createContext, useContext, useMemo } from 'react'; import { SIGN_IN_INITIAL_VALUE_KEYS } from '../../../core/constants'; import { buildURL } from '../../../utils'; import { RedirectUrls } from '../../../utils/redirectUrls'; +import { buildRedirectUrl, MAGIC_LINK_VERIFY_PATH_ROUTE, SSO_CALLBACK_PATH_ROUTE } from '../../common/redirects'; import { useEnvironment, useOptions } from '../../contexts'; import type { ParsedQueryString } from '../../router'; import { useRouter } from '../../router'; @@ -21,6 +22,8 @@ export type SignInContextType = SignInCtx & { afterSignInUrl: string; transferable: boolean; waitlistUrl: string; + emailLinkRedirectUrl: string; + ssoCallbackUrl: string; }; export const SignInContext = createContext(null); @@ -32,14 +35,14 @@ export const useSignInContext = (): SignInContextType => { const { queryParams, queryString } = useRouter(); const options = useOptions(); const clerk = useClerk(); + const isCombinedFlow = options.experimental?.combinedFlow; if (context === null || context.componentName !== 'SignIn') { throw new Error(`Clerk: useSignInContext called outside of the mounted SignIn component.`); } const { componentName, mode, ..._ctx } = context; - const ctx = _ctx.__experimental?.combinedProps || _ctx; - + const ctx = _ctx.__experimental?.combinedProps ? { ..._ctx, ..._ctx.__experimental?.combinedProps } : _ctx; const initialValuesFromQueryParams = useMemo( () => getInitialValuesFromQueryParams(queryString, SIGN_IN_INITIAL_VALUE_KEYS), [], @@ -65,15 +68,33 @@ export const useSignInContext = (): SignInContextType => { // SignIn's own options won't have a `signInUrl` property, so we have to get the value // from the `path` prop instead, when the routing is set to 'path'. let signInUrl = (ctx.routing === 'path' && ctx.path) || options.signInUrl || displayConfig.signInUrl; - let signUpUrl = ctx.signUpUrl || options.signUpUrl || displayConfig.signUpUrl; + let signUpUrl = isCombinedFlow + ? (ctx.routing === 'path' && ctx.path) || options.signUpUrl || displayConfig.signUpUrl + : ctx.signUpUrl || options.signUpUrl || displayConfig.signUpUrl; let waitlistUrl = ctx.waitlistUrl || options.waitlistUrl || displayConfig.waitlistUrl; const preservedParams = redirectUrls.getPreservedSearchParams(); signInUrl = buildURL({ base: signInUrl, hashSearchParams: [queryParams, preservedParams] }, { stringify: true }); signUpUrl = buildURL({ base: signUpUrl, hashSearchParams: [queryParams, preservedParams] }, { stringify: true }); waitlistUrl = buildURL({ base: waitlistUrl, hashSearchParams: [queryParams, preservedParams] }, { stringify: true }); + const emailLinkRedirectUrl = buildRedirectUrl({ + routing: ctx.routing, + baseUrl: signUpUrl, + authQueryString: '', + path: ctx.path, + endpoint: options.experimental?.combinedFlow + ? '/create' + MAGIC_LINK_VERIFY_PATH_ROUTE + : MAGIC_LINK_VERIFY_PATH_ROUTE, + }); + const ssoCallbackUrl = buildRedirectUrl({ + routing: ctx.routing, + baseUrl: signUpUrl, + authQueryString: '', + path: ctx.path, + endpoint: options.experimental?.combinedFlow ? '/create' + SSO_CALLBACK_PATH_ROUTE : SSO_CALLBACK_PATH_ROUTE, + }); - if (options.experimental?.combinedFlow) { + if (isCombinedFlow) { signUpUrl = buildURL( { base: signInUrl, hashPath: '/create', hashSearchParams: [queryParams, preservedParams] }, { stringify: true }, @@ -91,6 +112,8 @@ export const useSignInContext = (): SignInContextType => { waitlistUrl, afterSignInUrl, afterSignUpUrl, + emailLinkRedirectUrl, + ssoCallbackUrl, navigateAfterSignIn, signUpContinueUrl, queryParams, diff --git a/packages/clerk-js/src/ui/contexts/components/SignUp.ts b/packages/clerk-js/src/ui/contexts/components/SignUp.ts index 643525c4ef9..3fad601803a 100644 --- a/packages/clerk-js/src/ui/contexts/components/SignUp.ts +++ b/packages/clerk-js/src/ui/contexts/components/SignUp.ts @@ -4,6 +4,7 @@ import { createContext, useContext, useMemo } from 'react'; import { SIGN_UP_INITIAL_VALUE_KEYS } from '../../../core/constants'; import { buildURL } from '../../../utils'; import { RedirectUrls } from '../../../utils/redirectUrls'; +import { buildRedirectUrl, MAGIC_LINK_VERIFY_PATH_ROUTE, SSO_CALLBACK_PATH_ROUTE } from '../../common/redirects'; import { useEnvironment, useOptions } from '../../contexts'; import type { ParsedQueryString } from '../../router'; import { useRouter } from '../../router'; @@ -20,6 +21,8 @@ export type SignUpContextType = SignUpCtx & { afterSignUpUrl: string; afterSignInUrl: string; waitlistUrl: string; + emailLinkRedirectUrl: string; + ssoCallbackUrl: string; }; export const SignUpContext = createContext(null); @@ -63,6 +66,7 @@ export const useSignUpContext = (): SignUpContextType => { // SignUp's own options won't have a `signUpUrl` property, so we have to get the value // from the `path` prop instead, when the routing is set to 'path'. let signUpUrl = (ctx.routing === 'path' && ctx.path) || options.signUpUrl || displayConfig.signUpUrl; + console.log({ signUpUrlBeforeBuildUrlInSignUp: signUpUrl }); let signInUrl = ctx.signInUrl || options.signInUrl || displayConfig.signInUrl; let waitlistUrl = ctx.waitlistUrl || options.waitlistUrl || displayConfig.waitlistUrl; @@ -71,6 +75,27 @@ export const useSignUpContext = (): SignUpContextType => { signUpUrl = buildURL({ base: signUpUrl, hashSearchParams: [queryParams, preservedParams] }, { stringify: true }); waitlistUrl = buildURL({ base: waitlistUrl, hashSearchParams: [queryParams, preservedParams] }, { stringify: true }); + const emailLinkRedirectUrl = + ctx.emailLinkRedirectUrl ?? + buildRedirectUrl({ + routing: ctx.routing, + baseUrl: signUpUrl, + authQueryString: '', + path: ctx.path, + endpoint: options.experimental?.combinedFlow + ? '/create' + MAGIC_LINK_VERIFY_PATH_ROUTE + : MAGIC_LINK_VERIFY_PATH_ROUTE, + }); + const ssoCallbackUrl = + ctx.ssoCallbackUrl ?? + buildRedirectUrl({ + routing: ctx.routing, + baseUrl: signUpUrl, + authQueryString: '', + path: ctx.path, + endpoint: options.experimental?.combinedFlow ? '/create' + SSO_CALLBACK_PATH_ROUTE : SSO_CALLBACK_PATH_ROUTE, + }); + // TODO: Avoid building this url again to remove duplicate code. Get it from window.Clerk instead. const secondFactorUrl = buildURL({ base: signInUrl, hashPath: '/factor-two' }, { stringify: true }); @@ -83,6 +108,8 @@ export const useSignUpContext = (): SignUpContextType => { secondFactorUrl, afterSignUpUrl, afterSignInUrl, + emailLinkRedirectUrl, + ssoCallbackUrl, navigateAfterSignUp, queryParams, initialValues: { ...ctx.initialValues, ...initialValuesFromQueryParams }, diff --git a/packages/clerk-js/src/ui/types.ts b/packages/clerk-js/src/ui/types.ts index d9af51adce8..e90ebfff249 100644 --- a/packages/clerk-js/src/ui/types.ts +++ b/packages/clerk-js/src/ui/types.ts @@ -58,6 +58,8 @@ export type UserProfileCtx = UserProfileProps & { export type SignUpCtx = SignUpProps & { componentName: 'SignUp'; mode?: ComponentMode; + emailLinkRedirectUrl?: string; + ssoCallbackUrl?: string; }; export type UserButtonCtx = UserButtonProps & { From 81c230a6dcda6089e6906d1abe8c2fe840725b44 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 20 Dec 2024 13:28:00 -0500 Subject: [PATCH 02/12] resolve types --- packages/clerk-js/src/ui/contexts/components/SignIn.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/clerk-js/src/ui/contexts/components/SignIn.ts b/packages/clerk-js/src/ui/contexts/components/SignIn.ts index 7af4515690d..772345947cf 100644 --- a/packages/clerk-js/src/ui/contexts/components/SignIn.ts +++ b/packages/clerk-js/src/ui/contexts/components/SignIn.ts @@ -104,7 +104,7 @@ export const useSignInContext = (): SignInContextType => { const signUpContinueUrl = buildURL({ base: signUpUrl, hashPath: '/continue' }, { stringify: true }); return { - ...ctx, + ...(ctx as SignInCtx), transferable: ctx.transferable ?? true, componentName, signUpUrl, @@ -119,5 +119,5 @@ export const useSignInContext = (): SignInContextType => { queryParams, initialValues: { ...ctx.initialValues, ...initialValuesFromQueryParams }, authQueryString: redirectUrls.toSearchParams().toString(), - }; + } as SignInContextType; }; From 69fd8a9cf8e919e0baca7c9a564a468130b91d98 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 20 Dec 2024 13:34:59 -0500 Subject: [PATCH 03/12] Create flat-actors-clean.md --- .changeset/flat-actors-clean.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/flat-actors-clean.md diff --git a/.changeset/flat-actors-clean.md b/.changeset/flat-actors-clean.md new file mode 100644 index 00000000000..6a9db39070a --- /dev/null +++ b/.changeset/flat-actors-clean.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Fix combined flow routing. From ec464766b14196dd1378f894edb28545987f8f8f Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 20 Dec 2024 15:32:47 -0500 Subject: [PATCH 04/12] add check for password enabled --- packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx | 1 + .../src/ui/components/SignIn/handleCombinedFlowTransfer.ts | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx index a35371b199b..a4895912d6e 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx @@ -387,6 +387,7 @@ export function _SignInStart(): JSX.Element { signUpMode: userSettings.signUp.mode, redirectUrl, redirectUrlComplete, + passwordEnabled: userSettings.attributes.password.required, }); } else { handleError(e, [identifierField, instantPasswordField], card.setError); diff --git a/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts b/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts index bad25a763d6..7155b2a03f2 100644 --- a/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts +++ b/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts @@ -14,6 +14,7 @@ type HandleCombinedFlowTransferProps = { handleError: (err: any) => void; redirectUrl?: string; redirectUrlComplete?: string; + passwordEnabled: boolean; }; /** @@ -31,6 +32,7 @@ export function handleCombinedFlowTransfer({ handleError, redirectUrl, redirectUrlComplete, + passwordEnabled, }: HandleCombinedFlowTransferProps): Promise | void { if (signUpMode === SIGN_UP_MODES.WAITLIST) { const waitlistUrl = clerk.buildWaitlistUrl( @@ -54,7 +56,7 @@ export function handleCombinedFlowTransfer({ // Attempt to transfer directly to sign up verification if email or phone was used and there are no optional fields. The signUp.create() call will // inform us if the instance is eligible for moving directly to verification. if ( - (!hasOptionalFields(clerk.client.signUp) && identifierAttribute === 'emailAddress') || + (!passwordEnabled && !hasOptionalFields(clerk.client.signUp) && identifierAttribute === 'emailAddress') || identifierAttribute === 'phoneNumber' ) { return clerk.client.signUp From e458e55efa3416e4100258abd091c1b824828e58 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 20 Dec 2024 15:34:33 -0500 Subject: [PATCH 05/12] update comment --- .../src/ui/components/SignIn/handleCombinedFlowTransfer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts b/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts index 7155b2a03f2..1726166978f 100644 --- a/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts +++ b/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts @@ -53,7 +53,7 @@ export function handleCombinedFlowTransfer({ paramsToForward.set('__clerk_ticket', organizationTicket); } - // Attempt to transfer directly to sign up verification if email or phone was used and there are no optional fields. The signUp.create() call will + // Attempt to transfer directly to sign up verification if email or phone was used, there are no optional fields, and password is not enabled. The signUp.create() call will // inform us if the instance is eligible for moving directly to verification. if ( (!passwordEnabled && !hasOptionalFields(clerk.client.signUp) && identifierAttribute === 'emailAddress') || From 1eef6f56bb9ad4c8cf34cdd65fb126ca37431b38 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Fri, 20 Dec 2024 16:08:29 -0500 Subject: [PATCH 06/12] fix up conditional --- .../src/ui/components/SignIn/handleCombinedFlowTransfer.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts b/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts index 1726166978f..60ff47cb996 100644 --- a/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts +++ b/packages/clerk-js/src/ui/components/SignIn/handleCombinedFlowTransfer.ts @@ -56,8 +56,9 @@ export function handleCombinedFlowTransfer({ // Attempt to transfer directly to sign up verification if email or phone was used, there are no optional fields, and password is not enabled. The signUp.create() call will // inform us if the instance is eligible for moving directly to verification. if ( - (!passwordEnabled && !hasOptionalFields(clerk.client.signUp) && identifierAttribute === 'emailAddress') || - identifierAttribute === 'phoneNumber' + !passwordEnabled && + !hasOptionalFields(clerk.client.signUp) && + (identifierAttribute === 'emailAddress' || identifierAttribute === 'phoneNumber') ) { return clerk.client.signUp .create({ From 4b5cb39362a69889bcef2e6712a0e7859f3c1fce Mon Sep 17 00:00:00 2001 From: Dylan Staley <88163+dstaley@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:27:52 -0800 Subject: [PATCH 07/12] fix(tests): Update combined sign in tests --- .../tests/combined-sign-up-flow.test.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/integration/tests/combined-sign-up-flow.test.ts b/integration/tests/combined-sign-up-flow.test.ts index e2c3d8adc29..93818d0b95b 100644 --- a/integration/tests/combined-sign-up-flow.test.ts +++ b/integration/tests/combined-sign-up-flow.test.ts @@ -23,15 +23,17 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withCombinedFlow] })('combine // Fill in sign in form await u.po.signIn.setIdentifier(fakeUser.email); await u.po.signIn.continue(); + await u.page.waitForAppUrl('/sign-in/create'); - // Verify email - await u.po.signUp.enterTestOtpCode(); - - await u.page.waitForAppUrl('/sign-in/create/continue'); + const prefilledEmail = await u.po.signUp.getEmailAddressInput().inputValue(); + expect(prefilledEmail).toBe(fakeUser.email); await u.po.signUp.setPassword(fakeUser.password); await u.po.signUp.continue(); + // Verify email + await u.po.signUp.enterTestOtpCode(); + // Check if user is signed in await u.po.expect.toBeSignedIn(); @@ -69,7 +71,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withCombinedFlow] })('combine const u = createTestUtils({ app, page, context }); const fakeUser = u.services.users.createFakeUser({ fictionalEmail: true, - withPhoneNumber: true, + withPassword: true, withUsername: true, }); @@ -79,15 +81,17 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withCombinedFlow] })('combine // Fill in sign in form await u.po.signIn.setIdentifier(fakeUser.email); await u.po.signIn.continue(); + await u.page.waitForAppUrl('/sign-in/create'); - // Verify email - await u.po.signUp.enterTestOtpCode(); - - await u.page.waitForAppUrl('/sign-in/create/continue'); + const prefilledEmail = await u.po.signUp.getEmailAddressInput().inputValue(); + expect(prefilledEmail).toBe(fakeUser.email); await u.po.signUp.setPassword(fakeUser.password); await u.po.signUp.continue(); + // Verify email + await u.po.signUp.enterTestOtpCode(); + // Check if user is signed in await u.po.expect.toBeSignedIn(); From e191d9916206a189c2d9a6f15d81192cab4f1da0 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Tue, 7 Jan 2025 13:35:07 -0500 Subject: [PATCH 08/12] remove log --- packages/clerk-js/src/ui/contexts/components/SignUp.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/clerk-js/src/ui/contexts/components/SignUp.ts b/packages/clerk-js/src/ui/contexts/components/SignUp.ts index 3fad601803a..e142ac4e5a9 100644 --- a/packages/clerk-js/src/ui/contexts/components/SignUp.ts +++ b/packages/clerk-js/src/ui/contexts/components/SignUp.ts @@ -66,7 +66,6 @@ export const useSignUpContext = (): SignUpContextType => { // SignUp's own options won't have a `signUpUrl` property, so we have to get the value // from the `path` prop instead, when the routing is set to 'path'. let signUpUrl = (ctx.routing === 'path' && ctx.path) || options.signUpUrl || displayConfig.signUpUrl; - console.log({ signUpUrlBeforeBuildUrlInSignUp: signUpUrl }); let signInUrl = ctx.signInUrl || options.signInUrl || displayConfig.signInUrl; let waitlistUrl = ctx.waitlistUrl || options.waitlistUrl || displayConfig.waitlistUrl; From a722d50dd01d82daf0d3435b8f2a53036246115a Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Tue, 7 Jan 2025 13:58:54 -0500 Subject: [PATCH 09/12] Update packages/clerk-js/src/ui/components/SignIn/SignIn.tsx Co-authored-by: Bryce Kalow --- packages/clerk-js/src/ui/components/SignIn/SignIn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx index de8722f918f..ac8676de403 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx @@ -147,7 +147,7 @@ function SignInRoutes(): JSX.Element { function SignInRoot() { const signInContext = useSignInContext(); - const normalizedProps = { + const normalizedSignUpContext = { componentName: 'SignUp', ...signInContext.__experimental?.combinedProps, emailLinkRedirectUrl: signInContext.emailLinkRedirectUrl, From 800f3bbd8cb154d25d01278b8b7a0feb7de044f2 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Tue, 7 Jan 2025 13:59:01 -0500 Subject: [PATCH 10/12] Update packages/clerk-js/src/ui/components/SignIn/SignIn.tsx Co-authored-by: Bryce Kalow --- packages/clerk-js/src/ui/components/SignIn/SignIn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx index ac8676de403..dde7ba7278f 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx @@ -156,7 +156,7 @@ function SignInRoot() { } as SignUpContextType; return ( - + ); From c836acb3d2478a0e58cb8ef62cf1fde26da50d8f Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Tue, 7 Jan 2025 13:59:11 -0500 Subject: [PATCH 11/12] Update packages/clerk-js/src/ui/components/SignIn/SignIn.tsx Co-authored-by: Bryce Kalow --- packages/clerk-js/src/ui/components/SignIn/SignIn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx index dde7ba7278f..28daba191dd 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx @@ -153,7 +153,7 @@ function SignInRoot() { emailLinkRedirectUrl: signInContext.emailLinkRedirectUrl, ssoCallbackUrl: signInContext.ssoCallbackUrl, ...normalizeRoutingOptions({ routing: signInContext?.routing, path: signInContext?.path }), - } as SignUpContextType; + } satisfies SignUpContextType; return ( From 92e74f5ecfbfe380d0957b44342dd9a5833b4900 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Tue, 7 Jan 2025 14:33:43 -0500 Subject: [PATCH 12/12] use as --- packages/clerk-js/src/ui/components/SignIn/SignIn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx index 28daba191dd..dde7ba7278f 100644 --- a/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx +++ b/packages/clerk-js/src/ui/components/SignIn/SignIn.tsx @@ -153,7 +153,7 @@ function SignInRoot() { emailLinkRedirectUrl: signInContext.emailLinkRedirectUrl, ssoCallbackUrl: signInContext.ssoCallbackUrl, ...normalizeRoutingOptions({ routing: signInContext?.routing, path: signInContext?.path }), - } satisfies SignUpContextType; + } as SignUpContextType; return (