Helmet 8 adds script-src-attr: 'none' by default which blocks ALL
inline event attribute handlers (onclick, onchange, etc.) regardless
of script-src unsafe-inline. This silently broke every onclick button:
copy, read aloud, nextcloud upload, generate, record, etc.
- CSP connectSrc was blocking service worker re-fetches to cdnjs.cloudflare.com
causing Font Awesome icons to go blank (settings, logout, nextcloud buttons)
- Add cdnjs, googleapis, gstatic, google to connectSrc to fix icon rendering
and Chrome Web Speech API (which connects to Google servers for TTS voices)
- Add vendor model Opus 4.6 and vendor model Sonnet 4.6 to all three provider lists
(OpenRouter, Bedrock, Azure-compatible); Sonnet 4.6 now default for Bedrock
- speakText: revert async ElevenLabs fetch chain — browser requires
speechSynthesis.speak() to be called synchronously within user gesture;
async .catch() context caused silent failure across browsers
- copyText: fix fallback that always showed 'Copied!' even when it failed;
now shows real error message, uses selectNodeContents for accuracy,
handles missing clipboard API gracefully
- Switch speakText() to call /api/text-to-speech backend (ElevenLabs) with fallback to native speechSynthesis
- Upgrade ElevenLabs voice from Rachel to Adam (pNInz6obpgDQGcFmaJgB) — warmer, more professional
- Upgrade model from eleven_monolingual_v1 to eleven_turbo_v2_5 for better quality and lower latency
- Enable Helmet CSP (scripts/styles/fonts/connect restricted to self + CDNs)
- Lock CORS to APP_URL origin in production (open in dev)
- Reduce JSON body limit from 50mb to 1mb
- Add per-route rate limits: login 10/15min, register 5/hr, forgot-pw 5/hr
- Add README with full setup, Docker Hub, provider switching, env reference
- Bump version to 3.0.0