mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 16:46:17 +00:00
feat: separate browser callback and mobile app confirm endpoints
- Add GET /mgmt/spotify/callback (no auth) for browser OAuth redirect - Restore POST /mgmt/spotify/confirm (Basic Auth) for ueberboese mobile app - Callback returns HTML success/error pages; confirm returns JSON - Both call the same ExchangeCodeAndStore() logic
This commit is contained in:
committed by
Tobias Gesellchen
parent
c648027735
commit
dc81b0aa81
@@ -658,10 +658,10 @@ func setupRouter(server *handlers.Server) *chi.Mux {
|
||||
})
|
||||
|
||||
r.Route("/mgmt", func(r chi.Router) {
|
||||
// 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)
|
||||
// Browser OAuth callback — no auth required (Spotify redirects the
|
||||
// user's browser here directly). The authorization code is single-use,
|
||||
// short-lived, and useless without the client_secret.
|
||||
r.Get("/spotify/callback", server.HandleMgmtSpotifyCallback)
|
||||
|
||||
// All other management endpoints require Basic Auth.
|
||||
r.Group(func(r chi.Router) {
|
||||
@@ -669,6 +669,7 @@ func setupRouter(server *handlers.Server) *chi.Mux {
|
||||
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)
|
||||
|
||||
@@ -103,7 +103,51 @@ func (s *Server) HandleMgmtSpotifyInit(w http.ResponseWriter, _ *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// HandleMgmtSpotifyCallback is the browser OAuth callback from Spotify.
|
||||
// Not protected by Basic Auth — Spotify redirects the user's browser here directly.
|
||||
// Returns an HTML page the user can close.
|
||||
func (s *Server) HandleMgmtSpotifyCallback(w http.ResponseWriter, r *http.Request) {
|
||||
s.mu.RLock()
|
||||
svc := s.spotifyService
|
||||
s.mu.RUnlock()
|
||||
|
||||
if svc == nil {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
_, _ = w.Write([]byte(`<html><body><h1>Error</h1><p>Spotify integration not configured</p></body></html>`))
|
||||
return
|
||||
}
|
||||
|
||||
if errMsg := r.URL.Query().Get("error"); errMsg != "" {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = w.Write([]byte(`<html><body><h1>Spotify Authorization Failed</h1><p>Error: ` + errMsg + `</p></body></html>`))
|
||||
return
|
||||
}
|
||||
|
||||
code := r.URL.Query().Get("code")
|
||||
if code == "" {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = w.Write([]byte(`<html><body><h1>Missing authorization code</h1></body></html>`))
|
||||
return
|
||||
}
|
||||
|
||||
if err := svc.ExchangeCodeAndStore(code); err != nil {
|
||||
log.Printf("[Mgmt] Spotify callback failed: %v", err)
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte(`<html><body><h1>Error</h1><p>Token exchange failed</p></body></html>`))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
_, _ = w.Write([]byte(`<html><body><h1>Spotify Connected</h1><p>You can close this window.</p></body></html>`))
|
||||
}
|
||||
|
||||
// HandleMgmtSpotifyConfirm exchanges an authorization code for tokens.
|
||||
// Used by the ueberboese mobile app after the deep link callback delivers the code.
|
||||
// Protected by Basic Auth.
|
||||
func (s *Server) HandleMgmtSpotifyConfirm(w http.ResponseWriter, r *http.Request) {
|
||||
s.mu.RLock()
|
||||
svc := s.spotifyService
|
||||
|
||||
Reference in New Issue
Block a user