- Provider-controlled strings (channel names, groups, file names, log
lines, in-place mapping edits, client info) are rendered with
textContent instead of innerHTML. PopupContent.description() takes an
explicit isHTML flag that only the static help texts pass.
- Websocket: drop the always-true CheckOrigin so gorilla's same-origin
check applies; read the session token from the HttpOnly cookie sent with
the handshake (the ?Token= query parameter is still accepted for older
clients); the client no longer puts the token in the URL, rewrites the
cookie, or console-logs request/response payloads.
- Session cookie is HttpOnly, SameSite=Strict, Path=/, session-scoped
(expiry stays server side) and is cleared on logout.
- Serving the first-run wizard no longer sets Settings.AuthenticationWEB
to false; the wizard page simply bypasses login while it is active.
- Upgrade failures no longer write a second error response.
- Tests: src/websocket_test.go covers cross-origin refusal, same-origin
and no-Origin clients, missing/unknown/legacy tokens, and cookie flags.
Go:
- staticcheck 399 -> 0 with staticcheck.conf (style checks ST1000/1003/
1005/1016/1020/1021/1022 excluded; error strings are shown in the UI).
- io/ioutil and rand.Seed removed; CloseNotifier kept with a lint-ignore
until the Phase 2 context rewrite.
- Dead code deleted: Auto handler, getStreamByChannelID, updateXEPG,
indexOfInt, jsonToMapInt64, removeOldSystemData, randomTime, and the
commented-out blocks in struct-buffer.go and internal/authentication.
- Duplicates folded: cacheImagesInBackground(), one addErrorToStream().
- Bugs found by SA4006/SA5001: os.Create handle leaked per ffmpeg segment
(buffer.go), http.NewRequest error unchecked (buffer.go), xepg.json
migration wrote null on read error (migrate.go), WriteUserData errors
silently dropped (authentication.go), defer Close before error check
(buffer.go, toolchain.go). checkFilePermission results were discarded;
an unwritable config or temp dir is now fatal at start-up.
- gofmt applied repo-wide; Drone runs gofmt check and staticcheck.
Docker:
- Entrypoint starts as root, applies PUID/PGID (falls back to XTEVE_UID/
XTEVE_GID, then image defaults), fixes config ownership only when it
differs, then drops to xteve via su-exec. --user starts skip all of it.
- /xteve removed from LEGACY_CONFIG_DIRS (it is the parent of the default).
- mwader/static-ffmpeg pinned to 7.1.1; VOLUME /xteve/config.
- Compose files pull registry.coadcorp.com/nathan/xteve:latest, use
PUID/PGID/TZ, and explain that SSDP needs host networking.
- .dockerignore excludes the npm toolchain (bundle stays in html/js).
Docs: README rewritten for the fork (about, registry, compose, env vars,
security notes); README-DEV gains a container section.