mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 14:22:40 +01:00
Change implementation of the Smtp server (#3202)
* Change implementation of the Smtp server * Update BTCPayServer/Services/Mails/EmailSettings.cs Co-authored-by: Andrew Camilleri <evilkukka@gmail.com> Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
This commit is contained in:
parent
ece5401121
commit
ac099aa513
7 changed files with 61 additions and 60 deletions
|
@ -2724,7 +2724,6 @@ namespace BTCPayServer.Tests
|
||||||
Password = "admin@admin.com",
|
Password = "admin@admin.com",
|
||||||
Port = 1234,
|
Port = 1234,
|
||||||
Server = "admin.com",
|
Server = "admin.com",
|
||||||
EnableSSL = true
|
|
||||||
});
|
});
|
||||||
Assert.Equal("admin@admin.com",(await Assert.IsType<ServerEmailSender>(await emailSenderFactory.GetEmailSender()).GetEmailSettings()).Login);
|
Assert.Equal("admin@admin.com",(await Assert.IsType<ServerEmailSender>(await emailSenderFactory.GetEmailSender()).GetEmailSettings()).Login);
|
||||||
Assert.Equal("admin@admin.com",(await Assert.IsType<StoreEmailSender>(await emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
Assert.Equal("admin@admin.com",(await Assert.IsType<StoreEmailSender>(await emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
||||||
|
@ -2739,8 +2738,7 @@ namespace BTCPayServer.Tests
|
||||||
Login = "store@store.com",
|
Login = "store@store.com",
|
||||||
Password = "store@store.com",
|
Password = "store@store.com",
|
||||||
Port = 1234,
|
Port = 1234,
|
||||||
Server = "store.com",
|
Server = "store.com"
|
||||||
EnableSSL = true
|
|
||||||
}), ""));
|
}), ""));
|
||||||
|
|
||||||
Assert.Equal("store@store.com",(await Assert.IsType<StoreEmailSender>(await emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
Assert.Equal("store@store.com",(await Assert.IsType<StoreEmailSender>(await emailSenderFactory.GetEmailSender(acc.StoreId)).GetEmailSettings()).Login);
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
<PackageReference Include="Fido2.AspNet" Version="2.0.1" />
|
<PackageReference Include="Fido2.AspNet" Version="2.0.1" />
|
||||||
<PackageReference Include="HtmlSanitizer" Version="5.0.372" />
|
<PackageReference Include="HtmlSanitizer" Version="5.0.372" />
|
||||||
<PackageReference Include="LNURL" Version="0.0.15" />
|
<PackageReference Include="LNURL" Version="0.0.15" />
|
||||||
|
<PackageReference Include="MailKit" Version="3.0.0" />
|
||||||
<PackageReference Include="McMaster.NETCore.Plugins.Mvc" Version="1.4.0" />
|
<PackageReference Include="McMaster.NETCore.Plugins.Mvc" Version="1.4.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.2" />
|
||||||
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="3.3.2">
|
<PackageReference Include="Microsoft.NetCore.Analyzers" Version="3.3.2">
|
||||||
|
|
|
@ -32,6 +32,7 @@ using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using MimeKit;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.DataEncoders;
|
using NBitcoin.DataEncoders;
|
||||||
using Renci.SshNet;
|
using Renci.SshNet;
|
||||||
|
@ -1025,10 +1026,11 @@ namespace BTCPayServer.Controllers
|
||||||
TempData[WellKnownTempData.ErrorMessage] = "Required fields missing";
|
TempData[WellKnownTempData.ErrorMessage] = "Required fields missing";
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
using (var client = model.Settings.CreateSmtpClient())
|
using (var client = await model.Settings.CreateSmtpClient())
|
||||||
using (var message = model.Settings.CreateMailMessage(new MailAddress(model.TestEmail), "BTCPay test", "BTCPay test"))
|
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";
|
TempData[WellKnownTempData.SuccessMessage] = "Email sent to " + model.TestEmail + ", please, verify you received it";
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using BTCPayServer.Data;
|
||||||
using BTCPayServer.Models.ServerViewModels;
|
using BTCPayServer.Models.ServerViewModels;
|
||||||
using BTCPayServer.Services.Mails;
|
using BTCPayServer.Services.Mails;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MimeKit;
|
||||||
|
|
||||||
namespace BTCPayServer.Controllers
|
namespace BTCPayServer.Controllers
|
||||||
{
|
{
|
||||||
|
@ -41,9 +42,10 @@ namespace BTCPayServer.Controllers
|
||||||
TempData[WellKnownTempData.ErrorMessage] = "Required fields missing";
|
TempData[WellKnownTempData.ErrorMessage] = "Required fields missing";
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
var client = model.Settings.CreateSmtpClient();
|
using var client = await model.Settings.CreateSmtpClient();
|
||||||
var message = model.Settings.CreateMailMessage(new MailAddress(model.TestEmail), "BTCPay test", "BTCPay test");
|
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";
|
TempData[WellKnownTempData.SuccessMessage] = "Email sent to " + model.TestEmail + ", please, verify you received it";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Net.Mail;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Logging;
|
using BTCPayServer.Logging;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MimeKit;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
|
|
||||||
namespace BTCPayServer.Services.Mails
|
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");
|
Logs.Configuration.LogWarning("Should have sent email, but email settings are not configured");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
using (var smtp = emailSettings.CreateSmtpClient())
|
using (var smtp = await emailSettings.CreateSmtpClient())
|
||||||
{
|
{
|
||||||
var mail = emailSettings.CreateMailMessage(new MailAddress(email), subject, message);
|
var mail = emailSettings.CreateMailMessage(new MailboxAddress(email, email), subject, message, true);
|
||||||
mail.IsBodyHtml = true;
|
await smtp.SendAsync(mail, cancellationToken);
|
||||||
try
|
await smtp.DisconnectAsync(true, cancellationToken);
|
||||||
{
|
|
||||||
await smtp.SendMailAsync(mail).WithCancellation(cancellationToken);
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
smtp.SendAsyncCancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, TimeSpan.Zero);
|
}, TimeSpan.Zero);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Mail;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using MailKit.Net.Smtp;
|
||||||
|
using MimeKit;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace BTCPayServer.Services.Mails
|
namespace BTCPayServer.Services.Mails
|
||||||
{
|
{
|
||||||
|
@ -41,42 +44,47 @@ namespace BTCPayServer.Services.Mails
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Display(Name = "Enable SSL")]
|
|
||||||
public bool EnableSSL
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsComplete()
|
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<SmtpClient> CreateSmtpClient()
|
||||||
|
{
|
||||||
|
SmtpClient client = new SmtpClient();
|
||||||
|
using var connectCancel = new CancellationTokenSource(10000);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var smtp = CreateSmtpClient();
|
await client.ConnectAsync(Server, Port.Value, MailKit.Security.SecureSocketOptions.Auto, connectCancel.Token);
|
||||||
return true;
|
await client.AuthenticateAsync(Login, Password, connectCancel.Token);
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MailMessage CreateMailMessage(MailAddress to, string subject, string message)
|
|
||||||
{
|
|
||||||
return new MailMessage(
|
|
||||||
from: new MailAddress(From, FromDisplay),
|
|
||||||
to: to)
|
|
||||||
{
|
{
|
||||||
Subject = subject,
|
client.Dispose();
|
||||||
Body = message
|
throw;
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
Quick Fill
|
Quick Fill
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu" aria-labelledby="QuickFillDropdownToggle">
|
<div class="dropdown-menu" aria-labelledby="QuickFillDropdownToggle">
|
||||||
<a class="dropdown-item" href="" data-server="smtp.gmail.com" data-port="587" data-enablessl="true">Gmail.com</a>
|
<a class="dropdown-item" href="" data-server="smtp.gmail.com" data-port="587">Gmail.com</a>
|
||||||
<a class="dropdown-item" href="" data-server="mail.yahoo.com" data-port="587" data-enablessl="true">Yahoo.com</a>
|
<a class="dropdown-item" href="" data-server="mail.yahoo.com" data-port="587">Yahoo.com</a>
|
||||||
<a class="dropdown-item" href="" data-server="smtp.mailgun.org" data-port="587" data-enablessl="true">Mailgun</a>
|
<a class="dropdown-item" href="" data-server="smtp.mailgun.org" data-port="587">Mailgun</a>
|
||||||
<a class="dropdown-item" href="" data-server="smtp.office365.com" data-port="587" data-enablessl="true">Office365</a>
|
<a class="dropdown-item" href="" data-server="smtp.office365.com" data-port="587">Office365</a>
|
||||||
<a class="dropdown-item" href="" data-server="smtp.sendgrid.net" data-port="587" data-enablessl="true">SendGrid</a>
|
<a class="dropdown-item" href="" data-server="smtp.sendgrid.net" data-port="587">SendGrid</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,10 +75,6 @@
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label asp-for="Settings.EnableSSL" class="form-label"></label>
|
|
||||||
<input asp-for="Settings.EnableSSL" type="checkbox" data-fill="enablessl" class="btcpay-toggle ms-2" />
|
|
||||||
</div>
|
|
||||||
<input asp-for="PasswordSet" type="hidden"/>
|
<input asp-for="PasswordSet" type="hidden"/>
|
||||||
<button type="submit" class="btn btn-primary" name="command" value="Save">Save</button>
|
<button type="submit" class="btn btn-primary" name="command" value="Save">Save</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue