@thunderid/browser 1.0.7 → 1.2.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/dist/ThunderIDBrowserClient.d.ts +1 -4
- package/dist/ThunderIDBrowserClient.d.ts.map +1 -1
- package/dist/cjs/index.cjs +119 -289
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/constants/SPAConstants.d.ts +2 -9
- package/dist/constants/SPAConstants.d.ts.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +117 -280
- package/dist/index.js.map +1 -1
- package/dist/models/BrowserConfig.d.ts +0 -6
- package/dist/models/BrowserConfig.d.ts.map +1 -1
- package/dist/utils/AuthenticationHelper.d.ts +14 -25
- package/dist/utils/AuthenticationHelper.d.ts.map +1 -1
- package/dist/utils/SPAUtils.d.ts +0 -14
- package/dist/utils/SPAUtils.d.ts.map +1 -1
- package/dist/utils/createHttpClientFetcher.d.ts +24 -0
- package/dist/utils/createHttpClientFetcher.d.ts.map +1 -0
- package/dist/utils/hasAuthParamsInUrl.d.ts +2 -2
- package/package.json +4 -4
- package/dist/utils/SessionManagementHelper.d.ts +0 -26
- package/dist/utils/SessionManagementHelper.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -38,19 +38,12 @@ const ERROR = "error";
|
|
|
38
38
|
const ERROR_DESCRIPTION = "error_description";
|
|
39
39
|
const CUSTOM_GRANT_CONFIG = "custom_grant_config";
|
|
40
40
|
const STATE_QUERY = "state";
|
|
41
|
-
const OP_IFRAME = "opIFrame";
|
|
42
|
-
const RP_IFRAME = "rpIFrame";
|
|
43
|
-
const PROMPT_NONE_IFRAME = "promptNoneIFrame";
|
|
44
|
-
const STATE = "Y2hlY2tTZXNzaW9u";
|
|
45
41
|
const SILENT_SIGN_IN_STATE = "sign-in-silently";
|
|
46
|
-
const INITIALIZED_SILENT_SIGN_IN = "initialized-silent-sign-in";
|
|
47
|
-
const PROMPT_NONE_REQUEST_SENT = "promptNoneRequestSent";
|
|
48
42
|
const ACCESS_TOKEN_INVALID = "Access token is invalid";
|
|
49
43
|
const REFRESH_ACCESS_TOKEN_ERR0R = "refresh-access-token-error";
|
|
50
44
|
const TOKEN_REQUEST_CONFIG_KEY = "token_request_config";
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const SET_SESSION_STATE_FROM_IFRAME = "set_session_state_from_iframe";
|
|
45
|
+
const SILENT_SIGN_IN_SIGNED_IN = "silent_sign_in_signed_in";
|
|
46
|
+
const SILENT_SIGN_IN_SIGNED_OUT = "silent_sign_in_signed_out";
|
|
54
47
|
|
|
55
48
|
//#endregion
|
|
56
49
|
//#region src/FetchHttpClient.ts
|
|
@@ -288,13 +281,6 @@ var SPAUtils = class SPAUtils {
|
|
|
288
281
|
return false;
|
|
289
282
|
}
|
|
290
283
|
/**
|
|
291
|
-
* Returns `true` if a silent sign-in was previously initialized in this session.
|
|
292
|
-
*/
|
|
293
|
-
static wasSilentSignInCalled() {
|
|
294
|
-
const raw = sessionStorage.getItem(INITIALIZED_SILENT_SIGN_IN);
|
|
295
|
-
return Boolean(raw ? JSON.parse(raw) : null);
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
284
|
* Checks whether the current URL indicates a successful sign-out redirect.
|
|
299
285
|
* Clears the query string and session data if `true`.
|
|
300
286
|
*
|
|
@@ -357,21 +343,6 @@ var SPAUtils = class SPAUtils {
|
|
|
357
343
|
return !!urlObject.searchParams.get(ERROR) && urlObject.searchParams.get(STATE_QUERY) !== OIDCRequestConstants.Params.SIGN_OUT_SUCCESS;
|
|
358
344
|
}
|
|
359
345
|
/**
|
|
360
|
-
* Returns `true` if no prompt-none request has been sent yet this session.
|
|
361
|
-
*/
|
|
362
|
-
static canSendPromptNoneRequest() {
|
|
363
|
-
const raw = sessionStorage.getItem(PROMPT_NONE_REQUEST_SENT);
|
|
364
|
-
return !(raw ? JSON.parse(raw) : null);
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Records whether a prompt-none request has been sent.
|
|
368
|
-
*
|
|
369
|
-
* @param canSend - `true` marks the request as sent.
|
|
370
|
-
*/
|
|
371
|
-
static setPromptNoneRequestSent(canSend) {
|
|
372
|
-
sessionStorage.setItem(PROMPT_NONE_REQUEST_SENT, JSON.stringify(canSend));
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
346
|
* Waits until the browser has redirected (non-blocking delay).
|
|
376
347
|
*
|
|
377
348
|
* @param time - Time to wait in seconds (default: 3).
|
|
@@ -400,7 +371,7 @@ var SPAUtils_default = SPAUtils;
|
|
|
400
371
|
//#region src/utils/AuthenticationHelper.ts
|
|
401
372
|
/**
|
|
402
373
|
* Browser-level authentication helper that orchestrates HTTP requests with token attachment,
|
|
403
|
-
* automatic token refresh,
|
|
374
|
+
* automatic token refresh, and the silent sign-in flow.
|
|
404
375
|
*
|
|
405
376
|
* @typeParam T - The browser client config extension type.
|
|
406
377
|
*/
|
|
@@ -460,18 +431,6 @@ var AuthenticationHelper = class {
|
|
|
460
431
|
httpClient?.disableHandler && httpClient.disableHandler();
|
|
461
432
|
}
|
|
462
433
|
/**
|
|
463
|
-
* Initializes OIDC Session Management via an RP iframe.
|
|
464
|
-
*
|
|
465
|
-
* @param config - The current auth config.
|
|
466
|
-
* @param oidcEndpoints - Resolved OIDC provider endpoints.
|
|
467
|
-
* @param getSessionState - Returns the current session state from storage.
|
|
468
|
-
* @param getAuthzURL - Builds an authorization URL with optional params.
|
|
469
|
-
* @param sessionManagementHelper - The session management helper instance.
|
|
470
|
-
*/
|
|
471
|
-
initializeSessionManger(config, oidcEndpoints, getSessionState, getAuthzURL, sessionManagementHelper) {
|
|
472
|
-
sessionManagementHelper.initialize(config.clientId, oidcEndpoints.checkSessionIframe ?? "", getSessionState, config.checkSessionInterval ?? 3, config.sessionRefreshInterval ?? 300, config.afterSignInUrl, getAuthzURL);
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
434
|
* Executes a custom token exchange grant, enforcing `allowedExternalUrls` rules when applicable.
|
|
476
435
|
*
|
|
477
436
|
* @param config - The token exchange configuration.
|
|
@@ -641,76 +600,96 @@ var AuthenticationHelper = class {
|
|
|
641
600
|
});
|
|
642
601
|
}
|
|
643
602
|
/**
|
|
644
|
-
* Executes the silent sign-in flow
|
|
603
|
+
* Executes the silent sign-in flow by loading a `prompt=none` authorize request in a hidden iframe.
|
|
645
604
|
*
|
|
646
605
|
* @param constructSilentSignInUrl - Builds the prompt-none authorize URL.
|
|
647
606
|
* @param requestAccessToken - Exchanges the returned code for tokens.
|
|
648
|
-
* @param sessionManagementHelper - Handles the iFrame prompt-none response.
|
|
649
607
|
* @param additionalParams - Extra authorize request params.
|
|
650
608
|
* @param tokenRequestConfig - Additional params for the token request.
|
|
651
609
|
* @returns The user session, or `false` if the user is not signed in.
|
|
652
610
|
*/
|
|
653
|
-
async signInSilently(constructSilentSignInUrl, requestAccessToken,
|
|
611
|
+
async signInSilently(constructSilentSignInUrl, requestAccessToken, additionalParams, tokenRequestConfig) {
|
|
654
612
|
if (SPAUtils_default.isInitializedSilentSignIn()) {
|
|
655
|
-
await
|
|
613
|
+
await this.handleSilentSignInResponse();
|
|
656
614
|
return Promise.resolve({
|
|
657
615
|
allowedScopes: "",
|
|
658
616
|
displayName: "",
|
|
659
617
|
email: "",
|
|
660
|
-
sessionState: "",
|
|
661
618
|
sub: "",
|
|
662
619
|
tenantDomain: "",
|
|
663
620
|
username: ""
|
|
664
621
|
});
|
|
665
622
|
}
|
|
666
|
-
|
|
623
|
+
let url;
|
|
667
624
|
try {
|
|
668
|
-
|
|
625
|
+
url = await constructSilentSignInUrl(additionalParams);
|
|
669
626
|
} catch (error) {
|
|
670
627
|
return Promise.reject(error);
|
|
671
628
|
}
|
|
629
|
+
const silentSignInIFrame = document.createElement("iframe");
|
|
630
|
+
silentSignInIFrame.style.display = "none";
|
|
672
631
|
return new Promise((resolve, reject) => {
|
|
632
|
+
const cleanUp = () => {
|
|
633
|
+
window.removeEventListener("message", listenToSilentSignInIFrame);
|
|
634
|
+
clearTimeout(timer);
|
|
635
|
+
silentSignInIFrame.remove();
|
|
636
|
+
};
|
|
673
637
|
const timer = setTimeout(() => {
|
|
638
|
+
cleanUp();
|
|
674
639
|
resolve(false);
|
|
675
640
|
}, 1e4);
|
|
676
|
-
const
|
|
641
|
+
const listenToSilentSignInIFrame = async (e) => {
|
|
642
|
+
if (e.origin !== window.location.origin || e.source !== silentSignInIFrame.contentWindow) return;
|
|
677
643
|
const data = e.data;
|
|
678
|
-
if (data?.type
|
|
679
|
-
|
|
680
|
-
clearTimeout(timer);
|
|
644
|
+
if (data?.type === SILENT_SIGN_IN_SIGNED_OUT) {
|
|
645
|
+
cleanUp();
|
|
681
646
|
resolve(false);
|
|
682
647
|
}
|
|
683
|
-
if (data?.type
|
|
648
|
+
if (data?.type === SILENT_SIGN_IN_SIGNED_IN && data?.data?.code) {
|
|
684
649
|
const authInfo = data.data;
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
resolve(response);
|
|
688
|
-
}).catch((error) => {
|
|
689
|
-
window.removeEventListener("message", listenToPromptNoneIFrame);
|
|
690
|
-
reject(error);
|
|
691
|
-
}).finally(() => {
|
|
692
|
-
clearTimeout(timer);
|
|
693
|
-
});
|
|
650
|
+
cleanUp();
|
|
651
|
+
requestAccessToken(authInfo.code, authInfo.state, tokenRequestConfig).then(resolve).catch(reject);
|
|
694
652
|
}
|
|
695
653
|
};
|
|
696
|
-
window.addEventListener("message",
|
|
654
|
+
window.addEventListener("message", listenToSilentSignInIFrame);
|
|
655
|
+
silentSignInIFrame.src = url;
|
|
656
|
+
document.body.appendChild(silentSignInIFrame);
|
|
697
657
|
});
|
|
698
658
|
}
|
|
699
659
|
/**
|
|
660
|
+
* Handles the page load inside the silent sign-in iframe: relays the authorization response to the
|
|
661
|
+
* parent window and blanks the iframe.
|
|
662
|
+
*
|
|
663
|
+
* @returns `true` if the current page load was a silent sign-in response.
|
|
664
|
+
*/
|
|
665
|
+
async handleSilentSignInResponse() {
|
|
666
|
+
const url = new URL(window.location.href);
|
|
667
|
+
const state = url.searchParams.get(STATE_QUERY);
|
|
668
|
+
if (state === null || !state.includes(SILENT_SIGN_IN_STATE)) return false;
|
|
669
|
+
const code$1 = url.searchParams.get("code");
|
|
670
|
+
const message = code$1 !== null && code$1.length !== 0 ? {
|
|
671
|
+
data: {
|
|
672
|
+
code: code$1,
|
|
673
|
+
state
|
|
674
|
+
},
|
|
675
|
+
type: SILENT_SIGN_IN_SIGNED_IN
|
|
676
|
+
} : { type: SILENT_SIGN_IN_SIGNED_OUT };
|
|
677
|
+
window.parent.postMessage(message, window.location.origin);
|
|
678
|
+
window.location.href = "about:blank";
|
|
679
|
+
await SPAUtils_default.waitTillPageRedirect();
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
700
683
|
* Handles the early-return path of `signIn()` when a session already exists
|
|
701
|
-
* or the page is handling a
|
|
684
|
+
* or the page is handling a silent sign-in response.
|
|
702
685
|
*
|
|
703
|
-
* @param shouldStopAuthn - Returns `true` if we should short-circuit and return early.
|
|
704
|
-
* @param checkSession - Callback to initialize OIDC session management.
|
|
705
686
|
* @returns The current user if already signed in, or `undefined` to continue normal sign-in.
|
|
706
687
|
*/
|
|
707
|
-
async handleSignIn(
|
|
708
|
-
|
|
709
|
-
if (await shouldStopAuthn()) return Promise.resolve({
|
|
688
|
+
async handleSignIn() {
|
|
689
|
+
if (await this.handleSilentSignInResponse()) return Promise.resolve({
|
|
710
690
|
allowedScopes: "",
|
|
711
691
|
displayName: "",
|
|
712
692
|
email: "",
|
|
713
|
-
sessionState: "",
|
|
714
693
|
sub: "",
|
|
715
694
|
tenantDomain: "",
|
|
716
695
|
username: ""
|
|
@@ -718,7 +697,6 @@ var AuthenticationHelper = class {
|
|
|
718
697
|
if (await this._isSignedIn()) {
|
|
719
698
|
await this._spaHelper.clearRefreshTokenTimeout();
|
|
720
699
|
await this._spaHelper.refreshAccessTokenAutomatically(() => this.refreshAccessToken());
|
|
721
|
-
if (configAny.syncSession) checkSession();
|
|
722
700
|
return Promise.resolve(await this._getUser());
|
|
723
701
|
}
|
|
724
702
|
const error = new URL(window.location.href).searchParams.get(ERROR);
|
|
@@ -836,164 +814,6 @@ const navigate = (url) => {
|
|
|
836
814
|
};
|
|
837
815
|
var navigate_default = navigate;
|
|
838
816
|
|
|
839
|
-
//#endregion
|
|
840
|
-
//#region src/utils/SessionManagementHelper.ts
|
|
841
|
-
/**
|
|
842
|
-
* Factory that creates an OIDC Session Management helper using an RP iframe and polling.
|
|
843
|
-
* Appends a hidden RP iframe to the document and returns the helper interface.
|
|
844
|
-
*
|
|
845
|
-
* @param signOut - Returns the sign-out URL for the current session.
|
|
846
|
-
* @param setSessionState - Stores a new session state from a prompt-none response.
|
|
847
|
-
* @returns A `SessionManagementHelperInterface` instance.
|
|
848
|
-
*/
|
|
849
|
-
const createSessionManagementHelper = async (signOut, setSessionState) => {
|
|
850
|
-
let _clientID;
|
|
851
|
-
let _checkSessionEndpoint;
|
|
852
|
-
let _sessionState;
|
|
853
|
-
let _interval;
|
|
854
|
-
let _redirectURL;
|
|
855
|
-
let _sessionRefreshInterval;
|
|
856
|
-
let _sessionRefreshIntervalTimeout;
|
|
857
|
-
let _checkSessionIntervalTimeout;
|
|
858
|
-
let _getSignInUrl;
|
|
859
|
-
const initialize = (clientId, checkSessionEndpoint, getSessionState, interval, sessionRefreshInterval, redirectURL, getSignInUrl) => {
|
|
860
|
-
_clientID = clientId;
|
|
861
|
-
_checkSessionEndpoint = checkSessionEndpoint;
|
|
862
|
-
_sessionState = getSessionState;
|
|
863
|
-
_interval = interval;
|
|
864
|
-
_redirectURL = redirectURL;
|
|
865
|
-
_sessionRefreshInterval = sessionRefreshInterval;
|
|
866
|
-
_getSignInUrl = getSignInUrl;
|
|
867
|
-
if (_interval > -1) initiateCheckSession();
|
|
868
|
-
if (_sessionRefreshInterval > -1) _sessionRefreshIntervalTimeout = setInterval(() => {
|
|
869
|
-
sendPromptNoneRequest();
|
|
870
|
-
}, _sessionRefreshInterval * 1e3);
|
|
871
|
-
};
|
|
872
|
-
const initiateCheckSession = async () => {
|
|
873
|
-
if (!_checkSessionEndpoint || !_clientID || !_redirectURL) return;
|
|
874
|
-
async function checkSession() {
|
|
875
|
-
const sessionState = await _sessionState();
|
|
876
|
-
if (Boolean(_clientID) && Boolean(sessionState)) {
|
|
877
|
-
const message = `${_clientID} ${sessionState}`;
|
|
878
|
-
(document.getElementById(RP_IFRAME)?.contentDocument?.getElementById(OP_IFRAME)).contentWindow?.postMessage(message, _checkSessionEndpoint);
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
const opIframe = document.getElementById(RP_IFRAME)?.contentDocument?.getElementById(OP_IFRAME);
|
|
882
|
-
opIframe.src = _checkSessionEndpoint + "?client_id=" + _clientID + "&redirect_uri=" + _redirectURL;
|
|
883
|
-
_checkSessionIntervalTimeout = setInterval(checkSession, _interval * 1e3);
|
|
884
|
-
listenToResponseFromOPIFrame();
|
|
885
|
-
};
|
|
886
|
-
const reset = () => {
|
|
887
|
-
clearInterval(_checkSessionIntervalTimeout);
|
|
888
|
-
clearInterval(_sessionRefreshIntervalTimeout);
|
|
889
|
-
};
|
|
890
|
-
const listenToResponseFromOPIFrame = () => {
|
|
891
|
-
async function receiveMessage(e) {
|
|
892
|
-
const targetOrigin = _checkSessionEndpoint;
|
|
893
|
-
if (!targetOrigin || targetOrigin?.indexOf(e.origin) < 0 || e?.data?.type === SET_SESSION_STATE_FROM_IFRAME) return;
|
|
894
|
-
if (e.data === "unchanged") {} else if (e.data === "error") window.location.href = await signOut();
|
|
895
|
-
else if (e.data === "changed") sendPromptNoneRequest();
|
|
896
|
-
}
|
|
897
|
-
window?.addEventListener("message", receiveMessage, false);
|
|
898
|
-
};
|
|
899
|
-
const sendPromptNoneRequest = async () => {
|
|
900
|
-
const promptNoneIFrame = document.getElementById(RP_IFRAME)?.contentDocument?.getElementById(PROMPT_NONE_IFRAME);
|
|
901
|
-
if (SPAUtils_default.canSendPromptNoneRequest()) {
|
|
902
|
-
SPAUtils_default.setPromptNoneRequestSent(true);
|
|
903
|
-
const receiveMessageListener = (e) => {
|
|
904
|
-
if (e?.data?.type === SET_SESSION_STATE_FROM_IFRAME) {
|
|
905
|
-
setSessionState(e?.data?.data ?? "");
|
|
906
|
-
window?.removeEventListener("message", receiveMessageListener);
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
|
-
window?.addEventListener("message", receiveMessageListener);
|
|
910
|
-
promptNoneIFrame.src = await _getSignInUrl({
|
|
911
|
-
prompt: "none",
|
|
912
|
-
response_mode: "query",
|
|
913
|
-
state: STATE
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
};
|
|
917
|
-
const receivePromptNoneResponse = async (setSessionStateFn) => {
|
|
918
|
-
const state = new URL(window.location.href).searchParams.get(STATE_QUERY);
|
|
919
|
-
const sessionState = new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.SESSION_STATE);
|
|
920
|
-
const parent = window.parent.parent;
|
|
921
|
-
if (state !== null && (state.includes(STATE) || state.includes(SILENT_SIGN_IN_STATE))) {
|
|
922
|
-
const code$1 = new URL(window.location.href).searchParams.get("code");
|
|
923
|
-
if (code$1 !== null && code$1.length !== 0) {
|
|
924
|
-
if (state.includes(SILENT_SIGN_IN_STATE)) {
|
|
925
|
-
const message = {
|
|
926
|
-
data: {
|
|
927
|
-
code: code$1,
|
|
928
|
-
sessionState: sessionState ?? "",
|
|
929
|
-
state
|
|
930
|
-
},
|
|
931
|
-
type: CHECK_SESSION_SIGNED_IN
|
|
932
|
-
};
|
|
933
|
-
sessionStorage.setItem(INITIALIZED_SILENT_SIGN_IN, "false");
|
|
934
|
-
parent.postMessage(message, parent.origin);
|
|
935
|
-
SPAUtils_default.setPromptNoneRequestSent(false);
|
|
936
|
-
window.location.href = "about:blank";
|
|
937
|
-
await SPAUtils_default.waitTillPageRedirect();
|
|
938
|
-
return true;
|
|
939
|
-
}
|
|
940
|
-
const newSessionState = new URL(window.location.href).searchParams.get("session_state");
|
|
941
|
-
setSessionStateFn && await setSessionStateFn(newSessionState);
|
|
942
|
-
SPAUtils_default.setPromptNoneRequestSent(false);
|
|
943
|
-
window.location.href = "about:blank";
|
|
944
|
-
await SPAUtils_default.waitTillPageRedirect();
|
|
945
|
-
return true;
|
|
946
|
-
} else {
|
|
947
|
-
if (state.includes(SILENT_SIGN_IN_STATE)) {
|
|
948
|
-
const message = { type: CHECK_SESSION_SIGNED_OUT };
|
|
949
|
-
window.parent.parent.postMessage(message, parent.origin);
|
|
950
|
-
SPAUtils_default.setPromptNoneRequestSent(false);
|
|
951
|
-
window.location.href = "about:blank";
|
|
952
|
-
await SPAUtils_default.waitTillPageRedirect();
|
|
953
|
-
return true;
|
|
954
|
-
}
|
|
955
|
-
SPAUtils_default.setPromptNoneRequestSent(false);
|
|
956
|
-
const signOutURL = await signOut();
|
|
957
|
-
parent.location.href = signOutURL;
|
|
958
|
-
window.location.href = "about:blank";
|
|
959
|
-
await SPAUtils_default.waitTillPageRedirect();
|
|
960
|
-
return true;
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
return false;
|
|
964
|
-
};
|
|
965
|
-
let rpIFrame = document.createElement("iframe");
|
|
966
|
-
rpIFrame.setAttribute("id", RP_IFRAME);
|
|
967
|
-
rpIFrame.style.display = "none";
|
|
968
|
-
let rpIframeLoaded = false;
|
|
969
|
-
rpIFrame.onload = () => {
|
|
970
|
-
rpIFrame = document.getElementById(RP_IFRAME);
|
|
971
|
-
const rpDoc = rpIFrame?.contentDocument;
|
|
972
|
-
const opIFrame = rpDoc?.createElement("iframe");
|
|
973
|
-
if (opIFrame) {
|
|
974
|
-
opIFrame.setAttribute("id", OP_IFRAME);
|
|
975
|
-
opIFrame.style.display = "none";
|
|
976
|
-
}
|
|
977
|
-
const promptNoneIFrame = rpDoc?.createElement("iframe");
|
|
978
|
-
if (promptNoneIFrame) {
|
|
979
|
-
promptNoneIFrame.setAttribute("id", PROMPT_NONE_IFRAME);
|
|
980
|
-
promptNoneIFrame.style.display = "none";
|
|
981
|
-
}
|
|
982
|
-
opIFrame && rpIFrame?.contentDocument?.body?.appendChild(opIFrame);
|
|
983
|
-
promptNoneIFrame && rpIFrame?.contentDocument?.body?.appendChild(promptNoneIFrame);
|
|
984
|
-
rpIframeLoaded = true;
|
|
985
|
-
};
|
|
986
|
-
document?.body?.appendChild(rpIFrame);
|
|
987
|
-
const sleep = () => new Promise((resolve) => setTimeout(resolve, 1));
|
|
988
|
-
while (!rpIframeLoaded) await sleep();
|
|
989
|
-
return {
|
|
990
|
-
initialize,
|
|
991
|
-
receivePromptNoneResponse,
|
|
992
|
-
reset
|
|
993
|
-
};
|
|
994
|
-
};
|
|
995
|
-
var SessionManagementHelper_default = createSessionManagementHelper;
|
|
996
|
-
|
|
997
817
|
//#endregion
|
|
998
818
|
//#region ../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
|
|
999
819
|
var require_base64_js = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js": ((exports) => {
|
|
@@ -2596,10 +2416,7 @@ var SPAHelper_default = SPAHelper;
|
|
|
2596
2416
|
const logger$2 = createPackageComponentLogger("@thunderid/browser", "ThunderIDBrowserClient");
|
|
2597
2417
|
const BROWSER_DEFAULT_CONFIG = {
|
|
2598
2418
|
autoLogoutOnTokenRefreshError: false,
|
|
2599
|
-
|
|
2600
|
-
periodicTokenRefresh: false,
|
|
2601
|
-
sessionRefreshInterval: 300,
|
|
2602
|
-
syncSession: false
|
|
2419
|
+
periodicTokenRefresh: false
|
|
2603
2420
|
};
|
|
2604
2421
|
const initiateStore = (storage) => {
|
|
2605
2422
|
switch (storage) {
|
|
@@ -2614,7 +2431,6 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2614
2431
|
_browserInstanceId = 0;
|
|
2615
2432
|
_httpClient;
|
|
2616
2433
|
_spaHelper;
|
|
2617
|
-
_sessionManagementHelper;
|
|
2618
2434
|
_authHelper;
|
|
2619
2435
|
_storage = BrowserStorage_default.SessionStorage;
|
|
2620
2436
|
_getSignOutURLFromSessionStorage = false;
|
|
@@ -2653,7 +2469,6 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2653
2469
|
await this._authHelper?.attachTokenToRequestConfig(request);
|
|
2654
2470
|
};
|
|
2655
2471
|
this._httpClient = FetchHttpClient_default.getInstance(this._browserInstanceId, true, attachToken);
|
|
2656
|
-
this._sessionManagementHelper = await SessionManagementHelper_default(async () => this.getSignOutUrl(), (sessionState) => sm.setSessionDataParameter(OIDCRequestConstants.Params.SESSION_STATE, sessionState));
|
|
2657
2472
|
this._authHelper = new AuthenticationHelper_default(sm, this._spaHelper, this._browserInstanceId, {
|
|
2658
2473
|
exchangeToken: (cfg) => super.exchangeToken(cfg),
|
|
2659
2474
|
getAccessToken: (sessionId) => this.getAccessToken(sessionId),
|
|
@@ -2694,30 +2509,27 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2694
2509
|
isLoading() {
|
|
2695
2510
|
return false;
|
|
2696
2511
|
}
|
|
2697
|
-
async signIn(config, authorizationCode,
|
|
2512
|
+
async signIn(config, authorizationCode, state, tokenRequestConfig) {
|
|
2698
2513
|
await this.isInitialized();
|
|
2699
2514
|
if (!SPAUtils_default.canContinueSignIn(Boolean(config?.callOnlyOnRedirect), authorizationCode)) return;
|
|
2700
2515
|
delete config?.callOnlyOnRedirect;
|
|
2701
|
-
const user = await this._signInInternal(config, authorizationCode,
|
|
2516
|
+
const user = await this._signInInternal(config, authorizationCode, state, tokenRequestConfig);
|
|
2702
2517
|
if (user && this._onSignInCallback) this._onSignInCallback(user);
|
|
2703
2518
|
return user;
|
|
2704
2519
|
}
|
|
2705
|
-
async _signInInternal(signInConfig, authorizationCode,
|
|
2520
|
+
async _signInInternal(signInConfig, authorizationCode, state, tokenRequestConfig) {
|
|
2706
2521
|
const sm = this.getStorageManager();
|
|
2707
2522
|
const config = await sm.getConfigData();
|
|
2708
|
-
const basicUserInfo = await this._authHelper.handleSignIn(
|
|
2523
|
+
const basicUserInfo = await this._authHelper.handleSignIn();
|
|
2709
2524
|
if (basicUserInfo) return basicUserInfo;
|
|
2710
2525
|
let resolvedAuthorizationCode;
|
|
2711
|
-
let resolvedSessionState;
|
|
2712
2526
|
let resolvedState;
|
|
2713
2527
|
let resolvedTokenRequestConfig = { params: {} };
|
|
2714
2528
|
if (config?.responseMode === "form_post" && authorizationCode) {
|
|
2715
2529
|
resolvedAuthorizationCode = authorizationCode;
|
|
2716
|
-
resolvedSessionState = sessionState ?? "";
|
|
2717
2530
|
resolvedState = state ?? "";
|
|
2718
2531
|
} else {
|
|
2719
2532
|
resolvedAuthorizationCode = new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.AUTHORIZATION_CODE) ?? "";
|
|
2720
|
-
resolvedSessionState = new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.SESSION_STATE) ?? "";
|
|
2721
2533
|
resolvedState = new URL(window.location.href).searchParams.get(OIDCRequestConstants.Params.STATE) ?? "";
|
|
2722
2534
|
SPAUtils_default.removeAuthorizationCode();
|
|
2723
2535
|
}
|
|
@@ -2725,7 +2537,7 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2725
2537
|
sm.setSessionStatus("true");
|
|
2726
2538
|
const storedTokenRequestConfig = await sm.getTemporaryDataParameter(TOKEN_REQUEST_CONFIG_KEY);
|
|
2727
2539
|
if (storedTokenRequestConfig && typeof storedTokenRequestConfig === "string") resolvedTokenRequestConfig = JSON.parse(storedTokenRequestConfig);
|
|
2728
|
-
return this._exchangeCodeForTokens(resolvedAuthorizationCode,
|
|
2540
|
+
return this._exchangeCodeForTokens(resolvedAuthorizationCode, resolvedState, resolvedTokenRequestConfig);
|
|
2729
2541
|
}
|
|
2730
2542
|
return this.getSignInUrl(signInConfig).then(async (url) => {
|
|
2731
2543
|
if (this._storage === BrowserStorage_default.BrowserMemory && config.enablePKCE) {
|
|
@@ -2739,34 +2551,32 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2739
2551
|
allowedScopes: "",
|
|
2740
2552
|
displayName: "",
|
|
2741
2553
|
email: "",
|
|
2742
|
-
sessionState: "",
|
|
2743
2554
|
sub: "",
|
|
2744
2555
|
tenantDomain: "",
|
|
2745
2556
|
username: ""
|
|
2746
2557
|
};
|
|
2747
2558
|
});
|
|
2748
2559
|
}
|
|
2749
|
-
async _exchangeCodeForTokens(authorizationCode,
|
|
2560
|
+
async _exchangeCodeForTokens(authorizationCode, state, tokenRequestConfig) {
|
|
2750
2561
|
const config = await this.getStorageManager().getConfigData();
|
|
2751
|
-
if (this._storage === BrowserStorage_default.BrowserMemory && config.enablePKCE &&
|
|
2752
|
-
const pkceKey = extractPkceStorageKeyFromState(
|
|
2562
|
+
if (this._storage === BrowserStorage_default.BrowserMemory && config.enablePKCE && state) {
|
|
2563
|
+
const pkceKey = extractPkceStorageKeyFromState(state);
|
|
2753
2564
|
const pkce = SPAUtils_default.getPKCE(pkceKey);
|
|
2754
2565
|
await this.setPKCECode(pkce, pkceKey);
|
|
2755
2566
|
}
|
|
2756
|
-
await this.requestAccessToken(authorizationCode,
|
|
2567
|
+
await this.requestAccessToken(authorizationCode, state ?? "", void 0, tokenRequestConfig);
|
|
2757
2568
|
try {
|
|
2758
2569
|
const signOutUrl = await this.getSignOutUrl();
|
|
2759
2570
|
SPAUtils_default.setSignOutURL(signOutUrl, config.clientId, this._browserInstanceId);
|
|
2760
2571
|
} catch {}
|
|
2761
2572
|
await this._spaHelper.clearRefreshTokenTimeout();
|
|
2762
2573
|
await this._spaHelper.refreshAccessTokenAutomatically(() => this.refreshAccessToken());
|
|
2763
|
-
if (config.syncSession) this._checkSession();
|
|
2764
2574
|
return this.getUser();
|
|
2765
2575
|
}
|
|
2766
2576
|
async signInSilently(additionalParams, tokenRequestConfig) {
|
|
2767
2577
|
await this.isInitialized();
|
|
2768
2578
|
if (SPAUtils_default.wasSignInCalled()) return;
|
|
2769
|
-
const response = await this._authHelper.signInSilently((params) => this._constructSilentSignInUrl(params), (code$1,
|
|
2579
|
+
const response = await this._authHelper.signInSilently((params) => this._constructSilentSignInUrl(params), (code$1, s, trc) => this._exchangeCodeForTokens(code$1, s, trc), additionalParams, tokenRequestConfig);
|
|
2770
2580
|
if (this._onSignInCallback && response) this._onSignInCallback(response);
|
|
2771
2581
|
return response;
|
|
2772
2582
|
}
|
|
@@ -2865,7 +2675,6 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2865
2675
|
await this._validateMethod();
|
|
2866
2676
|
const timer = await this._spaHelper.getRefreshTimeoutTimer();
|
|
2867
2677
|
await super.revokeAccessToken(userId);
|
|
2868
|
-
this._sessionManagementHelper?.reset();
|
|
2869
2678
|
await this._spaHelper.clearRefreshTokenTimeout(timer);
|
|
2870
2679
|
this._onEndUserSession && await this._onEndUserSession(true);
|
|
2871
2680
|
return true;
|
|
@@ -2879,17 +2688,7 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2879
2688
|
}
|
|
2880
2689
|
async reInitialize(config) {
|
|
2881
2690
|
await this.isInitialized();
|
|
2882
|
-
|
|
2883
|
-
const isCheckSessionIframeDifferent = !(existingConfig?.endpoints?.checkSessionIframe && config?.endpoints?.checkSessionIframe && existingConfig.endpoints.checkSessionIframe === config.endpoints.checkSessionIframe);
|
|
2884
|
-
const result = await super.reInitialize(config);
|
|
2885
|
-
if ({
|
|
2886
|
-
...existingConfig,
|
|
2887
|
-
...config
|
|
2888
|
-
}.syncSession && isCheckSessionIframeDifferent) {
|
|
2889
|
-
this._sessionManagementHelper?.reset();
|
|
2890
|
-
this._checkSession();
|
|
2891
|
-
}
|
|
2892
|
-
return result;
|
|
2691
|
+
return super.reInitialize(config);
|
|
2893
2692
|
}
|
|
2894
2693
|
async startAutoRefreshToken() {
|
|
2895
2694
|
await this.isInitialized();
|
|
@@ -2952,18 +2751,6 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends ThunderIDJavaS
|
|
|
2952
2751
|
default: throw new ThunderIDAuthException("SPA-AUTH_CLIENT-ON-IV01", "Invalid hook.", `Unknown hook: "${hook}"`);
|
|
2953
2752
|
}
|
|
2954
2753
|
}
|
|
2955
|
-
async _checkSession() {
|
|
2956
|
-
const oidcEndpoints = await this.getOpenIDProviderEndpoints();
|
|
2957
|
-
const sm = this.getStorageManager();
|
|
2958
|
-
const config = await sm.getConfigData();
|
|
2959
|
-
this._authHelper.initializeSessionManger(config, oidcEndpoints, async () => (await sm.getSessionData())?.session_state ?? "", async (params) => this.getSignInUrl(params), this._sessionManagementHelper);
|
|
2960
|
-
}
|
|
2961
|
-
async _shouldStopAuthn() {
|
|
2962
|
-
const sm = this.getStorageManager();
|
|
2963
|
-
return this._sessionManagementHelper.receivePromptNoneResponse(async (sessionState) => {
|
|
2964
|
-
await sm.setSessionDataParameter(OIDCRequestConstants.Params.SESSION_STATE, sessionState ?? "");
|
|
2965
|
-
});
|
|
2966
|
-
}
|
|
2967
2754
|
_enableRetrievingSignOutURLFromSession(config) {
|
|
2968
2755
|
if (config.preventSignOutURLUpdate) this._getSignOutURLFromSessionStorage = true;
|
|
2969
2756
|
}
|
|
@@ -3012,10 +2799,10 @@ var Hooks_default = Hooks;
|
|
|
3012
2799
|
//#endregion
|
|
3013
2800
|
//#region src/utils/hasAuthParamsInUrl.ts
|
|
3014
2801
|
/**
|
|
3015
|
-
* Utility to check if `code`
|
|
2802
|
+
* Utility to check if `code` is available in the URL as a search param.
|
|
3016
2803
|
*
|
|
3017
2804
|
* @param params - The URL search params to check. Defaults to `window.location.search`.
|
|
3018
|
-
* @return `true` if the URL contains `code`
|
|
2805
|
+
* @return `true` if the URL contains a `code` search param, otherwise `false`.
|
|
3019
2806
|
*/
|
|
3020
2807
|
const hasAuthParamsInUrl = (params = window.location.search) => {
|
|
3021
2808
|
return /[?&]code=[^&]+/.test(params);
|
|
@@ -3060,6 +2847,56 @@ const http = (client) => {
|
|
|
3060
2847
|
};
|
|
3061
2848
|
var http_default = http;
|
|
3062
2849
|
|
|
2850
|
+
//#endregion
|
|
2851
|
+
//#region src/utils/createHttpClientFetcher.ts
|
|
2852
|
+
/**
|
|
2853
|
+
* Builds a `fetch`-shaped function backed by the shared `FetchHttpClient` singleton, for
|
|
2854
|
+
* framework wrappers (`@thunderid/react`, `@thunderid/vue`) that need to hand a core
|
|
2855
|
+
* `@thunderid/javascript` API function a `fetcher` carrying the access token automatically.
|
|
2856
|
+
*
|
|
2857
|
+
* Unlike a plain `fetch` call, `FetchHttpClient.request` throws on a non-2xx response instead
|
|
2858
|
+
* of resolving it. This adapter catches that and reconstructs a `Response`-shaped object from
|
|
2859
|
+
* the thrown error's `response`, so the core API function sees the real status and body instead
|
|
2860
|
+
* of treating every non-2xx result as a network failure. A genuine network error (no response
|
|
2861
|
+
* attached) still propagates.
|
|
2862
|
+
*
|
|
2863
|
+
* @param instanceId - Which `FetchHttpClient` instance to use, for multi-instance apps. Defaults to `0`.
|
|
2864
|
+
* @returns A function matching the `(url, config) => Promise<Response>` shape core API functions expect.
|
|
2865
|
+
* @example
|
|
2866
|
+
* ```typescript
|
|
2867
|
+
* await updateMeCredentials({
|
|
2868
|
+
* ...config,
|
|
2869
|
+
* fetcher: fetcher ?? createHttpClientFetcher(instanceId),
|
|
2870
|
+
* });
|
|
2871
|
+
* ```
|
|
2872
|
+
*/
|
|
2873
|
+
const createHttpClientFetcher = (instanceId = 0) => {
|
|
2874
|
+
return async (url, config) => {
|
|
2875
|
+
const httpClient = FetchHttpClient_default.getInstance(instanceId);
|
|
2876
|
+
const toResponse = (data, status, statusText) => ({
|
|
2877
|
+
json: () => Promise.resolve(data),
|
|
2878
|
+
ok: status >= 200 && status < 300,
|
|
2879
|
+
status,
|
|
2880
|
+
statusText,
|
|
2881
|
+
text: () => Promise.resolve(typeof data === "string" ? data : JSON.stringify(data))
|
|
2882
|
+
});
|
|
2883
|
+
try {
|
|
2884
|
+
const response = await httpClient.request({
|
|
2885
|
+
data: config.body ? JSON.parse(config.body) : void 0,
|
|
2886
|
+
headers: config.headers,
|
|
2887
|
+
method: config.method || "POST",
|
|
2888
|
+
url
|
|
2889
|
+
});
|
|
2890
|
+
return toResponse(response.data, response.status, response.statusText || "");
|
|
2891
|
+
} catch (error) {
|
|
2892
|
+
const httpError = error;
|
|
2893
|
+
if (httpError?.response) return toResponse(httpError.response.data, httpError.response.status, httpError.response.statusText ?? "");
|
|
2894
|
+
throw error;
|
|
2895
|
+
}
|
|
2896
|
+
};
|
|
2897
|
+
};
|
|
2898
|
+
var createHttpClientFetcher_default = createHttpClientFetcher;
|
|
2899
|
+
|
|
3063
2900
|
//#endregion
|
|
3064
2901
|
//#region src/utils/handleWebAuthnAuthentication.ts
|
|
3065
2902
|
const logger$1 = createPackageComponentLogger("@thunderid/browser", "WebAuthn");
|
|
@@ -3893,5 +3730,5 @@ const normalizeBorderRadius = (raw) => {
|
|
|
3893
3730
|
var normalizeBorderRadius_default = normalizeBorderRadius;
|
|
3894
3731
|
|
|
3895
3732
|
//#endregion
|
|
3896
|
-
export { ACCESS_TOKEN_INVALID, ANONYMOUS_ANIMAL_ICONS, ANONYMOUS_ENTITY_ICONS, AVATAR_GRADIENT_COUNT, AVATAR_URI_SCHEME, AuthenticationHelper_default as AuthenticationHelper, Hooks as BrowserHooks, BrowserStorage_default as BrowserStorage,
|
|
3733
|
+
export { ACCESS_TOKEN_INVALID, ANONYMOUS_ANIMAL_ICONS, ANONYMOUS_ENTITY_ICONS, AVATAR_GRADIENT_COUNT, AVATAR_URI_SCHEME, AuthenticationHelper_default as AuthenticationHelper, Hooks as BrowserHooks, BrowserStorage_default as BrowserStorage, CUSTOM_GRANT_CONFIG, ERROR, ERROR_DESCRIPTION, FetchHttpClient_default as FetchHttpClient, Hooks_default as Hooks, LocalStore_default as LocalStore, MemoryStore_default as MemoryStore, REFRESH_ACCESS_TOKEN_ERR0R, SILENT_SIGN_IN_SIGNED_IN, SILENT_SIGN_IN_SIGNED_OUT, SILENT_SIGN_IN_STATE, SPACryptoUtils_default as SPACryptoUtils, SPAHelper_default as SPAHelper, SPAUtils_default as SPAUtils, STATE_QUERY, SessionStore_default as SessionStore, TOKEN_REQUEST_CONFIG_KEY, ThunderIDBrowserClient_default as ThunderIDBrowserClient, buildAvatarSpec_default as buildAvatarSpec, createClassObserver, createHttpClientFetcher_default as createHttpClientFetcher, createMediaQueryListener, deriveAvatarContent, detectThemeMode, extractAvatarParamsFromUri_default as extractAvatarParamsFromUri, generateAvatarDataUri_default as generateAvatarDataUri, getActiveTheme_default as getActiveTheme, handleWebAuthnAuthentication_default as handleWebAuthnAuthentication, hasAuthParamsInUrl_default as hasAuthParamsInUrl, hasCalledForThisInstanceInUrl_default as hasCalledForThisInstanceInUrl, http_default as http, isAvatarUri_default as isAvatarUri, navigate_default as navigate, normalizeBorderRadius_default as normalizeBorderRadius, pickAnonymousAvatarName_default as pickAnonymousAvatarName, pickAnonymousEntityName_default as pickAnonymousEntityName, resolveEmojiUrisInHtml_default as resolveEmojiUrisInHtml, resolveLogoUri_default as resolveLogoUri };
|
|
3897
3734
|
//# sourceMappingURL=index.js.map
|