Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Lost Password Feature #715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feature: Initial Password reset flow implementation
  • Loading branch information
irfan-ikhwa committed Feb 18, 2024
commit c4b18bd65055c3a298b11faeadbbd33ee6cb8ffb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public boolean sendMail(String to, String token, String message) {
mimeMessageHelper.setSubject(subject);

// Construct the message with the token link
String resetLink = "http://localhost:8080/lost-password?token=" + token;
String resetLink = "http://localhost:8080/api/users/lost-password/" + token;
String messageWithLink = message + "\n\nReset your password here: " + resetLink;
mimeMessageHelper.setText(messageWithLink, true); // Set HTML to true to allow links

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public interface UserService {

Mono<Void> lostPassword(String userEmail);

Mono<Void> resetLostPassword(String userEmail, String token, String newPassword);

Mono<Boolean> setPassword(String userId, String password);

Mono<UserDetail> buildUserDetail(User user, boolean withoutDynamicGroups);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,30 @@ public Mono<Void> lostPassword(String userEmail) {
}
user.setPasswordResetToken(HashUtils.hash(token.getBytes()));
user.setPasswordResetTokenExpiry(tokenExpiry);
return Mono.empty();
return repository.save(user).then(Mono.empty());
});
}

@Override
public Mono<Void> resetLostPassword(String userEmail, String token, String newPassword) {
return findByName(userEmail)
.flatMap(user -> {
if (Instant.now().until(user.getPasswordResetTokenExpiry(), ChronoUnit.MINUTES) <= 0) {
return ofError(BizError.LOGIN_EXPIRED, "TOKEN_EXPIRED");
}

if (!StringUtils.equals(HashUtils.hash(token.getBytes()), user.getPasswordResetToken())) {
return ofError(BizError.INVALID_PASSWORD, "INVALID_TOKEN");
}

if (StringUtils.isBlank(newPassword)) {
return ofError(BizError.INVALID_PASSWORD, "PASSWORD_NOT_SET_YET");
}

user.setPassword(encryptionService.encryptPassword(newPassword));
user.setPasswordResetToken(StringUtils.EMPTY);
user.setPasswordResetTokenExpiry(Instant.now());
return repository.save(user).then(Mono.empty());
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ public Mono<Void> lostPassword(String userEmail) {
return userService.lostPassword(userEmail);
}

public Mono<Void> resetLostPassword(String userEmail, String token, String newPassword) {
return userService.resetLostPassword(userEmail, token, newPassword);
}

// ========================== TOKEN OPERATIONS START ==========================

public Mono<Void> saveToken(String userId, String source, String token) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ public Mono<ResponseView<Void>> lostPassword(@RequestBody LostPasswordRequest re
.map(ResponseView::success);
}

@Override
public Mono<ResponseView<Void>> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request) {
if (StringUtils.isBlank(request.userEmail()) || StringUtils.isBlank(token)
|| StringUtils.isBlank(request.newPassword())) {
return ofError(BizError.INVALID_PARAMETER, "INVALID_PARAMETER");
}

return userApiService.resetLostPassword(request.userEmail(), token, request.newPassword())
.map(ResponseView::success);
}

@Override
public Mono<ResponseView<Boolean>> setPassword(@RequestParam String password) {
if (StringUtils.isBlank(password)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ public interface UserEndpoints
public Mono<ResponseView<String>> resetPassword(@RequestBody ResetPasswordRequest request);

@PostMapping("/lost-password")
public Mono<ResponseView<Void>> lostPassword(@RequestBody LostPasswordRequest userEmail);
public Mono<ResponseView<Void>> lostPassword(@RequestBody LostPasswordRequest request);

@PostMapping("/lost-password/{token}")
public Mono<ResponseView<Void>> resetLostPassword(@PathVariable String token, @RequestBody ResetLostPasswordRequest request);

@Operation(
tags = TAG_USER_PASSWORD_MANAGEMENT,
Expand Down Expand Up @@ -157,6 +160,9 @@ public record ResetPasswordRequest(String userId) {
public record LostPasswordRequest(String userEmail) {
}

public record ResetLostPasswordRequest(String userEmail, String newPassword) {
}

public record UpdatePasswordRequest(String oldPassword, String newPassword) {
}

Expand Down