from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.middleware.auth import get_current_user from app.models.user import User from app.schemas.auth import ( LoginRequest, RegisterRequest, TokenResponse, UserResponse, ) from app.utils.auth import create_access_token, hash_password, verify_password router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/register", response_model=TokenResponse, status_code=status.HTTP_201_CREATED) async def register(data: RegisterRequest, db: AsyncSession = Depends(get_db)): result = await db.execute( select(User).where((User.email == data.email) | (User.username == data.username)) ) existing = result.scalar_one_or_none() if existing: field = "email" if existing.email == data.email else "username" raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail=f"A user with this {field} already exists", ) user = User( email=data.email, username=data.username, hashed_password=hash_password(data.password), ) db.add(user) await db.flush() token = create_access_token(user.id) return TokenResponse(access_token=token) @router.post("/login", response_model=TokenResponse) async def login(data: LoginRequest, db: AsyncSession = Depends(get_db)): result = await db.execute(select(User).where(User.email == data.email)) user = result.scalar_one_or_none() if user is None or not verify_password(data.password, user.hashed_password): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid email or password", ) token = create_access_token(user.id) return TokenResponse(access_token=token) @router.get("/me", response_model=UserResponse) async def get_me(current_user: User = Depends(get_current_user)): return current_user