public async Task <IActionResult> SendRegistrationEmail([FromBody] RegistrationEmailDTO emailModel) { try { if (!ModelState.IsValid) { _logger.LogError("Registration confirmation email requested with missing details.", emailModel); return(BadRequest("Invalid request.")); } var newUser = emailModel.UserDetails.Contains("@") ? await _unitOfWork.UserManager.FindByEmailAsync(emailModel.UserDetails).ConfigureAwait(false) : await _unitOfWork.UserManager.FindByNameAsync(emailModel.UserDetails).ConfigureAwait(false); if (newUser == null) { _logger.LogWarning("Registration confirmation email requested with invalid user ID."); return(StatusCode(500, "Failed to send registration confirmation email.")); } if (newUser.EmailConfirmed) { _logger.LogError("Request to verify email made by verified user."); return(StatusCode(500, "Failed to send registration confirmation email.")); } var token = await _unitOfWork.UserManager.GenerateEmailConfirmationTokenAsync(newUser).ConfigureAwait(false); token = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token)); var parameters = new string[] { "userID", newUser.Id, "token", token }; var emailData = new UsernameLinkTemplate() { Username = newUser.UserName, HrefLink = HtmlEncoder.Default.Encode(GetBaseURL("confirm-email", parameters)) }; var emailResponse = await _emailSender .SendEmailAsync(newUser.Email, _config["SendGrid:Templates:RegistrationConfirmation"], EmailFrom.Account, emailData) .ConfigureAwait(false); if (emailResponse.StatusCode != System.Net.HttpStatusCode.Accepted) { _logger.LogError($"SendGrid failed to send registration notification to {newUser.UserName}."); return(StatusCode(500, "Failed to send registration confirmation email.")); } else { _logger.LogInformation($"Registration confirmation email dispatched to {newUser.UserName}."); return(NoContent()); } } catch (Exception ex) { _logger.LogError(ex, "Exception thrown attempting to send registration confirmation email"); return(StatusCode(500, "Failed to send registration confirmation email.")); } }
public async Task <IActionResult> RequestEmailChange([FromBody] EmailDTO newEmail) { try { if (!ModelState.IsValid) { _logger.LogTrace("User email change failed due to missing parameters."); return(BadRequest("Change email failed - missing parameters.")); } var user = await _unitOfWork.UserManager.FindByNameAsync(User.Identity.Name).ConfigureAwait(false); if (user == null) { _logger.LogInformation("Email change request made by invalid user", newEmail); return(StatusCode(500, "Email change request unsuccessful.")); } if (!ValidEmailDomain(newEmail.NewEmail)) { _logger.LogInformation($"{user.UserName} attempted to change their email to one from an excluded domain ({newEmail.NewEmail})."); return(BadRequest("Email addresses from this domain are not accepted.")); } var token = await _unitOfWork.UserManager.GenerateChangeEmailTokenAsync(user, newEmail.NewEmail).ConfigureAwait(false); token = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token)); //send notification to new email var parameters = new string[] { "token", token, "userId", user.Id, "newEmail", newEmail.NewEmail }; var emailData = new UsernameLinkTemplate() { Username = user.UserName, HrefLink = HtmlEncoder.Default.Encode(GetBaseURL("email-change", parameters)) }; var emailResponse = await _emailSender .SendEmailAsync(newEmail.NewEmail, _config["SendGrid:Templates:EmailChangeConfirmation"], EmailFrom.Account, emailData) .ConfigureAwait(false); if (emailResponse.StatusCode != System.Net.HttpStatusCode.Accepted) { _logger.LogError($"SendGrid failed to send email change confirmation notification to {user.UserName}'s new email."); return(StatusCode(500, "Email change request unsuccessful.")); } else { _logger.LogInformation($"Email change confirmation request dispatched to {user.UserName}'s new email."); } //send notification to old email var oldEmailData = new UsernameTemplate() { Username = user.UserName }; emailResponse = await _emailSender .SendEmailAsync(user.Email, _config["SendGrid:Templates:EmailChangeRequestNotification"], EmailFrom.Account, oldEmailData) .ConfigureAwait(false); if (emailResponse.StatusCode != System.Net.HttpStatusCode.Accepted) { _logger.LogError($"SendGrid failed to send email change confirmation notification to {user.UserName}'s old email."); } else { _logger.LogInformation($"Email change confirmation request dispatched to {user.UserName}'s old email."); } return(NoContent()); } catch (Exception ex) { _logger.LogError(ex, "Exception thrown requesting email change."); return(StatusCode(500, "Email change request unsuccessful.")); } }
public async Task <IActionResult> RequestPasswordReset([FromBody] StringDTO stringModel) { try { if (!ModelState.IsValid) { _logger.LogWarning("User attempted to reset password with invalid model."); return(BadRequest("Request failed - invalid request")); } var recoveryString = stringModel.Value; if (recoveryString == null) { _logger.LogInformation("User attempted to reset password with missing parameter."); return(BadRequest("Request failed - missing parameters.")); } var email = recoveryString.Contains("@"); var user = email ? await _unitOfWork.UserManager.FindByEmailAsync(recoveryString).ConfigureAwait(false) : await _unitOfWork.UserManager.FindByNameAsync(recoveryString).ConfigureAwait(false); if (user == null) { _logger.LogWarning("Password reset attempted for invalid user."); if (email) { return(NoContent()); } else { return(StatusCode(500, "Password reset request unsuccessful.")); } } var token = await _unitOfWork.UserManager.GeneratePasswordResetTokenAsync(user).ConfigureAwait(false); token = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token)); var parameters = new string[] { "userId", user.Id, "token", token }; var emailData = new UsernameLinkTemplate() { Username = user.UserName, HrefLink = HtmlEncoder.Default.Encode(GetBaseURL("password-reset", parameters)) }; var emailResponse = await _emailSender .SendEmailAsync(user.Email, _config["SendGrid:Templates:PasswordRecoveryRequest"], EmailFrom.Account, emailData) .ConfigureAwait(false); if (emailResponse.StatusCode != System.Net.HttpStatusCode.Accepted) { _logger.LogError($"SendGrid failed to send password recovery notification to user {user.UserName}."); return(StatusCode(500, "Password reset request unsuccessful.")); } else { _logger.LogInformation($"Password reset confirmation request was successfully dispatched to {user.UserName}."); return(NoContent()); } } catch (Exception ex) { _logger.LogError(ex, "Exception thrown during password reset request."); return(StatusCode(500, "Password reset request unsuccessful.")); } }