fix: JTI revocation returns error, LogoutHandler returns 500 on failure

This commit is contained in:
2026-07-11 14:35:34 +01:00
parent 9e85bc766b
commit 7a51bcc49a
4 changed files with 41 additions and 22 deletions
+3 -1
View File
@@ -1731,7 +1731,9 @@ func TestJTI_Revocation_PostgreSQL(t *testing.T) {
t.Fatalf("token should be valid before revocation: %v", err)
}
auth.RevokeJTI(ctx, jti, clock.Now().Add(1*time.Hour))
if err := auth.RevokeJTI(ctx, jti, clock.Now().Add(1*time.Hour)); err != nil {
t.Fatalf("RevokeJTI() failed: %v", err)
}
if !auth.IsJTIRevoked(ctx, jti) {
t.Error("JTI should be revoked after RevokeJTI call")
+9 -2
View File
@@ -485,7 +485,10 @@ func RefreshTokenHandler(w http.ResponseWriter, r *http.Request) {
// Revoke the old token's JTI before issuing a new one (rotation)
if oldJTI != "" {
auth.RevokeJTI(r.Context(), oldJTI, clock.Now().Add(90*24*time.Hour)) // match refresh token lifetime
// Best-effort revocation: log the error but continue with the refresh
if err := auth.RevokeJTI(r.Context(), oldJTI, clock.Now().Add(90*24*time.Hour)); err != nil {
slog.Error("refresh: failed to revoke old JTI", "oldJTI", oldJTI, "err", err)
}
}
// Generate new token
@@ -510,7 +513,11 @@ func LogoutHandler(w http.ResponseWriter, r *http.Request) {
}
// Revoke the JTI — match the access token lifetime (1 hour)
auth.RevokeJTI(r.Context(), jti, clock.Now().Add(1*time.Hour))
if err := auth.RevokeJTI(r.Context(), jti, clock.Now().Add(1*time.Hour)); err != nil {
slog.Error("logout: failed to revoke JTI", "err", err)
http.Error(w, "Failed to revoke token. Please try again.", http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(map[string]bool{"success": true})
}