Beispiel #1
0
        public async Task GenerateTokenAndEmail(string username, string recoveryUrl)
        {
            string trimmedUsername = username.Trim();
            var    user            = await _userRepository.GetByUsernameAsync(trimmedUsername);

            if (user == null)
            {
                _logger.LogInformation($"Username '{trimmedUsername}' doesn't exist so can't create a recovery token.");
                throw new GraException($"User '{trimmedUsername}' not found.");
            }

            if (string.IsNullOrEmpty(user.Email))
            {
                _logger.LogInformation($"User {user.Id} doesn't have an email address configured so cannot send a recovery token.");
                throw new GraException($"User '{trimmedUsername}' doesn't have an email address configured.");
            }

            // clear any existing tokens
            var existingRequests = await _recoveryTokenRepository.GetByUserIdAsync(user.Id);

            _logger.LogInformation($"Found {existingRequests.Count()} existing recovery tokens for user {user.Id}.");
            foreach (var request in existingRequests)
            {
                await _recoveryTokenRepository.RemoveSaveAsync(-1, request.Id);
            }

            string tokenString = _tokenGenerator.Generate().ToUpper().Trim();

            // insert new token
            var token = await _recoveryTokenRepository.AddSaveAsync(-1, new RecoveryToken
            {
                Token  = tokenString.ToLower(),
                UserId = user.Id
            });

            _logger.LogInformation($"Inserted token for user {user.Id}.");

            var site = await _siteRepository.GetByIdAsync(GetCurrentSiteId());

            string subject  = $"{site.Name} password recovery";
            string mailBody = $"{site.Name} has received a request for a password recovery."
                              + "\n\rAccess the password recovery page in order to set a new password:"******"\n\r  {recoveryUrl}?username={trimmedUsername}&token={tokenString}"

                              + $"\n\r\n\rIf that link does not work work, please visit:"
                              + $"\n\r  {recoveryUrl}"
                              + $"\n\rand enter the following:"
                              + $"\n\r  Username: {trimmedUsername}"
                              + $"\n\r  Token: {tokenString}";

            string htmlBody = $"<p>{site.Name} has received a request for a password recovery.</p>"
                              + "<p>Access the "
                              + $"<a href=\"{recoveryUrl}?username={trimmedUsername}&token={tokenString}\">"
                              + "password recovery page</a> in order to set a new password.</p>"
                              + "<p>If that link does not work, please visit: "
                              + $"<a href=\"{recoveryUrl}\">{recoveryUrl}</a> "
                              + "and enter the following:<ul>"
                              + $"<li>Username:{trimmedUsername}</li>"
                              + $"<li>Token: {tokenString}</li></ul></p>";

            await _emailService.Send(user.Id, subject, mailBody, htmlBody);
        }
        public async Task <Models.ServiceResult> GenerateTokenAndEmail(string username, string recoveryUrl)
        {
            string trimmedUsername = username.Trim();
            var    user            = await _userRepository.GetByUsernameAsync(trimmedUsername);

            if (user == null)
            {
                _logger.LogInformation("Username {Username} doesn't exist so can't create a recovery token.",
                                       trimmedUsername);
                return(new Models.ServiceResult
                {
                    Status = Models.ServiceResultStatus.Error,
                    Message = Annotations.Validate.Username,
                    Arguments = new[] { trimmedUsername }
                });
            }

            if (string.IsNullOrEmpty(user.Email))
            {
                _logger.LogInformation("User {Username} ({UserId}) doesn't have an email address configured so cannot send a recovery token.",
                                       user?.Username,
                                       user?.Id);
                return(new Models.ServiceResult
                {
                    Status = Models.ServiceResultStatus.Error,
                    Message = Annotations.Validate.EmailConfigured,
                    Arguments = new[] { trimmedUsername }
                });
            }

            // clear any existing tokens
            var existingRequests = await _recoveryTokenRepository.GetByUserIdAsync(user.Id);

            foreach (var request in existingRequests)
            {
                await _recoveryTokenRepository.RemoveSaveAsync(-1, request.Id);
            }

            string tokenString = _tokenGenerator.Generate().ToUpperInvariant().Trim();

            // insert new token
            await _recoveryTokenRepository.AddSaveAsync(-1, new RecoveryToken
            {
                Token  = tokenString.ToLowerInvariant(),
                UserId = user.Id
            });

            _logger.LogInformation("Cleared {Existing} existing recovery tokens and inserted a new one for {Username} ({UserId})",
                                   existingRequests.Count(),
                                   user?.Username,
                                   user.Id);

            var site = await _siteRepository.GetByIdAsync(GetCurrentSiteId());

            string subject  = $"{site.Name} password recovery";
            string mailBody = $"{site.Name} has received a request for a password recovery."
                              + "\n\rAccess the password recovery page in order to set a new password:"******"\n\r  {recoveryUrl}?username={trimmedUsername}&token={tokenString}"

                              + $"\n\r\n\rIf that link does not work work, please visit:"
                              + $"\n\r  {recoveryUrl}"
                              + $"\n\rand enter the following:"
                              + $"\n\r  Username: {trimmedUsername}"
                              + $"\n\r  Token: {tokenString}";

            string htmlBody = $"<p>{site.Name} has received a request for a password recovery.</p>"
                              + "<p>Access the "
                              + $"<a href=\"{recoveryUrl}?username={trimmedUsername}&token={tokenString}\">"
                              + "password recovery page</a> in order to set a new password.</p>"
                              + "<p>If that link does not work, please visit: "
                              + $"<a href=\"{recoveryUrl}\">{recoveryUrl}</a> "
                              + "and enter the following:<ul>"
                              + $"<li>Username:{trimmedUsername}</li>"
                              + $"<li>Token: {tokenString}</li></ul></p>";

            await _emailService.Send(user.Id, subject, mailBody, htmlBody);

            return(new Models.ServiceResult(Models.ServiceResultStatus.Success));
        }
