i'm trying to implement a password reset/forgot password feature in my spring boot/react app but i'm having some problems trying to fully understand it, I'm unsure whether the approach i'm taking is correct or not.
I already have both register/login working
@PostMapping("/sendForgotPasswordEmail")
public ResponseEntity<?> sendForgotPasswordEmail(@Valid @RequestBody ForgotPasswordEmailRequest request) {
User user = userService.findUserByEmailAddress(request.getForgotPasswordEmail());
ResetPasswordToken resetPasswordToken = userService.createResetPasswordToken(user);
if(userService.existsByEmailAddress(request.getForgotPasswordEmail())) {
emailService.sendResetPasswordEmail(request.getForgotPasswordEmail(), resetPasswordToken.getToken());
return ResponseEntity.ok(new ApiResponse("Please check your email for a password reset link" , true));
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
}
@PostMapping("/resetPassword")
public ResponseEntity<?> resetPassword(@RequestParam("token") String token, @Valid @RequestBody ForgotPasswordEmailRequest request) {
ResetPasswordToken resetPasswordToken = userService.findByResetPasswordToken(token);
if(resetPasswordToken == null) throw new BadRequestException("Invalid token");
Calendar calendar = Calendar.getInstance();
if((resetPasswordToken.getExpiredAt().getTime() - calendar.getTime().getTime()) <= 0) {
throw new BadRequestException("Link expired. Generate new link from http://localhost:3000/signup");
}
userService.resetPassword(request.getForgotPasswordEmail(), request.getNewPassword());
return ResponseEntity.ok(token);
}
UserServiceImpl.java (Methods related to the reset token)
@Override
public ResetPasswordToken createResetPasswordToken(User user) {
ResetPasswordToken resetPasswordToken = new ResetPasswordToken(user);
return resetPasswordTokenRepository.save(resetPasswordToken);
}
@Override
public ResetPasswordToken findByResetPasswordToken(String token) {
return resetPasswordTokenRepository.findByToken(token);
}
@Override
public void resetPassword(String emailAddress, String password) {
User user = findUserByEmailAddress(emailAddress);
user.setPassword(passwordEncoder.encode(password));
}
ForgotPasswordEmailRequest.java
public class ForgotPasswordEmailRequest {
private String forgotPasswordEmail;
private String newPassword;
// constructors / getters and setters
}
The thing i'd like clarity on is how exactly to go about doing this and making sure i can successfully redirect a user to the reset password page, and they can change it from there. I'm unsure where my controller methods are missing something or where i'm going wrong.
When the user reaches the reset password form after being sent an email, what's the process that needs to happen on the front + backend from there.
I'd appreciate any help.
Usually the flow is like this: