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