Changeset 0.28.8 (#194)

This commit is contained in:
2026-03-15 23:43:36 +00:00
parent 3237d55e0c
commit 128cbb8174
25 changed files with 1157 additions and 863 deletions

View File

@@ -183,7 +183,7 @@ const Events = {
this._dispatch('ws.disconnected', {}, { event: 'ws.disconnected', ts: Date.now(), local: true });
},
_doConnect() {
async _doConnect() {
if (!this._wsUrl) return;
// Build full URL
@@ -193,14 +193,13 @@ const Events = {
url = `${proto}//${location.host}${url}`;
}
// Add auth token as query param (WebSocket doesn't support headers)
const token = (typeof API !== 'undefined' && API.accessToken) ? API.accessToken : null;
if (token) {
url += (url.includes('?') ? '&' : '?') + `token=${encodeURIComponent(token)}`;
} else {
console.warn('[EventBus] No auth token — skipping WebSocket');
// Authenticate: prefer ticket exchange, fall back to legacy ?token=
const authParam = await this._acquireWsAuth();
if (!authParam) {
console.warn('[EventBus] No auth available — skipping WebSocket');
return;
}
url += (url.includes('?') ? '&' : '?') + authParam;
try {
this._ws = new WebSocket(url);
@@ -269,6 +268,36 @@ const Events = {
this._startHeartbeat();
},
/**
* Acquire WebSocket auth parameter.
* Preferred: POST /api/v1/ws/ticket → ?ticket=<opaque> (v0.28.8+)
* Fallback: JWT access token → ?token=<jwt> (deprecated)
* @returns {string|null} query parameter string or null if no auth
*/
async _acquireWsAuth() {
// Try ticket exchange first
try {
if (typeof API !== 'undefined' && API._post) {
const data = await API._post('/api/v1/ws/ticket', {});
if (data && data.ticket) {
return `ticket=${encodeURIComponent(data.ticket)}`;
}
}
} catch (e) {
// Ticket endpoint unavailable (pre-v0.28.8 server) or auth error.
// Fall through to legacy path silently.
console.debug('[EventBus] Ticket exchange failed, falling back to ?token=', e.message || e);
}
// Legacy fallback: JWT in query param
const token = (typeof API !== 'undefined' && API.accessToken) ? API.accessToken : null;
if (token) {
return `token=${encodeURIComponent(token)}`;
}
return null;
},
_scheduleReconnect() {
if (!this._wsUrl) return;
if (this._wsReconnectTimer) return;