From 27d9cb632631987809003d6b4fe69313c097842e Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Thu, 22 Aug 2024 11:50:39 +0300 Subject: [PATCH] fix(clerk-js): Keep the session cookie while cache is being invalidated Otherwise, in Nextjs apps the invalidate cache server action will result in a 404 if current route is being protected by auth().protect() --- .changeset/sixty-kids-sparkle.md | 5 +++++ .../clerk-js/src/core/__tests__/clerk.test.ts | 19 ------------------- packages/clerk-js/src/core/clerk.ts | 12 ++++++------ 3 files changed, 11 insertions(+), 25 deletions(-) create mode 100644 .changeset/sixty-kids-sparkle.md diff --git a/.changeset/sixty-kids-sparkle.md b/.changeset/sixty-kids-sparkle.md new file mode 100644 index 00000000000..c1c7905909c --- /dev/null +++ b/.changeset/sixty-kids-sparkle.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": patch +--- + +Fix 404s after signing out in NextJS apps by keeping the session cookie while cache is being invalidated diff --git a/packages/clerk-js/src/core/__tests__/clerk.test.ts b/packages/clerk-js/src/core/__tests__/clerk.test.ts index 7c6a20bafdb..31da1d950d3 100644 --- a/packages/clerk-js/src/core/__tests__/clerk.test.ts +++ b/packages/clerk-js/src/core/__tests__/clerk.test.ts @@ -225,25 +225,6 @@ describe('Clerk singleton', () => { expect(mockSession.touch).toHaveBeenCalled(); }); - /** - * The __session cookie needs to be cleared before calling __unstable__onBeforeSetActive - * as the callback may rely on the absence of the cookie to determine the user is logged out or not - * For example, for NextJS integration, calling __unstable__onBeforeSetActive before clearing the cookie - * would result in hitting the middleware with a valid session cookie (until it expires), even if the session no longer exists - */ - it('clears __session cookie before calling __unstable__onBeforeSetActive', async () => { - mockSession.touch.mockReturnValueOnce(Promise.resolve()); - mockClientFetch.mockReturnValue(Promise.resolve({ activeSessions: [mockSession] })); - - (window as any).__unstable__onBeforeSetActive = () => { - expect(eventBusSpy).toHaveBeenCalledWith('token:update', { token: null }); - }; - - const sut = new Clerk(productionPublishableKey); - await sut.load(); - await sut.setActive({ session: null }); - }); - it('sets __session and __client_uat cookie before calling __unstable__onBeforeSetActive', async () => { mockSession.touch.mockReturnValueOnce(Promise.resolve()); mockClientFetch.mockReturnValue(Promise.resolve({ activeSessions: [mockSession] })); diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 7c45a8ba55e..71d2ee505a9 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -731,6 +731,12 @@ export class Clerk implements ClerkInterface { } } + if (session?.lastActiveToken) { + eventBus.dispatch(events.TokenUpdate, { token: session.lastActiveToken }); + } + + await onBeforeSetActive(); + // If this.session exists, then signOut was triggered by the current tab // and should emit. Other tabs should not emit the same event again const shouldSignOutSession = this.session && newSession === null; @@ -739,12 +745,6 @@ export class Clerk implements ClerkInterface { eventBus.dispatch(events.TokenUpdate, { token: null }); } - if (session?.lastActiveToken) { - eventBus.dispatch(events.TokenUpdate, { token: session.lastActiveToken }); - } - - await onBeforeSetActive(); - //1. setLastActiveSession to passed user session (add a param). // Note that this will also update the session's active organization // id.