Skip to content

Commit 2ba9ade

Browse files
devondragonclaude
andcommitted
feat: add password history cleanup and configuration
- Add historyCount field with @value annotation for configuration - Implement cleanUpPasswordHistory() method to remove old password entries - Automatically clean up entries beyond configured history count after saving - Add password history tracking to changeUserPassword() method - Prevent database bloat by limiting stored password history entries This ensures password history doesn't grow unbounded and maintains only the configured number of recent passwords for reuse checking. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent a87922e commit 2ba9ade

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

src/main/java/com/digitalsanctuary/spring/user/service/UserService.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ public String getValue() {
227227
@Value("${user.actuallyDeleteAccount:false}")
228228
private boolean actuallyDeleteAccount;
229229

230+
@Value("${user.security.password.history-count:0}")
231+
private int historyCount;
232+
230233
/**
231234
* Registers a new user account with the provided user data. If the email
232235
* already exists, throws a UserAlreadyExistException. If
@@ -294,6 +297,22 @@ private void savePasswordHistory(User user, String encodedPassword) {
294297
PasswordHistoryEntry entry = new PasswordHistoryEntry(user, encodedPassword, LocalDateTime.now());
295298
passwordHistoryRepository.save(entry);
296299
log.debug("Password history entry saved for user: {}", user.getEmail());
300+
301+
// Clean up old entries
302+
cleanUpPasswordHistory(user);
303+
}
304+
305+
private void cleanUpPasswordHistory(User user) {
306+
if (user == null || historyCount <= 0) {
307+
return;
308+
}
309+
310+
List<PasswordHistoryEntry> entries = passwordHistoryRepository.findByUserOrderByEntryDateDesc(user);
311+
if (entries.size() > historyCount) {
312+
List<PasswordHistoryEntry> toDelete = entries.subList(historyCount, entries.size());
313+
passwordHistoryRepository.deleteAll(toDelete);
314+
log.debug("Cleaned up {} old password history entries for user: {}", toDelete.size(), user.getEmail());
315+
}
297316
}
298317

299318
/**
@@ -395,8 +414,10 @@ public Optional<User> findUserByID(final long id) {
395414
* @param password the password
396415
*/
397416
public void changeUserPassword(final User user, final String password) {
398-
user.setPassword(passwordEncoder.encode(password));
417+
String encodedPassword = passwordEncoder.encode(password);
418+
user.setPassword(encodedPassword);
399419
userRepository.save(user);
420+
savePasswordHistory(user, encodedPassword);
400421
}
401422

402423
/**

0 commit comments

Comments
 (0)