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:
  1. An IMemberMailService interface that defines the methods
  2. A MemberMailService that implements the IMemberMailService interface
  3. 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>();

        }
    }

 

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.