Skip to content

Commit

Permalink
fix(clerk-js): Use afterSwitchSessionUrl switching sessions within …
Browse files Browse the repository at this point in the history
…`UserButton` (#4726)
  • Loading branch information
panteliselef authored Dec 12, 2024
1 parent a6ee05b commit 85a36a8
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/neat-donkeys-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-js': patch
---

Bug fix: Use `afterSwitchSessionUrl` instead of using`afterSignInUrl`when switching sessions within`<UserButton/>`.
9 changes: 1 addition & 8 deletions packages/clerk-js/src/core/__tests__/clerk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,6 @@ describe('Clerk singleton', () => {
expect(mockClientRemoveSessions).toHaveBeenCalled();
expect(sut.setActive).toHaveBeenCalledWith({
session: null,
beforeEmit: expect.any(Function),
redirectUrl: '/',
});
});
Expand All @@ -590,7 +589,6 @@ describe('Clerk singleton', () => {
expect(mockSession1.remove).not.toHaveBeenCalled();
expect(sut.setActive).toHaveBeenCalledWith({
session: null,
beforeEmit: expect.any(Function),
redirectUrl: '/',
});
});
Expand All @@ -614,7 +612,6 @@ describe('Clerk singleton', () => {
expect(mockClientDestroy).not.toHaveBeenCalled();
expect(sut.setActive).not.toHaveBeenCalledWith({
session: null,
beforeEmit: expect.any(Function),
});
});
});
Expand All @@ -637,7 +634,6 @@ describe('Clerk singleton', () => {
expect(mockClientDestroy).not.toHaveBeenCalled();
expect(sut.setActive).toHaveBeenCalledWith({
session: null,
beforeEmit: expect.any(Function),
redirectUrl: '/',
});
});
Expand All @@ -653,19 +649,16 @@ describe('Clerk singleton', () => {
);

const sut = new Clerk(productionPublishableKey);
sut.setActive = jest.fn(async ({ beforeEmit }) => void (beforeEmit && beforeEmit()));
sut.navigate = jest.fn();
sut.setActive = jest.fn();
await sut.load();
await sut.signOut({ sessionId: '1', redirectUrl: '/after-sign-out' });
await waitFor(() => {
expect(mockSession1.remove).toHaveBeenCalled();
expect(mockClientDestroy).not.toHaveBeenCalled();
expect(sut.setActive).toHaveBeenCalledWith({
session: null,
beforeEmit: expect.any(Function),
redirectUrl: '/after-sign-out',
});
expect(sut.navigate).toHaveBeenCalledWith('/after-sign-out');
});
});
});
Expand Down
36 changes: 22 additions & 14 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,21 @@ export class Clerk implements ClerkInterface {
const opts = callbackOrOptions && typeof callbackOrOptions === 'object' ? callbackOrOptions : options || {};

const redirectUrl = opts?.redirectUrl || this.buildAfterSignOutUrl();
const defaultCb = () => this.navigate(redirectUrl);
const cb = typeof callbackOrOptions === 'function' ? callbackOrOptions : defaultCb;

const handleSetActive = () => {
const signOutCallback = typeof callbackOrOptions === 'function' ? callbackOrOptions : undefined;
if (signOutCallback) {
return this.setActive({
session: null,
beforeEmit: ignoreEventValue(signOutCallback),
});
}

return this.setActive({
session: null,
redirectUrl,
});
};

if (!opts.sessionId || this.client.activeSessions.length === 1) {
if (this.#options.experimental?.persistClient ?? true) {
Expand All @@ -379,22 +392,14 @@ export class Clerk implements ClerkInterface {
await this.client.destroy();
}

return this.setActive({
session: null,
beforeEmit: ignoreEventValue(cb),
redirectUrl,
});
return handleSetActive();
}

const session = this.client.activeSessions.find(s => s.id === opts.sessionId);
const shouldSignOutCurrent = session?.id && this.session?.id === session.id;
await session?.remove();
if (shouldSignOutCurrent) {
return this.setActive({
session: null,
beforeEmit: ignoreEventValue(cb),
redirectUrl,
});
return handleSetActive();
}
};

Expand Down Expand Up @@ -906,12 +911,15 @@ export class Clerk implements ClerkInterface {
if (beforeEmit) {
beforeUnloadTracker?.startTracking();
this.#setTransitiveState();
deprecated('beforeEmit', 'Use the `redirectUrl` property instead.');
deprecated(
'Clerk.setActive({beforeEmit})',
'Use the `redirectUrl` property instead. Example `Clerk.setActive({redirectUrl:"/"})`',
);
await beforeEmit(newSession);
beforeUnloadTracker?.stopTracking();
}

if (redirectUrl) {
if (redirectUrl && !beforeEmit) {
beforeUnloadTracker?.startTracking();
this.#setTransitiveState();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import { useMultisessionActions } from '../UserButton/useMultisessionActions';
const _SignInAccountSwitcher = () => {
const card = useCardState();
const { userProfileUrl } = useEnvironment().displayConfig;
const { navigateAfterSignIn, afterSignInUrl, path: signInPath } = useSignInContext();
const { afterSignInUrl, path: signInPath } = useSignInContext();
const { navigateAfterSignOut } = useSignOutContext();
const { handleSignOutAllClicked, handleSessionClicked, activeSessions, handleAddAccountClicked } =
useMultisessionActions({
navigateAfterSignOut,
navigateAfterSwitchSession: navigateAfterSignIn,
afterSignInUrl,
afterSwitchSessionUrl: afterSignInUrl,
userProfileUrl,
signInUrl: signInPath,
user: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const UserButtonPopover = React.forwardRef<HTMLDivElement, UserButtonPopo
const { close: unsafeClose, ...rest } = props;
const close = () => unsafeClose?.(false);
const { session } = useSession() as { session: ActiveSessionResource };
const { __experimental_asStandalone } = useUserButtonContext();
const userButtonContext = useUserButtonContext();
const { __experimental_asStandalone } = userButtonContext;
const { authConfig } = useEnvironment();
const { user } = useUser();
const {
Expand All @@ -26,7 +27,7 @@ export const UserButtonPopover = React.forwardRef<HTMLDivElement, UserButtonPopo
handleSignOutSessionClicked,
handleUserProfileActionClicked,
otherSessions,
} = useMultisessionActions({ ...useUserButtonContext(), actionCompleteCallback: close, user });
} = useMultisessionActions({ ...userButtonContext, actionCompleteCallback: close, user });

return (
<RootBox elementDescriptor={descriptors.userButtonPopoverRootBox}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ type UseMultisessionActionsParams = {
actionCompleteCallback?: () => void;
navigateAfterSignOut?: () => any;
navigateAfterMultiSessionSingleSignOut?: () => any;
navigateAfterSwitchSession?: () => any;
afterSignInUrl?: string;
afterSwitchSessionUrl?: string;
userProfileUrl?: string;
signInUrl?: string;
} & Pick<UserButtonProps, 'userProfileMode' | 'appearance' | 'userProfileProps'>;
Expand Down Expand Up @@ -69,7 +68,7 @@ export const useMultisessionActions = (opts: UseMultisessionActionsParams) => {

const handleSessionClicked = (session: ActiveSessionResource) => async () => {
card.setLoading();
return setActive({ session, redirectUrl: opts.afterSignInUrl }).finally(() => {
return setActive({ session, redirectUrl: opts.afterSwitchSessionUrl }).finally(() => {
card.setIdle();
opts.actionCompleteCallback?.();
});
Expand Down
2 changes: 0 additions & 2 deletions packages/clerk-js/src/ui/contexts/components/SignOut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ export type SignOutContextType = {
export const useSignOutContext = (): SignOutContextType => {
const { navigate } = useRouter();
const clerk = useClerk();

const navigateAfterSignOut = () => navigate(clerk.buildAfterSignOutUrl());
const navigateAfterMultiSessionSingleSignOutUrl = () => navigate(clerk.buildAfterMultiSessionSingleSignOutUrl());

return {
navigateAfterSignOut,
navigateAfterMultiSessionSingleSignOutUrl,
Expand Down
2 changes: 0 additions & 2 deletions packages/clerk-js/src/ui/contexts/components/UserButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export const useUserButtonContext = () => {
const navigateAfterMultiSessionSingleSignOut = () => clerk.redirectWithAuth(afterMultiSessionSingleSignOutUrl);

const afterSwitchSessionUrl = ctx.afterSwitchSessionUrl || displayConfig.afterSwitchSessionUrl;
const navigateAfterSwitchSession = () => navigate(afterSwitchSessionUrl);

const userProfileMode = !!ctx.userProfileUrl && !ctx.userProfileMode ? 'navigation' : ctx.userProfileMode;

Expand All @@ -57,7 +56,6 @@ export const useUserButtonContext = () => {
componentName,
navigateAfterMultiSessionSingleSignOut,
navigateAfterSignOut,
navigateAfterSwitchSession,
signInUrl,
userProfileUrl,
afterMultiSessionSingleSignOutUrl,
Expand Down

0 comments on commit 85a36a8

Please sign in to comment.