using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; using GestorFacturas.API.Data; using GestorFacturas.API.Services.Interfaces; using GestorFacturas.API.Models; using Microsoft.EntityFrameworkCore; namespace GestorFacturas.API.Services; public class MailService : IMailService { private readonly ApplicationDbContext _context; private readonly ILogger _logger; private readonly IEncryptionService _encryptionService; public MailService(ApplicationDbContext context, ILogger logger, IEncryptionService encryptionService) { _context = context; _logger = logger; _encryptionService = encryptionService; } public async Task EnviarCorreoAsync(string destinatario, string asunto, string cuerpo, bool esHTML = true) { try { var config = await _context.Configuraciones.FirstOrDefaultAsync(c => c.Id == 1); if (config == null || string.IsNullOrEmpty(config.SMTPServidor)) { _logger.LogWarning("No hay configuración SMTP disponible"); return false; } if (!config.AvisoMail) { _logger.LogInformation("Envío de correos desactivado en configuración"); return false; } // --- CORRECCIÓN AQUÍ --- // Desencriptamos las credenciales AL PRINCIPIO para usarlas en el 'From' y en el 'Authenticate' string usuarioSmtp = string.IsNullOrEmpty(config.SMTPUsuario) ? "sistema@eldia.com" : _encryptionService.Decrypt(config.SMTPUsuario); string claveSmtp = string.IsNullOrEmpty(config.SMTPClave) ? "" : _encryptionService.Decrypt(config.SMTPClave); // ----------------------- var mensaje = new MimeMessage(); // Usamos la variable desencriptada mensaje.From.Add(new MailboxAddress("Gestor Facturas El Día", usuarioSmtp)); mensaje.To.Add(MailboxAddress.Parse(destinatario)); mensaje.Subject = asunto; var builder = new BodyBuilder(); if (esHTML) builder.HtmlBody = cuerpo; else builder.TextBody = cuerpo; mensaje.Body = builder.ToMessageBody(); using var cliente = new SmtpClient(); // Bypass de certificado SSL para redes internas cliente.ServerCertificateValidationCallback = (s, c, h, e) => true; var secureSocketOptions = config.SMTPSSL ? SecureSocketOptions.StartTls : SecureSocketOptions.Auto; await cliente.ConnectAsync(config.SMTPServidor, config.SMTPPuerto, secureSocketOptions); // Usamos las variables que ya desencriptamos arriba if (!string.IsNullOrEmpty(usuarioSmtp) && !string.IsNullOrEmpty(claveSmtp)) { await cliente.AuthenticateAsync(usuarioSmtp, claveSmtp); } await cliente.SendAsync(mensaje); await cliente.DisconnectAsync(true); _logger.LogInformation("Correo enviado exitosamente a {destinatario}", destinatario); return true; } catch (Exception ex) { _logger.LogError(ex, "Error al enviar correo a {destinatario}", destinatario); return false; } } public async Task ProbarConexionAsync() { // Este método no se está usando actualmente en el flujo crítico (usamos ProbarSMTP en el controller), // pero por consistencia deberías aplicar la misma lógica de desencriptación si planeas usarlo. return true; } /* public async Task ProbarConexionAsync() { try { var config = await _context.Configuraciones.FirstOrDefaultAsync(c => c.Id == 1); if (config == null || string.IsNullOrEmpty(config.SMTPServidor)) { return false; } using var cliente = new SmtpClient(); cliente.ServerCertificateValidationCallback = (s, c, h, e) => true; var secureSocketOptions = config.SMTPSSL ? SecureSocketOptions.StartTls : SecureSocketOptions.Auto; await cliente.ConnectAsync(config.SMTPServidor, config.SMTPPuerto, secureSocketOptions); if (!string.IsNullOrEmpty(config.SMTPUsuario) && !string.IsNullOrEmpty(config.SMTPClave)) { // DESENCRIPTAR AQUÍ var usuario = _encryptionService.Decrypt(config.SMTPUsuario); var clave = _encryptionService.Decrypt(config.SMTPClave); await cliente.AuthenticateAsync(usuario, clave); } await cliente.DisconnectAsync(true); return true; } catch (Exception ex) { _logger.LogError(ex, "Error al probar conexión SMTP"); return false; } }*/ }