diff --git a/pkg/service/handlers/handlers_landing_test.go b/pkg/service/handlers/handlers_landing_test.go index 0122033..d2a5aee 100644 --- a/pkg/service/handlers/handlers_landing_test.go +++ b/pkg/service/handlers/handlers_landing_test.go @@ -76,6 +76,25 @@ func TestHandleRootRedirects(t *testing.T) { } } +// TestHandleRootChooserOverride: "?chooser" forces the chooser even when a +// default redirect is configured, so the hub stays reachable. +func TestHandleRootChooserOverride(t *testing.T) { + for _, landing := range []string{"app", "admin"} { + server := newLandingServer(t, landing) + + rec := httptest.NewRecorder() + server.HandleRoot(rec, htmlGet("/?chooser")) + + if rec.Code != http.StatusOK { + t.Errorf("landing=%q with ?chooser: status = %d; want 200 (no redirect)", landing, rec.Code) + } + + if !strings.Contains(rec.Body.String(), `href="/admin"`) { + t.Errorf("landing=%q with ?chooser: body is not the chooser", landing) + } + } +} + // TestHandleRootJSONIgnoresLanding: API/speaker clients (non-HTML Accept) // always get the version JSON, never a landing redirect, regardless of // the configured default. diff --git a/pkg/service/handlers/handlers_media.go b/pkg/service/handlers/handlers_media.go index f8e81b9..05a4b19 100644 --- a/pkg/service/handlers/handlers_media.go +++ b/pkg/service/handlers/handlers_media.go @@ -117,15 +117,20 @@ func (s *Server) HandleRoot(w http.ResponseWriter, r *http.Request) { } // HTML branch: a browser hitting "/". Honour the configured default - // landing surface, otherwise serve the neutral chooser. The admin - // console itself now lives at /admin (served by HandleAdmin). - switch s.defaultLanding() { - case "app": - http.Redirect(w, r, "/app", http.StatusFound) - return - case "admin": - http.Redirect(w, r, "/admin", http.StatusFound) - return + // landing surface, otherwise serve the neutral chooser. A "?chooser" + // query forces the chooser even when a default redirect is set, so the + // hub (and through it the admin console) stays reachable: the "home" + // links on the player and admin point here. The admin console itself + // lives at /admin (served by HandleAdmin). + if !r.URL.Query().Has("chooser") { + switch s.defaultLanding() { + case "app": + http.Redirect(w, r, "/app", http.StatusFound) + return + case "admin": + http.Redirect(w, r, "/admin", http.StatusFound) + return + } } w.Header().Set("Content-Type", "text/html") diff --git a/pkg/service/handlers/web/index.html b/pkg/service/handlers/web/index.html index 0c1558f..7d2f2fa 100644 --- a/pkg/service/handlers/web/index.html +++ b/pkg/service/handlers/web/index.html @@ -9,7 +9,7 @@