ruby2210/todo-manager
0
1from datetime import datetime, timedelta2import time3from typing import Optional4from jose import JWTError, jwt5from src.core.config import settings6from sqlmodel import Session7from src.models.task import Task8from fastapi import HTTPException, status9import bcrypt10 11 12def verify_token(token: str) -> Optional[dict]:13 """14 Verify JWT token from Better Auth using shared BETTER_AUTH_SECRET.15 """16 try:17 payload = jwt.decode(18 token, settings.BETTER_AUTH_SECRET, algorithms=[settings.JWT_ALGORITHM]19 )20 21 # Check if token is expired using UTC timestamp22 exp = payload.get("exp")23 if exp and exp < time.time():24 return None25 26 return payload27 except JWTError:28 return None29 except Exception:30 return None31 32 33def get_current_user_id(token: str) -> Optional[str]:34 """35 Extract user ID from JWT token.36 """37 payload = verify_token(token)38 if payload:39 # Extract user ID from token - typically stored as 'sub' or 'user_id'40 user_id = payload.get("sub") or payload.get("user_id")41 return user_id42 return None43 44 45def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):46 """47 Create access token.48 """49 to_encode = data.copy()50 now = time.time()51 if expires_delta:52 expire = now + expires_delta.total_seconds()53 else:54 expire = now + (settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60)55 56 to_encode.update({"exp": expire})57 encoded_jwt = jwt.encode(58 to_encode, settings.BETTER_AUTH_SECRET, algorithm=settings.JWT_ALGORITHM59 )60 return encoded_jwt61 62 63def verify_password(plain_password: str, hashed_password: str) -> bool:64 return bcrypt.checkpw(65 plain_password.encode("utf-8"), hashed_password.encode("utf-8")66 )67 68 69def get_password_hash(password: str) -> str:70 # Hash a password for the first time71 return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")72 