From a5afbb1dc1b52cf01bf38412de19e212e9e50963 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Wed, 27 May 2026 21:40:32 -0400 Subject: [PATCH] fix: SSE sync indicator stuck on 'Connexion...' (3 fixes) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Move initSyncStatus() AFTER auth check — EventSource was connecting before the access_token cookie was available, causing 401 errors. 2. Reconnect SSE after login — Login form handler now calls IndexUpdateManager.connect() + showWelcome() after successful auth. 3. SSESafeGZipMiddleware — GZip buffering breaks Server-Sent Events streaming. Custom middleware subclass skips compression for /api/events endpoint (path-based bypass). --- backend/main.py | 18 +++++++++++++++++- frontend/app.js | 8 +++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/backend/main.py b/backend/main.py index 78c675f..d145bfb 100644 --- a/backend/main.py +++ b/backend/main.py @@ -556,8 +556,24 @@ async def lifespan(app: FastAPI): app = FastAPI(title="ObsiGate", version="1.4.0", lifespan=lifespan) # GZip compression — reduces bandwidth by ~70% for text responses +# Custom wrapper: skip compression for SSE streams (/api/events) from fastapi.middleware.gzip import GZipMiddleware -app.add_middleware(GZipMiddleware, minimum_size=1000) +from starlette.types import Scope, Receive, Send + +class SSESafeGZipMiddleware(GZipMiddleware): + """GZip middleware that skips SSE (Server-Sent Events) streams. + + GZip buffering breaks incremental streaming required by SSE. + We detect SSE endpoints by path and bypass compression entirely. + """ + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + if scope["type"] == "http" and scope.get("path") == "/api/events": + # Bypass GZip: passthrough directly to the inner app + await self.app(scope, receive, send) + else: + await super().__call__(scope, receive, send) + +app.add_middleware(SSESafeGZipMiddleware, minimum_size=1000) # Security headers on all responses app.add_middleware(SecurityHeadersMiddleware) diff --git a/frontend/app.js b/frontend/app.js index 7d30550..55d8485 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -1734,6 +1734,10 @@ // Load app data after successful login try { await Promise.all([loadVaults(), loadTags()]); + // Start SSE sync now that auth cookie is set + IndexUpdateManager.connect(); + // Show dashboard + showWelcome(); } catch (err) { console.error("Failed to load data after login:", err); } @@ -7818,7 +7822,6 @@ initSidebarFilter(); initSidebarResize(); initEditor(); - initSyncStatus(); initLoginForm(); initRecentTab(); RightSidebarManager.init(); @@ -7829,6 +7832,9 @@ const authOk = await AuthManager.initAuth(); if (authOk) { + // Start SSE sync AFTER auth is established (cookie available) + initSyncStatus(); + try { await Promise.all([loadVaultSettings(), loadVaults(), loadTags()]);