""" Auth helpers: password hashing + cookie token hashing. We intentionally avoid heavy dependencies. Password hashing uses PBKDF2-HMAC-SHA256. Session tokens are random and stored server-side as SHA256(token) hashes. """ from __future__ import annotations import hashlib import secrets from typing import Optional, Tuple PBKDF2_ITERS = 200_000 def hash_password(password: str, salt_hex: Optional[str] = None) -> Tuple[str, str]: salt = bytes.fromhex(salt_hex) if salt_hex else secrets.token_bytes(16) dk = hashlib.pbkdf2_hmac("sha256", (password or "").encode("utf-8"), salt, PBKDF2_ITERS) return dk.hex(), salt.hex() def verify_password(password: str, password_hash: str, salt_hex: str) -> bool: cand, _ = hash_password(password, salt_hex=salt_hex) return cand == (password_hash or "") def new_session_token() -> str: return secrets.token_urlsafe(32) def hash_token(token: str) -> str: return hashlib.sha256((token or "").encode("utf-8")).hexdigest()