Audit fixes: security hardening, Room migrations, CI/CD, codecs, debt cleanup#1
Merged
Conversation
…ding bugs, web + electron robustness
cloudflare-config/worker.js:
- opt-in protectReads per MAC: GET /api/config/:mac requires ?password= when enabled (dashboard toggle, session+CSRF)
- fail-closed session secret (500 if SESSION_SECRET/ADMIN_PASSWORD missing)
- constant-time compares for session/CSRF/password/token checks
- exponential login lockout backoff, JSON.parse lockout guard
- CSRF on raw-JSON POST /api/config/:mac
- Referrer-Policy + nosniff headers; CRASH_TOKEN documented
android-native:
- Room: exportSchema=true, schemaLocation, destructive fallback limited to v1-9 (no more DB wipe on future bumps)
- fix VOD resume race (prepareResume now suspend, seekTo gets real value)
- RecordingWorker: cancelled no longer overwritten by done; retryable vs terminal failures ("error" status, surfaced in UI)
- replace runBlocking in PlayerScreen composition with produceState (ANR)
- HlsRecorder: dedupe by media-sequence index (sliding playlist gaps + unbounded memory)
- ReminderReceiver: goAsync + scoped job instead of GlobalScope
- UpdateChecker: verify .sha256 sibling asset when published; drop dead versionCodeNormalised
web:
- fix series whitelist bug (dead vodCats overwrite) — extracted filterCategories helpers + tests
- top-level ErrorBoundary with TV-friendly fallback wired to diag buffer
- proxy worker default-deny (ALLOWED_HOSTS mandatory)
- EPG gzip magic-byte sniff + tests (vitest 9/9, tsc clean)
electron:
- validate URL scheme before shell.openExternal (http/https only)
- did-fail-load / render-process-gone / unresponsive fallback page
- scope header rewriting to http(s), document webSecurity tradeoff
- dev script sets SV_DEV via cross-env
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…web credential hygiene, debt cleanup cloudflare-config/worker.js: - PBKDF2-SHA256 (100k iters, versioned pbkdf2$<iters>$<hex> format) replaces single-pass SHA-256 - backward compat: legacy hashes verified then transparently re-hashed on login - min password length 4 -> 8 (signup, change, UI hints, README) CI/CD + versioning: - VERSION file as single source; build.gradle.kts derives versionName + versionCode (10029) - .github/workflows/ci.yml: web (tsc+vitest), android (compile+unit tests), workers (node --check) - .github/workflows/release.yml: tag==VERSION gate, ULTRA_* secrets with debug fallback, publishes UltraTV-debug.apk + .sha256 electron: - switch to castlabs fork pinned via GitHub tag v33.4.11+wvcus (HEVC/AC3/EAC3/Widevine); npm registry alias doesn't work (404) and semver ignores +wvcus metadata - electron/README.md (codecs, EVS signing notes, icon generation); build/ buildResources un-ignored web: - stop persisting Xtream credentials in stored stream URLs; URLs rebuilt at play time from provider record (backup exports no longer leak credentials); 9 new URL-builder tests (vitest 18/18, tsc clean) - remove dead proxy code (proxiedStreamUrl, getProxy, LEGACY_DEFAULTS) android-native: - StalkerClient: session token cached per provider (5 min TTL, invalidated on auth failure) — no more handshake on every zap - RemoteLog URL/token moved to BuildConfig fields (gradle prop/env overridable) - Search result opens the channel via the same player route as Live - remove unused Retrofit deps; drop redundant usesCleartextTraffic manifest flag android-app: marked DEPRECATED (README), dead Firebase wiring + boilerplate tests removed Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dlew Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Résumé
Audit complet multi-agents (5 sous-systèmes + sécurité/bugs/release) puis implémentation en deux phases. 61 fichiers, ~1500 lignes.
Sécurité (cloudflare-config/worker.js)
GET /api/config/:macpeut exiger?password=(toggle dashboard) — lectures anonymes préservées par défautReferrer-Policy/nosniffBugs critiques (android-native)
exportSchema=true+ fallback destructif limité aux v1-9 — fini le wipe DB (favoris/historique) à chaque bump de schémacancelled/errorcorrect,runBlockingretiré du player (ANR), HlsRecorder dédupliqué par media-sequence, updater vérifie le.sha256publiéCI/CD + versioning
VERSION= source unique (gradle dérive versionName/versionCode)ci.yml(web tsc+vitest · android compile+tests · workers syntax) ;release.yml(gate tag==VERSION, secrets ULTRA_*, publie APK + sha256)Web / Electron
v33.4.11+wvcus(HEVC/AC3/Widevine), validation schemeopenExternal, fallback crash/load, script dev réparéDivers
Vérification
tsc --noEmitclean, vitest 18/18node --checkOKandroidde cette PR fait foi🤖 Generated with Claude Code