fix(server): drop duplicate /api/admin route mount that shadowed api.Mount endpoints
Bug: r.Route("/api/admin", ...) in server.go for the /scan endpoint
created a second chi subtree at the same prefix as the nested admin
Route inside api.Mount. chi.Walk shows both subtrees registered, but
runtime routing dispatch only matched one — so every /api/admin/*
endpoint registered by api.Mount (Lidarr config, quarantine admin,
requests admin) silently returned 404 to authenticated callers.
Has shipped this way since 06a1fe1; M5a/b/c admin tests didn't catch
it because they call api.Mount on a fresh chi.NewRouter() rather than
going through Server.Router(), so only one /api/admin registration
existed in those tests.
Fix: register /api/admin/scan as a single inline-middleware route
(r.With(...).Post(...)) instead of a Route subtree, eliminating the
duplicate /api/admin mount.
Adds a regression test that uses a real seeded admin session to make
an authenticated GET /api/admin/lidarr/config and asserts != 404.
Verified the test fails without the fix and passes with it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -74,13 +74,14 @@ func (s *Server) Router() http.Handler {
|
||||
lidarrReqs := lidarrrequests.NewService(s.Pool, lidarrCfg, lidarrClientFn, nil)
|
||||
lidarrQuar := lidarrquarantine.NewService(s.Pool, lidarrCfg, lidarrClientFn)
|
||||
api.Mount(r, s.Pool, s.Logger, writer, s.RecommendationCfg, lidarrCfg, lidarrReqs, lidarrQuar)
|
||||
r.Route("/api/admin", func(admin chi.Router) {
|
||||
admin.Use(auth.RequireUser(s.Pool))
|
||||
admin.Use(auth.RequireAdmin())
|
||||
if s.Scanner != nil {
|
||||
admin.Post("/scan", s.handleAdminScan)
|
||||
}
|
||||
})
|
||||
// /api/admin/scan is the only admin route owned by the server package
|
||||
// (it needs the Scanner). Register it as a single inline-middleware
|
||||
// route — using r.Route("/api/admin", ...) here would create a second
|
||||
// subtree that shadows every admin route registered by api.Mount.
|
||||
if s.Scanner != nil {
|
||||
r.With(auth.RequireUser(s.Pool), auth.RequireAdmin()).
|
||||
Post("/api/admin/scan", s.handleAdminScan)
|
||||
}
|
||||
subsonic.Mount(r, s.Pool, s.Logger, s.SubsonicCfg, writer)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user