fix(webui): redirect to login when the GraphQL subscription WS auth fails

The subscription WebSocket retries forever on a 403 handshake (expired/invalid
cookie), but its error handler only escalated to auth:refresh when the error
*message* contained "403"/"auth required" — and browsers never expose the
handshake HTTP status on a WebSocket error event, so that detection never fired.
An idle page with active subscriptions therefore looped on 403 with no redirect
to login (the redirect only fired once a REST/axios call hit a 403). Dispatch
auth:refresh unconditionally on any WS error and let /info decide: it redirects
on a real 401/403 and is a no-op while the session holds. Live-verified both
ways: an invalid cookie now redirects to login from an idle page, and a
transient WS drop on a valid session keeps the user logged in. Pre-existing (the
WS handler is unchanged from main); surfaced by a tester.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Sergey Kozyrenko
2026-06-25 06:45:06 +07:00
co-authored by Claude Opus 4.8
parent 3d447c582f
commit ec608d7091
+3 -15
View File
@@ -390,21 +390,9 @@ const createApolloClient = () => {
error: (error) => {
Log.error('GraphQL WebSocket error:', error);
if (error && typeof error === 'object') {
const errorMessage = 'message' in error ? String(error.message) : '';
const errorString = errorMessage.toLowerCase();
if (
errorString.includes('403') ||
errorString.includes('401') ||
errorString.includes('unauthorized') ||
errorString.includes('auth required') ||
errorString.includes('forbidden')
) {
Log.warn('WebSocket authorization error detected, refreshing auth info');
window.dispatchEvent(new Event('auth:refresh'));
}
}
// A WebSocket error event doesn't expose the handshake HTTP status, so a
// 403 can't be detected here — let /info classify it via auth:refresh.
window.dispatchEvent(new Event('auth:refresh'));
},
ping: () => Log.debug('GraphQL WebSocket ping'),
pong: () => Log.debug('GraphQL WebSocket pong'),