using System; using System.Threading.Tasks; using Bit.Core.Utilities; 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(MailboxAddress.Parse(address)); } if (message.BccEmails != null) { foreach (var address in message.BccEmails) { mimeMessage.Bcc.Add(MailboxAddress.Parse(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; } if (!_globalSettings.Mail.Smtp.StartTls && !_globalSettings.Mail.Smtp.Ssl && _globalSettings.Mail.Smtp.Port == 25) { await client.ConnectAsync(_globalSettings.Mail.Smtp.Host, _globalSettings.Mail.Smtp.Port, MailKit.Security.SecureSocketOptions.None); } else { var useSsl = _globalSettings.Mail.Smtp.Port == 587 && !_globalSettings.Mail.Smtp.SslOverride ? false : _globalSettings.Mail.Smtp.Ssl; await client.ConnectAsync(_globalSettings.Mail.Smtp.Host, _globalSettings.Mail.Smtp.Port, useSsl); } if (CoreHelpers.SettingHasValue(_globalSettings.Mail.Smtp.Username) && CoreHelpers.SettingHasValue(_globalSettings.Mail.Smtp.Password)) { await client.AuthenticateAsync(_globalSettings.Mail.Smtp.Username, _globalSettings.Mail.Smtp.Password); } await client.SendAsync(mimeMessage); await client.DisconnectAsync(true); } } } }