import os from fastapi import APIRouter, HTTPException import bcrypt import jwt from fastapi import Depends from sqlalchemy.orm import Session from .models import User from .schemas import UserCreate, UserOut, UserLogin from ..config import get_db router = APIRouter( prefix="/auth", tags=["auth"], responses={404: {"description": "Not found"}}, dependencies=[], ) def create_token(user: User): return jwt.encode({"sub": user.username}, os.getenv("SECRET_KEY"), algorithm=os.getenv("ALGORITHM")) def verify_token(token: str): try: data = jwt.decode(token, os.getenv("SECRET_KEY"), algorithms=[os.getenv("ALGORITHM")]) return data.get("sub") except jwt.ExpiredSignatureError: raise HTTPException(401, "Token expired") except jwt.InvalidTokenError: raise HTTPException(401, "Invalid token") @router.post("/register") def register(user: UserCreate, db: Session = Depends(get_db)): if db.query(User).filter_by(username=user.username).first(): raise HTTPException(400, "Username taken") hashed = bcrypt.hashpw(user.password.encode(), bcrypt.gensalt()).decode() db_user = User(**user.model_dump(exclude={"password"}), hashedPassword=hashed) db.add(db_user) db.commit() return {"msg": "User created"} @router.post("/login") def login(user: UserLogin, db: Session = Depends(get_db)): db_user = db.query(User).filter_by(username=user.username).first() if not db_user or not bcrypt.checkpw(user.password.encode(), db_user.hashedPassword.encode()): raise HTTPException(401, "Invalid creds") return {"token": create_token(db_user)} @router.get("/me", response_model=UserOut) def get_me(token: str, db: Session = Depends(get_db)): username = verify_token(token) if not username: raise HTTPException(401, "Invalid token") user = db.query(User).filter_by(username=username).first() return user