using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Options; using PolyTrader.Web.Configuration; using PolyTraderSharp.Services; namespace PolyTrader.Web.Endpoints { /// /// Zugangseinstellungen des WebUI - nur lesend (#562). /// /// Entscheidung Richard, 13.09.2026: Geheimnisse verwalten wir ausschliesslich im Desktop. Bis /// dahin lieferte GET /api/settings/webui das Zugangs-Token im Klartext aus, und ueber das WebUI /// liessen sich Token setzen, ein neues erzeugen und LocalOnly abschalten. Wer das Token hatte, /// konnte damit das WebUI ins Netz oeffnen (unverschluesseltes HTTP), sich den Zugang verlegen oder /// sich selbst aussperren. /// /// Port, LocalOnly, Enabled und das Token werden jetzt nur noch im Desktop unter /// Einstellungen -> WebUI gepflegt. Das WebUI zeigt die Werte an, vom Token nur, ob es gesetzt ist. /// public static class SettingsEndpoints { internal const string DesktopOnlyMessage = "Zugang, Port und Token des WebUI werden ausschließlich im Desktop verwaltet (Einstellungen → WebUI)."; public static IEndpointRouteBuilder MapSettingsEndpoints(this IEndpointRouteBuilder routes) { var group = routes.MapGroup("/api/settings"); group.MapGet("/webui", (IOptions optionsProvider) => { var opt = optionsProvider.Value; return Results.Ok(new { enabled = opt.Enabled, port = opt.Port, localOnly = opt.LocalOnly, hasToken = !string.IsNullOrWhiteSpace(opt.AuthToken), managedIn = "desktop" }); }); // Die frueheren Schreibwege bleiben als ausdrueckliche Ablehnung stehen, statt zu verschwinden: // Ohne eigene Route faengt die Fallback-Route (index.html) den POST ab und antwortet mit 200 - // ein altes Skript hielte das fuer einen Erfolg. group.MapPost("/webui", RejectDesktopOnly); group.MapPost("/webui/generate-token", RejectDesktopOnly); return routes; } private static IResult RejectDesktopOnly(HttpContext context, TerminalLogger logger) { logger.Warning($"🌐 WebUI: Änderung der Zugangseinstellungen über {context.Request.Path} abgelehnt – nur im Desktop möglich."); return Results.Json(new { error = DesktopOnlyMessage }, statusCode: StatusCodes.Status403Forbidden); } } }