diff --git a/server/backend/internal/httpapi/router.go b/server/backend/internal/httpapi/router.go index f4e1068..98aaa71 100644 --- a/server/backend/internal/httpapi/router.go +++ b/server/backend/internal/httpapi/router.go @@ -141,6 +141,16 @@ func registerManageRoutes(mux *http.ServeMux, d RouterDeps) { authScreen := func(h http.Handler) http.Handler { return chain(h, RequireAuth(d.AuthStore), RequireScreenAccess(d.ScreenStore), setCSRF, csrf) } + // authScreenControl: wie authScreen, aber restricted-User werden mit 403 blockiert. + // Für Endpunkte, die restricted-User nicht nutzen dürfen (Display, Zeitplan, Override). + authScreenControl := func(h http.Handler) http.Handler { + return chain(h, RequireAuth(d.AuthStore), RequireScreenAccess(d.ScreenStore), RequireNotRestricted, setCSRF, csrf) + } + // authOnlyControl: wie authOnly, aber restricted-User werden mit 403 blockiert. + // Für globalen Override (kein spezifischer Screen). + authOnlyControl := func(h http.Handler) http.Handler { + return chain(h, RequireAuth(d.AuthStore), RequireNotRestricted, setCSRF, csrf) + } // ── Admin UI ────────────────────────────────────────────────────────── mux.Handle("GET /admin", @@ -187,23 +197,23 @@ func registerManageRoutes(mux *http.ServeMux, d RouterDeps) { // ── Display control ─────────────────────────────────────────────────── mux.Handle("POST /api/v1/screens/{screenSlug}/display", - authScreen(http.HandlerFunc(manage.HandleDisplayCommand(notifier)))) + authScreenControl(http.HandlerFunc(manage.HandleDisplayCommand(notifier)))) // ── Schedule control ────────────────────────────────────────────────── mux.Handle("POST /api/v1/screens/{screenSlug}/schedule", - authScreen(http.HandlerFunc(manage.HandleUpdateSchedule(d.ScreenStore, d.ScheduleStore)))) + authScreenControl(http.HandlerFunc(manage.HandleUpdateSchedule(d.ScreenStore, d.ScheduleStore)))) // ── Globaler Override ──────────────────────────────────────────────── mux.Handle("GET /api/v1/global-override", authOnly(http.HandlerFunc(manage.HandleGetGlobalOverride(d.GlobalOverrideStore)))) mux.Handle("POST /api/v1/global-override", - authOnly(http.HandlerFunc(manage.HandleSetGlobalOverride(d.GlobalOverrideStore, d.ScreenStore, notifier)))) + authOnlyControl(http.HandlerFunc(manage.HandleSetGlobalOverride(d.GlobalOverrideStore, d.ScreenStore, notifier)))) mux.Handle("DELETE /api/v1/global-override", - authOnly(http.HandlerFunc(manage.HandleDeleteGlobalOverride(d.GlobalOverrideStore)))) + authOnlyControl(http.HandlerFunc(manage.HandleDeleteGlobalOverride(d.GlobalOverrideStore)))) // ── Per-Screen Override ─────────────────────────────────────────────── mux.Handle("POST /api/v1/screens/{screenSlug}/override", - authScreen(http.HandlerFunc(manage.HandleSetScreenOverride(d.ScreenStore, d.ScheduleStore)))) + authScreenControl(http.HandlerFunc(manage.HandleSetScreenOverride(d.ScreenStore, d.ScheduleStore)))) // ── JSON API — screens ──────────────────────────────────────────────── // Self-registration: no auth (player calls this on startup).