using FastEndpoints; using KArtSell.Host.Features.Audit; namespace KArtSell.Host.Endpoints.Audit; /// /// GET /api/admin/audit-logs - Retrieve authentication audit logs /// Requires Admin or SecurityOfficer role /// public sealed class GetAuditLogsEndpoint : Endpoint { private readonly IAuthAuditSql _auditSql; public GetAuditLogsEndpoint(IAuthAuditSql auditSql) { _auditSql = auditSql; } public override void Configure() { Get("/audit-logs"); Roles("Admin", "SecurityOfficer"); Description(x => x .WithName("Get Audit Logs") .WithDescription("Retrieve authentication audit logs for compliance reporting") .Accepts("application/json") .Produces(200, "application/json")); } public override async Task HandleAsync(GetAuditLogsRequest req, CancellationToken ct) { var logs = await _auditSql.GetAuditLogsAsync( startDate: req.StartDate, endDate: req.EndDate, eventType: req.EventType, username: req.Username, limit: req.PageSize > 1000 ? 1000 : req.PageSize, // Cap at 1000 offset: (req.Page - 1) * req.PageSize, ct: ct ); var total = await _auditSql.GetAuditLogsCountAsync( startDate: req.StartDate, endDate: req.EndDate, eventType: req.EventType, username: req.Username, ct: ct ); var items = logs.Select(entry => new AuditLogItem { AuditId = entry.AuditId, EventType = entry.EventType, IdentityId = entry.IdentityId, Username = entry.Username, Role = entry.Role, IpAddress = entry.IpAddress, Endpoint = entry.Endpoint, HttpMethod = entry.HttpMethod, Status = entry.Status, ErrorCode = entry.ErrorCode, ErrorMessage = entry.ErrorMessage, OccurredAt = entry.OccurredAt }).ToList(); await Send.OkAsync(new GetAuditLogsResponse { Items = items, Total = total, Page = req.Page, PageSize = req.PageSize }, ct); } } public class GetAuditLogsRequest { public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public string? EventType { get; set; } // LOGIN, LOGOUT, MFA_SETUP, etc. public string? Username { get; set; } public int Page { get; set; } = 1; public int PageSize { get; set; } = 50; } public class GetAuditLogsResponse { public required List Items { get; set; } public int Total { get; set; } public int Page { get; set; } public int PageSize { get; set; } } public class AuditLogItem { public Guid AuditId { get; set; } public required string EventType { get; set; } public Guid? IdentityId { get; set; } public string? Username { get; set; } public string? Role { get; set; } public string? IpAddress { get; set; } public string? Endpoint { get; set; } public string? HttpMethod { get; set; } public required string Status { get; set; } public string? ErrorCode { get; set; } public string? ErrorMessage { get; set; } public DateTime OccurredAt { get; set; } }