From 83a10de4974cd55c1fb81c1c02d4053766c26cfe Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Mon, 27 Apr 2026 09:26:05 +0200 Subject: [PATCH] fix(auth): close same-ms revocation race + tidy audit cleanup Bumps token_revoked_before by 1ms so a JWT issued in the same millisecond as a logout call (Date.from(Instant.now()) quantises iat to ms) does not survive the filter's strict isBefore check. Also extends LogoutControllerIT @AfterEach to delete the audit_log row, keeping reused Postgres containers clean for downstream ITs. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../com/cameleer/server/app/security/UiAuthController.java | 6 +++++- .../cameleer/server/app/security/LogoutControllerIT.java | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java b/cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java index 467171de..a2a20f49 100644 --- a/cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java +++ b/cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java @@ -192,7 +192,11 @@ public class UiAuthController { return ResponseEntity.noContent().build(); } String userId = stripSubjectPrefix(authentication.getName()); - userRepository.revokeTokensBefore(userId, Instant.now()); + // +1ms guards against same-millisecond races: JWT iat is quantised to + // milliseconds (Date.from(now) in JwtServiceImpl), and the filter check + // is strict isBefore. Without the bump, a token issued in the same + // millisecond as logout would survive revocation. + userRepository.revokeTokensBefore(userId, Instant.now().plusMillis(1)); auditService.log(userId, "logout", AuditCategory.AUTH, null, null, AuditResult.SUCCESS, httpRequest); log.info("UI user logged out: {}", userId); diff --git a/cameleer-server-app/src/test/java/com/cameleer/server/app/security/LogoutControllerIT.java b/cameleer-server-app/src/test/java/com/cameleer/server/app/security/LogoutControllerIT.java index baa81cd0..dda14e39 100644 --- a/cameleer-server-app/src/test/java/com/cameleer/server/app/security/LogoutControllerIT.java +++ b/cameleer-server-app/src/test/java/com/cameleer/server/app/security/LogoutControllerIT.java @@ -30,6 +30,7 @@ class LogoutControllerIT extends AbstractPostgresIT { @AfterEach void cleanup() { userRepository.delete("logout-test"); + jdbc.update("DELETE FROM audit_log WHERE username = ?", "logout-test"); } @Test