In part 1 of Implementing a Forgot password, we discussed how to create views and controllers for the process.
The following example will show how to create a custom mailsender service used in part 1.
To create the mail sender we need three things:
- An
IMemberMailService
interface that defines the methods - A
MemberMailService
that implements theIMemberMailService
interface - A composer that adds the service to the runtime.
IMemberMailService
public interface IMemberMailService
{
Task SendResetPassword(string email, string token);
}
MemberMailService
public class MemberMailService : IMemberMailService
{
private readonly string _fromEmail;
private readonly HostingSettings _hostingSettings;
private readonly ILogger _logger;
private readonly IEmailSender _emailSender;
private readonly IHostingEnvrionment _hostingEnvironment;
private readonly ILocalizationService _localisation;
private readonly IMemberService _memberService;
public MemberMailService(IHostingEnvrionment hostingEnvironment, IOptions<GlobalSettings> globalSettings,IEmailSender emailSender,
ILocalizationService localisation,ILogger<MailMessage> logger,IMemberService memberService,IOptions<ContentSettings> contentSettings,
IOptions<HostingSettings> hostingSettings)
{
_logger = logger;
_emailSender = emailSender;
_hostingEnvironment = hostingEnvironment;
_localisation = localisation;
_memberService = memberService;
_hostingSettings = hostingSettings.Value;
_fromEmail = globalSettings.Value.Smtp?.From != null ? globalSettings.Value.Smtp.From : contentSettings.Value.Notifications.Email;
}
public async Task SendResetPassword(string email, string token)
{
try
{
var member = _memberService.GetByEmail(email);
if (member != null)
{
string baseURL = hostingEnvironment.ApplicationMainUrl.AbsoluteUri;
var resetUrl = baseURL + "/forgotpassword/?id=" + member.Id + "&token=" + token;
var messageBody = _localisation.GetOrCreateDictionaryValue("Forums.ResetBody",$@"<p>Hi {member.Name},</p>
<p>Someone requested a password reset for your account on {_hostingSettings.SiteName}.</p>
<p>If this wasn't you then you can ignore this email, otherwise, please click the following password reset link to continue:</p>
<p>Please go to <a href='{resetUrl}'>here</a> to reset your password</p>
<p>&nnbsp;</p>
<p>Kind regards,<br/>The {_hostingSettings.SiteName} Team</p>");
EmailMessage message = new EmailMessage(_fromEmail,email,_localisation.GetOrCreateDictionaryValue("Forums.ResetSubject", $@"Password reset requested for {_hostingSettings.SiteName}"),messageBody,true);
try
{
// smtp (assuming you've set all this up)
await _emailSender.SendAsync(message, emailType: "Contact");
}
catch (Exception ex)
{
_logger.LogInformation("Failed to send the email - probably because email isn't configured for this site\n {0}", ex.ToString());
}
}
}
catch (Exception ex)
{
_logger.LogError(ex,"Error {0}",ex.Message);
}
}
}
MailServiceComposer
public class MailServiceComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.ManifestFilters().Append<EmailValidationManifestFilter>();
builder.Services.AddScoped<IMemberMailService, MemberMailService>();
}
}
IMemberMailService
BlockGrid
Razor Class library
appsetting
nuget
Umbraco 9
style format
style_format
Forgot password
tinyMCE
json
package
manifest
IMailService
RichText
Umbraco
Umbraco 14
Error Handler
RTE
Registration
Error
RCL
migration
form
IEmailSender
Email Validate
Membership
blocklist
Umbraco 10
backoffice
In this article I will explain how to configure the TinyMCE rich text editor in Umbraco v14
This is my dive into the new Umbraco 14 backoffice to create a Member EntityAction in order to send an email to the selected member.
Previously known as Tree Actions, Entity Actions is a feature that provides a generic place for secondary or additional functionality for an entity type. An entity type can be a media, document and so on.
In this blog post I explain how to implement an email validation flow for Member registration.