diff --git a/backend/src/main/java/org/raddatz/familienarchiv/user/PasswordResetService.java b/backend/src/main/java/org/raddatz/familienarchiv/user/PasswordResetService.java index 850ea94d..9cc25c50 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/user/PasswordResetService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/user/PasswordResetService.java @@ -5,6 +5,7 @@ import java.time.LocalDateTime; import java.util.HexFormat; import java.util.Optional; +import org.raddatz.familienarchiv.auth.AuthService; import org.raddatz.familienarchiv.user.ResetPasswordRequest; import org.raddatz.familienarchiv.exception.DomainException; import org.raddatz.familienarchiv.exception.ErrorCode; @@ -32,6 +33,7 @@ public class PasswordResetService { private final UserService userService; private final PasswordResetTokenRepository tokenRepository; private final PasswordEncoder passwordEncoder; + private final AuthService authService; @Autowired(required = false) private JavaMailSender mailSender; @@ -85,6 +87,8 @@ public class PasswordResetService { resetToken.setUsed(true); tokenRepository.save(resetToken); + + authService.revokeAllSessions(user.getEmail()); } /** diff --git a/backend/src/test/java/org/raddatz/familienarchiv/user/PasswordResetServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/user/PasswordResetServiceTest.java index 00baef9c..86cbb3b7 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/user/PasswordResetServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/user/PasswordResetServiceTest.java @@ -27,6 +27,7 @@ import org.springframework.mail.MailSendException; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.security.crypto.password.PasswordEncoder; +import org.raddatz.familienarchiv.auth.AuthService; import org.springframework.test.util.ReflectionTestUtils; @ExtendWith(MockitoExtension.class) @@ -36,8 +37,10 @@ class PasswordResetServiceTest { @Mock PasswordResetTokenRepository tokenRepository; @Mock PasswordEncoder passwordEncoder; @Mock JavaMailSender mailSender; + @Mock AuthService authService; @InjectMocks PasswordResetService service; + private AppUser makeUser(String email) { return AppUser.builder() .id(UUID.randomUUID()) @@ -176,6 +179,27 @@ class PasswordResetServiceTest { verify(mailSender).send(any(SimpleMailMessage.class)); } + @Test + void resetPassword_revokes_all_sessions_after_password_reset() { + AppUser user = makeUser("user@example.com"); + PasswordResetToken token = PasswordResetToken.builder() + .id(UUID.randomUUID()) + .token("validtoken123") + .user(user) + .expiresAt(LocalDateTime.now().plusHours(1)) + .used(false) + .build(); + when(tokenRepository.findByToken("validtoken123")).thenReturn(Optional.of(token)); + when(passwordEncoder.encode(any())).thenReturn("hashed"); + + ResetPasswordRequest req = new ResetPasswordRequest(); + req.setToken("validtoken123"); + req.setNewPassword("newpass"); + service.resetPassword(req); + + verify(authService).revokeAllSessions("user@example.com"); + } + // ─── cleanupExpiredTokens ───────────────────────────────────────────────── @Test