Skip to content

Commit 0fa6237

Browse files
committed
fix email verif and pasword reset dublicate problem and add endpoint to exposed needed authorities for this service
1 parent 761218e commit 0fa6237

File tree

9 files changed

+49
-13
lines changed

9 files changed

+49
-13
lines changed

src/main/java/com/ics/configuration/SecurityConfiguration.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
6868
.requestMatchers(HttpMethod.POST, "/api/accounts/verify-email/resend").permitAll()
6969
// password resetting
7070
.requestMatchers(HttpMethod.POST, "/api/accounts/reset-password","/api/accounts/reset-password/resend").permitAll()
71+
.requestMatchers(HttpMethod.GET, "/api/accounts/reset-password").permitAll()
7172
// others require authentication
7273
.anyRequest().authenticated()
7374
);

src/main/java/com/ics/controllers/AccountController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public ResponseEntity<String> resendEmailVerificationToken(@RequestParam String
108108

109109
// password related
110110
@PostMapping("/reset-password/resend")
111-
public ResponseEntity<String> requestResetPassword(@RequestParam String email) {
111+
public ResponseEntity<String> requestResetPassword(@RequestParam String email) {
112112
Account account = accountService.getAccountByEmail(email);
113113
String token = passwordResetTokenService.generatePasswordResetToken(account);
114114

@@ -118,7 +118,7 @@ public ResponseEntity<String> requestResetPassword(@RequestParam String email) {
118118
}
119119

120120
@GetMapping("/reset-password")
121-
public ResponseEntity<String> isResetPasswordTokenValid(@RequestParam String token, @RequestParam String newPassword) {
121+
public ResponseEntity<String> isResetPasswordTokenValid(@RequestParam(defaultValue = "") String token) {
122122
String email = passwordResetTokenService.validatePasswordResetToken(token);
123123
return new ResponseEntity<>(email, HttpStatus.OK);
124124
}

src/main/java/com/ics/controllers/MainController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.ics.dto.DependencyStatus;
44
import com.ics.dto.HealthCheckResponse;
5+
import com.ics.enums.Authority;
56
import lombok.RequiredArgsConstructor;
67
import org.springframework.beans.factory.annotation.Value;
78
import org.springframework.http.HttpStatus;
@@ -10,8 +11,10 @@
1011
import org.springframework.web.bind.annotation.RestController;
1112
import org.springframework.web.client.RestTemplate;
1213

14+
import java.util.Arrays;
1315
import java.util.List;
1416
import java.util.Map;
17+
import java.util.stream.Collectors;
1518

1619
@RestController
1720
@RequiredArgsConstructor
@@ -47,4 +50,12 @@ public ResponseEntity<HealthCheckResponse> health() {
4750

4851
return new ResponseEntity<>(healthCheckResponse, statusCode);
4952
}
53+
54+
@GetMapping("/api/authorities")
55+
public ResponseEntity<List<String>> authorities() {
56+
List<String> authorityNames = Arrays.stream(Authority.values())
57+
.map(Authority::getAuthority)
58+
.collect(Collectors.toList());
59+
return new ResponseEntity<>(authorityNames, HttpStatus.OK);
60+
}
5061
}

src/main/java/com/ics/entities/EmailVerificationToken.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,16 @@ public boolean isExpired() {
4949
public boolean createdInLastSeconds(int seconds) {
5050
return Instant.now().isBefore(this.createdDate.plusSeconds(seconds));
5151
}
52+
53+
@Override
54+
public String toString() {
55+
return "EmailVerificationToken{" +
56+
"id=" + id +
57+
", token='" + token + '\'' +
58+
", expiryDate=" + expiryDate +
59+
", createdDate=" + createdDate +
60+
", isUsed=" + isUsed +
61+
", account=" + account +
62+
'}';
63+
}
5264
}

src/main/java/com/ics/entities/PasswordResetToken.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,4 @@ public boolean isExpired() {
4848
public boolean haveBeenCreatedLately(int seconds) {
4949
return Instant.now().isBefore(this.createdDate.plusSeconds(seconds));
5050
}
51-
5251
}

src/main/java/com/ics/events/listeners/EmailsListener.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ public void onAccountCreatedEvent(AccountCreatedEvent event) {
2626
"Your account have been created successfully." + "\n" +
2727
"If you didn't request this, please contact us.";
2828

29-
emailService.sendEmail(event.getEmail(), "Account created", body);
29+
emailService.sendEmail("[email protected]", "Account created", body);
3030
}
3131

3232
@EventListener(EmailVerificationTokenGeneratedEvent.class)
3333
public void onEmailVerificationTokenGeneratedEvent(EmailVerificationTokenGeneratedEvent event) {
34-
String link = amwc + "/auth/confirm-email-verification?token=" + event.getToken();
34+
String link = amwc + "/auth/email-verification/confirm?token=" + event.getToken();
3535
String email = event.getEmail();
3636
String body = "Hello, " + email + "\n" +
3737
"Click here to verify your email: " + link + "\n" +
@@ -42,13 +42,13 @@ public void onEmailVerificationTokenGeneratedEvent(EmailVerificationTokenGenerat
4242

4343
@EventListener(PasswordResetGeneratedEvent.class)
4444
public void onPasswordResetGeneratedEvent(PasswordResetGeneratedEvent event) {
45-
String link = amwc + "/auth/confirm-reset-password?token=" + event.getToken();
45+
String link = amwc + "/auth/reset-password/confirm?token=" + event.getToken();
4646
String email = event.getEmail();
4747
String body = "Hello, " + email + "\n" +
4848
"Click here to reset your password: " + link + "\n" +
4949
"If you didn't request this, please ignore this email.";
5050

51-
emailService.sendEmail(event.getEmail(), "Password reset", body);
51+
emailService.sendEmail("[email protected]", "Password reset", body);
5252
}
5353

5454
@EventListener(PasswordHaveBeenResetedEvent.class)
@@ -58,7 +58,7 @@ public void onPasswordHaveBeenResetedEvent(PasswordHaveBeenResetedEvent event) {
5858
"Your password have been reseted successfully." + "\n" +
5959
"If you didn't request this, please contact us.";
6060

61-
emailService.sendEmail(event.getEmail(), "Password reseted", body);
61+
emailService.sendEmail("[email protected]", "Password reseted", body);
6262
}
6363

6464
@EventListener(PasswordChangedEvent.class)
@@ -68,7 +68,7 @@ public void onPasswordChangedEvent(PasswordChangedEvent event) {
6868
"Your password have been changed successfully." + "\n" +
6969
"If you didn't request this, please contact us.";
7070

71-
emailService.sendEmail(event.getEmail(), "Password changed", body);
71+
emailService.sendEmail("[email protected]", "Password changed", body);
7272
}
7373

7474
@EventListener(AccountDeletedEvent.class)
@@ -78,7 +78,7 @@ public void onAccountDeletedEvent(AccountDeletedEvent event) {
7878
"Your account have been deleted successfully." + "\n" +
7979
"If you didn't request this, please contact us.";
8080

81-
emailService.sendEmail(event.getEmail(), "Account deleted", body);
81+
emailService.sendEmail("[email protected]", "Account deleted", body);
8282
}
8383

8484
}

src/main/java/com/ics/services/AccountService.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ public Account getAccountById(UUID accountId) {
205205
}
206206

207207
@Override
208-
@PreAuthorize("@securityService.hasAuthority(T(com.ics.enums.Authority).VIEW_ACCOUNT)")
209208
public Account getAccountByEmail(String email) {
210209
return accountRepository.findByEmail(email)
211210
.orElseThrow(() -> new EntityNotFoundException("'"+email+"'" + " Does not exist"));

src/main/java/com/ics/services/EmailVerificationTokenService.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.ics.interfaces.services.IEmailVerificationTokenService;
88
import com.ics.repositories.EmailVerificationTokenRepository;
99
import jakarta.persistence.EntityNotFoundException;
10+
import jakarta.transaction.Transactional;
1011
import lombok.RequiredArgsConstructor;
1112
import org.springframework.beans.factory.annotation.Value;
1213
import org.springframework.stereotype.Service;
@@ -27,6 +28,8 @@ public class EmailVerificationTokenService implements IEmailVerificationTokenSer
2728

2829
private final EmailVerificationTokenRepository emailVerificationTokenRepository;
2930

31+
@Override
32+
@Transactional
3033
public String generateEmailVerificationToken(Account account) {
3134
var existingToken = emailVerificationTokenRepository.findByAccount(account);
3235

@@ -44,15 +47,18 @@ public String generateEmailVerificationToken(Account account) {
4447
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mma dd/MM/yyyy");
4548
throw new BadRequestException("A New Token can be generated after " + canGenerateTokenAfter.format(formatter));
4649
}
47-
50+
token.setAccount(null);
51+
account.setEmailVerificationToken(null);
4852
emailVerificationTokenRepository.delete(token);
53+
emailVerificationTokenRepository.flush();
4954
}
5055

5156
var newToken = new EmailVerificationToken(account, emailVerificationTokenExpiryInSec);
5257
emailVerificationTokenRepository.save(newToken);
5358
return newToken.getToken();
5459
}
5560

61+
@Override
5662
public String consumeEmailVerificationToken(String token) {
5763
var emailVerificationToken = emailVerificationTokenRepository.findByToken(token).orElseThrow(
5864
() -> new EntityNotFoundException("Email verification token not found"));

src/main/java/com/ics/services/PasswordResetTokenService.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.ics.interfaces.services.IPasswordResetTokenService;
77
import com.ics.repositories.PasswordResetTokenRepository;
88
import jakarta.persistence.EntityNotFoundException;
9+
import jakarta.transaction.Transactional;
910
import lombok.RequiredArgsConstructor;
1011
import org.springframework.beans.factory.annotation.Value;
1112
import org.springframework.stereotype.Service;
@@ -27,6 +28,7 @@ public class PasswordResetTokenService implements IPasswordResetTokenService {
2728
private final PasswordResetTokenRepository passwordResetTokenRepository;
2829

2930
@Override
31+
@Transactional
3032
public String generatePasswordResetToken(Account account) {
3133
var existingToken = passwordResetTokenRepository.findByAccount(account);
3234

@@ -40,10 +42,16 @@ public String generatePasswordResetToken(Account account) {
4042
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mma dd/MM/yyyy");
4143
throw new BadRequestException("A New Token can be generated after " + canGenerateTokenAfter.format(formatter));
4244
}
43-
45+
account.setPasswordResetToken(null);
46+
token.setAccount(null);
4447
passwordResetTokenRepository.delete(token);
48+
passwordResetTokenRepository.flush();
4549
}
4650

51+
return createNewPasswordResetToken(account);
52+
}
53+
54+
private String createNewPasswordResetToken(Account account) {
4755
var newToken = new PasswordResetToken(account, passwordResetTokenExpiryInSec);
4856
passwordResetTokenRepository.save(newToken);
4957
return newToken.getToken();

0 commit comments

Comments
 (0)