mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-24 14:47:23 +00:00
Fixes CodeQL go/log-injection alerts in three packages. Adds logutil.go with a package-private sanitizeLog helper to each. pkg/service/soundtouchweb/discovery.go (2 call sites): - host, source (device fetch failure) - source, info.Name, info.Type, host (device added) pkg/service/soundtouchweb/websocket.go (9 call sites): - deviceID across connect/disconnect/upgrade/read/ping/status messages pkg/service/stockholm/bridge.go (2 call sites): - method, clientID (dispatch trace) - clientID, msg (log bridge method) pkg/service/stockholm/discovery.go (2 call sites): - host (fetch failure) - host, info.MargeAccountUUID, expectedAccountID (skipping device) pkg/service/stockholm/static.go (1 call site): - r.URL.Path (path-traversal rejection) pkg/service/zeroconf/zeroconf.go (2 call sites): - username (logAddUserNoOp) - username, server, ct, cl, bodySummary (logAddUserFailure) No behaviour change. golangci-lint and make check pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
97 lines
3.0 KiB
Go
97 lines
3.0 KiB
Go
package soundtouchweb
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/gesellix/bose-soundtouch/pkg/client"
|
|
"github.com/gesellix/bose-soundtouch/pkg/config"
|
|
"github.com/gesellix/bose-soundtouch/pkg/discovery"
|
|
"github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb/webtypes"
|
|
)
|
|
|
|
// NewDiscoveryService loads config and returns a unified discovery service
|
|
// preconfigured for the web UI's use (10 s discovery timeout, cache on).
|
|
// When discoveryInterface is non-empty, mDNS/UPnP are pinned to that NIC.
|
|
func NewDiscoveryService(discoveryInterface string) *discovery.UnifiedDiscoveryService {
|
|
cfg, err := config.LoadFromEnv()
|
|
if err != nil {
|
|
log.Printf("Failed to load config: %v, using defaults", err)
|
|
|
|
cfg = config.DefaultConfig()
|
|
}
|
|
|
|
cfg.DiscoveryTimeout = 10 * time.Second
|
|
cfg.CacheEnabled = true
|
|
|
|
if discoveryInterface != "" {
|
|
cfg.DiscoveryInterface = discoveryInterface
|
|
}
|
|
|
|
return discovery.NewUnifiedDiscoveryService(cfg)
|
|
}
|
|
|
|
// AddDeviceByHost registers a SoundTouch device with the WebApp by fetching
|
|
// its /info and creating a DeviceConnection. The source label
|
|
// ("manual" or "discovered") appears in log lines so the operator can
|
|
// tell apart entries that came from --devices from those found via
|
|
// mDNS/UPnP. If the host is already known, the existing entry's
|
|
// LastSeen is bumped and the function returns without re-fetching.
|
|
func (app *WebApp) AddDeviceByHost(host string, port int, source string) {
|
|
// Fast path: skip the network call if we already know this host.
|
|
if app.TouchDevice(host) {
|
|
return
|
|
}
|
|
|
|
c := client.NewClient(&client.Config{
|
|
Host: host,
|
|
Port: port,
|
|
Timeout: 10 * time.Second,
|
|
})
|
|
|
|
info, err := c.GetDeviceInfo()
|
|
if err != nil {
|
|
log.Printf("Failed to fetch device info from %s (%s): %v", sanitizeLog(host), sanitizeLog(source), err)
|
|
return
|
|
}
|
|
|
|
// Ensure IPAddress is set for the web UI
|
|
if info.IPAddress == "" {
|
|
info.IPAddress = host
|
|
}
|
|
|
|
conn := webtypes.NewDeviceConnection(c, info)
|
|
if !app.AddDevice(host, conn) {
|
|
// Lost a race — another goroutine inserted the same host
|
|
// between TouchDevice and AddDevice. AddDevice bumped LastSeen
|
|
// on the existing entry; discard our conn.
|
|
return
|
|
}
|
|
|
|
go app.UpdateDeviceStatus(host, conn)
|
|
|
|
log.Printf("Added %s device %s (%s) at %s:%d", sanitizeLog(source), sanitizeLog(info.Name), sanitizeLog(info.Type), sanitizeLog(host), port)
|
|
}
|
|
|
|
// DiscoverDevices runs an mDNS/UPnP sweep and registers any found
|
|
// devices via AddDeviceByHost. Used by the startup goroutine in main
|
|
// and by the /api/discover route inside Mount.
|
|
func (app *WebApp) DiscoverDevices(ctx context.Context, discoveryService *discovery.UnifiedDiscoveryService) {
|
|
log.Println("Starting device discovery...")
|
|
|
|
devices, err := discoveryService.DiscoverDevices(ctx)
|
|
if err != nil {
|
|
log.Printf("Discovery failed: %v", err)
|
|
app.BroadcastDiscoveryStatus("failed", app.DeviceCount())
|
|
|
|
return
|
|
}
|
|
|
|
log.Printf("Found %d devices", len(devices))
|
|
|
|
for _, device := range devices {
|
|
app.AddDeviceByHost(device.Host, device.Port, "discovered")
|
|
}
|
|
}
|