NCBACK-33 add email send
Test Workflow / test (push) Successful in 4s

This commit is contained in:
vladp
2026-01-20 03:47:51 +07:00
parent 4a8e561258
commit 55fa8b84e2
44 changed files with 443 additions and 147 deletions
@@ -1,6 +1,5 @@
package ru.soune.nocopy.service;
package ru.soune.nocopy.service.mail;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -29,14 +28,23 @@ public class EmailService {
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) {
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setFrom("NO COPY <noreply@nocopy.com>");
helper.setFrom(standartAdressFrom);
helper.setTo(user.getEmail());
helper.setSubject("NO COPY - Подтверждение email");
helper.setSubject(standartSubject);
String htmlContent = loadAndProcessTemplate(user.getFullName(), code);
helper.setText(htmlContent, true);
@@ -55,7 +63,6 @@ public class EmailService {
EmailVerificationToken emailToken = new EmailVerificationToken();
emailToken.setUser(authToken.getUser());
emailToken.setToken(generateVerificationCode());
emailToken.setExpiresAt(LocalDateTime.now().plusMinutes(15));
emailToken.setCreatedAt(LocalDateTime.now());
return emailVerificationTokenRepository.save(emailToken);
@@ -71,7 +78,7 @@ public class EmailService {
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 : "Пользователь");
String safeUsername = escapeHtml(username != null ? username : user);
String safeCode = escapeHtml(code);
return template
@@ -1,4 +1,4 @@
package ru.soune.nocopy.service;
package ru.soune.nocopy.service.register;
import lombok.RequiredArgsConstructor;
import org.springframework.context.MessageSource;
@@ -6,6 +6,9 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.*;
import ru.soune.nocopy.dto.register.LoginAnswer;
import ru.soune.nocopy.dto.register.LoginRequest;
import ru.soune.nocopy.dto.register.RegRequest;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.NotValidFieldException;
@@ -0,0 +1,31 @@
package ru.soune.nocopy.service.register;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.entity.user.EmailVerificationToken;
import ru.soune.nocopy.repository.EmailVerificationTokenRepository;
import java.time.LocalDateTime;
import java.util.List;
@Service
@RequiredArgsConstructor
public class CleanUpVerifyTokens {
private final EmailVerificationTokenRepository emailVerificationTokenRepository;
@Transactional
@Scheduled(fixedDelay = 30000)
public void cleanupExpiredTokens() {
LocalDateTime now = LocalDateTime.now();
List<EmailVerificationToken> expiredTokens = emailVerificationTokenRepository.findByExpiresAtBefore(now);
if (!expiredTokens.isEmpty()) {
emailVerificationTokenRepository.deleteAll(expiredTokens);
}
}
}
@@ -1,4 +1,4 @@
package ru.soune.nocopy.service;
package ru.soune.nocopy.service.search;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -12,7 +12,6 @@ import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.file.YandexSearchResponse;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.exception.FileEntityNotFoundException;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.repository.FileEntityRepository;
@@ -1,10 +1,10 @@
package ru.soune.nocopy.service;
package ru.soune.nocopy.service.user;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.UserContentRequest;
import ru.soune.nocopy.dto.UserContentUpdateRequest;
import ru.soune.nocopy.dto.user.UserContentRequest;
import ru.soune.nocopy.dto.user.UserContentUpdateRequest;
import ru.soune.nocopy.entity.file.FileType;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.entity.user.UserContent;
@@ -1,18 +1,20 @@
package ru.soune.nocopy.service;
package ru.soune.nocopy.service.user;
import lombok.AllArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.ChangePasswordRequest;
import ru.soune.nocopy.dto.UserDTO;
import ru.soune.nocopy.dto.UserRequest;
import ru.soune.nocopy.dto.register.ChangePasswordRequest;
import ru.soune.nocopy.dto.user.UserDTO;
import ru.soune.nocopy.dto.user.UserRequest;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.InvalidUserEmail;
import ru.soune.nocopy.exception.NotValidationPasswordException;
import ru.soune.nocopy.exception.UserNotFoundException;
import ru.soune.nocopy.repository.UserRepository;
import java.util.Optional;
@Service
@AllArgsConstructor
public class UserService {
@@ -44,6 +46,16 @@ public class UserService {
return mapToDTO(updatedUser);
}
@Transactional
public void activateAndVerifyUser(long userId) {
Optional<User> users = userRepository.findById(userId);
User user = users.orElseThrow(() -> new UserNotFoundException("User not found with id: " + userId));
user.setIsActive(true);
user.setEmailVerified(true);
userRepository.save(user);
}
private void updateUserFromRequest(User user, UserRequest request) {
if (request.getFullName() != null) {
user.setFullName(request.getFullName());