"""Password hashing — bcrypt. Standalone (no app imports) to avoid cycles.""" from __future__ import annotations import bcrypt def hash_password(plain: str) -> str: # bcrypt has a 72-byte input limit; truncate defensively raw = plain.encode("utf-8")[:72] return bcrypt.hashpw(raw, bcrypt.gensalt()).decode("utf-8") def verify_password(plain: str, hashed: str) -> bool: if not hashed: return False try: return bcrypt.checkpw(plain.encode("utf-8")[:72], hashed.encode("utf-8")) except (ValueError, TypeError): return False