mirror of
https://github.com/Heretek-Games/drop-seedbox.git
synced 2026-10-12 02:05:36 +00:00
main
Declares the storage:depot capability and registers a DepotStorageProvider that resolves a mapped game's seedbox content to an HTTP range stream on the selected enabled depot endpoint (lowest priority wins; explicit depot id supported), attaching an optional static Authorization header. This is the plugin half of remote depot consumption; the core depot/chunk pipeline follow-up will consume the resolved stream.
drop-seedbox
qBittorrent WebUI integration plugin for the Drop game distribution platform, built on @droposs/plugin-sdk (^0.4.0).
Maintained by Heretek Games.
Status
Implemented
- qBittorrent WebUI v2 client (
src/qbittorrent.ts):POST /api/v2/auth/loginwith explicit failures for missing credentials, non-OK responses, rejected logins, and missing session cookies.GET /api/v2/torrents/infowith configurable timeout (AbortSignal.timeout, default 10s), typed errors, exponential backoff for transient failures (timeouts, network errors, 5xx), and one-shot re-login when the session expires (401/403).POST /api/v2/torrents/add(magnet/URL as form data,.torrentas multipart),pause/resume/deleteactions, andGET /api/v2/transfer/info.checkHealth()connection probe (reachability, authentication, latency) that never throws.
- Plugin routes (
src/index.ts):POST /config— authenticated; validates the WebUIbaseUrl(absolutehttp(s), no embedded credentials, loopback/link-local hosts rejected by default), storesbaseUrl/credentials (encrypting the password, see below), and resets cached sessions.GET /torrents— authenticated; returns{ torrents }or a typed{ error, code }response; client failures never surface as unhandled rejections.POST /torrents— authenticated; adds a torrent from a magnet/URL or base64.torrent(url,torrentFile,torrentFileName,savePath,category,paused).POST /torrents/:hash/pause,POST /torrents/:hash/resume,DELETE /torrents/:hash— authenticated;deleteFilesis honored on delete.GET /transfer— authenticated; global transfer statistics.GET /health— authenticated; connection health probe (reachability, authentication, latency) that never throws.GET/POST /depots,DELETE /depots/:id— authenticated registry of remote/seedbox depot endpoints with per-depot enable/disable and priority.POST /mappingsandGET /mappings,GET /mappings/:gameId— authenticated; associate a torrent hash or content path with a Drop game.
seedbox:progressWebSocket channel — authenticated users only (subscription authorizer + per-messageuserIdgate). Subscribers receive an immediate torrent snapshot, then periodic snapshots (default 15s) broadcast on the channel.{"type":"unsubscribe"}stops updates;{"type":"ping"}replies withpong.
Roadmap (not implemented yet)
The repository name and earlier docs referenced remote streaming depots and game-library integration. Those features do not exist yet:
- Remote / mountable streaming depots (Heretek-Games/drop-seedbox#3, #4) — the depot registry, health probe and validation exist, but no torrent-backed chunk backend
- Play-while-download streaming (Heretek-Games/drop-seedbox#5)
- SSRF request rate limiting (Heretek-Games/drop-seedbox#6) — scheme/host validation, embedded-credential rejection, and loopback/link-local host blocking are implemented; RFC1918/ULA LAN hosts remain allowed by design, and throttling is not implemented
- Admin UI (Heretek-Games/drop-seedbox#7 — the health/depot monitoring backend is in place; a rendered admin page is not)
Progress updates are polled snapshots of the torrent list, not byte-level or per-peer real-time telemetry.
Security invariants
- Credentials and session cookies (
SID) are never logged. Error messages and log lines contain only status codes and error classifications. - Every route (
/config,/torrents,/transfer,/health,/depots,/mappings) requires an authenticateduserId; unauthenticated callers receive{ error, code: "unauthorized" }. - The qBittorrent password is never persisted in plaintext. Set
DROP_SEEDBOX_CONFIG_KEY(32 bytes as 64 hex characters or base64) to enable credential storage;POST /configrefuses to store a password without it. Stored passwords are encrypted with AES-256-GCM, and legacy plaintext rows are re-encrypted in storage on first read once the key is configured. baseUrlmust be an absolutehttp(s)URL without embedded credentials. Loopback (127.0.0.0/8,::1,localhost) and link-local (169.254.0.0/16,fe80::/10) hosts are rejected; setSEEDBOX_ALLOW_LOOPBACK=trueto opt in to loopback test setups. RFC1918 and ULA (fc00::/7) LAN hosts remain allowed, since LAN seedboxes are the primary use case.- Outbound requests send a
Referer/Originmatching the WebUI host (required by some qBittorrent CSRF configurations). seedbox:progresssubscriptions require an authenticateduserId; anonymous subscribers are rejected by the registered subscription authorizer and by the handler.- Outbound requests are bounded by a per-request timeout and retried with backoff so unreachable seedboxes cannot pin handlers indefinitely.
Development
npm ci
npm run build
npm test
npm run typecheck
CI runs the same commands on Node 22 (.github/workflows/ci.yml).
Description
Seedbox: qBittorrent WebUI integration and remote streaming depots plugin for Drop
165 KiB
Languages
TypeScript
94.9%
JavaScript
5.1%