@thunderid/javascript 0.0.5 → 0.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/README.md +3 -2
- package/dist/HttpClient.d.ts.map +1 -1
- package/dist/StorageManager.d.ts +10 -4
- package/dist/StorageManager.d.ts.map +1 -1
- package/dist/ThunderIDJavaScriptClient.d.ts.map +1 -1
- package/dist/api/createOrganization.d.ts +2 -2
- package/dist/api/executeEmbeddedSignUpFlow.d.ts +1 -1
- package/dist/api/getAllOrganizations.d.ts +2 -2
- package/dist/api/getBrandingPreference.d.ts +2 -2
- package/dist/api/getMeOrganizations.d.ts +2 -2
- package/dist/api/getOrganization.d.ts +2 -2
- package/dist/api/getSchemas.d.ts +2 -2
- package/dist/api/getScim2Me.d.ts +2 -2
- package/dist/api/getUserInfo.d.ts +1 -1
- package/dist/api/initializeEmbeddedSignInFlow.d.ts +1 -1
- package/dist/api/updateMeProfile.d.ts +2 -2
- package/dist/api/updateOrganization.d.ts +3 -3
- package/dist/api/v2/executeEmbeddedRecoveryFlowV2.d.ts +2 -2
- package/dist/api/v2/executeEmbeddedRecoveryFlowV2.d.ts.map +1 -1
- package/dist/api/v2/executeEmbeddedSignInFlowV2.d.ts +1 -1
- package/dist/api/v2/executeEmbeddedSignInFlowV2.d.ts.map +1 -1
- package/dist/api/v2/executeEmbeddedSignUpFlowV2.d.ts +1 -1
- package/dist/api/v2/executeEmbeddedSignUpFlowV2.d.ts.map +1 -1
- package/dist/api/v2/executeEmbeddedUserOnboardingFlowV2.d.ts +4 -4
- package/dist/api/v2/executeEmbeddedUserOnboardingFlowV2.d.ts.map +1 -1
- package/dist/cjs/index.cjs +269 -149
- package/dist/edge/index.js +269 -149
- package/dist/errors/ThunderIDAPIError.d.ts +3 -3
- package/dist/errors/ThunderIDAPIError.d.ts.map +1 -1
- package/dist/errors/ThunderIDRuntimeError.d.ts +2 -2
- package/dist/errors/ThunderIDRuntimeError.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +269 -149
- package/dist/models/config.d.ts +10 -3
- package/dist/models/config.d.ts.map +1 -1
- package/dist/models/embedded-flow.d.ts +1 -6
- package/dist/models/embedded-flow.d.ts.map +1 -1
- package/dist/models/store.d.ts +9 -1
- package/dist/models/store.d.ts.map +1 -1
- package/dist/models/v2/embedded-flow-v2.d.ts +63 -7
- package/dist/models/v2/embedded-flow-v2.d.ts.map +1 -1
- package/dist/models/v2/embedded-recovery-flow-v2.d.ts +4 -15
- package/dist/models/v2/embedded-recovery-flow-v2.d.ts.map +1 -1
- package/dist/models/v2/embedded-signin-flow-v2.d.ts +12 -7
- package/dist/models/v2/embedded-signin-flow-v2.d.ts.map +1 -1
- package/dist/models/v2/embedded-signup-flow-v2.d.ts +21 -54
- package/dist/models/v2/embedded-signup-flow-v2.d.ts.map +1 -1
- package/dist/theme/createTheme.d.ts.map +1 -1
- package/dist/utils/AuthenticationHelper.d.ts.map +1 -1
- package/dist/utils/deriveOrganizationHandleFromBaseUrl.d.ts +3 -11
- package/dist/utils/deriveOrganizationHandleFromBaseUrl.d.ts.map +1 -1
- package/dist/utils/identifyPlatform.d.ts.map +1 -1
- package/dist/utils/isRecognizedBaseUrlPattern.d.ts +1 -1
- package/dist/utils/parseApiErrorMessage.d.ts +1 -1
- package/dist/utils/v2/injectRequestedPermissions.d.ts +26 -0
- package/dist/utils/v2/injectRequestedPermissions.d.ts.map +1 -0
- package/package.json +9 -6
package/dist/index.js
CHANGED
|
@@ -256,7 +256,7 @@ var ThunderIDError = class ThunderIDError extends Error {
|
|
|
256
256
|
* The backend returns errors in the following form:
|
|
257
257
|
* {"code":"...","message":{"key":"...","defaultValue":"..."},"description":{"key":"...","defaultValue":"..."}}
|
|
258
258
|
*
|
|
259
|
-
* Returns `
|
|
259
|
+
* Returns `message.defaultValue` if present, then `description.defaultValue`, and falls back
|
|
260
260
|
* to the raw `errorText` when the response is not a recognised structured error.
|
|
261
261
|
*/
|
|
262
262
|
const parseApiErrorMessage = (errorText) => {
|
|
@@ -264,8 +264,10 @@ const parseApiErrorMessage = (errorText) => {
|
|
|
264
264
|
const parsed = JSON.parse(errorText);
|
|
265
265
|
const description = parsed["description"];
|
|
266
266
|
const message = parsed["message"];
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
const descFallback = description?.defaultValue;
|
|
268
|
+
const msgFallback = message?.defaultValue;
|
|
269
|
+
if (msgFallback) return msgFallback;
|
|
270
|
+
if (descFallback) return descFallback;
|
|
269
271
|
} catch {}
|
|
270
272
|
return errorText;
|
|
271
273
|
};
|
|
@@ -339,7 +341,7 @@ var ThunderIDAPIError = class extends ThunderIDError {
|
|
|
339
341
|
* ```typescript
|
|
340
342
|
* try {
|
|
341
343
|
* const authResponse = await initializeEmbeddedSignInFlow({
|
|
342
|
-
* url: "https://
|
|
344
|
+
* url: "https://localhost:8090/oauth2/authorize",
|
|
343
345
|
* payload: {
|
|
344
346
|
* response_type: "code",
|
|
345
347
|
* client_id: "your-client-id",
|
|
@@ -480,7 +482,7 @@ let EmbeddedFlowComponentType = /* @__PURE__ */ function(EmbeddedFlowComponentTy
|
|
|
480
482
|
* ```typescript
|
|
481
483
|
* try {
|
|
482
484
|
* const embeddedSignUpResponse = await executeEmbeddedSignUpFlow({
|
|
483
|
-
* url: "https://
|
|
485
|
+
* url: "https://localhost:8090/api/server/v1/flow/execute",
|
|
484
486
|
* payload: {
|
|
485
487
|
* flowType: "REGISTRATION"
|
|
486
488
|
* }
|
|
@@ -532,7 +534,7 @@ var executeEmbeddedSignUpFlow_default = executeEmbeddedSignUpFlow;
|
|
|
532
534
|
* @returns A promise that resolves with the user information.
|
|
533
535
|
* @throw
|
|
534
536
|
* const userInfo = await getUserInfo({
|
|
535
|
-
* url: "https://
|
|
537
|
+
* url: "https://localhost:8090/oauth2/userinfo",
|
|
536
538
|
* });
|
|
537
539
|
* console.log(userInfo);
|
|
538
540
|
* } catch (error) {
|
|
@@ -667,7 +669,7 @@ var processUsername_default = processUsername;
|
|
|
667
669
|
* // Using default fetch
|
|
668
670
|
* try {
|
|
669
671
|
* const userProfile = await getScim2Me({
|
|
670
|
-
* url: "https://
|
|
672
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
671
673
|
* });
|
|
672
674
|
* console.log(userProfile);
|
|
673
675
|
* } catch (error) {
|
|
@@ -682,7 +684,7 @@ var processUsername_default = processUsername;
|
|
|
682
684
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
683
685
|
* try {
|
|
684
686
|
* const userProfile = await getScim2Me({
|
|
685
|
-
* url: "https://
|
|
687
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
686
688
|
* fetcher: async (url, config) => {
|
|
687
689
|
* const response = await httpClient({
|
|
688
690
|
* url,
|
|
@@ -748,7 +750,7 @@ var getScim2Me_default = getScim2Me;
|
|
|
748
750
|
* // Using default fetch
|
|
749
751
|
* try {
|
|
750
752
|
* const schemas = await getSchemas({
|
|
751
|
-
* url: "https://
|
|
753
|
+
* url: "https://localhost:8090/scim2/Schemas",
|
|
752
754
|
* });
|
|
753
755
|
* console.log(schemas);
|
|
754
756
|
* } catch (error) {
|
|
@@ -763,7 +765,7 @@ var getScim2Me_default = getScim2Me;
|
|
|
763
765
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
764
766
|
* try {
|
|
765
767
|
* const schemas = await getSchemas({
|
|
766
|
-
* url: "https://
|
|
768
|
+
* url: "https://localhost:8090/scim2/Schemas",
|
|
767
769
|
* fetcher: async (url, config) => {
|
|
768
770
|
* const response = await httpClient({
|
|
769
771
|
* url,
|
|
@@ -829,7 +831,7 @@ var getSchemas_default = getSchemas;
|
|
|
829
831
|
* // Using default fetch
|
|
830
832
|
* try {
|
|
831
833
|
* const response = await getAllOrganizations({
|
|
832
|
-
* baseUrl: "https://
|
|
834
|
+
* baseUrl: "https://localhost:8090",
|
|
833
835
|
* filter: "",
|
|
834
836
|
* limit: 10,
|
|
835
837
|
* recursive: false
|
|
@@ -847,7 +849,7 @@ var getSchemas_default = getSchemas;
|
|
|
847
849
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
848
850
|
* try {
|
|
849
851
|
* const response = await getAllOrganizations({
|
|
850
|
-
* baseUrl: "https://
|
|
852
|
+
* baseUrl: "https://localhost:8090",
|
|
851
853
|
* filter: "",
|
|
852
854
|
* limit: 10,
|
|
853
855
|
* recursive: false,
|
|
@@ -927,7 +929,7 @@ var getAllOrganizations_default = getAllOrganizations;
|
|
|
927
929
|
* // Using default fetch
|
|
928
930
|
* try {
|
|
929
931
|
* const organization = await createOrganization({
|
|
930
|
-
* baseUrl: "https://
|
|
932
|
+
* baseUrl: "https://localhost:8090",
|
|
931
933
|
* payload: {
|
|
932
934
|
* description: "Share your screens",
|
|
933
935
|
* name: "Team Viewer",
|
|
@@ -949,7 +951,7 @@ var getAllOrganizations_default = getAllOrganizations;
|
|
|
949
951
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
950
952
|
* try {
|
|
951
953
|
* const organization = await createOrganization({
|
|
952
|
-
* baseUrl: "https://
|
|
954
|
+
* baseUrl: "https://localhost:8090",
|
|
953
955
|
* payload: {
|
|
954
956
|
* description: "Share your screens",
|
|
955
957
|
* name: "Team Viewer",
|
|
@@ -1029,7 +1031,7 @@ var createOrganization_default = createOrganization;
|
|
|
1029
1031
|
* // Using default fetch
|
|
1030
1032
|
* try {
|
|
1031
1033
|
* const organizations = await getMeOrganizations({
|
|
1032
|
-
* baseUrl: "https://
|
|
1034
|
+
* baseUrl: "https://localhost:8090",
|
|
1033
1035
|
* after: "",
|
|
1034
1036
|
* before: "",
|
|
1035
1037
|
* filter: "",
|
|
@@ -1049,7 +1051,7 @@ var createOrganization_default = createOrganization;
|
|
|
1049
1051
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1050
1052
|
* try {
|
|
1051
1053
|
* const organizations = await getMeOrganizations({
|
|
1052
|
-
* baseUrl: "https://
|
|
1054
|
+
* baseUrl: "https://localhost:8090",
|
|
1053
1055
|
* after: "",
|
|
1054
1056
|
* before: "",
|
|
1055
1057
|
* filter: "",
|
|
@@ -1128,7 +1130,7 @@ var getMeOrganizations_default = getMeOrganizations;
|
|
|
1128
1130
|
* // Using default fetch
|
|
1129
1131
|
* try {
|
|
1130
1132
|
* const organization = await getOrganization({
|
|
1131
|
-
* baseUrl: "https://
|
|
1133
|
+
* baseUrl: "https://localhost:8090",
|
|
1132
1134
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1"
|
|
1133
1135
|
* });
|
|
1134
1136
|
* console.log(organization);
|
|
@@ -1144,7 +1146,7 @@ var getMeOrganizations_default = getMeOrganizations;
|
|
|
1144
1146
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1145
1147
|
* try {
|
|
1146
1148
|
* const organization = await getOrganization({
|
|
1147
|
-
* baseUrl: "https://
|
|
1149
|
+
* baseUrl: "https://localhost:8090",
|
|
1148
1150
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1",
|
|
1149
1151
|
* fetcher: async (url, config) => {
|
|
1150
1152
|
* const response = await httpClient({
|
|
@@ -1274,14 +1276,14 @@ var isEmpty_default = isEmpty;
|
|
|
1274
1276
|
* });
|
|
1275
1277
|
*
|
|
1276
1278
|
* await updateOrganization({
|
|
1277
|
-
* baseUrl: "https://
|
|
1279
|
+
* baseUrl: "https://localhost:8090",
|
|
1278
1280
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1",
|
|
1279
1281
|
* operations
|
|
1280
1282
|
* });
|
|
1281
1283
|
*
|
|
1282
1284
|
* // Or manually specify operations
|
|
1283
1285
|
* await updateOrganization({
|
|
1284
|
-
* baseUrl: "https://
|
|
1286
|
+
* baseUrl: "https://localhost:8090",
|
|
1285
1287
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1",
|
|
1286
1288
|
* operations: [
|
|
1287
1289
|
* { operation: "REPLACE", path: "/name", value: "Updated Organization Name" },
|
|
@@ -1294,7 +1296,7 @@ var isEmpty_default = isEmpty;
|
|
|
1294
1296
|
* ```typescript
|
|
1295
1297
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1296
1298
|
* await updateOrganization({
|
|
1297
|
-
* baseUrl: "https://
|
|
1299
|
+
* baseUrl: "https://localhost:8090",
|
|
1298
1300
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1",
|
|
1299
1301
|
* operations: [
|
|
1300
1302
|
* { operation: "REPLACE", path: "/name", value: "Updated Organization Name" }
|
|
@@ -1379,7 +1381,7 @@ var updateOrganization_default = updateOrganization;
|
|
|
1379
1381
|
* ```typescript
|
|
1380
1382
|
* // Using default fetch
|
|
1381
1383
|
* await updateMeProfile({
|
|
1382
|
-
* url: "https://
|
|
1384
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
1383
1385
|
* payload: { "urn:scim:wso2:schema": { mobileNumbers: ["0777933830"] } }
|
|
1384
1386
|
* });
|
|
1385
1387
|
* ```
|
|
@@ -1388,7 +1390,7 @@ var updateOrganization_default = updateOrganization;
|
|
|
1388
1390
|
* ```typescript
|
|
1389
1391
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1390
1392
|
* await updateMeProfile({
|
|
1391
|
-
* url: "https://
|
|
1393
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
1392
1394
|
* payload: { "urn:scim:wso2:schema": { mobileNumbers: ["0777933830"] } },
|
|
1393
1395
|
* fetcher: async (url, config) => {
|
|
1394
1396
|
* const response = await httpClient({
|
|
@@ -1845,7 +1847,7 @@ var ThunderIDRuntimeError = class extends ThunderIDError {
|
|
|
1845
1847
|
* @returns boolean - true if sensible fallbacks can be used, false otherwise
|
|
1846
1848
|
*
|
|
1847
1849
|
* @example
|
|
1848
|
-
* isRecognizedBaseUrlPattern('https://
|
|
1850
|
+
* isRecognizedBaseUrlPattern('https://localhost:8090/t/dxlab'); // true
|
|
1849
1851
|
* isRecognizedBaseUrlPattern('https://custom.example.com/auth'); // false
|
|
1850
1852
|
*/
|
|
1851
1853
|
const isRecognizedBaseUrlPattern = (baseUrl) => {
|
|
@@ -1908,7 +1910,7 @@ var identifyPlatform_default = identifyPlatform;
|
|
|
1908
1910
|
* // Using default fetch
|
|
1909
1911
|
* try {
|
|
1910
1912
|
* const response = await getBrandingPreference({
|
|
1911
|
-
* baseUrl: "https://
|
|
1913
|
+
* baseUrl: "https://localhost:8090",
|
|
1912
1914
|
* locale: "en-US",
|
|
1913
1915
|
* name: "my-branding",
|
|
1914
1916
|
* type: "org"
|
|
@@ -1926,7 +1928,7 @@ var identifyPlatform_default = identifyPlatform;
|
|
|
1926
1928
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1927
1929
|
* try {
|
|
1928
1930
|
* const response = await getBrandingPreference({
|
|
1929
|
-
* baseUrl: "https://
|
|
1931
|
+
* baseUrl: "https://localhost:8090",
|
|
1930
1932
|
* locale: "en-US",
|
|
1931
1933
|
* name: "my-branding",
|
|
1932
1934
|
* type: "org",
|
|
@@ -2086,18 +2088,59 @@ let EmbeddedSignInFlowType$1 = /* @__PURE__ */ function(EmbeddedSignInFlowType$2
|
|
|
2086
2088
|
return EmbeddedSignInFlowType$2;
|
|
2087
2089
|
}({});
|
|
2088
2090
|
|
|
2091
|
+
//#endregion
|
|
2092
|
+
//#region src/utils/v2/injectRequestedPermissions.ts
|
|
2093
|
+
/**
|
|
2094
|
+
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
2095
|
+
*
|
|
2096
|
+
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
2097
|
+
* Version 2.0 (the "License"); you may not use this file except
|
|
2098
|
+
* in compliance with the License.
|
|
2099
|
+
* You may obtain a copy of the License at
|
|
2100
|
+
*
|
|
2101
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2102
|
+
*
|
|
2103
|
+
* Unless required by applicable law or agreed to in writing,
|
|
2104
|
+
* software distributed under the License is distributed on an
|
|
2105
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
2106
|
+
* KIND, either express or implied. See the License for the
|
|
2107
|
+
* specific language governing permissions and limitations
|
|
2108
|
+
* under the License.
|
|
2109
|
+
*/
|
|
2110
|
+
/**
|
|
2111
|
+
* Strips the top-level `scopes` field from a payload and injects it as
|
|
2112
|
+
* `inputs.requested_permissions` (space-separated string).
|
|
2113
|
+
*
|
|
2114
|
+
* The backend reads requested_permissions from UserInputs (the `inputs` map), not a top-level field.
|
|
2115
|
+
*/
|
|
2116
|
+
const injectRequestedPermissions = (payload) => {
|
|
2117
|
+
const { scopes,...rest } = payload;
|
|
2118
|
+
const normalizedScopes = Array.isArray(scopes) ? scopes.map((s) => String(s).trim()).filter(Boolean).join(" ") : typeof scopes === "string" ? scopes.trim() : "";
|
|
2119
|
+
if (!normalizedScopes) return rest;
|
|
2120
|
+
const existingInputs = rest["inputs"] != null && typeof rest["inputs"] === "object" && !Array.isArray(rest["inputs"]) ? rest["inputs"] : {};
|
|
2121
|
+
return {
|
|
2122
|
+
...rest,
|
|
2123
|
+
inputs: {
|
|
2124
|
+
...existingInputs,
|
|
2125
|
+
requested_permissions: normalizedScopes
|
|
2126
|
+
}
|
|
2127
|
+
};
|
|
2128
|
+
};
|
|
2129
|
+
var injectRequestedPermissions_default = injectRequestedPermissions;
|
|
2130
|
+
|
|
2089
2131
|
//#endregion
|
|
2090
2132
|
//#region src/api/v2/executeEmbeddedSignInFlowV2.ts
|
|
2091
2133
|
const executeEmbeddedSignInFlowV2 = async ({ url, baseUrl, payload, authId,...requestConfig }) => {
|
|
2092
2134
|
if (!payload) throw new ThunderIDAPIError("Authorization payload is required", "executeEmbeddedSignInFlow-ValidationError-002", "javascript", 400, "If an authorization payload is not provided, the request cannot be constructed correctly.");
|
|
2093
2135
|
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2094
2136
|
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2095
|
-
const
|
|
2137
|
+
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
2096
2138
|
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2097
|
-
const
|
|
2098
|
-
|
|
2139
|
+
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
2140
|
+
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
2141
|
+
...basePayload,
|
|
2099
2142
|
verbose: true
|
|
2100
|
-
} :
|
|
2143
|
+
} : basePayload;
|
|
2101
2144
|
const response = await fetch(endpoint, {
|
|
2102
2145
|
...requestConfig,
|
|
2103
2146
|
body: JSON.stringify(requestPayload),
|
|
@@ -2124,14 +2167,15 @@ const executeEmbeddedSignInFlowV2 = async ({ url, baseUrl, payload, authId,...re
|
|
|
2124
2167
|
},
|
|
2125
2168
|
method: "POST"
|
|
2126
2169
|
});
|
|
2127
|
-
if (!oauth2Response.ok) throw new ThunderIDAPIError(
|
|
2170
|
+
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignInFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
2128
2171
|
const oauth2Result = await oauth2Response.json();
|
|
2129
2172
|
return {
|
|
2130
2173
|
flowStatus: flowResponse.flowStatus,
|
|
2131
2174
|
redirectUrl: oauth2Result["redirect_uri"]
|
|
2132
2175
|
};
|
|
2133
2176
|
} catch (authError) {
|
|
2134
|
-
|
|
2177
|
+
if (authError instanceof ThunderIDAPIError) throw authError;
|
|
2178
|
+
throw new ThunderIDAPIError(authError instanceof Error ? authError.message : "Unknown error", "executeEmbeddedSignInFlow-OAuth2Error-001", "javascript", 500, "Failed to complete OAuth2 authorization after successful embedded sign-in flow.", "OAuth2 authorization failed");
|
|
2135
2179
|
}
|
|
2136
2180
|
return flowResponse;
|
|
2137
2181
|
};
|
|
@@ -2156,9 +2200,9 @@ var executeEmbeddedSignInFlowV2_default = executeEmbeddedSignInFlowV2;
|
|
|
2156
2200
|
* // Registration successful - handle completion
|
|
2157
2201
|
* break;
|
|
2158
2202
|
* case EmbeddedSignUpFlowStatus.Error:
|
|
2159
|
-
* // Registration failed - show
|
|
2203
|
+
* // Registration failed - show error details
|
|
2160
2204
|
* const errorResponse = response as EmbeddedSignUpFlowErrorResponse;
|
|
2161
|
-
* showError(errorResponse.
|
|
2205
|
+
* showError(errorResponse.error.description.defaultValue);
|
|
2162
2206
|
* break;
|
|
2163
2207
|
* }
|
|
2164
2208
|
* ```
|
|
@@ -2230,12 +2274,13 @@ const executeEmbeddedSignUpFlowV2 = async ({ url, baseUrl, payload, authId,...re
|
|
|
2230
2274
|
if (!payload) throw new ThunderIDAPIError("Registration payload is required", "executeEmbeddedSignUpFlow-ValidationError-002", "javascript", 400, "If a registration payload is not provided, the request cannot be constructed correctly.");
|
|
2231
2275
|
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2232
2276
|
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2233
|
-
const
|
|
2277
|
+
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
2234
2278
|
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2235
|
-
const
|
|
2236
|
-
|
|
2279
|
+
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
2280
|
+
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
2281
|
+
...basePayload,
|
|
2237
2282
|
verbose: true
|
|
2238
|
-
} :
|
|
2283
|
+
} : basePayload;
|
|
2239
2284
|
const response = await fetch(endpoint, {
|
|
2240
2285
|
...requestConfig,
|
|
2241
2286
|
body: JSON.stringify(requestPayload),
|
|
@@ -2262,14 +2307,15 @@ const executeEmbeddedSignUpFlowV2 = async ({ url, baseUrl, payload, authId,...re
|
|
|
2262
2307
|
},
|
|
2263
2308
|
method: "POST"
|
|
2264
2309
|
});
|
|
2265
|
-
if (!oauth2Response.ok) throw new ThunderIDAPIError(
|
|
2310
|
+
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignUpFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
2266
2311
|
const oauth2Result = await oauth2Response.json();
|
|
2267
2312
|
return {
|
|
2268
2313
|
flowStatus: flowResponse.flowStatus,
|
|
2269
2314
|
redirectUrl: oauth2Result["redirect_uri"]
|
|
2270
2315
|
};
|
|
2271
2316
|
} catch (authError) {
|
|
2272
|
-
|
|
2317
|
+
if (authError instanceof ThunderIDAPIError) throw authError;
|
|
2318
|
+
throw new ThunderIDAPIError(authError instanceof Error ? authError.message : "Unknown error", "executeEmbeddedSignUpFlow-OAuth2Error-001", "javascript", 500, "Failed to complete OAuth2 authorization after successful embedded sign-up flow.", "OAuth2 authorization failed");
|
|
2273
2319
|
}
|
|
2274
2320
|
return flowResponse;
|
|
2275
2321
|
};
|
|
@@ -2293,7 +2339,7 @@ var executeEmbeddedSignUpFlowV2_default = executeEmbeddedSignUpFlowV2;
|
|
|
2293
2339
|
* ```typescript
|
|
2294
2340
|
* // Initiate recovery flow
|
|
2295
2341
|
* const response = await executeEmbeddedRecoveryFlowV2({
|
|
2296
|
-
* baseUrl: 'https://
|
|
2342
|
+
* baseUrl: 'https://localhost:8090',
|
|
2297
2343
|
* payload: {
|
|
2298
2344
|
* flowType: 'RECOVERY',
|
|
2299
2345
|
* applicationId: 'my-app-id',
|
|
@@ -2302,7 +2348,7 @@ var executeEmbeddedSignUpFlowV2_default = executeEmbeddedSignUpFlowV2;
|
|
|
2302
2348
|
*
|
|
2303
2349
|
* // Continue recovery flow with user input
|
|
2304
2350
|
* const nextResponse = await executeEmbeddedRecoveryFlowV2({
|
|
2305
|
-
* baseUrl: 'https://
|
|
2351
|
+
* baseUrl: 'https://localhost:8090',
|
|
2306
2352
|
* payload: {
|
|
2307
2353
|
* executionId: response.executionId,
|
|
2308
2354
|
* action: 'submit',
|
|
@@ -2332,7 +2378,7 @@ const executeEmbeddedRecoveryFlowV2 = async ({ url, baseUrl, payload,...requestC
|
|
|
2332
2378
|
},
|
|
2333
2379
|
method: requestConfig.method || "POST"
|
|
2334
2380
|
});
|
|
2335
|
-
if (!response.ok) throw new ThunderIDAPIError(
|
|
2381
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedRecoveryFlow-ResponseError-001", "javascript", response.status, response.statusText, "Recovery request failed");
|
|
2336
2382
|
return await response.json();
|
|
2337
2383
|
};
|
|
2338
2384
|
var executeEmbeddedRecoveryFlowV2_default = executeEmbeddedRecoveryFlowV2;
|
|
@@ -2747,6 +2793,8 @@ let EmbeddedFlowComponentType$1 = /* @__PURE__ */ function(EmbeddedFlowComponent
|
|
|
2747
2793
|
EmbeddedFlowComponentType$2["TextInput"] = "TEXT_INPUT";
|
|
2748
2794
|
/** Timer component for displaying a countdown */
|
|
2749
2795
|
EmbeddedFlowComponentType$2["Timer"] = "TIMER";
|
|
2796
|
+
/** QR code display component for wallet-based flows (e.g. OpenID4VP) */
|
|
2797
|
+
EmbeddedFlowComponentType$2["QrCode"] = "QR_CODE";
|
|
2750
2798
|
return EmbeddedFlowComponentType$2;
|
|
2751
2799
|
}({});
|
|
2752
2800
|
/**
|
|
@@ -3231,6 +3279,10 @@ let Stores = /* @__PURE__ */ function(Stores$1) {
|
|
|
3231
3279
|
* Store for temporary data that needs to persist only for a short duration.
|
|
3232
3280
|
*/
|
|
3233
3281
|
Stores$1["TemporaryData"] = "temporary_data";
|
|
3282
|
+
/**
|
|
3283
|
+
* Store for data that leverages local storage if available, falling back to the configured storage.
|
|
3284
|
+
*/
|
|
3285
|
+
Stores$1["HybridData"] = "hybrid_data";
|
|
3234
3286
|
return Stores$1;
|
|
3235
3287
|
}({});
|
|
3236
3288
|
|
|
@@ -3292,7 +3344,18 @@ var StorageManager = class StorageManager {
|
|
|
3292
3344
|
this.setDataInBulk(this.resolveKey(Stores.OIDCProviderMetaData), oidcProviderMetaData);
|
|
3293
3345
|
}
|
|
3294
3346
|
async setTemporaryData(temporaryData, userId) {
|
|
3295
|
-
this.setDataInBulk(this.resolveKey(Stores.TemporaryData, userId), temporaryData);
|
|
3347
|
+
await this.setDataInBulk(this.resolveKey(Stores.TemporaryData, userId), temporaryData);
|
|
3348
|
+
}
|
|
3349
|
+
async setHybridData(hybridData, userId) {
|
|
3350
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3351
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3352
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3353
|
+
const dataToBeSaved = {
|
|
3354
|
+
...existingDataJSON ? JSON.parse(existingDataJSON) : {},
|
|
3355
|
+
...hybridData
|
|
3356
|
+
};
|
|
3357
|
+
localStorage.setItem(resolvedKey, JSON.stringify(dataToBeSaved));
|
|
3358
|
+
} else await this.setDataInBulk(resolvedKey, hybridData);
|
|
3296
3359
|
}
|
|
3297
3360
|
async setSessionData(sessionData, userId) {
|
|
3298
3361
|
this.setDataInBulk(this.resolveKey(Stores.SessionData, userId), sessionData);
|
|
@@ -3307,7 +3370,35 @@ var StorageManager = class StorageManager {
|
|
|
3307
3370
|
return JSON.parse(await this.store.getData(this.resolveKey(Stores.OIDCProviderMetaData)) ?? null);
|
|
3308
3371
|
}
|
|
3309
3372
|
async getTemporaryData(userId) {
|
|
3310
|
-
|
|
3373
|
+
const data = await this.store.getData(this.resolveKey(Stores.TemporaryData, userId));
|
|
3374
|
+
if (data) try {
|
|
3375
|
+
return JSON.parse(data);
|
|
3376
|
+
} catch (error$1) {
|
|
3377
|
+
logger_default.error(`StorageManager: Failed to parse temporary data for key ${this.resolveKey(Stores.TemporaryData, userId)}`, error$1);
|
|
3378
|
+
return {};
|
|
3379
|
+
}
|
|
3380
|
+
return {};
|
|
3381
|
+
}
|
|
3382
|
+
async getHybridData(userId) {
|
|
3383
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3384
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3385
|
+
const storeDataJSON$1 = localStorage.getItem(resolvedKey);
|
|
3386
|
+
if (storeDataJSON$1) try {
|
|
3387
|
+
return JSON.parse(storeDataJSON$1);
|
|
3388
|
+
} catch (error$1) {
|
|
3389
|
+
logger_default.error(`StorageManager: Failed to parse hybrid data from local storage for key ${resolvedKey}`, error$1);
|
|
3390
|
+
return {};
|
|
3391
|
+
}
|
|
3392
|
+
return {};
|
|
3393
|
+
}
|
|
3394
|
+
const storeDataJSON = await this.store.getData(resolvedKey) ?? null;
|
|
3395
|
+
if (storeDataJSON) try {
|
|
3396
|
+
return JSON.parse(storeDataJSON);
|
|
3397
|
+
} catch (error$1) {
|
|
3398
|
+
logger_default.error(`StorageManager: Failed to parse hybrid data from store for key ${resolvedKey}`, error$1);
|
|
3399
|
+
return {};
|
|
3400
|
+
}
|
|
3401
|
+
return {};
|
|
3311
3402
|
}
|
|
3312
3403
|
async getPersistedData(userId) {
|
|
3313
3404
|
return JSON.parse(await this.store.getData(this.resolveKey(Stores.PersistedData, userId)) ?? null);
|
|
@@ -3339,6 +3430,11 @@ var StorageManager = class StorageManager {
|
|
|
3339
3430
|
async removeTemporaryData(userId) {
|
|
3340
3431
|
await this.store.removeData(this.resolveKey(Stores.TemporaryData, userId));
|
|
3341
3432
|
}
|
|
3433
|
+
async removeHybridData(userId) {
|
|
3434
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3435
|
+
if (StorageManager.isLocalStorageAvailable()) localStorage.removeItem(resolvedKey);
|
|
3436
|
+
else await this.store.removeData(resolvedKey);
|
|
3437
|
+
}
|
|
3342
3438
|
async removeSessionData(userId) {
|
|
3343
3439
|
await this.store.removeData(this.resolveKey(Stores.SessionData, userId));
|
|
3344
3440
|
}
|
|
@@ -3354,6 +3450,15 @@ var StorageManager = class StorageManager {
|
|
|
3354
3450
|
const data = await this.store.getData(this.resolveKey(Stores.TemporaryData, userId));
|
|
3355
3451
|
return data && JSON.parse(data)[key];
|
|
3356
3452
|
}
|
|
3453
|
+
async getHybridDataParameter(key, userId) {
|
|
3454
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3455
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3456
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3457
|
+
return (existingDataJSON ? JSON.parse(existingDataJSON) : {})[key];
|
|
3458
|
+
}
|
|
3459
|
+
const data = await this.store.getData(resolvedKey);
|
|
3460
|
+
return data && JSON.parse(data)[key];
|
|
3461
|
+
}
|
|
3357
3462
|
async getSessionDataParameter(key, userId) {
|
|
3358
3463
|
const data = await this.store.getData(this.resolveKey(Stores.SessionData, userId));
|
|
3359
3464
|
return data && JSON.parse(data)[key];
|
|
@@ -3367,6 +3472,17 @@ var StorageManager = class StorageManager {
|
|
|
3367
3472
|
async setTemporaryDataParameter(key, value, userId) {
|
|
3368
3473
|
await this.setValue(this.resolveKey(Stores.TemporaryData, userId), key, value);
|
|
3369
3474
|
}
|
|
3475
|
+
async setHybridDataParameter(key, value, userId) {
|
|
3476
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3477
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3478
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3479
|
+
const dataToBeSaved = {
|
|
3480
|
+
...existingDataJSON ? JSON.parse(existingDataJSON) : {},
|
|
3481
|
+
[key]: value
|
|
3482
|
+
};
|
|
3483
|
+
localStorage.setItem(resolvedKey, JSON.stringify(dataToBeSaved));
|
|
3484
|
+
} else await this.setValue(resolvedKey, key, value);
|
|
3485
|
+
}
|
|
3370
3486
|
async setSessionDataParameter(key, value, userId) {
|
|
3371
3487
|
await this.setValue(this.resolveKey(Stores.SessionData, userId), key, value);
|
|
3372
3488
|
}
|
|
@@ -3379,56 +3495,21 @@ var StorageManager = class StorageManager {
|
|
|
3379
3495
|
async removeTemporaryDataParameter(key, userId) {
|
|
3380
3496
|
await this.removeValue(this.resolveKey(Stores.TemporaryData, userId), key);
|
|
3381
3497
|
}
|
|
3498
|
+
async removeHybridDataParameter(key, userId) {
|
|
3499
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3500
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3501
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3502
|
+
const existingData = existingDataJSON ? JSON.parse(existingDataJSON) : {};
|
|
3503
|
+
delete existingData[key];
|
|
3504
|
+
localStorage.setItem(resolvedKey, JSON.stringify(existingData));
|
|
3505
|
+
} else await this.removeValue(resolvedKey, key);
|
|
3506
|
+
}
|
|
3382
3507
|
async removeSessionDataParameter(key, userId) {
|
|
3383
3508
|
await this.removeValue(this.resolveKey(Stores.SessionData, userId), key);
|
|
3384
3509
|
}
|
|
3385
3510
|
};
|
|
3386
3511
|
var StorageManager_default = StorageManager;
|
|
3387
3512
|
|
|
3388
|
-
//#endregion
|
|
3389
|
-
//#region src/constants/TokenExchangeConstants.ts
|
|
3390
|
-
/**
|
|
3391
|
-
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
|
|
3392
|
-
*
|
|
3393
|
-
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
3394
|
-
* Version 2.0 (the "License"); you may not use this file except
|
|
3395
|
-
* in compliance with the License.
|
|
3396
|
-
* You may obtain a copy of the License at
|
|
3397
|
-
*
|
|
3398
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
3399
|
-
*
|
|
3400
|
-
* Unless required by applicable law or agreed to in writing,
|
|
3401
|
-
* software distributed under the License is distributed on an
|
|
3402
|
-
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
3403
|
-
* KIND, either express or implied. See the License for the
|
|
3404
|
-
* specific language governing permissions and limitations
|
|
3405
|
-
* under the License.
|
|
3406
|
-
*/
|
|
3407
|
-
/**
|
|
3408
|
-
* Constants for OAuth 2.0 Token Exchange operations.
|
|
3409
|
-
* This object contains placeholders used in token exchange requests
|
|
3410
|
-
* and responses for dynamic value substitution.
|
|
3411
|
-
*
|
|
3412
|
-
* @remarks
|
|
3413
|
-
* These placeholders are used in token exchange templates and are replaced
|
|
3414
|
-
* with actual values during request processing. They help in creating
|
|
3415
|
-
* flexible and reusable token exchange configurations.
|
|
3416
|
-
*
|
|
3417
|
-
* @example
|
|
3418
|
-
* ```typescript
|
|
3419
|
-
* // Using placeholders in a token exchange template
|
|
3420
|
-
* const template = `grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=${TokenExchangeConstants.Placeholders.TOKEN}`;
|
|
3421
|
-
* ```
|
|
3422
|
-
*/
|
|
3423
|
-
const TokenExchangeConstants = { Placeholders: {
|
|
3424
|
-
ACCESS_TOKEN: "{{accessToken}}",
|
|
3425
|
-
CLIENT_ID: "{{clientId}}",
|
|
3426
|
-
CLIENT_SECRET: "{{clientSecret}}",
|
|
3427
|
-
SCOPES: "{{scopes}}",
|
|
3428
|
-
USERNAME: "{{username}}"
|
|
3429
|
-
} };
|
|
3430
|
-
var TokenExchangeConstants_default = TokenExchangeConstants;
|
|
3431
|
-
|
|
3432
3513
|
//#endregion
|
|
3433
3514
|
//#region src/utils/extractUserClaimsFromIdToken.ts
|
|
3434
3515
|
/**
|
|
@@ -3524,6 +3605,50 @@ const processOpenIDScopes = (scopes) => {
|
|
|
3524
3605
|
};
|
|
3525
3606
|
var processOpenIDScopes_default = processOpenIDScopes;
|
|
3526
3607
|
|
|
3608
|
+
//#endregion
|
|
3609
|
+
//#region src/constants/TokenExchangeConstants.ts
|
|
3610
|
+
/**
|
|
3611
|
+
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
|
|
3612
|
+
*
|
|
3613
|
+
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
3614
|
+
* Version 2.0 (the "License"); you may not use this file except
|
|
3615
|
+
* in compliance with the License.
|
|
3616
|
+
* You may obtain a copy of the License at
|
|
3617
|
+
*
|
|
3618
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
3619
|
+
*
|
|
3620
|
+
* Unless required by applicable law or agreed to in writing,
|
|
3621
|
+
* software distributed under the License is distributed on an
|
|
3622
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
3623
|
+
* KIND, either express or implied. See the License for the
|
|
3624
|
+
* specific language governing permissions and limitations
|
|
3625
|
+
* under the License.
|
|
3626
|
+
*/
|
|
3627
|
+
/**
|
|
3628
|
+
* Constants for OAuth 2.0 Token Exchange operations.
|
|
3629
|
+
* This object contains placeholders used in token exchange requests
|
|
3630
|
+
* and responses for dynamic value substitution.
|
|
3631
|
+
*
|
|
3632
|
+
* @remarks
|
|
3633
|
+
* These placeholders are used in token exchange templates and are replaced
|
|
3634
|
+
* with actual values during request processing. They help in creating
|
|
3635
|
+
* flexible and reusable token exchange configurations.
|
|
3636
|
+
*
|
|
3637
|
+
* @example
|
|
3638
|
+
* ```typescript
|
|
3639
|
+
* // Using placeholders in a token exchange template
|
|
3640
|
+
* const template = `grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=${TokenExchangeConstants.Placeholders.TOKEN}`;
|
|
3641
|
+
* ```
|
|
3642
|
+
*/
|
|
3643
|
+
const TokenExchangeConstants = { Placeholders: {
|
|
3644
|
+
ACCESS_TOKEN: "{{accessToken}}",
|
|
3645
|
+
CLIENT_ID: "{{clientId}}",
|
|
3646
|
+
CLIENT_SECRET: "{{clientSecret}}",
|
|
3647
|
+
SCOPES: "{{scopes}}",
|
|
3648
|
+
USERNAME: "{{username}}"
|
|
3649
|
+
} };
|
|
3650
|
+
var TokenExchangeConstants_default = TokenExchangeConstants;
|
|
3651
|
+
|
|
3527
3652
|
//#endregion
|
|
3528
3653
|
//#region src/utils/AuthenticationHelper.ts
|
|
3529
3654
|
/**
|
|
@@ -3649,7 +3774,7 @@ var AuthenticationHelper = class {
|
|
|
3649
3774
|
const { issuer } = await this.oidcProviderMetaData();
|
|
3650
3775
|
const { keys } = await response.json();
|
|
3651
3776
|
const jwk = await this.cryptoHelper.getJWKForTheIdToken(idToken.split(".")[0], keys);
|
|
3652
|
-
return this.cryptoHelper.isValidIdToken(idToken, jwk, (await this.config()).clientId, issuer ?? "", this.cryptoHelper.decodeJwtToken(idToken).sub, (await this.config()).tokenValidation?.idToken?.clockTolerance, (await this.config()).tokenValidation?.idToken?.validateIssuer ?? true);
|
|
3777
|
+
return this.cryptoHelper.isValidIdToken(idToken, jwk, (await this.config()).clientId ?? "", issuer ?? "", this.cryptoHelper.decodeJwtToken(idToken).sub, (await this.config()).tokenValidation?.idToken?.clockTolerance, (await this.config()).tokenValidation?.idToken?.validateIssuer ?? true);
|
|
3653
3778
|
}
|
|
3654
3779
|
/**
|
|
3655
3780
|
* Extracts user information from a decoded ID token payload.
|
|
@@ -3691,7 +3816,7 @@ var AuthenticationHelper = class {
|
|
|
3691
3816
|
} else sessionData = await this.storageManager.getSessionData(userId);
|
|
3692
3817
|
const scope = processOpenIDScopes_default(configData.scopes);
|
|
3693
3818
|
if (typeof text !== "string") return text;
|
|
3694
|
-
return text.replace(TokenExchangeConstants_default.Placeholders.ACCESS_TOKEN, sessionData.access_token).replace(TokenExchangeConstants_default.Placeholders.USERNAME, this.getAuthenticatedUserInfo(sessionData.id_token).username).replace(TokenExchangeConstants_default.Placeholders.SCOPES, scope).replace(TokenExchangeConstants_default.Placeholders.CLIENT_ID, configData.clientId).replace(TokenExchangeConstants_default.Placeholders.CLIENT_SECRET, configData.clientSecret ?? "");
|
|
3819
|
+
return text.replace(TokenExchangeConstants_default.Placeholders.ACCESS_TOKEN, sessionData.access_token).replace(TokenExchangeConstants_default.Placeholders.USERNAME, this.getAuthenticatedUserInfo(sessionData.id_token).username ?? "").replace(TokenExchangeConstants_default.Placeholders.SCOPES, scope).replace(TokenExchangeConstants_default.Placeholders.CLIENT_ID, configData.clientId ?? "").replace(TokenExchangeConstants_default.Placeholders.CLIENT_SECRET, configData.clientSecret ?? "");
|
|
3695
3820
|
}
|
|
3696
3821
|
/**
|
|
3697
3822
|
* Clears all temporary and session data for the given user.
|
|
@@ -3940,7 +4065,7 @@ const getAuthorizeRequestUrlParams = (options, pkceOptions, customParams) => {
|
|
|
3940
4065
|
const authorizeRequestParams = /* @__PURE__ */ new Map();
|
|
3941
4066
|
authorizeRequestParams.set("response_type", "code");
|
|
3942
4067
|
authorizeRequestParams.set("client_id", clientId);
|
|
3943
|
-
authorizeRequestParams.set("scope", scopes);
|
|
4068
|
+
authorizeRequestParams.set("scope", scopes ?? "");
|
|
3944
4069
|
authorizeRequestParams.set("redirect_uri", redirectUri);
|
|
3945
4070
|
if (responseMode) authorizeRequestParams.set("response_mode", responseMode);
|
|
3946
4071
|
const pkceKey = pkceOptions?.key;
|
|
@@ -4007,13 +4132,11 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4007
4132
|
if (persistedData?.["applicationId"]) resolvedApplicationId = persistedData["applicationId"];
|
|
4008
4133
|
}
|
|
4009
4134
|
const resolvedEndpoints = endpoints ? { ...endpoints } : {};
|
|
4010
|
-
await this.storageManager.setConfigData({
|
|
4011
|
-
...DEFAULT_CONFIG,
|
|
4012
|
-
...fullConfig,
|
|
4135
|
+
await this.storageManager.setConfigData(deepMerge_default({}, DEFAULT_CONFIG, fullConfig, {
|
|
4013
4136
|
applicationId: resolvedApplicationId,
|
|
4014
4137
|
endpoints: resolvedEndpoints,
|
|
4015
4138
|
scope: processOpenIDScopes_default(fullConfig.scopes)
|
|
4016
|
-
});
|
|
4139
|
+
}));
|
|
4017
4140
|
this.baseURL = fullConfig.baseUrl ?? "";
|
|
4018
4141
|
return true;
|
|
4019
4142
|
}
|
|
@@ -4161,19 +4284,19 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4161
4284
|
if (configData.enablePKCE) {
|
|
4162
4285
|
codeVerifier = this.cryptoHelper?.getCodeVerifier();
|
|
4163
4286
|
codeChallenge = await this.cryptoHelper?.getCodeChallenge(codeVerifier);
|
|
4164
|
-
await this.storageManager.
|
|
4287
|
+
await this.storageManager.setHybridDataParameter(pkceKey, codeVerifier, userId);
|
|
4165
4288
|
}
|
|
4166
|
-
if (authRequestConfig["client_secret"]) authRequestConfig["client_secret"] = configData.clientSecret;
|
|
4167
|
-
const authorizeRequestParams = getAuthorizeRequestUrlParams_default({
|
|
4168
|
-
clientId: configData.clientId,
|
|
4289
|
+
if (authRequestConfig["client_secret"]) authRequestConfig["client_secret"] = configData.clientSecret ?? "";
|
|
4290
|
+
const authorizeRequestParams = getAuthorizeRequestUrlParams_default(Object.fromEntries(Object.entries({
|
|
4291
|
+
clientId: configData.clientId ?? "",
|
|
4169
4292
|
codeChallenge,
|
|
4170
4293
|
codeChallengeMethod: PKCEConstants_default.DEFAULT_CODE_CHALLENGE_METHOD,
|
|
4171
4294
|
instanceId: this.getInstanceId().toString(),
|
|
4172
4295
|
prompt: configData.prompt,
|
|
4173
|
-
redirectUri: configData.afterSignInUrl,
|
|
4296
|
+
redirectUri: configData.afterSignInUrl ?? "",
|
|
4174
4297
|
responseMode: configData.responseMode,
|
|
4175
4298
|
scopes: processOpenIDScopes_default(configData.scopes)
|
|
4176
|
-
}, { key: pkceKey }, authRequestConfig);
|
|
4299
|
+
}).filter(([, v]) => v !== void 0)), { key: pkceKey }, authRequestConfig);
|
|
4177
4300
|
Array.from(authorizeRequestParams.entries()).forEach(([paramKey, paramValue]) => {
|
|
4178
4301
|
authorizeRequest.searchParams.append(paramKey, paramValue);
|
|
4179
4302
|
});
|
|
@@ -4189,19 +4312,19 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4189
4312
|
if (!tokenEndpoint || tokenEndpoint.trim().length === 0) throw new ThunderIDAuthException("JS-AUTH_CORE-RAT1-NF01", "Token endpoint not found.", "No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint or the token endpoint passed to the SDK is empty.");
|
|
4190
4313
|
if (sessionState) await this.storageManager.setSessionDataParameter(OIDCRequestConstants_default.Params.SESSION_STATE, sessionState, userId);
|
|
4191
4314
|
const body = new URLSearchParams();
|
|
4192
|
-
body.set("client_id", configData.clientId);
|
|
4315
|
+
body.set("client_id", configData.clientId ?? "");
|
|
4193
4316
|
const hasSecret = Boolean(configData.clientSecret && configData.clientSecret.trim().length > 0);
|
|
4194
4317
|
const tokenEndpointAuthMethod = configData.tokenRequest?.authMethod ?? "client_secret_basic";
|
|
4195
4318
|
if (hasSecret && tokenEndpointAuthMethod === "client_secret_post") body.set("client_secret", configData.clientSecret);
|
|
4196
4319
|
body.set("code", authorizationCode);
|
|
4197
4320
|
body.set("grant_type", "authorization_code");
|
|
4198
|
-
body.set("redirect_uri", configData.afterSignInUrl);
|
|
4321
|
+
body.set("redirect_uri", configData.afterSignInUrl ?? "");
|
|
4199
4322
|
if (tokenRequestConfig?.params) Object.entries(tokenRequestConfig.params).forEach(([key, value]) => {
|
|
4200
4323
|
body.append(key, value);
|
|
4201
4324
|
});
|
|
4202
4325
|
if (configData.enablePKCE) {
|
|
4203
|
-
body.set("code_verifier", `${await this.storageManager.
|
|
4204
|
-
await this.storageManager.
|
|
4326
|
+
body.set("code_verifier", `${await this.storageManager.getHybridDataParameter(extractPkceStorageKeyFromState_default(state), userId)}`);
|
|
4327
|
+
await this.storageManager.removeHybridDataParameter(extractPkceStorageKeyFromState_default(state), userId);
|
|
4205
4328
|
}
|
|
4206
4329
|
const tokenRequestHeaders = {
|
|
4207
4330
|
Accept: "application/json",
|
|
@@ -4234,7 +4357,7 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4234
4357
|
const idToken = (await this.storageManager.getSessionData(userId))?.id_token;
|
|
4235
4358
|
if (!idToken || idToken.trim().length === 0) throw new ThunderIDAuthException("JS-AUTH_CORE-GSOU-NF02", "ID token not found.", "No ID token could be found. Either the session information is lost or you have not signed in.");
|
|
4236
4359
|
queryParams.set("id_token_hint", idToken);
|
|
4237
|
-
} else queryParams.set("client_id", configData.clientId);
|
|
4360
|
+
} else queryParams.set("client_id", configData.clientId ?? "");
|
|
4238
4361
|
queryParams.set("state", OIDCRequestConstants_default.Params.SIGN_OUT_SUCCESS);
|
|
4239
4362
|
return `${logoutEndpoint}?${queryParams.toString()}`;
|
|
4240
4363
|
}
|
|
@@ -4329,10 +4452,10 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4329
4452
|
return response;
|
|
4330
4453
|
}
|
|
4331
4454
|
async getPKCECode(state, userId) {
|
|
4332
|
-
return await this.storageManager.
|
|
4455
|
+
return await this.storageManager.getHybridDataParameter(extractPkceStorageKeyFromState_default(state), userId);
|
|
4333
4456
|
}
|
|
4334
4457
|
async setPKCECode(pkce, state, userId) {
|
|
4335
|
-
return this.storageManager.
|
|
4458
|
+
return this.storageManager.setHybridDataParameter(extractPkceStorageKeyFromState_default(state), pkce, userId);
|
|
4336
4459
|
}
|
|
4337
4460
|
getInstanceId() {
|
|
4338
4461
|
return this.instanceIdValue;
|
|
@@ -4663,12 +4786,15 @@ const toCssVariables = (theme) => {
|
|
|
4663
4786
|
if (theme.typography?.lineHeights?.tight !== void 0) cssVars[`--${prefix}-typography-lineHeight-tight`] = theme.typography.lineHeights.tight.toString();
|
|
4664
4787
|
if (theme.typography?.lineHeights?.normal !== void 0) cssVars[`--${prefix}-typography-lineHeight-normal`] = theme.typography.lineHeights.normal.toString();
|
|
4665
4788
|
if (theme.typography?.lineHeights?.relaxed !== void 0) cssVars[`--${prefix}-typography-lineHeight-relaxed`] = theme.typography.lineHeights.relaxed.toString();
|
|
4666
|
-
if (theme.images)
|
|
4667
|
-
const
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4789
|
+
if (theme.images) {
|
|
4790
|
+
const themeImages = theme.images;
|
|
4791
|
+
Object.keys(themeImages).forEach((imageKey) => {
|
|
4792
|
+
const imageConfig = themeImages[imageKey];
|
|
4793
|
+
if (imageConfig?.url) cssVars[`--${prefix}-image-${imageKey}-url`] = imageConfig.url;
|
|
4794
|
+
if (imageConfig?.title) cssVars[`--${prefix}-image-${imageKey}-title`] = imageConfig.title;
|
|
4795
|
+
if (imageConfig?.alt) cssVars[`--${prefix}-image-${imageKey}-alt`] = imageConfig.alt;
|
|
4796
|
+
});
|
|
4797
|
+
}
|
|
4672
4798
|
if (theme.components?.Button?.styleOverrides?.root?.borderRadius) cssVars[`--${prefix}-component-button-root-borderRadius`] = theme.components.Button.styleOverrides.root.borderRadius;
|
|
4673
4799
|
if (theme.components?.Field?.styleOverrides?.root?.borderRadius) cssVars[`--${prefix}-component-field-root-borderRadius`] = theme.components.Field.styleOverrides.root.borderRadius;
|
|
4674
4800
|
return cssVars;
|
|
@@ -4765,9 +4891,11 @@ const toThemeVars = (theme) => {
|
|
|
4765
4891
|
};
|
|
4766
4892
|
if (theme.images) {
|
|
4767
4893
|
themeVars.images = {};
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4894
|
+
const themeImages = theme.images;
|
|
4895
|
+
const imageVars = themeVars.images;
|
|
4896
|
+
Object.keys(themeImages).forEach((imageKey) => {
|
|
4897
|
+
const imageConfig = themeImages[imageKey];
|
|
4898
|
+
imageVars[imageKey] = {
|
|
4771
4899
|
alt: imageConfig?.alt ? `var(--${prefix}-image-${imageKey}-alt)` : void 0,
|
|
4772
4900
|
title: imageConfig?.title ? `var(--${prefix}-image-${imageKey}-title)` : void 0,
|
|
4773
4901
|
url: imageConfig?.url ? `var(--${prefix}-image-${imageKey}-url)` : void 0
|
|
@@ -5061,13 +5189,9 @@ var formatDate_default = formatDate;
|
|
|
5061
5189
|
//#endregion
|
|
5062
5190
|
//#region src/utils/deriveOrganizationHandleFromBaseUrl.ts
|
|
5063
5191
|
/**
|
|
5064
|
-
* Extracts the organization handle from
|
|
5192
|
+
* Extracts the organization handle from a ThunderID base URL.
|
|
5065
5193
|
*
|
|
5066
|
-
*
|
|
5067
|
-
* - https://dev.asgardeo.io/t/{orgHandle}
|
|
5068
|
-
* - https://stage.asgardeo.io/t/{orgHandle}
|
|
5069
|
-
* - https://prod.asgardeo.io/t/{orgHandle}
|
|
5070
|
-
* - https://{subdomain}.asgardeo.io/t/{orgHandle}
|
|
5194
|
+
* Parses URLs following the `/t/{orgHandle}` pattern.
|
|
5071
5195
|
*
|
|
5072
5196
|
* @param baseUrl - The base URL of the ThunderID identity server
|
|
5073
5197
|
* @returns The extracted organization handle
|
|
@@ -5076,13 +5200,9 @@ var formatDate_default = formatDate;
|
|
|
5076
5200
|
*
|
|
5077
5201
|
* @example
|
|
5078
5202
|
* ```typescript
|
|
5079
|
-
*
|
|
5080
|
-
* const handle1 = deriveOrganizationHandleFromBaseUrl('https://dev.asgardeo.io/t/dxlab');
|
|
5203
|
+
* const handle = deriveOrganizationHandleFromBaseUrl('https://localhost:8090/t/dxlab');
|
|
5081
5204
|
* // Returns: 'dxlab'
|
|
5082
5205
|
*
|
|
5083
|
-
* const handle2 = deriveOrganizationHandleFromBaseUrl('https://stage.asgardeo.io/t/myorg');
|
|
5084
|
-
* // Returns: 'myorg'
|
|
5085
|
-
*
|
|
5086
5206
|
* // Custom domain - returns empty string with a warning
|
|
5087
5207
|
* const handle2 = deriveOrganizationHandleFromBaseUrl('https://custom.example.com/auth');
|
|
5088
5208
|
* // Returns: '' and logs a warning
|
|
@@ -5907,7 +6027,7 @@ var withVendorCSSClassPrefix_default = withVendorCSSClassPrefix;
|
|
|
5907
6027
|
//#endregion
|
|
5908
6028
|
//#region src/utils/transformBrandingPreferenceToTheme.ts
|
|
5909
6029
|
const extractColorValue = (colorVariant, preferDark = false) => {
|
|
5910
|
-
if (preferDark && colorVariant?.dark
|
|
6030
|
+
if (preferDark && colorVariant?.dark?.trim()) return colorVariant.dark;
|
|
5911
6031
|
return colorVariant?.main;
|
|
5912
6032
|
};
|
|
5913
6033
|
/**
|
|
@@ -5940,47 +6060,47 @@ const transformThemeVariant = (themeVariant, isDark = false) => {
|
|
|
5940
6060
|
background: {
|
|
5941
6061
|
body: {
|
|
5942
6062
|
dark: (colors?.background?.body)?.dark || (colors?.background?.body)?.main,
|
|
5943
|
-
main: extractColorValue(colors?.background?.body, isDark)
|
|
6063
|
+
main: extractColorValue(colors?.background?.body, isDark) ?? ""
|
|
5944
6064
|
},
|
|
5945
6065
|
dark: (colors?.background?.surface)?.dark || (colors?.background?.surface)?.main,
|
|
5946
|
-
disabled: extractColorValue(colors?.background?.surface, isDark),
|
|
5947
|
-
surface: extractColorValue(colors?.background?.surface, isDark)
|
|
6066
|
+
disabled: extractColorValue(colors?.background?.surface, isDark) ?? "",
|
|
6067
|
+
surface: extractColorValue(colors?.background?.surface, isDark) ?? ""
|
|
5948
6068
|
},
|
|
5949
|
-
border: colors?.outlined?.default,
|
|
6069
|
+
border: colors?.outlined?.default ?? "",
|
|
5950
6070
|
error: {
|
|
5951
|
-
contrastText: extractContrastText(colors?.alerts?.error),
|
|
6071
|
+
contrastText: extractContrastText(colors?.alerts?.error) ?? "",
|
|
5952
6072
|
dark: (colors?.alerts?.error)?.dark || (colors?.alerts?.error)?.main,
|
|
5953
|
-
main: extractColorValue(colors?.alerts?.error, isDark)
|
|
6073
|
+
main: extractColorValue(colors?.alerts?.error, isDark) ?? ""
|
|
5954
6074
|
},
|
|
5955
6075
|
info: {
|
|
5956
|
-
contrastText: extractContrastText(colors?.alerts?.info),
|
|
6076
|
+
contrastText: extractContrastText(colors?.alerts?.info) ?? "",
|
|
5957
6077
|
dark: (colors?.alerts?.info)?.dark || (colors?.alerts?.info)?.main,
|
|
5958
|
-
main: extractColorValue(colors?.alerts?.info, isDark)
|
|
6078
|
+
main: extractColorValue(colors?.alerts?.info, isDark) ?? ""
|
|
5959
6079
|
},
|
|
5960
6080
|
primary: {
|
|
5961
|
-
contrastText: extractContrastText(colors?.primary),
|
|
6081
|
+
contrastText: extractContrastText(colors?.primary) ?? "",
|
|
5962
6082
|
dark: colors?.primary?.dark || (colors?.primary)?.main,
|
|
5963
|
-
main: extractColorValue(colors?.primary, isDark)
|
|
6083
|
+
main: extractColorValue(colors?.primary, isDark) ?? ""
|
|
5964
6084
|
},
|
|
5965
6085
|
secondary: {
|
|
5966
|
-
contrastText: extractContrastText(colors?.secondary),
|
|
6086
|
+
contrastText: extractContrastText(colors?.secondary) ?? "",
|
|
5967
6087
|
dark: colors?.secondary?.dark || (colors?.secondary)?.main,
|
|
5968
|
-
main: extractColorValue(colors?.secondary, isDark)
|
|
6088
|
+
main: extractColorValue(colors?.secondary, isDark) ?? ""
|
|
5969
6089
|
},
|
|
5970
6090
|
success: {
|
|
5971
|
-
contrastText: extractContrastText(colors?.alerts?.neutral),
|
|
6091
|
+
contrastText: extractContrastText(colors?.alerts?.neutral) ?? "",
|
|
5972
6092
|
dark: (colors?.alerts?.neutral)?.dark || (colors?.alerts?.neutral)?.main,
|
|
5973
|
-
main: extractColorValue(colors?.alerts?.neutral, isDark)
|
|
6093
|
+
main: extractColorValue(colors?.alerts?.neutral, isDark) ?? ""
|
|
5974
6094
|
},
|
|
5975
6095
|
text: {
|
|
5976
6096
|
dark: (colors?.text)?.dark || (colors?.text)?.primary,
|
|
5977
|
-
primary: (colors?.text)?.primary,
|
|
5978
|
-
secondary: (colors?.text)?.secondary
|
|
6097
|
+
primary: (colors?.text)?.primary ?? "",
|
|
6098
|
+
secondary: (colors?.text)?.secondary ?? ""
|
|
5979
6099
|
},
|
|
5980
6100
|
warning: {
|
|
5981
|
-
contrastText: extractContrastText(colors?.alerts?.warning),
|
|
6101
|
+
contrastText: extractContrastText(colors?.alerts?.warning) ?? "",
|
|
5982
6102
|
dark: (colors?.alerts?.warning)?.dark || (colors?.alerts?.warning)?.main,
|
|
5983
|
-
main: extractColorValue(colors?.alerts?.warning, isDark)
|
|
6103
|
+
main: extractColorValue(colors?.alerts?.warning, isDark) ?? ""
|
|
5984
6104
|
}
|
|
5985
6105
|
},
|
|
5986
6106
|
images: {
|
|
@@ -6118,7 +6238,7 @@ var HttpClient = class HttpClient {
|
|
|
6118
6238
|
return (array) => callback(...array);
|
|
6119
6239
|
}
|
|
6120
6240
|
async requestHandler(config) {
|
|
6121
|
-
await this.attachToken(config);
|
|
6241
|
+
if (config.attachToken !== false) await this.attachToken(config);
|
|
6122
6242
|
if (config.shouldEncodeToFormData && config.data) {
|
|
6123
6243
|
const formData = new FormData();
|
|
6124
6244
|
Object.keys(config.data).forEach((key) => formData.append(key, config.data[key]));
|