You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
event, blocked-user denial within TTL bound, cache expiry re-query,
28
28
cleanup job deletes-only-expired.
29
+
<<<<<<< Updated upstream
30
+
=======
31
+
=======
32
+
## 2026-08-26
33
+
34
+
- Centralized role authorization on server truth: updated `UserStatusService` to cache user status and role with a 30s staleness bound (`USER_STATUS_CACHE_TTL_MS = 30_000`), and updated `RolesGuard` to enforce datastore roles instead of relying on un-enforced JWT role claims. Stale-token attacks are now rejected with 403 `AUTH_ROLE_FORBIDDEN`.
35
+
- Added admin-only role-management endpoint `POST /admin/users/:wallet/role/reset` in `AdminRolesController`, guarded by `JwtAuthGuard` and `AdminGuard`, and audited via `@AuditAction('admin_users', 'RESET_USER_ROLE')` and `AuditInterceptor`.
36
+
- Wired cache invalidation (`userStatusService.invalidate(wallet)`) into `setRole` and admin role reset, ensuring role changes take effect immediately on local server instance and within 30s across instances.
37
+
- Added unit tests for `RolesGuard`, `AdminRolesController`, `UserStatusService`, and `UsersService.setRole`.
38
+
- Fixed registration race conditions in `AuthService.register()` by eliminating application-side pre-checks (`findByWallet`, `checkUsernameExists`) and relying directly on DB-level UNIQUE constraints (`users.wallet_address`, `users.username`).
39
+
- Added idempotent migration `20260826130000_ensure_users_unique_constraints.sql` to ensure unique indexes exist on `users.wallet_address` and `users.username`.
40
+
- Updated `UsersRepository.createProfile()` to catch PostgreSQL unique constraint violation error `23505` and map to structured 409 `ConflictException` (`AUTH_WALLET_EXISTS`, `AUTH_USERNAME_TAKEN`).
41
+
- Added cleanup handlers (`deleteAvatar`, `deleteUserById`) in `AuthService.register()` and `UsersRepository` to ensure failed registrations do not leave orphaned avatar files or partial user records.
0 commit comments