From a36120003b76680f963b3d6b31011dec1ded9840 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 30 Sep 2024 14:27:44 -0400 Subject: [PATCH] fix(clerk-js): Navigate to `/choose` when signing out during multi session (#4203) --- .changeset/three-nails-fetch.md | 5 ++++ packages/clerk-js/src/core/clerk.ts | 11 +++++++- .../UserButton/__tests__/UserButton.test.tsx | 25 ++++++++++++++++--- .../clerk-js/src/ui/utils/test/mockHelpers.ts | 1 + 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 .changeset/three-nails-fetch.md diff --git a/.changeset/three-nails-fetch.md b/.changeset/three-nails-fetch.md new file mode 100644 index 0000000000..3a687b1752 --- /dev/null +++ b/.changeset/three-nails-fetch.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": patch +--- + +Navigate to `/choose` when signing out during multi session. diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 0aa484da6a..ddd5e93a50 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -969,7 +969,16 @@ export class Clerk implements ClerkInterface { public buildAfterMultiSessionSingleSignOutUrl(): string { if (!this.#options.afterMultiSessionSingleSignOutUrl) { - return this.buildAfterSignOutUrl(); + return this.buildUrlWithAuth( + buildURL( + { + base: this.#options.signInUrl + ? `${this.#options.signInUrl}/choose` + : this.environment?.displayConfig.afterSignOutOneUrl, + }, + { stringify: true }, + ), + ); } return this.buildUrlWithAuth(this.#options.afterMultiSessionSingleSignOutUrl); diff --git a/packages/clerk-js/src/ui/components/UserButton/__tests__/UserButton.test.tsx b/packages/clerk-js/src/ui/components/UserButton/__tests__/UserButton.test.tsx index f9f2bd3142..42692294ab 100644 --- a/packages/clerk-js/src/ui/components/UserButton/__tests__/UserButton.test.tsx +++ b/packages/clerk-js/src/ui/components/UserButton/__tests__/UserButton.test.tsx @@ -1,6 +1,6 @@ import { describe } from '@jest/globals'; -import { render } from '../../../../testUtils'; +import { render, waitFor } from '../../../../testUtils'; import { bindCreateFixtures } from '../../../utils/test/createFixtures'; import { UserButton } from '../UserButton'; @@ -139,11 +139,30 @@ describe('UserButton', () => { it('signs out of the currently active session when clicking "Sign out"', async () => { const { wrapper, fixtures } = await createFixtures(initConfig); - fixtures.clerk.signOut.mockReturnValueOnce(Promise.resolve()); + fixtures.clerk.signOut.mockImplementationOnce(callback => { + return Promise.resolve(callback()); + }); const { getByText, getByRole, userEvent } = render(, { wrapper }); await userEvent.click(getByRole('button', { name: 'Open user button' })); await userEvent.click(getByText('Sign out')); - expect(fixtures.clerk.signOut).toHaveBeenCalledWith(expect.any(Function), { sessionId: '0' }); + await waitFor(() => { + expect(fixtures.clerk.signOut).toHaveBeenCalledWith(expect.any(Function), { sessionId: '0' }); + expect(fixtures.clerk.redirectWithAuth).toHaveBeenCalledWith('https://accounts.clerk.com/sign-in/choose'); + }); + }); + + it('signs out of all currently active session when clicking "Sign out of all accounts"', async () => { + const { wrapper, fixtures } = await createFixtures(initConfig); + fixtures.clerk.signOut.mockImplementationOnce(callback => { + return Promise.resolve(callback()); + }); + const { getByText, getByRole, userEvent } = render(, { wrapper }); + await userEvent.click(getByRole('button', { name: 'Open user button' })); + await userEvent.click(getByText('Sign out of all accounts')); + await waitFor(() => { + expect(fixtures.clerk.signOut).toHaveBeenCalledWith(expect.any(Function)); + expect(fixtures.router.navigate).toHaveBeenCalledWith('/'); + }); }); }); diff --git a/packages/clerk-js/src/ui/utils/test/mockHelpers.ts b/packages/clerk-js/src/ui/utils/test/mockHelpers.ts index 482727622e..8e7cf2a326 100644 --- a/packages/clerk-js/src/ui/utils/test/mockHelpers.ts +++ b/packages/clerk-js/src/ui/utils/test/mockHelpers.ts @@ -65,6 +65,7 @@ export const mockClerkMethods = (clerk: LoadedClerk): DeepJestMocked; };