@thunderid/browser 1.3.0 → 1.3.1
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 +26 -9
- package/dist/ThunderIDBrowserClient.d.ts.map +1 -1
- package/dist/cjs/index.cjs +174 -124
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +175 -125
- package/dist/index.js.map +1 -1
- package/dist/models/BrowserConfig.d.ts +1 -1
- package/dist/models/BrowserConfig.d.ts.map +1 -1
- package/dist/theme/themeDetection.d.ts +11 -2
- package/dist/theme/themeDetection.d.ts.map +1 -1
- package/dist/utils/generateAvatarDataUri.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ThunderIDJavaScriptClient, User, IsomorphicCrypto, IdToken, OIDCEndpoints, Storage, TokenResponse, HttpRequestConfig, HttpResponse } from '@thunderid/javascript';
|
|
1
|
+
import { ThunderIDJavaScriptClient, User, IsomorphicCrypto, IdToken, OIDCEndpoints, Storage, TokenResponse, HttpRequestConfig, HttpResponse, UserProfile } from '@thunderid/javascript';
|
|
2
2
|
import FetchHttpClient from './FetchHttpClient';
|
|
3
3
|
import { BrowserAuthConfig } from './models/BrowserConfig';
|
|
4
4
|
import SignInConfig from './models/SignInConfig';
|
|
@@ -11,14 +11,7 @@ declare class ThunderIDBrowserClient<T = BrowserAuthConfig> extends ThunderIDJav
|
|
|
11
11
|
private _storage;
|
|
12
12
|
private _getSignOutURLFromSessionStorage;
|
|
13
13
|
private _isHttpHandlerEnabled;
|
|
14
|
-
private
|
|
15
|
-
private _httpFinishCallback;
|
|
16
|
-
private _onSignInCallback;
|
|
17
|
-
private _onSignOutCallback;
|
|
18
|
-
private _onSignOutFailedCallback;
|
|
19
|
-
private _onEndUserSession;
|
|
20
|
-
private _onInitialize;
|
|
21
|
-
private _onCustomGrant;
|
|
14
|
+
private _hookCallbacks;
|
|
22
15
|
private _initialized;
|
|
23
16
|
private _startedInitialize;
|
|
24
17
|
constructor(instanceId?: number);
|
|
@@ -39,6 +32,17 @@ declare class ThunderIDBrowserClient<T = BrowserAuthConfig> extends ThunderIDJav
|
|
|
39
32
|
httpRequest(requestConfig: HttpRequestConfig): Promise<HttpResponse | undefined>;
|
|
40
33
|
httpRequestAll(configs: HttpRequestConfig[]): Promise<HttpResponse[] | undefined>;
|
|
41
34
|
getUser(userId?: string): Promise<User>;
|
|
35
|
+
/**
|
|
36
|
+
* Fetches the signed-in user's profile from the `/users/me` endpoint (or `endpoints.usersMe` when
|
|
37
|
+
* configured), sending the request through the client's HTTP client so the access token is attached.
|
|
38
|
+
*
|
|
39
|
+
* @param options - Optional `baseUrl` or full `url` overrides for the profile endpoint.
|
|
40
|
+
* @returns The user's profile.
|
|
41
|
+
*/
|
|
42
|
+
getUserProfile(options?: {
|
|
43
|
+
baseUrl?: string;
|
|
44
|
+
url?: string;
|
|
45
|
+
}): Promise<UserProfile>;
|
|
42
46
|
getAccessToken(sessionId?: string): Promise<string>;
|
|
43
47
|
getDecodedIdToken(userId?: string, idToken?: string): Promise<IdToken>;
|
|
44
48
|
getIdToken(userId?: string): Promise<string>;
|
|
@@ -56,7 +60,20 @@ declare class ThunderIDBrowserClient<T = BrowserAuthConfig> extends ThunderIDJav
|
|
|
56
60
|
enableHttpHandler(): Promise<boolean | undefined>;
|
|
57
61
|
disableHttpHandler(): Promise<boolean | undefined>;
|
|
58
62
|
decodeJwtToken<R = Record<string, unknown>>(token: string): Promise<R>;
|
|
63
|
+
/**
|
|
64
|
+
* Subscribes a callback to a lifecycle hook. Every callback registered for a hook is called when it
|
|
65
|
+
* fires; registering the same callback again for the same hook has no further effect. Hooks can be
|
|
66
|
+
* registered before or after `initialize()`.
|
|
67
|
+
*
|
|
68
|
+
* @param hook - The hook to subscribe to (see `Hooks`).
|
|
69
|
+
* @param callback - Called when the hook fires.
|
|
70
|
+
* @param id - The custom grant id. Required for `custom-grant`.
|
|
71
|
+
*/
|
|
59
72
|
on(hook: string, callback: (response?: any) => void | Promise<void>, id?: string): Promise<void>;
|
|
73
|
+
private _addHookCallback;
|
|
74
|
+
private _emitHook;
|
|
75
|
+
private _emitHttpError;
|
|
76
|
+
private _emitHttpFinish;
|
|
60
77
|
private _enableRetrievingSignOutURLFromSession;
|
|
61
78
|
private _constructSilentSignInUrl;
|
|
62
79
|
getInstanceId(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThunderIDBrowserClient.d.ts","sourceRoot":"","sources":["../src/ThunderIDBrowserClient.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,yBAAyB,EAEzB,IAAI,EACJ,gBAAgB,EAChB,OAAO,EACP,aAAa,EAGb,OAAO,EACP,aAAa,EAGb,iBAAiB,EACjB,YAAY,
|
|
1
|
+
{"version":3,"file":"ThunderIDBrowserClient.d.ts","sourceRoot":"","sources":["../src/ThunderIDBrowserClient.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -35,6 +35,26 @@ fast_sha256 = __toESM(fast_sha256);
|
|
|
35
35
|
let jose = require("jose");
|
|
36
36
|
jose = __toESM(jose);
|
|
37
37
|
|
|
38
|
+
//#region src/constants/Hooks.ts
|
|
39
|
+
/**
|
|
40
|
+
* Event hook names for attaching callbacks via `ThunderIDBrowserClient.on()`.
|
|
41
|
+
*/
|
|
42
|
+
let Hooks = /* @__PURE__ */ function(Hooks$1) {
|
|
43
|
+
Hooks$1["SignIn"] = "sign-in";
|
|
44
|
+
Hooks$1["SignOut"] = "sign-out";
|
|
45
|
+
Hooks$1["Initialize"] = "initialize";
|
|
46
|
+
Hooks$1["HttpRequestStart"] = "http-request-start";
|
|
47
|
+
Hooks$1["HttpRequestFinish"] = "http-request-finish";
|
|
48
|
+
Hooks$1["HttpRequestError"] = "http-request-error";
|
|
49
|
+
Hooks$1["HttpRequestSuccess"] = "http-request-success";
|
|
50
|
+
Hooks$1["RevokeAccessToken"] = "revoke-access-token";
|
|
51
|
+
Hooks$1["CustomGrant"] = "custom-grant";
|
|
52
|
+
Hooks$1["SignOutFailed"] = "sign-out-failed";
|
|
53
|
+
return Hooks$1;
|
|
54
|
+
}({});
|
|
55
|
+
var Hooks_default = Hooks;
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
38
58
|
//#region src/constants/SPAConstants.ts
|
|
39
59
|
const ERROR = "error";
|
|
40
60
|
const ERROR_DESCRIPTION = "error_description";
|
|
@@ -782,6 +802,57 @@ var AuthenticationHelper = class {
|
|
|
782
802
|
};
|
|
783
803
|
var AuthenticationHelper_default = AuthenticationHelper;
|
|
784
804
|
|
|
805
|
+
//#endregion
|
|
806
|
+
//#region src/utils/createHttpClientFetcher.ts
|
|
807
|
+
/**
|
|
808
|
+
* Builds a `fetch`-shaped function backed by the shared `FetchHttpClient` singleton, for
|
|
809
|
+
* framework wrappers (`@thunderid/react`, `@thunderid/vue`) that need to hand a core
|
|
810
|
+
* `@thunderid/javascript` API function a `fetcher` carrying the access token automatically.
|
|
811
|
+
*
|
|
812
|
+
* Unlike a plain `fetch` call, `FetchHttpClient.request` throws on a non-2xx response instead
|
|
813
|
+
* of resolving it. This adapter catches that and reconstructs a `Response`-shaped object from
|
|
814
|
+
* the thrown error's `response`, so the core API function sees the real status and body instead
|
|
815
|
+
* of treating every non-2xx result as a network failure. A genuine network error (no response
|
|
816
|
+
* attached) still propagates.
|
|
817
|
+
*
|
|
818
|
+
* @param instanceId - Which `FetchHttpClient` instance to use, for multi-instance apps. Defaults to `0`.
|
|
819
|
+
* @returns A function matching the `(url, config) => Promise<Response>` shape core API functions expect.
|
|
820
|
+
* @example
|
|
821
|
+
* ```typescript
|
|
822
|
+
* await updateMeCredentials({
|
|
823
|
+
* ...config,
|
|
824
|
+
* fetcher: fetcher ?? createHttpClientFetcher(instanceId),
|
|
825
|
+
* });
|
|
826
|
+
* ```
|
|
827
|
+
*/
|
|
828
|
+
const createHttpClientFetcher = (instanceId = 0) => {
|
|
829
|
+
return async (url, config) => {
|
|
830
|
+
const httpClient = FetchHttpClient_default.getInstance(instanceId);
|
|
831
|
+
const toResponse = (data, status, statusText) => ({
|
|
832
|
+
json: () => Promise.resolve(data),
|
|
833
|
+
ok: status >= 200 && status < 300,
|
|
834
|
+
status,
|
|
835
|
+
statusText,
|
|
836
|
+
text: () => Promise.resolve(typeof data === "string" ? data : JSON.stringify(data))
|
|
837
|
+
});
|
|
838
|
+
try {
|
|
839
|
+
const response = await httpClient.request({
|
|
840
|
+
data: config.body ? JSON.parse(config.body) : void 0,
|
|
841
|
+
headers: config.headers,
|
|
842
|
+
method: config.method || "POST",
|
|
843
|
+
signal: config.signal,
|
|
844
|
+
url
|
|
845
|
+
});
|
|
846
|
+
return toResponse(response.data, response.status, response.statusText || "");
|
|
847
|
+
} catch (error) {
|
|
848
|
+
const httpError = error;
|
|
849
|
+
if (httpError?.response) return toResponse(httpError.response.data, httpError.response.status, httpError.response.statusText ?? "");
|
|
850
|
+
throw error;
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
};
|
|
854
|
+
var createHttpClientFetcher_default = createHttpClientFetcher;
|
|
855
|
+
|
|
785
856
|
//#endregion
|
|
786
857
|
//#region src/utils/navigate.ts
|
|
787
858
|
/**
|
|
@@ -2441,14 +2512,7 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2441
2512
|
_storage = BrowserStorage_default.SessionStorage;
|
|
2442
2513
|
_getSignOutURLFromSessionStorage = false;
|
|
2443
2514
|
_isHttpHandlerEnabled = true;
|
|
2444
|
-
|
|
2445
|
-
_httpFinishCallback;
|
|
2446
|
-
_onSignInCallback = () => null;
|
|
2447
|
-
_onSignOutCallback = () => null;
|
|
2448
|
-
_onSignOutFailedCallback = () => null;
|
|
2449
|
-
_onEndUserSession = () => null;
|
|
2450
|
-
_onInitialize = () => null;
|
|
2451
|
-
_onCustomGrant = /* @__PURE__ */ new Map();
|
|
2515
|
+
_hookCallbacks = /* @__PURE__ */ new Map();
|
|
2452
2516
|
_initialized = false;
|
|
2453
2517
|
_startedInitialize = false;
|
|
2454
2518
|
constructor(instanceId = 0) {
|
|
@@ -2475,6 +2539,12 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2475
2539
|
await this._authHelper?.attachTokenToRequestConfig(request);
|
|
2476
2540
|
};
|
|
2477
2541
|
this._httpClient = FetchHttpClient_default.getInstance(this._browserInstanceId, true, attachToken);
|
|
2542
|
+
this._httpClient.setHttpRequestStartCallback((request) => {
|
|
2543
|
+
this._emitHook(Hooks_default.HttpRequestStart, request);
|
|
2544
|
+
});
|
|
2545
|
+
this._httpClient.setHttpRequestSuccessCallback((response) => {
|
|
2546
|
+
this._emitHook(Hooks_default.HttpRequestSuccess, response);
|
|
2547
|
+
});
|
|
2478
2548
|
this._authHelper = new AuthenticationHelper_default(sm, this._spaHelper, this._browserInstanceId, {
|
|
2479
2549
|
exchangeToken: (cfg) => super.exchangeToken(cfg),
|
|
2480
2550
|
getAccessToken: (sessionId) => this.getAccessToken(sessionId),
|
|
@@ -2489,7 +2559,7 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2489
2559
|
setPKCECode: (pkceKey, state) => this.setPKCECode(pkceKey, state)
|
|
2490
2560
|
});
|
|
2491
2561
|
this._initialized = true;
|
|
2492
|
-
|
|
2562
|
+
this._emitHook(Hooks_default.Initialize, true);
|
|
2493
2563
|
if (!merged.autoLogoutOnTokenRefreshError) return true;
|
|
2494
2564
|
window.addEventListener("message", (event) => {
|
|
2495
2565
|
if (event?.data?.type === REFRESH_ACCESS_TOKEN_ERR0R) this.signOut();
|
|
@@ -2520,7 +2590,7 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2520
2590
|
if (!SPAUtils_default.canContinueSignIn(Boolean(config?.callOnlyOnRedirect), authorizationCode)) return;
|
|
2521
2591
|
delete config?.callOnlyOnRedirect;
|
|
2522
2592
|
const user = await this._signInInternal(config, authorizationCode, state, tokenRequestConfig);
|
|
2523
|
-
if (user
|
|
2593
|
+
if (user) this._emitHook(Hooks_default.SignIn, user);
|
|
2524
2594
|
return user;
|
|
2525
2595
|
}
|
|
2526
2596
|
async _signInInternal(signInConfig, authorizationCode, state, tokenRequestConfig) {
|
|
@@ -2589,7 +2659,7 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2589
2659
|
await this.isInitialized();
|
|
2590
2660
|
if (SPAUtils_default.wasSignInCalled()) return;
|
|
2591
2661
|
const response = await this._signInSilentlyInternal(additionalParams, tokenRequestConfig);
|
|
2592
|
-
if (
|
|
2662
|
+
if (response) this._emitHook(Hooks_default.SignIn, response);
|
|
2593
2663
|
return response;
|
|
2594
2664
|
}
|
|
2595
2665
|
async _signInSilentlyInternal(additionalParams, tokenRequestConfig) {
|
|
@@ -2635,16 +2705,40 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2635
2705
|
}
|
|
2636
2706
|
async httpRequest(requestConfig) {
|
|
2637
2707
|
await this._validateMethod(false);
|
|
2638
|
-
|
|
2708
|
+
const response = await this._authHelper.httpRequest(this._httpClient, requestConfig, this._isHttpHandlerEnabled, this._emitHttpError, this._emitHttpFinish);
|
|
2709
|
+
if (this._isHttpHandlerEnabled) this._emitHttpFinish();
|
|
2710
|
+
return response;
|
|
2639
2711
|
}
|
|
2640
2712
|
async httpRequestAll(configs) {
|
|
2641
2713
|
await this._validateMethod(false);
|
|
2642
|
-
|
|
2714
|
+
const responses = await this._authHelper.httpRequestAll(configs, this._httpClient, this._isHttpHandlerEnabled, this._emitHttpError, this._emitHttpFinish);
|
|
2715
|
+
if (this._isHttpHandlerEnabled) this._emitHttpFinish();
|
|
2716
|
+
return responses;
|
|
2643
2717
|
}
|
|
2644
2718
|
async getUser(userId) {
|
|
2645
2719
|
await this._validateMethod();
|
|
2646
2720
|
return super.getUser(userId);
|
|
2647
2721
|
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Fetches the signed-in user's profile from the `/users/me` endpoint (or `endpoints.usersMe` when
|
|
2724
|
+
* configured), sending the request through the client's HTTP client so the access token is attached.
|
|
2725
|
+
*
|
|
2726
|
+
* @param options - Optional `baseUrl` or full `url` overrides for the profile endpoint.
|
|
2727
|
+
* @returns The user's profile.
|
|
2728
|
+
*/
|
|
2729
|
+
async getUserProfile(options) {
|
|
2730
|
+
await this._validateMethod();
|
|
2731
|
+
const configData = await this.getStorageManager().getConfigData();
|
|
2732
|
+
const profile = await (0, __thunderid_javascript.getUsersMe)({
|
|
2733
|
+
baseUrl: options?.baseUrl ?? configData?.baseUrl,
|
|
2734
|
+
fetcher: createHttpClientFetcher_default(this._browserInstanceId),
|
|
2735
|
+
url: (0, __thunderid_javascript.resolveResourceEndpoint)("usersMe", configData, options?.url)
|
|
2736
|
+
});
|
|
2737
|
+
return {
|
|
2738
|
+
flattenedProfile: (0, __thunderid_javascript.generateFlattenedUserProfile)(profile),
|
|
2739
|
+
profile
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2648
2742
|
async getAccessToken(sessionId) {
|
|
2649
2743
|
return super.getAccessToken(sessionId);
|
|
2650
2744
|
}
|
|
@@ -2673,7 +2767,7 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2673
2767
|
return super.isSignedIn(userId);
|
|
2674
2768
|
}
|
|
2675
2769
|
notifySignIn(user) {
|
|
2676
|
-
this.
|
|
2770
|
+
this._emitHook(Hooks_default.SignIn, user);
|
|
2677
2771
|
}
|
|
2678
2772
|
async isSessionActive() {
|
|
2679
2773
|
await this.isInitialized();
|
|
@@ -2692,14 +2786,14 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2692
2786
|
const timer = await this._spaHelper.getRefreshTimeoutTimer();
|
|
2693
2787
|
await super.revokeAccessToken(userId);
|
|
2694
2788
|
await this._spaHelper.clearRefreshTokenTimeout(timer);
|
|
2695
|
-
|
|
2789
|
+
await this._emitHook(Hooks_default.RevokeAccessToken, true);
|
|
2696
2790
|
return true;
|
|
2697
2791
|
}
|
|
2698
2792
|
async exchangeToken(config) {
|
|
2699
2793
|
if (config.signInRequired) await this._validateMethod();
|
|
2700
2794
|
if (!config.id) return Promise.reject(new __thunderid_javascript.ThunderIDAuthException("SPA-AUTH_CLIENT-RCG-NF01", "The custom grant request id not found.", "Set the `id` attribute on the token exchange config."));
|
|
2701
2795
|
const response = await this._authHelper.exchangeToken(config, (cfg) => this._enableRetrievingSignOutURLFromSession(cfg));
|
|
2702
|
-
this.
|
|
2796
|
+
this._emitHook(`${Hooks_default.CustomGrant}:${config.id}`, response);
|
|
2703
2797
|
return response;
|
|
2704
2798
|
}
|
|
2705
2799
|
async reInitialize(config) {
|
|
@@ -2726,47 +2820,56 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2726
2820
|
async decodeJwtToken(token) {
|
|
2727
2821
|
return this.getCryptoHelper().decodeJwtToken(token);
|
|
2728
2822
|
}
|
|
2823
|
+
/**
|
|
2824
|
+
* Subscribes a callback to a lifecycle hook. Every callback registered for a hook is called when it
|
|
2825
|
+
* fires; registering the same callback again for the same hook has no further effect. Hooks can be
|
|
2826
|
+
* registered before or after `initialize()`.
|
|
2827
|
+
*
|
|
2828
|
+
* @param hook - The hook to subscribe to (see `Hooks`).
|
|
2829
|
+
* @param callback - Called when the hook fires.
|
|
2830
|
+
* @param id - The custom grant id. Required for `custom-grant`.
|
|
2831
|
+
*/
|
|
2729
2832
|
async on(hook, callback, id) {
|
|
2730
2833
|
await this.isInitialized();
|
|
2731
2834
|
if (!callback || typeof callback !== "function") throw new __thunderid_javascript.ThunderIDAuthException("SPA-AUTH_CLIENT-ON-IV02", "Invalid callback function.", "The provided callback must be a function.");
|
|
2732
2835
|
switch (hook) {
|
|
2733
|
-
case
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
case
|
|
2737
|
-
|
|
2738
|
-
|
|
2836
|
+
case Hooks_default.SignIn:
|
|
2837
|
+
case Hooks_default.RevokeAccessToken:
|
|
2838
|
+
case Hooks_default.Initialize:
|
|
2839
|
+
case Hooks_default.HttpRequestError:
|
|
2840
|
+
case Hooks_default.HttpRequestFinish:
|
|
2841
|
+
case Hooks_default.HttpRequestStart:
|
|
2842
|
+
case Hooks_default.HttpRequestSuccess:
|
|
2843
|
+
this._addHookCallback(hook, callback);
|
|
2739
2844
|
break;
|
|
2740
|
-
case
|
|
2741
|
-
|
|
2845
|
+
case Hooks_default.SignOut:
|
|
2846
|
+
if (await SPAUtils_default.isSignOutSuccessful(ThunderIDBrowserClient.isSignOutSuccessful.bind(ThunderIDBrowserClient), () => ThunderIDBrowserClient.clearSession())) callback();
|
|
2742
2847
|
break;
|
|
2743
|
-
case
|
|
2744
|
-
this.
|
|
2848
|
+
case Hooks_default.CustomGrant:
|
|
2849
|
+
id && this._addHookCallback(`${Hooks_default.CustomGrant}:${id}`, callback);
|
|
2745
2850
|
break;
|
|
2746
|
-
case
|
|
2747
|
-
this._httpErrorCallback = callback;
|
|
2748
|
-
break;
|
|
2749
|
-
case "http-request-finish":
|
|
2750
|
-
this._httpFinishCallback = callback;
|
|
2751
|
-
break;
|
|
2752
|
-
case "http-request-start":
|
|
2753
|
-
this._httpClient?.setHttpRequestStartCallback?.(callback);
|
|
2754
|
-
break;
|
|
2755
|
-
case "http-request-success":
|
|
2756
|
-
this._httpClient?.setHttpRequestSuccessCallback?.(callback);
|
|
2757
|
-
break;
|
|
2758
|
-
case "custom-grant":
|
|
2759
|
-
id && this._onCustomGrant.set(id, callback);
|
|
2760
|
-
break;
|
|
2761
|
-
case "sign-out-failed": {
|
|
2762
|
-
this._onSignOutFailedCallback = callback;
|
|
2851
|
+
case Hooks_default.SignOutFailed: {
|
|
2763
2852
|
const signOutFail = SPAUtils_default.didSignOutFail(ThunderIDBrowserClient.didSignOutFail.bind(ThunderIDBrowserClient));
|
|
2764
|
-
if (signOutFail)
|
|
2853
|
+
if (signOutFail) callback(signOutFail);
|
|
2765
2854
|
break;
|
|
2766
2855
|
}
|
|
2767
2856
|
default: throw new __thunderid_javascript.ThunderIDAuthException("SPA-AUTH_CLIENT-ON-IV01", "Invalid hook.", `Unknown hook: "${hook}"`);
|
|
2768
2857
|
}
|
|
2769
2858
|
}
|
|
2859
|
+
_addHookCallback(hook, callback) {
|
|
2860
|
+
const callbacks = this._hookCallbacks.get(hook) ?? /* @__PURE__ */ new Set();
|
|
2861
|
+
callbacks.add(callback);
|
|
2862
|
+
this._hookCallbacks.set(hook, callbacks);
|
|
2863
|
+
}
|
|
2864
|
+
_emitHook(hook, response) {
|
|
2865
|
+
return Promise.all([...this._hookCallbacks.get(hook) ?? []].map((callback) => Promise.resolve(callback(response))));
|
|
2866
|
+
}
|
|
2867
|
+
_emitHttpError = async (error) => {
|
|
2868
|
+
await this._emitHook(Hooks_default.HttpRequestError, error);
|
|
2869
|
+
};
|
|
2870
|
+
_emitHttpFinish = () => {
|
|
2871
|
+
this._emitHook(Hooks_default.HttpRequestFinish);
|
|
2872
|
+
};
|
|
2770
2873
|
_enableRetrievingSignOutURLFromSession(config) {
|
|
2771
2874
|
if (config.preventSignOutURLUpdate) this._getSignOutURLFromSessionStorage = true;
|
|
2772
2875
|
}
|
|
@@ -2792,26 +2895,6 @@ var ThunderIDBrowserClient = class ThunderIDBrowserClient extends __thunderid_ja
|
|
|
2792
2895
|
};
|
|
2793
2896
|
var ThunderIDBrowserClient_default = ThunderIDBrowserClient;
|
|
2794
2897
|
|
|
2795
|
-
//#endregion
|
|
2796
|
-
//#region src/constants/Hooks.ts
|
|
2797
|
-
/**
|
|
2798
|
-
* Event hook names for attaching callbacks via `ThunderIDBrowserClient.on()`.
|
|
2799
|
-
*/
|
|
2800
|
-
let Hooks = /* @__PURE__ */ function(Hooks$1) {
|
|
2801
|
-
Hooks$1["SignIn"] = "sign-in";
|
|
2802
|
-
Hooks$1["SignOut"] = "sign-out";
|
|
2803
|
-
Hooks$1["Initialize"] = "initialize";
|
|
2804
|
-
Hooks$1["HttpRequestStart"] = "http-request-start";
|
|
2805
|
-
Hooks$1["HttpRequestFinish"] = "http-request-finish";
|
|
2806
|
-
Hooks$1["HttpRequestError"] = "http-request-error";
|
|
2807
|
-
Hooks$1["HttpRequestSuccess"] = "http-request-success";
|
|
2808
|
-
Hooks$1["RevokeAccessToken"] = "revoke-access-token";
|
|
2809
|
-
Hooks$1["CustomGrant"] = "custom-grant";
|
|
2810
|
-
Hooks$1["SignOutFailed"] = "sign-out-failed";
|
|
2811
|
-
return Hooks$1;
|
|
2812
|
-
}({});
|
|
2813
|
-
var Hooks_default = Hooks;
|
|
2814
|
-
|
|
2815
2898
|
//#endregion
|
|
2816
2899
|
//#region src/utils/hasAuthParamsInUrl.ts
|
|
2817
2900
|
/**
|
|
@@ -2863,57 +2946,6 @@ const http = (client) => {
|
|
|
2863
2946
|
};
|
|
2864
2947
|
var http_default = http;
|
|
2865
2948
|
|
|
2866
|
-
//#endregion
|
|
2867
|
-
//#region src/utils/createHttpClientFetcher.ts
|
|
2868
|
-
/**
|
|
2869
|
-
* Builds a `fetch`-shaped function backed by the shared `FetchHttpClient` singleton, for
|
|
2870
|
-
* framework wrappers (`@thunderid/react`, `@thunderid/vue`) that need to hand a core
|
|
2871
|
-
* `@thunderid/javascript` API function a `fetcher` carrying the access token automatically.
|
|
2872
|
-
*
|
|
2873
|
-
* Unlike a plain `fetch` call, `FetchHttpClient.request` throws on a non-2xx response instead
|
|
2874
|
-
* of resolving it. This adapter catches that and reconstructs a `Response`-shaped object from
|
|
2875
|
-
* the thrown error's `response`, so the core API function sees the real status and body instead
|
|
2876
|
-
* of treating every non-2xx result as a network failure. A genuine network error (no response
|
|
2877
|
-
* attached) still propagates.
|
|
2878
|
-
*
|
|
2879
|
-
* @param instanceId - Which `FetchHttpClient` instance to use, for multi-instance apps. Defaults to `0`.
|
|
2880
|
-
* @returns A function matching the `(url, config) => Promise<Response>` shape core API functions expect.
|
|
2881
|
-
* @example
|
|
2882
|
-
* ```typescript
|
|
2883
|
-
* await updateMeCredentials({
|
|
2884
|
-
* ...config,
|
|
2885
|
-
* fetcher: fetcher ?? createHttpClientFetcher(instanceId),
|
|
2886
|
-
* });
|
|
2887
|
-
* ```
|
|
2888
|
-
*/
|
|
2889
|
-
const createHttpClientFetcher = (instanceId = 0) => {
|
|
2890
|
-
return async (url, config) => {
|
|
2891
|
-
const httpClient = FetchHttpClient_default.getInstance(instanceId);
|
|
2892
|
-
const toResponse = (data, status, statusText) => ({
|
|
2893
|
-
json: () => Promise.resolve(data),
|
|
2894
|
-
ok: status >= 200 && status < 300,
|
|
2895
|
-
status,
|
|
2896
|
-
statusText,
|
|
2897
|
-
text: () => Promise.resolve(typeof data === "string" ? data : JSON.stringify(data))
|
|
2898
|
-
});
|
|
2899
|
-
try {
|
|
2900
|
-
const response = await httpClient.request({
|
|
2901
|
-
data: config.body ? JSON.parse(config.body) : void 0,
|
|
2902
|
-
headers: config.headers,
|
|
2903
|
-
method: config.method || "POST",
|
|
2904
|
-
signal: config.signal,
|
|
2905
|
-
url
|
|
2906
|
-
});
|
|
2907
|
-
return toResponse(response.data, response.status, response.statusText || "");
|
|
2908
|
-
} catch (error) {
|
|
2909
|
-
const httpError = error;
|
|
2910
|
-
if (httpError?.response) return toResponse(httpError.response.data, httpError.response.status, httpError.response.statusText ?? "");
|
|
2911
|
-
throw error;
|
|
2912
|
-
}
|
|
2913
|
-
};
|
|
2914
|
-
};
|
|
2915
|
-
var createHttpClientFetcher_default = createHttpClientFetcher;
|
|
2916
|
-
|
|
2917
2949
|
//#endregion
|
|
2918
2950
|
//#region src/utils/copyTextToClipboard.ts
|
|
2919
2951
|
/**
|
|
@@ -3507,6 +3539,23 @@ const AVATAR_PALETTES = [
|
|
|
3507
3539
|
* without needing the actual palette values.
|
|
3508
3540
|
*/
|
|
3509
3541
|
const AVATAR_GRADIENT_COUNT = AVATAR_PALETTES.length;
|
|
3542
|
+
const XML_ESCAPES = {
|
|
3543
|
+
"\"": """,
|
|
3544
|
+
"&": "&",
|
|
3545
|
+
"'": "'",
|
|
3546
|
+
"<": "<",
|
|
3547
|
+
">": ">"
|
|
3548
|
+
};
|
|
3549
|
+
/**
|
|
3550
|
+
* Escapes a caller-supplied value for interpolation into SVG text.
|
|
3551
|
+
*/
|
|
3552
|
+
const escapeXml = (value) => value.replace(/["&'<>]/g, (ch) => XML_ESCAPES[ch]);
|
|
3553
|
+
/**
|
|
3554
|
+
* Encodes an SVG document as a data URI. Lone UTF-16 surrogates are replaced with U+FFFD
|
|
3555
|
+
* first, since `encodeURIComponent` throws a `URIError` on them. `Array.from` iterates by
|
|
3556
|
+
* code point, so a surrogate it yields on its own is unpaired.
|
|
3557
|
+
*/
|
|
3558
|
+
const toSvgDataUri = (svg) => `data:image/svg+xml,${encodeURIComponent(Array.from(svg, (ch) => ch.length === 1 && ch >= "\ud800" && ch <= "\udfff" ? "�" : ch).join(""))}`;
|
|
3510
3559
|
/**
|
|
3511
3560
|
* Fills in `params.content` when the spec itself didn't carry one, deriving it from a raw
|
|
3512
3561
|
* seed name (e.g. an app or user display name) — extracting initials for letter variants,
|
|
@@ -3557,11 +3606,10 @@ const generateGradientAvatar = ({ shape, variant, content, colors, bg }) => {
|
|
|
3557
3606
|
let text = "";
|
|
3558
3607
|
if (variant !== "blank") {
|
|
3559
3608
|
const letterCount = variant === "one_letter" ? 1 : 2;
|
|
3560
|
-
const initials = (content || "A").toUpperCase().slice(0, letterCount);
|
|
3609
|
+
const initials = escapeXml(Array.from((content || "A").toUpperCase()).slice(0, letterCount).join(""));
|
|
3561
3610
|
text = `<text x="50" y="64" font-family="Helvetica,Arial,sans-serif" font-weight="700" font-size="${letterCount === 1 ? 46 : 34}" text-anchor="middle" fill="#fff">${initials}</text>`;
|
|
3562
3611
|
}
|
|
3563
|
-
|
|
3564
|
-
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
3612
|
+
return toSvgDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${defs}${shapeMarkup(shape, background)}${text}</svg>`);
|
|
3565
3613
|
};
|
|
3566
3614
|
/**
|
|
3567
3615
|
* Renders one of the curated anonymous-animal icons, applying the requested background
|
|
@@ -3573,8 +3621,7 @@ const generateAnonymousAnimalAvatar = ({ shape, content, bg }) => {
|
|
|
3573
3621
|
const icon = ANONYMOUS_ANIMAL_ICONS[Object.prototype.hasOwnProperty.call(ANONYMOUS_ANIMAL_ICONS, content) ? content : pickAnonymousAvatarName_default()];
|
|
3574
3622
|
const color = bg ?? icon.color;
|
|
3575
3623
|
const markup = icon.markup.replaceAll("%COLOR%", color);
|
|
3576
|
-
|
|
3577
|
-
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
3624
|
+
return toSvgDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${shapeMarkup(shape, color)}${markup}</svg>`);
|
|
3578
3625
|
};
|
|
3579
3626
|
/**
|
|
3580
3627
|
* Renders one of the curated anonymous-entity icons (application/organization/resource-server
|
|
@@ -3586,8 +3633,7 @@ const generateAnonymousEntityAvatar = ({ shape, content, bg }) => {
|
|
|
3586
3633
|
const icon = ANONYMOUS_ENTITY_ICONS[Object.prototype.hasOwnProperty.call(ANONYMOUS_ENTITY_ICONS, content) ? content : pickAnonymousEntityName_default()];
|
|
3587
3634
|
const color = bg ?? icon.color;
|
|
3588
3635
|
const markup = icon.markup.replaceAll("%COLOR%", color);
|
|
3589
|
-
|
|
3590
|
-
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
3636
|
+
return toSvgDataUri(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">${shapeMarkup(shape, color)}${markup}</svg>`);
|
|
3591
3637
|
};
|
|
3592
3638
|
/**
|
|
3593
3639
|
* Generates an avatar image as an `svg+xml` data URI from a fully-resolved {@link AvatarParams}.
|
|
@@ -3704,7 +3750,8 @@ const createClassObserver = (targetElement, callback, config = {}) => {
|
|
|
3704
3750
|
return observer;
|
|
3705
3751
|
};
|
|
3706
3752
|
/**
|
|
3707
|
-
* Creates a media query listener for system theme changes
|
|
3753
|
+
* Creates a media query listener for system theme changes. Call `disconnect()` on the returned
|
|
3754
|
+
* object to remove the listener.
|
|
3708
3755
|
*/
|
|
3709
3756
|
const createMediaQueryListener = (callback) => {
|
|
3710
3757
|
if (typeof window === "undefined" || !window.matchMedia) return null;
|
|
@@ -3714,7 +3761,10 @@ const createMediaQueryListener = (callback) => {
|
|
|
3714
3761
|
};
|
|
3715
3762
|
if (mediaQuery.addEventListener) mediaQuery.addEventListener("change", handleChange);
|
|
3716
3763
|
else mediaQuery.addListener(handleChange);
|
|
3717
|
-
return mediaQuery
|
|
3764
|
+
return Object.assign(mediaQuery, { disconnect: () => {
|
|
3765
|
+
if (mediaQuery.removeEventListener) mediaQuery.removeEventListener("change", handleChange);
|
|
3766
|
+
else mediaQuery.removeListener(handleChange);
|
|
3767
|
+
} });
|
|
3718
3768
|
};
|
|
3719
3769
|
|
|
3720
3770
|
//#endregion
|