fix: security and reliability improvements

- Switch HTTPServer to ThreadingHTTPServer (concurrent request handling)
- Replace SHA-256 password hashing with bcrypt (auth.py, database.py)
- Add bcrypt to Dockerfile
- Move qBittorrent env vars to config.py
- Move _booklore_token state out of config into booklore.py
- Remove dead fitness_token variable in command.py
- Fix OpenAI call to use default SSL context instead of no-verify ctx
- Log swallowed budget fetch error in dashboard.py
This commit is contained in:
Yusuf Suleman
2026-03-29 07:02:09 -05:00
parent 7cd81181ed
commit d9768547be
9 changed files with 39 additions and 31 deletions

View File

@@ -5,12 +5,12 @@ Platform Gateway — Booklore integration (book library manager).
import json
import time
from config import (
BOOKLORE_URL, BOOKLORE_USER, BOOKLORE_PASS,
BOOKLORE_BOOKS_DIR, _booklore_token,
)
from config import BOOKLORE_URL, BOOKLORE_USER, BOOKLORE_PASS, BOOKLORE_BOOKS_DIR
from proxy import proxy_request
# Mutable auth token state (not in config — config is for immutable values)
_booklore_token = {"access": "", "refresh": "", "expires": 0}
def booklore_auth():
"""Get a valid Booklore JWT token, refreshing if needed."""

View File

@@ -3,21 +3,18 @@ Platform Gateway — qBittorrent integration (download status).
"""
import json
import os
import urllib.request
import urllib.parse
from config import QBITTORRENT_HOST, QBITTORRENT_PORT, QBITTORRENT_USERNAME, QBITTORRENT_PASSWORD
def handle_downloads_status(handler):
"""Get active downloads from qBittorrent."""
qbt_host = os.environ.get("QBITTORRENT_HOST", "192.168.1.42")
qbt_port = os.environ.get("QBITTORRENT_PORT", "8080")
qbt_user = os.environ.get("QBITTORRENT_USERNAME", "admin")
qbt_pass = os.environ.get("QBITTORRENT_PASSWORD", "")
base = f"http://{qbt_host}:{qbt_port}"
base = f"http://{QBITTORRENT_HOST}:{QBITTORRENT_PORT}"
try:
# Login
login_data = urllib.parse.urlencode({"username": qbt_user, "password": qbt_pass}).encode()
login_data = urllib.parse.urlencode({"username": QBITTORRENT_USERNAME, "password": QBITTORRENT_PASSWORD}).encode()
req = urllib.request.Request(f"{base}/api/v2/auth/login", data=login_data)
with urllib.request.urlopen(req, timeout=5) as resp:
cookie = resp.headers.get("Set-Cookie", "").split(";")[0]