mitra-interactions-sdk 1.0.68 → 1.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -5
- package/dist/index.d.mts +55 -26
- package/dist/index.d.ts +55 -26
- package/dist/index.js +146 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -118,19 +118,28 @@ async function loginMitra(method, options) {
|
|
|
118
118
|
return doLogin(method, options);
|
|
119
119
|
}
|
|
120
120
|
var REFRESH_TIMEOUT_MS = 15e3;
|
|
121
|
+
var AUTH_HANDOFF_READY_TYPE = "mitra-auth-ready";
|
|
122
|
+
var AUTH_HANDOFF_TOKEN_TYPE = "mitra-auth-refresh-token";
|
|
121
123
|
var _refreshPromise = null;
|
|
122
|
-
function openAuthIframe(url, expectedOrigin) {
|
|
124
|
+
function openAuthIframe(url, expectedOrigin, handoffToken) {
|
|
123
125
|
return new Promise((resolve, reject) => {
|
|
124
126
|
const iframe = document.createElement("iframe");
|
|
125
127
|
iframe.style.display = "none";
|
|
126
128
|
iframe.src = url;
|
|
127
|
-
const
|
|
129
|
+
const timer2 = setTimeout(() => {
|
|
128
130
|
cleanup();
|
|
129
131
|
reject(new Error("Token refresh timeout"));
|
|
130
132
|
}, REFRESH_TIMEOUT_MS);
|
|
131
133
|
function onMessage(event) {
|
|
132
134
|
if (event.origin !== expectedOrigin) return;
|
|
133
|
-
if (!event.data
|
|
135
|
+
if (!event.data) return;
|
|
136
|
+
if (event.data.type === AUTH_HANDOFF_READY_TYPE) {
|
|
137
|
+
if (handoffToken && iframe.contentWindow && event.source === iframe.contentWindow) {
|
|
138
|
+
iframe.contentWindow.postMessage({ type: AUTH_HANDOFF_TOKEN_TYPE, token: handoffToken }, expectedOrigin);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (event.data.type !== AUTH_MESSAGE_TYPE) return;
|
|
134
143
|
cleanup();
|
|
135
144
|
if (event.data.success) {
|
|
136
145
|
resolve(event.data.data);
|
|
@@ -140,20 +149,20 @@ function openAuthIframe(url, expectedOrigin) {
|
|
|
140
149
|
}
|
|
141
150
|
function cleanup() {
|
|
142
151
|
window.removeEventListener("message", onMessage);
|
|
143
|
-
clearTimeout(
|
|
152
|
+
clearTimeout(timer2);
|
|
144
153
|
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
145
154
|
}
|
|
146
155
|
window.addEventListener("message", onMessage);
|
|
147
156
|
document.body.appendChild(iframe);
|
|
148
157
|
});
|
|
149
158
|
}
|
|
150
|
-
async function refreshTokenSilently(authUrl, projectId) {
|
|
159
|
+
async function refreshTokenSilently(authUrl, projectId, currentToken) {
|
|
151
160
|
if (_refreshPromise) return _refreshPromise;
|
|
152
161
|
_refreshPromise = (async () => {
|
|
153
162
|
try {
|
|
154
163
|
const origin = getOriginFromUrl(authUrl);
|
|
155
|
-
const url = buildAuthUrl(authUrl, "refresh", projectId);
|
|
156
|
-
const response = await openAuthIframe(url, origin);
|
|
164
|
+
const url = buildAuthUrl(authUrl, "refresh", projectId) + (currentToken ? "&handoff=1" : "");
|
|
165
|
+
const response = await openAuthIframe(url, origin, currentToken);
|
|
157
166
|
return response;
|
|
158
167
|
} finally {
|
|
159
168
|
_refreshPromise = null;
|
|
@@ -175,7 +184,7 @@ function openSilentAuthIframe(authUrl, projectId, credentials) {
|
|
|
175
184
|
}
|
|
176
185
|
const iframe = document.createElement("iframe");
|
|
177
186
|
iframe.style.display = "none";
|
|
178
|
-
const
|
|
187
|
+
const timer2 = setTimeout(() => {
|
|
179
188
|
cleanup();
|
|
180
189
|
reject(new Error("Timeout na autentica\xE7\xE3o silenciosa"));
|
|
181
190
|
}, SILENT_TIMEOUT_MS);
|
|
@@ -199,7 +208,7 @@ function openSilentAuthIframe(authUrl, projectId, credentials) {
|
|
|
199
208
|
}
|
|
200
209
|
function cleanup() {
|
|
201
210
|
window.removeEventListener("message", onMessage);
|
|
202
|
-
clearTimeout(
|
|
211
|
+
clearTimeout(timer2);
|
|
203
212
|
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
204
213
|
}
|
|
205
214
|
window.addEventListener("message", onMessage);
|
|
@@ -381,6 +390,105 @@ function withServerFunctionProof(headers, proof = readServerFunctionProof()) {
|
|
|
381
390
|
return { ...headers, [SF_EXECUTION_TOKEN_HEADER]: proof };
|
|
382
391
|
}
|
|
383
392
|
|
|
393
|
+
// src/session-watch.ts
|
|
394
|
+
var RENEW_BEFORE_MS = 6e4;
|
|
395
|
+
var RETRY_MS = 1e4;
|
|
396
|
+
var MAX_TIMEOUT_MS = 2147483647;
|
|
397
|
+
var refresher = null;
|
|
398
|
+
var timer = null;
|
|
399
|
+
var listening = false;
|
|
400
|
+
var expiryAtLastAttempt = null;
|
|
401
|
+
var notifiedFor = null;
|
|
402
|
+
function registerSessionRefresher(fn) {
|
|
403
|
+
refresher = fn;
|
|
404
|
+
}
|
|
405
|
+
function limitedSessionExpiry(token) {
|
|
406
|
+
if (!token) return null;
|
|
407
|
+
const payload = decodeJwtPayload(token);
|
|
408
|
+
if (!payload || typeof payload.authTime !== "number" || typeof payload.exp !== "number") return null;
|
|
409
|
+
return payload.exp * 1e3;
|
|
410
|
+
}
|
|
411
|
+
function currentExpiry() {
|
|
412
|
+
if (typeof window === "undefined" || !isConfigured()) return null;
|
|
413
|
+
const config = getConfig();
|
|
414
|
+
if (!config.token || !config.authUrl || config.projectId == null) return null;
|
|
415
|
+
return limitedSessionExpiry(config.token);
|
|
416
|
+
}
|
|
417
|
+
function clearTimer() {
|
|
418
|
+
if (timer) {
|
|
419
|
+
clearTimeout(timer);
|
|
420
|
+
timer = null;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function startSessionWatch() {
|
|
424
|
+
expiryAtLastAttempt = null;
|
|
425
|
+
notifiedFor = null;
|
|
426
|
+
watchSession();
|
|
427
|
+
}
|
|
428
|
+
function watchSession() {
|
|
429
|
+
clearTimer();
|
|
430
|
+
const expiry = currentExpiry();
|
|
431
|
+
if (expiry == null) return;
|
|
432
|
+
listenForReturn();
|
|
433
|
+
let delay = Math.max(expiry - Date.now() - RENEW_BEFORE_MS, 0);
|
|
434
|
+
if (expiryAtLastAttempt != null && expiry <= expiryAtLastAttempt + 1e3) {
|
|
435
|
+
delay = Math.max(expiry - Date.now() + 1e3, RETRY_MS);
|
|
436
|
+
}
|
|
437
|
+
if (delay > MAX_TIMEOUT_MS) return;
|
|
438
|
+
timer = setTimeout(() => {
|
|
439
|
+
void renewNow();
|
|
440
|
+
}, delay);
|
|
441
|
+
}
|
|
442
|
+
async function renewNow() {
|
|
443
|
+
clearTimer();
|
|
444
|
+
const before = currentExpiry();
|
|
445
|
+
if (before == null || !refresher) return;
|
|
446
|
+
expiryAtLastAttempt = before;
|
|
447
|
+
const renewed = await refresher().catch(() => false);
|
|
448
|
+
if (renewed) return;
|
|
449
|
+
const expiry = currentExpiry();
|
|
450
|
+
if (expiry != null && Date.now() < expiry) {
|
|
451
|
+
timer = setTimeout(() => {
|
|
452
|
+
void renewNow();
|
|
453
|
+
}, RETRY_MS);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function onReturn() {
|
|
457
|
+
const expiry = currentExpiry();
|
|
458
|
+
if (expiry == null) return;
|
|
459
|
+
const atSessionEnd = expiryAtLastAttempt != null && expiry <= expiryAtLastAttempt + 1e3;
|
|
460
|
+
if (expiry - Date.now() <= RENEW_BEFORE_MS && (!atSessionEnd || Date.now() >= expiry)) {
|
|
461
|
+
void renewNow();
|
|
462
|
+
} else {
|
|
463
|
+
watchSession();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function listenForReturn() {
|
|
467
|
+
if (listening || typeof window === "undefined") return;
|
|
468
|
+
listening = true;
|
|
469
|
+
if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
|
|
470
|
+
document.addEventListener("visibilitychange", () => {
|
|
471
|
+
if (document.visibilityState === "visible") onReturn();
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
if (typeof window.addEventListener === "function") {
|
|
475
|
+
window.addEventListener("online", onReturn);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
function reportRefreshFailure() {
|
|
479
|
+
var _a, _b;
|
|
480
|
+
const expiry = currentExpiry();
|
|
481
|
+
if (expiry == null || Date.now() < expiry) return;
|
|
482
|
+
const config = getConfig();
|
|
483
|
+
if (notifiedFor === config.token) return;
|
|
484
|
+
notifiedFor = (_a = config.token) != null ? _a : null;
|
|
485
|
+
clearTimer();
|
|
486
|
+
try {
|
|
487
|
+
(_b = config.onSessionExpired) == null ? void 0 : _b.call(config);
|
|
488
|
+
} catch (e) {
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
384
492
|
// src/client.ts
|
|
385
493
|
function getFetch2() {
|
|
386
494
|
if (typeof globalThis.fetch === "function") {
|
|
@@ -415,14 +523,18 @@ function tryRefreshToken() {
|
|
|
415
523
|
if (refreshInFlight === attempt) refreshInFlight = null;
|
|
416
524
|
};
|
|
417
525
|
attempt.then(clear, clear);
|
|
526
|
+
attempt.then((renewed) => {
|
|
527
|
+
if (!renewed) reportRefreshFailure();
|
|
528
|
+
}, () => void 0);
|
|
418
529
|
return attempt;
|
|
419
530
|
}
|
|
531
|
+
registerSessionRefresher(tryRefreshToken);
|
|
420
532
|
async function doRefreshToken() {
|
|
421
533
|
const config = getConfig();
|
|
422
534
|
if (!config.token || config.projectId == null || !config.baseURL) return false;
|
|
423
535
|
if (!config.authUrl || typeof window === "undefined") return false;
|
|
424
536
|
try {
|
|
425
|
-
const session = await refreshTokenSilently(config.authUrl, config.projectId);
|
|
537
|
+
const session = await refreshTokenSilently(config.authUrl, config.projectId, config.token);
|
|
426
538
|
updateGlobalToken(session.token);
|
|
427
539
|
if (config.onTokenRefresh) config.onTokenRefresh(session);
|
|
428
540
|
return true;
|
|
@@ -824,11 +936,13 @@ async function deleteProfileMitra(options) {
|
|
|
824
936
|
});
|
|
825
937
|
}
|
|
826
938
|
async function setProfileUsersMitra(options) {
|
|
827
|
-
|
|
939
|
+
const body = {
|
|
828
940
|
projectId: resolveProjectId2(options.projectId),
|
|
829
|
-
profileId: options.profileId
|
|
830
|
-
|
|
831
|
-
|
|
941
|
+
profileId: options.profileId
|
|
942
|
+
};
|
|
943
|
+
if (options.userIds !== void 0) body.userIds = options.userIds;
|
|
944
|
+
if (options.emails !== void 0) body.emails = options.emails;
|
|
945
|
+
return http.post("/interactions/profiles/users", body);
|
|
832
946
|
}
|
|
833
947
|
async function setProfileSelectTablesMitra(options) {
|
|
834
948
|
const body = {
|
|
@@ -1496,7 +1610,7 @@ function openSocket() {
|
|
|
1496
1610
|
return new Promise((resolve, reject) => {
|
|
1497
1611
|
const socket = new WebSocket(url);
|
|
1498
1612
|
let opened = false;
|
|
1499
|
-
const
|
|
1613
|
+
const timer2 = setTimeout(() => {
|
|
1500
1614
|
if (!opened) {
|
|
1501
1615
|
try {
|
|
1502
1616
|
socket.close();
|
|
@@ -1507,13 +1621,13 @@ function openSocket() {
|
|
|
1507
1621
|
}, 15e3);
|
|
1508
1622
|
socket.onopen = () => {
|
|
1509
1623
|
opened = true;
|
|
1510
|
-
clearTimeout(
|
|
1624
|
+
clearTimeout(timer2);
|
|
1511
1625
|
ws = socket;
|
|
1512
1626
|
resolve(socket);
|
|
1513
1627
|
};
|
|
1514
1628
|
socket.onerror = () => {
|
|
1515
1629
|
if (!opened) {
|
|
1516
|
-
clearTimeout(
|
|
1630
|
+
clearTimeout(timer2);
|
|
1517
1631
|
reject(new Error("Agent Chat: erro ao conectar no WebSocket"));
|
|
1518
1632
|
}
|
|
1519
1633
|
};
|
|
@@ -1521,7 +1635,7 @@ function openSocket() {
|
|
|
1521
1635
|
if (ws === socket) ws = null;
|
|
1522
1636
|
const detalhe = closeDetail(event);
|
|
1523
1637
|
if (!opened) {
|
|
1524
|
-
clearTimeout(
|
|
1638
|
+
clearTimeout(timer2);
|
|
1525
1639
|
reject(new Error(`Agent Chat: conex\xE3o fechada${detalhe}`));
|
|
1526
1640
|
}
|
|
1527
1641
|
for (const [id, pending] of pendingRequests) {
|
|
@@ -1896,7 +2010,7 @@ function createMitraInstance(initialConfig) {
|
|
|
1896
2010
|
if (!_config.token || _config.projectId == null || !_config.baseURL) return false;
|
|
1897
2011
|
if (!_config.authUrl || typeof window === "undefined") return false;
|
|
1898
2012
|
try {
|
|
1899
|
-
const session = await refreshTokenSilently(_config.authUrl, _config.projectId);
|
|
2013
|
+
const session = await refreshTokenSilently(_config.authUrl, _config.projectId, _config.token);
|
|
1900
2014
|
_config = { ..._config, token: stripBearer(session.token) };
|
|
1901
2015
|
updateGlobalToken(session.token);
|
|
1902
2016
|
if (_config.onTokenRefresh) _config.onTokenRefresh(session);
|
|
@@ -2186,19 +2300,21 @@ function createMitraInstance(initialConfig) {
|
|
|
2186
2300
|
return request("DELETE", "/interactions/profiles", { body: { projectId: resolveProjectId4(options.projectId), profileId: options.profileId } });
|
|
2187
2301
|
},
|
|
2188
2302
|
async setProfileUsers(options) {
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2303
|
+
const body = { projectId: resolveProjectId4(options.projectId), profileId: options.profileId };
|
|
2304
|
+
if (options.userIds !== void 0) body.userIds = options.userIds;
|
|
2305
|
+
if (options.emails !== void 0) body.emails = options.emails;
|
|
2306
|
+
return request("POST", "/interactions/profiles/users", { body });
|
|
2192
2307
|
},
|
|
2308
|
+
// jdbcConnectionConfigId era descartado nos dois abaixo (as funções soltas repassavam).
|
|
2193
2309
|
async setProfileSelectTables(options) {
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
});
|
|
2310
|
+
const body = { projectId: resolveProjectId4(options.projectId), profileId: options.profileId, tables: options.tables };
|
|
2311
|
+
if (options.jdbcConnectionConfigId !== void 0) body.jdbcConnectionConfigId = options.jdbcConnectionConfigId;
|
|
2312
|
+
return request("POST", "/interactions/profiles/selectTables", { body });
|
|
2197
2313
|
},
|
|
2198
2314
|
async setProfileDmlTables(options) {
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
});
|
|
2315
|
+
const body = { projectId: resolveProjectId4(options.projectId), profileId: options.profileId, tables: options.tables };
|
|
2316
|
+
if (options.jdbcConnectionConfigId !== void 0) body.jdbcConnectionConfigId = options.jdbcConnectionConfigId;
|
|
2317
|
+
return request("POST", "/interactions/profiles/dmlTables", { body });
|
|
2202
2318
|
},
|
|
2203
2319
|
async setProfileActions(options) {
|
|
2204
2320
|
return request("POST", "/interactions/profiles/actions", {
|
|
@@ -2304,6 +2420,7 @@ function configureSdkMitra(config = {}) {
|
|
|
2304
2420
|
const chat = window.__mitraChat;
|
|
2305
2421
|
if (chat) chat.init(merged.token);
|
|
2306
2422
|
}
|
|
2423
|
+
startSessionWatch();
|
|
2307
2424
|
return createMitraInstance(globalConfig);
|
|
2308
2425
|
}
|
|
2309
2426
|
function getConfig() {
|
|
@@ -2318,6 +2435,7 @@ function isConfigured() {
|
|
|
2318
2435
|
function updateGlobalToken(token) {
|
|
2319
2436
|
if (globalConfig) {
|
|
2320
2437
|
globalConfig = { ...globalConfig, token: stripBearer(token) };
|
|
2438
|
+
watchSession();
|
|
2321
2439
|
}
|
|
2322
2440
|
}
|
|
2323
2441
|
function inferProjectId(projectId) {
|