Commit Graph

5 Commits

Author SHA1 Message Date
larssand
e8a2799a92 feat(audio): add offline local neural voice via Piper (sv + en)
Announcements can use Piper, a free local neural TTS, instead of the browser's system
voice. No account, no paid service, and it keeps working with no internet at the track.

- npm run tts:install (or Settings -> Audio -> Install) downloads the standalone Piper
  release for Linux/Windows/macOS plus Swedish and English voices into piper/ once
- server/tts.js generates each line once, one at a time, and caches it as WAV under
  data/tts/; a new line takes ~0.3 s with the standalone build
- src/piper_speech.js plays it and falls back to the browser voice if Piper is missing,
  errors, or takes over 2.5 s, so no announcement is lost and timing is never held up
- "Pre-generate phrases and driver names" renders every fixed phrase and name in both
  languages before race day

Browser voice stays the default. Generation routes fall under the admin PIN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 19:28:15 +02:00
larssand
9016ce02e4 feat(auth): add optional admin PIN for all API writes
Off by default. Once a PIN is set in Settings -> System & backup, every non-GET /api/*
request (plus GET /api/ammc/config) needs a signed 30-day HttpOnly cookie, which also
closes the unauthenticated /api/update/run restart trigger. A 401 opens a PIN dialog
and the pending save is retried after login. Reads stay open because the public overlay
hydrates through GET /api/state. Optional RC_ADMIN_ALLOWED_CIDRS restricts the same
routes by client address.

The PIN hash and signing secret live in data/, outside the app_state blob, so they
never leak through GET /api/state, exports or backups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:14:58 +02:00
larssand
ae445097b0 Re-run the security audit against everything shipped since 2026-08-28
npm audit stays clean (0 vulnerabilities). Checked every new db.prepare()/spawn()/
execFileSync() call added since the last audit for injection risk - none found, all
parameterized SQL and array-form process args. Confirmed the CORS/security-header
middleware still covers every route added since, including the new ones.

One new notable finding: POST /api/update/run unconditionally stops the server before
checking whether an update is even available, making it a more direct denial-of-service
primitive than the app's other already-documented unauthenticated endpoints. No code
change made - tracked alongside the deferred permissions/auth work.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 20:22:31 +02:00
larssand
375bfb2416 förbättreing tränings 2026-08-28 21:44:23 +02:00
larssand
c6262aceab fix live leaderbord details 2026-08-28 21:12:43 +02:00