fix: OAuth callback as GET outside auth group, remove dead zeroconf flag, update .env.example

- Change /mgmt/spotify/confirm from POST to GET (Spotify redirects via GET)
- Move confirm endpoint outside Basic Auth group (code is single-use, needs client_secret)
- Remove --zeroconf-primer-enabled flag (no ZeroConf primer code on this branch)
- Add Spotify/mgmt env var documentation to .env.example
This commit is contained in:
Tim Van Wassenhove
2026-02-21 00:21:52 +01:00
committed by Tobias Gesellchen
parent fced88a8a6
commit c648027735
3 changed files with 29 additions and 27 deletions
+14
View File
@@ -41,3 +41,17 @@ PREFERRED_DEVICES="Living Room@192.168.1.100:8090;Kitchen@192.168.1.101;192.168.
# Alternative format examples:
# PREFERRED_DEVICES="192.168.178.35;192.168.178.28"
# PREFERRED_DEVICES="SoundTouch 10@192.168.178.35;SoundTouch 20@192.168.178.28"
# Spotify Integration
# Create an app at https://developer.spotify.com/dashboard
# SPOTIFY_CLIENT_ID=your_client_id
# SPOTIFY_CLIENT_SECRET=your_client_secret
# SPOTIFY_REDIRECT_URI=https://your-server.example.com/mgmt/spotify/confirm
# Management API Authentication
# Protects /mgmt/* endpoints (Spotify token access, account management)
MGMT_USERNAME=admin
MGMT_PASSWORD=change_me!
# External base URL (required when behind a reverse proxy for OAuth callbacks)
# BASE_URL=https://your-server.example.com
+15 -18
View File
@@ -184,12 +184,6 @@ func main() {
Value: "change_me!",
EnvVars: []string{"MGMT_PASSWORD"},
},
&cli.BoolFlag{
Name: "zeroconf-primer-enabled",
Usage: "Enable ZeroConf Spotify primer for speakers",
Value: true,
EnvVars: []string{"ZEROCONF_PRIMER_ENABLED"},
},
&cli.StringFlag{
Name: "base-url",
Usage: "External base URL for OAuth callbacks behind reverse proxy",
@@ -226,7 +220,6 @@ func main() {
server.SetDNSSettings(persisted.DNSEnabled, persisted.DNSUpstream, persisted.DNSBindAddr)
server.SetSpotifyConfig(config.spotifyClientID, config.spotifyClientSecret, config.spotifyRedirectURI)
server.SetMgmtConfig(config.mgmtUsername, config.mgmtPassword)
server.SetZeroconfEnabled(config.zeroconfEnabled)
server.SetBaseURL(config.baseURL)
if config.spotifyClientID != "" {
@@ -362,7 +355,6 @@ type serviceConfig struct {
spotifyRedirectURI string
mgmtUsername string
mgmtPassword string
zeroconfEnabled bool
baseURL string
}
@@ -427,7 +419,6 @@ func loadConfig(c *cli.Context) serviceConfig {
spotifyRedirectURI := c.String("spotify-redirect-uri")
mgmtUsername := c.String("mgmt-username")
mgmtPassword := c.String("mgmt-password")
zeroconfEnabled := c.Bool("zeroconf-primer-enabled")
baseURL := c.String("base-url")
return serviceConfig{
@@ -453,7 +444,6 @@ func loadConfig(c *cli.Context) serviceConfig {
spotifyRedirectURI: spotifyRedirectURI,
mgmtUsername: mgmtUsername,
mgmtPassword: mgmtPassword,
zeroconfEnabled: zeroconfEnabled,
baseURL: baseURL,
}
}
@@ -668,14 +658,21 @@ func setupRouter(server *handlers.Server) *chi.Mux {
})
r.Route("/mgmt", func(r chi.Router) {
r.Use(server.BasicAuthMgmt())
r.Get("/accounts/{accountId}/speakers", server.HandleMgmtListSpeakers)
r.Get("/devices/{deviceId}/events", server.HandleMgmtDeviceEvents)
r.Post("/spotify/init", server.HandleMgmtSpotifyInit)
r.Post("/spotify/confirm", server.HandleMgmtSpotifyConfirm)
r.Get("/spotify/accounts", server.HandleMgmtSpotifyAccounts)
r.Get("/spotify/token", server.HandleMgmtSpotifyToken)
r.Post("/spotify/entity", server.HandleMgmtSpotifyEntity)
// OAuth callback — no auth required (browser redirect from Spotify).
// The authorization code is single-use, short-lived, and useless without
// the client_secret (which only the server has).
r.Get("/spotify/confirm", server.HandleMgmtSpotifyConfirm)
// All other management endpoints require Basic Auth.
r.Group(func(r chi.Router) {
r.Use(server.BasicAuthMgmt())
r.Get("/accounts/{accountId}/speakers", server.HandleMgmtListSpeakers)
r.Get("/devices/{deviceId}/events", server.HandleMgmtDeviceEvents)
r.Post("/spotify/init", server.HandleMgmtSpotifyInit)
r.Get("/spotify/accounts", server.HandleMgmtSpotifyAccounts)
r.Get("/spotify/token", server.HandleMgmtSpotifyToken)
r.Post("/spotify/entity", server.HandleMgmtSpotifyEntity)
})
})
r.Get("/proxy/*", server.HandleProxyRequest)
-9
View File
@@ -46,7 +46,6 @@ type Server struct {
spotifyClientID string
spotifyClientSecret string
spotifyRedirectURI string
zeroconfEnabled bool
baseURL string
spotifyService *spotify.SpotifyService
}
@@ -243,14 +242,6 @@ func (s *Server) SetMgmtConfig(username, password string) {
s.mgmtPassword = password
}
// SetZeroconfEnabled sets whether ZeroConf Spotify primer is enabled.
func (s *Server) SetZeroconfEnabled(enabled bool) {
s.mu.Lock()
defer s.mu.Unlock()
s.zeroconfEnabled = enabled
}
// SetBaseURL sets the external base URL for OAuth callbacks.
func (s *Server) SetBaseURL(baseURL string) {
s.mu.Lock()