Skip to content

Commit ff308af

Browse files
committed
feat(clerk-js): Add debugLogger statements for session token swap detection
Add debug logging to detect server-side token swaps in multi-session scenarios: - Session.ts: Check if returned token's sid matches requested session (token swap detection) - AuthCookieService.ts: Log multi-session cookie updates to track active session - AuthCookieService.ts: Log token fetch errors (4xx and degraded status) - clerk.ts: Log session state before unauthenticated flow to see active sessions
1 parent 51bc9a9 commit ff308af

3 files changed

Lines changed: 38 additions & 4 deletions

File tree

packages/clerk-js/src/core/auth/AuthCookieService.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,15 @@ export class AuthCookieService {
177177
return;
178178
}
179179

180+
const sessions = (this.clerk.client as any)?.sessions;
181+
if (sessions?.length > 1 && token) {
182+
debugLogger.info(
183+
'Updating session cookie (multi-session client)',
184+
{ activeSessionId: this.clerk.session?.id, sessionCount: sessions.length, hasActor: !!this.clerk.session?.actor },
185+
'authCookieService',
186+
);
187+
}
188+
180189
if (!token && !isValidBrowserOnline()) {
181190
debugLogger.warn('Removing session cookie (offline)', { sessionId: this.clerk.session?.id }, 'authCookieService');
182191
}
@@ -205,17 +214,23 @@ export class AuthCookieService {
205214

206215
//sign user out if a 4XX error
207216
if (is4xxError(e)) {
217+
debugLogger.warn(
218+
'Token fetch failed with 4xx, triggering unauthenticated flow',
219+
{ errorCode: isClerkAPIResponseError(e) ? e.errors[0]?.code : undefined, sessionId: this.clerk.session?.id },
220+
'authCookieService',
221+
);
208222
void this.clerk.handleUnauthenticated().catch(noop);
209223
return;
210224
}
211225

212226
// The poller failed to fetch a fresh session token, update status to `degraded`.
213227
this.clerkEventBus.emit(clerkEvents.Status, 'degraded');
214228

215-
// --------
216-
// Treat any other error as a noop
217-
// TODO(debug-logs): Once debug logs is available log this error.
218-
// --------
229+
debugLogger.warn(
230+
'Token fetch failed, status degraded',
231+
{ error: e?.message || String(e), sessionId: this.clerk.session?.id },
232+
'authCookieService',
233+
);
219234
}
220235

221236
private handleSignOut() {

packages/clerk-js/src/core/clerk.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,6 +2347,16 @@ export class Clerk implements ClerkInterface {
23472347
if (!this.client || !this.session) {
23482348
return;
23492349
}
2350+
debugLogger.warn(
2351+
'handleUnauthenticated triggered',
2352+
{
2353+
activeSessionId: this.session.id,
2354+
hasActor: !!this.session.actor,
2355+
totalSessions: this.client.sessions.length,
2356+
signedInSessions: this.client.signedInSessions.map(s => ({ id: s.id, hasActor: !!s.actor })),
2357+
},
2358+
'clerk',
2359+
);
23502360
try {
23512361
const newClient = await Client.getOrCreateInstance().fetch();
23522362
this.updateClient(newClient);

packages/clerk-js/src/core/resources/Session.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,15 @@ export class Session extends BaseResource implements SessionResource {
413413
SessionTokenCache.set({ tokenId, tokenResolver });
414414

415415
return tokenResolver.then(token => {
416+
const returnedSid = token.jwt?.claims?.sid;
417+
if (returnedSid && returnedSid !== this.id) {
418+
debugLogger.warn(
419+
'Token session mismatch: requested token for one session but received token for another',
420+
{ requestedSessionId: this.id, returnedSessionId: returnedSid, tokenId, hasActor: !!this.actor },
421+
'session',
422+
);
423+
}
424+
416425
if (shouldDispatchTokenUpdate) {
417426
eventBus.emit(events.TokenUpdate, { token });
418427

0 commit comments

Comments
 (0)