diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 4c75faefbc..b86969acbb 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Core/GlobalSettings.cs b/src/Core/GlobalSettings.cs index 0640671c0c..879ec28038 100644 --- a/src/Core/GlobalSettings.cs +++ b/src/Core/GlobalSettings.cs @@ -117,6 +117,7 @@ namespace Bit.Core public string Password { get; set; } public bool UseDefaultCredentials { get; set; } = false; public string AuthType { get; set; } + public bool TrustServer { get; set; } = false; } } diff --git a/src/Core/Services/Implementations/MailKitSmtpMailDeliveryService.cs b/src/Core/Services/Implementations/MailKitSmtpMailDeliveryService.cs new file mode 100644 index 0000000000..e7b410f52a --- /dev/null +++ b/src/Core/Services/Implementations/MailKitSmtpMailDeliveryService.cs @@ -0,0 +1,84 @@ +using System; +using System.Threading.Tasks; +using MailKit.Net.Smtp; +using Microsoft.Extensions.Logging; +using MimeKit; + +namespace Bit.Core.Services +{ + public class MailKitSmtpMailDeliveryService : IMailDeliveryService + { + private readonly GlobalSettings _globalSettings; + private readonly ILogger _logger; + private readonly string _replyDomain; + + public MailKitSmtpMailDeliveryService( + GlobalSettings globalSettings, + ILogger logger) + { + if(globalSettings.Mail?.Smtp?.Host == null) + { + throw new ArgumentNullException(nameof(globalSettings.Mail.Smtp.Host)); + } + if(globalSettings.Mail?.ReplyToEmail?.Contains("@") ?? false) + { + _replyDomain = globalSettings.Mail.ReplyToEmail.Split('@')[1]; + } + + _globalSettings = globalSettings; + _logger = logger; + } + + public async Task SendEmailAsync(Models.Mail.MailMessage message) + { + var mimeMessage = new MimeMessage(); + mimeMessage.From.Add(new MailboxAddress(_globalSettings.SiteName, _globalSettings.Mail.ReplyToEmail)); + mimeMessage.Subject = message.Subject; + if(!string.IsNullOrWhiteSpace(_replyDomain)) + { + mimeMessage.MessageId = $"<{Guid.NewGuid()}@{_replyDomain}>"; + } + + foreach(var address in message.ToEmails) + { + mimeMessage.To.Add(new MailboxAddress(address)); + } + + if(message.BccEmails != null) + { + foreach(var address in message.BccEmails) + { + mimeMessage.Bcc.Add(new MailboxAddress(address)); + } + } + + var builder = new BodyBuilder(); + if(!string.IsNullOrWhiteSpace(message.TextContent)) + { + builder.TextBody = message.TextContent; + } + builder.HtmlBody = message.HtmlContent; + mimeMessage.Body = builder.ToMessageBody(); + + using(var client = new SmtpClient()) + { + if(_globalSettings.Mail.Smtp.TrustServer) + { + client.ServerCertificateValidationCallback = (s, c, h, e) => true; + } + + var useSsl = _globalSettings.Mail.Smtp.Port == 587 ? false : _globalSettings.Mail.Smtp.Ssl; + await client.ConnectAsync(_globalSettings.Mail.Smtp.Host, _globalSettings.Mail.Smtp.Port, useSsl); + + if(!_globalSettings.Mail.Smtp.UseDefaultCredentials) + { + await client.AuthenticateAsync(_globalSettings.Mail.Smtp.Username, + _globalSettings.Mail.Smtp.Password); + } + + await client.SendAsync(mimeMessage); + await client.DisconnectAsync(true); + } + } + } +} diff --git a/src/Core/Services/Implementations/SmtpMailDeliveryService.cs b/src/Core/Services/Implementations/SmtpMailDeliveryService.cs index 5f206686e8..65c7ea8a07 100644 --- a/src/Core/Services/Implementations/SmtpMailDeliveryService.cs +++ b/src/Core/Services/Implementations/SmtpMailDeliveryService.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Logging; namespace Bit.Core.Services { + [Obsolete] public class SmtpMailDeliveryService : IMailDeliveryService { private readonly GlobalSettings _globalSettings; diff --git a/src/Core/Utilities/ServiceCollectionExtensions.cs b/src/Core/Utilities/ServiceCollectionExtensions.cs index ab4906c6cc..6dac10bb0c 100644 --- a/src/Core/Utilities/ServiceCollectionExtensions.cs +++ b/src/Core/Utilities/ServiceCollectionExtensions.cs @@ -87,7 +87,7 @@ namespace Bit.Core.Utilities } else if(CoreHelpers.SettingHasValue(globalSettings.Mail?.Smtp?.Host)) { - services.AddSingleton(); + services.AddSingleton(); } else {