From 46ff3d8bb636bd188b62f36b86813b3a998df7ed Mon Sep 17 00:00:00 2001 From: Nick Nisi Date: Fri, 8 Aug 2025 09:54:00 -0700 Subject: [PATCH 1/2] fix: use fresh user data when refreshing sessions Previously, refreshSession and updateSession preserved stale user and impersonator data from existing sessions instead of using the fresh data returned by the WorkOS authenticateWithRefreshToken API. This could lead to outdated user information persisting after token refreshes. Now both functions use the current user and impersonator data from the API response, ensuring sessions stay up-to-date with any changes. Fixes #35 --- src/session.spec.ts | 14 ++++++++++++++ src/session.ts | 34 ++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/session.spec.ts b/src/session.spec.ts index 456e11c..39a6027 100644 --- a/src/session.spec.ts +++ b/src/session.spec.ts @@ -717,6 +717,20 @@ describe('session', () => { authenticateWithRefreshToken.mockResolvedValue({ accessToken: 'new.valid.token', refreshToken: 'new.refresh.token', + user: { + object: 'user', + id: 'user-1', + email: 'test@example.com', + emailVerified: true, + profilePictureUrl: null, + firstName: 'Test', + lastName: 'User', + lastSignInAt: '2021-01-01T00:00:00Z', + createdAt: '2021-01-01T00:00:00Z', + updatedAt: '2021-01-01T00:00:00Z', + externalId: null, + }, + impersonator: undefined, } as AuthenticationResponse); // Mock JWT decoding diff --git a/src/session.ts b/src/session.ts index e4bf4f6..3a70cdc 100644 --- a/src/session.ts +++ b/src/session.ts @@ -45,17 +45,18 @@ export async function refreshSession(request: Request, { organizationId }: { org } try { - const { accessToken, refreshToken } = await getWorkOS().userManagement.authenticateWithRefreshToken({ - clientId: getConfig('clientId'), - refreshToken: session.refreshToken, - organizationId, - }); + const { accessToken, refreshToken, user, impersonator } = + await getWorkOS().userManagement.authenticateWithRefreshToken({ + clientId: getConfig('clientId'), + refreshToken: session.refreshToken, + organizationId, + }); const newSession = { accessToken, refreshToken, - user: session.user, - impersonator: session.impersonator, + user: user, + impersonator, headers: {} as Record, }; @@ -77,7 +78,7 @@ export async function refreshSession(request: Request, { organizationId }: { org } = getClaimsFromAccessToken(accessToken); return { - user: session.user, + user, sessionId, accessToken, organizationId: newOrgId, @@ -85,7 +86,7 @@ export async function refreshSession(request: Request, { organizationId }: { org permissions, entitlements, featureFlags, - impersonator: session.impersonator || null, + impersonator: impersonator ?? null, sealedSession: cookieSession.get('jwt'), headers: newSession.headers, }; @@ -119,11 +120,12 @@ async function updateSession(request: Request, debug: boolean) { const { organizationId } = getClaimsFromAccessToken(session.accessToken); // If the session is invalid (i.e. the access token has expired) attempt to re-authenticate with the refresh token - const { accessToken, refreshToken } = await getWorkOS().userManagement.authenticateWithRefreshToken({ - clientId: getConfig('clientId'), - refreshToken: session.refreshToken, - organizationId, - }); + const { accessToken, refreshToken, user, impersonator } = + await getWorkOS().userManagement.authenticateWithRefreshToken({ + clientId: getConfig('clientId'), + refreshToken: session.refreshToken, + organizationId, + }); // istanbul ignore next if (debug) console.log(`Refresh successful. New access token ends in ${accessToken.slice(-10)}`); @@ -131,8 +133,8 @@ async function updateSession(request: Request, debug: boolean) { const newSession = { accessToken, refreshToken, - user: session.user, - impersonator: session.impersonator, + user, + impersonator, headers: {}, }; From 7658c5b25e31af4834e2388e32dedfb2b6191b72 Mon Sep 17 00:00:00 2001 From: Nick Nisi Date: Fri, 8 Aug 2025 11:56:29 -0500 Subject: [PATCH 2/2] Update src/session.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- src/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/session.ts b/src/session.ts index 3a70cdc..dc4175b 100644 --- a/src/session.ts +++ b/src/session.ts @@ -55,7 +55,7 @@ export async function refreshSession(request: Request, { organizationId }: { org const newSession = { accessToken, refreshToken, - user: user, + user, impersonator, headers: {} as Record, };