"""Password hashing and JWT token handling (stdlib-only PBKDF2, no bcrypt deps).""" import datetime import hashlib import hmac import os import jwt from .config import SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES _ITERATIONS = 200_000 def hash_password(password: str) -> str: salt = os.urandom(16) digest = hashlib.pbkdf2_hmac("sha256", password.encode(), salt, _ITERATIONS) return f"{salt.hex()}${digest.hex()}" def verify_password(password: str, stored: str) -> bool: try: salt_hex, digest_hex = stored.split("$") except ValueError: return False digest = hashlib.pbkdf2_hmac("sha256", password.encode(), bytes.fromhex(salt_hex), _ITERATIONS) return hmac.compare_digest(digest.hex(), digest_hex) def create_access_token(user_id: str) -> str: payload = { "sub": user_id, "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES), } return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM) def decode_access_token(token: str) -> dict: return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])