From 04828fefe20905e03480f726909a8b5cc466b112 Mon Sep 17 00:00:00 2001 From: BOHA Date: Mon, 23 Mar 2026 20:38:09 +0100 Subject: [PATCH] fix: logout deletes all tokens from same browser/IP, not just current On logout, finds all refresh tokens matching the same user + IP + user-agent (same browser session) and deletes them all. This cleans up zombie tokens from previous logins and token rotations that were showing as stale sessions on the dashboard. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/services/auth.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/services/auth.ts b/src/services/auth.ts index 2ddc6b3..c10a6f8 100644 --- a/src/services/auth.ts +++ b/src/services/auth.ts @@ -224,23 +224,24 @@ export async function refreshAccessToken( export async function logout(refreshTokenRaw: string): Promise { const tokenHash = hashToken(refreshTokenRaw); - // Delete the current token const token = await prisma.refresh_tokens.findFirst({ where: { token_hash: tokenHash } }); + if (token) { - // Delete the current token and all replaced tokens in its chain + // Delete all tokens for this user from the same IP + user agent (same browser session) await prisma.refresh_tokens.deleteMany({ where: { - OR: [ - { token_hash: tokenHash }, - { replaced_by_hash: tokenHash }, - ], + user_id: token.user_id, + ip_address: token.ip_address, + user_agent: token.user_agent, }, }); + } else { + // Fallback: just delete by hash + await prisma.refresh_tokens.deleteMany({ where: { token_hash: tokenHash } }); } - // Clean up expired tokens for all users - await prisma.refresh_tokens.deleteMany({ - where: { expires_at: { lt: new Date() } }, - }); + + // Clean up expired tokens + await prisma.refresh_tokens.deleteMany({ where: { expires_at: { lt: new Date() } } }); } export async function verifyAccessToken(token: string): Promise {