recovery del pass hecho en el backend a falta de hacer los formularios

This commit is contained in:
2025-09-28 18:36:44 +02:00
parent 22198b4f25
commit 865b1573b9
15 changed files with 517 additions and 8 deletions

View File

@ -0,0 +1,54 @@
package com.imprimelibros.erp.common;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.context.MessageSource;
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.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.util.Locale;
import java.util.Map;
@Service
public class EmailService {
private final JavaMailSender mailSender;
private final TemplateEngine templateEngine;
private final MessageSource messageSource;
public EmailService(JavaMailSender mailSender, TemplateEngine templateEngine, MessageSource messageSource) {
this.mailSender = mailSender;
this.templateEngine = templateEngine;
this.messageSource = messageSource;
}
public void sendPasswordResetMail(String to, String username, String resetLink, Locale locale) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setFrom("no-reply@imprimelibros.com");
helper.setTo(to);
helper.setSubject(messageSource.getMessage("email.resetPassword.title", null, locale));
// Variables para la plantilla
Context context = new Context();
context.setVariables(Map.of(
"username", username,
"resetLink", resetLink,
"year", String.valueOf(java.time.Year.now().getValue())
));
// Procesar plantilla HTML
String html = templateEngine.process("email/password-reset", context);
helper.setText(html, true);
helper.addInline("companyLogo", new ClassPathResource("static/images/logo-light.png"));
mailSender.send(message);
}
}

View File

@ -0,0 +1,26 @@
package com.imprimelibros.erp.common;
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Refill;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class RateLimiterService {
private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
// 5 solicitudes cada 15 minutos por clave (IP)
private Bucket newBucket() {
Bandwidth limit = Bandwidth.classic(5, Refill.greedy(5, Duration.ofMinutes(15)));
return Bucket.builder().addLimit(limit).build();
}
public boolean tryConsume(String key) {
return buckets.computeIfAbsent(key, k -> newBucket()).tryConsume(1);
}
}