|
| 1 | +## [3.5.1] - 2025-10-26 |
| 2 | +### Features |
| 3 | +- New password reset endpoint: /user/savePassword |
| 4 | + - Implements the missing step in the password reset flow: validates a reset token and saves a new password. |
| 5 | + - Accepts SavePasswordDto { token, newPassword, confirmPassword } with validation. |
| 6 | + - Enforces full password policy (length, complexity, common password prevention, history, similarity). |
| 7 | + - Returns localized messages and a login redirect path on success. |
| 8 | + |
| 9 | +### Fixes |
| 10 | +- Hardened password management and validation |
| 11 | + - Update password now enforced by policy: |
| 12 | + - The /updatePassword endpoint validates the new password against the configured policy (history, similarity, complexity) before saving, preventing weak or reused passwords. |
| 13 | + - Complete password reset flow: |
| 14 | + - Added /user/savePassword endpoint with full validation and token checks. |
| 15 | + - Optimized reset token invalidation: |
| 16 | + - Added PasswordResetTokenRepository.deleteByToken(@Modifying @Query) to delete via a single DELETE statement. |
| 17 | + - UserService.deletePasswordResetToken() now uses the direct delete method and logs the deletion, reducing DB round trips. |
| 18 | + - Clarified password matching: |
| 19 | + - Documented that using String.equals() to compare two user-provided inputs (new vs confirm) is safe; constant-time comparison is needed only when comparing against stored secrets (handled by PasswordEncoder). |
| 20 | + - Reduced risk of race conditions during password history cleanup: |
| 21 | + - Added @Transactional(isolation = SERIALIZABLE) to UserService.cleanUpPasswordHistory to ensure atomic trimming of history entries during concurrent updates. |
| 22 | + - JPA mapping and performance improvements: |
| 23 | + - Adjusted PasswordHistoryEntry/User relationships for LAZY fetching and cascade delete to reduce unnecessary loads and avoid orphaned entries. |
| 24 | + - Internationalized messages: |
| 25 | + - Added message.password.mismatch and message.reset-password.success keys for clearer user feedback. |
| 26 | + |
| 27 | +### Breaking Changes |
| 28 | +- None in API surface. However, behavior is intentionally stricter: |
| 29 | + - Password updates that previously succeeded with weak/reused passwords will now be rejected per policy. |
| 30 | + - Applications relying on lax validation may see new 400 responses from /updatePassword and /savePassword until client-side validation and UX are aligned. |
| 31 | + |
| 32 | +### Refactoring |
| 33 | +- Repository-level optimization for token deletion: |
| 34 | + - Introduced deleteByToken() JPQL delete in PasswordResetTokenRepository and migrated service logic to use it. |
| 35 | +- Minor code comments and documentation improvements in UserAPI for clarity and audit logging. |
| 36 | + |
| 37 | +### Documentation |
| 38 | +- README |
| 39 | + - Updated dependency examples from 3.4.1 → 3.5.0 and then to 3.5.1 for both Maven and Gradle snippets. |
| 40 | +- DEMO_APP_CHANGES_REQUIRED.md (new) |
| 41 | + - Detailed steps to fix demo app password reset form: |
| 42 | + - Change form action to /user/savePassword. |
| 43 | + - Add name="confirmPassword" to the confirm field to match SavePasswordDto. |
| 44 | + - Notes on reusing the existing registration password strength meter in reset/update flows; reduced estimated effort (1–2 hours). |
| 45 | + - Optional consistency update: rename currentPassword → oldPassword in update-password.js to match backend DTO (non-breaking). |
| 46 | + - Comprehensive testing checklist for reset/update/registration flows. |
| 47 | +- IMPLEMENTATION_PLAN_PASSWORD_FIXES.md (new) |
| 48 | + - Full analysis and plan covering: |
| 49 | + - Adding validation to /updatePassword. |
| 50 | + - Implementing /savePassword with DTO, token checks, and policy enforcement. |
| 51 | + - Design decision: history checks apply to existing users; registration passes user=null by design. |
| 52 | + - Transaction isolation choice for history cleanup and concurrent-change considerations. |
| 53 | + |
| 54 | +### Testing |
| 55 | +- All existing tests pass (372 tests), confirming no regressions. |
| 56 | +- The plan documents recommended additional unit and integration tests for reset/update flows; no new test files were added in the provided diffs. |
| 57 | + |
| 58 | +### Other Changes |
| 59 | +- CI/CD and Developer Experience |
| 60 | + - Added GitHub Actions workflows: |
| 61 | + - .github/workflows/claude-code-review.yml: Automated PR code reviews using anthropics/claude-code-action@v1 with limited gh tool permissions and review prompts. |
| 62 | + - .github/workflows/claude.yml: On-demand “@claude” assistant for issues and PRs with permissions to read CI results and repository metadata. |
| 63 | +- Release and versioning |
| 64 | + - Bumped project version to 3.5.1-SNAPSHOT in gradle.properties to begin the next development iteration. |
| 65 | + |
| 66 | +Notes for integrators |
| 67 | +- Update any client UI that performs password reset: |
| 68 | + - Post to /user/savePassword with fields: token, newPassword, confirmPassword. |
| 69 | + - Expect localized error messages and strict validation failures for policy violations. |
| 70 | +- Consider surfacing the same password strength and requirements UX used in registration on reset/update screens to align with backend enforcement. |
| 71 | + |
1 | 72 | ## [3.5.0] - 2025-10-26 |
2 | 73 | ### Features |
3 | 74 | - Password policy enforcement integrated into registration and password updates |
|
0 commit comments