from datetime import datetime, timedelta, timezone import jwt from pwdlib import PasswordHash from app.core.config import get_settings _password_hash = PasswordHash.recommended() # argon2id ALGORITHM = "HS256" def hash_password(password: str) -> str: return _password_hash.hash(password) def verify_password(plain: str, hashed: str) -> bool: return _password_hash.verify(plain, hashed) def create_access_token( subject: str, expires_delta: timedelta | None = None, extra_claims: dict | None = None, ) -> str: settings = get_settings() expire = datetime.now(timezone.utc) + ( expires_delta or timedelta(minutes=settings.access_token_expire_minutes) ) payload = {"sub": subject, "exp": expire} if extra_claims: payload.update(extra_claims) return jwt.encode(payload, settings.secret_key, algorithm=ALGORITHM) def decode_access_token(token: str) -> dict | None: settings = get_settings() try: return jwt.decode(token, settings.secret_key, algorithms=[ALGORITHM]) except jwt.PyJWTError: return None