feat(subsonic): getUser + envelope-shaped 404 for /rest/*
Feishin's first-login flow hits getUser to discover the authenticated
identity's roles. We never registered the route, so chi returned a
plain-text 404 — Feishin's parser treats anything non-Subsonic as a
generic auth failure ("Failed to log in"), masking the real cause.
- Implement /rest/getUser with the full role bag. Admins get every
role; non-admins get the play-music subset. Single-user M1 means
cross-user lookups by admins return the caller's roles for now;
revisit when user management lands.
- Set sub.NotFound on /rest/* to emit a Subsonic envelope (code 0,
"Method not implemented") instead of plain text. Any future client
probing an unimplemented endpoint now sees a parseable failure.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,16 @@ func Mount(r chi.Router, pool *pgxpool.Pool, logger *slog.Logger, cfg Config) {
|
||||
register(sub, "/download", m.handleDownload)
|
||||
register(sub, "/getCoverArt", m.handleGetCoverArt)
|
||||
register(sub, "/scrobble", m.handleScrobble)
|
||||
register(sub, "/getUser", handleGetUser)
|
||||
|
||||
// Subsonic clients expect every /rest/* miss to come back as a
|
||||
// Subsonic-shaped error envelope, not chi's plain-text 404. Without
|
||||
// this, hitting an unimplemented method (Feishin's first-login probe
|
||||
// hits getUser, getPlaylists, etc.) breaks the client's parser and
|
||||
// surfaces as a generic "failed to log in".
|
||||
sub.NotFound(func(w http.ResponseWriter, r *http.Request) {
|
||||
WriteFail(w, r, ErrGeneric, "Method not implemented")
|
||||
})
|
||||
_ = logger
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user