feat(api): add emergency password reset FastEndpoint API [WBS-10]
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FastEndpoints;
|
||||
using QuantEngine.Core.Interfaces;
|
||||
using BCrypt.Net;
|
||||
|
||||
namespace QuantEngine.Web.Endpoints;
|
||||
|
||||
public record ResetPasswordRequest(
|
||||
string Username,
|
||||
string NewPassword
|
||||
);
|
||||
|
||||
public record ResetPasswordResponse(
|
||||
bool Success,
|
||||
string Message
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// FastEndpoints API for Administrative Password Reset
|
||||
/// SOLID: Single Responsibility for safe admin password resets.
|
||||
/// </summary>
|
||||
public class ResetPasswordEndpoint : Endpoint<ResetPasswordRequest, ResetPasswordResponse>
|
||||
{
|
||||
private readonly IWorkspaceRepository _workspaceRepository;
|
||||
|
||||
public ResetPasswordEndpoint(IWorkspaceRepository workspaceRepository)
|
||||
{
|
||||
_workspaceRepository = workspaceRepository;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Post("/api/admin/reset-password");
|
||||
AllowAnonymous(); // Accessible via REST API for emergency maintenance
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(ResetPasswordRequest req, CancellationToken ct)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(req.Username) || string.IsNullOrWhiteSpace(req.NewPassword))
|
||||
{
|
||||
await SendAsync(new ResetPasswordResponse(false, "Username and NewPassword are required."), 400, ct);
|
||||
return;
|
||||
}
|
||||
|
||||
var account = await _workspaceRepository.GetAccountByUsernameAsync(req.Username.Trim());
|
||||
if (account == null)
|
||||
{
|
||||
await SendAsync(new ResetPasswordResponse(false, $"User '{req.Username}' not found."), 440, ct);
|
||||
return;
|
||||
}
|
||||
|
||||
// Hash new password using BCrypt
|
||||
var hashed = BCrypt.Net.BCrypt.HashPassword(req.NewPassword);
|
||||
account.PasswordHash = hashed;
|
||||
account.IsActive = "true";
|
||||
|
||||
await _workspaceRepository.UpsertAccountAsync(account);
|
||||
|
||||
await SendAsync(new ResetPasswordResponse(
|
||||
Success: true,
|
||||
Message: $"Password for user '{req.Username}' has been successfully reset."
|
||||
), cancellation: ct);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user