Creates new EmailSender which should take the place throughout the codebase for sending emails in the Core. Have replaced most places where SMTP is used directly (but not the notifications part since that is more complicated right now). Added the internal event and special usage so we can raise an event to send an email if smtp is not configured.
This commit is contained in:
114
src/Umbraco.Core/EmailSender.cs
Normal file
114
src/Umbraco.Core/EmailSender.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Events;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A utility class for sending emails
|
||||
/// </summary>
|
||||
public class EmailSender : IEmailSender
|
||||
{
|
||||
//TODO: This should encapsulate a BackgroundTaskRunner with a queue to send these emails!
|
||||
|
||||
private readonly bool _enableEvents;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public EmailSender() : this(false)
|
||||
{
|
||||
}
|
||||
|
||||
internal EmailSender(bool enableEvents)
|
||||
{
|
||||
_enableEvents = enableEvents;
|
||||
}
|
||||
|
||||
private static readonly Lazy<bool> SmtpConfigured = new Lazy<bool>(() => GlobalSettings.HasSmtpServerConfigured(HttpRuntime.AppDomainAppVirtualPath));
|
||||
|
||||
/// <summary>
|
||||
/// Sends the message non-async
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public void Send(MailMessage message)
|
||||
{
|
||||
if (SmtpConfigured.Value == false && _enableEvents)
|
||||
{
|
||||
OnSendEmail(new SendEmailEventArgs(message));
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var client = new SmtpClient())
|
||||
{
|
||||
client.Send(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends the message async
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task SendAsync(MailMessage message)
|
||||
{
|
||||
if (SmtpConfigured.Value == false && _enableEvents)
|
||||
{
|
||||
OnSendEmail(new SendEmailEventArgs(message));
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var client = new SmtpClient())
|
||||
{
|
||||
if (client.DeliveryMethod == SmtpDeliveryMethod.Network)
|
||||
{
|
||||
await client.SendMailAsync(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Send(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the application should be able to send a required application email
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We assume this is possible if either an event handler is registered or an smtp server is configured
|
||||
/// </remarks>
|
||||
internal static bool CanSendRequiredEmail
|
||||
{
|
||||
get { return EventHandlerRegistered || SmtpConfigured.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns true if an event handler has been registered
|
||||
/// </summary>
|
||||
internal static bool EventHandlerRegistered
|
||||
{
|
||||
get { return SendEmail != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event that is raised when no smtp server is configured if events are enabled
|
||||
/// </summary>
|
||||
internal static event EventHandler<SendEmailEventArgs> SendEmail;
|
||||
|
||||
private static void OnSendEmail(SendEmailEventArgs e)
|
||||
{
|
||||
var handler = SendEmail;
|
||||
if (handler != null) handler(null, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/Umbraco.Core/Events/SendEmailEventArgs.cs
Normal file
27
src/Umbraco.Core/Events/SendEmailEventArgs.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Net.Mail;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
public class SendEmailEventArgs : EventArgs
|
||||
{
|
||||
public SmtpClient Smtp { get; private set; }
|
||||
public MailMessage Message { get; private set; }
|
||||
|
||||
///// <summary>
|
||||
///// A flag indicating that the mail sending was handled by an event handler
|
||||
///// </summary>
|
||||
//public bool SendingHandledExternally { get; set; }
|
||||
|
||||
public SendEmailEventArgs(MailMessage message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public SendEmailEventArgs(SmtpClient smtp, MailMessage message)
|
||||
{
|
||||
Smtp = smtp;
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
src/Umbraco.Core/IEmailSender.cs
Normal file
13
src/Umbraco.Core/IEmailSender.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Net.Mail;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple abstraction to send an email message
|
||||
/// </summary>
|
||||
public interface IEmailSender
|
||||
{
|
||||
Task SendAsync(MailMessage message);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ using System.Web.Security;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Identity.Owin;
|
||||
using Microsoft.Owin.Security.DataProtection;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
@@ -24,14 +26,25 @@ namespace Umbraco.Core.Security
|
||||
{
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the constructor specifying all dependencies instead")]
|
||||
public BackOfficeUserManager(
|
||||
IUserStore<BackOfficeIdentityUser, int> store,
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options,
|
||||
MembershipProviderBase membershipProvider)
|
||||
: this(store, options, membershipProvider, UmbracoConfig.For.UmbracoSettings().Content)
|
||||
{
|
||||
}
|
||||
|
||||
public BackOfficeUserManager(
|
||||
IUserStore<BackOfficeIdentityUser, int> store,
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options,
|
||||
MembershipProviderBase membershipProvider,
|
||||
IContentSection contentSectionConfig)
|
||||
: base(store)
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException("options");;
|
||||
InitUserManager(this, membershipProvider, options);
|
||||
if (options == null) throw new ArgumentNullException("options"); ;
|
||||
InitUserManager(this, membershipProvider, contentSectionConfig, options);
|
||||
}
|
||||
|
||||
#region Static Create methods
|
||||
@@ -46,7 +59,8 @@ namespace Umbraco.Core.Security
|
||||
{
|
||||
return Create(options, userService,
|
||||
ApplicationContext.Current.Services.EntityService,
|
||||
externalLoginService, membershipProvider);
|
||||
externalLoginService, membershipProvider,
|
||||
UmbracoConfig.For.UmbracoSettings().Content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,20 +71,34 @@ namespace Umbraco.Core.Security
|
||||
/// <param name="entityService"></param>
|
||||
/// <param name="externalLoginService"></param>
|
||||
/// <param name="membershipProvider"></param>
|
||||
/// <param name="contentSectionConfig"></param>
|
||||
/// <returns></returns>
|
||||
public static BackOfficeUserManager Create(
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options,
|
||||
IUserService userService,
|
||||
IEntityService entityService,
|
||||
IExternalLoginService externalLoginService,
|
||||
MembershipProviderBase membershipProvider)
|
||||
MembershipProviderBase membershipProvider,
|
||||
IContentSection contentSectionConfig)
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException("options");
|
||||
if (userService == null) throw new ArgumentNullException("userService");
|
||||
if (externalLoginService == null) throw new ArgumentNullException("externalLoginService");
|
||||
|
||||
var manager = new BackOfficeUserManager(new BackOfficeUserStore(userService, entityService, externalLoginService, membershipProvider));
|
||||
manager.InitUserManager(manager, membershipProvider, options);
|
||||
var manager = new BackOfficeUserManager(
|
||||
new BackOfficeUserStore(userService, entityService, externalLoginService, membershipProvider));
|
||||
manager.InitUserManager(manager, membershipProvider, contentSectionConfig, options);
|
||||
return manager;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the overload specifying all dependencies instead")]
|
||||
public static BackOfficeUserManager Create(
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options,
|
||||
BackOfficeUserStore customUserStore,
|
||||
MembershipProviderBase membershipProvider)
|
||||
{
|
||||
var manager = new BackOfficeUserManager(customUserStore, options, membershipProvider);
|
||||
return manager;
|
||||
}
|
||||
|
||||
@@ -80,33 +108,46 @@ namespace Umbraco.Core.Security
|
||||
/// <param name="options"></param>
|
||||
/// <param name="customUserStore"></param>
|
||||
/// <param name="membershipProvider"></param>
|
||||
/// <param name="contentSectionConfig"></param>
|
||||
/// <returns></returns>
|
||||
public static BackOfficeUserManager Create(
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options,
|
||||
BackOfficeUserStore customUserStore,
|
||||
MembershipProviderBase membershipProvider)
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options,
|
||||
BackOfficeUserStore customUserStore,
|
||||
MembershipProviderBase membershipProvider,
|
||||
IContentSection contentSectionConfig)
|
||||
{
|
||||
var manager = new BackOfficeUserManager(customUserStore, options, membershipProvider);
|
||||
var manager = new BackOfficeUserManager(customUserStore, options, membershipProvider, contentSectionConfig);
|
||||
return manager;
|
||||
}
|
||||
#endregion
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the overload specifying all dependencies instead")]
|
||||
protected void InitUserManager(
|
||||
BackOfficeUserManager manager,
|
||||
MembershipProviderBase membershipProvider,
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options)
|
||||
{
|
||||
InitUserManager(manager, membershipProvider, UmbracoConfig.For.UmbracoSettings().Content, options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the user manager with the correct options
|
||||
/// </summary>
|
||||
/// <param name="manager"></param>
|
||||
/// <param name="membershipProvider"></param>
|
||||
/// <param name="contentSectionConfig"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
protected void InitUserManager(
|
||||
BackOfficeUserManager manager,
|
||||
MembershipProviderBase membershipProvider,
|
||||
IContentSection contentSectionConfig,
|
||||
IdentityFactoryOptions<BackOfficeUserManager> options)
|
||||
{
|
||||
//NOTE: This method is mostly here for backwards compat
|
||||
base.InitUserManager(manager, membershipProvider, options.DataProtectionProvider);
|
||||
base.InitUserManager(manager, membershipProvider, options.DataProtectionProvider, contentSectionConfig);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -151,6 +192,16 @@ namespace Umbraco.Core.Security
|
||||
}
|
||||
#endregion
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the overload specifying all dependencies instead")]
|
||||
protected void InitUserManager(
|
||||
BackOfficeUserManager<T> manager,
|
||||
MembershipProviderBase membershipProvider,
|
||||
IDataProtectionProvider dataProtectionProvider)
|
||||
{
|
||||
InitUserManager(manager, membershipProvider, dataProtectionProvider, UmbracoConfig.For.UmbracoSettings().Content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the user manager with the correct options
|
||||
/// </summary>
|
||||
@@ -159,11 +210,13 @@ namespace Umbraco.Core.Security
|
||||
/// The <see cref="MembershipProviderBase"/> for the users called UsersMembershipProvider
|
||||
/// </param>
|
||||
/// <param name="dataProtectionProvider"></param>
|
||||
/// <param name="contentSectionConfig"></param>
|
||||
/// <returns></returns>
|
||||
protected void InitUserManager(
|
||||
BackOfficeUserManager<T> manager,
|
||||
MembershipProviderBase membershipProvider,
|
||||
IDataProtectionProvider dataProtectionProvider)
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
IContentSection contentSectionConfig)
|
||||
{
|
||||
// Configure validation logic for usernames
|
||||
manager.UserValidator = new BackOfficeUserValidator<T>(manager)
|
||||
@@ -193,7 +246,9 @@ namespace Umbraco.Core.Security
|
||||
//custom identity factory for creating the identity object for which we auth against in the back office
|
||||
manager.ClaimsIdentityFactory = new BackOfficeClaimsIdentityFactory<T>();
|
||||
|
||||
manager.EmailService = new EmailService();
|
||||
manager.EmailService = new EmailService(
|
||||
contentSectionConfig.NotificationEmailAddress,
|
||||
new EmailSender());
|
||||
|
||||
//NOTE: Not implementing these, if people need custom 2 factor auth, they'll need to implement their own UserStore to suport it
|
||||
|
||||
|
||||
@@ -1,16 +1,37 @@
|
||||
using System.Net.Mail;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Net.Mail;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IIdentityMessageService"/> implementation for Umbraco
|
||||
/// </summary>
|
||||
public class EmailService : IIdentityMessageService
|
||||
{
|
||||
private readonly string _notificationEmailAddress;
|
||||
private readonly IEmailSender _defaultEmailSender;
|
||||
|
||||
public EmailService(string notificationEmailAddress, IEmailSender defaultEmailSender)
|
||||
{
|
||||
_notificationEmailAddress = notificationEmailAddress;
|
||||
_defaultEmailSender = defaultEmailSender;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the constructor specifying all dependencies")]
|
||||
public EmailService()
|
||||
: this(UmbracoConfig.For.UmbracoSettings().Content.NotificationEmailAddress, new EmailSender())
|
||||
{
|
||||
}
|
||||
|
||||
public async Task SendAsync(IdentityMessage message)
|
||||
{
|
||||
var mailMessage = new MailMessage(
|
||||
UmbracoConfig.For.UmbracoSettings().Content.NotificationEmailAddress,
|
||||
_notificationEmailAddress,
|
||||
message.Destination,
|
||||
message.Subject,
|
||||
message.Body)
|
||||
@@ -21,16 +42,15 @@ namespace Umbraco.Core.Security
|
||||
|
||||
try
|
||||
{
|
||||
using (var client = new SmtpClient())
|
||||
//check if it's a custom message and if so use it's own defined mail sender
|
||||
var umbMsg = message as UmbracoEmailMessage;
|
||||
if (umbMsg != null)
|
||||
{
|
||||
if (client.DeliveryMethod == SmtpDeliveryMethod.Network)
|
||||
{
|
||||
await client.SendMailAsync(mailMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Send(mailMessage);
|
||||
}
|
||||
await umbMsg.MailSender.SendAsync(mailMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _defaultEmailSender.SendAsync(mailMessage);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
||||
17
src/Umbraco.Core/Security/UmbracoEmailMessage.cs
Normal file
17
src/Umbraco.Core/Security/UmbracoEmailMessage.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Microsoft.AspNet.Identity;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom implementation for IdentityMessage that allows the customization of how an email is sent
|
||||
/// </summary>
|
||||
internal class UmbracoEmailMessage : IdentityMessage
|
||||
{
|
||||
public IEmailSender MailSender { get; private set; }
|
||||
|
||||
public UmbracoEmailMessage(IEmailSender mailSender)
|
||||
{
|
||||
MailSender = mailSender;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,14 +348,17 @@
|
||||
<Compile Include="Deploy\Direction.cs" />
|
||||
<Compile Include="Deploy\IFileType.cs" />
|
||||
<Compile Include="Deploy\IFileTypeCollection.cs" />
|
||||
<Compile Include="EmailSender.cs" />
|
||||
<Compile Include="Events\EventDefinitionFilter.cs" />
|
||||
<Compile Include="Events\IDeletingMediaFilesEventArgs.cs" />
|
||||
<Compile Include="Events\ScopeEventDispatcherBase.cs" />
|
||||
<Compile Include="Events\ScopeLifespanMessagesFactory.cs" />
|
||||
<Compile Include="Events\SendEmailEventArgs.cs" />
|
||||
<Compile Include="Events\SupersedeEventAttribute.cs" />
|
||||
<Compile Include="Exceptions\ConnectionException.cs" />
|
||||
<Compile Include="HashCodeHelper.cs" />
|
||||
<Compile Include="HashGenerator.cs" />
|
||||
<Compile Include="IEmailSender.cs" />
|
||||
<Compile Include="IHttpContextAccessor.cs" />
|
||||
<Compile Include="Models\EntityBase\EntityPath.cs" />
|
||||
<Compile Include="Models\EntityBase\IDeletableEntity.cs" />
|
||||
@@ -688,6 +691,7 @@
|
||||
<Compile Include="Security\EmailService.cs" />
|
||||
<Compile Include="Security\MembershipProviderPasswordValidator.cs" />
|
||||
<Compile Include="Security\OwinExtensions.cs" />
|
||||
<Compile Include="Security\UmbracoEmailMessage.cs" />
|
||||
<Compile Include="Security\UserAwareMembershipProviderPasswordHasher.cs" />
|
||||
<Compile Include="SemVersionExtensions.cs" />
|
||||
<Compile Include="Serialization\NoTypeConverterJsonConverter.cs" />
|
||||
|
||||
@@ -50,24 +50,31 @@
|
||||
"selected": true
|
||||
};
|
||||
|
||||
//don't set this if no email is configured
|
||||
if (Umbraco.Sys.ServerVariables.umbracoSettings.emailServerConfigured) {
|
||||
//don't show the invite button if no email is configured
|
||||
if (Umbraco.Sys.ServerVariables.umbracoSettings.showUserInvite) {
|
||||
vm.defaultButton = {
|
||||
labelKey: "user_inviteUser",
|
||||
handler: function () {
|
||||
handler: function() {
|
||||
vm.setUsersViewState('inviteUser');
|
||||
}
|
||||
};
|
||||
vm.subButtons = [
|
||||
{
|
||||
labelKey: "user_createUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('createUser');
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
vm.subButtons = [
|
||||
{
|
||||
else {
|
||||
vm.defaultButton = {
|
||||
labelKey: "user_createUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('createUser');
|
||||
}
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
vm.toggleFilter = toggleFilter;
|
||||
vm.setUsersViewState = setUsersViewState;
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace Umbraco.Web.Editors
|
||||
{"cssPath", IOHelper.ResolveUrl(SystemDirectories.Css).TrimEnd('/')},
|
||||
{"allowPasswordReset", UmbracoConfig.For.UmbracoSettings().Security.AllowPasswordReset},
|
||||
{"loginBackgroundImage", UmbracoConfig.For.UmbracoSettings().Content.LoginBackgroundImage},
|
||||
{"emailServerConfigured", GlobalSettings.HasSmtpServerConfigured(_httpContext.Request.ApplicationPath)},
|
||||
{"showUserInvite", EmailSender.CanSendRequiredEmail},
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -345,9 +345,8 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
|
||||
}
|
||||
|
||||
var hasSmtp = GlobalSettings.HasSmtpServerConfigured(RequestContext.VirtualPathRoot);
|
||||
if (hasSmtp == false)
|
||||
|
||||
if (EmailSender.CanSendRequiredEmail == false)
|
||||
{
|
||||
throw new HttpResponseException(
|
||||
Request.CreateNotificationValidationErrorResponse("No Email server is configured"));
|
||||
@@ -442,12 +441,15 @@ namespace Umbraco.Web.Editors
|
||||
UserExtensions.GetUserCulture(to.Language, Services.TextService),
|
||||
new[] { userDisplay.Name, from, message, inviteUri.ToString() });
|
||||
|
||||
await UserManager.EmailService.SendAsync(new IdentityMessage
|
||||
{
|
||||
Body = emailBody,
|
||||
Destination = userDisplay.Email,
|
||||
Subject = emailSubject
|
||||
});
|
||||
await UserManager.EmailService.SendAsync(
|
||||
//send the special UmbracoEmailMessage which configures it's own sender
|
||||
//to allow for events to handle sending the message if no smtp is configured
|
||||
new UmbracoEmailMessage(new EmailSender(true))
|
||||
{
|
||||
Body = emailBody,
|
||||
Destination = userDisplay.Email,
|
||||
Subject = emailSubject
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods
|
||||
|
||||
var subject = _textService.Localize("healthcheck/scheduledHealthCheckEmailSubject");
|
||||
|
||||
using (var client = new SmtpClient())
|
||||
var mailSender = new EmailSender();
|
||||
using (var mailMessage = new MailMessage(UmbracoConfig.For.UmbracoSettings().Content.NotificationEmailAddress,
|
||||
RecipientEmail,
|
||||
string.IsNullOrEmpty(subject) ? "Umbraco Health Check Status" : subject,
|
||||
@@ -77,14 +77,7 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods
|
||||
&& message.Contains("<") && message.Contains("</")
|
||||
})
|
||||
{
|
||||
if (client.DeliveryMethod == SmtpDeliveryMethod.Network)
|
||||
{
|
||||
await client.SendMailAsync(mailMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Send(mailMessage);
|
||||
}
|
||||
await mailSender.SendAsync(mailMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,8 @@ namespace Umbraco.Web.Security.Identity
|
||||
appContext.Services.UserService,
|
||||
appContext.Services.EntityService,
|
||||
appContext.Services.ExternalLoginService,
|
||||
userMembershipProvider));
|
||||
userMembershipProvider,
|
||||
UmbracoConfig.For.UmbracoSettings().Content));
|
||||
|
||||
app.SetBackOfficeUserManagerType<BackOfficeUserManager, BackOfficeIdentityUser>();
|
||||
|
||||
@@ -119,7 +120,8 @@ namespace Umbraco.Web.Security.Identity
|
||||
(options, owinContext) => BackOfficeUserManager.Create(
|
||||
options,
|
||||
customUserStore,
|
||||
userMembershipProvider));
|
||||
userMembershipProvider,
|
||||
UmbracoConfig.For.UmbracoSettings().Content));
|
||||
|
||||
app.SetBackOfficeUserManagerType<BackOfficeUserManager, BackOfficeIdentityUser>();
|
||||
|
||||
|
||||
@@ -1613,7 +1613,8 @@ namespace umbraco
|
||||
public static void SendMail(string fromMail, string toMail, string subject, string body, bool isHtml)
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
var mailSender = new EmailSender();
|
||||
using (var mail = new MailMessage())
|
||||
{
|
||||
mail.From = new MailAddress(fromMail.Trim());
|
||||
@@ -1622,8 +1623,7 @@ namespace umbraco
|
||||
mail.Subject = subject;
|
||||
mail.IsBodyHtml = isHtml;
|
||||
mail.Body = body;
|
||||
using (var smtpClient = new SmtpClient())
|
||||
smtpClient.Send(mail);
|
||||
mailSender.Send(mail);
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace umbraco.cms.businesslogic.translation
|
||||
{
|
||||
try
|
||||
{
|
||||
var mailSender = new EmailSender();
|
||||
using (var mail = new MailMessage())
|
||||
{
|
||||
mail.From = new MailAddress(user.Email.Trim());
|
||||
@@ -66,8 +67,7 @@ namespace umbraco.cms.businesslogic.translation
|
||||
mail.Subject = ui.Text("translation", "mailSubject", subjectVars, translator); ;
|
||||
mail.IsBodyHtml = false;
|
||||
mail.Body = ui.Text("translation", "mailBody", bodyVars, translator); ;
|
||||
using (var smtpClient = new SmtpClient())
|
||||
smtpClient.Send(mail);
|
||||
mailSender.Send(mail);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user