|
| 1 | +## [4.0.2] - 2026-01-25 |
| 2 | +### Features |
| 3 | +- Admin-initiated password reset with optional session invalidation |
| 4 | + - Added SessionInvalidationService to expire all active sessions for a user using Spring Security’s SessionRegistry, with a documented race-condition caveat (sessions created during the sweep may survive). |
| 5 | + - Extended UserEmailService with new admin reset entry points: |
| 6 | + - initiateAdminPasswordReset(User user, String appUrl, boolean invalidateSessions) |
| 7 | + - initiateAdminPasswordReset(User user) – uses configured user.admin.appUrl, defaults to invalidating sessions. |
| 8 | + - End-to-end flow: |
| 9 | + - Generates a cryptographically secure, URL-safe Base64 token (256-bit entropy) for reset links. |
| 10 | + - Sends password reset email with validated app URL and reset link path (/user/changePassword?token=). |
| 11 | + - Optionally invalidates all user sessions. |
| 12 | + - Publishes an audit event with action adminInitiatedPasswordReset, correlation ID, admin identity, and session counts. |
| 13 | + - Security hardening baked into the feature: |
| 14 | + - @PreAuthorize now uses hasRole('ADMIN') (Spring auto-prefixes ROLE_) on admin APIs. |
| 15 | + - Admin identity is derived from the SecurityContext (prevents log injection and spoofing). |
| 16 | + - URL validation rejects dangerous schemes (javascript:, data:) for appUrl. |
| 17 | + - Operation order improved to avoid accidental lockout: token creation + email send happen before session invalidation. |
| 18 | + - Configuration support: |
| 19 | + - user.admin.appUrl for default reset link base URL. |
| 20 | + - user.session.invalidation.warn-threshold for performance warnings on principal scans. |
| 21 | + - Extensive tests added covering session invalidation behavior, email content/link generation, authorization metadata, URL validation, audit contents, and token format. |
| 22 | + |
| 23 | +### Fixes |
| 24 | +- Security and robustness improvements in the new admin reset capability |
| 25 | + - Reordered initiateAdminPasswordReset steps to prevent a user lockout if token creation/email sending fails. |
| 26 | + - Replaced UUID.randomUUID() tokens with SecureRandom-based 32-byte tokens encoded as URL-safe Base64 (no padding). |
| 27 | + - Switched audit extraData from CSV-like strings to JSON for safe, predictable parsing. |
| 28 | + - Replaced ad-hoc JSON-escaping with Jackson ObjectMapper to safely serialize audit metadata. |
| 29 | + - Truncated session IDs to first 8 characters in debug logs to reduce exposure risk. |
| 30 | +- Authorization annotation correctness |
| 31 | + - Changed @PreAuthorize("hasRole('ROLE_ADMIN')") to @PreAuthorize("hasRole('ADMIN')") in all admin APIs to match Spring Security’s ROLE_ auto-prefixing. |
| 32 | +- OIDC claim safety |
| 33 | + - DSUserDetails.getClaims() now guards against null OIDC user info, returning an empty map instead of throwing a NullPointerException. |
| 34 | + |
| 35 | +### Breaking Changes |
| 36 | +- Audit event extraData format changed from ad-hoc CSV to JSON |
| 37 | + - If any downstream systems parse AuditEvent.extraData, update them to expect JSON (e.g., {"adminIdentifier":"...","sessionsInvalidated":3,"correlationId":"..."}). |
| 38 | +- Token and correlation ID formats |
| 39 | + - Password reset and verification tokens are now URL-safe Base64 (43 chars for 32 bytes) instead of UUIDs. |
| 40 | + - The correlationId used in audit extraData was also moved to URL-safe Base64 in later changes. Update any format assumptions in log-processing pipelines. |
| 41 | +- API method deprecations (not removals) |
| 42 | + - Admin reset overloads taking an explicit adminIdentifier are now deprecated; admin identity is derived from the SecurityContext. No functional break, but planned for removal later. |
| 43 | + |
| 44 | +### Refactoring |
| 45 | +- UserEmailService |
| 46 | + - Extracted helper methods to align with SRP: |
| 47 | + - URL validation (isValidAppUrl), password-reset email sending (sendPasswordResetEmail), session invalidation handling (handleSessionInvalidation), and audit emission (publishAdminPasswordResetAuditEvent). |
| 48 | + - Centralized JSON serialization for audit metadata via ObjectMapper. |
| 49 | +- SessionInvalidationService |
| 50 | + - Added performance logging and warn threshold configuration. |
| 51 | + - Documented inherent SessionRegistry race condition and included safer logging for session IDs. |
| 52 | + |
| 53 | +### Documentation |
| 54 | +- Admin password reset documentation |
| 55 | + - README: Added to Features list, detailed usage examples (with/without session invalidation, using configured appUrl), security notes (role requirements, URL validation, operation ordering), and configuration snippet. |
| 56 | + - CONFIG.md: New Admin Settings section documenting user.admin.appUrl and user.session.invalidation.warn-threshold. |
| 57 | +- Version and compatibility updates |
| 58 | + - README install snippets updated to 4.0.2; added Java 25 to supported Java badge. |
| 59 | +- Developer guidance |
| 60 | + - CLAUDE.md substantially rewritten with architecture overview, package map, entry points, core services, extension points, configuration namespaces, and common commands. |
| 61 | +- JavaDoc quality pass |
| 62 | + - Added/standardized class-level JavaDoc across 40+ classes; added lombok.config and Javadoc task options to suppress Lombok-generated constructor warnings; restored consistent @RequiredArgsConstructor usage where appropriate. |
| 63 | + |
| 64 | +### Testing |
| 65 | +- New and expanded test coverage |
| 66 | + - SessionInvalidationServiceTest: |
| 67 | + - Validates mixed principal types (User and DSUserDetails), correct counting, performance warnings, and resilience on empty/null inputs. |
| 68 | + - UserEmailServiceTest: |
| 69 | + - Verifies admin-initiated flow (email sending, token creation, session invalidation counts). |
| 70 | + - Ensures URL validation rejects null/empty and javascript: schemes. |
| 71 | + - Confirms @PreAuthorize role expressions are correct (hasRole('ADMIN')). |
| 72 | + - Validates audit extraData JSON content and correlation ID format. |
| 73 | + - Updates for token format: assertions now check URL-safe Base64 43-character tokens. |
| 74 | +- Test dependency updates |
| 75 | + - Testcontainers upgraded from 2.0.2 to 2.0.3 (core and MariaDB modules). |
| 76 | + |
| 77 | +### Other Changes |
| 78 | +- Dependency and build updates |
| 79 | + - Spring Boot bumped from 4.0.0 to 4.0.1. |
| 80 | + - com.vanniktech.maven.publish upgraded 0.35.0 → 0.36.0. |
| 81 | + - Project version set to 4.0.2-SNAPSHOT post-release. |
| 82 | +- CI/CD and workflows |
| 83 | + - Updated Claude Code Review and PR Assistant GitHub Actions: |
| 84 | + - Permissions adjusted (read vs write), token input switched to claude_code_oauth_token, documentation links updated, allowed-tools refined. |
| 85 | +- Repository hygiene |
| 86 | + - Removed obsolete planning docs and boilerplate (DEMO_APP_CHANGES_REQUIRED.md, IMPLEMENTATION_PLAN_PASSWORD_FIXES.md, HELP.md). |
| 87 | + |
| 88 | +Notes for integrators: |
| 89 | +- If you parse audit logs or rely on token/correlation ID formats, update your parsers to expect JSON extraData and URL-safe Base64 tokens/IDs. |
| 90 | +- Ensure the admin role mapping aligns with Spring’s ROLE_ prefixing; the correct expression is hasRole('ADMIN'). |
| 91 | +- Configure user.admin.appUrl if using the convenience admin reset method without passing an explicit app URL. |
| 92 | + |
1 | 93 | ## [4.0.1] - 2025-12-15 |
2 | 94 | ### Features |
3 | 95 | - No user-facing features in this set of commits. |
|
0 commit comments