From 20f10004bf7b840f9b5a83f4b5e5ebc8b20a731f Mon Sep 17 00:00:00 2001 From: AK CHAVAN <90214281+iamakchavan@users.noreply.github.com> Date: Sat, 22 Aug 2026 19:42:22 +0530 Subject: [PATCH 1/7] feat(serve): built-in web remote UI with live SSE updates Serve a self-contained, zero-dependency web remote from torhunt serve. The shell (src/daemon/assets/ui.html) mirrors the TUI's Electric Cyan design language and works on desktop and mobile: add magnets or info hashes, watch live progress with per-torrent speed/peers/ETA, pause/resume/delete downloads, stop seeding, and browse the completed archive. Server side: new src/daemon/webui.ts holds the asset locator, the server-sent-event stream manager (initial snapshot + push-on-update + keepalive + self-cleanup), and an Origin-vs-Host cross-site guard for state-changing requests. serve.ts gains GET / and /ui (secretless HTML shell), token-authenticated GET /events (EventSource-friendly query-param token), and read-only GET /history; statusPayload now includes totalBytes/downloadedBytes/eta additively. The request handler is extracted into createServeHandler so tests can drive a real HTTP server against a fake runtime. The TUI is untouched. postbuild ships dist/ui.html beside the bundle; runServe delegates to the shared handler. 45 daemon tests pass (9 new webui unit tests, 10 new integration tests); full suite 348 green; typecheck clean. --- README.md | 2 +- scripts/postbuild.cjs | 8 +- src/daemon/assets/ui.html | 827 ++++++++++++++++++++++++++++++++++++++ src/daemon/serve.test.ts | 143 ++++++- src/daemon/serve.ts | 125 ++++-- src/daemon/webui.test.ts | 105 +++++ src/daemon/webui.ts | 107 +++++ 7 files changed, 1287 insertions(+), 30 deletions(-) create mode 100644 src/daemon/assets/ui.html create mode 100644 src/daemon/webui.test.ts create mode 100644 src/daemon/webui.ts diff --git a/README.md b/README.md index 46c918d..079abfb 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ torhunt files range-aware HTTP server for media streaming torhunt attach persistent tmux session for remote SSH usage ``` -Append `--daemon` to run `watch`, `serve`, or `files` as background processes. Run `torhunt --help` for all commands and flags. +Append `--daemon` to run `watch`, `serve`, or `files` as background processes. `torhunt serve` also ships a built-in **web remote**: open `http://127.0.0.1:9161/` in any browser (phone included) to add magnets, watch progress live, pause/resume, and manage seeding. Run with `--token` when exposing the port beyond loopback. Run `torhunt --help` for all commands and flags. ## Privacy & security diff --git a/scripts/postbuild.cjs b/scripts/postbuild.cjs index e28f88d..571eb0d 100644 --- a/scripts/postbuild.cjs +++ b/scripts/postbuild.cjs @@ -11,6 +11,12 @@ copyFileSync(src, dest); // The WebRTC fallback stub must ship beside cli.cjs, which resolves it via // __dirname when the node-datachannel binary is unavailable. copyFileSync(resolve(root, 'scripts/webrtc-stub.mjs'), resolve(root, 'dist/webrtc-stub.mjs')); +// The web remote's HTML shell ships beside the bundle; src/daemon/webui.ts +// loads it relative to the bundled entry at runtime. +copyFileSync( + resolve(root, 'src/daemon/assets/ui.html'), + resolve(root, 'dist/ui.html'), +); // On Windows chmod is effectively a no-op, and npm re-applies bin permissions on install anyway, so a failure // here shouldn't fail the build, but warn rather than swallow the error. @@ -20,4 +26,4 @@ try { console.warn('postbuild: could not set executable bit on dist/cli.cjs:', err.message); } -console.log('postbuild: wrote dist/cli.cjs and dist/webrtc-stub.mjs'); +console.log('postbuild: wrote dist/cli.cjs, dist/webrtc-stub.mjs and dist/ui.html'); diff --git a/src/daemon/assets/ui.html b/src/daemon/assets/ui.html new file mode 100644 index 0000000..bbf0003 --- /dev/null +++ b/src/daemon/assets/ui.html @@ -0,0 +1,827 @@ + + +
+ + +This daemon requires an access token.
Start it with: torhunt serve --token …