From 2eef9b2e4a38e0331be7384f443cdd1f92ca1c78 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sat, 18 Jul 2026 11:51:12 +0200 Subject: [PATCH] fix(samba): register /api/sharing/ on the mux, not the web switch The /api/ subtree is routed on the main mux, so the browse case in the web ServeHTTP switch was shadowed by the apiRouter catch-all and 401'd. Moved to ServeSharingAPI behind RequireAuth+CsrfProtect, matching /api/storage/. Found by live validation. --- controller/cmd/controller/main.go | 3 +++ controller/internal/web/server.go | 2 -- controller/internal/web/sharing_handlers.go | 12 ++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/controller/cmd/controller/main.go b/controller/cmd/controller/main.go index 4b96668..52b6d52 100644 --- a/controller/cmd/controller/main.go +++ b/controller/cmd/controller/main.go @@ -1009,6 +1009,9 @@ func main() { mux.Handle("/api/disks/", webServer.RequireAuth(webServer.CsrfProtect(http.HandlerFunc(webServer.ServeDiskAPI)))) // Guided storage provisioning (init/attach/eject orchestration over the agent disk API + registry). mux.Handle("/api/storage/", webServer.RequireAuth(webServer.CsrfProtect(http.HandlerFunc(webServer.ServeStorageAPI)))) + // LAN network-sharing folder picker (R-7 slice 1). Must live here, not in the web ServeHTTP + // switch: the /api/ subtree is routed on this mux, so a case there is shadowed and 401s. + mux.Handle("/api/sharing/", webServer.RequireAuth(webServer.CsrfProtect(http.HandlerFunc(webServer.ServeSharingAPI)))) // Guest RAM resize (v0.143.0, R-24): read current allocation/bounds + apply a bounded resize. mux.Handle("/api/system/", webServer.RequireAuth(webServer.CsrfProtect(http.HandlerFunc(webServer.ServeSystemAPI)))) // Standalone full-server (guest) restart — the "Kiszolgáló újraindítása" maintenance affordance, diff --git a/controller/internal/web/server.go b/controller/internal/web/server.go index 96bd110..4ecd799 100644 --- a/controller/internal/web/server.go +++ b/controller/internal/web/server.go @@ -367,8 +367,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.sharingShareDeleteHandler(w, r) case path == "/sharing/shares/offsite" && r.Method == http.MethodPost: s.sharingShareOffsiteHandler(w, r) - case path == "/api/sharing/browse" && r.Method == http.MethodGet: - s.sharingBrowseHandler(w, r) case path == "/settings/notifications" && r.Method == http.MethodGet: s.settingsNotificationsPageHandler(w, r) case path == "/settings/security" && r.Method == http.MethodGet: diff --git a/controller/internal/web/sharing_handlers.go b/controller/internal/web/sharing_handlers.go index e51a010..6625527 100644 --- a/controller/internal/web/sharing_handlers.go +++ b/controller/internal/web/sharing_handlers.go @@ -294,6 +294,18 @@ func (s *Server) sharingShareOffsiteHandler(w http.ResponseWriter, r *http.Reque sharingRedirect(w, r, "Beállítás mentve.") } +// ServeSharingAPI dispatches the /api/sharing/* XHR endpoints. Registered on the mux in main.go +// behind RequireAuth+CsrfProtect (the /api/ subtree is claimed there, NOT in the web ServeHTTP +// switch — a case added there would be shadowed by the apiRouter catch-all and 401). +func (s *Server) ServeSharingAPI(w http.ResponseWriter, r *http.Request) { + switch { + case r.URL.Path == "/api/sharing/browse" && r.Method == http.MethodGet: + s.sharingBrowseHandler(w, r) + default: + http.NotFound(w, r) + } +} + // sharingBrowseHandler is the folder picker (GET /api/sharing/browse?path=). With no path it lists // the registered live storage roots; otherwise the sub-DIRECTORIES of a guard-approved path, sorted. // Deny-listed children are omitted so the picker never offers an unshareable folder.