public async Task SendEmail(string userId, string?clientIp)
        {
            if (EmailSettings.Type == EmailSettings.EmailTypeDisabled)
            {
                // Email shouldn't be disabled, but if it is, we want to
                // fail this job so it retries
                throw new Exception("Email is disabled, failing job to it will retry");
            }
            var user = await Db.Get <User>(userId);

            if (user == null)
            {
                throw new EmailJobException("No User");
            }
            if (user.Email.PlainText == null)
            {
                logger.LogDebug($"Sending email to user {user.Id} who doesn't have an email address");
                return;
            }
            var oneTimeToken = new OneTimeToken(user.Id);

            Uri verifyUri = this.MakeEmailLink("confirm-email", oneTimeToken.UserId, oneTimeToken.GetUnhashedToken());

            await Db.Save(oneTimeToken);

            FillAttributes(user, verifyUri.ToString(), clientIp);
            await SendOneEmail(EmailType, Attributes);
        }
        public async Task SendEmail(string userId, string?clientIp)
        {
            if (EmailSettings.Type == EmailSettings.EmailTypeDisabled)
            {
                // Email shouldn't be disabled, but if it is, we want to
                // fail this job so it retries
                throw new Exception("Email is disabled, failing job to it will retry");
            }

            var user = await Db.Get <User>(userId);

            if (user == null)
            {
                throw new EmailJobException("No User");
            }
            if (user.Email.PlainText == null)
            {
                logger.LogDebug($"Sending email to user {user.Id} who doesn't have an email address");
                return;
            }

            var oneTimeToken = new OneTimeToken(user.Id);
            var uri          = GetFrontEndUri("/password/reset", new Dictionary <string, string>()
            {
                { "token", oneTimeToken.GetUnhashedToken() }
            });
            await Db.Save(oneTimeToken);

            FillAttributes(user, uri.ToString(), clientIp);
            await SendOneEmail(EmailType, Attributes);
        }