password reset added
This commit is contained in:
@@ -1,4 +1,23 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace SportsDivision.Application.DTOs;
|
namespace SportsDivision.Application.DTOs;
|
||||||
public class UserDto { public string Id { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public string FullName { get; set; } = string.Empty; public string Role { get; set; } = string.Empty; public int? SchoolId { get; set; } public string? SchoolName { get; set; } public bool IsActive { get; set; } }
|
public class UserDto { public string Id { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public string FullName { get; set; } = string.Empty; public string Role { get; set; } = string.Empty; public int? SchoolId { get; set; } public string? SchoolName { get; set; } public bool IsActive { get; set; } }
|
||||||
public class UserCreateDto { public string Email { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public string Role { get; set; } = string.Empty; public int? SchoolId { get; set; } }
|
public class UserCreateDto { public string Email { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public string Role { get; set; } = string.Empty; public int? SchoolId { get; set; } }
|
||||||
public class UserUpdateDto { public string Id { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public string Role { get; set; } = string.Empty; public int? SchoolId { get; set; } public bool IsActive { get; set; } }
|
public class UserUpdateDto { public string Id { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public string Role { get; set; } = string.Empty; public int? SchoolId { get; set; } public bool IsActive { get; set; } }
|
||||||
|
public class ResetPasswordDto
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = string.Empty;
|
||||||
|
public string Email { get; set; } = string.Empty;
|
||||||
|
public string FullName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "New password is required.")]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "New Password")]
|
||||||
|
public string NewPassword { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Please confirm the new password.")]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm Password")]
|
||||||
|
[Compare(nameof(NewPassword), ErrorMessage = "Passwords do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|||||||
@@ -202,6 +202,51 @@ public class UserManagementController : Controller
|
|||||||
return RedirectToAction(nameof(Index));
|
return RedirectToAction(nameof(Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> ResetPassword(string id)
|
||||||
|
{
|
||||||
|
var user = await _userManager.FindByIdAsync(id);
|
||||||
|
if (user == null) return NotFound();
|
||||||
|
|
||||||
|
return View(new ResetPasswordDto
|
||||||
|
{
|
||||||
|
Id = user.Id,
|
||||||
|
Email = user.Email ?? string.Empty,
|
||||||
|
FullName = user.FullName
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public async Task<IActionResult> ResetPassword(ResetPasswordDto dto)
|
||||||
|
{
|
||||||
|
var user = await _userManager.FindByIdAsync(dto.Id);
|
||||||
|
if (user == null) return NotFound();
|
||||||
|
|
||||||
|
// Keep display fields populated regardless of the posted values.
|
||||||
|
dto.Email = user.Email ?? string.Empty;
|
||||||
|
dto.FullName = user.FullName;
|
||||||
|
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return View(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
|
||||||
|
var result = await _userManager.ResetPasswordAsync(user, token, dto.NewPassword);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
{
|
||||||
|
foreach (var error in result.Errors)
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(string.Empty, error.Description);
|
||||||
|
}
|
||||||
|
return View(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
TempData["SuccessMessage"] = $"Password reset successfully for {user.Email}.";
|
||||||
|
return RedirectToAction(nameof(Index));
|
||||||
|
}
|
||||||
|
|
||||||
private async Task PopulateDropdowns()
|
private async Task PopulateDropdowns()
|
||||||
{
|
{
|
||||||
ViewBag.Roles = await _roleManager.Roles.Select(r => r.Name).ToListAsync();
|
ViewBag.Roles = await _roleManager.Roles.Select(r => r.Name).ToListAsync();
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
<th>Role</th>
|
<th>Role</th>
|
||||||
<th>School</th>
|
<th>School</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th style="width: 160px;">Actions</th>
|
<th style="width: 200px;">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -78,6 +78,9 @@
|
|||||||
<a asp-action="Edit" asp-route-id="@user.Id" class="btn btn-sm btn-outline-primary" title="Edit">
|
<a asp-action="Edit" asp-route-id="@user.Id" class="btn btn-sm btn-outline-primary" title="Edit">
|
||||||
<i class="bi bi-pencil"></i>
|
<i class="bi bi-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<a asp-action="ResetPassword" asp-route-id="@user.Id" class="btn btn-sm btn-outline-secondary" title="Reset Password">
|
||||||
|
<i class="bi bi-key"></i>
|
||||||
|
</a>
|
||||||
<form asp-action="ToggleActive" asp-route-id="@user.Id" method="post" class="d-inline">
|
<form asp-action="ToggleActive" asp-route-id="@user.Id" method="post" class="d-inline">
|
||||||
@Html.AntiForgeryToken()
|
@Html.AntiForgeryToken()
|
||||||
@if (user.IsActive)
|
@if (user.IsActive)
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
@model ResetPasswordDto
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Reset Password";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h2 class="page-header">
|
||||||
|
<i class="bi bi-key me-2"></i>Reset Password
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="text-muted">
|
||||||
|
Set a new password for <strong>@Model.FullName</strong> (@Model.Email).
|
||||||
|
The user will need to sign in with this new password.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form asp-action="ResetPassword" method="post">
|
||||||
|
@Html.AntiForgeryToken()
|
||||||
|
<input asp-for="Id" type="hidden" />
|
||||||
|
<input asp-for="Email" type="hidden" />
|
||||||
|
<input asp-for="FullName" type="hidden" />
|
||||||
|
<div asp-validation-summary="All" class="text-danger mb-3"></div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label asp-for="NewPassword" class="form-label">New Password</label>
|
||||||
|
<input asp-for="NewPassword" class="form-control" type="password" autocomplete="new-password" required />
|
||||||
|
<span asp-validation-for="NewPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label asp-for="ConfirmPassword" class="form-label">Confirm Password</label>
|
||||||
|
<input asp-for="ConfirmPassword" class="form-control" type="password" autocomplete="new-password" required />
|
||||||
|
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="bi bi-key me-1"></i>Reset Password
|
||||||
|
</button>
|
||||||
|
<a asp-action="Index" class="btn btn-outline-secondary">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user