Introduces a secure peer-to-peer cache sharing system using HMAC-SHA256 request signatures and Fernet (AES-128-CBC) response encryption.
- New peer_keys table for per-peer credential management (key_id, secret)
- New /api/peer/check endpoint returns encrypted debrid availability data
- New /api/peer/items endpoint returns encrypted torrent metadata
- Rate limiting per peer key with configurable limits and windows
- Admin UI for creating, viewing, revoking, and deleting peer keys
- Peer cache enrichment integrated into BaseDebrid L2.5 lookup pipeline
- StremThruDebrid override with cross-service PG L2 check + peer cache
- Removed old /api/share/cache endpoint (replaced by /api/peer/*)
- Added cryptography package dependency
BREAKING CHANGE: The /api/share/cache endpoint has been removed and replaced with /api/peer/check. Clients must update to use HMAC authentication with X-Peer-Key-Id, X-Peer-Timestamp, and X-Peer-Signature headers.
Async correctness:
- Wrap blocking time.sleep/requests.get calls with asyncio.to_thread()
in torrent_service.py and torr9_service.py
- Run cache_container_items() as fire-and-forget background task via
asyncio.create_task(asyncio.to_thread(...)) in search/views.py
- Make RDTokenManager.get_access_token() and new_access_token() async,
replace requests.post with aiohttp (token_manager.py)
- Make RealDebrid.get_headers() async, await all callers (realdebrid.py)
Security:
- Remove API key, device code, and PIN values from log output
(auth/views.py, admin/views.py)
- Add WARNING on startup when SESSION_KEY uses the insecure default
value (settings.py)
- Make admin template dir configurable via settings.admin_template_dir
Performance:
- Parallelize TMDB metadata fetches with asyncio.gather() (catalog/views.py)
- Add tmdb_language setting instead of hardcoded "fr-FR"
Deduplication:
- Extract ensure_uuid() to stream_fusion/web/api/utils.py
- Extract get_client_ip() to stream_fusion/web/utils.py
- Replace 8-way if/elif debrid factory with _SERVICE_MAP dict +
_build_service() helper (get_debrid_service.py)
- Extract _model_to_schema() in APIKeyDAO to remove 6 repeated blocks
- Simplify ProxyStreamer: remove manual BytesIO buffer, stream directly
via iter_any() (stream/views.py)
Inspired by commits 823bc77 and e306eb5 from limedrive/develop.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>