web-client/bff/ws_proxy.py
Markov 2f1778c821
Some checks failed
Deploy Web Client / deploy (push) Has been cancelled
feat: BFF (Python FastAPI) — proxy to Tracker with JWT auth
- BFF on port 8200: auth + proxy to tracker
- All /api/* routes go through BFF
- WebSocket proxy with JWT auth
- Tracker no longer exposed to internet
- Logging on all requests
- Removed Next.js API routes for auth (BFF handles it)
2026-02-15 19:44:55 +01:00

55 lines
1.6 KiB
Python

"""WebSocket proxy: authenticated users ↔ Tracker."""
import asyncio
import logging
import json
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
import websockets
from auth import verify_token
from config import TRACKER_WS_URL, TRACKER_TOKEN
logger = logging.getLogger("bff.ws")
router = APIRouter()
@router.websocket("/ws")
async def ws_proxy(ws: WebSocket, token: str = ""):
# Authenticate user
if not token:
await ws.close(code=4001, reason="No token")
return
user = verify_token(token)
if not user:
await ws.close(code=4001, reason="Invalid token")
return
await ws.accept()
logger.info("WS connected: %s", user.get("name"))
# Connect to tracker
tracker_url = f"{TRACKER_WS_URL}?client_type=human&client_id={user['sub']}&token={TRACKER_TOKEN}"
try:
async with websockets.connect(tracker_url) as tracker_ws:
async def forward_to_tracker():
try:
while True:
data = await ws.receive_text()
await tracker_ws.send(data)
except WebSocketDisconnect:
pass
async def forward_to_client():
try:
async for msg in tracker_ws:
await ws.send_text(msg)
except Exception:
pass
await asyncio.gather(forward_to_tracker(), forward_to_client())
except Exception as e:
logger.error("WS proxy error: %s", e)
finally:
logger.info("WS disconnected: %s", user.get("name"))