Skip to content

Commit

Permalink
Introduce new base skeleton for URL resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
LauraBeatris committed Feb 25, 2025
1 parent e15d124 commit 61dff33
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 10 deletions.
4 changes: 2 additions & 2 deletions integration/tests/session-tasks.test.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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');

Expand Down
53 changes: 45 additions & 8 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
});
};

Expand Down

0 comments on commit 61dff33

Please sign in to comment.