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>();

        }
    }

 

TypeScript MediaWiz BlockGrid nuget Membership RichText LIT package Vite Umbraco Email Validate Extension Umbraco 9 Umbraco 17 backoffice MediaWiz Forum Umbraco 10 Media Wizard IMailService appsetting

This guide walks through building a real Tiptap extension for the Umbraco backoffice — a DateTime inserter that lets editors insert the current date, time, or both into a Rich Text Editor (RTE) field from a toolbar dropdown menu

building a custom collection view for Umbraco 17 that displays documents as beautiful cards with images, using the new extension system and Lit Element web components.

In this post, I'll show you how to build a flexible, on-the-fly watermarking system using SixLabors.ImageSharp.Web that doesn't require modifying your original images.