progress on registration flow

This commit is contained in:
2025-09-11 00:02:20 +02:00
parent 1987c1855e
commit e13e8e1ffe
10 changed files with 238 additions and 6 deletions

View File

@@ -0,0 +1,46 @@
package zw.qantra.tm.domain.services;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import zw.qantra.tm.domain.dtos.EmailRequest;
import java.util.Objects;
@Slf4j
@Service
@RequiredArgsConstructor
public class EmailService {
private final JavaMailSender mailSender;
/**
* Sends an email based on the provided EmailRequest
* @param emailRequest the email request containing recipient, subject, and body
* @return true if the email was sent successfully, false otherwise
*/
public boolean sendEmail(EmailRequest emailRequest) {
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(emailRequest.getTo());
if (emailRequest.getCc() != null && !emailRequest.getCc().isEmpty()) {
helper.setCc(emailRequest.getCc().toArray(new String[0]));
}
helper.setSubject(emailRequest.getSubject());
helper.setText(emailRequest.getBody(), emailRequest.isHtml());
mailSender.send(message);
log.info("Email sent successfully to {}", emailRequest.getTo());
return true;
} catch (MessagingException e) {
log.error("Failed to send email to {}: {}", emailRequest.getTo(), e.getMessage(), e);
return false;
}
}
}

View File

@@ -0,0 +1,67 @@
package zw.qantra.tm.domain.services;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import zw.qantra.tm.domain.enums.Status;
import zw.qantra.tm.domain.models.Otp;
import zw.qantra.tm.domain.repositories.OtpRepository;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class OtpService {
private static final int OTP_LENGTH = 6;
private static final String NUMBERS = "0123456789";
private static final SecureRandom random = new SecureRandom();
private final OtpRepository otpRepository;
public Otp generateOtp(String username, String otpType) {
// Delete any existing OTP for this username and type
otpRepository.deleteByUsernameAndOtpType(username, otpType);
String otpCode = generateRandomOtp();
Otp otp = Otp.builder()
.username(username)
.otp(otpCode)
.otpType(otpType)
.otpStatus(Status.ACTIVE)
.build();
return otpRepository.save(otp);
}
public boolean verifyOtp(String username, String otpCode, String otpType) {
Optional<Otp> otpOpt = otpRepository.findByUsernameAndOtpTypeAndOtp(username, otpType, otpCode);
if (otpOpt.isEmpty()) {
return false;
}
Otp otp = otpOpt.get();
// Mark OTP as used
otp.setOtpStatus(Status.COMPLETE);
otpRepository.save(otp);
return true;
}
public boolean isOtpValid(String username, String otpType) {
Optional<Otp> otpOpt = otpRepository.findByUsernameAndOtpType(username, otpType);
return otpOpt.isPresent() && otpOpt.get().getOtpStatus() == Status.ACTIVE;
}
private String generateRandomOtp() {
StringBuilder otp = new StringBuilder(OTP_LENGTH);
for (int i = 0; i < OTP_LENGTH; i++) {
otp.append(NUMBERS.charAt(random.nextInt(NUMBERS.length())));
}
return otp.toString();
}
}