From 5447c54154d987c36741773566182b65066af5f2 Mon Sep 17 00:00:00 2001 From: Benedek Farkas Date: Mon, 28 Oct 2024 09:44:48 +0100 Subject: [PATCH] Email.Azure: Deconstructing email addresses that include a display name (Lombiq Technologies: OCORE-204) (#16889) --- .../Services/AzureEmailProvider.cs | 3 +- .../Services/AzureEmailProviderBase.cs | 68 ++++++++++++++----- .../Services/DefaultAzureEmailProvider.cs | 3 +- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProvider.cs b/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProvider.cs index f1d444b2310..e5891bddafa 100644 --- a/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProvider.cs @@ -11,10 +11,9 @@ public class AzureEmailProvider : AzureEmailProviderBase public AzureEmailProvider( IOptions options, - IEmailAddressValidator emailAddressValidator, ILogger logger, IStringLocalizer stringLocalizer) - : base(options.Value, emailAddressValidator, logger, stringLocalizer) + : base(options.Value, logger, stringLocalizer) { } diff --git a/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProviderBase.cs b/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProviderBase.cs index ae02404f1f1..f71114ad43c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProviderBase.cs +++ b/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/AzureEmailProviderBase.cs @@ -1,3 +1,4 @@ +using System.Net.Mail; using Azure; using Azure.Communication.Email; using Microsoft.Extensions.Localization; @@ -78,7 +79,6 @@ public abstract class AzureEmailProviderBase : IEmailProvider }; private readonly AzureEmailOptions _providerOptions; - private readonly IEmailAddressValidator _emailAddressValidator; private readonly ILogger _logger; private EmailClient _emailClient; @@ -87,12 +87,10 @@ public abstract class AzureEmailProviderBase : IEmailProvider public AzureEmailProviderBase( AzureEmailOptions options, - IEmailAddressValidator emailAddressValidator, ILogger logger, IStringLocalizer stringLocalizer) { _providerOptions = options; - _emailAddressValidator = emailAddressValidator; _logger = logger; S = stringLocalizer; } @@ -116,12 +114,15 @@ public virtual async Task SendAsync(MailMessage message) if (!string.IsNullOrWhiteSpace(senderAddress)) { - if (!_emailAddressValidator.Validate(senderAddress)) + if (MailAddress.TryCreate(senderAddress, out var senderMailAddress)) + { + // For compatibility with configuration for other providers that allow a sender with display name. + message.From = senderMailAddress.Address; + } + else { return EmailResult.FailedResult(nameof(message.From), S["Invalid email address for the sender: '{0}'.", senderAddress]); } - - message.From = senderAddress; } var errors = new Dictionary>(); @@ -149,7 +150,7 @@ public virtual async Task SendAsync(MailMessage message) { _logger.LogError(ex, "An error occurred while sending an email using the Azure Email Provider."); - // IMPORTANT, do not expose ex.Message as it could contain the connection string in a raw format! + // IMPORTANT: Do not expose ex.Message as it could contain the connection string in a raw format! return EmailResult.FailedResult(string.Empty, S["An error occurred while sending an email."]); } } @@ -158,22 +159,43 @@ private EmailMessage FromMailMessage(MailMessage message, Dictionary toRecipients = null; - if (recipients.To.Count > 0) + var toRecipients = new List(); + foreach (var toRecipient in recipients.To) { - toRecipients = [.. recipients.To.Select(r => new EmailAddress(r))]; + if (MailAddress.TryCreate(toRecipient, out var toMailAddress)) + { + toRecipients.Add(ConvertMailAddressToAzureEmailAddress(toMailAddress)); + } + else + { + errors[nameof(recipients.To)].Add(S["Invalid email address for the 'To' recipient: '{0}'.", toRecipient]); + } } - List ccRecipients = null; - if (recipients.Cc.Count > 0) + var ccRecipients = new List(); + foreach (var ccRecipient in recipients.Cc) { - ccRecipients = [.. recipients.Cc.Select(r => new EmailAddress(r))]; + if (MailAddress.TryCreate(ccRecipient, out var ccMailAddress)) + { + ccRecipients.Add(ConvertMailAddressToAzureEmailAddress(ccMailAddress)); + } + else + { + errors[nameof(recipients.Cc)].Add(S["Invalid email address for the 'CC' recipient: '{0}'.", ccRecipient]); + } } - List bccRecipients = null; - if (recipients.Bcc.Count > 0) + var bccRecipients = new List(); + foreach (var bccRecipient in recipients.Bcc) { - bccRecipients = [.. recipients.Bcc.Select(r => new EmailAddress(r))]; + if (MailAddress.TryCreate(bccRecipient, out var bccMailAddress)) + { + bccRecipients.Add(ConvertMailAddressToAzureEmailAddress(bccMailAddress)); + } + else + { + errors[nameof(recipients.Bcc)].Add(S["Invalid email address for the 'BCC' recipient: '{0}'.", bccRecipient]); + } } var content = new EmailContent(message.Subject); @@ -191,9 +213,16 @@ private EmailMessage FromMailMessage(MailMessage message, Dictionary + new EmailAddress(mailAddress.Address, mailAddress.DisplayName); } diff --git a/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/DefaultAzureEmailProvider.cs b/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/DefaultAzureEmailProvider.cs index 321b18754de..009189cc46c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/DefaultAzureEmailProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Email.Azure/Services/DefaultAzureEmailProvider.cs @@ -11,10 +11,9 @@ public class DefaultAzureEmailProvider : AzureEmailProviderBase public DefaultAzureEmailProvider( IOptions options, - IEmailAddressValidator emailAddressValidator, ILogger logger, IStringLocalizer stringLocalizer) - : base(options.Value, emailAddressValidator, logger, stringLocalizer) + : base(options.Value, logger, stringLocalizer) { }