package ru.soune.nocopy.service.mail; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.soune.nocopy.entity.user.AuthToken; import ru.soune.nocopy.entity.user.EmailVerificationToken; import ru.soune.nocopy.entity.user.User; import ru.soune.nocopy.repository.EmailVerificationTokenRepository; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.time.LocalDateTime; @Service @RequiredArgsConstructor @Slf4j public class EmailService { private final JavaMailSender mailSender; private final EmailVerificationTokenRepository emailVerificationTokenRepository; @Value("${app.email.verification.standart-subject}") private String standartSubject; @Value("${app.email.verification.standart-address-from}") private String standartAdressFrom; @Value("${app.email.verification.user}") private String user; public void sendVerificationEmail(User user, String code) throws MessagingException, IOException { MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); helper.setFrom(standartAdressFrom); helper.setTo(user.getEmail()); helper.setSubject(standartSubject); String htmlContent = loadAndProcessTemplate(user.getFullName(), code); helper.setText(htmlContent, true); mailSender.send(message); log.info("Email sent to: {}", user.getEmail()); } @Transactional public EmailVerificationToken createEmailVerificationToken(AuthToken authToken) { EmailVerificationToken emailToken = new EmailVerificationToken(); emailToken.setUser(authToken.getUser()); emailToken.setToken(generateVerificationCode()); emailToken.setCreatedAt(LocalDateTime.now()); return emailVerificationTokenRepository.save(emailToken); } private String generateVerificationCode() { SecureRandom random = new SecureRandom(); int code = 100000 + random.nextInt(900000); return String.valueOf(code); } private String loadAndProcessTemplate(String username, String code) throws IOException { ClassPathResource resource = new ClassPathResource("templates/email-verification.html"); String template = new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8); String safeUsername = escapeHtml(username != null ? username : user); String safeCode = escapeHtml(code); return template .replace("{{username}}", safeUsername) .replace("{{code}}", safeCode); } private String escapeHtml(String text) { if (text == null) return ""; return text .replace("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """) .replace("'", "'"); } }