from datetime import datetime, timedelta, timezone import bcrypt from jose import JWTError, jwt from app.core.config import settings def verify_password(plain: str, hashed: str) -> bool: if not plain or not hashed: return False try: return bcrypt.checkpw(plain.encode("utf-8"), hashed.encode("utf-8")) except (ValueError, TypeError): return False def hash_password(password: str) -> str: return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8") def create_access_token(subject: str) -> str: expire = datetime.now(timezone.utc) + timedelta(minutes=settings.access_token_expire_minutes) payload = {"sub": subject, "exp": expire} return str(jwt.encode(payload, settings.secret_key, algorithm=settings.algorithm)) def decode_token(token: str) -> str | None: try: payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm]) sub = payload.get("sub") return str(sub) if sub is not None else None except JWTError: return None