diff --git a/.changeset/early-apples-return.md b/.changeset/early-apples-return.md new file mode 100644 index 00000000000..59089bc05c5 --- /dev/null +++ b/.changeset/early-apples-return.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Opt out of combined flow when sign up mode is restricted. diff --git a/integration/presets/envs.ts b/integration/presets/envs.ts index 459a73a22c3..ad988bc4e79 100644 --- a/integration/presets/envs.ts +++ b/integration/presets/envs.ts @@ -123,6 +123,13 @@ const withSignInOrUpEmailLinksFlow = withEmailLinks .setId('withSignInOrUpEmailLinksFlow') .setEnvVariable('public', 'CLERK_SIGN_UP_URL', undefined); +const withSignInOrUpwithRestrictedModeFlow = withEmailCodes + .clone() + .setId('withSignInOrUpwithRestrictedModeFlow') + .setEnvVariable('private', 'CLERK_SECRET_KEY', instanceKeys.get('with-restricted-mode').sk) + .setEnvVariable('public', 'CLERK_PUBLISHABLE_KEY', instanceKeys.get('with-restricted-mode').pk) + .setEnvVariable('public', 'CLERK_SIGN_UP_URL', undefined); + export const envs = { base, withEmailCodes, @@ -141,4 +148,5 @@ export const envs = { withWaitlistdMode, withSignInOrUpFlow, withSignInOrUpEmailLinksFlow, + withSignInOrUpwithRestrictedModeFlow, } as const; diff --git a/integration/tests/sign-in-or-up-restricted-mode.test.ts b/integration/tests/sign-in-or-up-restricted-mode.test.ts new file mode 100644 index 00000000000..554c85078a5 --- /dev/null +++ b/integration/tests/sign-in-or-up-restricted-mode.test.ts @@ -0,0 +1,37 @@ +import { expect, test } from '@playwright/test'; + +import type { Application } from '../models/application'; +import { appConfigs } from '../presets'; +import type { FakeUser } from '../testUtils'; +import { createTestUtils } from '../testUtils'; + +test.describe('sign-in-or-up restricted mode @nextjs', () => { + test.describe.configure({ mode: 'serial' }); + let app: Application; + let fakeUser: FakeUser; + + test.beforeAll(async () => { + app = await appConfigs.next.appRouter.clone().commit(); + await app.setup(); + await app.withEnv(appConfigs.envs.withSignInOrUpwithRestrictedModeFlow); + await app.dev(); + + const m = createTestUtils({ app }); + fakeUser = m.services.users.createFakeUser(); + }); + + test.afterAll(async () => { + await fakeUser.deleteIfExists(); + await app.teardown(); + }); + + test('It does not allow sign-in-or-up flow', async ({ page, context }) => { + const u = createTestUtils({ app, page, context }); + await u.po.signIn.goTo(); + await u.po.signIn.waitForMounted(); + await expect(u.page.getByText(/continue to/i)).toBeHidden(); + await u.po.signIn.getIdentifierInput().fill(fakeUser.email); + await u.po.signIn.continue(); + await expect(u.page.getByText(/no account found with this identifier/i)).toBeVisible(); + }); +}); diff --git a/packages/clerk-js/src/ui/contexts/components/SignIn.ts b/packages/clerk-js/src/ui/contexts/components/SignIn.ts index 0bf148a99a5..9bfdad969b2 100644 --- a/packages/clerk-js/src/ui/contexts/components/SignIn.ts +++ b/packages/clerk-js/src/ui/contexts/components/SignIn.ts @@ -33,8 +33,9 @@ export const SignInContext = createContext(null); export const useSignInContext = (): SignInContextType => { const context = useContext(SignInContext); const { navigate } = useRouter(); - const { displayConfig } = useEnvironment(); + const { displayConfig, userSettings } = useEnvironment(); const { queryParams, queryString } = useRouter(); + const signUpMode = userSettings.signUp.mode; const options = useOptions(); const clerk = useClerk(); @@ -43,7 +44,8 @@ export const useSignInContext = (): SignInContextType => { } const isCombinedFlow = - Boolean(!options.signUpUrl && options.signInUrl && !isAbsoluteUrl(options.signInUrl)) || + (signUpMode !== 'restricted' && + Boolean(!options.signUpUrl && options.signInUrl && !isAbsoluteUrl(options.signInUrl))) || context.withSignUp || false; diff --git a/packages/clerk-js/src/ui/contexts/components/SignUp.ts b/packages/clerk-js/src/ui/contexts/components/SignUp.ts index 6cea37e8777..32b4e4794c0 100644 --- a/packages/clerk-js/src/ui/contexts/components/SignUp.ts +++ b/packages/clerk-js/src/ui/contexts/components/SignUp.ts @@ -32,11 +32,17 @@ export const SignUpContext = createContext(null); export const useSignUpContext = (): SignUpContextType => { const context = useContext(SignUpContext); const { navigate } = useRouter(); - const { displayConfig } = useEnvironment(); + const { displayConfig, userSettings } = useEnvironment(); const { queryParams, queryString } = useRouter(); + const signUpMode = userSettings.signUp.mode; const options = useOptions(); const clerk = useClerk(); - const isCombinedFlow = Boolean(!options.signUpUrl && options.signInUrl && !isAbsoluteUrl(options.signInUrl)); + const isCombinedFlow = + (signUpMode !== 'restricted' && + Boolean( + !options.signUpUrl && options.signInUrl && !isAbsoluteUrl(options.signInUrl) && signUpMode === 'public', + )) || + false; const initialValuesFromQueryParams = useMemo( () => getInitialValuesFromQueryParams(queryString, SIGN_UP_INITIAL_VALUE_KEYS),