Beispiel #3
0
        public async Task <Models.ServiceResult> GenerateTokenAndEmail(string username,
                                                                       string recoveryUrl)
        {
            string trimmedUsername = username.Trim();
            var    user            = await _userRepository.GetByUsernameAsync(trimmedUsername);

            if (user == null)
            {
                _logger.LogInformation("Username {Username} doesn't exist so can't create a recovery token.",
                                       trimmedUsername);
                return(new Models.ServiceResult
                {
                    Status = Models.ServiceResultStatus.Error,
                    Message = Annotations.Validate.Username,
                    Arguments = new[] { trimmedUsername }
                });
            }

            if (string.IsNullOrEmpty(user.Email))
            {
                _logger.LogInformation("User {Username} ({UserId}) doesn't have an email address configured so cannot send a recovery token.",
                                       user?.Username,
                                       user?.Id);
                return(new Models.ServiceResult
                {
                    Status = Models.ServiceResultStatus.Error,
                    Message = Annotations.Validate.EmailConfigured,
                    Arguments = new[] { trimmedUsername }
                });
            }

            // clear any existing tokens
            var existingRequests = await _recoveryTokenRepository.GetByUserIdAsync(user.Id);

            foreach (var request in existingRequests)
            {
                await _recoveryTokenRepository.RemoveSaveAsync(-1, request.Id);
            }

            string tokenString = _tokenGenerator.Generate().ToUpperInvariant().Trim();

            // insert new token
            await _recoveryTokenRepository.AddSaveAsync(-1, new RecoveryToken
            {
                Token  = tokenString.ToLowerInvariant(),
                UserId = user.Id
            });

            _logger.LogInformation("Cleared {Existing} existing recovery tokens and inserted a new one for {Username} ({UserId})",
                                   existingRequests.Count(),
                                   user?.Username,
                                   user.Id);

            var site = await _siteLookupService.GetByIdAsync(GetCurrentSiteId());

            var directEmailDetails = new DirectEmailDetails(site.Name)
            {
                DirectEmailSystemId = "PasswordRecovery",
                LanguageId          = await _languageService
                                      .GetLanguageIdAsync(CultureInfo.CurrentUICulture.Name),
                SendingUserId = await _userRepository.GetSystemUserId(),
                ToUserId      = user.Id
            };

            directEmailDetails.Tags.Add("RecoveryLink",
                                        $"{recoveryUrl}?username={trimmedUsername}&token={tokenString}");
            directEmailDetails.Tags.Add("RecoveryBaseLink", recoveryUrl);
            directEmailDetails.Tags.Add("Username", trimmedUsername);
            directEmailDetails.Tags.Add("Token", tokenString);

            var siteLink = await _siteLookupService.GetSiteLinkAsync(site.Id);

            directEmailDetails.Tags.Add("Sitelink", siteLink.AbsoluteUri);

            var result = new Models.ServiceResult();

            try
            {
                var history = await _emailService.SendDirectAsync(directEmailDetails);

                result.Status = history?.Successful == true
                    ? Models.ServiceResultStatus.Success
                    : Models.ServiceResultStatus.Error;
            }
            catch (GraException ex)
            {
                if (ex?.InnerException is MimeKit.ParseException)
                {
                    result.Status    = Models.ServiceResultStatus.Error;
                    result.Message   = Annotations.Validate.AssociatedEmailAddressInvalid;
                    result.Arguments = new[] { username };
                }
            }

            return(result);
        }