SendPasswordResetEmail(string id, string? returnUrl = null)
{
var user = await _userManager.FindByIdAsync(id);
if (user == null)
{
TempData["Error"] = "User not found.";
return RedirectToAction(nameof(Index));
}
if (user.Email?.Equals(RootUserEmail, StringComparison.OrdinalIgnoreCase) == true)
{
TempData["Error"] = "The root account cannot be modified.";
return RedirectToAction(nameof(Index));
}
try
{
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var encodedToken = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token));
var resetUrl = $"{Request.Scheme}://{Request.Host}/Identity/Account/ResetPassword" +
$"?code={Uri.EscapeDataString(encodedToken)}";
var firstName = user.FirstName ?? user.Email ?? "there";
var subject = "Password Reset — Powder Coating Logix";
var plain =
$"Hi {firstName},\r\n\r\n" +
$"A password reset was requested for your Powder Coating Logix account.\r\n\r\n" +
$"Click the link below to set a new password:\r\n{resetUrl}\r\n\r\n" +
$"This link expires in 24 hours. If you did not request this, you can safely ignore it.\r\n\r\n" +
$"— The Powder Coating Logix Team";
var html =
$"Hi {System.Net.WebUtility.HtmlEncode(firstName)},
" +
$"A password reset was requested for your Powder Coating Logix account.
" +
$"Set New Password
" +
$"Or copy this link: {System.Net.WebUtility.HtmlEncode(resetUrl)}
" +
$"This link expires in 24 hours.
";
var (success, error) = await _emailService.SendEmailAsync(
user.Email!, user.FullName, subject, plain, html);
if (success)
{
_logger.LogInformation("Password reset email sent to {Email} by {Admin}",
user.Email, User.Identity?.Name);
TempData["Success"] = $"Password reset email sent to {user.Email}.";
}
else
{
_logger.LogWarning("Failed to send password reset email to {Email}: {Error}", user.Email, error);
TempData["Error"] = "Failed to send email. Please try again or reset the password manually.";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error sending password reset email for user {UserId}", id);
TempData["Error"] = "An error occurred while sending the reset email.";
}
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
return Redirect(returnUrl);
return RedirectToAction(nameof(Index));
}
}