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/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 timer = setTimeout(() => {
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 || event.data.type !== AUTH_MESSAGE_TYPE) return;
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(timer);
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 timer = setTimeout(() => {
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(timer);
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
- return http.post("/interactions/profiles/users", {
939
+ const body = {
828
940
  projectId: resolveProjectId2(options.projectId),
829
- profileId: options.profileId,
830
- userIds: options.userIds
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 timer = setTimeout(() => {
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(timer);
1624
+ clearTimeout(timer2);
1511
1625
  ws = socket;
1512
1626
  resolve(socket);
1513
1627
  };
1514
1628
  socket.onerror = () => {
1515
1629
  if (!opened) {
1516
- clearTimeout(timer);
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(timer);
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
- return request("POST", "/interactions/profiles/users", {
2190
- body: { projectId: resolveProjectId4(options.projectId), profileId: options.profileId, userIds: options.userIds }
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
- return request("POST", "/interactions/profiles/selectTables", {
2195
- body: { projectId: resolveProjectId4(options.projectId), profileId: options.profileId, tables: options.tables }
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
- return request("POST", "/interactions/profiles/dmlTables", {
2200
- body: { projectId: resolveProjectId4(options.projectId), profileId: options.profileId, tables: options.tables }
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) {