Skip to content

Commit

Permalink
fix(clerk-js): Remove session cookie when signing out and `onBeforeSe…
Browse files Browse the repository at this point in the history
…tActive` (#3371)
  • Loading branch information
octoper committed May 16, 2024
1 parent c106022 commit 1fdd436
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-turtles-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-js': patch
---

Remove cookie when signing out before running `onBeforeSetActive` to resolve issues where we do navigations in `onBeforeSetActive`.
19 changes: 19 additions & 0 deletions packages/clerk-js/src/core/__tests__/clerk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,25 @@ 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(evenBusSpy).toHaveBeenCalledWith('token:update', { token: null });
};

const sut = new Clerk(productionPublishableKey);
await sut.load();
await sut.setActive({ session: null });
});

it('calls __unstable__onAfterSetActive after beforeEmit and session.touch', async () => {
const beforeEmitMock = jest.fn();
mockSession.touch.mockReturnValueOnce(Promise.resolve());
Expand Down
11 changes: 4 additions & 7 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@ export class Clerk implements ClerkInterface {
const shouldSignOutSession = this.session && newSession === null;
if (shouldSignOutSession) {
this.#broadcastSignOutEvent();
eventBus.dispatch(events.TokenUpdate, { token: null });
}

await onBeforeSetActive();
Expand All @@ -741,13 +742,9 @@ export class Clerk implements ClerkInterface {
newSession = this.#getSessionFromClient(newSession?.id);
}

// Sync __session and __client_uat to cookies using events.TokenUpdate dispatched event
// only for newSession is null since the getToken will not be executed. Since getToken
// triggers internally a events.TokenUpdate there is no need to trigger it when the newSession exists.
const token = await newSession?.getToken();
if (!token) {
eventBus.dispatch(events.TokenUpdate, { token: null });
}
// getToken syncs __session and __client_uat to cookies using events.TokenUpdate dispatched event.
await newSession?.getToken();

//2. If there's a beforeEmit, typically we're navigating. Emit the session as
// undefined, then wait for beforeEmit to complete before emitting the new session.
// When undefined, neither SignedIn nor SignedOut renders, which avoids flickers or
Expand Down

0 comments on commit 1fdd436

Please sign in to comment.