@thunderid/javascript 0.1.0 → 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 +2 -1
- 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 +22 -3
- 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 +5 -4
package/dist/cjs/index.cjs
CHANGED
|
@@ -276,7 +276,7 @@ var ThunderIDError = class ThunderIDError extends Error {
|
|
|
276
276
|
* The backend returns errors in the following form:
|
|
277
277
|
* {"code":"...","message":{"key":"...","defaultValue":"..."},"description":{"key":"...","defaultValue":"..."}}
|
|
278
278
|
*
|
|
279
|
-
* Returns `
|
|
279
|
+
* Returns `message.defaultValue` if present, then `description.defaultValue`, and falls back
|
|
280
280
|
* to the raw `errorText` when the response is not a recognised structured error.
|
|
281
281
|
*/
|
|
282
282
|
const parseApiErrorMessage = (errorText) => {
|
|
@@ -284,8 +284,10 @@ const parseApiErrorMessage = (errorText) => {
|
|
|
284
284
|
const parsed = JSON.parse(errorText);
|
|
285
285
|
const description = parsed["description"];
|
|
286
286
|
const message = parsed["message"];
|
|
287
|
-
|
|
288
|
-
|
|
287
|
+
const descFallback = description?.defaultValue;
|
|
288
|
+
const msgFallback = message?.defaultValue;
|
|
289
|
+
if (msgFallback) return msgFallback;
|
|
290
|
+
if (descFallback) return descFallback;
|
|
289
291
|
} catch {}
|
|
290
292
|
return errorText;
|
|
291
293
|
};
|
|
@@ -359,7 +361,7 @@ var ThunderIDAPIError = class extends ThunderIDError {
|
|
|
359
361
|
* ```typescript
|
|
360
362
|
* try {
|
|
361
363
|
* const authResponse = await initializeEmbeddedSignInFlow({
|
|
362
|
-
* url: "https://
|
|
364
|
+
* url: "https://localhost:8090/oauth2/authorize",
|
|
363
365
|
* payload: {
|
|
364
366
|
* response_type: "code",
|
|
365
367
|
* client_id: "your-client-id",
|
|
@@ -500,7 +502,7 @@ let EmbeddedFlowComponentType = /* @__PURE__ */ function(EmbeddedFlowComponentTy
|
|
|
500
502
|
* ```typescript
|
|
501
503
|
* try {
|
|
502
504
|
* const embeddedSignUpResponse = await executeEmbeddedSignUpFlow({
|
|
503
|
-
* url: "https://
|
|
505
|
+
* url: "https://localhost:8090/api/server/v1/flow/execute",
|
|
504
506
|
* payload: {
|
|
505
507
|
* flowType: "REGISTRATION"
|
|
506
508
|
* }
|
|
@@ -552,7 +554,7 @@ var executeEmbeddedSignUpFlow_default = executeEmbeddedSignUpFlow;
|
|
|
552
554
|
* @returns A promise that resolves with the user information.
|
|
553
555
|
* @throw
|
|
554
556
|
* const userInfo = await getUserInfo({
|
|
555
|
-
* url: "https://
|
|
557
|
+
* url: "https://localhost:8090/oauth2/userinfo",
|
|
556
558
|
* });
|
|
557
559
|
* console.log(userInfo);
|
|
558
560
|
* } catch (error) {
|
|
@@ -687,7 +689,7 @@ var processUsername_default = processUsername;
|
|
|
687
689
|
* // Using default fetch
|
|
688
690
|
* try {
|
|
689
691
|
* const userProfile = await getScim2Me({
|
|
690
|
-
* url: "https://
|
|
692
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
691
693
|
* });
|
|
692
694
|
* console.log(userProfile);
|
|
693
695
|
* } catch (error) {
|
|
@@ -702,7 +704,7 @@ var processUsername_default = processUsername;
|
|
|
702
704
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
703
705
|
* try {
|
|
704
706
|
* const userProfile = await getScim2Me({
|
|
705
|
-
* url: "https://
|
|
707
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
706
708
|
* fetcher: async (url, config) => {
|
|
707
709
|
* const response = await httpClient({
|
|
708
710
|
* url,
|
|
@@ -768,7 +770,7 @@ var getScim2Me_default = getScim2Me;
|
|
|
768
770
|
* // Using default fetch
|
|
769
771
|
* try {
|
|
770
772
|
* const schemas = await getSchemas({
|
|
771
|
-
* url: "https://
|
|
773
|
+
* url: "https://localhost:8090/scim2/Schemas",
|
|
772
774
|
* });
|
|
773
775
|
* console.log(schemas);
|
|
774
776
|
* } catch (error) {
|
|
@@ -783,7 +785,7 @@ var getScim2Me_default = getScim2Me;
|
|
|
783
785
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
784
786
|
* try {
|
|
785
787
|
* const schemas = await getSchemas({
|
|
786
|
-
* url: "https://
|
|
788
|
+
* url: "https://localhost:8090/scim2/Schemas",
|
|
787
789
|
* fetcher: async (url, config) => {
|
|
788
790
|
* const response = await httpClient({
|
|
789
791
|
* url,
|
|
@@ -849,7 +851,7 @@ var getSchemas_default = getSchemas;
|
|
|
849
851
|
* // Using default fetch
|
|
850
852
|
* try {
|
|
851
853
|
* const response = await getAllOrganizations({
|
|
852
|
-
* baseUrl: "https://
|
|
854
|
+
* baseUrl: "https://localhost:8090",
|
|
853
855
|
* filter: "",
|
|
854
856
|
* limit: 10,
|
|
855
857
|
* recursive: false
|
|
@@ -867,7 +869,7 @@ var getSchemas_default = getSchemas;
|
|
|
867
869
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
868
870
|
* try {
|
|
869
871
|
* const response = await getAllOrganizations({
|
|
870
|
-
* baseUrl: "https://
|
|
872
|
+
* baseUrl: "https://localhost:8090",
|
|
871
873
|
* filter: "",
|
|
872
874
|
* limit: 10,
|
|
873
875
|
* recursive: false,
|
|
@@ -947,7 +949,7 @@ var getAllOrganizations_default = getAllOrganizations;
|
|
|
947
949
|
* // Using default fetch
|
|
948
950
|
* try {
|
|
949
951
|
* const organization = await createOrganization({
|
|
950
|
-
* baseUrl: "https://
|
|
952
|
+
* baseUrl: "https://localhost:8090",
|
|
951
953
|
* payload: {
|
|
952
954
|
* description: "Share your screens",
|
|
953
955
|
* name: "Team Viewer",
|
|
@@ -969,7 +971,7 @@ var getAllOrganizations_default = getAllOrganizations;
|
|
|
969
971
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
970
972
|
* try {
|
|
971
973
|
* const organization = await createOrganization({
|
|
972
|
-
* baseUrl: "https://
|
|
974
|
+
* baseUrl: "https://localhost:8090",
|
|
973
975
|
* payload: {
|
|
974
976
|
* description: "Share your screens",
|
|
975
977
|
* name: "Team Viewer",
|
|
@@ -1049,7 +1051,7 @@ var createOrganization_default = createOrganization;
|
|
|
1049
1051
|
* // Using default fetch
|
|
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: "",
|
|
@@ -1069,7 +1071,7 @@ var createOrganization_default = createOrganization;
|
|
|
1069
1071
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1070
1072
|
* try {
|
|
1071
1073
|
* const organizations = await getMeOrganizations({
|
|
1072
|
-
* baseUrl: "https://
|
|
1074
|
+
* baseUrl: "https://localhost:8090",
|
|
1073
1075
|
* after: "",
|
|
1074
1076
|
* before: "",
|
|
1075
1077
|
* filter: "",
|
|
@@ -1148,7 +1150,7 @@ var getMeOrganizations_default = getMeOrganizations;
|
|
|
1148
1150
|
* // Using default fetch
|
|
1149
1151
|
* try {
|
|
1150
1152
|
* const organization = await getOrganization({
|
|
1151
|
-
* baseUrl: "https://
|
|
1153
|
+
* baseUrl: "https://localhost:8090",
|
|
1152
1154
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1"
|
|
1153
1155
|
* });
|
|
1154
1156
|
* console.log(organization);
|
|
@@ -1164,7 +1166,7 @@ var getMeOrganizations_default = getMeOrganizations;
|
|
|
1164
1166
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1165
1167
|
* try {
|
|
1166
1168
|
* const organization = await getOrganization({
|
|
1167
|
-
* baseUrl: "https://
|
|
1169
|
+
* baseUrl: "https://localhost:8090",
|
|
1168
1170
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1",
|
|
1169
1171
|
* fetcher: async (url, config) => {
|
|
1170
1172
|
* const response = await httpClient({
|
|
@@ -1294,14 +1296,14 @@ var isEmpty_default = isEmpty;
|
|
|
1294
1296
|
* });
|
|
1295
1297
|
*
|
|
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
|
* });
|
|
1301
1303
|
*
|
|
1302
1304
|
* // Or manually specify operations
|
|
1303
1305
|
* await updateOrganization({
|
|
1304
|
-
* baseUrl: "https://
|
|
1306
|
+
* baseUrl: "https://localhost:8090",
|
|
1305
1307
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1",
|
|
1306
1308
|
* operations: [
|
|
1307
1309
|
* { operation: "REPLACE", path: "/name", value: "Updated Organization Name" },
|
|
@@ -1314,7 +1316,7 @@ var isEmpty_default = isEmpty;
|
|
|
1314
1316
|
* ```typescript
|
|
1315
1317
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1316
1318
|
* await updateOrganization({
|
|
1317
|
-
* baseUrl: "https://
|
|
1319
|
+
* baseUrl: "https://localhost:8090",
|
|
1318
1320
|
* organizationId: "0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1",
|
|
1319
1321
|
* operations: [
|
|
1320
1322
|
* { operation: "REPLACE", path: "/name", value: "Updated Organization Name" }
|
|
@@ -1399,7 +1401,7 @@ var updateOrganization_default = updateOrganization;
|
|
|
1399
1401
|
* ```typescript
|
|
1400
1402
|
* // Using default fetch
|
|
1401
1403
|
* await updateMeProfile({
|
|
1402
|
-
* url: "https://
|
|
1404
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
1403
1405
|
* payload: { "urn:scim:wso2:schema": { mobileNumbers: ["0777933830"] } }
|
|
1404
1406
|
* });
|
|
1405
1407
|
* ```
|
|
@@ -1408,7 +1410,7 @@ var updateOrganization_default = updateOrganization;
|
|
|
1408
1410
|
* ```typescript
|
|
1409
1411
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1410
1412
|
* await updateMeProfile({
|
|
1411
|
-
* url: "https://
|
|
1413
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
1412
1414
|
* payload: { "urn:scim:wso2:schema": { mobileNumbers: ["0777933830"] } },
|
|
1413
1415
|
* fetcher: async (url, config) => {
|
|
1414
1416
|
* const response = await httpClient({
|
|
@@ -1865,7 +1867,7 @@ var ThunderIDRuntimeError = class extends ThunderIDError {
|
|
|
1865
1867
|
* @returns boolean - true if sensible fallbacks can be used, false otherwise
|
|
1866
1868
|
*
|
|
1867
1869
|
* @example
|
|
1868
|
-
* isRecognizedBaseUrlPattern('https://
|
|
1870
|
+
* isRecognizedBaseUrlPattern('https://localhost:8090/t/dxlab'); // true
|
|
1869
1871
|
* isRecognizedBaseUrlPattern('https://custom.example.com/auth'); // false
|
|
1870
1872
|
*/
|
|
1871
1873
|
const isRecognizedBaseUrlPattern = (baseUrl) => {
|
|
@@ -1928,7 +1930,7 @@ var identifyPlatform_default = identifyPlatform;
|
|
|
1928
1930
|
* // Using default fetch
|
|
1929
1931
|
* try {
|
|
1930
1932
|
* const response = await getBrandingPreference({
|
|
1931
|
-
* baseUrl: "https://
|
|
1933
|
+
* baseUrl: "https://localhost:8090",
|
|
1932
1934
|
* locale: "en-US",
|
|
1933
1935
|
* name: "my-branding",
|
|
1934
1936
|
* type: "org"
|
|
@@ -1946,7 +1948,7 @@ var identifyPlatform_default = identifyPlatform;
|
|
|
1946
1948
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1947
1949
|
* try {
|
|
1948
1950
|
* const response = await getBrandingPreference({
|
|
1949
|
-
* baseUrl: "https://
|
|
1951
|
+
* baseUrl: "https://localhost:8090",
|
|
1950
1952
|
* locale: "en-US",
|
|
1951
1953
|
* name: "my-branding",
|
|
1952
1954
|
* type: "org",
|
|
@@ -2106,18 +2108,59 @@ let EmbeddedSignInFlowType$1 = /* @__PURE__ */ function(EmbeddedSignInFlowType$2
|
|
|
2106
2108
|
return EmbeddedSignInFlowType$2;
|
|
2107
2109
|
}({});
|
|
2108
2110
|
|
|
2111
|
+
//#endregion
|
|
2112
|
+
//#region src/utils/v2/injectRequestedPermissions.ts
|
|
2113
|
+
/**
|
|
2114
|
+
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
2115
|
+
*
|
|
2116
|
+
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
2117
|
+
* Version 2.0 (the "License"); you may not use this file except
|
|
2118
|
+
* in compliance with the License.
|
|
2119
|
+
* You may obtain a copy of the License at
|
|
2120
|
+
*
|
|
2121
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2122
|
+
*
|
|
2123
|
+
* Unless required by applicable law or agreed to in writing,
|
|
2124
|
+
* software distributed under the License is distributed on an
|
|
2125
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
2126
|
+
* KIND, either express or implied. See the License for the
|
|
2127
|
+
* specific language governing permissions and limitations
|
|
2128
|
+
* under the License.
|
|
2129
|
+
*/
|
|
2130
|
+
/**
|
|
2131
|
+
* Strips the top-level `scopes` field from a payload and injects it as
|
|
2132
|
+
* `inputs.requested_permissions` (space-separated string).
|
|
2133
|
+
*
|
|
2134
|
+
* The backend reads requested_permissions from UserInputs (the `inputs` map), not a top-level field.
|
|
2135
|
+
*/
|
|
2136
|
+
const injectRequestedPermissions = (payload) => {
|
|
2137
|
+
const { scopes,...rest } = payload;
|
|
2138
|
+
const normalizedScopes = Array.isArray(scopes) ? scopes.map((s) => String(s).trim()).filter(Boolean).join(" ") : typeof scopes === "string" ? scopes.trim() : "";
|
|
2139
|
+
if (!normalizedScopes) return rest;
|
|
2140
|
+
const existingInputs = rest["inputs"] != null && typeof rest["inputs"] === "object" && !Array.isArray(rest["inputs"]) ? rest["inputs"] : {};
|
|
2141
|
+
return {
|
|
2142
|
+
...rest,
|
|
2143
|
+
inputs: {
|
|
2144
|
+
...existingInputs,
|
|
2145
|
+
requested_permissions: normalizedScopes
|
|
2146
|
+
}
|
|
2147
|
+
};
|
|
2148
|
+
};
|
|
2149
|
+
var injectRequestedPermissions_default = injectRequestedPermissions;
|
|
2150
|
+
|
|
2109
2151
|
//#endregion
|
|
2110
2152
|
//#region src/api/v2/executeEmbeddedSignInFlowV2.ts
|
|
2111
2153
|
const executeEmbeddedSignInFlowV2 = async ({ url, baseUrl, payload, authId,...requestConfig }) => {
|
|
2112
2154
|
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.");
|
|
2113
2155
|
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2114
2156
|
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2115
|
-
const
|
|
2157
|
+
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
2116
2158
|
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2117
|
-
const
|
|
2118
|
-
|
|
2159
|
+
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
2160
|
+
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
2161
|
+
...basePayload,
|
|
2119
2162
|
verbose: true
|
|
2120
|
-
} :
|
|
2163
|
+
} : basePayload;
|
|
2121
2164
|
const response = await fetch(endpoint, {
|
|
2122
2165
|
...requestConfig,
|
|
2123
2166
|
body: JSON.stringify(requestPayload),
|
|
@@ -2144,14 +2187,15 @@ const executeEmbeddedSignInFlowV2 = async ({ url, baseUrl, payload, authId,...re
|
|
|
2144
2187
|
},
|
|
2145
2188
|
method: "POST"
|
|
2146
2189
|
});
|
|
2147
|
-
if (!oauth2Response.ok) throw new ThunderIDAPIError(
|
|
2190
|
+
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignInFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
2148
2191
|
const oauth2Result = await oauth2Response.json();
|
|
2149
2192
|
return {
|
|
2150
2193
|
flowStatus: flowResponse.flowStatus,
|
|
2151
2194
|
redirectUrl: oauth2Result["redirect_uri"]
|
|
2152
2195
|
};
|
|
2153
2196
|
} catch (authError) {
|
|
2154
|
-
|
|
2197
|
+
if (authError instanceof ThunderIDAPIError) throw authError;
|
|
2198
|
+
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");
|
|
2155
2199
|
}
|
|
2156
2200
|
return flowResponse;
|
|
2157
2201
|
};
|
|
@@ -2176,9 +2220,9 @@ var executeEmbeddedSignInFlowV2_default = executeEmbeddedSignInFlowV2;
|
|
|
2176
2220
|
* // Registration successful - handle completion
|
|
2177
2221
|
* break;
|
|
2178
2222
|
* case EmbeddedSignUpFlowStatus.Error:
|
|
2179
|
-
* // Registration failed - show
|
|
2223
|
+
* // Registration failed - show error details
|
|
2180
2224
|
* const errorResponse = response as EmbeddedSignUpFlowErrorResponse;
|
|
2181
|
-
* showError(errorResponse.
|
|
2225
|
+
* showError(errorResponse.error.description.defaultValue);
|
|
2182
2226
|
* break;
|
|
2183
2227
|
* }
|
|
2184
2228
|
* ```
|
|
@@ -2250,12 +2294,13 @@ const executeEmbeddedSignUpFlowV2 = async ({ url, baseUrl, payload, authId,...re
|
|
|
2250
2294
|
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.");
|
|
2251
2295
|
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2252
2296
|
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2253
|
-
const
|
|
2297
|
+
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
2254
2298
|
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2255
|
-
const
|
|
2256
|
-
|
|
2299
|
+
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
2300
|
+
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
2301
|
+
...basePayload,
|
|
2257
2302
|
verbose: true
|
|
2258
|
-
} :
|
|
2303
|
+
} : basePayload;
|
|
2259
2304
|
const response = await fetch(endpoint, {
|
|
2260
2305
|
...requestConfig,
|
|
2261
2306
|
body: JSON.stringify(requestPayload),
|
|
@@ -2282,14 +2327,15 @@ const executeEmbeddedSignUpFlowV2 = async ({ url, baseUrl, payload, authId,...re
|
|
|
2282
2327
|
},
|
|
2283
2328
|
method: "POST"
|
|
2284
2329
|
});
|
|
2285
|
-
if (!oauth2Response.ok) throw new ThunderIDAPIError(
|
|
2330
|
+
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignUpFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
2286
2331
|
const oauth2Result = await oauth2Response.json();
|
|
2287
2332
|
return {
|
|
2288
2333
|
flowStatus: flowResponse.flowStatus,
|
|
2289
2334
|
redirectUrl: oauth2Result["redirect_uri"]
|
|
2290
2335
|
};
|
|
2291
2336
|
} catch (authError) {
|
|
2292
|
-
|
|
2337
|
+
if (authError instanceof ThunderIDAPIError) throw authError;
|
|
2338
|
+
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");
|
|
2293
2339
|
}
|
|
2294
2340
|
return flowResponse;
|
|
2295
2341
|
};
|
|
@@ -2313,7 +2359,7 @@ var executeEmbeddedSignUpFlowV2_default = executeEmbeddedSignUpFlowV2;
|
|
|
2313
2359
|
* ```typescript
|
|
2314
2360
|
* // Initiate recovery flow
|
|
2315
2361
|
* const response = await executeEmbeddedRecoveryFlowV2({
|
|
2316
|
-
* baseUrl: 'https://
|
|
2362
|
+
* baseUrl: 'https://localhost:8090',
|
|
2317
2363
|
* payload: {
|
|
2318
2364
|
* flowType: 'RECOVERY',
|
|
2319
2365
|
* applicationId: 'my-app-id',
|
|
@@ -2322,7 +2368,7 @@ var executeEmbeddedSignUpFlowV2_default = executeEmbeddedSignUpFlowV2;
|
|
|
2322
2368
|
*
|
|
2323
2369
|
* // Continue recovery flow with user input
|
|
2324
2370
|
* const nextResponse = await executeEmbeddedRecoveryFlowV2({
|
|
2325
|
-
* baseUrl: 'https://
|
|
2371
|
+
* baseUrl: 'https://localhost:8090',
|
|
2326
2372
|
* payload: {
|
|
2327
2373
|
* executionId: response.executionId,
|
|
2328
2374
|
* action: 'submit',
|
|
@@ -2352,7 +2398,7 @@ const executeEmbeddedRecoveryFlowV2 = async ({ url, baseUrl, payload,...requestC
|
|
|
2352
2398
|
},
|
|
2353
2399
|
method: requestConfig.method || "POST"
|
|
2354
2400
|
});
|
|
2355
|
-
if (!response.ok) throw new ThunderIDAPIError(
|
|
2401
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedRecoveryFlow-ResponseError-001", "javascript", response.status, response.statusText, "Recovery request failed");
|
|
2356
2402
|
return await response.json();
|
|
2357
2403
|
};
|
|
2358
2404
|
var executeEmbeddedRecoveryFlowV2_default = executeEmbeddedRecoveryFlowV2;
|
|
@@ -2767,6 +2813,8 @@ let EmbeddedFlowComponentType$1 = /* @__PURE__ */ function(EmbeddedFlowComponent
|
|
|
2767
2813
|
EmbeddedFlowComponentType$2["TextInput"] = "TEXT_INPUT";
|
|
2768
2814
|
/** Timer component for displaying a countdown */
|
|
2769
2815
|
EmbeddedFlowComponentType$2["Timer"] = "TIMER";
|
|
2816
|
+
/** QR code display component for wallet-based flows (e.g. OpenID4VP) */
|
|
2817
|
+
EmbeddedFlowComponentType$2["QrCode"] = "QR_CODE";
|
|
2770
2818
|
return EmbeddedFlowComponentType$2;
|
|
2771
2819
|
}({});
|
|
2772
2820
|
/**
|
|
@@ -3251,6 +3299,10 @@ let Stores = /* @__PURE__ */ function(Stores$1) {
|
|
|
3251
3299
|
* Store for temporary data that needs to persist only for a short duration.
|
|
3252
3300
|
*/
|
|
3253
3301
|
Stores$1["TemporaryData"] = "temporary_data";
|
|
3302
|
+
/**
|
|
3303
|
+
* Store for data that leverages local storage if available, falling back to the configured storage.
|
|
3304
|
+
*/
|
|
3305
|
+
Stores$1["HybridData"] = "hybrid_data";
|
|
3254
3306
|
return Stores$1;
|
|
3255
3307
|
}({});
|
|
3256
3308
|
|
|
@@ -3312,7 +3364,18 @@ var StorageManager = class StorageManager {
|
|
|
3312
3364
|
this.setDataInBulk(this.resolveKey(Stores.OIDCProviderMetaData), oidcProviderMetaData);
|
|
3313
3365
|
}
|
|
3314
3366
|
async setTemporaryData(temporaryData, userId) {
|
|
3315
|
-
this.setDataInBulk(this.resolveKey(Stores.TemporaryData, userId), temporaryData);
|
|
3367
|
+
await this.setDataInBulk(this.resolveKey(Stores.TemporaryData, userId), temporaryData);
|
|
3368
|
+
}
|
|
3369
|
+
async setHybridData(hybridData, userId) {
|
|
3370
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3371
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3372
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3373
|
+
const dataToBeSaved = {
|
|
3374
|
+
...existingDataJSON ? JSON.parse(existingDataJSON) : {},
|
|
3375
|
+
...hybridData
|
|
3376
|
+
};
|
|
3377
|
+
localStorage.setItem(resolvedKey, JSON.stringify(dataToBeSaved));
|
|
3378
|
+
} else await this.setDataInBulk(resolvedKey, hybridData);
|
|
3316
3379
|
}
|
|
3317
3380
|
async setSessionData(sessionData, userId) {
|
|
3318
3381
|
this.setDataInBulk(this.resolveKey(Stores.SessionData, userId), sessionData);
|
|
@@ -3327,7 +3390,35 @@ var StorageManager = class StorageManager {
|
|
|
3327
3390
|
return JSON.parse(await this.store.getData(this.resolveKey(Stores.OIDCProviderMetaData)) ?? null);
|
|
3328
3391
|
}
|
|
3329
3392
|
async getTemporaryData(userId) {
|
|
3330
|
-
|
|
3393
|
+
const data = await this.store.getData(this.resolveKey(Stores.TemporaryData, userId));
|
|
3394
|
+
if (data) try {
|
|
3395
|
+
return JSON.parse(data);
|
|
3396
|
+
} catch (error$1) {
|
|
3397
|
+
logger_default.error(`StorageManager: Failed to parse temporary data for key ${this.resolveKey(Stores.TemporaryData, userId)}`, error$1);
|
|
3398
|
+
return {};
|
|
3399
|
+
}
|
|
3400
|
+
return {};
|
|
3401
|
+
}
|
|
3402
|
+
async getHybridData(userId) {
|
|
3403
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3404
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3405
|
+
const storeDataJSON$1 = localStorage.getItem(resolvedKey);
|
|
3406
|
+
if (storeDataJSON$1) try {
|
|
3407
|
+
return JSON.parse(storeDataJSON$1);
|
|
3408
|
+
} catch (error$1) {
|
|
3409
|
+
logger_default.error(`StorageManager: Failed to parse hybrid data from local storage for key ${resolvedKey}`, error$1);
|
|
3410
|
+
return {};
|
|
3411
|
+
}
|
|
3412
|
+
return {};
|
|
3413
|
+
}
|
|
3414
|
+
const storeDataJSON = await this.store.getData(resolvedKey) ?? null;
|
|
3415
|
+
if (storeDataJSON) try {
|
|
3416
|
+
return JSON.parse(storeDataJSON);
|
|
3417
|
+
} catch (error$1) {
|
|
3418
|
+
logger_default.error(`StorageManager: Failed to parse hybrid data from store for key ${resolvedKey}`, error$1);
|
|
3419
|
+
return {};
|
|
3420
|
+
}
|
|
3421
|
+
return {};
|
|
3331
3422
|
}
|
|
3332
3423
|
async getPersistedData(userId) {
|
|
3333
3424
|
return JSON.parse(await this.store.getData(this.resolveKey(Stores.PersistedData, userId)) ?? null);
|
|
@@ -3359,6 +3450,11 @@ var StorageManager = class StorageManager {
|
|
|
3359
3450
|
async removeTemporaryData(userId) {
|
|
3360
3451
|
await this.store.removeData(this.resolveKey(Stores.TemporaryData, userId));
|
|
3361
3452
|
}
|
|
3453
|
+
async removeHybridData(userId) {
|
|
3454
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3455
|
+
if (StorageManager.isLocalStorageAvailable()) localStorage.removeItem(resolvedKey);
|
|
3456
|
+
else await this.store.removeData(resolvedKey);
|
|
3457
|
+
}
|
|
3362
3458
|
async removeSessionData(userId) {
|
|
3363
3459
|
await this.store.removeData(this.resolveKey(Stores.SessionData, userId));
|
|
3364
3460
|
}
|
|
@@ -3374,6 +3470,15 @@ var StorageManager = class StorageManager {
|
|
|
3374
3470
|
const data = await this.store.getData(this.resolveKey(Stores.TemporaryData, userId));
|
|
3375
3471
|
return data && JSON.parse(data)[key];
|
|
3376
3472
|
}
|
|
3473
|
+
async getHybridDataParameter(key, userId) {
|
|
3474
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3475
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3476
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3477
|
+
return (existingDataJSON ? JSON.parse(existingDataJSON) : {})[key];
|
|
3478
|
+
}
|
|
3479
|
+
const data = await this.store.getData(resolvedKey);
|
|
3480
|
+
return data && JSON.parse(data)[key];
|
|
3481
|
+
}
|
|
3377
3482
|
async getSessionDataParameter(key, userId) {
|
|
3378
3483
|
const data = await this.store.getData(this.resolveKey(Stores.SessionData, userId));
|
|
3379
3484
|
return data && JSON.parse(data)[key];
|
|
@@ -3387,6 +3492,17 @@ var StorageManager = class StorageManager {
|
|
|
3387
3492
|
async setTemporaryDataParameter(key, value, userId) {
|
|
3388
3493
|
await this.setValue(this.resolveKey(Stores.TemporaryData, userId), key, value);
|
|
3389
3494
|
}
|
|
3495
|
+
async setHybridDataParameter(key, value, userId) {
|
|
3496
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3497
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3498
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3499
|
+
const dataToBeSaved = {
|
|
3500
|
+
...existingDataJSON ? JSON.parse(existingDataJSON) : {},
|
|
3501
|
+
[key]: value
|
|
3502
|
+
};
|
|
3503
|
+
localStorage.setItem(resolvedKey, JSON.stringify(dataToBeSaved));
|
|
3504
|
+
} else await this.setValue(resolvedKey, key, value);
|
|
3505
|
+
}
|
|
3390
3506
|
async setSessionDataParameter(key, value, userId) {
|
|
3391
3507
|
await this.setValue(this.resolveKey(Stores.SessionData, userId), key, value);
|
|
3392
3508
|
}
|
|
@@ -3399,56 +3515,21 @@ var StorageManager = class StorageManager {
|
|
|
3399
3515
|
async removeTemporaryDataParameter(key, userId) {
|
|
3400
3516
|
await this.removeValue(this.resolveKey(Stores.TemporaryData, userId), key);
|
|
3401
3517
|
}
|
|
3518
|
+
async removeHybridDataParameter(key, userId) {
|
|
3519
|
+
const resolvedKey = this.resolveKey(Stores.HybridData, userId);
|
|
3520
|
+
if (StorageManager.isLocalStorageAvailable()) {
|
|
3521
|
+
const existingDataJSON = localStorage.getItem(resolvedKey);
|
|
3522
|
+
const existingData = existingDataJSON ? JSON.parse(existingDataJSON) : {};
|
|
3523
|
+
delete existingData[key];
|
|
3524
|
+
localStorage.setItem(resolvedKey, JSON.stringify(existingData));
|
|
3525
|
+
} else await this.removeValue(resolvedKey, key);
|
|
3526
|
+
}
|
|
3402
3527
|
async removeSessionDataParameter(key, userId) {
|
|
3403
3528
|
await this.removeValue(this.resolveKey(Stores.SessionData, userId), key);
|
|
3404
3529
|
}
|
|
3405
3530
|
};
|
|
3406
3531
|
var StorageManager_default = StorageManager;
|
|
3407
3532
|
|
|
3408
|
-
//#endregion
|
|
3409
|
-
//#region src/constants/TokenExchangeConstants.ts
|
|
3410
|
-
/**
|
|
3411
|
-
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
|
|
3412
|
-
*
|
|
3413
|
-
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
3414
|
-
* Version 2.0 (the "License"); you may not use this file except
|
|
3415
|
-
* in compliance with the License.
|
|
3416
|
-
* You may obtain a copy of the License at
|
|
3417
|
-
*
|
|
3418
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
3419
|
-
*
|
|
3420
|
-
* Unless required by applicable law or agreed to in writing,
|
|
3421
|
-
* software distributed under the License is distributed on an
|
|
3422
|
-
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
3423
|
-
* KIND, either express or implied. See the License for the
|
|
3424
|
-
* specific language governing permissions and limitations
|
|
3425
|
-
* under the License.
|
|
3426
|
-
*/
|
|
3427
|
-
/**
|
|
3428
|
-
* Constants for OAuth 2.0 Token Exchange operations.
|
|
3429
|
-
* This object contains placeholders used in token exchange requests
|
|
3430
|
-
* and responses for dynamic value substitution.
|
|
3431
|
-
*
|
|
3432
|
-
* @remarks
|
|
3433
|
-
* These placeholders are used in token exchange templates and are replaced
|
|
3434
|
-
* with actual values during request processing. They help in creating
|
|
3435
|
-
* flexible and reusable token exchange configurations.
|
|
3436
|
-
*
|
|
3437
|
-
* @example
|
|
3438
|
-
* ```typescript
|
|
3439
|
-
* // Using placeholders in a token exchange template
|
|
3440
|
-
* const template = `grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=${TokenExchangeConstants.Placeholders.TOKEN}`;
|
|
3441
|
-
* ```
|
|
3442
|
-
*/
|
|
3443
|
-
const TokenExchangeConstants = { Placeholders: {
|
|
3444
|
-
ACCESS_TOKEN: "{{accessToken}}",
|
|
3445
|
-
CLIENT_ID: "{{clientId}}",
|
|
3446
|
-
CLIENT_SECRET: "{{clientSecret}}",
|
|
3447
|
-
SCOPES: "{{scopes}}",
|
|
3448
|
-
USERNAME: "{{username}}"
|
|
3449
|
-
} };
|
|
3450
|
-
var TokenExchangeConstants_default = TokenExchangeConstants;
|
|
3451
|
-
|
|
3452
3533
|
//#endregion
|
|
3453
3534
|
//#region src/utils/extractUserClaimsFromIdToken.ts
|
|
3454
3535
|
/**
|
|
@@ -3544,6 +3625,50 @@ const processOpenIDScopes = (scopes) => {
|
|
|
3544
3625
|
};
|
|
3545
3626
|
var processOpenIDScopes_default = processOpenIDScopes;
|
|
3546
3627
|
|
|
3628
|
+
//#endregion
|
|
3629
|
+
//#region src/constants/TokenExchangeConstants.ts
|
|
3630
|
+
/**
|
|
3631
|
+
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
|
|
3632
|
+
*
|
|
3633
|
+
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
3634
|
+
* Version 2.0 (the "License"); you may not use this file except
|
|
3635
|
+
* in compliance with the License.
|
|
3636
|
+
* You may obtain a copy of the License at
|
|
3637
|
+
*
|
|
3638
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
3639
|
+
*
|
|
3640
|
+
* Unless required by applicable law or agreed to in writing,
|
|
3641
|
+
* software distributed under the License is distributed on an
|
|
3642
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
3643
|
+
* KIND, either express or implied. See the License for the
|
|
3644
|
+
* specific language governing permissions and limitations
|
|
3645
|
+
* under the License.
|
|
3646
|
+
*/
|
|
3647
|
+
/**
|
|
3648
|
+
* Constants for OAuth 2.0 Token Exchange operations.
|
|
3649
|
+
* This object contains placeholders used in token exchange requests
|
|
3650
|
+
* and responses for dynamic value substitution.
|
|
3651
|
+
*
|
|
3652
|
+
* @remarks
|
|
3653
|
+
* These placeholders are used in token exchange templates and are replaced
|
|
3654
|
+
* with actual values during request processing. They help in creating
|
|
3655
|
+
* flexible and reusable token exchange configurations.
|
|
3656
|
+
*
|
|
3657
|
+
* @example
|
|
3658
|
+
* ```typescript
|
|
3659
|
+
* // Using placeholders in a token exchange template
|
|
3660
|
+
* const template = `grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=${TokenExchangeConstants.Placeholders.TOKEN}`;
|
|
3661
|
+
* ```
|
|
3662
|
+
*/
|
|
3663
|
+
const TokenExchangeConstants = { Placeholders: {
|
|
3664
|
+
ACCESS_TOKEN: "{{accessToken}}",
|
|
3665
|
+
CLIENT_ID: "{{clientId}}",
|
|
3666
|
+
CLIENT_SECRET: "{{clientSecret}}",
|
|
3667
|
+
SCOPES: "{{scopes}}",
|
|
3668
|
+
USERNAME: "{{username}}"
|
|
3669
|
+
} };
|
|
3670
|
+
var TokenExchangeConstants_default = TokenExchangeConstants;
|
|
3671
|
+
|
|
3547
3672
|
//#endregion
|
|
3548
3673
|
//#region src/utils/AuthenticationHelper.ts
|
|
3549
3674
|
/**
|
|
@@ -3669,7 +3794,7 @@ var AuthenticationHelper = class {
|
|
|
3669
3794
|
const { issuer } = await this.oidcProviderMetaData();
|
|
3670
3795
|
const { keys } = await response.json();
|
|
3671
3796
|
const jwk = await this.cryptoHelper.getJWKForTheIdToken(idToken.split(".")[0], keys);
|
|
3672
|
-
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);
|
|
3797
|
+
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);
|
|
3673
3798
|
}
|
|
3674
3799
|
/**
|
|
3675
3800
|
* Extracts user information from a decoded ID token payload.
|
|
@@ -3711,7 +3836,7 @@ var AuthenticationHelper = class {
|
|
|
3711
3836
|
} else sessionData = await this.storageManager.getSessionData(userId);
|
|
3712
3837
|
const scope = processOpenIDScopes_default(configData.scopes);
|
|
3713
3838
|
if (typeof text !== "string") return text;
|
|
3714
|
-
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 ?? "");
|
|
3839
|
+
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 ?? "");
|
|
3715
3840
|
}
|
|
3716
3841
|
/**
|
|
3717
3842
|
* Clears all temporary and session data for the given user.
|
|
@@ -3960,7 +4085,7 @@ const getAuthorizeRequestUrlParams = (options, pkceOptions, customParams) => {
|
|
|
3960
4085
|
const authorizeRequestParams = /* @__PURE__ */ new Map();
|
|
3961
4086
|
authorizeRequestParams.set("response_type", "code");
|
|
3962
4087
|
authorizeRequestParams.set("client_id", clientId);
|
|
3963
|
-
authorizeRequestParams.set("scope", scopes);
|
|
4088
|
+
authorizeRequestParams.set("scope", scopes ?? "");
|
|
3964
4089
|
authorizeRequestParams.set("redirect_uri", redirectUri);
|
|
3965
4090
|
if (responseMode) authorizeRequestParams.set("response_mode", responseMode);
|
|
3966
4091
|
const pkceKey = pkceOptions?.key;
|
|
@@ -4027,13 +4152,11 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4027
4152
|
if (persistedData?.["applicationId"]) resolvedApplicationId = persistedData["applicationId"];
|
|
4028
4153
|
}
|
|
4029
4154
|
const resolvedEndpoints = endpoints ? { ...endpoints } : {};
|
|
4030
|
-
await this.storageManager.setConfigData({
|
|
4031
|
-
...DEFAULT_CONFIG,
|
|
4032
|
-
...fullConfig,
|
|
4155
|
+
await this.storageManager.setConfigData(deepMerge_default({}, DEFAULT_CONFIG, fullConfig, {
|
|
4033
4156
|
applicationId: resolvedApplicationId,
|
|
4034
4157
|
endpoints: resolvedEndpoints,
|
|
4035
4158
|
scope: processOpenIDScopes_default(fullConfig.scopes)
|
|
4036
|
-
});
|
|
4159
|
+
}));
|
|
4037
4160
|
this.baseURL = fullConfig.baseUrl ?? "";
|
|
4038
4161
|
return true;
|
|
4039
4162
|
}
|
|
@@ -4181,19 +4304,19 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4181
4304
|
if (configData.enablePKCE) {
|
|
4182
4305
|
codeVerifier = this.cryptoHelper?.getCodeVerifier();
|
|
4183
4306
|
codeChallenge = await this.cryptoHelper?.getCodeChallenge(codeVerifier);
|
|
4184
|
-
await this.storageManager.
|
|
4307
|
+
await this.storageManager.setHybridDataParameter(pkceKey, codeVerifier, userId);
|
|
4185
4308
|
}
|
|
4186
|
-
if (authRequestConfig["client_secret"]) authRequestConfig["client_secret"] = configData.clientSecret;
|
|
4187
|
-
const authorizeRequestParams = getAuthorizeRequestUrlParams_default({
|
|
4188
|
-
clientId: configData.clientId,
|
|
4309
|
+
if (authRequestConfig["client_secret"]) authRequestConfig["client_secret"] = configData.clientSecret ?? "";
|
|
4310
|
+
const authorizeRequestParams = getAuthorizeRequestUrlParams_default(Object.fromEntries(Object.entries({
|
|
4311
|
+
clientId: configData.clientId ?? "",
|
|
4189
4312
|
codeChallenge,
|
|
4190
4313
|
codeChallengeMethod: PKCEConstants_default.DEFAULT_CODE_CHALLENGE_METHOD,
|
|
4191
4314
|
instanceId: this.getInstanceId().toString(),
|
|
4192
4315
|
prompt: configData.prompt,
|
|
4193
|
-
redirectUri: configData.afterSignInUrl,
|
|
4316
|
+
redirectUri: configData.afterSignInUrl ?? "",
|
|
4194
4317
|
responseMode: configData.responseMode,
|
|
4195
4318
|
scopes: processOpenIDScopes_default(configData.scopes)
|
|
4196
|
-
}, { key: pkceKey }, authRequestConfig);
|
|
4319
|
+
}).filter(([, v]) => v !== void 0)), { key: pkceKey }, authRequestConfig);
|
|
4197
4320
|
Array.from(authorizeRequestParams.entries()).forEach(([paramKey, paramValue]) => {
|
|
4198
4321
|
authorizeRequest.searchParams.append(paramKey, paramValue);
|
|
4199
4322
|
});
|
|
@@ -4209,19 +4332,19 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4209
4332
|
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.");
|
|
4210
4333
|
if (sessionState) await this.storageManager.setSessionDataParameter(OIDCRequestConstants_default.Params.SESSION_STATE, sessionState, userId);
|
|
4211
4334
|
const body = new URLSearchParams();
|
|
4212
|
-
body.set("client_id", configData.clientId);
|
|
4335
|
+
body.set("client_id", configData.clientId ?? "");
|
|
4213
4336
|
const hasSecret = Boolean(configData.clientSecret && configData.clientSecret.trim().length > 0);
|
|
4214
4337
|
const tokenEndpointAuthMethod = configData.tokenRequest?.authMethod ?? "client_secret_basic";
|
|
4215
4338
|
if (hasSecret && tokenEndpointAuthMethod === "client_secret_post") body.set("client_secret", configData.clientSecret);
|
|
4216
4339
|
body.set("code", authorizationCode);
|
|
4217
4340
|
body.set("grant_type", "authorization_code");
|
|
4218
|
-
body.set("redirect_uri", configData.afterSignInUrl);
|
|
4341
|
+
body.set("redirect_uri", configData.afterSignInUrl ?? "");
|
|
4219
4342
|
if (tokenRequestConfig?.params) Object.entries(tokenRequestConfig.params).forEach(([key, value]) => {
|
|
4220
4343
|
body.append(key, value);
|
|
4221
4344
|
});
|
|
4222
4345
|
if (configData.enablePKCE) {
|
|
4223
|
-
body.set("code_verifier", `${await this.storageManager.
|
|
4224
|
-
await this.storageManager.
|
|
4346
|
+
body.set("code_verifier", `${await this.storageManager.getHybridDataParameter(extractPkceStorageKeyFromState_default(state), userId)}`);
|
|
4347
|
+
await this.storageManager.removeHybridDataParameter(extractPkceStorageKeyFromState_default(state), userId);
|
|
4225
4348
|
}
|
|
4226
4349
|
const tokenRequestHeaders = {
|
|
4227
4350
|
Accept: "application/json",
|
|
@@ -4254,7 +4377,7 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4254
4377
|
const idToken = (await this.storageManager.getSessionData(userId))?.id_token;
|
|
4255
4378
|
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.");
|
|
4256
4379
|
queryParams.set("id_token_hint", idToken);
|
|
4257
|
-
} else queryParams.set("client_id", configData.clientId);
|
|
4380
|
+
} else queryParams.set("client_id", configData.clientId ?? "");
|
|
4258
4381
|
queryParams.set("state", OIDCRequestConstants_default.Params.SIGN_OUT_SUCCESS);
|
|
4259
4382
|
return `${logoutEndpoint}?${queryParams.toString()}`;
|
|
4260
4383
|
}
|
|
@@ -4349,10 +4472,10 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4349
4472
|
return response;
|
|
4350
4473
|
}
|
|
4351
4474
|
async getPKCECode(state, userId) {
|
|
4352
|
-
return await this.storageManager.
|
|
4475
|
+
return await this.storageManager.getHybridDataParameter(extractPkceStorageKeyFromState_default(state), userId);
|
|
4353
4476
|
}
|
|
4354
4477
|
async setPKCECode(pkce, state, userId) {
|
|
4355
|
-
return this.storageManager.
|
|
4478
|
+
return this.storageManager.setHybridDataParameter(extractPkceStorageKeyFromState_default(state), pkce, userId);
|
|
4356
4479
|
}
|
|
4357
4480
|
getInstanceId() {
|
|
4358
4481
|
return this.instanceIdValue;
|
|
@@ -4683,12 +4806,15 @@ const toCssVariables = (theme) => {
|
|
|
4683
4806
|
if (theme.typography?.lineHeights?.tight !== void 0) cssVars[`--${prefix}-typography-lineHeight-tight`] = theme.typography.lineHeights.tight.toString();
|
|
4684
4807
|
if (theme.typography?.lineHeights?.normal !== void 0) cssVars[`--${prefix}-typography-lineHeight-normal`] = theme.typography.lineHeights.normal.toString();
|
|
4685
4808
|
if (theme.typography?.lineHeights?.relaxed !== void 0) cssVars[`--${prefix}-typography-lineHeight-relaxed`] = theme.typography.lineHeights.relaxed.toString();
|
|
4686
|
-
if (theme.images)
|
|
4687
|
-
const
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4809
|
+
if (theme.images) {
|
|
4810
|
+
const themeImages = theme.images;
|
|
4811
|
+
Object.keys(themeImages).forEach((imageKey) => {
|
|
4812
|
+
const imageConfig = themeImages[imageKey];
|
|
4813
|
+
if (imageConfig?.url) cssVars[`--${prefix}-image-${imageKey}-url`] = imageConfig.url;
|
|
4814
|
+
if (imageConfig?.title) cssVars[`--${prefix}-image-${imageKey}-title`] = imageConfig.title;
|
|
4815
|
+
if (imageConfig?.alt) cssVars[`--${prefix}-image-${imageKey}-alt`] = imageConfig.alt;
|
|
4816
|
+
});
|
|
4817
|
+
}
|
|
4692
4818
|
if (theme.components?.Button?.styleOverrides?.root?.borderRadius) cssVars[`--${prefix}-component-button-root-borderRadius`] = theme.components.Button.styleOverrides.root.borderRadius;
|
|
4693
4819
|
if (theme.components?.Field?.styleOverrides?.root?.borderRadius) cssVars[`--${prefix}-component-field-root-borderRadius`] = theme.components.Field.styleOverrides.root.borderRadius;
|
|
4694
4820
|
return cssVars;
|
|
@@ -4785,9 +4911,11 @@ const toThemeVars = (theme) => {
|
|
|
4785
4911
|
};
|
|
4786
4912
|
if (theme.images) {
|
|
4787
4913
|
themeVars.images = {};
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4914
|
+
const themeImages = theme.images;
|
|
4915
|
+
const imageVars = themeVars.images;
|
|
4916
|
+
Object.keys(themeImages).forEach((imageKey) => {
|
|
4917
|
+
const imageConfig = themeImages[imageKey];
|
|
4918
|
+
imageVars[imageKey] = {
|
|
4791
4919
|
alt: imageConfig?.alt ? `var(--${prefix}-image-${imageKey}-alt)` : void 0,
|
|
4792
4920
|
title: imageConfig?.title ? `var(--${prefix}-image-${imageKey}-title)` : void 0,
|
|
4793
4921
|
url: imageConfig?.url ? `var(--${prefix}-image-${imageKey}-url)` : void 0
|
|
@@ -5081,13 +5209,9 @@ var formatDate_default = formatDate;
|
|
|
5081
5209
|
//#endregion
|
|
5082
5210
|
//#region src/utils/deriveOrganizationHandleFromBaseUrl.ts
|
|
5083
5211
|
/**
|
|
5084
|
-
* Extracts the organization handle from
|
|
5212
|
+
* Extracts the organization handle from a ThunderID base URL.
|
|
5085
5213
|
*
|
|
5086
|
-
*
|
|
5087
|
-
* - https://dev.asgardeo.io/t/{orgHandle}
|
|
5088
|
-
* - https://stage.asgardeo.io/t/{orgHandle}
|
|
5089
|
-
* - https://prod.asgardeo.io/t/{orgHandle}
|
|
5090
|
-
* - https://{subdomain}.asgardeo.io/t/{orgHandle}
|
|
5214
|
+
* Parses URLs following the `/t/{orgHandle}` pattern.
|
|
5091
5215
|
*
|
|
5092
5216
|
* @param baseUrl - The base URL of the ThunderID identity server
|
|
5093
5217
|
* @returns The extracted organization handle
|
|
@@ -5096,13 +5220,9 @@ var formatDate_default = formatDate;
|
|
|
5096
5220
|
*
|
|
5097
5221
|
* @example
|
|
5098
5222
|
* ```typescript
|
|
5099
|
-
*
|
|
5100
|
-
* const handle1 = deriveOrganizationHandleFromBaseUrl('https://dev.asgardeo.io/t/dxlab');
|
|
5223
|
+
* const handle = deriveOrganizationHandleFromBaseUrl('https://localhost:8090/t/dxlab');
|
|
5101
5224
|
* // Returns: 'dxlab'
|
|
5102
5225
|
*
|
|
5103
|
-
* const handle2 = deriveOrganizationHandleFromBaseUrl('https://stage.asgardeo.io/t/myorg');
|
|
5104
|
-
* // Returns: 'myorg'
|
|
5105
|
-
*
|
|
5106
5226
|
* // Custom domain - returns empty string with a warning
|
|
5107
5227
|
* const handle2 = deriveOrganizationHandleFromBaseUrl('https://custom.example.com/auth');
|
|
5108
5228
|
* // Returns: '' and logs a warning
|
|
@@ -5927,7 +6047,7 @@ var withVendorCSSClassPrefix_default = withVendorCSSClassPrefix;
|
|
|
5927
6047
|
//#endregion
|
|
5928
6048
|
//#region src/utils/transformBrandingPreferenceToTheme.ts
|
|
5929
6049
|
const extractColorValue = (colorVariant, preferDark = false) => {
|
|
5930
|
-
if (preferDark && colorVariant?.dark
|
|
6050
|
+
if (preferDark && colorVariant?.dark?.trim()) return colorVariant.dark;
|
|
5931
6051
|
return colorVariant?.main;
|
|
5932
6052
|
};
|
|
5933
6053
|
/**
|
|
@@ -5960,47 +6080,47 @@ const transformThemeVariant = (themeVariant, isDark = false) => {
|
|
|
5960
6080
|
background: {
|
|
5961
6081
|
body: {
|
|
5962
6082
|
dark: (colors?.background?.body)?.dark || (colors?.background?.body)?.main,
|
|
5963
|
-
main: extractColorValue(colors?.background?.body, isDark)
|
|
6083
|
+
main: extractColorValue(colors?.background?.body, isDark) ?? ""
|
|
5964
6084
|
},
|
|
5965
6085
|
dark: (colors?.background?.surface)?.dark || (colors?.background?.surface)?.main,
|
|
5966
|
-
disabled: extractColorValue(colors?.background?.surface, isDark),
|
|
5967
|
-
surface: extractColorValue(colors?.background?.surface, isDark)
|
|
6086
|
+
disabled: extractColorValue(colors?.background?.surface, isDark) ?? "",
|
|
6087
|
+
surface: extractColorValue(colors?.background?.surface, isDark) ?? ""
|
|
5968
6088
|
},
|
|
5969
|
-
border: colors?.outlined?.default,
|
|
6089
|
+
border: colors?.outlined?.default ?? "",
|
|
5970
6090
|
error: {
|
|
5971
|
-
contrastText: extractContrastText(colors?.alerts?.error),
|
|
6091
|
+
contrastText: extractContrastText(colors?.alerts?.error) ?? "",
|
|
5972
6092
|
dark: (colors?.alerts?.error)?.dark || (colors?.alerts?.error)?.main,
|
|
5973
|
-
main: extractColorValue(colors?.alerts?.error, isDark)
|
|
6093
|
+
main: extractColorValue(colors?.alerts?.error, isDark) ?? ""
|
|
5974
6094
|
},
|
|
5975
6095
|
info: {
|
|
5976
|
-
contrastText: extractContrastText(colors?.alerts?.info),
|
|
6096
|
+
contrastText: extractContrastText(colors?.alerts?.info) ?? "",
|
|
5977
6097
|
dark: (colors?.alerts?.info)?.dark || (colors?.alerts?.info)?.main,
|
|
5978
|
-
main: extractColorValue(colors?.alerts?.info, isDark)
|
|
6098
|
+
main: extractColorValue(colors?.alerts?.info, isDark) ?? ""
|
|
5979
6099
|
},
|
|
5980
6100
|
primary: {
|
|
5981
|
-
contrastText: extractContrastText(colors?.primary),
|
|
6101
|
+
contrastText: extractContrastText(colors?.primary) ?? "",
|
|
5982
6102
|
dark: colors?.primary?.dark || (colors?.primary)?.main,
|
|
5983
|
-
main: extractColorValue(colors?.primary, isDark)
|
|
6103
|
+
main: extractColorValue(colors?.primary, isDark) ?? ""
|
|
5984
6104
|
},
|
|
5985
6105
|
secondary: {
|
|
5986
|
-
contrastText: extractContrastText(colors?.secondary),
|
|
6106
|
+
contrastText: extractContrastText(colors?.secondary) ?? "",
|
|
5987
6107
|
dark: colors?.secondary?.dark || (colors?.secondary)?.main,
|
|
5988
|
-
main: extractColorValue(colors?.secondary, isDark)
|
|
6108
|
+
main: extractColorValue(colors?.secondary, isDark) ?? ""
|
|
5989
6109
|
},
|
|
5990
6110
|
success: {
|
|
5991
|
-
contrastText: extractContrastText(colors?.alerts?.neutral),
|
|
6111
|
+
contrastText: extractContrastText(colors?.alerts?.neutral) ?? "",
|
|
5992
6112
|
dark: (colors?.alerts?.neutral)?.dark || (colors?.alerts?.neutral)?.main,
|
|
5993
|
-
main: extractColorValue(colors?.alerts?.neutral, isDark)
|
|
6113
|
+
main: extractColorValue(colors?.alerts?.neutral, isDark) ?? ""
|
|
5994
6114
|
},
|
|
5995
6115
|
text: {
|
|
5996
6116
|
dark: (colors?.text)?.dark || (colors?.text)?.primary,
|
|
5997
|
-
primary: (colors?.text)?.primary,
|
|
5998
|
-
secondary: (colors?.text)?.secondary
|
|
6117
|
+
primary: (colors?.text)?.primary ?? "",
|
|
6118
|
+
secondary: (colors?.text)?.secondary ?? ""
|
|
5999
6119
|
},
|
|
6000
6120
|
warning: {
|
|
6001
|
-
contrastText: extractContrastText(colors?.alerts?.warning),
|
|
6121
|
+
contrastText: extractContrastText(colors?.alerts?.warning) ?? "",
|
|
6002
6122
|
dark: (colors?.alerts?.warning)?.dark || (colors?.alerts?.warning)?.main,
|
|
6003
|
-
main: extractColorValue(colors?.alerts?.warning, isDark)
|
|
6123
|
+
main: extractColorValue(colors?.alerts?.warning, isDark) ?? ""
|
|
6004
6124
|
}
|
|
6005
6125
|
},
|
|
6006
6126
|
images: {
|
|
@@ -6138,7 +6258,7 @@ var HttpClient = class HttpClient {
|
|
|
6138
6258
|
return (array) => callback(...array);
|
|
6139
6259
|
}
|
|
6140
6260
|
async requestHandler(config) {
|
|
6141
|
-
await this.attachToken(config);
|
|
6261
|
+
if (config.attachToken !== false) await this.attachToken(config);
|
|
6142
6262
|
if (config.shouldEncodeToFormData && config.data) {
|
|
6143
6263
|
const formData = new FormData();
|
|
6144
6264
|
Object.keys(config.data).forEach((key) => formData.append(key, config.data[key]));
|