mitra-interactions-sdk 1.0.69 → 1.0.71
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 +12 -0
- package/dist/index.d.mts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +133 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +133 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,18 @@ await loginMitra('mitra', {
|
|
|
132
132
|
|
|
133
133
|
Quando qualquer requisição retorna **403**, o SDK tenta renovar o token automaticamente via iframe invisível (usa o cookie de sessão do provider). Se o refresh funcionar, a requisição é retentada com o novo token — transparente para o desenvolvedor.
|
|
134
134
|
|
|
135
|
+
**Sessão com duração limitada.** Quando o ambiente limita a duração da sessão, o token vale poucos minutos e traz a claim `authTime`. Nesse caso a SDK renova sozinha **antes** do vencimento (e ao voltar para a aba), sem esperar o 403. Se a sessão acabou de vez, a SDK chama `onSessionExpired`: limpe a sessão guardada e leve o usuário ao login. Para os demais tokens nada muda.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
configureSdkMitra({
|
|
139
|
+
...session,
|
|
140
|
+
onSessionExpired: () => {
|
|
141
|
+
localStorage.removeItem('minha_sessao');
|
|
142
|
+
window.location.reload();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
135
147
|
O callback `onTokenRefresh` é chamado após renovação bem-sucedida:
|
|
136
148
|
|
|
137
149
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -417,6 +417,19 @@ interface CallIntegrationOptions {
|
|
|
417
417
|
params?: Record<string, unknown>;
|
|
418
418
|
/** Body da requisição (para POST/PUT) */
|
|
419
419
|
body?: Record<string, unknown>;
|
|
420
|
+
/**
|
|
421
|
+
* Headers só desta chamada. Use apenas quando a API externa exigir um header específico.
|
|
422
|
+
*
|
|
423
|
+
* Se a API exigir corpo `application/x-www-form-urlencoded` (comum em endpoints OAuth como
|
|
424
|
+
* introspect, revoke e token), passe `{ 'Content-Type': 'application/x-www-form-urlencoded' }`
|
|
425
|
+
* e monte o `body` como objeto plano de campos texto, número ou booleano: objeto ou lista dentro
|
|
426
|
+
* do `body` é recusado com 400. Sem esse header, o corpo vai em JSON.
|
|
427
|
+
*
|
|
428
|
+
* A autenticação da integração continua sendo aplicada; um header com o mesmo nome de um da
|
|
429
|
+
* integração (ex.: `Authorization`) substitui o da integração nesta chamada. Valores são texto
|
|
430
|
+
* literal. Quando omitido, nenhum header é enviado.
|
|
431
|
+
*/
|
|
432
|
+
headers?: Record<string, string>;
|
|
420
433
|
}
|
|
421
434
|
interface CallIntegrationResponse {
|
|
422
435
|
/** HTTP status retornado pelo serviço externo */
|
|
@@ -1042,6 +1055,13 @@ interface MitraConfig {
|
|
|
1042
1055
|
projectId?: number;
|
|
1043
1056
|
/** Callback chamado quando o token é renovado automaticamente (após 401/403). Recebe a nova sessão. */
|
|
1044
1057
|
onTokenRefresh?: (session: LoginResponse) => void;
|
|
1058
|
+
/**
|
|
1059
|
+
* Callback chamado quando a sessão acabou e não há mais como renovar: o token
|
|
1060
|
+
* de uma sessão com duração limitada venceu e a renovação foi recusada. O app
|
|
1061
|
+
* deve limpar a sessão guardada e levar o usuário ao login. Nunca é chamado
|
|
1062
|
+
* para token de validade longa nem em erro de permissão (403 comum).
|
|
1063
|
+
*/
|
|
1064
|
+
onSessionExpired?: () => void;
|
|
1045
1065
|
}
|
|
1046
1066
|
/**
|
|
1047
1067
|
* Configura o SDK globalmente e retorna uma instância configurada.
|
|
@@ -1102,8 +1122,15 @@ declare function loginMitra(method: 'email' | 'google' | 'microsoft' | 'mitra',
|
|
|
1102
1122
|
/**
|
|
1103
1123
|
* Renova o token silenciosamente via iframe invisível.
|
|
1104
1124
|
* Se já houver um refresh em andamento, reaproveita a mesma promise.
|
|
1125
|
+
*
|
|
1126
|
+
* `currentToken` é o token que o app tem agora. Quando a página de auth pede
|
|
1127
|
+
* (aperto de mão `mitra-auth-ready`), ele é entregue ao iframe por postMessage.
|
|
1128
|
+
* Sem isso, app em domínio próprio não renova: o navegador particiona o
|
|
1129
|
+
* localStorage do iframe de outro site e a página de auth não acha o token que
|
|
1130
|
+
* gravou no login. Página de auth antiga ignora o pedido e renova pelo token
|
|
1131
|
+
* guardado, como sempre.
|
|
1105
1132
|
*/
|
|
1106
|
-
declare function refreshTokenSilently(authUrl: string, projectId: number): Promise<LoginResponse>;
|
|
1133
|
+
declare function refreshTokenSilently(authUrl: string, projectId: number, currentToken?: string): Promise<LoginResponse>;
|
|
1107
1134
|
/**
|
|
1108
1135
|
* Cria conta via email usando iframe silencioso.
|
|
1109
1136
|
* Após sucesso, o usuário recebe um código de verificação por email.
|
|
@@ -1318,6 +1345,11 @@ declare function listIntegrationsMitra(options?: ListIntegrationsOptions): Promi
|
|
|
1318
1345
|
* POST /interactions/integrations/call
|
|
1319
1346
|
* Chama uma API externa via serviço de integrações
|
|
1320
1347
|
* Mapeia connection → integrationSlug no body
|
|
1348
|
+
*
|
|
1349
|
+
* `headers` é opcional e vale só para esta chamada. Com
|
|
1350
|
+
* `headers: { 'Content-Type': 'application/x-www-form-urlencoded' }` o `body` sai como formulário
|
|
1351
|
+
* (`campo=valor&campo=valor`), o que endpoints OAuth como introspect, revoke e token exigem; o
|
|
1352
|
+
* `body` precisa então ser um objeto plano. Sem esse header, o corpo vai em JSON.
|
|
1321
1353
|
*/
|
|
1322
1354
|
declare function callIntegrationMitra(options: CallIntegrationOptions): Promise<CallIntegrationResponse>;
|
|
1323
1355
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -417,6 +417,19 @@ interface CallIntegrationOptions {
|
|
|
417
417
|
params?: Record<string, unknown>;
|
|
418
418
|
/** Body da requisição (para POST/PUT) */
|
|
419
419
|
body?: Record<string, unknown>;
|
|
420
|
+
/**
|
|
421
|
+
* Headers só desta chamada. Use apenas quando a API externa exigir um header específico.
|
|
422
|
+
*
|
|
423
|
+
* Se a API exigir corpo `application/x-www-form-urlencoded` (comum em endpoints OAuth como
|
|
424
|
+
* introspect, revoke e token), passe `{ 'Content-Type': 'application/x-www-form-urlencoded' }`
|
|
425
|
+
* e monte o `body` como objeto plano de campos texto, número ou booleano: objeto ou lista dentro
|
|
426
|
+
* do `body` é recusado com 400. Sem esse header, o corpo vai em JSON.
|
|
427
|
+
*
|
|
428
|
+
* A autenticação da integração continua sendo aplicada; um header com o mesmo nome de um da
|
|
429
|
+
* integração (ex.: `Authorization`) substitui o da integração nesta chamada. Valores são texto
|
|
430
|
+
* literal. Quando omitido, nenhum header é enviado.
|
|
431
|
+
*/
|
|
432
|
+
headers?: Record<string, string>;
|
|
420
433
|
}
|
|
421
434
|
interface CallIntegrationResponse {
|
|
422
435
|
/** HTTP status retornado pelo serviço externo */
|
|
@@ -1042,6 +1055,13 @@ interface MitraConfig {
|
|
|
1042
1055
|
projectId?: number;
|
|
1043
1056
|
/** Callback chamado quando o token é renovado automaticamente (após 401/403). Recebe a nova sessão. */
|
|
1044
1057
|
onTokenRefresh?: (session: LoginResponse) => void;
|
|
1058
|
+
/**
|
|
1059
|
+
* Callback chamado quando a sessão acabou e não há mais como renovar: o token
|
|
1060
|
+
* de uma sessão com duração limitada venceu e a renovação foi recusada. O app
|
|
1061
|
+
* deve limpar a sessão guardada e levar o usuário ao login. Nunca é chamado
|
|
1062
|
+
* para token de validade longa nem em erro de permissão (403 comum).
|
|
1063
|
+
*/
|
|
1064
|
+
onSessionExpired?: () => void;
|
|
1045
1065
|
}
|
|
1046
1066
|
/**
|
|
1047
1067
|
* Configura o SDK globalmente e retorna uma instância configurada.
|
|
@@ -1102,8 +1122,15 @@ declare function loginMitra(method: 'email' | 'google' | 'microsoft' | 'mitra',
|
|
|
1102
1122
|
/**
|
|
1103
1123
|
* Renova o token silenciosamente via iframe invisível.
|
|
1104
1124
|
* Se já houver um refresh em andamento, reaproveita a mesma promise.
|
|
1125
|
+
*
|
|
1126
|
+
* `currentToken` é o token que o app tem agora. Quando a página de auth pede
|
|
1127
|
+
* (aperto de mão `mitra-auth-ready`), ele é entregue ao iframe por postMessage.
|
|
1128
|
+
* Sem isso, app em domínio próprio não renova: o navegador particiona o
|
|
1129
|
+
* localStorage do iframe de outro site e a página de auth não acha o token que
|
|
1130
|
+
* gravou no login. Página de auth antiga ignora o pedido e renova pelo token
|
|
1131
|
+
* guardado, como sempre.
|
|
1105
1132
|
*/
|
|
1106
|
-
declare function refreshTokenSilently(authUrl: string, projectId: number): Promise<LoginResponse>;
|
|
1133
|
+
declare function refreshTokenSilently(authUrl: string, projectId: number, currentToken?: string): Promise<LoginResponse>;
|
|
1107
1134
|
/**
|
|
1108
1135
|
* Cria conta via email usando iframe silencioso.
|
|
1109
1136
|
* Após sucesso, o usuário recebe um código de verificação por email.
|
|
@@ -1318,6 +1345,11 @@ declare function listIntegrationsMitra(options?: ListIntegrationsOptions): Promi
|
|
|
1318
1345
|
* POST /interactions/integrations/call
|
|
1319
1346
|
* Chama uma API externa via serviço de integrações
|
|
1320
1347
|
* Mapeia connection → integrationSlug no body
|
|
1348
|
+
*
|
|
1349
|
+
* `headers` é opcional e vale só para esta chamada. Com
|
|
1350
|
+
* `headers: { 'Content-Type': 'application/x-www-form-urlencoded' }` o `body` sai como formulário
|
|
1351
|
+
* (`campo=valor&campo=valor`), o que endpoints OAuth como introspect, revoke e token exigem; o
|
|
1352
|
+
* `body` precisa então ser um objeto plano. Sem esse header, o corpo vai em JSON.
|
|
1321
1353
|
*/
|
|
1322
1354
|
declare function callIntegrationMitra(options: CallIntegrationOptions): Promise<CallIntegrationResponse>;
|
|
1323
1355
|
/**
|
package/dist/index.js
CHANGED
|
@@ -120,19 +120,28 @@ async function loginMitra(method, options) {
|
|
|
120
120
|
return doLogin(method, options);
|
|
121
121
|
}
|
|
122
122
|
var REFRESH_TIMEOUT_MS = 15e3;
|
|
123
|
+
var AUTH_HANDOFF_READY_TYPE = "mitra-auth-ready";
|
|
124
|
+
var AUTH_HANDOFF_TOKEN_TYPE = "mitra-auth-refresh-token";
|
|
123
125
|
var _refreshPromise = null;
|
|
124
|
-
function openAuthIframe(url, expectedOrigin) {
|
|
126
|
+
function openAuthIframe(url, expectedOrigin, handoffToken) {
|
|
125
127
|
return new Promise((resolve, reject) => {
|
|
126
128
|
const iframe = document.createElement("iframe");
|
|
127
129
|
iframe.style.display = "none";
|
|
128
130
|
iframe.src = url;
|
|
129
|
-
const
|
|
131
|
+
const timer2 = setTimeout(() => {
|
|
130
132
|
cleanup();
|
|
131
133
|
reject(new Error("Token refresh timeout"));
|
|
132
134
|
}, REFRESH_TIMEOUT_MS);
|
|
133
135
|
function onMessage(event) {
|
|
134
136
|
if (event.origin !== expectedOrigin) return;
|
|
135
|
-
if (!event.data
|
|
137
|
+
if (!event.data) return;
|
|
138
|
+
if (event.data.type === AUTH_HANDOFF_READY_TYPE) {
|
|
139
|
+
if (handoffToken && iframe.contentWindow && event.source === iframe.contentWindow) {
|
|
140
|
+
iframe.contentWindow.postMessage({ type: AUTH_HANDOFF_TOKEN_TYPE, token: handoffToken }, expectedOrigin);
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (event.data.type !== AUTH_MESSAGE_TYPE) return;
|
|
136
145
|
cleanup();
|
|
137
146
|
if (event.data.success) {
|
|
138
147
|
resolve(event.data.data);
|
|
@@ -142,20 +151,20 @@ function openAuthIframe(url, expectedOrigin) {
|
|
|
142
151
|
}
|
|
143
152
|
function cleanup() {
|
|
144
153
|
window.removeEventListener("message", onMessage);
|
|
145
|
-
clearTimeout(
|
|
154
|
+
clearTimeout(timer2);
|
|
146
155
|
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
147
156
|
}
|
|
148
157
|
window.addEventListener("message", onMessage);
|
|
149
158
|
document.body.appendChild(iframe);
|
|
150
159
|
});
|
|
151
160
|
}
|
|
152
|
-
async function refreshTokenSilently(authUrl, projectId) {
|
|
161
|
+
async function refreshTokenSilently(authUrl, projectId, currentToken) {
|
|
153
162
|
if (_refreshPromise) return _refreshPromise;
|
|
154
163
|
_refreshPromise = (async () => {
|
|
155
164
|
try {
|
|
156
165
|
const origin = getOriginFromUrl(authUrl);
|
|
157
|
-
const url = buildAuthUrl(authUrl, "refresh", projectId);
|
|
158
|
-
const response = await openAuthIframe(url, origin);
|
|
166
|
+
const url = buildAuthUrl(authUrl, "refresh", projectId) + (currentToken ? "&handoff=1" : "");
|
|
167
|
+
const response = await openAuthIframe(url, origin, currentToken);
|
|
159
168
|
return response;
|
|
160
169
|
} finally {
|
|
161
170
|
_refreshPromise = null;
|
|
@@ -177,7 +186,7 @@ function openSilentAuthIframe(authUrl, projectId, credentials) {
|
|
|
177
186
|
}
|
|
178
187
|
const iframe = document.createElement("iframe");
|
|
179
188
|
iframe.style.display = "none";
|
|
180
|
-
const
|
|
189
|
+
const timer2 = setTimeout(() => {
|
|
181
190
|
cleanup();
|
|
182
191
|
reject(new Error("Timeout na autentica\xE7\xE3o silenciosa"));
|
|
183
192
|
}, SILENT_TIMEOUT_MS);
|
|
@@ -201,7 +210,7 @@ function openSilentAuthIframe(authUrl, projectId, credentials) {
|
|
|
201
210
|
}
|
|
202
211
|
function cleanup() {
|
|
203
212
|
window.removeEventListener("message", onMessage);
|
|
204
|
-
clearTimeout(
|
|
213
|
+
clearTimeout(timer2);
|
|
205
214
|
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
206
215
|
}
|
|
207
216
|
window.addEventListener("message", onMessage);
|
|
@@ -383,6 +392,105 @@ function withServerFunctionProof(headers, proof = readServerFunctionProof()) {
|
|
|
383
392
|
return { ...headers, [SF_EXECUTION_TOKEN_HEADER]: proof };
|
|
384
393
|
}
|
|
385
394
|
|
|
395
|
+
// src/session-watch.ts
|
|
396
|
+
var RENEW_BEFORE_MS = 6e4;
|
|
397
|
+
var RETRY_MS = 1e4;
|
|
398
|
+
var MAX_TIMEOUT_MS = 2147483647;
|
|
399
|
+
var refresher = null;
|
|
400
|
+
var timer = null;
|
|
401
|
+
var listening = false;
|
|
402
|
+
var expiryAtLastAttempt = null;
|
|
403
|
+
var notifiedFor = null;
|
|
404
|
+
function registerSessionRefresher(fn) {
|
|
405
|
+
refresher = fn;
|
|
406
|
+
}
|
|
407
|
+
function limitedSessionExpiry(token) {
|
|
408
|
+
if (!token) return null;
|
|
409
|
+
const payload = decodeJwtPayload(token);
|
|
410
|
+
if (!payload || typeof payload.authTime !== "number" || typeof payload.exp !== "number") return null;
|
|
411
|
+
return payload.exp * 1e3;
|
|
412
|
+
}
|
|
413
|
+
function currentExpiry() {
|
|
414
|
+
if (typeof window === "undefined" || !isConfigured()) return null;
|
|
415
|
+
const config = getConfig();
|
|
416
|
+
if (!config.token || !config.authUrl || config.projectId == null) return null;
|
|
417
|
+
return limitedSessionExpiry(config.token);
|
|
418
|
+
}
|
|
419
|
+
function clearTimer() {
|
|
420
|
+
if (timer) {
|
|
421
|
+
clearTimeout(timer);
|
|
422
|
+
timer = null;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function startSessionWatch() {
|
|
426
|
+
expiryAtLastAttempt = null;
|
|
427
|
+
notifiedFor = null;
|
|
428
|
+
watchSession();
|
|
429
|
+
}
|
|
430
|
+
function watchSession() {
|
|
431
|
+
clearTimer();
|
|
432
|
+
const expiry = currentExpiry();
|
|
433
|
+
if (expiry == null) return;
|
|
434
|
+
listenForReturn();
|
|
435
|
+
let delay = Math.max(expiry - Date.now() - RENEW_BEFORE_MS, 0);
|
|
436
|
+
if (expiryAtLastAttempt != null && expiry <= expiryAtLastAttempt + 1e3) {
|
|
437
|
+
delay = Math.max(expiry - Date.now() + 1e3, RETRY_MS);
|
|
438
|
+
}
|
|
439
|
+
if (delay > MAX_TIMEOUT_MS) return;
|
|
440
|
+
timer = setTimeout(() => {
|
|
441
|
+
void renewNow();
|
|
442
|
+
}, delay);
|
|
443
|
+
}
|
|
444
|
+
async function renewNow() {
|
|
445
|
+
clearTimer();
|
|
446
|
+
const before = currentExpiry();
|
|
447
|
+
if (before == null || !refresher) return;
|
|
448
|
+
expiryAtLastAttempt = before;
|
|
449
|
+
const renewed = await refresher().catch(() => false);
|
|
450
|
+
if (renewed) return;
|
|
451
|
+
const expiry = currentExpiry();
|
|
452
|
+
if (expiry != null && Date.now() < expiry) {
|
|
453
|
+
timer = setTimeout(() => {
|
|
454
|
+
void renewNow();
|
|
455
|
+
}, RETRY_MS);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function onReturn() {
|
|
459
|
+
const expiry = currentExpiry();
|
|
460
|
+
if (expiry == null) return;
|
|
461
|
+
const atSessionEnd = expiryAtLastAttempt != null && expiry <= expiryAtLastAttempt + 1e3;
|
|
462
|
+
if (expiry - Date.now() <= RENEW_BEFORE_MS && (!atSessionEnd || Date.now() >= expiry)) {
|
|
463
|
+
void renewNow();
|
|
464
|
+
} else {
|
|
465
|
+
watchSession();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
function listenForReturn() {
|
|
469
|
+
if (listening || typeof window === "undefined") return;
|
|
470
|
+
listening = true;
|
|
471
|
+
if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
|
|
472
|
+
document.addEventListener("visibilitychange", () => {
|
|
473
|
+
if (document.visibilityState === "visible") onReturn();
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
if (typeof window.addEventListener === "function") {
|
|
477
|
+
window.addEventListener("online", onReturn);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function reportRefreshFailure() {
|
|
481
|
+
var _a, _b;
|
|
482
|
+
const expiry = currentExpiry();
|
|
483
|
+
if (expiry == null || Date.now() < expiry) return;
|
|
484
|
+
const config = getConfig();
|
|
485
|
+
if (notifiedFor === config.token) return;
|
|
486
|
+
notifiedFor = (_a = config.token) != null ? _a : null;
|
|
487
|
+
clearTimer();
|
|
488
|
+
try {
|
|
489
|
+
(_b = config.onSessionExpired) == null ? void 0 : _b.call(config);
|
|
490
|
+
} catch (e) {
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
386
494
|
// src/client.ts
|
|
387
495
|
function getFetch2() {
|
|
388
496
|
if (typeof globalThis.fetch === "function") {
|
|
@@ -417,14 +525,18 @@ function tryRefreshToken() {
|
|
|
417
525
|
if (refreshInFlight === attempt) refreshInFlight = null;
|
|
418
526
|
};
|
|
419
527
|
attempt.then(clear, clear);
|
|
528
|
+
attempt.then((renewed) => {
|
|
529
|
+
if (!renewed) reportRefreshFailure();
|
|
530
|
+
}, () => void 0);
|
|
420
531
|
return attempt;
|
|
421
532
|
}
|
|
533
|
+
registerSessionRefresher(tryRefreshToken);
|
|
422
534
|
async function doRefreshToken() {
|
|
423
535
|
const config = getConfig();
|
|
424
536
|
if (!config.token || config.projectId == null || !config.baseURL) return false;
|
|
425
537
|
if (!config.authUrl || typeof window === "undefined") return false;
|
|
426
538
|
try {
|
|
427
|
-
const session = await refreshTokenSilently(config.authUrl, config.projectId);
|
|
539
|
+
const session = await refreshTokenSilently(config.authUrl, config.projectId, config.token);
|
|
428
540
|
updateGlobalToken(session.token);
|
|
429
541
|
if (config.onTokenRefresh) config.onTokenRefresh(session);
|
|
430
542
|
return true;
|
|
@@ -711,6 +823,9 @@ async function callIntegrationMitra(options) {
|
|
|
711
823
|
if (options.body !== void 0) {
|
|
712
824
|
body.body = options.body;
|
|
713
825
|
}
|
|
826
|
+
if (options.headers !== void 0) {
|
|
827
|
+
body.headers = options.headers;
|
|
828
|
+
}
|
|
714
829
|
return http.post("/interactions/integrations/call", body);
|
|
715
830
|
}
|
|
716
831
|
async function stopServerFunctionExecutionMitra(options) {
|
|
@@ -1500,7 +1615,7 @@ function openSocket() {
|
|
|
1500
1615
|
return new Promise((resolve, reject) => {
|
|
1501
1616
|
const socket = new WebSocket(url);
|
|
1502
1617
|
let opened = false;
|
|
1503
|
-
const
|
|
1618
|
+
const timer2 = setTimeout(() => {
|
|
1504
1619
|
if (!opened) {
|
|
1505
1620
|
try {
|
|
1506
1621
|
socket.close();
|
|
@@ -1511,13 +1626,13 @@ function openSocket() {
|
|
|
1511
1626
|
}, 15e3);
|
|
1512
1627
|
socket.onopen = () => {
|
|
1513
1628
|
opened = true;
|
|
1514
|
-
clearTimeout(
|
|
1629
|
+
clearTimeout(timer2);
|
|
1515
1630
|
ws = socket;
|
|
1516
1631
|
resolve(socket);
|
|
1517
1632
|
};
|
|
1518
1633
|
socket.onerror = () => {
|
|
1519
1634
|
if (!opened) {
|
|
1520
|
-
clearTimeout(
|
|
1635
|
+
clearTimeout(timer2);
|
|
1521
1636
|
reject(new Error("Agent Chat: erro ao conectar no WebSocket"));
|
|
1522
1637
|
}
|
|
1523
1638
|
};
|
|
@@ -1525,7 +1640,7 @@ function openSocket() {
|
|
|
1525
1640
|
if (ws === socket) ws = null;
|
|
1526
1641
|
const detalhe = closeDetail(event);
|
|
1527
1642
|
if (!opened) {
|
|
1528
|
-
clearTimeout(
|
|
1643
|
+
clearTimeout(timer2);
|
|
1529
1644
|
reject(new Error(`Agent Chat: conex\xE3o fechada${detalhe}`));
|
|
1530
1645
|
}
|
|
1531
1646
|
for (const [id, pending] of pendingRequests) {
|
|
@@ -1900,7 +2015,7 @@ function createMitraInstance(initialConfig) {
|
|
|
1900
2015
|
if (!_config.token || _config.projectId == null || !_config.baseURL) return false;
|
|
1901
2016
|
if (!_config.authUrl || typeof window === "undefined") return false;
|
|
1902
2017
|
try {
|
|
1903
|
-
const session = await refreshTokenSilently(_config.authUrl, _config.projectId);
|
|
2018
|
+
const session = await refreshTokenSilently(_config.authUrl, _config.projectId, _config.token);
|
|
1904
2019
|
_config = { ..._config, token: stripBearer(session.token) };
|
|
1905
2020
|
updateGlobalToken(session.token);
|
|
1906
2021
|
if (_config.onTokenRefresh) _config.onTokenRefresh(session);
|
|
@@ -2128,6 +2243,7 @@ function createMitraInstance(initialConfig) {
|
|
|
2128
2243
|
if (options.endpoint !== void 0) body.endpoint = options.endpoint;
|
|
2129
2244
|
if (options.params !== void 0) body.params = options.params;
|
|
2130
2245
|
if (options.body !== void 0) body.body = options.body;
|
|
2246
|
+
if (options.headers !== void 0) body.headers = options.headers;
|
|
2131
2247
|
return request("POST", "/interactions/integrations/call", { body });
|
|
2132
2248
|
},
|
|
2133
2249
|
// Dynamic Schema CRUD
|
|
@@ -2310,6 +2426,7 @@ function configureSdkMitra(config = {}) {
|
|
|
2310
2426
|
const chat = window.__mitraChat;
|
|
2311
2427
|
if (chat) chat.init(merged.token);
|
|
2312
2428
|
}
|
|
2429
|
+
startSessionWatch();
|
|
2313
2430
|
return createMitraInstance(globalConfig);
|
|
2314
2431
|
}
|
|
2315
2432
|
function getConfig() {
|
|
@@ -2324,6 +2441,7 @@ function isConfigured() {
|
|
|
2324
2441
|
function updateGlobalToken(token) {
|
|
2325
2442
|
if (globalConfig) {
|
|
2326
2443
|
globalConfig = { ...globalConfig, token: stripBearer(token) };
|
|
2444
|
+
watchSession();
|
|
2327
2445
|
}
|
|
2328
2446
|
}
|
|
2329
2447
|
function inferProjectId(projectId) {
|