From 6dfc9b8f383495ba3b5a63fc3a775c49587f616a Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Fri, 8 Aug 2025 21:56:34 -0300 Subject: [PATCH 1/3] Remove conditional to always send `redirect_url` for after-auth --- .changeset/mighty-ducks-occur.md | 5 +++++ packages/clerk-js/src/core/resources/SignIn.ts | 16 ++-------------- packages/clerk-js/src/core/resources/SignUp.ts | 9 +-------- 3 files changed, 8 insertions(+), 22 deletions(-) create mode 100644 .changeset/mighty-ducks-occur.md diff --git a/.changeset/mighty-ducks-occur.md b/.changeset/mighty-ducks-occur.md new file mode 100644 index 00000000000..2dd22eaf343 --- /dev/null +++ b/.changeset/mighty-ducks-occur.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Remove sending `redirect_url_complete` as `redirect_url` for SSO with after-auth flows diff --git a/packages/clerk-js/src/core/resources/SignIn.ts b/packages/clerk-js/src/core/resources/SignIn.ts index 1585c731f79..65abd43dd87 100644 --- a/packages/clerk-js/src/core/resources/SignIn.ts +++ b/packages/clerk-js/src/core/resources/SignIn.ts @@ -43,7 +43,6 @@ import type { } from '@clerk/types'; import { - buildURL, generateSignatureWithCoinbaseWallet, generateSignatureWithMetamask, generateSignatureWithOKXWallet, @@ -251,24 +250,13 @@ export class SignIn extends BaseResource implements SignInResource { navigateCallback: (url: URL | string) => void, ): Promise => { const { strategy, redirectUrl, redirectUrlComplete, identifier, oidcPrompt, continueSignIn } = params || {}; - - const redirectUrlWithAuthToken = SignIn.clerk.buildUrlWithAuth(redirectUrl); - - // When after-auth is enabled, redirect to SSO callback route. - // This ensures organization selection tasks are displayed after sign-in, - // rather than redirecting to potentially unprotected pages while the session is pending. - const actionCompleteRedirectUrl = SignIn.clerk.__internal_hasAfterAuthFlows - ? buildURL({ - base: redirectUrlWithAuthToken, - search: `?redirect_url=${redirectUrlComplete}`, - }).toString() - : redirectUrlComplete; + const actionCompleteRedirectUrl = redirectUrlComplete; if (!this.id || !continueSignIn) { await this.create({ strategy, identifier, - redirectUrl: redirectUrlWithAuthToken, + redirectUrl, actionCompleteRedirectUrl, }); } diff --git a/packages/clerk-js/src/core/resources/SignUp.ts b/packages/clerk-js/src/core/resources/SignUp.ts index ed16d882875..079b6c34d67 100644 --- a/packages/clerk-js/src/core/resources/SignUp.ts +++ b/packages/clerk-js/src/core/resources/SignUp.ts @@ -290,18 +290,11 @@ export class SignUp extends BaseResource implements SignUpResource { const redirectUrlWithAuthToken = SignUp.clerk.buildUrlWithAuth(redirectUrl); - // When force after-auth is enabled, redirect to SSO callback route. - // This ensures organization selection tasks are displayed after sign-up, - // rather than redirecting to potentially unprotected pages while the session is pending. - const actionCompleteRedirectUrl = SignUp.clerk.__internal_hasAfterAuthFlows - ? redirectUrlWithAuthToken - : redirectUrlComplete; - const authenticateFn = () => { const authParams = { strategy, redirectUrl: redirectUrlWithAuthToken, - actionCompleteRedirectUrl, + actionCompleteRedirectUrl: redirectUrlComplete, unsafeMetadata, emailAddress, legalAccepted, From dc91b5e3c6032f032af8398fc3753f2492fb64d8 Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Sun, 10 Aug 2025 11:18:25 -0300 Subject: [PATCH 2/3] Fix clean up of OAuth user --- .../tests/session-tasks-sign-up.test.ts | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/integration/tests/session-tasks-sign-up.test.ts b/integration/tests/session-tasks-sign-up.test.ts index 772110429fd..e35caa576b6 100644 --- a/integration/tests/session-tasks-sign-up.test.ts +++ b/integration/tests/session-tasks-sign-up.test.ts @@ -1,19 +1,28 @@ +import { createClerkClient } from '@clerk/backend'; import { expect, test } from '@playwright/test'; import { appConfigs } from '../presets'; +import { instanceKeys } from '../presets/envs'; import type { FakeUser } from '../testUtils'; import { createTestUtils, testAgainstRunningApps } from '../testUtils'; +import { createUserService } from '../testUtils/usersService'; testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( 'session tasks after sign-up flow @nextjs', ({ app }) => { test.describe.configure({ mode: 'serial' }); - let fakeUser: FakeUser; + let regularFakeUser: FakeUser; + let fakeUserForOAuth: FakeUser; test.beforeEach(() => { const u = createTestUtils({ app }); - fakeUser = u.services.users.createFakeUser({ + regularFakeUser = u.services.users.createFakeUser({ + fictionalEmail: true, + withPhoneNumber: true, + withUsername: true, + }); + fakeUserForOAuth = u.services.users.createFakeUser({ fictionalEmail: true, withPhoneNumber: true, withUsername: true, @@ -23,10 +32,18 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( test.afterAll(async () => { const u = createTestUtils({ app }); await u.services.organizations.deleteAll(); - // Delete the user on the OAuth provider instance. - await fakeUser.deleteIfExists(); - // Delete the user on the app instance. - await u.services.users.deleteIfExists({ email: fakeUser.email }); + await regularFakeUser.deleteIfExists(); + + // Delete user from OAuth provider instance + const client = createClerkClient({ + secretKey: instanceKeys.get('oauth-provider').sk, + publishableKey: instanceKeys.get('oauth-provider').pk, + }); + const users = createUserService(client); + await users.deleteIfExists({ email: fakeUserForOAuth.email }); + // Delete OAuth user from `with-session-tasks` instance + await u.services.users.deleteIfExists({ email: fakeUserForOAuth.email }); + await app.teardown(); }); @@ -41,8 +58,8 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( const u = createTestUtils({ app, page, context }); await u.po.signUp.goTo(); await u.po.signUp.signUpWithEmailAndPassword({ - email: fakeUser.email, - password: fakeUser.password, + email: regularFakeUser.email, + password: regularFakeUser.password, }); await u.po.expect.toBeSignedIn(); @@ -71,10 +88,15 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( await u.po.signIn.getGoToSignUp().click(); await u.po.signUp.waitForMounted(); - await u.po.signUp.setEmailAddress(fakeUser.email); + await u.po.signUp.setEmailAddress(fakeUserForOAuth.email); await u.po.signUp.continue(); await u.po.signUp.enterTestOtpCode(); + // TODO - Remove this once FAPI changes are deployed to redirect + // to `redirect_url` for pending sessions on SSO callback + await u.page.waitForAppUrl('/'); + await u.page.goToRelative('/page-protected'); + // Resolves task await u.po.signUp.waitForMounted(); const fakeOrganization = Object.assign(u.services.organizations.createFakeOrganization(), { From 44c77261f58f00e2dfa5d6f8e925afc54d900e79 Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Mon, 11 Aug 2025 11:24:51 -0300 Subject: [PATCH 3/3] Remove condition from E2E test --- integration/tests/session-tasks-sign-up.test.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/integration/tests/session-tasks-sign-up.test.ts b/integration/tests/session-tasks-sign-up.test.ts index e35caa576b6..08a783d3aa3 100644 --- a/integration/tests/session-tasks-sign-up.test.ts +++ b/integration/tests/session-tasks-sign-up.test.ts @@ -92,11 +92,6 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })( await u.po.signUp.continue(); await u.po.signUp.enterTestOtpCode(); - // TODO - Remove this once FAPI changes are deployed to redirect - // to `redirect_url` for pending sessions on SSO callback - await u.page.waitForAppUrl('/'); - await u.page.goToRelative('/page-protected'); - // Resolves task await u.po.signUp.waitForMounted(); const fakeOrganization = Object.assign(u.services.organizations.createFakeOrganization(), {