@returningai/widget-sdk 1.8.2 → 1.8.3
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/CHANGELOG.md +29 -0
- package/dist/rai-banner.iife.js +1 -1
- package/dist/rai-banner.js +1 -1
- package/dist/rai-widget.iife.js +1 -1
- package/dist/rai-widget.js +48 -5
- package/dist/types/BaseWidget.d.ts +12 -0
- package/package.json +5 -3
package/dist/rai-widget.js
CHANGED
|
@@ -12418,8 +12418,12 @@ async function authenticateServerless(config, state, onRefreshScheduled) {
|
|
|
12418
12418
|
setTokens(config, state, data, onRefreshScheduled);
|
|
12419
12419
|
state.isAuthenticated = true;
|
|
12420
12420
|
return true;
|
|
12421
|
-
} catch {
|
|
12421
|
+
} catch (err) {
|
|
12422
12422
|
if (is4xx || attempt === maxRetries) {
|
|
12423
|
+
state.lastAuthError ?? (state.lastAuthError = {
|
|
12424
|
+
status: 0,
|
|
12425
|
+
error: err instanceof Error ? err.message : "Authentication failed"
|
|
12426
|
+
});
|
|
12423
12427
|
state.isAuthenticated = false;
|
|
12424
12428
|
return false;
|
|
12425
12429
|
}
|
|
@@ -12438,6 +12442,7 @@ async function authenticateViaProxy(config, state, onRefreshScheduled) {
|
|
|
12438
12442
|
);
|
|
12439
12443
|
}
|
|
12440
12444
|
let is4xx = false;
|
|
12445
|
+
let status = 0;
|
|
12441
12446
|
try {
|
|
12442
12447
|
const response = await fetch(config.authUrl, {
|
|
12443
12448
|
method: "POST",
|
|
@@ -12445,6 +12450,7 @@ async function authenticateViaProxy(config, state, onRefreshScheduled) {
|
|
|
12445
12450
|
headers: { "Content-Type": "application/json" }
|
|
12446
12451
|
});
|
|
12447
12452
|
if (!response.ok) {
|
|
12453
|
+
status = response.status;
|
|
12448
12454
|
is4xx = response.status >= 400 && response.status < 500;
|
|
12449
12455
|
throw new Error(`HTTP ${response.status}`);
|
|
12450
12456
|
}
|
|
@@ -12459,12 +12465,17 @@ async function authenticateViaProxy(config, state, onRefreshScheduled) {
|
|
|
12459
12465
|
state.accessTokenExpiry = Date.now() + ttl * 1e3;
|
|
12460
12466
|
state.refreshTokenExpiry = null;
|
|
12461
12467
|
state.isAuthenticated = true;
|
|
12468
|
+
state.lastAuthError = null;
|
|
12462
12469
|
if (config.autoRefresh && onRefreshScheduled) {
|
|
12463
12470
|
onRefreshScheduled();
|
|
12464
12471
|
}
|
|
12465
12472
|
return true;
|
|
12466
|
-
} catch {
|
|
12473
|
+
} catch (err) {
|
|
12467
12474
|
if (is4xx || attempt === maxRetries) {
|
|
12475
|
+
state.lastAuthError = {
|
|
12476
|
+
status,
|
|
12477
|
+
error: err instanceof Error ? err.message : "Authentication failed"
|
|
12478
|
+
};
|
|
12468
12479
|
state.isAuthenticated = false;
|
|
12469
12480
|
return false;
|
|
12470
12481
|
}
|
|
@@ -12513,6 +12524,7 @@ async function refreshAccessToken(config, state, onRefreshScheduled, sendToken)
|
|
|
12513
12524
|
throw new Error("Invalid refresh response");
|
|
12514
12525
|
}
|
|
12515
12526
|
setTokens(config, state, data, onRefreshScheduled);
|
|
12527
|
+
state.isAuthenticated = true;
|
|
12516
12528
|
if (sendToken) sendToken();
|
|
12517
12529
|
return true;
|
|
12518
12530
|
} catch {
|
|
@@ -14847,13 +14859,15 @@ class BaseWidget extends HTMLElement {
|
|
|
14847
14859
|
() => this.scheduleRefresh()
|
|
14848
14860
|
);
|
|
14849
14861
|
if (ok) pushToken();
|
|
14862
|
+
else this.handleSessionExpired();
|
|
14850
14863
|
} else {
|
|
14851
|
-
await refreshAccessToken(
|
|
14864
|
+
const ok = await refreshAccessToken(
|
|
14852
14865
|
this.config,
|
|
14853
14866
|
this.state,
|
|
14854
14867
|
() => this.scheduleRefresh(),
|
|
14855
14868
|
pushToken
|
|
14856
14869
|
);
|
|
14870
|
+
if (!ok) this.handleSessionExpired();
|
|
14857
14871
|
}
|
|
14858
14872
|
};
|
|
14859
14873
|
if (delay > 0) {
|
|
@@ -14869,6 +14883,35 @@ class BaseWidget extends HTMLElement {
|
|
|
14869
14883
|
sendTokenToWidget(this.config, this.state, iframe);
|
|
14870
14884
|
}, 12e4);
|
|
14871
14885
|
}
|
|
14886
|
+
/**
|
|
14887
|
+
* A background refresh exhausted every recovery path — /auth/refresh failed
|
|
14888
|
+
* and the re-auth that follows it failed too, so `state.isAuthenticated` is
|
|
14889
|
+
* now false and there is no live token.
|
|
14890
|
+
*
|
|
14891
|
+
* Every startup auth path already calls showError() on failure; this one is
|
|
14892
|
+
* reached from a timer, so without it the widget stays mounted showing stale
|
|
14893
|
+
* content while isAuthenticated() reports false to the host page — which is
|
|
14894
|
+
* how a signed-in user ends up looking at content meant for signed-out users.
|
|
14895
|
+
* The event gives hosts a signal to re-mint credentials instead of polling.
|
|
14896
|
+
*/
|
|
14897
|
+
handleSessionExpired() {
|
|
14898
|
+
var _a;
|
|
14899
|
+
if (this.state.refreshTimer) {
|
|
14900
|
+
clearTimeout(this.state.refreshTimer);
|
|
14901
|
+
this.state.refreshTimer = null;
|
|
14902
|
+
}
|
|
14903
|
+
(_a = this.state).lastAuthError ?? (_a.lastAuthError = {
|
|
14904
|
+
status: 401,
|
|
14905
|
+
error: "Session expired",
|
|
14906
|
+
hint: "The widget session could not be renewed. Reload to sign in again."
|
|
14907
|
+
});
|
|
14908
|
+
this.emit("rai-session-expired", {
|
|
14909
|
+
communityId: this.config.communityId,
|
|
14910
|
+
widgetType: this.config.widgetType,
|
|
14911
|
+
lastAuthError: this.state.lastAuthError ?? void 0
|
|
14912
|
+
});
|
|
14913
|
+
this.showError();
|
|
14914
|
+
}
|
|
14872
14915
|
// ── Logout helper ─────────────────────────────────────────────────────
|
|
14873
14916
|
async logoutAndClear() {
|
|
14874
14917
|
await logout(this.config, this.state);
|
|
@@ -15024,7 +15067,7 @@ class CustomWidget extends BaseWidget {
|
|
|
15024
15067
|
}
|
|
15025
15068
|
}
|
|
15026
15069
|
}
|
|
15027
|
-
console.log(`[rai-widget] v${"1.8.
|
|
15070
|
+
console.log(`[rai-widget] v${"1.8.3"}`);
|
|
15028
15071
|
class StoreWidgetCompat extends StoreWidget {
|
|
15029
15072
|
}
|
|
15030
15073
|
const WIDGET_REGISTRY = [
|
|
@@ -15088,7 +15131,7 @@ function exposePublicApi() {
|
|
|
15088
15131
|
})();
|
|
15089
15132
|
const widget = container == null ? void 0 : container.querySelector(ALL_WIDGET_SELECTOR);
|
|
15090
15133
|
window.ReturningAIWidget = {
|
|
15091
|
-
version: "1.8.
|
|
15134
|
+
version: "1.8.3",
|
|
15092
15135
|
reload: () => (widget == null ? void 0 : widget.reload()) ?? Promise.resolve(),
|
|
15093
15136
|
logout: () => (widget == null ? void 0 : widget.logoutPublic()) ?? Promise.resolve(),
|
|
15094
15137
|
isAuthenticated: () => (widget == null ? void 0 : widget.isAuthenticated()) ?? false,
|
|
@@ -110,6 +110,18 @@ export declare abstract class BaseWidget extends HTMLElement {
|
|
|
110
110
|
private mountWidget;
|
|
111
111
|
private scheduleRefresh;
|
|
112
112
|
private schedulePeriodicSync;
|
|
113
|
+
/**
|
|
114
|
+
* A background refresh exhausted every recovery path — /auth/refresh failed
|
|
115
|
+
* and the re-auth that follows it failed too, so `state.isAuthenticated` is
|
|
116
|
+
* now false and there is no live token.
|
|
117
|
+
*
|
|
118
|
+
* Every startup auth path already calls showError() on failure; this one is
|
|
119
|
+
* reached from a timer, so without it the widget stays mounted showing stale
|
|
120
|
+
* content while isAuthenticated() reports false to the host page — which is
|
|
121
|
+
* how a signed-in user ends up looking at content meant for signed-out users.
|
|
122
|
+
* The event gives hosts a signal to re-mint credentials instead of polling.
|
|
123
|
+
*/
|
|
124
|
+
private handleSessionExpired;
|
|
113
125
|
private logoutAndClear;
|
|
114
126
|
reload(): Promise<void>;
|
|
115
127
|
logoutPublic(): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@returningai/widget-sdk",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
4
|
"description": "Shadow DOM isolated widget SDK for ReturningAI",
|
|
5
5
|
"main": "dist/rai-widget.iife.js",
|
|
6
6
|
"module": "dist/rai-widget.js",
|
|
@@ -25,12 +25,14 @@
|
|
|
25
25
|
"build:all": "npm run build && npm run build:banner",
|
|
26
26
|
"build:all:min": "npm run build:min && npm run build:banner:min",
|
|
27
27
|
"types": "tsc --emitDeclarationOnly --outDir dist/types && cp src/jsx.d.ts dist/types/jsx.d.ts",
|
|
28
|
-
"test": "npm run test:host-callback && npm run test:bundle-readiness && npm run test:bundle-runtime-cache && npm run test:bundle-token-sync && npm run test:auth-bootstrap && npm run test:startup-performance && npm run test:jsx-types",
|
|
28
|
+
"test": "npm run test:host-callback && npm run test:bundle-readiness && npm run test:bundle-runtime-cache && npm run test:bundle-token-sync && npm run test:auth-bootstrap && npm run test:auth-error-reporting && npm run test:auth-refresh-state && npm run test:startup-performance && npm run test:jsx-types",
|
|
29
29
|
"test:host-callback": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/postmessage-host-callback.test.js",
|
|
30
30
|
"test:bundle-readiness": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/bundle-readiness.test.js",
|
|
31
31
|
"test:bundle-runtime-cache": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/bundle-runtime-cache.test.js",
|
|
32
32
|
"test:bundle-token-sync": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/bundle-token-sync.test.js",
|
|
33
33
|
"test:auth-bootstrap": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/auth-bootstrap.test.js",
|
|
34
|
+
"test:auth-error-reporting": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/auth-error-reporting.test.js",
|
|
35
|
+
"test:auth-refresh-state": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/auth-refresh-state.test.js",
|
|
34
36
|
"test:startup-performance": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/startup-performance.test.js",
|
|
35
37
|
"test:jsx-types": "tsc --noEmit --strict --lib ES2020,DOM --skipLibCheck false src/jsx.d.ts",
|
|
36
38
|
"coverage:repowise": "rm -rf coverage && npm run coverage:host-callback && npm run coverage:bundle-readiness && npm run test:jsx-types",
|
|
@@ -48,4 +50,4 @@
|
|
|
48
50
|
"dompurify": "^3.4.12",
|
|
49
51
|
"lottie-web": "^5.13.0"
|
|
50
52
|
}
|
|
51
|
-
}
|
|
53
|
+
}
|