Skip to content

Commit 988f2e1

Browse files
authored
Fix SSR hydration mismatch in tokenStore (#306)
* fix SSR rendering of token * test: fix session refresh error tests for Node 20 - Update test expectations to match wrapped error messages - Provide valid JWT tokens in mock sessions to prevent decoding errors - Tests now expect 'Failed to refresh session:' prefix in error messages
1 parent 5ee1c47 commit 988f2e1

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

src/components/tokenStore.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class TokenStore {
1919

2020
constructor() {
2121
// Initialize state with token from cookie if available
22-
const initialToken = this.getInitialTokenFromCookie();
22+
const initialToken = typeof window !== 'undefined' ? this.getInitialTokenFromCookie() : undefined;
2323
this.state = {
2424
token: initialToken,
2525
loading: false,
@@ -28,7 +28,7 @@ export class TokenStore {
2828

2929
// Server snapshot should match initial state for hydration
3030
this.serverSnapshot = {
31-
token: initialToken,
31+
token: undefined,
3232
loading: false,
3333
error: null,
3434
};

src/session.spec.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -825,22 +825,32 @@ describe('session.ts', () => {
825825

826826
it('throws if authenticateWithRefreshToken fails with string', async () => {
827827
const nextCookies = await cookies();
828+
// Create a mock session with a valid JWT that includes org_id
829+
const mockSessionWithValidJWT = {
830+
...mockSession,
831+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdfaWQiOiJvcmdfMTIzIn0.fake',
832+
};
828833
nextCookies.set(
829834
'wos-session',
830-
await sealData(mockSession, { password: process.env.WORKOS_COOKIE_PASSWORD as string }),
835+
await sealData(mockSessionWithValidJWT, { password: process.env.WORKOS_COOKIE_PASSWORD as string }),
831836
);
832837
jest.spyOn(workos.userManagement, 'authenticateWithRefreshToken').mockRejectedValue('fail');
833-
expect(refreshSession({ ensureSignedIn: false })).rejects.toThrow('fail');
838+
expect(refreshSession({ ensureSignedIn: false })).rejects.toThrow('Failed to refresh session: fail');
834839
});
835840

836841
it('throws if authenticateWithRefreshToken fails with error', async () => {
837842
const nextCookies = await cookies();
843+
// Create a mock session with a valid JWT that includes org_id
844+
const mockSessionWithValidJWT = {
845+
...mockSession,
846+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdfaWQiOiJvcmdfMTIzIn0.fake',
847+
};
838848
nextCookies.set(
839849
'wos-session',
840-
await sealData(mockSession, { password: process.env.WORKOS_COOKIE_PASSWORD as string }),
850+
await sealData(mockSessionWithValidJWT, { password: process.env.WORKOS_COOKIE_PASSWORD as string }),
841851
);
842852
jest.spyOn(workos.userManagement, 'authenticateWithRefreshToken').mockRejectedValue(new Error('error'));
843-
await expect(refreshSession()).rejects.toThrow('error');
853+
await expect(refreshSession()).rejects.toThrow('Failed to refresh session: error');
844854
});
845855
});
846856

0 commit comments

Comments
 (0)