oidc-spa 8.2.11 → 8.3.0
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 +58 -6
- package/core/createOidc.js +9 -2
- package/core/createOidc.js.map +1 -1
- package/core/earlyInit.d.ts +6 -2
- package/core/earlyInit.js +157 -32
- package/core/earlyInit.js.map +1 -1
- package/core/loginSilent.js +7 -42
- package/core/loginSilent.js.map +1 -1
- package/esm/core/createOidc.js +9 -2
- package/esm/core/createOidc.js.map +1 -1
- package/esm/core/earlyInit.d.ts +6 -2
- package/esm/core/earlyInit.js +156 -32
- package/esm/core/earlyInit.js.map +1 -1
- package/esm/core/loginSilent.js +7 -42
- package/esm/core/loginSilent.js.map +1 -1
- package/esm/tanstack-start/react/withHandlingOidcPostLoginNavigation.js +13 -2
- package/esm/tanstack-start/react/withHandlingOidcPostLoginNavigation.js.map +1 -1
- package/esm/tools/Evt.js +18 -10
- package/esm/tools/Evt.js.map +1 -1
- package/package.json +2 -2
- package/src/core/createOidc.ts +8 -1
- package/src/core/earlyInit.ts +205 -42
- package/src/core/loginSilent.ts +18 -79
- package/src/tanstack-start/react/withHandlingOidcPostLoginNavigation.tsx +13 -2
- package/src/tools/Evt.ts +17 -16
- package/src/vite-plugin/handleClientEntrypoint.ts +4 -6
- package/tools/Evt.js +18 -10
- package/tools/Evt.js.map +1 -1
- package/vite-plugin/handleClientEntrypoint.js +3 -1
- package/vite-plugin/handleClientEntrypoint.js.map +1 -1
- package/core/iframeMessageProtection.d.ts +0 -29
- package/core/iframeMessageProtection.js +0 -129
- package/core/iframeMessageProtection.js.map +0 -1
- package/esm/core/iframeMessageProtection.d.ts +0 -29
- package/esm/core/iframeMessageProtection.js +0 -123
- package/esm/core/iframeMessageProtection.js.map +0 -1
- package/esm/tools/asymmetricEncryption.d.ts +0 -18
- package/esm/tools/asymmetricEncryption.js +0 -85
- package/esm/tools/asymmetricEncryption.js.map +0 -1
- package/src/core/iframeMessageProtection.ts +0 -186
- package/src/tools/asymmetricEncryption.ts +0 -184
- package/tools/asymmetricEncryption.d.ts +0 -18
- package/tools/asymmetricEncryption.js +0 -90
- package/tools/asymmetricEncryption.js.map +0 -1
package/esm/core/loginSilent.js
CHANGED
|
@@ -6,8 +6,8 @@ import { getStateData, clearStateStore } from "./StateData";
|
|
|
6
6
|
import { getDownlinkAndRtt } from "../tools/getDownlinkAndRtt";
|
|
7
7
|
import { getIsDev } from "../tools/isDev";
|
|
8
8
|
import { addOrUpdateSearchParam } from "../tools/urlSearchParams";
|
|
9
|
-
import { initIframeMessageProtection } from "./iframeMessageProtection";
|
|
10
9
|
import { getIsOnline } from "../tools/getIsOnline";
|
|
10
|
+
import { getEvtIframeAuthResponse } from "./earlyInit";
|
|
11
11
|
export async function loginSilent(params) {
|
|
12
12
|
const { oidcClientTsUserManager, stateUrlParamValue_instance, configId, transformUrlBeforeRedirect, getExtraQueryParams, getExtraTokenParams, autoLogin, log } = params;
|
|
13
13
|
delay_until_online: {
|
|
@@ -33,9 +33,6 @@ export async function loginSilent(params) {
|
|
|
33
33
|
const dynamicDelay = rtt * 2.5 + BASE_DELAY_MS / (downlink + 1);
|
|
34
34
|
return Math.max(BASE_DELAY_MS, dynamicDelay);
|
|
35
35
|
})();
|
|
36
|
-
const { getIsReadyToReadPublicKeyMessage, startSessionStoragePublicKeyMaliciousWriteDetection, setSessionStoragePublicKey, decodeEncryptedAuth, getIsEncryptedAuthResponse, clearSessionStoragePublicKey } = await initIframeMessageProtection({
|
|
37
|
-
stateUrlParamValue: stateUrlParamValue_instance
|
|
38
|
-
});
|
|
39
36
|
let clearTimeouts;
|
|
40
37
|
{
|
|
41
38
|
let hasLoggedWarningMessage = false;
|
|
@@ -65,41 +62,11 @@ export async function loginSilent(params) {
|
|
|
65
62
|
}
|
|
66
63
|
};
|
|
67
64
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (event.origin !== window.location.origin) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (!getIsReadyToReadPublicKeyMessage({
|
|
74
|
-
stateUrlParamValue: stateUrlParamValue_instance,
|
|
75
|
-
message: event.data
|
|
76
|
-
})) {
|
|
65
|
+
const { unsubscribe: unsubscribe_evtIframeAuthResponse } = getEvtIframeAuthResponse().subscribe(authResponse => {
|
|
66
|
+
if (authResponse.state !== stateUrlParamValue_instance) {
|
|
77
67
|
return;
|
|
78
68
|
}
|
|
79
|
-
|
|
80
|
-
setSessionStoragePublicKey();
|
|
81
|
-
const dEncryptedAuthResponse = new Deferred();
|
|
82
|
-
listener = event => {
|
|
83
|
-
if (event.origin !== window.location.origin) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const message = event.data;
|
|
87
|
-
if (!getIsEncryptedAuthResponse({
|
|
88
|
-
stateUrlParamValue: stateUrlParamValue_instance,
|
|
89
|
-
message
|
|
90
|
-
})) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
window.removeEventListener("message", listener);
|
|
94
|
-
// NOTE: Acknowledge that we're also doing it later but
|
|
95
|
-
// since there's a aggressive write protection in place
|
|
96
|
-
// it's good to clear the key ASAP.
|
|
97
|
-
clearSessionStoragePublicKey();
|
|
98
|
-
dEncryptedAuthResponse.resolve(message);
|
|
99
|
-
};
|
|
100
|
-
window.addEventListener("message", listener, false);
|
|
101
|
-
const encryptedAuthResponse = await dEncryptedAuthResponse.pr;
|
|
102
|
-
const { authResponse } = await decodeEncryptedAuth({ encryptedAuthResponse });
|
|
69
|
+
unsubscribe_evtIframeAuthResponse();
|
|
103
70
|
const stateData = getStateData({ stateUrlParamValue: authResponse.state });
|
|
104
71
|
assert(stateData !== undefined, "765645");
|
|
105
72
|
assert(stateData.context === "iframe", "250711");
|
|
@@ -109,8 +76,7 @@ export async function loginSilent(params) {
|
|
|
109
76
|
outcome: "got auth response from iframe",
|
|
110
77
|
authResponse
|
|
111
78
|
});
|
|
112
|
-
};
|
|
113
|
-
window.addEventListener("message", listener, false);
|
|
79
|
+
});
|
|
114
80
|
const transformUrl_oidcClientTs = (url) => {
|
|
115
81
|
add_extra_query_params: {
|
|
116
82
|
if (getExtraQueryParams === undefined) {
|
|
@@ -132,7 +98,6 @@ export async function loginSilent(params) {
|
|
|
132
98
|
}
|
|
133
99
|
return url;
|
|
134
100
|
};
|
|
135
|
-
startSessionStoragePublicKeyMaliciousWriteDetection();
|
|
136
101
|
oidcClientTsUserManager
|
|
137
102
|
.signinSilent({
|
|
138
103
|
state: id({
|
|
@@ -146,7 +111,7 @@ export async function loginSilent(params) {
|
|
|
146
111
|
.then(oidcClientTsUser => {
|
|
147
112
|
assert(oidcClientTsUser !== null, "oidcClientTsUser is not supposed to be null here");
|
|
148
113
|
clearTimeouts({ wasSuccess: true });
|
|
149
|
-
|
|
114
|
+
unsubscribe_evtIframeAuthResponse();
|
|
150
115
|
dResult.resolve({
|
|
151
116
|
outcome: "token refreshed using refresh token",
|
|
152
117
|
oidcClientTsUser
|
|
@@ -156,9 +121,9 @@ export async function loginSilent(params) {
|
|
|
156
121
|
// error than timeout so we fail silently and let the timeout expire.
|
|
157
122
|
});
|
|
158
123
|
dResult.pr.then(result => {
|
|
159
|
-
clearSessionStoragePublicKey();
|
|
160
124
|
if (result.outcome === "timeout") {
|
|
161
125
|
clearStateStore({ stateUrlParamValue: stateUrlParamValue_instance });
|
|
126
|
+
unsubscribe_evtIframeAuthResponse();
|
|
162
127
|
}
|
|
163
128
|
});
|
|
164
129
|
return dResult.pr;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loginSilent.js","sourceRoot":"","sources":["../../src/core/loginSilent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAkB,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"loginSilent.js","sourceRoot":"","sources":["../../src/core/loginSilent.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAkB,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAevD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAgBjC;IACG,MAAM,EACF,uBAAuB,EACvB,2BAA2B,EAC3B,QAAQ,EACR,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,GAAG,EACN,GAAG,MAAM,CAAC;IAEX,kBAAkB,EAAE,CAAC;QACjB,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,WAAW,EAAE,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,kBAAkB,CAAC;QAC7B,CAAC;QACD,GAAG,EAAE,CAAC,wFAAwF,CAAC,CAAC;QAChG,MAAM,QAAQ,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,QAAQ,EAAuB,CAAC;IAEpD,MAAM,cAAc,GAAW,CAAC,GAAG,EAAE;QACjC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;QAEzB,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;QAE3C,6DAA6D;QAC7D,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,CAAC,IAAK,CAAC;QAEjE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,aAAa,CAAC;QACzB,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC;QAEzC,oDAAoD;QACpD,8CAA8C;QAC9C,MAAM,YAAY,GAAG,GAAG,GAAG,GAAG,GAAG,aAAa,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAEhE,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACjD,CAAC,CAAC,EAAE,CAAC;IAEL,IAAI,aAAwD,CAAC;IAC7D,CAAC;QACG,IAAI,uBAAuB,GAAG,KAAK,CAAC;QAEpC,MAAM,QAAQ,GAAG;YACb,UAAU,CAAC,GAAG,EAAE;gBACZ,OAAO,CAAC,OAAO,CAAC;oBACZ,OAAO,EAAE,SAAS;iBACrB,CAAC,CAAC;YACP,CAAC,EAAE,cAAc,CAAC;YAClB,UAAU,CAAC,GAAG,EAAE;gBACZ,OAAO,CAAC,IAAI,CACR;oBACI,+DAA+D;oBAC/D,2CAA2C;oBAC3C,WAAW,IAAI,CAAC,KAAK,CACjB,cAAc,GAAG,IAAK,CACzB,sCAAsC;oBACvC,yFAAyF;iBAC5F,CAAC,IAAI,CAAC,GAAG,CAAC,CACd,CAAC;gBACF,uBAAuB,GAAG,IAAI,CAAC;YACnC,CAAC,EAAE,IAAK,CAAC;SACZ,CAAC;QAEF,aAAa,GAAG,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE;YAC/B,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAC/B,IAAI,UAAU,IAAI,uBAAuB,EAAE,CAAC;gBACxC,OAAO,CAAC,GAAG,CACP;oBACI,iEAAiE;oBACjE,6CAA6C;iBAChD,CAAC,IAAI,CAAC,GAAG,CAAC,CACd,CAAC;YACN,CAAC;QACL,CAAC,CAAC;IACN,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,iCAAiC,EAAE,GAAG,wBAAwB,EAAE,CAAC,SAAS,CAC3F,YAAY,CAAC,EAAE;QACX,IAAI,YAAY,CAAC,KAAK,KAAK,2BAA2B,EAAE,CAAC;YACrD,OAAO;QACX,CAAC;QAED,iCAAiC,EAAE,CAAC;QAEpC,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,kBAAkB,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;QAE3E,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,OAAO,KAAK,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,QAAQ,EAAE,SAAS,CAAC,CAAC;QAEnD,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpC,OAAO,CAAC,OAAO,CAAC;YACZ,OAAO,EAAE,+BAA+B;YACxC,YAAY;SACf,CAAC,CAAC;IACP,CAAC,CACJ,CAAC;IAEF,MAAM,yBAAyB,GAAG,CAAC,GAAW,EAAE,EAAE;QAC9C,sBAAsB,EAAE,CAAC;YACrB,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;gBACpC,MAAM,sBAAsB,CAAC;YACjC,CAAC;YAED,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YAEtE,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC3D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACtB,SAAS;gBACb,CAAC;gBACD,GAAG,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;YACjF,CAAC;QACL,CAAC;QAED,mBAAmB,EAAE,CAAC;YAClB,IAAI,0BAA0B,KAAK,SAAS,EAAE,CAAC;gBAC3C,MAAM,mBAAmB,CAAC;YAC9B,CAAC;YACD,GAAG,GAAG,0BAA0B,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,OAAO,GAAG,CAAC;IACf,CAAC,CAAC;IAEF,uBAAuB;SAClB,YAAY,CAAC;QACV,KAAK,EAAE,EAAE,CAAmB;YACxB,OAAO,EAAE,QAAQ;YACjB,QAAQ;SACX,CAAC;QACF,6BAA6B,EAAE,cAAc,GAAG,IAAI;QACpD,gBAAgB,EACZ,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAC;QACtF,YAAY,EAAE,yBAAyB;KAC1C,CAAC;SACD,IAAI,CACD,gBAAgB,CAAC,EAAE;QACf,MAAM,CAAC,gBAAgB,KAAK,IAAI,EAAE,kDAAkD,CAAC,CAAC;QAEtF,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,iCAAiC,EAAE,CAAC;QAEpC,OAAO,CAAC,OAAO,CAAC;YACZ,OAAO,EAAE,qCAAqC;YAC9C,gBAAgB;SACnB,CAAC,CAAC;IACP,CAAC,EACD,GAAG,EAAE;QACD,yEAAyE;QACzE,qEAAqE;IACzE,CAAC,CACJ,CAAC;IAEN,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACrB,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,eAAe,CAAC,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,CAAC,CAAC;YACrE,iCAAiC,EAAE,CAAC;QACxC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -14,8 +14,19 @@ export function withHandlingOidcPostLoginNavigation(Component) {
|
|
|
14
14
|
if (rootRelativeRedirectUrl === undefined) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// Defer navigation to the next paint to avoid hydration mismatches.
|
|
18
|
+
// A double rAF schedules after hydration/paint without arbitrary timeouts.
|
|
19
|
+
requestAnimationFrame(() => {
|
|
20
|
+
requestAnimationFrame(() => {
|
|
21
|
+
if (rootRelativeRedirectUrl !== undefined) {
|
|
22
|
+
router.navigate({
|
|
23
|
+
to: rootRelativeRedirectUrl,
|
|
24
|
+
replace: true
|
|
25
|
+
});
|
|
26
|
+
rootRelativeRedirectUrl = undefined;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
19
30
|
}, []);
|
|
20
31
|
return _jsx(Component, { ...props });
|
|
21
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withHandlingOidcPostLoginNavigation.js","sourceRoot":"","sources":["../../../src/tanstack-start/react/withHandlingOidcPostLoginNavigation.tsx"],"names":[],"mappings":";AAAA,OAAO,EAA+B,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,gDAAgD,EAAE,MAAM,sDAAsD,CAAC;AACxH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,UAAU,mCAAmC,CAC/C,SAA+B;IAE/B,IAAI,EAAE,uBAAuB,EAAE,GAAG,gDAAgD,EAAE,CAAC;IAErF,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;QACxC,mBAAmB;QACnB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,SAAS,4CAA4C,CAAC,KAAY;QAC9D,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAE3B,SAAS,CAAC,GAAG,EAAE;YACX,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;gBACxC,OAAO;YACX,CAAC;YAED,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"withHandlingOidcPostLoginNavigation.js","sourceRoot":"","sources":["../../../src/tanstack-start/react/withHandlingOidcPostLoginNavigation.tsx"],"names":[],"mappings":";AAAA,OAAO,EAA+B,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,gDAAgD,EAAE,MAAM,sDAAsD,CAAC;AACxH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,UAAU,mCAAmC,CAC/C,SAA+B;IAE/B,IAAI,EAAE,uBAAuB,EAAE,GAAG,gDAAgD,EAAE,CAAC;IAErF,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;QACxC,mBAAmB;QACnB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,SAAS,4CAA4C,CAAC,KAAY;QAC9D,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAE3B,SAAS,CAAC,GAAG,EAAE;YACX,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;gBACxC,OAAO;YACX,CAAC;YAED,oEAAoE;YACpE,2EAA2E;YAC3E,qBAAqB,CAAC,GAAG,EAAE;gBACvB,qBAAqB,CAAC,GAAG,EAAE;oBACvB,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;wBACxC,MAAM,CAAC,QAAQ,CAAC;4BACZ,EAAE,EAAE,uBAAuB;4BAC3B,OAAO,EAAE,IAAI;yBAChB,CAAC,CAAC;wBACH,uBAAuB,GAAG,SAAS,CAAC;oBACxC,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,OAAO,KAAC,SAAS,OAAK,KAAK,GAAI,CAAC;IACpC,CAAC;IAED,4CAA4C,CAAC,WAAW,GAAG,GACvD,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,IAAI,WAC/C,qCAAqC,CAAC;IAEtC,OAAO,4CAA4C,CAAC;AACxD,CAAC"}
|
package/esm/tools/Evt.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { Deferred } from "./Deferred";
|
|
2
|
-
import { assert, is } from "../tools/tsafe/assert";
|
|
3
2
|
export function createEvt() {
|
|
4
|
-
const
|
|
5
|
-
const KEY = "event";
|
|
3
|
+
const listeners = [];
|
|
6
4
|
let postCount = 0;
|
|
7
5
|
const evt = {
|
|
8
6
|
subscribe: next => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
next(e.detail);
|
|
12
|
-
};
|
|
13
|
-
eventTarget.addEventListener(KEY, listener);
|
|
7
|
+
listeners.push(next);
|
|
8
|
+
let isActive = true;
|
|
14
9
|
return {
|
|
15
10
|
unsubscribe: () => {
|
|
16
|
-
|
|
11
|
+
if (!isActive) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
isActive = false;
|
|
15
|
+
const i = listeners.indexOf(next);
|
|
16
|
+
if (i >= 0) {
|
|
17
|
+
listeners.splice(i, 1);
|
|
18
|
+
}
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
21
|
},
|
|
@@ -27,7 +29,13 @@ export function createEvt() {
|
|
|
27
29
|
},
|
|
28
30
|
post: (data) => {
|
|
29
31
|
postCount++;
|
|
30
|
-
|
|
32
|
+
const snapshot = listeners.slice();
|
|
33
|
+
for (const l of snapshot) {
|
|
34
|
+
try {
|
|
35
|
+
l(data);
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
}
|
|
31
39
|
},
|
|
32
40
|
get postCount() {
|
|
33
41
|
return postCount;
|
package/esm/tools/Evt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Evt.js","sourceRoot":"","sources":["../../src/tools/Evt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Evt.js","sourceRoot":"","sources":["../../src/tools/Evt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAYtC,MAAM,UAAU,SAAS;IACrB,MAAM,SAAS,GAA6B,EAAE,CAAC;IAC/C,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,GAAG,GAAW;QAChB,SAAS,EAAE,IAAI,CAAC,EAAE;YACd,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,QAAQ,GAAG,IAAI,CAAC;YACpB,OAAO;gBACH,WAAW,EAAE,GAAG,EAAE;oBACd,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACZ,OAAO;oBACX,CAAC;oBACD,QAAQ,GAAG,KAAK,CAAC;oBACjB,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAClC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBACT,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC;aACJ,CAAC;QACN,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,QAAQ,EAAK,CAAC;YAC5B,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;gBACzC,WAAW,EAAE,CAAC;gBACd,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,CAAC,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,EAAE,CAAC,IAAO,EAAE,EAAE;YACd,SAAS,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;YACnC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACD,CAAC,CAAC,IAAI,CAAC,CAAC;gBACZ,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACd,CAAC;QACL,CAAC;QACD,IAAI,SAAS;YACT,OAAO,SAAS,CAAC;QACrB,CAAC;KACJ,CAAC;IAEF,OAAO,GAAG,CAAC;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oidc-spa",
|
|
3
|
-
"version": "8.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "8.3.0",
|
|
4
|
+
"description": "OIDC Client for Client Centric Web Applications",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git://github.com/keycloakify/oidc-spa.git"
|
package/src/core/createOidc.ts
CHANGED
|
@@ -748,7 +748,14 @@ export async function createOidc_nonMemoized<
|
|
|
748
748
|
{
|
|
749
749
|
log?.(
|
|
750
750
|
`Handling login redirect auth response ${JSON.stringify(
|
|
751
|
-
|
|
751
|
+
{
|
|
752
|
+
...authResponse,
|
|
753
|
+
...(authResponse.code === undefined
|
|
754
|
+
? undefined
|
|
755
|
+
: {
|
|
756
|
+
code: authResponse.code.slice(0, 20) + "..."
|
|
757
|
+
})
|
|
758
|
+
},
|
|
752
759
|
null,
|
|
753
760
|
2
|
|
754
761
|
)}`
|
package/src/core/earlyInit.ts
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import { getStateData, getIsStatQueryParamValue } from "./StateData";
|
|
2
2
|
import { assert, type Equals } from "../tools/tsafe/assert";
|
|
3
3
|
import type { AuthResponse } from "./AuthResponse";
|
|
4
|
-
import {
|
|
5
|
-
captureApisForIframeProtection,
|
|
6
|
-
postEncryptedAuthResponseToParent,
|
|
7
|
-
preventSessionStorageSetItemOfPublicKeyByThirdParty
|
|
8
|
-
} from "./iframeMessageProtection";
|
|
9
4
|
import { setOidcRequiredPostHydrationReplaceNavigationUrl } from "./requiredPostHydrationReplaceNavigationUrl";
|
|
10
5
|
import { setBASE_URL } from "./BASE_URL";
|
|
11
6
|
import { resolvePrShouldLoadApp } from "./prShouldLoadApp";
|
|
12
7
|
import { isBrowser } from "../tools/isBrowser";
|
|
8
|
+
import { createEvt, type Evt } from "../tools/Evt";
|
|
13
9
|
|
|
14
10
|
let hasEarlyInitBeenCalled = false;
|
|
15
11
|
|
|
12
|
+
const IFRAME_MESSAGE_PREFIX = "oidc-spa:cross-window-messaging:";
|
|
13
|
+
|
|
16
14
|
export function oidcEarlyInit(params: {
|
|
17
|
-
freezeFetch
|
|
18
|
-
freezeXMLHttpRequest
|
|
19
|
-
// NOTE: Made optional just to avoid breaking change.
|
|
20
|
-
// Will be made mandatory next major.
|
|
15
|
+
freezeFetch?: boolean;
|
|
16
|
+
freezeXMLHttpRequest?: boolean;
|
|
21
17
|
freezeWebSocket?: boolean;
|
|
18
|
+
freezePromise?: boolean;
|
|
19
|
+
safeMode?: boolean;
|
|
22
20
|
isPostLoginRedirectManual?: boolean;
|
|
23
21
|
BASE_URL?: string;
|
|
24
22
|
}) {
|
|
@@ -32,12 +30,12 @@ export function oidcEarlyInit(params: {
|
|
|
32
30
|
return { shouldLoadApp: true };
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
captureApisForIframeProtection();
|
|
36
|
-
|
|
37
33
|
const {
|
|
38
34
|
freezeFetch,
|
|
39
35
|
freezeXMLHttpRequest,
|
|
40
|
-
freezeWebSocket
|
|
36
|
+
freezeWebSocket,
|
|
37
|
+
freezePromise,
|
|
38
|
+
safeMode = false,
|
|
41
39
|
isPostLoginRedirectManual = false,
|
|
42
40
|
BASE_URL
|
|
43
41
|
} = params;
|
|
@@ -45,48 +43,194 @@ export function oidcEarlyInit(params: {
|
|
|
45
43
|
const { shouldLoadApp } = handleOidcCallback({ isPostLoginRedirectManual });
|
|
46
44
|
|
|
47
45
|
if (shouldLoadApp) {
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
const createWriteError = (target: string) =>
|
|
47
|
+
new Error(
|
|
48
|
+
[
|
|
49
|
+
`oidc-spa: ${target} has been frozen for security reasons.`,
|
|
50
|
+
"Set `safeMode: false` in oidcEarlyInit() or in the Vite plugin configuration",
|
|
51
|
+
"to disable this restriction at the cost of security.",
|
|
52
|
+
"If you think this restriction is overzealous please open an issue at",
|
|
53
|
+
"https://github.com/keycloakify/oidc-spa"
|
|
54
|
+
].join(" ")
|
|
55
|
+
);
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
for (const name of [
|
|
58
|
+
"fetch",
|
|
59
|
+
"XMLHttpRequest",
|
|
60
|
+
"WebSocket",
|
|
61
|
+
"String",
|
|
62
|
+
"Object",
|
|
63
|
+
"Promise",
|
|
64
|
+
"Array",
|
|
65
|
+
"RegExp",
|
|
66
|
+
"TextEncoder",
|
|
67
|
+
"Uint8Array",
|
|
68
|
+
"Uint32Array",
|
|
69
|
+
"Response",
|
|
70
|
+
"Reflect",
|
|
71
|
+
"JSON",
|
|
72
|
+
"encodeURIComponent",
|
|
73
|
+
"decodeURIComponent",
|
|
74
|
+
"atob",
|
|
75
|
+
"btoa"
|
|
76
|
+
] as const) {
|
|
77
|
+
const doSkip = (() => {
|
|
78
|
+
switch (name) {
|
|
79
|
+
case "XMLHttpRequest":
|
|
80
|
+
if (freezeXMLHttpRequest !== undefined) {
|
|
81
|
+
return !freezeXMLHttpRequest;
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
case "fetch":
|
|
85
|
+
if (freezeFetch !== undefined) {
|
|
86
|
+
return !freezeFetch;
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
case "WebSocket":
|
|
90
|
+
if (freezeWebSocket !== undefined) {
|
|
91
|
+
return !freezeWebSocket;
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
case "Promise":
|
|
95
|
+
if (freezePromise !== undefined) {
|
|
96
|
+
return !freezePromise;
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
53
100
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
writable: false,
|
|
57
|
-
enumerable: true,
|
|
58
|
-
value: XMLHttpRequest_trusted
|
|
59
|
-
});
|
|
60
|
-
}
|
|
101
|
+
return !safeMode;
|
|
102
|
+
})();
|
|
61
103
|
|
|
62
|
-
|
|
63
|
-
|
|
104
|
+
if (doSkip) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const original = window[name];
|
|
109
|
+
|
|
110
|
+
if ("prototype" in original) {
|
|
111
|
+
for (const propertyName of Object.getOwnPropertyNames(original.prototype)) {
|
|
112
|
+
if (name === "Object" && propertyName === "toString") {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const pd = Object.getOwnPropertyDescriptor(original.prototype, propertyName);
|
|
117
|
+
|
|
118
|
+
assert(pd !== undefined);
|
|
119
|
+
|
|
120
|
+
if (!pd.configurable) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Object.defineProperty(original.prototype, propertyName, {
|
|
125
|
+
enumerable: pd.enumerable,
|
|
126
|
+
configurable: false,
|
|
127
|
+
...("value" in pd
|
|
128
|
+
? {
|
|
129
|
+
get: () => pd.value,
|
|
130
|
+
set: () => {
|
|
131
|
+
throw createWriteError(`window.${name}.prototype.${propertyName}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
: {
|
|
135
|
+
get: pd.get,
|
|
136
|
+
set:
|
|
137
|
+
pd.set ??
|
|
138
|
+
(() => {
|
|
139
|
+
throw createWriteError(
|
|
140
|
+
`window.${name}.prototype.${propertyName}`
|
|
141
|
+
);
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
64
147
|
|
|
65
|
-
Object.freeze(
|
|
148
|
+
Object.freeze(original);
|
|
66
149
|
|
|
67
|
-
Object.defineProperty(
|
|
150
|
+
Object.defineProperty(window, name, {
|
|
68
151
|
configurable: false,
|
|
69
|
-
writable: false,
|
|
70
152
|
enumerable: true,
|
|
71
|
-
|
|
153
|
+
get: () => original,
|
|
154
|
+
set: () => {
|
|
155
|
+
throw createWriteError(`window.${name}`);
|
|
156
|
+
}
|
|
72
157
|
});
|
|
73
158
|
}
|
|
74
159
|
|
|
75
|
-
if (
|
|
76
|
-
const
|
|
160
|
+
if (safeMode) {
|
|
161
|
+
for (const name of ["call", "apply", "bind"] as const) {
|
|
162
|
+
const original = Function.prototype[name];
|
|
163
|
+
|
|
164
|
+
Object.defineProperty(Function.prototype, name, {
|
|
165
|
+
configurable: false,
|
|
166
|
+
enumerable: true,
|
|
167
|
+
get: () => original,
|
|
168
|
+
set: () => {
|
|
169
|
+
throw createWriteError(`window.Function.prototype.${name});`);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
77
174
|
|
|
78
|
-
|
|
79
|
-
Object.
|
|
175
|
+
const _MessageEvent_prototype_data_get = (() => {
|
|
176
|
+
const pd = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
|
|
80
177
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
178
|
+
assert(pd !== undefined);
|
|
179
|
+
|
|
180
|
+
const { get } = pd;
|
|
181
|
+
|
|
182
|
+
assert(get !== undefined);
|
|
183
|
+
|
|
184
|
+
return get;
|
|
185
|
+
})();
|
|
88
186
|
|
|
89
|
-
|
|
187
|
+
const _MessageEvent_prototype_origin_get = (() => {
|
|
188
|
+
const pd = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "origin");
|
|
189
|
+
|
|
190
|
+
assert(pd !== undefined);
|
|
191
|
+
|
|
192
|
+
const { get } = pd;
|
|
193
|
+
|
|
194
|
+
assert(get !== undefined);
|
|
195
|
+
|
|
196
|
+
return get;
|
|
197
|
+
})();
|
|
198
|
+
|
|
199
|
+
const _Event_prototype_stopImmediatePropagation_value = Event.prototype.stopImmediatePropagation;
|
|
200
|
+
|
|
201
|
+
const origin = window.location.origin;
|
|
202
|
+
|
|
203
|
+
window.addEventListener(
|
|
204
|
+
"message",
|
|
205
|
+
event => {
|
|
206
|
+
if (_MessageEvent_prototype_origin_get.call(event) !== origin) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const eventData: unknown = _MessageEvent_prototype_data_get.call(event);
|
|
211
|
+
|
|
212
|
+
if (typeof eventData !== "string") {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (!eventData.startsWith(IFRAME_MESSAGE_PREFIX)) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
_Event_prototype_stopImmediatePropagation_value.call(event);
|
|
221
|
+
|
|
222
|
+
const authResponse: AuthResponse = JSON.parse(
|
|
223
|
+
eventData.slice(IFRAME_MESSAGE_PREFIX.length)
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
(evtIframeAuthResponse ??= createEvt()).post(authResponse);
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
capture: true,
|
|
230
|
+
once: false,
|
|
231
|
+
passive: false
|
|
232
|
+
}
|
|
233
|
+
);
|
|
90
234
|
|
|
91
235
|
if (BASE_URL !== undefined) {
|
|
92
236
|
setBASE_URL({ BASE_URL });
|
|
@@ -98,6 +242,12 @@ export function oidcEarlyInit(params: {
|
|
|
98
242
|
return { shouldLoadApp };
|
|
99
243
|
}
|
|
100
244
|
|
|
245
|
+
let evtIframeAuthResponse: Evt<AuthResponse> | undefined = undefined;
|
|
246
|
+
|
|
247
|
+
export function getEvtIframeAuthResponse() {
|
|
248
|
+
return (evtIframeAuthResponse ??= createEvt());
|
|
249
|
+
}
|
|
250
|
+
|
|
101
251
|
let redirectAuthResponse: AuthResponse | undefined = undefined;
|
|
102
252
|
|
|
103
253
|
export function getRedirectAuthResponse():
|
|
@@ -211,7 +361,19 @@ function handleOidcCallback(params: { isPostLoginRedirectManual?: boolean }): {
|
|
|
211
361
|
|
|
212
362
|
switch (stateData.context) {
|
|
213
363
|
case "iframe":
|
|
214
|
-
|
|
364
|
+
if (parent !== top) {
|
|
365
|
+
const errorMessage = [
|
|
366
|
+
"oidc-spa: For security reasons, refusing to post the auth response.",
|
|
367
|
+
"If you want your app to be framable use sessionRestorationMethod: 'full page redirect'."
|
|
368
|
+
].join(" ");
|
|
369
|
+
alert(errorMessage);
|
|
370
|
+
|
|
371
|
+
throw new Error(errorMessage);
|
|
372
|
+
}
|
|
373
|
+
parent.postMessage(
|
|
374
|
+
`${IFRAME_MESSAGE_PREFIX}${JSON.stringify(authResponse)}`,
|
|
375
|
+
location.origin
|
|
376
|
+
);
|
|
215
377
|
return { shouldLoadApp: false };
|
|
216
378
|
case "redirect": {
|
|
217
379
|
redirectAuthResponse = authResponse;
|
|
@@ -225,6 +387,7 @@ function handleOidcCallback(params: { isPostLoginRedirectManual?: boolean }): {
|
|
|
225
387
|
|
|
226
388
|
if (isPostLoginRedirectManual) {
|
|
227
389
|
setOidcRequiredPostHydrationReplaceNavigationUrl({ rootRelativeRedirectUrl });
|
|
390
|
+
history.replaceState({}, "", rootRelativeOriginalLocationHref);
|
|
228
391
|
} else {
|
|
229
392
|
history.replaceState({}, "", rootRelativeRedirectUrl);
|
|
230
393
|
}
|