Skip to content

Commit

Permalink
fix email verif and pasword reset dublicate problem and add endpoint …
Browse files Browse the repository at this point in the history
…to exposed needed authorities for this service
  • Loading branch information
Wassim-Rached committed Nov 1, 2024
1 parent 761218e commit 0fa6237
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.requestMatchers(HttpMethod.POST, "/api/accounts/verify-email/resend").permitAll()
// password resetting
.requestMatchers(HttpMethod.POST, "/api/accounts/reset-password","/api/accounts/reset-password/resend").permitAll()
.requestMatchers(HttpMethod.GET, "/api/accounts/reset-password").permitAll()
// others require authentication
.anyRequest().authenticated()
);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/ics/controllers/AccountController.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public ResponseEntity<String> resendEmailVerificationToken(@RequestParam String

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

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

@GetMapping("/reset-password")
public ResponseEntity<String> isResetPasswordTokenValid(@RequestParam String token, @RequestParam String newPassword) {
public ResponseEntity<String> isResetPasswordTokenValid(@RequestParam(defaultValue = "") String token) {
String email = passwordResetTokenService.validatePasswordResetToken(token);
return new ResponseEntity<>(email, HttpStatus.OK);
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/ics/controllers/MainController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.ics.dto.DependencyStatus;
import com.ics.dto.HealthCheckResponse;
import com.ics.enums.Authority;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
Expand All @@ -10,8 +11,10 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequiredArgsConstructor
Expand Down Expand Up @@ -47,4 +50,12 @@ public ResponseEntity<HealthCheckResponse> health() {

return new ResponseEntity<>(healthCheckResponse, statusCode);
}

@GetMapping("/api/authorities")
public ResponseEntity<List<String>> authorities() {
List<String> authorityNames = Arrays.stream(Authority.values())
.map(Authority::getAuthority)
.collect(Collectors.toList());
return new ResponseEntity<>(authorityNames, HttpStatus.OK);
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/ics/entities/EmailVerificationToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,16 @@ public boolean isExpired() {
public boolean createdInLastSeconds(int seconds) {
return Instant.now().isBefore(this.createdDate.plusSeconds(seconds));
}

@Override
public String toString() {
return "EmailVerificationToken{" +
"id=" + id +
", token='" + token + '\'' +
", expiryDate=" + expiryDate +
", createdDate=" + createdDate +
", isUsed=" + isUsed +
", account=" + account +
'}';
}
}
1 change: 0 additions & 1 deletion src/main/java/com/ics/entities/PasswordResetToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,4 @@ public boolean isExpired() {
public boolean haveBeenCreatedLately(int seconds) {
return Instant.now().isBefore(this.createdDate.plusSeconds(seconds));
}

}
14 changes: 7 additions & 7 deletions src/main/java/com/ics/events/listeners/EmailsListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public void onAccountCreatedEvent(AccountCreatedEvent event) {
"Your account have been created successfully." + "\n" +
"If you didn't request this, please contact us.";

emailService.sendEmail(event.getEmail(), "Account created", body);
emailService.sendEmail("wa55death405@gmail.com", "Account created", body);
}

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

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

emailService.sendEmail(event.getEmail(), "Password reset", body);
emailService.sendEmail("wa55death405@gmail.com", "Password reset", body);
}

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

emailService.sendEmail(event.getEmail(), "Password reseted", body);
emailService.sendEmail("wa55death405@gmail.com", "Password reseted", body);
}

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

emailService.sendEmail(event.getEmail(), "Password changed", body);
emailService.sendEmail("wa55death405@gmail.com", "Password changed", body);
}

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

emailService.sendEmail(event.getEmail(), "Account deleted", body);
emailService.sendEmail("wa55death405@gmail.com", "Account deleted", body);
}

}
1 change: 0 additions & 1 deletion src/main/java/com/ics/services/AccountService.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ public Account getAccountById(UUID accountId) {
}

@Override
@PreAuthorize("@securityService.hasAuthority(T(com.ics.enums.Authority).VIEW_ACCOUNT)")
public Account getAccountByEmail(String email) {
return accountRepository.findByEmail(email)
.orElseThrow(() -> new EntityNotFoundException("'"+email+"'" + " Does not exist"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.ics.interfaces.services.IEmailVerificationTokenService;
import com.ics.repositories.EmailVerificationTokenRepository;
import jakarta.persistence.EntityNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
Expand All @@ -27,6 +28,8 @@ public class EmailVerificationTokenService implements IEmailVerificationTokenSer

private final EmailVerificationTokenRepository emailVerificationTokenRepository;

@Override
@Transactional
public String generateEmailVerificationToken(Account account) {
var existingToken = emailVerificationTokenRepository.findByAccount(account);

Expand All @@ -44,15 +47,18 @@ public String generateEmailVerificationToken(Account account) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mma dd/MM/yyyy");
throw new BadRequestException("A New Token can be generated after " + canGenerateTokenAfter.format(formatter));
}

token.setAccount(null);
account.setEmailVerificationToken(null);
emailVerificationTokenRepository.delete(token);
emailVerificationTokenRepository.flush();
}

var newToken = new EmailVerificationToken(account, emailVerificationTokenExpiryInSec);
emailVerificationTokenRepository.save(newToken);
return newToken.getToken();
}

@Override
public String consumeEmailVerificationToken(String token) {
var emailVerificationToken = emailVerificationTokenRepository.findByToken(token).orElseThrow(
() -> new EntityNotFoundException("Email verification token not found"));
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/com/ics/services/PasswordResetTokenService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.ics.interfaces.services.IPasswordResetTokenService;
import com.ics.repositories.PasswordResetTokenRepository;
import jakarta.persistence.EntityNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
Expand All @@ -27,6 +28,7 @@ public class PasswordResetTokenService implements IPasswordResetTokenService {
private final PasswordResetTokenRepository passwordResetTokenRepository;

@Override
@Transactional
public String generatePasswordResetToken(Account account) {
var existingToken = passwordResetTokenRepository.findByAccount(account);

Expand All @@ -40,10 +42,16 @@ public String generatePasswordResetToken(Account account) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mma dd/MM/yyyy");
throw new BadRequestException("A New Token can be generated after " + canGenerateTokenAfter.format(formatter));
}

account.setPasswordResetToken(null);
token.setAccount(null);
passwordResetTokenRepository.delete(token);
passwordResetTokenRepository.flush();
}

return createNewPasswordResetToken(account);
}

private String createNewPasswordResetToken(Account account) {
var newToken = new PasswordResetToken(account, passwordResetTokenExpiryInSec);
passwordResetTokenRepository.save(newToken);
return newToken.getToken();
Expand Down

0 comments on commit 0fa6237

Please sign in to comment.