Skip to content

feat(auth): add logout-all endpoint to revoke all sessions (#74) - #105

Merged
datvt243 merged 1 commit into
stagingfrom
feat/issue-74-logout-all-sessions
Sep 2, 2026
Merged

feat(auth): add logout-all endpoint to revoke all sessions (#74)#105
datvt243 merged 1 commit into
stagingfrom
feat/issue-74-logout-all-sessions

Conversation

@datvt243

@datvt243 datvt243 commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Adds POST /api/v1/auth/logout-all so a candidate can invalidate every access/refresh token issued to them at once, not just the current one (as /logout already does).

Design note (diverges from the issue's proposal)

The issue proposed a tokenVersion field on the Candidate model, checked via an extra Mongo lookup on every authenticated request — but it also flagged that cost as worth measuring/avoiding before committing to it.

Instead, this reuses the exact Redis-with-in-memory-fallback shape already used by tokenBlacklist.ts:

  • A per-candidate invalidated-before timestamp is stored in Redis/mem (sessionRevocation.ts).
  • It's compared against each JWT's standard iat claim in verifyToken.middleware.ts and authRefreshToken.

Result: no schema change, no new DB round trip — just one more Redis/mem lookup alongside the blacklist check that already runs on every request.

Changes

  • src/utils/sessionRevocation.ts (new) — invalidateAllSessions, getSessionsInvalidatedAt, isSessionRevoked
  • verifyToken.middleware.ts — reject tokens issued before the candidate's last logout-all
  • auth.controller.ts — new authLogoutAll controller + same revocation check added to authRefreshToken
  • auth.route.tsPOST /api/v1/auth/logout-all (authenticated via verifyToken), with Swagger docs
  • locales (en/vi) — auth.logoutAllSuccess
  • Tests updated/added: verifyToken.test.ts, refreshToken.test.ts, auth.controller.test.ts

Testing

  • npm test — 60/60 passing
  • npm run build — clean, no tsc errors

Closes #74

🤖 Generated with Claude Code

https://claude.ai/code/session_01ACpXY4MGdQHFTmu3SZTPLG

Adds POST /api/v1/auth/logout-all so a candidate can invalidate every
access/refresh token issued to them at once, not just the current one
(as /logout already does).

Design differs from the issue's tokenVersion-on-Candidate-model
proposal: instead of adding a Mongo field + an extra DB lookup per
authenticated request, this reuses the exact Redis-with-in-memory-
fallback shape already used by tokenBlacklist.ts. A per-candidate
'invalidated before' timestamp is stored in Redis/mem
(sessionRevocation.ts) and compared against each JWT's standard iat
claim in verifyToken.middleware.ts and authRefreshToken — one more
Redis/mem lookup alongside the blacklist check that already runs on
every request, no schema change, no new DB round trip.

- src/utils/sessionRevocation.ts: invalidateAllSessions / getSessionsInvalidatedAt / isSessionRevoked
- verifyToken.middleware.ts: reject tokens issued before the last logout-all
- auth.controller.ts: authLogoutAll controller + same check in authRefreshToken
- auth.route.ts: POST /logout-all (authenticated via verifyToken)
- locales: logoutAllSuccess (en/vi)
- tests updated/added for verifyToken middleware, authRefreshToken, authLogoutAll

Closes #74
@datvt243
datvt243 merged commit 4cde424 into staging Sep 2, 2026
3 checks passed
@datvt243
datvt243 deleted the feat/issue-74-logout-all-sessions branch September 2, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant