using MediatR; using mws.backend.dotnet.application.Audit; using mws.backend.dotnet.application.Auth; using mws.backend.dotnet.application.Common; using mws.backend.dotnet.application.Permissions; namespace mws.backend.dotnet.application.Users; public record ResetPasswordCommand(Guid ActorUserId, Guid Id, ResetPasswordRequest Request) : IRequest, IAuditableRequest { public string Action => "User.ResetPassword"; public string EntityType => "User"; public Guid? EntityId => Id; } public class ResetPasswordHandler(IUnitOfWork uow, IPasswordHasher passwordHasher, IPermissionService permissions, IAuditContext auditContext) : IRequestHandler { private const string Screen = "users"; public async Task Handle(ResetPasswordCommand command, CancellationToken ct) { await permissions.EnsureAsync(command.ActorUserId, Screen, PermissionAction.Edit, ct); if (string.IsNullOrWhiteSpace(command.Request.NewPassword)) { throw new BadRequestException("New password is required"); } var user = await uow.Users.GetByIdAsync(command.Id, ct) ?? throw new NotFoundException("User not found"); user.PasswordHash = passwordHasher.Hash(command.Request.NewPassword); user.UpdatedAt = DateTime.UtcNow; await uow.SaveChangesAsync(ct); auditContext.EntityName = user.Username; } }