mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 00:56:16 +00:00
fix(web): trust service CA and send a known target for TTS
soundtouch-web's "Speak" feature proxies to the AfterTouch service's /setup/tts/speak endpoint. Two issues blocked it end to end. 1. TLS: the proxy used http.DefaultClient, which trusts only system roots, so the HTTPS call to a service using its own self-signed CA failed with "x509: certificate signed by unknown authority". Add a --service-ca flag (SERVICE_CA env) that loads the CA PEM, appends it to the system pool, and uses a custom client for the TTS call. 2. Target: soundtouch-web sent device.Client.Host() (a full base URL like http://ip:8090), but the service's SSRF guard exact-matches the target against bare datastore IPs, returning "host ... is not a known device". Prefer the device ID (the canonical key) and send a bare-IP host fallback. Also normalize the incoming host in resolveTTSHost so a URL/host:port form still resolves; it still only ever returns a datastore IP, so the SSRF guarantee is unchanged. Adds unit tests for the CA client builder, hostOnly, and resolveTTSHost (including the preserved unknown-host/device rejections). Documents --service-ca in the soundtouch-web README and TROUBLESHOOTING guide. Wires SERVICE_URL and SERVICE_CA (empty defaults) into the Raspberry Pi install-web.sh env file and documents them in the Pi guide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7051793e81
commit
d94b1bc067
@@ -161,6 +161,8 @@ PORT=8080
|
||||
BIND_ADDR=
|
||||
DISCOVERY_INTERFACE=
|
||||
SOUNDTOUCH_DEVICES=
|
||||
SERVICE_URL=
|
||||
SERVICE_CA=
|
||||
```
|
||||
|
||||
`SOUNDTOUCH_DEVICES` accepts a comma-separated list of IP addresses for manual
|
||||
@@ -171,6 +173,22 @@ network:
|
||||
SOUNDTOUCH_DEVICES=192.0.2.1,192.0.2.2
|
||||
```
|
||||
|
||||
`SERVICE_URL` links `soundtouch-web` to your `soundtouch-service` instance,
|
||||
which is required for Text-to-Speech ("Speak"). When the service is served
|
||||
over HTTPS with its own self-signed certificate (the default), also set
|
||||
`SERVICE_CA` to that CA certificate, or the proxied TTS call fails with
|
||||
`x509: certificate signed by unknown authority`. The CA is the service's
|
||||
`<dataDir>/certs/ca.crt` (also downloadable from `GET /setup/ca.crt`). For
|
||||
example:
|
||||
|
||||
```bash
|
||||
SERVICE_URL=https://soundtouch.local
|
||||
SERVICE_CA=/var/lib/soundtouch-service/certs/ca.crt
|
||||
```
|
||||
|
||||
With a plain `http://` `SERVICE_URL`, `SERVICE_CA` is unused (no TLS) and can
|
||||
be left empty.
|
||||
|
||||
After editing the env file:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -623,6 +623,52 @@ fmt.Printf("Current source: %s, status: %s\n",
|
||||
nowPlaying.Source, nowPlaying.PlayStatus)
|
||||
```
|
||||
|
||||
### ❌ soundtouch-web TTS fails with `certificate signed by unknown authority`
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
TTS service request failed: Post "https://soundtouch.fritz.box/setup/tts/speak":
|
||||
tls: failed to verify certificate: x509: certificate signed by unknown authority
|
||||
```
|
||||
|
||||
**Cause:** TTS synthesis and the Bose app key live in `soundtouch-service`,
|
||||
so `soundtouch-web` proxies the "Speak" action to the service. When the
|
||||
service is served over HTTPS with its own self-signed certificate (the
|
||||
default — see `GET /setup/ca.crt`), `soundtouch-web` doesn't trust that CA out
|
||||
of the box, so the proxied call fails verification.
|
||||
|
||||
**Solution:** start `soundtouch-web` with `--service-ca` pointing at the
|
||||
service's CA certificate (its `<dataDir>/certs/ca.crt`, or the file served at
|
||||
`/setup/ca.crt`):
|
||||
|
||||
```bash
|
||||
soundtouch-web \
|
||||
--service-url https://soundtouch.fritz.box \
|
||||
--service-ca /path/to/certs/ca.crt
|
||||
```
|
||||
|
||||
`SERVICE_CA` is the equivalent environment variable. The CA is appended to the
|
||||
system trust store, so a service URL that uses a publicly trusted certificate
|
||||
needs no flag.
|
||||
|
||||
### ❌ soundtouch-web TTS returns `host ... is not a known device`
|
||||
|
||||
**Symptoms:**
|
||||
```
|
||||
TTS service returned 400: {"error":"host http://192.0.2.10:8090 is not a known device"}
|
||||
```
|
||||
|
||||
**Cause:** the service only plays TTS on speakers it knows (an SSRF guard:
|
||||
the target is matched against the service's device datastore, never taken
|
||||
verbatim from the request).
|
||||
|
||||
**Solution:** make sure the target speaker is known to `soundtouch-service`
|
||||
(discovered or manually added, and migrated to AfterTouch), not only to
|
||||
`soundtouch-web`'s own discovery. Check with `GET /setup/devices` on the
|
||||
service. (Recent `soundtouch-web` versions identify the speaker by its device
|
||||
ID and a bare IP, so this error otherwise indicates the speaker simply isn't
|
||||
registered with the service.)
|
||||
|
||||
---
|
||||
|
||||
## 📡 **WebSocket Issues**
|
||||
|
||||
Reference in New Issue
Block a user