|
@@ -1,10 +1,13 @@
|
|
|
-from fastapi import FastAPI, HTTPException, Request
|
|
|
|
|
|
|
+from fastapi import FastAPI, HTTPException, Request, WebSocket, WebSocketDisconnect, Query
|
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.staticfiles import StaticFiles
|
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
from fastapi.exceptions import RequestValidationError
|
|
from fastapi.exceptions import RequestValidationError
|
|
|
from fastapi.responses import JSONResponse
|
|
from fastapi.responses import JSONResponse
|
|
|
import traceback
|
|
import traceback
|
|
|
import os
|
|
import os
|
|
|
|
|
+import auth_utils
|
|
|
|
|
+import session_utils
|
|
|
|
|
+from services.global_manager import global_manager
|
|
|
|
|
|
|
|
import locales
|
|
import locales
|
|
|
import config
|
|
import config
|
|
@@ -70,6 +73,45 @@ app.include_router(chat.router)
|
|
|
app.include_router(blog.router)
|
|
app.include_router(blog.router)
|
|
|
app.include_router(admin.router)
|
|
app.include_router(admin.router)
|
|
|
|
|
|
|
|
|
|
+# WebSocket Global Handler (Centralized to handle various proxy prefixes)
|
|
|
|
|
+@app.websocket("/ws/auth/ws/global")
|
|
|
|
|
+@app.websocket("/auth/ws/global")
|
|
|
|
|
+async def ws_global(websocket: WebSocket, token: str = Query(...)):
|
|
|
|
|
+ print(f"DEBUG: WS Connection attempt with token: {token[:10]}...")
|
|
|
|
|
+ payload = auth_utils.decode_token(token)
|
|
|
|
|
+ if not payload:
|
|
|
|
|
+ print("DEBUG: WS Auth failed: Invalid token")
|
|
|
|
|
+ await websocket.close(code=4001)
|
|
|
|
|
+ return
|
|
|
|
|
+ user_id = payload.get("id")
|
|
|
|
|
+ role = payload.get("role")
|
|
|
|
|
+ if not user_id:
|
|
|
|
|
+ print("DEBUG: WS Auth failed: No user ID in payload")
|
|
|
|
|
+ await websocket.close(code=4001)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ print(f"DEBUG: WS Connected: user_id={user_id}, role={role}")
|
|
|
|
|
+ await global_manager.connect(websocket, user_id, role)
|
|
|
|
|
+ session_utils.track_user_ping(user_id)
|
|
|
|
|
+
|
|
|
|
|
+ # Send initial unread count
|
|
|
|
|
+ if role != 'admin':
|
|
|
|
|
+ await global_manager.notify_user(user_id)
|
|
|
|
|
+ else:
|
|
|
|
|
+ await global_manager.notify_admins()
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ while True:
|
|
|
|
|
+ data = await websocket.receive_text()
|
|
|
|
|
+ if data == "ping":
|
|
|
|
|
+ session_utils.track_user_ping(user_id)
|
|
|
|
|
+ except WebSocketDisconnect:
|
|
|
|
|
+ print(f"DEBUG: WS Disconnected: user_id={user_id}")
|
|
|
|
|
+ global_manager.disconnect(websocket, user_id)
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ print(f"DEBUG: WS Error: {e}")
|
|
|
|
|
+ global_manager.disconnect(websocket, user_id)
|
|
|
|
|
+
|
|
|
# Mount Static Files
|
|
# Mount Static Files
|
|
|
if not os.path.exists("uploads"):
|
|
if not os.path.exists("uploads"):
|
|
|
os.makedirs("uploads")
|
|
os.makedirs("uploads")
|