fix: auth reconnection loop, duplicate login listeners, modal double-disable

- websocket: clear tokens on refresh failure to prevent infinite 401 loop
- api: write vw:user to sessionStorage on refresh for consistency with WS
- api: remove vw:user from sessionStorage in clearAuthTokens
- login: guard listener setup with flags to prevent duplicate attachment
- modal: skip inline button disable when handler uses processing state
- users: remove unused requestUpdate import
This commit is contained in:
wall
2026-07-24 04:02:44 +00:00
parent edaf16a433
commit d4213fb93b
5 changed files with 33 additions and 7 deletions
+12 -4
View File
@@ -7,6 +7,7 @@
*/
import { refreshByTopic } from './model.js?v=9';
import { clearAuthTokens } from './api.js?v=12';
let _wsConn = null;
let _wsReconnectMs = 0;
@@ -16,8 +17,8 @@ let _wsFailCount = 0;
const _directHandlers = [];
/**
* Refresh the access token. Does NOT redirect on failure — the caller
* decides what to do when refresh fails.
* Refresh the access token. On failure, clears all tokens to prevent
* an infinite reconnection loop with a stale token.
*
* @returns {Promise<boolean>} true if token was refreshed
*/
@@ -31,9 +32,15 @@ async function _tryRefreshToken() {
body: JSON.stringify({ refresh_token: refresh }),
credentials: 'same-origin',
});
if (res.status !== 200) return false;
if (res.status !== 200) {
clearAuthTokens();
return false;
}
const json = await res.json();
if (!json.ok || !json.data?.tokens) return false;
if (!json.ok || !json.data?.tokens) {
clearAuthTokens();
return false;
}
const tokens = json.data.tokens;
window.__auth_token__ = tokens.access_token;
sessionStorage.setItem('vw:refresh', tokens.refresh_token);
@@ -47,6 +54,7 @@ async function _tryRefreshToken() {
}
return true;
} catch {
clearAuthTokens();
return false;
}
}