3 Commits
Author SHA1 Message Date
m3ta-chironandClaude Fable 5.1 85fa64cfe6 refactor: switch the whole project to English
talk is going to be published. Code comments, CLI output, error messages,
daemon log lines, MCP descriptions and results, test names and assertions,
README, spec, skill, build scripts and flake are now English. Only the
spoken announcement texts stay bilingual: the wrap result and the test
sentence are German or English depending on the detected language.

Language fallback is now configurable: `lang = "en" | "de"` (env
TALK_LANG, default en) is used when detection cannot tell (numbers, single
words, ties) and for talk's own announcements. langdetect.Detect takes the
fallback as an argument instead of hard-coding German. `talk setup` asks for
it; `talk doctor` and `talk status` show it.

Vocabulary pinned across packages so the process-boundary tests observe
stable strings: chain log lines ("chain: tier X skipped (not available)",
"falling back to the next tier", "spoken via X"), queue lines ("discarded:
quiet hours ... active", "replaced by toast", "max_age"), CLI notes
("speaking directly", "daemon started at", "no daemon", "nothing to cancel"),
status block with aligned English labels, MCP messages, origin guard 403.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-24 11:15:35 +02:00
m3ta-chironandClaude Fable 5.1 46bd507fd8 fix(api): Origin-Guard — Browser erreichen nur POST /speak von gelisteten Origins
CORS allein verhindert nur das Lesen der Antwort, nicht die Wirkung: Ein
POST mit text/plain-Body oder ein Formular-POST geht ohne Preflight raus,
und talkd hat den Body trotzdem als JSON gelesen bzw. /mute, /cancel und
/mcp ohne Body ausgeführt. Jede Webseite konnte so sprechen, muten und
abbrechen.

Neue Middleware vor dem Router: Anfragen mit Origin-Header kommen nur als
OPTIONS /speak (Preflight, ohne Wirkung) oder POST /speak von gelisteter
Origin durch; alles andere ist 403, bevor ein Body gelesen wird. CLI, curl
und MCP-Clients senden keinen Origin und sind nicht betroffen.

Prozesstests angepasst (ungelistete Origin auf /speak → 403, Steuer-
Endpunkte aus dem Browser → 403) und TestBrowserKannNichtSteuern ergänzt,
der den Angriff mit simple requests durchspielt und prüft, dass weder
Provider noch Mute-State berührt werden.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-24 09:35:45 +02:00
m3ta-chiron 156c20dbb3 feat(api): CORS-Tür für POST /speak — OPTIONS-Preflight und ACAO aus Config
OPTIONS /speak beantwortet Preflights mit 204 + Allow-Headers/Methods/Max-Age,
wenn die Origin in server.allowed_origins steht; ungeliste Origins und leere
Liste bekommen keine CORS-Header (Browser blockt). Nur /speak, kein anderer
Endpunkt. /status ergänzt additiv cors:[origins] (immer vorhanden, [] wenn zu).
2026-10-18 20:06:05 +02:00