mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-24 14:47:23 +00:00
After the proxy/mirror removal there is no proxy left in the service,
but the parallel partial-update endpoint /setup/proxy-settings stuck
around with its legacy name. It serves a legitimate purpose distinct
from the bulk /setup/settings POST: the three checkboxes
(Redact / Log Bodies / Record) use onchange-triggered live save,
while /setup/settings drives a Save-button form for dozens of fields.
Folding the two endpoints together would either lose the live-toggle
UX or send half-edited draft form data on every toggle, so the
partial-update endpoint earns its keep — it just needed the right
name.
Renamed symbols (no behaviour change):
Go handler funcs:
HandleGetProxySettings → HandleGetLoggingSettings
HandleUpdateProxySettings → HandleUpdateLoggingSettings
GetProxySettings → GetLoggingSettings
Route:
/setup/proxy-settings → /setup/logging-settings
JS:
fetchProxySettings() → fetchLoggingSettings()
updateProxySettings() → updateLoggingSettings()
HTML element IDs (cosmetic, kept consistent):
proxy-redact / proxy-log-body / proxy-record
→ logging-redact / logging-log-body / logging-record
HTML heading:
"Proxy Logging:" → "Logging:"
JSON payload shapes (request + response keys) are UNCHANGED: the
endpoint still emits / accepts {"redact", "log_body", "record"}.
Persisted Settings on disk are UNCHANGED. CLI flags are UNCHANGED.
Server struct fields redactLogs / logBodies / recordEnabled
(renamed earlier this session) are UNCHANGED.
testdata/router_routes.txt regenerated. go build clean. go test
./... clean except pre-existing TestDocsConsistency (untracked-file
issue, unrelated). golangci-lint 0 issues.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
158 lines
7.9 KiB
Go
158 lines
7.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"github.com/gesellix/bose-soundtouch/pkg/service/datastore"
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
func setupRouter(targetURL string, ds *datastore.DataStore) (*chi.Mux, *Server) {
|
|
server := NewServer(ds, nil, targetURL, false, false, false)
|
|
|
|
r := chi.NewRouter()
|
|
r.Use(server.OriginMiddleware)
|
|
r.Use(server.ShortcutMiddleware)
|
|
r.Use(server.RecordMiddleware)
|
|
|
|
r.Get("/", server.HandleRoot)
|
|
|
|
// Setup media and web directories for tests
|
|
r.Get("/media/*", server.HandleMedia())
|
|
r.Get("/web/*", server.HandleWeb())
|
|
|
|
// Setup BMX for tests
|
|
r.Route("/bmx", func(r chi.Router) {
|
|
r.Get("/registry/v1/services", server.HandleBMXRegistry)
|
|
r.Get("/registry/v1/servicesAvailability", server.HandleBMXServicesAvailability)
|
|
r.Get("/tunein/v1/playback/station/{stationID}", server.HandleTuneInPlayback)
|
|
r.Get("/tunein/v1/playback/episodes/{podcastID}", server.HandleTuneInPodcastInfo)
|
|
r.Get("/tunein/v1/playback/episode/{podcastID}", server.HandleTuneInPlaybackPodcast)
|
|
r.Post("/tunein/v1/token", server.HandleTuneInToken)
|
|
r.Post("/tunein/v1/report", server.HandleTuneInReport)
|
|
r.Get("/tunein/v1/navigate", server.HandleTuneInNavigate)
|
|
r.Get("/tunein/v1/navigate/*", server.HandleTuneInNavigate)
|
|
r.Get("/tunein/v1/search", server.HandleTuneInSearch)
|
|
})
|
|
|
|
// Orion lives at the top level — see the matching note in
|
|
// cmd/soundtouch-service/main.go. Mirrored here so the test router
|
|
// exercises the same paths the production router does.
|
|
r.Post("/core02/svc-bmx-adapter-orion/prod/orion/token", server.HandleOrionToken)
|
|
r.Get("/core02/svc-bmx-adapter-orion/prod/orion/station", server.HandleOrionPlayback)
|
|
|
|
r.Get("/custom/v1/playback/{encodedURL}", server.HandleCustomPlayback)
|
|
|
|
streamingRoutes := func(r chi.Router) {
|
|
r.Get("/sourceproviders", server.HandleMargeSourceProviders)
|
|
r.Route("/account/{account}/device", func(r chi.Router) {
|
|
r.Post("/", server.HandleMargeAddDevice)
|
|
r.Post("/{device}", server.HandleMargeAddDevice)
|
|
// Rename PUT — mirrors the production router. Issue #285.
|
|
r.Put("/{device}", server.HandleMargeUpdateDevice)
|
|
})
|
|
r.Get("/account/{account}/device/{device}/recent", server.HandleMargeRecents)
|
|
r.Post("/account/{account}/device/{device}/recent", server.HandleMargeAddRecent)
|
|
r.Get("/account/{account}/device/{device}/presets", server.HandleMargePresets)
|
|
r.Post("/account/{account}/device/{device}/presets/{presetNumber}", server.HandleMargeUpdatePreset)
|
|
r.Put("/account/{account}/device/{device}/preset/{presetNumber}", server.HandleMargeUpdatePreset)
|
|
r.Post("/support/power_on", server.HandleMargePowerOn)
|
|
r.Get("/account/{account}/provider_settings", server.HandleMargeProviderSettings)
|
|
r.Get("/device/{device}/streaming_token", server.HandleMargeStreamingToken)
|
|
r.Post("/support/customersupport", server.HandleMargeCustomerSupport)
|
|
r.Get("/device_setting/account/{account}/device/{device}/device_settings", server.HandleMargeGetDeviceSettings)
|
|
// Native group endpoint (both with and without trailing slash)
|
|
r.Get("/account/{account}/device/{device}/group", server.HandleMargeDeviceGroup)
|
|
r.Get("/account/{account}/device/{device}/group/", server.HandleMargeDeviceGroup)
|
|
r.Get("/account/{account}/device/{device}/group/server", server.HandleMargeDeviceGroupServer)
|
|
r.Get("/account/{account}/device/{device}/group/member", server.HandleMargeDeviceGroupMember)
|
|
// Speakers POST to /group/ (with trailing slash) when forwarding the
|
|
// addGroup payload to Marge during stereo-pair formation -- see issue
|
|
// #252. Register both forms so chi accepts either.
|
|
r.Post("/account/{account}/group", server.HandleMargeAddGroup)
|
|
r.Post("/account/{account}/group/", server.HandleMargeAddGroup)
|
|
r.Post("/account/{account}/group/{groupId}", server.HandleMargeModifyGroup)
|
|
r.Delete("/account/{account}/group/{groupId}", server.HandleMargeDeleteGroup)
|
|
r.Post("/device_setting/account/{account}/device/{device}/device_settings", server.HandleMargeUpdateDeviceSettings)
|
|
r.Get("/account/{account}/emailaddress", server.HandleMargeGetEmailAddress)
|
|
r.Get("/account/{account}/full", server.HandleMargeAccountFull)
|
|
r.Get("/account/{account}/sources", server.HandleMargeAccountSources)
|
|
r.Get("/account/{account}/devices", server.HandleMargeAccountDevices)
|
|
r.Get("/account/{account}/presets", server.HandleMargeAccountPresets)
|
|
r.Get("/account/{account}/presets/all", server.HandleMargeAccountPresets)
|
|
r.Get("/software/update/account/{account}", server.HandleMargeSoftwareUpdate)
|
|
r.Post("/account", server.HandleMargeCreateAccount)
|
|
r.Post("/account/login", server.HandleMargeLogin)
|
|
r.Post("/music/musicprovider/{providerID}/is_eligible", server.HandleMusicProviderIsEligible)
|
|
r.Get("/resources/api_versions.xml", server.HandleMargeAPIVersions)
|
|
}
|
|
|
|
accountsRoutes := func(r chi.Router) {
|
|
r.Get("/{account}/full", server.HandleMargeAccountFull)
|
|
r.Get("/{account}/sources", server.HandleMargeAccountSources)
|
|
r.Get("/{account}/devices", server.HandleMargeAccountDevices)
|
|
r.Get("/{account}/devices/{device}/presets", server.HandleMargePresets)
|
|
r.Post("/{account}/devices/{device}/presets/{presetNumber}", server.HandleMargeUpdatePreset)
|
|
r.Put("/{account}/devices/{device}/preset/{presetNumber}", server.HandleMargeUpdatePreset)
|
|
r.Get("/{account}/devices/{device}/recents", server.HandleMargeRecents)
|
|
r.Post("/{account}/devices/{device}/recents", server.HandleMargeAddRecent)
|
|
r.Post("/{account}/devices", server.HandleMargeAddDevice)
|
|
r.Delete("/{account}/devices/{device}", server.HandleMargeRemoveDevice)
|
|
r.Get("/{account}/devices/{device}/group", server.HandleMargeDeviceGroup)
|
|
r.Get("/{account}/devices/{device}/group/", server.HandleMargeDeviceGroup)
|
|
r.Get("/{account}/devices/{device}/group/server", server.HandleMargeDeviceGroupServer)
|
|
r.Get("/{account}/devices/{device}/group/member", server.HandleMargeDeviceGroupMember)
|
|
r.Post("/{account}/group", server.HandleMargeAddGroup)
|
|
r.Post("/{account}/group/", server.HandleMargeAddGroup)
|
|
r.Post("/{account}/group/{groupId}", server.HandleMargeModifyGroup)
|
|
r.Delete("/{account}/group/{groupId}", server.HandleMargeDeleteGroup)
|
|
}
|
|
|
|
// Setup Marge for tests
|
|
r.Route("/marge", func(r chi.Router) {
|
|
r.Route("/streaming", streamingRoutes)
|
|
r.Route("/accounts", accountsRoutes)
|
|
r.Get("/updates/soundtouch", server.HandleMargeSoftwareUpdate)
|
|
})
|
|
|
|
// Legacy or direct domain calls without /marge prefix
|
|
r.Route("/streaming", streamingRoutes)
|
|
r.Route("/accounts", accountsRoutes)
|
|
r.Get("/updates/soundtouch", server.HandleMargeSoftwareUpdate)
|
|
|
|
// Setup Customer for tests
|
|
r.Route("/customer", func(r chi.Router) {
|
|
r.Get("/account/{account}", server.HandleMargeAccountProfile)
|
|
r.Post("/account/{account}", server.HandleMargeUpdateAccountProfile)
|
|
r.Post("/account/{account}/password", server.HandleMargeChangePassword)
|
|
})
|
|
|
|
// Setup Setup for tests
|
|
r.Route("/setup", func(r chi.Router) {
|
|
r.Get("/devices", server.HandleListDiscoveredDevices)
|
|
r.Delete("/devices/{deviceId}", server.HandleRemoveDevice)
|
|
r.Get("/settings", server.HandleGetSettings)
|
|
r.Post("/settings", server.HandleUpdateSettings)
|
|
r.Get("/logging-settings", server.HandleGetLoggingSettings)
|
|
r.Post("/logging-settings", server.HandleUpdateLoggingSettings)
|
|
r.Post("/ensure-remote-services/{deviceId}", server.HandleEnsureRemoteServices)
|
|
r.Post("/remove-remote-services/{deviceId}", server.HandleRemoveRemoteServices)
|
|
r.Post("/migrate/{deviceId}", server.HandleMigrateDevice)
|
|
r.Post("/revert/{deviceId}", server.HandleRevertMigration)
|
|
r.Post("/reboot/{deviceId}", server.HandleRebootDevice)
|
|
r.Get("/account-id-suggestions/{deviceId}", server.HandleAccountIDSuggestions)
|
|
r.Post("/pair-account/{deviceId}", server.HandlePairAccount)
|
|
r.Post("/trust-ca/{deviceId}", server.HandleTrustCACert)
|
|
r.Post("/test-connection/{deviceId}", server.HandleTestConnection)
|
|
r.Post("/test-hosts/{deviceId}", server.HandleTestHostsRedirection)
|
|
r.Get("/ca.crt", server.HandleGetCACert)
|
|
})
|
|
|
|
r.NotFound(server.HandleNotFound)
|
|
|
|
return r, server
|
|
}
|
|
|
|
func init() {
|
|
// Silence logger for tests
|
|
// log.SetOutput(io.Discard)
|
|
}
|