namespace QRRapidoApp.Middleware
{
///
/// Adds security headers and JSON error handling for /api/v1/* routes.
///
public class ApiSecurityHeadersMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public ApiSecurityHeadersMiddleware(RequestDelegate next, ILogger logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Path.StartsWithSegments("/api/v1"))
{
await _next(context);
return;
}
// Security headers for API responses
context.Response.Headers["X-Content-Type-Options"] = "nosniff";
context.Response.Headers["X-Frame-Options"] = "DENY";
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception on API route {Path}", context.Request.Path);
if (!context.Response.HasStarted)
{
context.Response.StatusCode = 500;
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(new
{
error = "An internal error occurred. Please try again later.",
requestId = context.TraceIdentifier
});
}
}
}
}
}