diff --git a/.changeset/thirty-experts-knock.md b/.changeset/thirty-experts-knock.md new file mode 100644 index 00000000000..d378cf5d13f --- /dev/null +++ b/.changeset/thirty-experts-knock.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Navigate to tasks on `sso-callback` route diff --git a/integration/tests/session-tasks-sign-up.test.ts b/integration/tests/session-tasks-sign-up.test.ts index aad5e5fd3c2..d43ea2c5def 100644 --- a/integration/tests/session-tasks-sign-up.test.ts +++ b/integration/tests/session-tasks-sign-up.test.ts @@ -11,7 +11,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( let fakeUser: FakeUser; - test.beforeAll(() => { + test.beforeEach(() => { const u = createTestUtils({ app }); fakeUser = u.services.users.createFakeUser({ fictionalEmail: true, @@ -27,6 +27,12 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( await app.teardown(); }); + test.afterEach(async ({ page, context }) => { + const u = createTestUtils({ app, page, context }); + await u.page.signOut(); + await u.page.context().clearCookies(); + }); + test('navigate to task on after sign-up', async ({ page, context }) => { // Performs sign-up const u = createTestUtils({ app, page, context }); @@ -51,5 +57,31 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( // Navigates to after sign-up await u.page.waitForAppUrl('/'); }); + + test('with sso, navigate to task on after sign-up', async ({ page, context }) => { + const u = createTestUtils({ app, page, context }); + + await u.po.signUp.goTo(); + await u.page.getByRole('button', { name: 'E2E OAuth Provider' }).click(); + + await u.po.signIn.waitForMounted(); + await u.po.signIn.getGoToSignUp().click(); + + await u.po.signUp.waitForMounted(); + await u.po.signUp.setEmailAddress(fakeUser.email); + await u.po.signUp.continue(); + await u.po.signUp.enterTestOtpCode(); + + // Resolves task + await u.po.signIn.waitForMounted(); + const fakeOrganization = Object.assign(u.services.organizations.createFakeOrganization(), { + slug: u.services.organizations.createFakeOrganization().slug + '-with-sign-in-sso', + }); + await u.po.sessionTask.resolveForceOrganizationSelectionTask(fakeOrganization); + await u.po.expect.toHaveResolvedTask(); + + // Navigates to after sign-up + await u.page.waitForAppUrl('/'); + }); }, ); diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json index 1c60f243df8..8e2e4fa4c06 100644 --- a/packages/clerk-js/bundlewatch.config.json +++ b/packages/clerk-js/bundlewatch.config.json @@ -1,11 +1,11 @@ { "files": [ - { "path": "./dist/clerk.js", "maxSize": "616.27KB" }, + { "path": "./dist/clerk.js", "maxSize": "618KB" }, { "path": "./dist/clerk.browser.js", "maxSize": "72.2KB" }, { "path": "./dist/clerk.legacy.browser.js", "maxSize": "115.08KB" }, { "path": "./dist/clerk.headless*.js", "maxSize": "55KB" }, - { "path": "./dist/ui-common*.js", "maxSize": "111.57KB" }, - { "path": "./dist/ui-common*.legacy.*.js", "maxSize": "115.38KB" }, + { "path": "./dist/ui-common*.js", "maxSize": "113KB" }, + { "path": "./dist/ui-common*.legacy.*.js", "maxSize": "118KB" }, { "path": "./dist/vendors*.js", "maxSize": "40.2KB" }, { "path": "./dist/coinbase*.js", "maxSize": "38KB" }, { "path": "./dist/stripe-vendors*.js", "maxSize": "1KB" }, diff --git a/packages/clerk-js/src/ui/common/SSOCallback.tsx b/packages/clerk-js/src/ui/common/SSOCallback.tsx index 5dc908bdfb3..27fba8c9e76 100644 --- a/packages/clerk-js/src/ui/common/SSOCallback.tsx +++ b/packages/clerk-js/src/ui/common/SSOCallback.tsx @@ -19,13 +19,19 @@ export const SSOCallback = withCardStateProvider { - const { handleRedirectCallback, __internal_setActiveInProgress } = useClerk(); + const { handleRedirectCallback, __internal_setActiveInProgress, __internal_navigateToTaskIfAvailable, session } = + useClerk(); const { navigate } = useRouter(); const card = useCardState(); React.useEffect(() => { let timeoutId: ReturnType; if (__internal_setActiveInProgress !== true) { + if (session?.currentTask) { + void __internal_navigateToTaskIfAvailable(); + return; + } + const intent = new URLSearchParams(window.location.search).get('intent'); const reloadResource = intent === 'signIn' || intent === 'signUp' ? intent : undefined; handleRedirectCallback({ ...props, reloadResource }, navigate).catch(e => {