RSS → ntfy bridge with modern web UI
build-and-push / docker (push) Has been cancelled

Features: feed CRUD, per-feed ntfy target (incl. private servers),
Telegram/webhook channels, keyword filters, image attachments,
per-feed intervals, OPML import/export, notification history & stats,
users with roles, admin alerts, RU/EN i18n, light/dark theme,
notification preview, history search, activity chart. Dockerized.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
dimon
2026-06-02 21:11:57 +08:00
commit bf52bc3079
28 changed files with 3396 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
"""Password hashing and session helpers.
Uses stdlib PBKDF2 so no native build dependencies are required.
"""
from __future__ import annotations
import hashlib
import hmac
import secrets
_ALGO = "sha256"
_ITERATIONS = 240_000
def hash_password(password: str) -> str:
salt = secrets.token_hex(16)
digest = hashlib.pbkdf2_hmac(
_ALGO, password.encode(), bytes.fromhex(salt), _ITERATIONS
).hex()
return f"pbkdf2_{_ALGO}${_ITERATIONS}${salt}${digest}"
def verify_password(password: str, stored: str) -> bool:
try:
scheme, iterations, salt, digest = stored.split("$")
if not scheme.startswith("pbkdf2_"):
return False
algo = scheme.split("_", 1)[1]
expected = hashlib.pbkdf2_hmac(
algo, password.encode(), bytes.fromhex(salt), int(iterations)
).hex()
return hmac.compare_digest(expected, digest)
except (ValueError, TypeError):
return False