fix(backend): revoke refresh tokens on logout and admin deactivation - #564
Merged
Conversation
Logout was a no-op: refresh tokens stayed valid for their full lifetime (30-day gesdinet default), so a stolen token survived 'logout'. Likewise, admin deactivation cleared the password reset token but left refresh tokens usable. - DELETE /api/auth/logout now deletes the user's refresh token rows - AdminUserService::deactivate revokes the user's refresh tokens too - Make gesdinet refresh token ttl explicit (2592000 = 30 days) Test: e2e flow proves a rotated refresh token is rejected with 401 after logout while another user's token is untouched; logout without a JWT returns 401.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Security audit finding:
DELETE /api/auth/logoutwas a no-op — refresh tokens stayed valid for their full gesdinet default lifetime (30 days), so a stolen refresh token survived logout. Same gap in admin deactivation: it cleared the password reset token but left live refresh tokens, and nouser_checkerblocks deactivated accounts.Fix
RefreshTokenRepository::revokeAllForUser()(DQL delete byusername= user identifier/email).LogoutControllernow requires the authenticated user and revokes all their refresh tokens (revokes every session — per-device revoke can come later if clients start sending the token).AdminUserService::deactivate()revokes the user's refresh tokens too.ttl: 2592000ingesdinet_jwt_refresh_token.yaml.No frontend change needed: Nebular already calls
DELETE /auth/logoutand only clears the local token on a successful response, which this keeps (200).Tests
LogoutControllerTest: seeds refresh tokens for two users, rotates one viaPOST /api/auth/refresh-token, logs out, then asserts the rotated token is rejected with 401, the user's rows are gone, and the other user's token is untouched.AuthenticationRequiredTest(no JWT → 401).