AswinMathew's picture
Upload folder using huggingface_hub
7190fd0 verified
from fastapi import APIRouter, Depends, HTTPException, Response, Cookie, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.models.user import User
from app.schemas.auth import UserCreate, UserLogin, UserResponse, TokenResponse
from app.services.auth import (
hash_password, verify_password,
create_access_token, create_refresh_token, decode_token,
get_current_user,
)
from app.config import get_settings
router = APIRouter(prefix="/api/auth", tags=["auth"])
settings = get_settings()
@router.post("/register", response_model=UserResponse, status_code=201)
async def register(data: UserCreate, db: AsyncSession = Depends(get_db)):
# Check existing
existing = await db.execute(
select(User).where((User.email == data.email) | (User.username == data.username))
)
if existing.scalar_one_or_none():
raise HTTPException(status_code=409, detail="Email or username already registered")
user = User(
email=data.email,
username=data.username,
password_hash=hash_password(data.password),
)
db.add(user)
await db.commit()
await db.refresh(user)
return user
@router.post("/login", response_model=TokenResponse)
async def login(data: UserLogin, response: Response, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.email == data.email))
user = result.scalar_one_or_none()
if not user or not verify_password(data.password, user.password_hash):
raise HTTPException(status_code=401, detail="Invalid credentials")
access_token = create_access_token(user.id)
refresh_token = create_refresh_token(user.id)
response.set_cookie(
key="refresh_token",
value=refresh_token,
httponly=True,
secure=False, # Set True in production with HTTPS
samesite="lax",
max_age=settings.refresh_token_expire_days * 86400,
path="/api/auth",
)
return TokenResponse(access_token=access_token)
@router.post("/refresh", response_model=TokenResponse)
async def refresh(
response: Response,
refresh_token: str | None = Cookie(default=None),
db: AsyncSession = Depends(get_db),
):
if not refresh_token:
raise HTTPException(status_code=401, detail="No refresh token")
payload = decode_token(refresh_token)
if payload.get("type") != "refresh":
raise HTTPException(status_code=401, detail="Invalid token type")
user_id = int(payload["sub"])
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=401, detail="User not found")
new_access = create_access_token(user.id)
new_refresh = create_refresh_token(user.id)
response.set_cookie(
key="refresh_token",
value=new_refresh,
httponly=True,
secure=False,
samesite="lax",
max_age=settings.refresh_token_expire_days * 86400,
path="/api/auth",
)
return TokenResponse(access_token=new_access)
@router.post("/logout")
async def logout(response: Response):
response.delete_cookie("refresh_token", path="/api/auth")
return {"message": "Logged out"}
@router.get("/me", response_model=UserResponse)
async def me(user: User = Depends(get_current_user)):
return user