hamzabhatti/Todo-fullstack-web
0
1"""2Authentication Utilities3 4Handles password hashing, JWT token creation and verification.5"""6 7from datetime import datetime, timedelta8from jose import JWTError, jwt9from passlib.context import CryptContext10from typing import Optional11import os12from dotenv import load_dotenv13 14load_dotenv()15 16# Password hashing context17pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")18 19# JWT configuration20SECRET_KEY = os.getenv("JWT_SECRET_KEY", "your-secret-key-here-min-32-chars-change-in-production")21ALGORITHM = os.getenv("JWT_ALGORITHM", "HS256")22ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "30"))23 24 25def verify_password(plain_password: str, hashed_password: str) -> bool:26 """27 Verify a plain password against a hashed password.28 29 Args:30 plain_password: The plain text password31 hashed_password: The hashed password from database32 33 Returns:34 bool: True if password matches, False otherwise35 """36 return pwd_context.verify(plain_password, hashed_password)37 38 39def get_password_hash(password: str) -> str:40 """41 Hash a password using bcrypt.42 43 Args:44 password: The plain text password45 46 Returns:47 str: The hashed password48 """49 return pwd_context.hash(password)50 51 52def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:53 """54 Create a JWT access token.55 56 Args:57 data: Dictionary containing claims to encode in token58 expires_delta: Optional custom expiration time59 60 Returns:61 str: Encoded JWT token62 """63 to_encode = data.copy()64 if expires_delta:65 expire = datetime.utcnow() + expires_delta66 else:67 expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)68 69 to_encode.update({"exp": expire})70 encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)71 return encoded_jwt72 73 74def decode_token(token: str) -> dict:75 """76 Decode and verify a JWT token.77 78 Args:79 token: The JWT token to decode80 81 Returns:82 dict: The decoded payload83 84 Raises:85 JWTError: If token is invalid or expired86 """87 payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])88 return payload89 