From 61dff33440a5af0de405e585c42c765b33c4f71a Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:49:02 -0500 Subject: [PATCH] Introduce new base skeleton for URL resolution --- integration/tests/session-tasks.test.ts | 4 +- packages/clerk-js/src/core/clerk.ts | 53 +++++++++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/integration/tests/session-tasks.test.ts b/integration/tests/session-tasks.test.ts index b582b5982a..2ecf8b8da6 100644 --- a/integration/tests/session-tasks.test.ts +++ b/integration/tests/session-tasks.test.ts @@ -1,7 +1,7 @@ import { appConfigs } from '../presets'; import { testAgainstRunningApps } from '../testUtils'; -// TODO ORGS-566 - write integration tests for after-auth flow +// TODO ORGS-566 - Write integration tests for after-auth flow testAgainstRunningApps({ withEnv: [appConfigs.envs.withEmailCodes] })('after-auth flows @generic @nextjs', () => { describe('after sign-in', () => { // /sign-in -> /sign-in/select-organization @@ -25,7 +25,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withEmailCodes] })('after-aut it.todo('on single-session mode, sign-up redirects back to tasks when accessed with a pending session'); }); - describe('middle app', () => { + describe('when user is using the app and session transitions to active to pending', () => { // /my-dashboard/recipes -> /sign-in/select-organization it.todo('on session transition to pending with tasks, redirects to tasks'); diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 4a1cad6080..0de74f34e5 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -1120,13 +1120,53 @@ export class Clerk implements ClerkInterface { } public buildTasksUrl(): string { + const signInUrl = this.#options.signInUrl || this.environment?.displayConfig.signInUrl; + const signUpUrl = this.#options.signUpUrl || this.environment?.displayConfig.signUpUrl; const currentTask = this.session?.currentTask; if (!currentTask) { return ''; } - return buildURL({ hashPath: sessionTaskKeyToRoutePaths[currentTask.key] }, { stringify: true }); + let redirectUrl = ''; + const referrerIsSignInUrl = signInUrl && window.location.href.startsWith(signInUrl); + const referrerIsSignUpUrl = signUpUrl && window.location.href.startsWith(signUpUrl); + + if (referrerIsSignInUrl) { + redirectUrl = this.buildAfterSignInUrl(); + } else if (referrerIsSignUpUrl) { + redirectUrl = this.buildAfterSignUpUrl(); + } else { + /** + * User already has a active session and gets transition to a pending status + * on the client update + * + * It could happen on instance configuration changes that lead to new tasks that + * need to get resolved by the user, eg: Force MFA + */ + // Preserves the origin path, eg: /my-app/recipes -> /sign-in/select-organization -> /my-app/recipes + redirectUrl = window.location.href; + } + + /** + * For after sign-in or after sign-up, it's agnostic to the original base path + * in order to avoid having to check for the referrer + * + * If it's coming from a protected route where the user already exists, then + * the base path becomes the sign in URL + */ + const shouldAppendBasePath = !referrerIsSignInUrl && !referrerIsSignUpUrl; + + return buildURL( + { + ...(shouldAppendBasePath ? { base: signInUrl } : {}), + hashPath: sessionTaskKeyToRoutePaths[currentTask.key], + hashSearchParams: { + redirect_url: redirectUrl, + }, + }, + { stringify: true }, + ); } public buildAfterMultiSessionSingleSignOutUrl(): string { @@ -1750,10 +1790,6 @@ export class Clerk implements ClerkInterface { if (this.session) { const session = this.#getSessionFromClient(this.session.id); - // TODO - Resolve after-task redirection - // TODO - Resolve issue on closing modals on navigation within Clerk.navigate - // sign-in/select-organization -> /home - // sign-in -> sign-in/select-organization const hasResolvedPreviousTask = this.session.currentTask != session?.currentTask; // Note: this might set this.session to null @@ -2114,13 +2150,14 @@ export class Clerk implements ClerkInterface { }); eventBus.on(events.NewSessionTask, () => { - console.log('new session task'); void this.redirectToTasks(); }); eventBus.on(events.ResolvedSessionTask, () => { - console.log('resolved task'); - void this.redirectToAfterSignIn(); + // `redirect_url` gets appended based on the origin (after sign-in vs after sign-up), + // if it gets accidentally deleted, then fallbacks to the sign in URL + const redirectUrl = new URLSearchParams(window.location.search).get('redirect_url') ?? this.buildSignInUrl(); + void this.navigate(redirectUrl); }); };