using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; using BTCPayServer.Client.Models; using BTCPayServer.Validation; using MailKit.Net.Smtp; using Microsoft.AspNetCore.Mvc.ModelBinding; using MimeKit; namespace BTCPayServer.Services.Mails { public class EmailSettings : EmailSettingsData { public bool IsComplete() { return MailboxAddressValidator.IsMailboxAddress(From) && !string.IsNullOrWhiteSpace(Server) && Port is int; } public void Validate(string prefixKey, ModelStateDictionary modelState) { if (string.IsNullOrWhiteSpace(From)) { modelState.AddModelError($"{prefixKey}{nameof(From)}", new RequiredAttribute().FormatErrorMessage(nameof(From))); } if (!MailboxAddressValidator.IsMailboxAddress(From)) { modelState.AddModelError($"{prefixKey}{nameof(From)}", MailboxAddressAttribute.ErrorMessageConst); } if (string.IsNullOrWhiteSpace(Server)) { modelState.AddModelError($"{prefixKey}{nameof(Server)}", new RequiredAttribute().FormatErrorMessage(nameof(Server))); } if (Port is null) { modelState.AddModelError($"{prefixKey}{nameof(Port)}", new RequiredAttribute().FormatErrorMessage(nameof(Port))); } } public MimeMessage CreateMailMessage(MailboxAddress to, string subject, string message, bool isHtml) => CreateMailMessage(new[] { to }, null, null, subject, message, isHtml); public MimeMessage CreateMailMessage(MailboxAddress[] to, MailboxAddress[] cc, MailboxAddress[] bcc, string subject, string message, bool isHtml) { var bodyBuilder = new BodyBuilder(); if (isHtml) { bodyBuilder.HtmlBody = message; } else { bodyBuilder.TextBody = message; } var mm = new MimeMessage(); mm.Body = bodyBuilder.ToMessageBody(); mm.Subject = subject; mm.From.Add(MailboxAddressValidator.Parse(From)); mm.To.AddRange(to); mm.Cc.AddRange(cc ?? System.Array.Empty()); mm.Bcc.AddRange(bcc ?? System.Array.Empty()); return mm; } public async Task CreateSmtpClient() { SmtpClient client = new SmtpClient(); using var connectCancel = new CancellationTokenSource(10000); try { if (DisableCertificateCheck) { client.CheckCertificateRevocation = false; #pragma warning disable CA5359 // Do Not Disable Certificate Validation client.ServerCertificateValidationCallback = (s, c, h, e) => true; #pragma warning restore CA5359 // Do Not Disable Certificate Validation } await client.ConnectAsync(Server, Port.Value, MailKit.Security.SecureSocketOptions.Auto, connectCancel.Token); if ((client.Capabilities & SmtpCapabilities.Authentication) != 0) await client.AuthenticateAsync(Login ?? string.Empty, Password ?? string.Empty, connectCancel.Token); } catch { client.Dispose(); throw; } return client; } } }