import hashlib
import secrets
from datetime import UTC, datetime, timedelta
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
from .config import settings
password_hasher = PasswordHasher()
def hash_password(password: str) -> str:
return password_hasher.hash(password)
def verify_password(password: str, password_hash: str) -> bool:
try:
return password_hasher.verify(password_hash, password)
except VerifyMismatchError:
return False
except Exception:
return False
def generate_session_token() -> str:
"""Opaque bearer/cookie credential. Only its sha256 is stored."""
return secrets.token_urlsafe(32)
def hash_token(token: str) -> str:
return hashlib.sha256(token.encode()).hexdigest()
def session_expiry(client: str) -> datetime:
days = settings.extension_session_ttl_days if client == "extension" else settings.web_session_ttl_days
return datetime.now(UTC) + timedelta(days=days)
SESSION_COOKIE_NAME = "ltt_session"