From ee9dc0286414fa67a2a377b5bf521470e993d1ae Mon Sep 17 00:00:00 2001 From: Talon Date: Wed, 13 May 2026 16:26:35 +0200 Subject: [PATCH] Fix catch-all route, SSE auth via query token, and live progress SSE connections --- src/server/middleware/auth.ts | 8 +++++++- src/server/public/app.js | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/server/middleware/auth.ts b/src/server/middleware/auth.ts index 5e20574..82025fe 100644 --- a/src/server/middleware/auth.ts +++ b/src/server/middleware/auth.ts @@ -9,7 +9,13 @@ export function basicAuth(req: Request, res: Response, next: NextFunction): void return; } - const authHeader = req.headers.authorization; + // Support token via query param for SSE (EventSource doesn't support custom headers) + let authHeader = req.headers.authorization; + if (!authHeader && req.query.token) { + const token = Array.isArray(req.query.token) ? req.query.token[0] : req.query.token; + authHeader = `Basic ${token}`; + } + if (!authHeader || !authHeader.startsWith('Basic ')) { res.setHeader('WWW-Authenticate', 'Basic realm="Audio Description Server"'); res.status(401).json({ error: 'Authentication required' }); diff --git a/src/server/public/app.js b/src/server/public/app.js index aad6075..fc9a159 100644 --- a/src/server/public/app.js +++ b/src/server/public/app.js @@ -220,6 +220,11 @@ async function loadJobs() { try { const data = await apiJson('GET', '/api/jobs'); renderJobs(data.jobs); + data.jobs.forEach(j => { + if (j.status === 'processing' || j.status === 'queued') { + connectSSE(j.id); + } + }); } catch (err) { console.error(err); } @@ -432,7 +437,7 @@ async function loadConfigDefaults() { const sseConnections = {}; function connectSSE(jobId) { if (sseConnections[jobId]) return; - const source = new EventSource(`/api/jobs/${jobId}/progress`); + const source = new EventSource(`/api/jobs/${jobId}/progress?token=${encodeURIComponent(authToken)}`); source.onmessage = (event) => { const data = JSON.parse(event.data); updateJobCard(jobId, data);