continuous-integration/drone/push Build encountered an error
Input handling: - uploadLogo: client file name reduced to a safe base name with an image extension (path traversal and arbitrary-extension writes closed). - extractZIP: zip-slip guard; entries that resolve outside the target are refused. Per-entry closes no longer pile up as defers. - ffmpeg.path / vlc.path must be an existing regular file named ffmpeg, vlc or cvlc, checked both when saved and right before exec. - Stream URLs passed to the external buffer must use a network scheme (http, https, rtsp, rtmp, rtp, udp, mms); file:, concat:, pipe: are refused. - /download/ (backups with settings.json and authentication.json) requires the web session when web authentication is enabled. - settings.json is written 0600; the Plex token is masked in every payload sent to the UI and the mask round-trips as "unchanged" on save. Authentication: - Passwords are stored with bcrypt. Existing HMAC-SHA256 records still verify (constant time) and are re-hashed on the first successful login. Username lookups compare in constant time. - URL (?username=&password=) and HTTP Basic authentication verify the credentials per request via AuthenticateUser and no longer create a session token, which removes the unbounded token growth under Plex polling. Expired sessions are evicted whenever a new one is created. - createFirstUserForAuthentication and checkAuthorizationLevel now return real errors instead of calling no-op closures. Tests: src/security_test.go and src/internal/authentication/ authentication_test.go cover each of the above.
6.5 KiB
6.5 KiB
xTeVe improvement checklist
Detailed rationale, file references and effort estimates: tasks/improvement-plan.md.
Status: Phase 0 committed on branch improvements 2026-09-26.
Phase 0: Hygiene
.gitignore(.gocache/), deleted.gocache/, extended.dockerignoreagent.md/skill.mdgit-ignored and docker-ignored (left in place)- Version drift fixed (
xteve.gonow 0201) and Drone drift check added - Auto-updater deleted (
BinaryUpdate,internal/up2date,GitHub/Updatestructs,xteveAutoUpdate+update.urlsettings, UI rows,en.json); migrations kept inmigrate.go;kardianos/osextgone go 1.27.1; Dockerfile and Drone golang images pinned to 1.27.1- Four
go vetunreachable-code warnings fixed (vet clean) - staticcheck baseline via
go run honnef.co/go/tools/cmd/staticcheck@latest ./...: 408 findings (S1002 113, SA5008 79, S1039 67, S1038 40, S1023 35, ST1005 20, SA1019 14, SA4006 9, misc 11). Mostly style; SA5008/SA4006/SA1019 worth a pass in Phase 3 cleanup
Phase 1: Security
textContentfor provider-controlled strings (cells, client info, in-place edits, logs, popup descriptions with an explicit static-HTML flag)- Websocket uses gorilla's same-origin check; token read from the HttpOnly cookie (query param kept for legacy clients); payload/token console logging removed. Tests in
src/websocket_test.go - Cookie
HttpOnly,SameSite=Strict,Path=/, cleared on logout - Wizard GET no longer mutates
AuthenticationWEB; the wizard page just bypasses login while active uploadLogofilename sanitised (base name, image extensions only)- Zip-slip guard in
extractZIP(also no more defer-in-loop there) ffmpeg.path/vlc.pathmust be a regular file named ffmpeg/vlc/cvlc; stream URLs handed to the external buffer must use a network scheme/download/requires the web session when web auth is on- [~] Host-header-derived URLs kept by design (LAN, many interfaces; URLs must match how the client reached the server)
- bcrypt for new passwords and credential changes; legacy SHA256 records verified in constant time and upgraded on first login; username compare constant-time
- Expired tokens evicted on every new session; URL/Basic auth no longer mint tokens at all (
AuthenticateUser) - [~] Not applicable: xTeVe has no roles, every web user is an administrator by design (documented in README security notes)
settings.jsonwritten 0600; Plex token masked in every payload to the UI, mask round-trips as "unchanged" on save- Decide default for web auth on fresh installs (keep off; LAN only, decided 2026-09-25)
Phase 2: Streaming stability
- Race tests: two concurrent tuners against a fake TS server, run with
-race *Playlistwith own mutex; remove stale store-backs- Atomic tuner reservation; clean
BufferClientson force kill - RWMutex around
StreamingURLS - Remove
deferinside read loops (buffer, compression, imgcache) - Single external-process buffer (
exec.CommandContext+ request context) with ffmpeg and VLC argument builders; dropCloseNotifier - Real mutex for screen log
http.Serverwith timeouts; timeouts on all outbound clients- imgcache: download outside the lock
- Atomic write helper (temp + fsync + rename)
- Fix listed concrete bugs (xepg append, range mutation, log overflow, headers after WriteHeader, random notification eviction, unchecked assertions, API double write, WS struct reuse)
- Error hygiene: no-op closures,
os.Exit/panicoutside main, ignored results
Phase 3: Build, embed, CI, Docker
//go:embedviahtml/embed.go; deletedwebUI.go,html-build.go,cmd/webui-gen; ETag + Cache-Control on static assets- i18n dropped: 254 placeholders inlined,
en.jsondeleted, only HTML pages templated (authenticationErr) package.json+ts/tsconfig.json(tsc 5.9.3, ES2020, single outFilehtml/js/app.js, committed, CI-verified); 10 dead JS files deleted; 6 tsc errors fixed incl. a real ASI bug in the search shortcut- CI: vet, gofmt check, staticcheck v0.8.1 (config in
staticcheck.conf), bundle freshness check.go test -racestill to add once tests exist - Version-tagged images (amd64 only)
- PUID/PGID via su-exec at runtime; static-ffmpeg pinned to 7.1.1;
VOLUME /xteve/config;/xteveremoved fromLEGACY_CONFIG_DIRS; compose files pull from the registry and document SSDP/host networking /healthzendpoint; Dockerfile healthcheck uses itREADME-DEV.mdand fork-specificREADME.md(about, container usage, env vars, security notes)- staticcheck 399 -> 0; dead code and duplicates removed;
ioutil/rand.Seedgone. Real bugs fixed on the way: leaked file handle per ffmpeg segment, uncheckedhttp.NewRequest, migration writingnullxepg.json, silent user-write failures, unwritable config/temp dir now fatal at start - Resolve missing
docs/design-system/referenced byagent.md(user decision: agent.md is a personal, git-ignored file)
Phase 4: Data model and performance
Not planned (lineup is ~170 channels, decided 2026-09-25). See plan for the reference list.
Phase 5: Frontend architecture
- Persistent websocket with request IDs, queue, backoff reconnect
- Section-level re-render instead of full
createLayout() - Virtualised mapping table
- Split
menu_ts.ts;addEventListener; data-driven settings rows - Accessibility follow-ups; light theme via
prefers-color-scheme - Consolidate CSS layers
Phase 6: Optional features
- Regex filters
- Per-playlist tuner limit and buffer choice
- Bulk channel edit
- Versioned backup/restore
- Dummy EPG durations
Review
Phase 0 (2026-09-26, branch improvements)
go build,go vet,go test ./...all clean.src/webUI.goregenerated.- Smoke run against an empty config dir on port 34499:
/web/,/lineup_status.json,/discover.jsonall 200, no errors logged. - Not verified locally: Docker image build (no daemon on this machine); Drone will cover it.
- Compiled JS in
html/js/was hand-edited to mirror the TS change because a currenttscdoes not reproduce the committed output (different shim, 5 type errors inmenu_ts.ts). Phase 3 replaces this with a pinned toolchain. html/js/menu.jsstill mentionsxteveAutoUpdate; it is one of the ten dead legacy files scheduled for deletion in Phase 3.Settings.Branch(git.branch) was kept: it still drives whether the build number is shown in the UI and XMLTV header.