using System.Security.Claims;
using MeterVault.Infrastructure.Options;
using Microsoft.Extensions.Options;
namespace MeterVault.App.Api;
///
/// When enabled (SDD §10), trusts an authenticating reverse proxy (Authelia/Traefik) by adopting
/// the user it asserts via X-Forwarded-User / Remote-User. This lets the homelab run
/// MeterVault behind existing SSO without built-in accounts. Only enable when the app is not
/// directly reachable — any client could otherwise spoof the header.
///
public static class ReverseProxyTrust
{
private static readonly string[] UserHeaders = ["X-Forwarded-User", "Remote-User", "X-Forwarded-Preferred-Username"];
public static IApplicationBuilder UseReverseProxyTrust(this WebApplication app)
{
var options = app.Services.GetRequiredService>().Value;
if (!options.ReverseProxyTrust)
{
return app;
}
app.Use(async (context, next) =>
{
foreach (var header in UserHeaders)
{
var user = context.Request.Headers[header].ToString();
if (!string.IsNullOrWhiteSpace(user))
{
var identity = new ClaimsIdentity([new Claim(ClaimTypes.Name, user)], "ReverseProxy");
context.User = new ClaimsPrincipal(identity);
break;
}
}
await next(context).ConfigureAwait(false);
});
return app;
}
}