using System.Net; using System.Net.Mail; using ColaFlow.Modules.Identity.Application.Services; using ColaFlow.Modules.Identity.Domain.Services; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace ColaFlow.Modules.Identity.Infrastructure.Services; /// /// SMTP-based email service for production use /// public sealed class SmtpEmailService( ILogger logger, IConfiguration configuration) : IEmailService { public async Task SendEmailAsync(EmailMessage message, CancellationToken cancellationToken = default) { try { var smtpHost = configuration["Email:Smtp:Host"]; var smtpPort = int.Parse(configuration["Email:Smtp:Port"] ?? "587"); var smtpUsername = configuration["Email:Smtp:Username"]; var smtpPassword = configuration["Email:Smtp:Password"]; var enableSsl = bool.Parse(configuration["Email:Smtp:EnableSsl"] ?? "true"); var defaultFromEmail = configuration["Email:From"] ?? "noreply@colaflow.local"; var defaultFromName = configuration["Email:FromName"] ?? "ColaFlow"; using var smtpClient = new SmtpClient(smtpHost, smtpPort) { Credentials = new NetworkCredential(smtpUsername, smtpPassword), EnableSsl = enableSsl }; using var mailMessage = new MailMessage { From = new MailAddress( message.FromEmail ?? defaultFromEmail, message.FromName ?? defaultFromName), Subject = message.Subject, Body = message.HtmlBody, IsBodyHtml = true }; mailMessage.To.Add(message.To); // Add plain text alternative if provided if (!string.IsNullOrEmpty(message.PlainTextBody)) { var plainView = AlternateView.CreateAlternateViewFromString( message.PlainTextBody, null, "text/plain"); mailMessage.AlternateViews.Add(plainView); } await smtpClient.SendMailAsync(mailMessage, cancellationToken); logger.LogInformation( "Email sent successfully to {To} with subject: {Subject}", message.To, message.Subject); return true; } catch (Exception ex) { logger.LogError( ex, "Failed to send email to {To} with subject: {Subject}", message.To, message.Subject); return false; } } }