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>();
}
}
Umbraco
IMailService
Umbraco 9
tinyMCE
appsetting
form
RCL
RTE
Error Handler
BlockGrid
Razor Class library
package
Forgot password
blocklist
migration
Membership
Umbraco 10
Registration
manifest
Error
json
IMemberMailService
backoffice
style_format
Umbraco 14
Email Validate
IEmailSender
nuget
RichText
style format
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.