mirror of
https://github.com/bitwarden/server.git
synced 2025-03-12 13:29:14 +01:00
ses mail delivery service
This commit is contained in:
parent
6421e326b9
commit
8d54442173
src/Core
@ -21,6 +21,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.3.7.38" />
|
||||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
|
||||||
<PackageReference Include="MailKit" Version="2.1.3" />
|
<PackageReference Include="MailKit" Version="2.1.3" />
|
||||||
|
@ -32,6 +32,7 @@ namespace Bit.Core
|
|||||||
public virtual DuoSettings Duo { get; set; } = new DuoSettings();
|
public virtual DuoSettings Duo { get; set; } = new DuoSettings();
|
||||||
public virtual BraintreeSettings Braintree { get; set; } = new BraintreeSettings();
|
public virtual BraintreeSettings Braintree { get; set; } = new BraintreeSettings();
|
||||||
public virtual BitPaySettings BitPay { get; set; } = new BitPaySettings();
|
public virtual BitPaySettings BitPay { get; set; } = new BitPaySettings();
|
||||||
|
public virtual AmazonSettings Amazon { get; set; } = new AmazonSettings();
|
||||||
|
|
||||||
public class BaseServiceUriSettings
|
public class BaseServiceUriSettings
|
||||||
{
|
{
|
||||||
@ -200,5 +201,12 @@ namespace Bit.Core
|
|||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
public string IdentityUri { get; set; }
|
public string IdentityUri { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AmazonSettings
|
||||||
|
{
|
||||||
|
public string AccessKeyId { get; set; }
|
||||||
|
public string AccessKeySecret { get; set; }
|
||||||
|
public string Region { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Models.Mail;
|
||||||
|
using System.Linq;
|
||||||
|
using Amazon.SimpleEmail;
|
||||||
|
using Amazon;
|
||||||
|
using Amazon.SimpleEmail.Model;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Bit.Core.Services
|
||||||
|
{
|
||||||
|
public class AmazonSesMailDeliveryService : IMailDeliveryService, IDisposable
|
||||||
|
{
|
||||||
|
private readonly GlobalSettings _globalSettings;
|
||||||
|
private readonly IHostingEnvironment _hostingEnvironment;
|
||||||
|
private readonly ILogger<AmazonSesMailDeliveryService> _logger;
|
||||||
|
private readonly AmazonSimpleEmailServiceClient _client;
|
||||||
|
private readonly string _source;
|
||||||
|
private readonly string _senderTag;
|
||||||
|
|
||||||
|
public AmazonSesMailDeliveryService(
|
||||||
|
GlobalSettings globalSettings,
|
||||||
|
IHostingEnvironment hostingEnvironment,
|
||||||
|
ILogger<AmazonSesMailDeliveryService> logger)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeyId))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeyId));
|
||||||
|
}
|
||||||
|
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeySecret))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeySecret));
|
||||||
|
}
|
||||||
|
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.Region))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(globalSettings.Amazon.Region));
|
||||||
|
}
|
||||||
|
|
||||||
|
_globalSettings = globalSettings;
|
||||||
|
_hostingEnvironment = hostingEnvironment;
|
||||||
|
_logger = logger;
|
||||||
|
_client = new AmazonSimpleEmailServiceClient(globalSettings.Amazon.AccessKeyId,
|
||||||
|
globalSettings.Amazon.AccessKeySecret, RegionEndpoint.GetBySystemName(globalSettings.Amazon.Region));
|
||||||
|
_source = $"\"{globalSettings.SiteName}\" <{globalSettings.Mail.ReplyToEmail}>";
|
||||||
|
_senderTag = $"Server: {globalSettings.ProjectName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_client?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SendEmailAsync(MailMessage message)
|
||||||
|
{
|
||||||
|
var request = new SendEmailRequest
|
||||||
|
{
|
||||||
|
ConfigurationSetName = "Email",
|
||||||
|
Source = _source,
|
||||||
|
Destination = new Destination
|
||||||
|
{
|
||||||
|
ToAddresses = message.ToEmails.ToList()
|
||||||
|
},
|
||||||
|
Message = new Message
|
||||||
|
{
|
||||||
|
Subject = new Content(message.Subject),
|
||||||
|
Body = new Body
|
||||||
|
{
|
||||||
|
Html = new Content
|
||||||
|
{
|
||||||
|
Charset = "UTF-8",
|
||||||
|
Data = message.HtmlContent
|
||||||
|
},
|
||||||
|
Text = new Content
|
||||||
|
{
|
||||||
|
Charset = "UTF-8",
|
||||||
|
Data = message.TextContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Tags = new List<MessageTag>
|
||||||
|
{
|
||||||
|
new MessageTag { Name = "Environment", Value = _hostingEnvironment.EnvironmentName },
|
||||||
|
new MessageTag { Name = "Sender", Value = _senderTag }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(message.BccEmails?.Any() ?? false)
|
||||||
|
{
|
||||||
|
request.Destination.BccAddresses = message.BccEmails.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.MetaData?.ContainsKey("SendGridCategories") ?? false)
|
||||||
|
{
|
||||||
|
var cats = (message.MetaData["SendGridCategories"] as List<string>)
|
||||||
|
.Select(c => new MessageTag { Name = "Category", Value = c });
|
||||||
|
request.Tags.AddRange(cats);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await SendAsync(request, false);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(e, "Failed to send email.");
|
||||||
|
await SendAsync(request, true);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SendAsync(SendEmailRequest request, bool retry)
|
||||||
|
{
|
||||||
|
if(retry)
|
||||||
|
{
|
||||||
|
// wait and try again
|
||||||
|
await Task.Delay(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _client.SendEmailAsync(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user