Refactor email account configuration for multi-account support
Refactored `EmailAccountDto` to represent a single account with immutable properties and added an `Id` field. Introduced `EmailAccountsOptions` to manage multiple accounts and bound it to the `EmailAccounts` configuration section. Updated `DependencyInjection` to register `EmailAccountsOptions` and removed the old single-account binding. Refactored `LimilabsEmailService` to use `EmailAccountsOptions` and select the appropriate account dynamically. Replaced the `EmailAccount` section in `appsettings.Secrets.json` with a new `EmailAccounts` section supporting multiple accounts. Added a package reference for `Microsoft.Extensions.Options. ConfigurationExtensions` to support the options pattern.
This commit is contained in:
@@ -6,20 +6,21 @@ using Limilabs.Client.SMTP;
|
||||
using Limilabs.Mail;
|
||||
using Limilabs.Mail.Headers;
|
||||
using Microsoft.Extensions.Options;
|
||||
using DigitalData.MessagingService.Application.Common.Options;
|
||||
|
||||
namespace DigitalData.MessagingService.Infrastructure.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Email service using Limilabs Mail.dll for SMTP operations (send-only).
|
||||
/// Commercial-grade library with superior Exchange support.
|
||||
/// SMTP configuration is injected via IOptions<EmailAccountDto> from appsettings.json.
|
||||
/// SMTP configuration is injected via IOptions<EmailAccountsOptions> from appsettings.json.
|
||||
/// Uses the first account in the list whose <see cref="EmailAccountDto.Name"/> equals <c>"default"</c>,
|
||||
/// or falls back to the first account if none is named "default".
|
||||
/// </summary>
|
||||
public class LimilabsEmailService(
|
||||
IEncryptionService encryptionService,
|
||||
IOptions<EmailAccountDto> smtpConfig) : IEmailService
|
||||
IOptions<EmailAccountsOptions> smtpConfig) : IEmailService
|
||||
{
|
||||
private readonly EmailAccountDto _smtpAccount = smtpConfig.Value;
|
||||
|
||||
// Register encoding provider for Limilabs (requires windows-1252 and other code pages)
|
||||
static LimilabsEmailService()
|
||||
{
|
||||
@@ -28,14 +29,16 @@ public class LimilabsEmailService(
|
||||
|
||||
public async Task SendEmailAsync(string to, string subject, string body, bool isHtml = true, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var smtpAccount = smtpConfig.Value.Accounts.First();
|
||||
|
||||
using var smtp = new Smtp();
|
||||
|
||||
try
|
||||
{
|
||||
await ConnectAndAuthenticateSmtpAsync(smtp);
|
||||
await ConnectAndAuthenticateSmtpAsync(smtp, smtpAccount);
|
||||
|
||||
var builder = new MailBuilder();
|
||||
builder.From.Add(new MailBox(_smtpAccount.Username));
|
||||
builder.From.Add(new MailBox(smtpAccount.Username));
|
||||
builder.To.Add(new MailBox(to));
|
||||
builder.Subject = subject;
|
||||
|
||||
@@ -74,26 +77,26 @@ public class LimilabsEmailService(
|
||||
|
||||
// --- Private Helper Methods ---
|
||||
|
||||
private async Task ConnectAndAuthenticateSmtpAsync(Smtp smtp)
|
||||
private async Task ConnectAndAuthenticateSmtpAsync(Smtp smtp, EmailAccountDto smtpAccount)
|
||||
{
|
||||
if (_smtpAccount.SmtpUseSsl)
|
||||
if (smtpAccount.SmtpUseSsl)
|
||||
{
|
||||
smtp.ConnectSSL(_smtpAccount.SmtpServer, _smtpAccount.SmtpPort);
|
||||
smtp.ConnectSSL(smtpAccount.SmtpServer, smtpAccount.SmtpPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
smtp.Connect(_smtpAccount.SmtpServer, _smtpAccount.SmtpPort);
|
||||
smtp.Connect(smtpAccount.SmtpServer, smtpAccount.SmtpPort);
|
||||
}
|
||||
|
||||
if (_smtpAccount.UseOAuth2)
|
||||
if (smtpAccount.UseOAuth2)
|
||||
{
|
||||
throw new NotSupportedException("OAuth2 is not configured for this SMTP account. UseOAuth2 must be false.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var password = _smtpAccount.PasswordEncrypted ? encryptionService.Decrypt(_smtpAccount.Password) : _smtpAccount.Password;
|
||||
var password = smtpAccount.PasswordEncrypted ? encryptionService.Decrypt(smtpAccount.Password) : smtpAccount.Password;
|
||||
|
||||
smtp.Login(_smtpAccount.Username, password);
|
||||
smtp.Login(smtpAccount.Username, password);
|
||||
}
|
||||
|
||||
await Task.CompletedTask; // For async consistency
|
||||
|
||||
Reference in New Issue
Block a user