From ac099aa5131bc358488c300483d3572f585bb0bc Mon Sep 17 00:00:00 2001 From: Nicolas Dorier Date: Wed, 15 Dec 2021 21:30:46 +0900 Subject: [PATCH] Change implementation of the Smtp server (#3202) * Change implementation of the Smtp server * Update BTCPayServer/Services/Mails/EmailSettings.cs Co-authored-by: Andrew Camilleri Co-authored-by: Andrew Camilleri --- BTCPayServer.Tests/UnitTest1.cs | 4 +- BTCPayServer/BTCPayServer.csproj | 1 + BTCPayServer/Controllers/ServerController.cs | 8 ++- .../Controllers/StoresController.Email.cs | 8 ++- BTCPayServer/Services/Mails/EmailSender.cs | 16 ++--- BTCPayServer/Services/Mails/EmailSettings.cs | 70 +++++++++++-------- BTCPayServer/Views/Shared/EmailsBody.cshtml | 14 ++-- 7 files changed, 61 insertions(+), 60 deletions(-) diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 388b6bdfd..f8dd221a8 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -2724,7 +2724,6 @@ namespace BTCPayServer.Tests Password = "admin@admin.com", Port = 1234, Server = "admin.com", - EnableSSL = true }); Assert.Equal("admin@admin.com",(await Assert.IsType(await emailSenderFactory.GetEmailSender()).GetEmailSettings()).Login); Assert.Equal("admin@admin.com",(await Assert.IsType(await emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login); @@ -2739,8 +2738,7 @@ namespace BTCPayServer.Tests Login = "store@store.com", Password = "store@store.com", Port = 1234, - Server = "store.com", - EnableSSL = true + Server = "store.com" }), "")); Assert.Equal("store@store.com",(await Assert.IsType(await emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login); diff --git a/BTCPayServer/BTCPayServer.csproj b/BTCPayServer/BTCPayServer.csproj index 5dd4a205c..f25a4b664 100644 --- a/BTCPayServer/BTCPayServer.csproj +++ b/BTCPayServer/BTCPayServer.csproj @@ -56,6 +56,7 @@ + diff --git a/BTCPayServer/Controllers/ServerController.cs b/BTCPayServer/Controllers/ServerController.cs index e87db9518..b51971f94 100644 --- a/BTCPayServer/Controllers/ServerController.cs +++ b/BTCPayServer/Controllers/ServerController.cs @@ -32,6 +32,7 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using MimeKit; using NBitcoin; using NBitcoin.DataEncoders; using Renci.SshNet; @@ -1025,10 +1026,11 @@ namespace BTCPayServer.Controllers TempData[WellKnownTempData.ErrorMessage] = "Required fields missing"; return View(model); } - using (var client = model.Settings.CreateSmtpClient()) - using (var message = model.Settings.CreateMailMessage(new MailAddress(model.TestEmail), "BTCPay test", "BTCPay test")) + using (var client = await model.Settings.CreateSmtpClient()) + using (var message = model.Settings.CreateMailMessage(new MailboxAddress(model.TestEmail, model.TestEmail), "BTCPay test", "BTCPay test", false)) { - await client.SendMailAsync(message); + await client.SendAsync(message); + await client.DisconnectAsync(true); } TempData[WellKnownTempData.SuccessMessage] = "Email sent to " + model.TestEmail + ", please, verify you received it"; } diff --git a/BTCPayServer/Controllers/StoresController.Email.cs b/BTCPayServer/Controllers/StoresController.Email.cs index 1551489e2..b9fbeb9ba 100644 --- a/BTCPayServer/Controllers/StoresController.Email.cs +++ b/BTCPayServer/Controllers/StoresController.Email.cs @@ -5,6 +5,7 @@ using BTCPayServer.Data; using BTCPayServer.Models.ServerViewModels; using BTCPayServer.Services.Mails; using Microsoft.AspNetCore.Mvc; +using MimeKit; namespace BTCPayServer.Controllers { @@ -41,9 +42,10 @@ namespace BTCPayServer.Controllers TempData[WellKnownTempData.ErrorMessage] = "Required fields missing"; return View(model); } - var client = model.Settings.CreateSmtpClient(); - var message = model.Settings.CreateMailMessage(new MailAddress(model.TestEmail), "BTCPay test", "BTCPay test"); - await client.SendMailAsync(message); + using var client = await model.Settings.CreateSmtpClient(); + var message = model.Settings.CreateMailMessage(new MailboxAddress(model.TestEmail, model.TestEmail), "BTCPay test", "BTCPay test", false); + await client.SendAsync(message); + await client.DisconnectAsync(true); TempData[WellKnownTempData.SuccessMessage] = "Email sent to " + model.TestEmail + ", please, verify you received it"; } catch (Exception ex) diff --git a/BTCPayServer/Services/Mails/EmailSender.cs b/BTCPayServer/Services/Mails/EmailSender.cs index abe011bd8..21e26fb12 100644 --- a/BTCPayServer/Services/Mails/EmailSender.cs +++ b/BTCPayServer/Services/Mails/EmailSender.cs @@ -3,6 +3,7 @@ using System.Net.Mail; using System.Threading.Tasks; using BTCPayServer.Logging; using Microsoft.Extensions.Logging; +using MimeKit; using NBitcoin; namespace BTCPayServer.Services.Mails @@ -29,18 +30,11 @@ namespace BTCPayServer.Services.Mails Logs.Configuration.LogWarning("Should have sent email, but email settings are not configured"); return; } - using (var smtp = emailSettings.CreateSmtpClient()) + using (var smtp = await emailSettings.CreateSmtpClient()) { - var mail = emailSettings.CreateMailMessage(new MailAddress(email), subject, message); - mail.IsBodyHtml = true; - try - { - await smtp.SendMailAsync(mail).WithCancellation(cancellationToken); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - smtp.SendAsyncCancel(); - } + var mail = emailSettings.CreateMailMessage(new MailboxAddress(email, email), subject, message, true); + await smtp.SendAsync(mail, cancellationToken); + await smtp.DisconnectAsync(true, cancellationToken); } }, TimeSpan.Zero); } diff --git a/BTCPayServer/Services/Mails/EmailSettings.cs b/BTCPayServer/Services/Mails/EmailSettings.cs index 9483b2f46..b137231af 100644 --- a/BTCPayServer/Services/Mails/EmailSettings.cs +++ b/BTCPayServer/Services/Mails/EmailSettings.cs @@ -1,7 +1,10 @@ using System.ComponentModel.DataAnnotations; using System.Net; -using System.Net.Mail; using Newtonsoft.Json; +using MailKit.Net.Smtp; +using MimeKit; +using System.Threading.Tasks; +using System.Threading; namespace BTCPayServer.Services.Mails { @@ -41,42 +44,47 @@ namespace BTCPayServer.Services.Mails get; set; } - [Display(Name = "Enable SSL")] - public bool EnableSSL - { - get; set; - } - public bool IsComplete() { + return !string.IsNullOrWhiteSpace(Server) && + Port is int && + !string.IsNullOrWhiteSpace(Login) && + !string.IsNullOrWhiteSpace(Password); + } + + public MimeMessage CreateMailMessage(MailboxAddress to, string subject, string message, bool isHtml) + { + var bodyBuilder = new BodyBuilder(); + if (isHtml) + { + bodyBuilder.HtmlBody = message; + } + else + { + bodyBuilder.TextBody = message; + } + + return new MimeMessage( + from : new[] { new MailboxAddress(From, !string.IsNullOrWhiteSpace(FromDisplay) ? From : FromDisplay) }, + to: new[] { to }, + subject, + bodyBuilder.ToMessageBody()); + } + + public async Task CreateSmtpClient() + { + SmtpClient client = new SmtpClient(); + using var connectCancel = new CancellationTokenSource(10000); try { - using var smtp = CreateSmtpClient(); - return true; + await client.ConnectAsync(Server, Port.Value, MailKit.Security.SecureSocketOptions.Auto, connectCancel.Token); + await client.AuthenticateAsync(Login, Password, connectCancel.Token); } - catch { } - return false; - } - - public MailMessage CreateMailMessage(MailAddress to, string subject, string message) - { - return new MailMessage( - from: new MailAddress(From, FromDisplay), - to: to) + catch { - Subject = subject, - Body = message - }; - } - - public SmtpClient CreateSmtpClient() - { - SmtpClient client = new SmtpClient(Server, Port.Value); - client.EnableSsl = EnableSSL; - client.UseDefaultCredentials = false; - client.Credentials = new NetworkCredential(Login, Password); - client.DeliveryMethod = SmtpDeliveryMethod.Network; - client.Timeout = 10000; + client.Dispose(); + throw; + } return client; } } diff --git a/BTCPayServer/Views/Shared/EmailsBody.cshtml b/BTCPayServer/Views/Shared/EmailsBody.cshtml index edec6efde..7621db7db 100644 --- a/BTCPayServer/Views/Shared/EmailsBody.cshtml +++ b/BTCPayServer/Views/Shared/EmailsBody.cshtml @@ -9,11 +9,11 @@ Quick Fill @@ -75,10 +75,6 @@ } -
- - -