Spaces:
Sleeping
Sleeping
| """``/api/xp`` — proxy to the Supabase ``apex-xp`` edge function.""" | |
| import httpx | |
| from fastapi import APIRouter, Depends, HTTPException, Request | |
| from slowapi import Limiter | |
| from slowapi.util import get_remote_address | |
| from app.core.auth import get_current_user | |
| from app.core.config import SUPABASE_EDGE_URL | |
| from app.types import XpRequest | |
| router = APIRouter() | |
| # Rate limiter: 10 XP requests per minute per IP | |
| limiter = Limiter(key_func=get_remote_address) | |
| async def handle_xp(request: Request, req: XpRequest, user: dict = Depends(get_current_user)): | |
| # IDOR FIX: Use authenticated user's ID from JWT, ignore client-provided user_id | |
| user_id = user["user_id"] | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| resp = await client.post( | |
| f"{SUPABASE_EDGE_URL}/apex-xp", | |
| json={"action": req.action, "user_id": user_id, "xp_amount": req.xp_amount}, | |
| ) | |
| data = resp.json() | |
| if resp.status_code != 200: | |
| raise HTTPException(status_code=resp.status_code, detail="XP operation failed") | |
| return data | |