@thunderid/javascript 0.3.0 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/StorageManager.d.ts +2 -2
- package/dist/StorageManager.d.ts.map +1 -1
- package/dist/ThunderIDJavaScriptClient.d.ts +2 -7
- package/dist/ThunderIDJavaScriptClient.d.ts.map +1 -1
- package/dist/api/{v2/executeEmbeddedRecoveryFlowV2.d.ts → executeEmbeddedRecoveryFlow.d.ts} +7 -7
- package/dist/api/executeEmbeddedRecoveryFlow.d.ts.map +1 -0
- package/dist/api/executeEmbeddedSignInFlow.d.ts +3 -3
- package/dist/api/executeEmbeddedSignInFlow.d.ts.map +1 -1
- package/dist/api/executeEmbeddedSignUpFlow.d.ts +4 -27
- package/dist/api/executeEmbeddedSignUpFlow.d.ts.map +1 -1
- package/dist/api/{v2/executeEmbeddedUserOnboardingFlowV2.d.ts → executeEmbeddedUserOnboardingFlow.d.ts} +6 -6
- package/dist/api/executeEmbeddedUserOnboardingFlow.d.ts.map +1 -0
- package/dist/api/getBrandingPreference.d.ts.map +1 -1
- package/dist/api/{v2/getFlowMetaV2.d.ts → getFlowMeta.d.ts} +7 -7
- package/dist/api/getFlowMeta.d.ts.map +1 -0
- package/dist/api/{v2/getOrganizationUnitChildren.d.ts → getOrganizationUnitChildren.d.ts} +1 -1
- package/dist/api/getOrganizationUnitChildren.d.ts.map +1 -0
- package/dist/cjs/index.cjs +1096 -1342
- package/dist/edge/index.js +1084 -1319
- package/dist/i18n/models/i18n.d.ts +3 -0
- package/dist/i18n/models/i18n.d.ts.map +1 -1
- package/dist/i18n/translations/en-US.d.ts.map +1 -1
- package/dist/i18n/translations/fr-FR.d.ts.map +1 -1
- package/dist/i18n/translations/hi-IN.d.ts.map +1 -1
- package/dist/i18n/translations/ja-JP.d.ts.map +1 -1
- package/dist/i18n/translations/pt-BR.d.ts.map +1 -1
- package/dist/i18n/translations/pt-PT.d.ts.map +1 -1
- package/dist/i18n/translations/si-LK.d.ts.map +1 -1
- package/dist/i18n/translations/ta-IN.d.ts.map +1 -1
- package/dist/i18n/translations/te-IN.d.ts.map +1 -1
- package/dist/index.d.ts +29 -36
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1084 -1319
- package/dist/models/client.d.ts +3 -28
- package/dist/models/client.d.ts.map +1 -1
- package/dist/models/config.d.ts +1 -1
- package/dist/models/config.d.ts.map +1 -1
- package/dist/models/embedded-flow.d.ts +572 -92
- package/dist/models/embedded-flow.d.ts.map +1 -1
- package/dist/models/{v2/embedded-recovery-flow-v2.d.ts → embedded-recovery-flow.d.ts} +2 -3
- package/dist/models/embedded-recovery-flow.d.ts.map +1 -0
- package/dist/models/embedded-signin-flow.d.ts +310 -66
- package/dist/models/embedded-signin-flow.d.ts.map +1 -1
- package/dist/models/{v2/embedded-signup-flow-v2.d.ts → embedded-signup-flow.d.ts} +4 -5
- package/dist/models/embedded-signup-flow.d.ts.map +1 -0
- package/dist/models/extensions/components.d.ts +55 -0
- package/dist/models/extensions/components.d.ts.map +1 -0
- package/dist/models/{v2/flow-meta-v2.d.ts → flow-meta.d.ts} +1 -1
- package/dist/models/flow-meta.d.ts.map +1 -0
- package/dist/models/organization-unit.d.ts.map +1 -0
- package/dist/models/translation.d.ts.map +1 -0
- package/dist/models/{v2/vars.d.ts → vars.d.ts} +1 -1
- package/dist/models/vars.d.ts.map +1 -0
- package/dist/utils/buildValidatorFromRules.d.ts +31 -0
- package/dist/utils/buildValidatorFromRules.d.ts.map +1 -0
- package/dist/utils/containsMetaFlowTemplateLiteral.d.ts.map +1 -0
- package/dist/utils/countryCodeToFlagEmoji.d.ts.map +1 -0
- package/dist/utils/evaluateValidationRule.d.ts +42 -0
- package/dist/utils/evaluateValidationRule.d.ts.map +1 -0
- package/dist/utils/extractEmojiFromUri.d.ts.map +1 -0
- package/dist/utils/getRedirectBasedSignUpUrl.d.ts +1 -1
- package/dist/utils/getRedirectBasedSignUpUrl.d.ts.map +1 -1
- package/dist/utils/injectRequestedPermissions.d.ts.map +1 -0
- package/dist/utils/isEmojiUri.d.ts.map +1 -0
- package/dist/utils/isMetaFlowTemplateLiteral.d.ts.map +1 -0
- package/dist/utils/isTranslationFlowTemplateLiteral.d.ts.map +1 -0
- package/dist/utils/parseApiErrorMessage.d.ts.map +1 -1
- package/dist/utils/parseFlowTemplateLiteral.d.ts.map +1 -0
- package/dist/utils/{v2/resolveFlowTemplateLiterals.d.ts → resolveFlowTemplateLiterals.d.ts} +2 -2
- package/dist/utils/resolveFlowTemplateLiterals.d.ts.map +1 -0
- package/dist/utils/resolveLocaleDisplayName.d.ts.map +1 -0
- package/dist/utils/resolveLocaleEmoji.d.ts.map +1 -0
- package/dist/utils/{v2/resolveMeta.d.ts → resolveMeta.d.ts} +1 -1
- package/dist/utils/resolveMeta.d.ts.map +1 -0
- package/package.json +7 -7
- package/dist/api/initializeEmbeddedSignInFlow.d.ts +0 -52
- package/dist/api/initializeEmbeddedSignInFlow.d.ts.map +0 -1
- package/dist/api/v2/executeEmbeddedRecoveryFlowV2.d.ts.map +0 -1
- package/dist/api/v2/executeEmbeddedSignInFlowV2.d.ts +0 -22
- package/dist/api/v2/executeEmbeddedSignInFlowV2.d.ts.map +0 -1
- package/dist/api/v2/executeEmbeddedSignUpFlowV2.d.ts +0 -22
- package/dist/api/v2/executeEmbeddedSignUpFlowV2.d.ts.map +0 -1
- package/dist/api/v2/executeEmbeddedUserOnboardingFlowV2.d.ts.map +0 -1
- package/dist/api/v2/getFlowMetaV2.d.ts.map +0 -1
- package/dist/api/v2/getOrganizationUnitChildren.d.ts.map +0 -1
- package/dist/constants/v2/OIDCDiscoveryConstants.d.ts +0 -40
- package/dist/constants/v2/OIDCDiscoveryConstants.d.ts.map +0 -1
- package/dist/models/platforms.d.ts +0 -33
- package/dist/models/platforms.d.ts.map +0 -1
- package/dist/models/v2/embedded-flow-v2.d.ts +0 -550
- package/dist/models/v2/embedded-flow-v2.d.ts.map +0 -1
- package/dist/models/v2/embedded-recovery-flow-v2.d.ts.map +0 -1
- package/dist/models/v2/embedded-signin-flow-v2.d.ts +0 -345
- package/dist/models/v2/embedded-signin-flow-v2.d.ts.map +0 -1
- package/dist/models/v2/embedded-signup-flow-v2.d.ts.map +0 -1
- package/dist/models/v2/extensions/components.d.ts +0 -89
- package/dist/models/v2/extensions/components.d.ts.map +0 -1
- package/dist/models/v2/flow-meta-v2.d.ts.map +0 -1
- package/dist/models/v2/organization-unit.d.ts.map +0 -1
- package/dist/models/v2/translation.d.ts.map +0 -1
- package/dist/models/v2/vars.d.ts.map +0 -1
- package/dist/utils/identifyPlatform.d.ts +0 -31
- package/dist/utils/identifyPlatform.d.ts.map +0 -1
- package/dist/utils/resolveFieldType.d.ts +0 -21
- package/dist/utils/resolveFieldType.d.ts.map +0 -1
- package/dist/utils/v2/containsMetaFlowTemplateLiteral.d.ts.map +0 -1
- package/dist/utils/v2/countryCodeToFlagEmoji.d.ts.map +0 -1
- package/dist/utils/v2/extractEmojiFromUri.d.ts.map +0 -1
- package/dist/utils/v2/injectRequestedPermissions.d.ts.map +0 -1
- package/dist/utils/v2/isEmojiUri.d.ts.map +0 -1
- package/dist/utils/v2/isMetaFlowTemplateLiteral.d.ts.map +0 -1
- package/dist/utils/v2/isTranslationFlowTemplateLiteral.d.ts.map +0 -1
- package/dist/utils/v2/parseFlowTemplateLiteral.d.ts.map +0 -1
- package/dist/utils/v2/resolveFlowTemplateLiterals.d.ts.map +0 -1
- package/dist/utils/v2/resolveLocaleDisplayName.d.ts.map +0 -1
- package/dist/utils/v2/resolveLocaleEmoji.d.ts.map +0 -1
- package/dist/utils/v2/resolveMeta.d.ts.map +0 -1
- /package/dist/models/{v2/organization-unit.d.ts → organization-unit.d.ts} +0 -0
- /package/dist/models/{v2/translation.d.ts → translation.d.ts} +0 -0
- /package/dist/utils/{v2/containsMetaFlowTemplateLiteral.d.ts → containsMetaFlowTemplateLiteral.d.ts} +0 -0
- /package/dist/utils/{v2/countryCodeToFlagEmoji.d.ts → countryCodeToFlagEmoji.d.ts} +0 -0
- /package/dist/utils/{v2/extractEmojiFromUri.d.ts → extractEmojiFromUri.d.ts} +0 -0
- /package/dist/utils/{v2/injectRequestedPermissions.d.ts → injectRequestedPermissions.d.ts} +0 -0
- /package/dist/utils/{v2/isEmojiUri.d.ts → isEmojiUri.d.ts} +0 -0
- /package/dist/utils/{v2/isMetaFlowTemplateLiteral.d.ts → isMetaFlowTemplateLiteral.d.ts} +0 -0
- /package/dist/utils/{v2/isTranslationFlowTemplateLiteral.d.ts → isTranslationFlowTemplateLiteral.d.ts} +0 -0
- /package/dist/utils/{v2/parseFlowTemplateLiteral.d.ts → parseFlowTemplateLiteral.d.ts} +0 -0
- /package/dist/utils/{v2/resolveLocaleDisplayName.d.ts → resolveLocaleDisplayName.d.ts} +0 -0
- /package/dist/utils/{v2/resolveLocaleEmoji.d.ts → resolveLocaleEmoji.d.ts} +0 -0
package/dist/edge/index.js
CHANGED
|
@@ -329,101 +329,91 @@ var ThunderIDAPIError = class extends ThunderIDError {
|
|
|
329
329
|
};
|
|
330
330
|
|
|
331
331
|
//#endregion
|
|
332
|
-
//#region src/
|
|
332
|
+
//#region src/models/embedded-signin-flow.ts
|
|
333
333
|
/**
|
|
334
|
-
*
|
|
334
|
+
* Status enumeration for ThunderID embedded sign-in flow operations.
|
|
335
335
|
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
336
|
+
* These statuses indicate the current state of the sign-in flow and determine
|
|
337
|
+
* the next action required by the client application. Each status provides
|
|
338
|
+
* specific guidance on how to proceed with the authentication process.
|
|
339
339
|
*
|
|
340
340
|
* @example
|
|
341
341
|
* ```typescript
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
* code_challenge_method: "S256"
|
|
353
|
-
* }
|
|
354
|
-
* });
|
|
355
|
-
* console.log(authResponse);
|
|
356
|
-
* } catch (error) {
|
|
357
|
-
* if (error instanceof ThunderIDAPIError) {
|
|
358
|
-
* console.error('Authorization failed:', error.message);
|
|
359
|
-
* }
|
|
342
|
+
* switch (response.flowStatus) {
|
|
343
|
+
* case EmbeddedSignInFlowStatus.Incomplete:
|
|
344
|
+
* // More user input needed - render form components
|
|
345
|
+
* break;
|
|
346
|
+
* case EmbeddedSignInFlowStatus.Complete:
|
|
347
|
+
* // Authentication successful - handle completion
|
|
348
|
+
* break;
|
|
349
|
+
* case EmbeddedSignInFlowStatus.Error:
|
|
350
|
+
* // Authentication failed - show error message
|
|
351
|
+
* break;
|
|
360
352
|
* }
|
|
361
353
|
* ```
|
|
354
|
+
*
|
|
355
|
+
* @experimental Part of the new ThunderID API
|
|
362
356
|
*/
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "executeEmbeddedSignInFlow-NetworkError-001", "javascript", 0, "Network Error");
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
var executeEmbeddedSignInFlow_default = executeEmbeddedSignInFlow;
|
|
357
|
+
let EmbeddedSignInFlowStatus = /* @__PURE__ */ function(EmbeddedSignInFlowStatus$1) {
|
|
358
|
+
/**
|
|
359
|
+
* Sign-in flow completed successfully.
|
|
360
|
+
*
|
|
361
|
+
* The user has been authenticated and the flow can proceed to
|
|
362
|
+
* OAuth2 completion or redirection. Check for redirectUrl or
|
|
363
|
+
* assertion data in the response.
|
|
364
|
+
*/
|
|
365
|
+
EmbeddedSignInFlowStatus$1["Complete"] = "COMPLETE";
|
|
366
|
+
/**
|
|
367
|
+
* Sign-in flow encountered an error.
|
|
368
|
+
*
|
|
369
|
+
* Authentication failed due to invalid credentials, system error,
|
|
370
|
+
* or other issues. Check error details in the response and handle
|
|
371
|
+
* appropriately (retry, show error message, etc.).
|
|
372
|
+
*/
|
|
373
|
+
EmbeddedSignInFlowStatus$1["Error"] = "ERROR";
|
|
374
|
+
/**
|
|
375
|
+
* Sign-in flow requires additional user input.
|
|
376
|
+
*
|
|
377
|
+
* More authentication steps are needed. The response will contain
|
|
378
|
+
* components in data.meta.components that should be rendered to
|
|
379
|
+
* collect additional user input (e.g., MFA, password, etc.).
|
|
380
|
+
*/
|
|
381
|
+
EmbeddedSignInFlowStatus$1["Incomplete"] = "INCOMPLETE";
|
|
382
|
+
return EmbeddedSignInFlowStatus$1;
|
|
383
|
+
}({});
|
|
384
|
+
/**
|
|
385
|
+
* Type enumeration for ThunderID embedded sign-in flow responses.
|
|
386
|
+
*
|
|
387
|
+
* Determines the nature of the flow response and how the client should
|
|
388
|
+
* handle the returned data. This affects both UI rendering and flow
|
|
389
|
+
* continuation logic.
|
|
390
|
+
*
|
|
391
|
+
* @experimental Part of the new ThunderID API
|
|
392
|
+
*/
|
|
393
|
+
let EmbeddedSignInFlowType = /* @__PURE__ */ function(EmbeddedSignInFlowType$1) {
|
|
394
|
+
/**
|
|
395
|
+
* Response requires external redirection.
|
|
396
|
+
*
|
|
397
|
+
* Used for social login providers, external identity providers,
|
|
398
|
+
* or other flows that require navigating to an external URL.
|
|
399
|
+
* The response will contain redirection information.
|
|
400
|
+
*/
|
|
401
|
+
EmbeddedSignInFlowType$1["Redirection"] = "REDIRECTION";
|
|
402
|
+
/**
|
|
403
|
+
* Response contains view components for rendering.
|
|
404
|
+
*
|
|
405
|
+
* Standard embedded flow response containing UI components
|
|
406
|
+
* that should be rendered within the current application
|
|
407
|
+
* context. Most common type for embedded authentication.
|
|
408
|
+
*/
|
|
409
|
+
EmbeddedSignInFlowType$1["View"] = "VIEW";
|
|
410
|
+
return EmbeddedSignInFlowType$1;
|
|
411
|
+
}({});
|
|
422
412
|
|
|
423
413
|
//#endregion
|
|
424
|
-
//#region src/
|
|
414
|
+
//#region src/utils/injectRequestedPermissions.ts
|
|
425
415
|
/**
|
|
426
|
-
* Copyright (c)
|
|
416
|
+
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
427
417
|
*
|
|
428
418
|
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
429
419
|
* Version 2.0 (the "License"); you may not use this file except
|
|
@@ -439,140 +429,286 @@ var executeEmbeddedSignInFlow_default = executeEmbeddedSignInFlow;
|
|
|
439
429
|
* specific language governing permissions and limitations
|
|
440
430
|
* under the License.
|
|
441
431
|
*/
|
|
442
|
-
let EmbeddedFlowType = /* @__PURE__ */ function(EmbeddedFlowType$1) {
|
|
443
|
-
EmbeddedFlowType$1["Authentication"] = "AUTHENTICATION";
|
|
444
|
-
EmbeddedFlowType$1["Recovery"] = "RECOVERY";
|
|
445
|
-
EmbeddedFlowType$1["Registration"] = "REGISTRATION";
|
|
446
|
-
EmbeddedFlowType$1["UserOnboarding"] = "USER_ONBOARDING";
|
|
447
|
-
return EmbeddedFlowType$1;
|
|
448
|
-
}({});
|
|
449
|
-
let EmbeddedFlowStatus = /* @__PURE__ */ function(EmbeddedFlowStatus$1) {
|
|
450
|
-
EmbeddedFlowStatus$1["Complete"] = "COMPLETE";
|
|
451
|
-
EmbeddedFlowStatus$1["Incomplete"] = "INCOMPLETE";
|
|
452
|
-
return EmbeddedFlowStatus$1;
|
|
453
|
-
}({});
|
|
454
|
-
let EmbeddedFlowResponseType = /* @__PURE__ */ function(EmbeddedFlowResponseType$1) {
|
|
455
|
-
EmbeddedFlowResponseType$1["Redirection"] = "REDIRECTION";
|
|
456
|
-
EmbeddedFlowResponseType$1["View"] = "VIEW";
|
|
457
|
-
return EmbeddedFlowResponseType$1;
|
|
458
|
-
}({});
|
|
459
|
-
let EmbeddedFlowComponentType = /* @__PURE__ */ function(EmbeddedFlowComponentType$2) {
|
|
460
|
-
EmbeddedFlowComponentType$2["Button"] = "BUTTON";
|
|
461
|
-
EmbeddedFlowComponentType$2["Checkbox"] = "CHECKBOX";
|
|
462
|
-
EmbeddedFlowComponentType$2["Divider"] = "DIVIDER";
|
|
463
|
-
EmbeddedFlowComponentType$2["Form"] = "FORM";
|
|
464
|
-
EmbeddedFlowComponentType$2["Image"] = "IMAGE";
|
|
465
|
-
EmbeddedFlowComponentType$2["Input"] = "INPUT";
|
|
466
|
-
EmbeddedFlowComponentType$2["Radio"] = "RADIO";
|
|
467
|
-
EmbeddedFlowComponentType$2["Select"] = "SELECT";
|
|
468
|
-
EmbeddedFlowComponentType$2["Typography"] = "TYPOGRAPHY";
|
|
469
|
-
return EmbeddedFlowComponentType$2;
|
|
470
|
-
}({});
|
|
471
|
-
|
|
472
|
-
//#endregion
|
|
473
|
-
//#region src/api/executeEmbeddedSignUpFlow.ts
|
|
474
432
|
/**
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* @param requestConfig - Request configuration object containing URL and payload.
|
|
478
|
-
* @returns A promise that resolves with the flow execution response.
|
|
479
|
-
* @throws ThunderIDAPIError when the request fails or URL is invalid.
|
|
433
|
+
* Strips the top-level `scopes` field from a payload and injects it as
|
|
434
|
+
* `inputs.requested_permissions` (space-separated string).
|
|
480
435
|
*
|
|
481
|
-
*
|
|
482
|
-
* ```typescript
|
|
483
|
-
* try {
|
|
484
|
-
* const embeddedSignUpResponse = await executeEmbeddedSignUpFlow({
|
|
485
|
-
* url: "https://localhost:8090/api/server/v1/flow/execute",
|
|
486
|
-
* payload: {
|
|
487
|
-
* flowType: "REGISTRATION"
|
|
488
|
-
* }
|
|
489
|
-
* });
|
|
490
|
-
* console.log(embeddedSignUpResponse);
|
|
491
|
-
* } catch (error) {
|
|
492
|
-
* if (error instanceof ThunderIDAPIError) {
|
|
493
|
-
* console.error('Embedded SignUp flow execution failed:', error.message);
|
|
494
|
-
* }
|
|
495
|
-
* }
|
|
496
|
-
* ```
|
|
436
|
+
* The backend reads requested_permissions from UserInputs (the `inputs` map), not a top-level field.
|
|
497
437
|
*/
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
438
|
+
const injectRequestedPermissions = (payload) => {
|
|
439
|
+
const { scopes,...rest } = payload;
|
|
440
|
+
const normalizedScopes = Array.isArray(scopes) ? scopes.map((s) => String(s).trim()).filter(Boolean).join(" ") : typeof scopes === "string" ? scopes.trim() : "";
|
|
441
|
+
if (!normalizedScopes) return rest;
|
|
442
|
+
const existingInputs = rest["inputs"] != null && typeof rest["inputs"] === "object" && !Array.isArray(rest["inputs"]) ? rest["inputs"] : {};
|
|
443
|
+
return {
|
|
444
|
+
...rest,
|
|
445
|
+
inputs: {
|
|
446
|
+
...existingInputs,
|
|
447
|
+
requested_permissions: normalizedScopes
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
};
|
|
451
|
+
var injectRequestedPermissions_default = injectRequestedPermissions;
|
|
452
|
+
|
|
453
|
+
//#endregion
|
|
454
|
+
//#region src/api/executeEmbeddedSignInFlow.ts
|
|
455
|
+
const executeEmbeddedSignInFlow = async ({ url, baseUrl, payload, authId,...requestConfig }) => {
|
|
456
|
+
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.");
|
|
457
|
+
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
458
|
+
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
459
|
+
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
460
|
+
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
461
|
+
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
462
|
+
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
463
|
+
...basePayload,
|
|
464
|
+
verbose: true
|
|
465
|
+
} : basePayload;
|
|
466
|
+
const response = await fetch(endpoint, {
|
|
467
|
+
...requestConfig,
|
|
468
|
+
body: JSON.stringify(requestPayload),
|
|
469
|
+
headers: {
|
|
470
|
+
Accept: "application/json",
|
|
471
|
+
"Content-Type": "application/json",
|
|
472
|
+
...requestConfig.headers
|
|
473
|
+
},
|
|
474
|
+
method: requestConfig.method || "POST"
|
|
475
|
+
});
|
|
476
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedSignInFlow-ResponseError-001", "javascript", response.status, response.statusText, "Authorization request failed");
|
|
477
|
+
const flowResponse = await response.json();
|
|
478
|
+
if (flowResponse.flowStatus === EmbeddedSignInFlowStatus.Complete && flowResponse.assertion && authId) try {
|
|
479
|
+
const oauth2Response = await fetch(`${baseUrl}/oauth2/auth/callback`, {
|
|
508
480
|
body: JSON.stringify({
|
|
509
|
-
|
|
510
|
-
|
|
481
|
+
assertion: flowResponse.assertion,
|
|
482
|
+
authId
|
|
511
483
|
}),
|
|
484
|
+
credentials: "include",
|
|
512
485
|
headers: {
|
|
513
486
|
Accept: "application/json",
|
|
514
487
|
"Content-Type": "application/json",
|
|
515
488
|
...requestConfig.headers
|
|
516
489
|
},
|
|
517
|
-
method:
|
|
490
|
+
method: "POST"
|
|
518
491
|
});
|
|
519
|
-
if (!
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
492
|
+
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignInFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
493
|
+
const oauth2Result = await oauth2Response.json();
|
|
494
|
+
return {
|
|
495
|
+
flowStatus: flowResponse.flowStatus,
|
|
496
|
+
redirectUrl: oauth2Result["redirect_uri"]
|
|
497
|
+
};
|
|
498
|
+
} catch (authError) {
|
|
499
|
+
if (authError instanceof ThunderIDAPIError) throw authError;
|
|
500
|
+
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");
|
|
524
501
|
}
|
|
502
|
+
return flowResponse;
|
|
525
503
|
};
|
|
526
|
-
var
|
|
504
|
+
var executeEmbeddedSignInFlow_default = executeEmbeddedSignInFlow;
|
|
527
505
|
|
|
528
506
|
//#endregion
|
|
529
|
-
//#region src/
|
|
507
|
+
//#region src/models/embedded-signup-flow.ts
|
|
530
508
|
/**
|
|
531
|
-
*
|
|
509
|
+
* Status enumeration for ThunderID embedded sign-up flow operations.
|
|
532
510
|
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
511
|
+
* These statuses indicate the current state of the registration flow and determine
|
|
512
|
+
* the next action required by the client application. Each status provides specific
|
|
513
|
+
* guidance on how to proceed with the user registration process.
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```typescript
|
|
517
|
+
* switch (response.flowStatus) {
|
|
518
|
+
* case EmbeddedSignUpFlowStatus.Incomplete:
|
|
519
|
+
* // More user input needed - render registration form components
|
|
520
|
+
* break;
|
|
521
|
+
* case EmbeddedSignUpFlowStatus.Complete:
|
|
522
|
+
* // Registration successful - handle completion
|
|
523
|
+
* break;
|
|
524
|
+
* case EmbeddedSignUpFlowStatus.Error:
|
|
525
|
+
* // Registration failed - show error details
|
|
526
|
+
* const errorResponse = response as EmbeddedSignUpFlowErrorResponse;
|
|
527
|
+
* showError(errorResponse.error.description.defaultValue);
|
|
528
|
+
* break;
|
|
544
529
|
* }
|
|
545
530
|
* ```
|
|
531
|
+
*
|
|
532
|
+
* @experimental Part of the new ThunderID API
|
|
546
533
|
*/
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
534
|
+
let EmbeddedSignUpFlowStatus = /* @__PURE__ */ function(EmbeddedSignUpFlowStatus$1) {
|
|
535
|
+
/**
|
|
536
|
+
* Sign-up flow completed successfully.
|
|
537
|
+
*
|
|
538
|
+
* The user has successfully registered and the flow can proceed to
|
|
539
|
+
* OAuth2 completion or redirection. Check for redirectUrl or assertion
|
|
540
|
+
* data in the response for next steps.
|
|
541
|
+
*/
|
|
542
|
+
EmbeddedSignUpFlowStatus$1["Complete"] = "COMPLETE";
|
|
543
|
+
/**
|
|
544
|
+
* Sign-up flow encountered an error and cannot proceed.
|
|
545
|
+
*
|
|
546
|
+
* Registration failed due to validation errors, duplicate user,
|
|
547
|
+
* system errors, or other issues. The response will be of type
|
|
548
|
+
* `EmbeddedSignUpFlowErrorResponse` containing detailed failure
|
|
549
|
+
* information that can be displayed to the user.
|
|
550
|
+
*
|
|
551
|
+
* @see {@link EmbeddedSignUpFlowErrorResponse} for error response structure
|
|
552
|
+
*/
|
|
553
|
+
EmbeddedSignUpFlowStatus$1["Error"] = "ERROR";
|
|
554
|
+
/**
|
|
555
|
+
* Sign-up flow requires additional user input.
|
|
556
|
+
*
|
|
557
|
+
* More registration steps are needed. The response will contain
|
|
558
|
+
* components in data.meta.components that should be rendered to
|
|
559
|
+
* collect additional user information (e.g., profile data, verification).
|
|
560
|
+
*/
|
|
561
|
+
EmbeddedSignUpFlowStatus$1["Incomplete"] = "INCOMPLETE";
|
|
562
|
+
return EmbeddedSignUpFlowStatus$1;
|
|
563
|
+
}({});
|
|
564
|
+
/**
|
|
565
|
+
* Type enumeration for ThunderID embedded sign-up flow responses.
|
|
566
|
+
*
|
|
567
|
+
* Determines the nature of the registration flow response and how the client
|
|
568
|
+
* should handle the returned data. This affects both UI rendering and flow
|
|
569
|
+
* continuation logic during the user registration process.
|
|
570
|
+
*
|
|
571
|
+
* @experimental Part of the new ThunderID API
|
|
572
|
+
*/
|
|
573
|
+
let EmbeddedSignUpFlowType = /* @__PURE__ */ function(EmbeddedSignUpFlowType$1) {
|
|
574
|
+
/**
|
|
575
|
+
* Response requires external redirection.
|
|
576
|
+
*
|
|
577
|
+
* Used for social registration providers, external identity providers,
|
|
578
|
+
* or other flows that require navigating to an external URL during
|
|
579
|
+
* the registration process. The response will contain redirection information.
|
|
580
|
+
*/
|
|
581
|
+
EmbeddedSignUpFlowType$1["Redirection"] = "REDIRECTION";
|
|
582
|
+
/**
|
|
583
|
+
* Response contains view components for rendering.
|
|
584
|
+
*
|
|
585
|
+
* Standard embedded registration flow response containing UI components
|
|
586
|
+
* that should be rendered within the current application context.
|
|
587
|
+
* Most common type for embedded user registration.
|
|
588
|
+
*/
|
|
589
|
+
EmbeddedSignUpFlowType$1["View"] = "VIEW";
|
|
590
|
+
return EmbeddedSignUpFlowType$1;
|
|
591
|
+
}({});
|
|
592
|
+
|
|
593
|
+
//#endregion
|
|
594
|
+
//#region src/api/executeEmbeddedSignUpFlow.ts
|
|
595
|
+
const executeEmbeddedSignUpFlow = async ({ url, baseUrl, payload, authId,...requestConfig }) => {
|
|
596
|
+
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.");
|
|
597
|
+
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
598
|
+
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
599
|
+
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
600
|
+
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
601
|
+
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
602
|
+
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
603
|
+
...basePayload,
|
|
604
|
+
verbose: true
|
|
605
|
+
} : basePayload;
|
|
606
|
+
const response = await fetch(endpoint, {
|
|
607
|
+
...requestConfig,
|
|
608
|
+
body: JSON.stringify(requestPayload),
|
|
609
|
+
headers: {
|
|
610
|
+
Accept: "application/json",
|
|
611
|
+
"Content-Type": "application/json",
|
|
612
|
+
...requestConfig.headers
|
|
613
|
+
},
|
|
614
|
+
method: requestConfig.method || "POST"
|
|
615
|
+
});
|
|
616
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedSignUpFlow-ResponseError-001", "javascript", response.status, response.statusText, "Registration request failed");
|
|
617
|
+
const flowResponse = await response.json();
|
|
618
|
+
if (flowResponse.flowStatus === EmbeddedSignUpFlowStatus.Complete && flowResponse.assertion && authId) try {
|
|
619
|
+
const oauth2Response = await fetch(`${baseUrl}/oauth2/auth/callback`, {
|
|
620
|
+
body: JSON.stringify({
|
|
621
|
+
assertion: flowResponse.assertion,
|
|
622
|
+
authId
|
|
623
|
+
}),
|
|
624
|
+
credentials: "include",
|
|
556
625
|
headers: {
|
|
557
626
|
Accept: "application/json",
|
|
558
627
|
"Content-Type": "application/json",
|
|
559
628
|
...requestConfig.headers
|
|
560
629
|
},
|
|
561
|
-
method: "
|
|
630
|
+
method: "POST"
|
|
562
631
|
});
|
|
563
|
-
if (!
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
632
|
+
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignUpFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
633
|
+
const oauth2Result = await oauth2Response.json();
|
|
634
|
+
return {
|
|
635
|
+
flowStatus: flowResponse.flowStatus,
|
|
636
|
+
redirectUrl: oauth2Result["redirect_uri"]
|
|
637
|
+
};
|
|
638
|
+
} catch (authError) {
|
|
639
|
+
if (authError instanceof ThunderIDAPIError) throw authError;
|
|
640
|
+
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");
|
|
568
641
|
}
|
|
642
|
+
return flowResponse;
|
|
569
643
|
};
|
|
570
|
-
var
|
|
644
|
+
var executeEmbeddedSignUpFlow_default = executeEmbeddedSignUpFlow;
|
|
571
645
|
|
|
572
646
|
//#endregion
|
|
573
|
-
//#region src/
|
|
647
|
+
//#region src/api/executeEmbeddedRecoveryFlow.ts
|
|
574
648
|
/**
|
|
575
|
-
*
|
|
649
|
+
* Executes an embedded recovery flow by sending a request to the flow execution endpoint.
|
|
650
|
+
*
|
|
651
|
+
* This function handles password-recovery and account-recovery flows driven by the
|
|
652
|
+
* ThunderID server. The server returns UI components for each step (e.g. username
|
|
653
|
+
* collection, OTP verification, password reset) and this function forwards the
|
|
654
|
+
* user's responses back to the server.
|
|
655
|
+
*
|
|
656
|
+
* @param requestConfig - Request configuration containing URL, payload, and optional headers.
|
|
657
|
+
* @returns A promise that resolves with the flow execution response.
|
|
658
|
+
* @throws ThunderIDAPIError when the request fails or a payload is missing.
|
|
659
|
+
*
|
|
660
|
+
* @example
|
|
661
|
+
* ```typescript
|
|
662
|
+
* // Initiate recovery flow
|
|
663
|
+
* const response = await executeEmbeddedRecoveryFlow({
|
|
664
|
+
* baseUrl: 'https://localhost:8090',
|
|
665
|
+
* payload: {
|
|
666
|
+
* flowType: 'RECOVERY',
|
|
667
|
+
* applicationId: 'my-app-id',
|
|
668
|
+
* },
|
|
669
|
+
* });
|
|
670
|
+
*
|
|
671
|
+
* // Continue recovery flow with user input
|
|
672
|
+
* const nextResponse = await executeEmbeddedRecoveryFlow({
|
|
673
|
+
* baseUrl: 'https://localhost:8090',
|
|
674
|
+
* payload: {
|
|
675
|
+
* executionId: response.executionId,
|
|
676
|
+
* action: 'submit',
|
|
677
|
+
* inputs: { username: 'user@example.com' },
|
|
678
|
+
* challengeToken: response.challengeToken,
|
|
679
|
+
* },
|
|
680
|
+
* });
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
const executeEmbeddedRecoveryFlow = async ({ url, baseUrl, payload,...requestConfig }) => {
|
|
684
|
+
if (!payload) throw new ThunderIDAPIError("Recovery payload is required", "executeEmbeddedRecoveryFlow-ValidationError-002", "javascript", 400, "If a recovery payload is not provided, the request cannot be constructed correctly.");
|
|
685
|
+
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
686
|
+
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
687
|
+
const hasOnlyAppIdAndFlowType = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload && Object.keys(cleanPayload).length === 2;
|
|
688
|
+
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
689
|
+
const requestPayload = hasOnlyAppIdAndFlowType || hasOnlyFlowId ? {
|
|
690
|
+
...cleanPayload,
|
|
691
|
+
verbose: true
|
|
692
|
+
} : cleanPayload;
|
|
693
|
+
const response = await fetch(endpoint, {
|
|
694
|
+
...requestConfig,
|
|
695
|
+
body: JSON.stringify(requestPayload),
|
|
696
|
+
headers: {
|
|
697
|
+
Accept: "application/json",
|
|
698
|
+
"Content-Type": "application/json",
|
|
699
|
+
...requestConfig.headers
|
|
700
|
+
},
|
|
701
|
+
method: requestConfig.method || "POST"
|
|
702
|
+
});
|
|
703
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedRecoveryFlow-ResponseError-001", "javascript", response.status, response.statusText, "Recovery request failed");
|
|
704
|
+
return await response.json();
|
|
705
|
+
};
|
|
706
|
+
var executeEmbeddedRecoveryFlow_default = executeEmbeddedRecoveryFlow;
|
|
707
|
+
|
|
708
|
+
//#endregion
|
|
709
|
+
//#region src/models/embedded-flow.ts
|
|
710
|
+
/**
|
|
711
|
+
* Copyright (c) 2025-2026, WSO2 LLC. (https://www.wso2.com).
|
|
576
712
|
*
|
|
577
713
|
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
578
714
|
* Version 2.0 (the "License"); you may not use this file except
|
|
@@ -588,174 +724,476 @@ var getUserInfo_default = getUserInfo;
|
|
|
588
724
|
* specific language governing permissions and limitations
|
|
589
725
|
* under the License.
|
|
590
726
|
*/
|
|
727
|
+
let EmbeddedFlowType = /* @__PURE__ */ function(EmbeddedFlowType$1) {
|
|
728
|
+
EmbeddedFlowType$1["Authentication"] = "AUTHENTICATION";
|
|
729
|
+
EmbeddedFlowType$1["Recovery"] = "RECOVERY";
|
|
730
|
+
EmbeddedFlowType$1["Registration"] = "REGISTRATION";
|
|
731
|
+
EmbeddedFlowType$1["UserOnboarding"] = "USER_ONBOARDING";
|
|
732
|
+
return EmbeddedFlowType$1;
|
|
733
|
+
}({});
|
|
734
|
+
let EmbeddedFlowResponseType = /* @__PURE__ */ function(EmbeddedFlowResponseType$1) {
|
|
735
|
+
EmbeddedFlowResponseType$1["Redirection"] = "REDIRECTION";
|
|
736
|
+
EmbeddedFlowResponseType$1["View"] = "VIEW";
|
|
737
|
+
return EmbeddedFlowResponseType$1;
|
|
738
|
+
}({});
|
|
591
739
|
/**
|
|
592
|
-
*
|
|
593
|
-
* Matches patterns like "DEFAULT/", "ASGARDEO_USER/", "PRIMARY/", etc.
|
|
594
|
-
* The pattern matches any uppercase letters, numbers, and underscores followed by a forward slash.
|
|
595
|
-
*/
|
|
596
|
-
const USERSTORE_PREFIX_REGEX = /^[A-Z_][A-Z0-9_]*\//;
|
|
597
|
-
/**
|
|
598
|
-
* Removes userstore prefixes from a username if they exist.
|
|
599
|
-
* This is commonly used to clean usernames returned from SCIM2 endpoints
|
|
600
|
-
* that include userstore prefixes like "DEFAULT/", "ASGARDEO_USER/", "PRIMARY/", etc.
|
|
740
|
+
* Component types supported by the ThunderID embedded flow API.
|
|
601
741
|
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
742
|
+
* These types define the different UI components that can be rendered
|
|
743
|
+
* as part of the embedded authentication flows. Each type corresponds
|
|
744
|
+
* to a specific UI element with its own behavior and properties.
|
|
604
745
|
*
|
|
605
746
|
* @example
|
|
606
747
|
* ```typescript
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
* const primaryUser = removeUserstorePrefix("PRIMARY/admin");
|
|
614
|
-
* console.log(primaryUser); // "admin"
|
|
615
|
-
*
|
|
616
|
-
* const alreadyClean = removeUserstorePrefix("user.name");
|
|
617
|
-
* console.log(alreadyClean); // "user.name"
|
|
618
|
-
*
|
|
619
|
-
* const emptyInput = removeUserstorePrefix("");
|
|
620
|
-
* console.log(emptyInput); // ""
|
|
748
|
+
* // Check component type to render appropriate UI
|
|
749
|
+
* if (component.type === EmbeddedFlowComponentType.TextInput) {
|
|
750
|
+
* // Render text input field
|
|
751
|
+
* } else if (component.type === EmbeddedFlowComponentType.Action) {
|
|
752
|
+
* // Render button/action
|
|
753
|
+
* }
|
|
621
754
|
* ```
|
|
755
|
+
*
|
|
756
|
+
* @experimental This API may change in future versions
|
|
622
757
|
*/
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
758
|
+
let EmbeddedFlowComponentType = /* @__PURE__ */ function(EmbeddedFlowComponentType$1) {
|
|
759
|
+
/** Interactive action component (buttons, links) for user interactions */
|
|
760
|
+
EmbeddedFlowComponentType$1["Action"] = "ACTION";
|
|
761
|
+
/** Container block component that groups other components */
|
|
762
|
+
EmbeddedFlowComponentType$1["Block"] = "BLOCK";
|
|
763
|
+
/** Consent component for displaying consent purposes and attributes */
|
|
764
|
+
EmbeddedFlowComponentType$1["Consent"] = "CONSENT";
|
|
765
|
+
/** Copyable text display component that shows text with a copy-to-clipboard action */
|
|
766
|
+
EmbeddedFlowComponentType$1["CopyableText"] = "COPYABLE_TEXT";
|
|
767
|
+
/** Date input field for selecting a calendar date */
|
|
768
|
+
EmbeddedFlowComponentType$1["DateInput"] = "DATE_INPUT";
|
|
769
|
+
/** Divider component for visual separation of content */
|
|
770
|
+
EmbeddedFlowComponentType$1["Divider"] = "DIVIDER";
|
|
771
|
+
/** Email input field with validation for email addresses. */
|
|
772
|
+
EmbeddedFlowComponentType$1["EmailInput"] = "EMAIL_INPUT";
|
|
773
|
+
/** Icon display component for rendering named vector icons */
|
|
774
|
+
EmbeddedFlowComponentType$1["Icon"] = "ICON";
|
|
775
|
+
/** Image display component for logos and illustrations */
|
|
776
|
+
EmbeddedFlowComponentType$1["Image"] = "IMAGE";
|
|
777
|
+
/** One-time password input field for multi-factor authentication */
|
|
778
|
+
EmbeddedFlowComponentType$1["OtpInput"] = "OTP_INPUT";
|
|
779
|
+
/** Organization unit tree picker for selecting an OU */
|
|
780
|
+
EmbeddedFlowComponentType$1["OuSelect"] = "OU_SELECT";
|
|
781
|
+
/** Password input field with masking for sensitive data */
|
|
782
|
+
EmbeddedFlowComponentType$1["PasswordInput"] = "PASSWORD_INPUT";
|
|
783
|
+
/** Phone number input field with country code support */
|
|
784
|
+
EmbeddedFlowComponentType$1["PhoneInput"] = "PHONE_INPUT";
|
|
785
|
+
/** Rich text display component that renders formatted HTML content */
|
|
786
|
+
EmbeddedFlowComponentType$1["RichText"] = "RICH_TEXT";
|
|
787
|
+
/** Select/dropdown input component for single choice selection */
|
|
788
|
+
EmbeddedFlowComponentType$1["Select"] = "SELECT";
|
|
789
|
+
/** Stack layout component for arranging children in a row or column */
|
|
790
|
+
EmbeddedFlowComponentType$1["Stack"] = "STACK";
|
|
791
|
+
/** Text display component for labels, headings, and messages */
|
|
792
|
+
EmbeddedFlowComponentType$1["Text"] = "TEXT";
|
|
793
|
+
/** Standard text input field for user data entry */
|
|
794
|
+
EmbeddedFlowComponentType$1["TextInput"] = "TEXT_INPUT";
|
|
795
|
+
/** Timer component for displaying a countdown */
|
|
796
|
+
EmbeddedFlowComponentType$1["Timer"] = "TIMER";
|
|
797
|
+
/** QR code display component for wallet-based flows (e.g. OpenID4VP) */
|
|
798
|
+
EmbeddedFlowComponentType$1["QrCode"] = "QR_CODE";
|
|
799
|
+
return EmbeddedFlowComponentType$1;
|
|
800
|
+
}({});
|
|
627
801
|
/**
|
|
628
|
-
*
|
|
629
|
-
* This is a helper function for processing user objects returned from SCIM2 endpoints.
|
|
630
|
-
* Handles various username field variations: username, userName, and user_name.
|
|
631
|
-
*
|
|
632
|
-
* @param user - The user object to process
|
|
633
|
-
* @returns The user object with processed username fields
|
|
634
|
-
*
|
|
635
|
-
* @example
|
|
636
|
-
* ```typescript
|
|
637
|
-
* const user = { username: "DEFAULT/john.doe", email: "john@example.com" };
|
|
638
|
-
* const processedUser = processUserUsername(user);
|
|
639
|
-
* console.log(processedUser.username); // "john.doe"
|
|
802
|
+
* Action variant types for buttons and interactive elements.
|
|
640
803
|
*
|
|
641
|
-
*
|
|
642
|
-
|
|
643
|
-
|
|
804
|
+
* @experimental This API may change in future versions
|
|
805
|
+
*/
|
|
806
|
+
let EmbeddedFlowActionVariant = /* @__PURE__ */ function(EmbeddedFlowActionVariant$1) {
|
|
807
|
+
/** Danger action button for destructive operations */
|
|
808
|
+
EmbeddedFlowActionVariant$1["Danger"] = "DANGER";
|
|
809
|
+
/** Info action button for informational purposes */
|
|
810
|
+
EmbeddedFlowActionVariant$1["Info"] = "INFO";
|
|
811
|
+
/** Link-styled action button */
|
|
812
|
+
EmbeddedFlowActionVariant$1["Link"] = "LINK";
|
|
813
|
+
/** Outlined action button for secondary emphasis */
|
|
814
|
+
EmbeddedFlowActionVariant$1["Outlined"] = "OUTLINED";
|
|
815
|
+
/** Primary action button with highest visual emphasis */
|
|
816
|
+
EmbeddedFlowActionVariant$1["Primary"] = "PRIMARY";
|
|
817
|
+
/** Secondary action button with moderate visual emphasis */
|
|
818
|
+
EmbeddedFlowActionVariant$1["Secondary"] = "SECONDARY";
|
|
819
|
+
/** Success action button for positive confirmations */
|
|
820
|
+
EmbeddedFlowActionVariant$1["Success"] = "SUCCESS";
|
|
821
|
+
/** Tertiary action button with minimal visual emphasis */
|
|
822
|
+
EmbeddedFlowActionVariant$1["Tertiary"] = "TERTIARY";
|
|
823
|
+
/** Warning action button for cautionary actions */
|
|
824
|
+
EmbeddedFlowActionVariant$1["Warning"] = "WARNING";
|
|
825
|
+
return EmbeddedFlowActionVariant$1;
|
|
826
|
+
}({});
|
|
827
|
+
/**
|
|
828
|
+
* Text variant types for typography components.
|
|
644
829
|
*
|
|
645
|
-
*
|
|
646
|
-
* const processedSnakeCaseUser = processUserUsername(snakeCaseUser);
|
|
647
|
-
* console.log(processedSnakeCaseUser.user_name); // "admin"
|
|
648
|
-
* ```
|
|
830
|
+
* @experimental This API may change in future versions
|
|
649
831
|
*/
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
832
|
+
let EmbeddedFlowTextVariant = /* @__PURE__ */ function(EmbeddedFlowTextVariant$1) {
|
|
833
|
+
/** Primary body text for main content */
|
|
834
|
+
EmbeddedFlowTextVariant$1["Body1"] = "BODY_1";
|
|
835
|
+
/** Secondary body text for supplementary content */
|
|
836
|
+
EmbeddedFlowTextVariant$1["Body2"] = "BODY_2";
|
|
837
|
+
/** Text styled for button labels */
|
|
838
|
+
EmbeddedFlowTextVariant$1["ButtonText"] = "BUTTON_TEXT";
|
|
839
|
+
/** Small caption text for annotations and descriptions */
|
|
840
|
+
EmbeddedFlowTextVariant$1["Caption"] = "CAPTION";
|
|
841
|
+
/** Largest heading level for main titles */
|
|
842
|
+
EmbeddedFlowTextVariant$1["Heading1"] = "HEADING_1";
|
|
843
|
+
/** Second level heading for major sections */
|
|
844
|
+
EmbeddedFlowTextVariant$1["Heading2"] = "HEADING_2";
|
|
845
|
+
/** Third level heading for subsections */
|
|
846
|
+
EmbeddedFlowTextVariant$1["Heading3"] = "HEADING_3";
|
|
847
|
+
/** Fourth level heading for minor sections */
|
|
848
|
+
EmbeddedFlowTextVariant$1["Heading4"] = "HEADING_4";
|
|
849
|
+
/** Fifth level heading for detailed sections */
|
|
850
|
+
EmbeddedFlowTextVariant$1["Heading5"] = "HEADING_5";
|
|
851
|
+
/** Smallest heading level for fine-grained sections */
|
|
852
|
+
EmbeddedFlowTextVariant$1["Heading6"] = "HEADING_6";
|
|
853
|
+
/** Overline text for labels and categories */
|
|
854
|
+
EmbeddedFlowTextVariant$1["Overline"] = "OVERLINE";
|
|
855
|
+
/** Primary subtitle text with larger emphasis */
|
|
856
|
+
EmbeddedFlowTextVariant$1["Subtitle1"] = "SUBTITLE_1";
|
|
857
|
+
/** Secondary subtitle text with moderate emphasis */
|
|
858
|
+
EmbeddedFlowTextVariant$1["Subtitle2"] = "SUBTITLE_2";
|
|
859
|
+
return EmbeddedFlowTextVariant$1;
|
|
860
|
+
}({});
|
|
861
|
+
/**
|
|
862
|
+
* Event types for action components.
|
|
863
|
+
*
|
|
864
|
+
* @experimental This API may change in future versions
|
|
865
|
+
*/
|
|
866
|
+
let EmbeddedFlowEventType = /* @__PURE__ */ function(EmbeddedFlowEventType$1) {
|
|
867
|
+
/** Navigate back to the previous step */
|
|
868
|
+
EmbeddedFlowEventType$1["Back"] = "BACK";
|
|
869
|
+
/** Cancel the current operation */
|
|
870
|
+
EmbeddedFlowEventType$1["Cancel"] = "CANCEL";
|
|
871
|
+
/** Navigate to a different flow step or page */
|
|
872
|
+
EmbeddedFlowEventType$1["Navigate"] = "NAVIGATE";
|
|
873
|
+
/** Reset form fields to initial state */
|
|
874
|
+
EmbeddedFlowEventType$1["Reset"] = "RESET";
|
|
875
|
+
/** Submit form data to the server */
|
|
876
|
+
EmbeddedFlowEventType$1["Submit"] = "SUBMIT";
|
|
877
|
+
/** Trigger an action or event */
|
|
878
|
+
EmbeddedFlowEventType$1["Trigger"] = "TRIGGER";
|
|
879
|
+
return EmbeddedFlowEventType$1;
|
|
880
|
+
}({});
|
|
659
881
|
|
|
660
882
|
//#endregion
|
|
661
|
-
//#region src/api/
|
|
883
|
+
//#region src/api/executeEmbeddedUserOnboardingFlow.ts
|
|
662
884
|
/**
|
|
663
|
-
*
|
|
885
|
+
* Executes an embedded user onboarding flow by sending a request to the flow execution endpoint.
|
|
886
|
+
*
|
|
887
|
+
* This function handles both:
|
|
888
|
+
* - Admin flow: Initiates onboarding, collects user details, generates invite link
|
|
889
|
+
* - End-user flow: Validates invite token and allows password setting
|
|
890
|
+
*
|
|
891
|
+
* @param requestConfig - Request configuration object containing URL, payload, and optional auth token.
|
|
892
|
+
* @returns A promise that resolves with the flow execution response.
|
|
893
|
+
* @throws ThunderIDAPIError when the request fails or URL is invalid.
|
|
664
894
|
*
|
|
665
|
-
* @param config - Request configuration object.
|
|
666
|
-
* @returns A promise that resolves with the user profile information.
|
|
667
895
|
* @example
|
|
668
896
|
* ```typescript
|
|
669
|
-
* //
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
*
|
|
676
|
-
*
|
|
677
|
-
* console.error('Failed to get user profile:', error.message);
|
|
897
|
+
* // Admin initiating user onboarding (requires auth token)
|
|
898
|
+
* const response = await executeEmbeddedUserOnboardingFlow({
|
|
899
|
+
* baseUrl: "https://api.thunder.io",
|
|
900
|
+
* payload: {
|
|
901
|
+
* flowType: "USER_ONBOARDING"
|
|
902
|
+
* },
|
|
903
|
+
* headers: {
|
|
904
|
+
* Authorization: `Bearer ${accessToken}`
|
|
678
905
|
* }
|
|
679
|
-
* }
|
|
906
|
+
* });
|
|
907
|
+
*
|
|
908
|
+
* // End-user accepting invite (no auth required)
|
|
909
|
+
* const response = await executeEmbeddedUserOnboardingFlow({
|
|
910
|
+
* baseUrl: "https://api.thunder.io",
|
|
911
|
+
* payload: {
|
|
912
|
+
* executionId: "flow-id-from-url",
|
|
913
|
+
* inputs: { inviteToken: "token-from-url" }
|
|
914
|
+
* }
|
|
915
|
+
* });
|
|
680
916
|
* ```
|
|
917
|
+
*/
|
|
918
|
+
const executeEmbeddedUserOnboardingFlow = async ({ url, baseUrl, payload,...requestConfig }) => {
|
|
919
|
+
if (!payload) throw new ThunderIDAPIError("User onboarding payload is required", "executeEmbeddedUserOnboardingFlow-ValidationError-002", "javascript", 400, "If a user onboarding payload is not provided, the request cannot be constructed correctly.");
|
|
920
|
+
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
921
|
+
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
922
|
+
const hasOnlyFlowType = typeof cleanPayload === "object" && cleanPayload !== null && "flowType" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
923
|
+
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
924
|
+
const hasFlowIdWithInputs = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && "inputs" in cleanPayload;
|
|
925
|
+
const requestPayload = hasOnlyFlowType || hasOnlyFlowId || hasFlowIdWithInputs ? {
|
|
926
|
+
...cleanPayload,
|
|
927
|
+
verbose: true
|
|
928
|
+
} : cleanPayload;
|
|
929
|
+
if ("flowType" in requestPayload && requestPayload["flowType"] !== EmbeddedFlowType.UserOnboarding) requestPayload["flowType"] = EmbeddedFlowType.UserOnboarding;
|
|
930
|
+
const response = await fetch(endpoint, {
|
|
931
|
+
...requestConfig,
|
|
932
|
+
body: JSON.stringify(requestPayload),
|
|
933
|
+
headers: {
|
|
934
|
+
Accept: "application/json",
|
|
935
|
+
"Content-Type": "application/json",
|
|
936
|
+
...requestConfig.headers
|
|
937
|
+
},
|
|
938
|
+
method: requestConfig.method || "POST"
|
|
939
|
+
});
|
|
940
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedUserOnboardingFlow-ResponseError-001", "javascript", response.status, response.statusText, "User onboarding request failed");
|
|
941
|
+
return await response.json();
|
|
942
|
+
};
|
|
943
|
+
var executeEmbeddedUserOnboardingFlow_default = executeEmbeddedUserOnboardingFlow;
|
|
944
|
+
|
|
945
|
+
//#endregion
|
|
946
|
+
//#region src/api/getFlowMeta.ts
|
|
947
|
+
/**
|
|
948
|
+
* Fetches aggregated flow metadata from the `GET /flow/meta` endpoint.
|
|
949
|
+
*
|
|
950
|
+
* The response includes:
|
|
951
|
+
* - Application or OU details depending on the `type` parameter
|
|
952
|
+
* - Resolved design configuration (theme and layout)
|
|
953
|
+
* - i18n translations filtered by `language` and `namespace`
|
|
954
|
+
* - Registration flow enablement status
|
|
955
|
+
*
|
|
956
|
+
* @param config - Request configuration including `baseUrl`/`url`, and optional
|
|
957
|
+
* `type`, `id`, `language`, and `namespace` filters. When `type`
|
|
958
|
+
* and `id` are omitted the server returns i18n-only metadata.
|
|
959
|
+
* @returns A promise that resolves to the {@link FlowMetadataResponse}.
|
|
960
|
+
*
|
|
961
|
+
* @throws {ThunderIDAPIError} When the server returns a non-OK response.
|
|
681
962
|
*
|
|
682
963
|
* @example
|
|
683
964
|
* ```typescript
|
|
684
|
-
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
*
|
|
689
|
-
*
|
|
690
|
-
*
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
* ok: response.status >= 200 && response.status < 300,
|
|
698
|
-
* status: response.status,
|
|
699
|
-
* statusText: response.statusText,
|
|
700
|
-
* json: () => Promise.resolve(response.data),
|
|
701
|
-
* text: () => Promise.resolve(typeof response.data === 'string' ? response.data : JSON.stringify(response.data))
|
|
702
|
-
* } as Response;
|
|
703
|
-
* }
|
|
704
|
-
* });
|
|
705
|
-
* console.log(userProfile);
|
|
706
|
-
* } catch (error) {
|
|
707
|
-
* if (error instanceof ThunderIDAPIError) {
|
|
708
|
-
* console.error('Failed to get user profile:', error.message);
|
|
709
|
-
* }
|
|
710
|
-
* }
|
|
965
|
+
* import getFlowMeta from './api/getFlowMeta';
|
|
966
|
+
* import { FlowMetaType } from './models/flow-meta';
|
|
967
|
+
*
|
|
968
|
+
* const meta = await getFlowMeta({
|
|
969
|
+
* baseUrl: 'https://localhost:8090',
|
|
970
|
+
* type: FlowMetaType.App,
|
|
971
|
+
* id: '60a9b38b-6eba-9f9e-55f9-267067de4680',
|
|
972
|
+
* language: 'en',
|
|
973
|
+
* namespace: 'auth',
|
|
974
|
+
* });
|
|
975
|
+
*
|
|
976
|
+
* console.log(meta.application?.name);
|
|
977
|
+
* console.log(meta.i18n.translations);
|
|
711
978
|
* ```
|
|
979
|
+
*
|
|
980
|
+
* @experimental This function targets the ThunderID V2 platform API
|
|
712
981
|
*/
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
const
|
|
721
|
-
const
|
|
982
|
+
const getFlowMeta = async ({ url, baseUrl, type, id, language, namespace,...requestConfig }) => {
|
|
983
|
+
const queryParams = new URLSearchParams({
|
|
984
|
+
...id ? { id } : {},
|
|
985
|
+
...type ? { type } : {},
|
|
986
|
+
...language ? { language } : {},
|
|
987
|
+
...namespace ? { namespace } : {}
|
|
988
|
+
});
|
|
989
|
+
const endpoint = `${url ?? `${baseUrl}/flow/meta`}?${queryParams.toString()}`;
|
|
990
|
+
const response = await fetch(endpoint, {
|
|
722
991
|
...requestConfig,
|
|
723
992
|
headers: {
|
|
724
993
|
Accept: "application/json",
|
|
725
|
-
"Content-Type": "application/scim+json",
|
|
726
994
|
...requestConfig.headers
|
|
727
995
|
},
|
|
728
996
|
method: "GET"
|
|
729
|
-
};
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
if (!response?.ok) throw new ThunderIDAPIError(await response.text(), "getScim2Me-ResponseError-001", "javascript", response.status, response.statusText, "Failed to fetch user profile");
|
|
733
|
-
return processUsername_default(await response.json());
|
|
734
|
-
} catch (error$1) {
|
|
735
|
-
if (error$1 instanceof ThunderIDAPIError) throw error$1;
|
|
736
|
-
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "getScim2Me-NetworkError-001", "javascript", 0, "Network Error");
|
|
737
|
-
}
|
|
997
|
+
});
|
|
998
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "getFlowMeta-ResponseError-001", "javascript", response.status, response.statusText, "Flow metadata request failed");
|
|
999
|
+
return await response.json();
|
|
738
1000
|
};
|
|
739
|
-
var
|
|
1001
|
+
var getFlowMeta_default = getFlowMeta;
|
|
740
1002
|
|
|
741
1003
|
//#endregion
|
|
742
|
-
//#region src/api/
|
|
1004
|
+
//#region src/api/getOrganizationUnitChildren.ts
|
|
743
1005
|
/**
|
|
744
|
-
* Retrieves the
|
|
1006
|
+
* Retrieves the child organization units of a given parent OU.
|
|
1007
|
+
*
|
|
1008
|
+
* @param config - Request configuration including `baseUrl`/`url`, `organizationUnitId`,
|
|
1009
|
+
* and optional `limit`/`offset` pagination parameters.
|
|
1010
|
+
* @returns A promise that resolves with the paginated list of child organization units.
|
|
1011
|
+
*
|
|
1012
|
+
* @throws {ThunderIDAPIError} When the server returns a non-OK response.
|
|
745
1013
|
*
|
|
746
|
-
* @param config - Request configuration object.
|
|
747
|
-
* @returns A promise that resolves with the SCIM2 schemas information.
|
|
748
1014
|
* @example
|
|
749
1015
|
* ```typescript
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
*
|
|
1016
|
+
* const children = await getOrganizationUnitChildren({
|
|
1017
|
+
* baseUrl: 'https://localhost:8090',
|
|
1018
|
+
* organizationUnitId: '0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1',
|
|
1019
|
+
* limit: 10,
|
|
1020
|
+
* offset: 0,
|
|
1021
|
+
* });
|
|
1022
|
+
* console.log(children.organizationUnits);
|
|
1023
|
+
* ```
|
|
1024
|
+
*
|
|
1025
|
+
* @experimental This function targets the ThunderID V2 platform API
|
|
1026
|
+
*/
|
|
1027
|
+
const getOrganizationUnitChildren = async ({ url, baseUrl, organizationUnitId, limit = 10, offset = 0,...requestConfig }) => {
|
|
1028
|
+
if (!organizationUnitId) throw new ThunderIDAPIError("Organization Unit ID is required", "getOrganizationUnitChildren-ValidationError-001", "javascript", 400, "If an organization unit ID is not provided, the request cannot be constructed correctly.");
|
|
1029
|
+
const queryParams = new URLSearchParams({
|
|
1030
|
+
limit: String(limit),
|
|
1031
|
+
offset: String(offset)
|
|
1032
|
+
});
|
|
1033
|
+
const endpoint = url ?? `${baseUrl}/organization-units/${organizationUnitId}/ous?${queryParams.toString()}`;
|
|
1034
|
+
const response = await fetch(endpoint, {
|
|
1035
|
+
...requestConfig,
|
|
1036
|
+
headers: {
|
|
1037
|
+
Accept: "application/json",
|
|
1038
|
+
...requestConfig.headers
|
|
1039
|
+
},
|
|
1040
|
+
method: "GET"
|
|
1041
|
+
});
|
|
1042
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "getOrganizationUnitChildren-ResponseError-001", "javascript", response.status, response.statusText, "Failed to fetch organization unit children");
|
|
1043
|
+
return await response.json();
|
|
1044
|
+
};
|
|
1045
|
+
var getOrganizationUnitChildren_default = getOrganizationUnitChildren;
|
|
1046
|
+
|
|
1047
|
+
//#endregion
|
|
1048
|
+
//#region src/api/getUserInfo.ts
|
|
1049
|
+
/**
|
|
1050
|
+
* Retrieves the user information from the specified OIDC userinfo endpoint.
|
|
1051
|
+
*
|
|
1052
|
+
* @param requestConfig - Request configuration object.
|
|
1053
|
+
* @returns A promise that resolves with the user information.
|
|
1054
|
+
* @throw
|
|
1055
|
+
* const userInfo = await getUserInfo({
|
|
1056
|
+
* url: "https://localhost:8090/oauth2/userinfo",
|
|
754
1057
|
* });
|
|
755
|
-
* console.log(
|
|
1058
|
+
* console.log(userInfo);
|
|
756
1059
|
* } catch (error) {
|
|
757
1060
|
* if (error instanceof ThunderIDAPIError) {
|
|
758
|
-
* console.error('Failed to get
|
|
1061
|
+
* console.error('Failed to get user info:', error.message);
|
|
1062
|
+
* }
|
|
1063
|
+
* }
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
const getUserInfo = async ({ url,...requestConfig }) => {
|
|
1067
|
+
try {
|
|
1068
|
+
new URL(url);
|
|
1069
|
+
} catch (error$1) {
|
|
1070
|
+
throw new ThunderIDAPIError("Invalid endpoint URL provided", "getUserInfo-ValidationError-001", "javascript", 400, "Invalid Request");
|
|
1071
|
+
}
|
|
1072
|
+
try {
|
|
1073
|
+
const response = await fetch(url, {
|
|
1074
|
+
...requestConfig,
|
|
1075
|
+
headers: {
|
|
1076
|
+
Accept: "application/json",
|
|
1077
|
+
"Content-Type": "application/json",
|
|
1078
|
+
...requestConfig.headers
|
|
1079
|
+
},
|
|
1080
|
+
method: "GET"
|
|
1081
|
+
});
|
|
1082
|
+
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "getUserInfo-ResponseError-001", "javascript", response.status, response.statusText, "Failed to fetch user info");
|
|
1083
|
+
return await response.json();
|
|
1084
|
+
} catch (error$1) {
|
|
1085
|
+
if (error$1 instanceof ThunderIDAPIError) throw error$1;
|
|
1086
|
+
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "getUserInfo-NetworkError-001", "javascript", 0, "Network Error");
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
var getUserInfo_default = getUserInfo;
|
|
1090
|
+
|
|
1091
|
+
//#endregion
|
|
1092
|
+
//#region src/utils/processUsername.ts
|
|
1093
|
+
/**
|
|
1094
|
+
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
|
|
1095
|
+
*
|
|
1096
|
+
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
1097
|
+
* Version 2.0 (the "License"); you may not use this file except
|
|
1098
|
+
* in compliance with the License.
|
|
1099
|
+
* You may obtain a copy of the License at
|
|
1100
|
+
*
|
|
1101
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1102
|
+
*
|
|
1103
|
+
* Unless required by applicable law or agreed to in writing,
|
|
1104
|
+
* software distributed under the License is distributed on an
|
|
1105
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
1106
|
+
* KIND, either express or implied. See the License for the
|
|
1107
|
+
* specific language governing permissions and limitations
|
|
1108
|
+
* under the License.
|
|
1109
|
+
*/
|
|
1110
|
+
/**
|
|
1111
|
+
* Regular expression to match userstore prefixes in usernames.
|
|
1112
|
+
* Matches patterns like "DEFAULT/", "ASGARDEO_USER/", "PRIMARY/", etc.
|
|
1113
|
+
* The pattern matches any uppercase letters, numbers, and underscores followed by a forward slash.
|
|
1114
|
+
*/
|
|
1115
|
+
const USERSTORE_PREFIX_REGEX = /^[A-Z_][A-Z0-9_]*\//;
|
|
1116
|
+
/**
|
|
1117
|
+
* Removes userstore prefixes from a username if they exist.
|
|
1118
|
+
* This is commonly used to clean usernames returned from SCIM2 endpoints
|
|
1119
|
+
* that include userstore prefixes like "DEFAULT/", "ASGARDEO_USER/", "PRIMARY/", etc.
|
|
1120
|
+
*
|
|
1121
|
+
* @param username - The username string to process
|
|
1122
|
+
* @returns The username without the userstore prefix, or the original username if no prefix exists
|
|
1123
|
+
*
|
|
1124
|
+
* @example
|
|
1125
|
+
* ```typescript
|
|
1126
|
+
* const cleanUsername = removeUserstorePrefix("DEFAULT/john.doe");
|
|
1127
|
+
* console.log(cleanUsername); // "john.doe"
|
|
1128
|
+
*
|
|
1129
|
+
* const thunderidUser = removeUserstorePrefix("ASGARDEO_USER/jane.doe");
|
|
1130
|
+
* console.log(thunderidUser); // "jane.doe"
|
|
1131
|
+
*
|
|
1132
|
+
* const primaryUser = removeUserstorePrefix("PRIMARY/admin");
|
|
1133
|
+
* console.log(primaryUser); // "admin"
|
|
1134
|
+
*
|
|
1135
|
+
* const alreadyClean = removeUserstorePrefix("user.name");
|
|
1136
|
+
* console.log(alreadyClean); // "user.name"
|
|
1137
|
+
*
|
|
1138
|
+
* const emptyInput = removeUserstorePrefix("");
|
|
1139
|
+
* console.log(emptyInput); // ""
|
|
1140
|
+
* ```
|
|
1141
|
+
*/
|
|
1142
|
+
const removeUserstorePrefix = (username) => {
|
|
1143
|
+
if (!username) return "";
|
|
1144
|
+
return username.replace(USERSTORE_PREFIX_REGEX, "");
|
|
1145
|
+
};
|
|
1146
|
+
/**
|
|
1147
|
+
* Processes a user object to remove userstore prefixes from username fields.
|
|
1148
|
+
* This is a helper function for processing user objects returned from SCIM2 endpoints.
|
|
1149
|
+
* Handles various username field variations: username, userName, and user_name.
|
|
1150
|
+
*
|
|
1151
|
+
* @param user - The user object to process
|
|
1152
|
+
* @returns The user object with processed username fields
|
|
1153
|
+
*
|
|
1154
|
+
* @example
|
|
1155
|
+
* ```typescript
|
|
1156
|
+
* const user = { username: "DEFAULT/john.doe", email: "john@example.com" };
|
|
1157
|
+
* const processedUser = processUserUsername(user);
|
|
1158
|
+
* console.log(processedUser.username); // "john.doe"
|
|
1159
|
+
*
|
|
1160
|
+
* const camelCaseUser = { userName: "ASGARDEO_USER/jane.doe", email: "jane@example.com" };
|
|
1161
|
+
* const processedCamelCaseUser = processUserUsername(camelCaseUser);
|
|
1162
|
+
* console.log(processedCamelCaseUser.userName); // "jane.doe"
|
|
1163
|
+
*
|
|
1164
|
+
* const snakeCaseUser = { user_name: "PRIMARY/admin", email: "admin@example.com" };
|
|
1165
|
+
* const processedSnakeCaseUser = processUserUsername(snakeCaseUser);
|
|
1166
|
+
* console.log(processedSnakeCaseUser.user_name); // "admin"
|
|
1167
|
+
* ```
|
|
1168
|
+
*/
|
|
1169
|
+
const processUsername = (user) => {
|
|
1170
|
+
if (!user) return user;
|
|
1171
|
+
const processedUser = { ...user };
|
|
1172
|
+
if (processedUser.username) processedUser.username = removeUserstorePrefix(processedUser.username);
|
|
1173
|
+
if (processedUser.userName) processedUser.userName = removeUserstorePrefix(processedUser.userName);
|
|
1174
|
+
if (processedUser.user_name) processedUser.user_name = removeUserstorePrefix(processedUser.user_name);
|
|
1175
|
+
return processedUser;
|
|
1176
|
+
};
|
|
1177
|
+
var processUsername_default = processUsername;
|
|
1178
|
+
|
|
1179
|
+
//#endregion
|
|
1180
|
+
//#region src/api/getScim2Me.ts
|
|
1181
|
+
/**
|
|
1182
|
+
* Retrieves the user profile information from the specified SCIM2 /Me endpoint.
|
|
1183
|
+
*
|
|
1184
|
+
* @param config - Request configuration object.
|
|
1185
|
+
* @returns A promise that resolves with the user profile information.
|
|
1186
|
+
* @example
|
|
1187
|
+
* ```typescript
|
|
1188
|
+
* // Using default fetch
|
|
1189
|
+
* try {
|
|
1190
|
+
* const userProfile = await getScim2Me({
|
|
1191
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
1192
|
+
* });
|
|
1193
|
+
* console.log(userProfile);
|
|
1194
|
+
* } catch (error) {
|
|
1195
|
+
* if (error instanceof ThunderIDAPIError) {
|
|
1196
|
+
* console.error('Failed to get user profile:', error.message);
|
|
759
1197
|
* }
|
|
760
1198
|
* }
|
|
761
1199
|
* ```
|
|
@@ -764,8 +1202,8 @@ var getScim2Me_default = getScim2Me;
|
|
|
764
1202
|
* ```typescript
|
|
765
1203
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
766
1204
|
* try {
|
|
767
|
-
* const
|
|
768
|
-
* url: "https://localhost:8090/scim2/
|
|
1205
|
+
* const userProfile = await getScim2Me({
|
|
1206
|
+
* url: "https://localhost:8090/scim2/Me",
|
|
769
1207
|
* fetcher: async (url, config) => {
|
|
770
1208
|
* const response = await httpClient({
|
|
771
1209
|
* url,
|
|
@@ -783,63 +1221,60 @@ var getScim2Me_default = getScim2Me;
|
|
|
783
1221
|
* } as Response;
|
|
784
1222
|
* }
|
|
785
1223
|
* });
|
|
786
|
-
* console.log(
|
|
1224
|
+
* console.log(userProfile);
|
|
787
1225
|
* } catch (error) {
|
|
788
1226
|
* if (error instanceof ThunderIDAPIError) {
|
|
789
|
-
* console.error('Failed to get
|
|
1227
|
+
* console.error('Failed to get user profile:', error.message);
|
|
790
1228
|
* }
|
|
791
1229
|
* }
|
|
792
1230
|
* ```
|
|
793
1231
|
*/
|
|
794
|
-
const
|
|
1232
|
+
const getScim2Me = async ({ url, baseUrl, fetcher,...requestConfig }) => {
|
|
795
1233
|
try {
|
|
796
1234
|
new URL(url ?? baseUrl);
|
|
797
1235
|
} catch (error$1) {
|
|
798
|
-
throw new ThunderIDAPIError(`Invalid URL provided. ${error$1?.toString()}`, "
|
|
1236
|
+
throw new ThunderIDAPIError(`Invalid URL provided. ${error$1?.toString()}`, "getScim2Me-ValidationError-001", "javascript", 400, "The provided `url` or `baseUrl` path does not adhere to the URL schema.");
|
|
799
1237
|
}
|
|
800
1238
|
const fetchFn = fetcher || fetch;
|
|
801
|
-
const resolvedUrl = url ?? `${baseUrl}/scim2/
|
|
1239
|
+
const resolvedUrl = url ?? `${baseUrl}/scim2/Me`;
|
|
802
1240
|
const requestInit = {
|
|
803
1241
|
...requestConfig,
|
|
804
1242
|
headers: {
|
|
805
1243
|
Accept: "application/json",
|
|
806
|
-
"Content-Type": "application/json",
|
|
1244
|
+
"Content-Type": "application/scim+json",
|
|
807
1245
|
...requestConfig.headers
|
|
808
1246
|
},
|
|
809
1247
|
method: "GET"
|
|
810
1248
|
};
|
|
811
1249
|
try {
|
|
812
1250
|
const response = await fetchFn(resolvedUrl, requestInit);
|
|
813
|
-
if (!response?.ok) throw new ThunderIDAPIError(await response.text(), "
|
|
814
|
-
return await response.json();
|
|
1251
|
+
if (!response?.ok) throw new ThunderIDAPIError(await response.text(), "getScim2Me-ResponseError-001", "javascript", response.status, response.statusText, "Failed to fetch user profile");
|
|
1252
|
+
return processUsername_default(await response.json());
|
|
815
1253
|
} catch (error$1) {
|
|
816
1254
|
if (error$1 instanceof ThunderIDAPIError) throw error$1;
|
|
817
|
-
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "
|
|
1255
|
+
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "getScim2Me-NetworkError-001", "javascript", 0, "Network Error");
|
|
818
1256
|
}
|
|
819
1257
|
};
|
|
820
|
-
var
|
|
1258
|
+
var getScim2Me_default = getScim2Me;
|
|
821
1259
|
|
|
822
1260
|
//#endregion
|
|
823
|
-
//#region src/api/
|
|
1261
|
+
//#region src/api/getSchemas.ts
|
|
824
1262
|
/**
|
|
825
|
-
* Retrieves
|
|
1263
|
+
* Retrieves the SCIM2 schemas from the specified endpoint.
|
|
826
1264
|
*
|
|
827
|
-
* @param config -
|
|
828
|
-
* @returns A promise that resolves with the
|
|
1265
|
+
* @param config - Request configuration object.
|
|
1266
|
+
* @returns A promise that resolves with the SCIM2 schemas information.
|
|
829
1267
|
* @example
|
|
830
1268
|
* ```typescript
|
|
831
1269
|
* // Using default fetch
|
|
832
1270
|
* try {
|
|
833
|
-
* const
|
|
834
|
-
*
|
|
835
|
-
* filter: "",
|
|
836
|
-
* limit: 10,
|
|
837
|
-
* recursive: false
|
|
1271
|
+
* const schemas = await getSchemas({
|
|
1272
|
+
* url: "https://localhost:8090/scim2/Schemas",
|
|
838
1273
|
* });
|
|
839
|
-
* console.log(
|
|
1274
|
+
* console.log(schemas);
|
|
840
1275
|
* } catch (error) {
|
|
841
1276
|
* if (error instanceof ThunderIDAPIError) {
|
|
842
|
-
* console.error('Failed to get
|
|
1277
|
+
* console.error('Failed to get schemas:', error.message);
|
|
843
1278
|
* }
|
|
844
1279
|
* }
|
|
845
1280
|
* ```
|
|
@@ -848,11 +1283,8 @@ var getSchemas_default = getSchemas;
|
|
|
848
1283
|
* ```typescript
|
|
849
1284
|
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
850
1285
|
* try {
|
|
851
|
-
* const
|
|
852
|
-
*
|
|
853
|
-
* filter: "",
|
|
854
|
-
* limit: 10,
|
|
855
|
-
* recursive: false,
|
|
1286
|
+
* const schemas = await getSchemas({
|
|
1287
|
+
* url: "https://localhost:8090/scim2/Schemas",
|
|
856
1288
|
* fetcher: async (url, config) => {
|
|
857
1289
|
* const response = await httpClient({
|
|
858
1290
|
* url,
|
|
@@ -870,43 +1302,130 @@ var getSchemas_default = getSchemas;
|
|
|
870
1302
|
* } as Response;
|
|
871
1303
|
* }
|
|
872
1304
|
* });
|
|
873
|
-
* console.log(
|
|
1305
|
+
* console.log(schemas);
|
|
874
1306
|
* } catch (error) {
|
|
875
1307
|
* if (error instanceof ThunderIDAPIError) {
|
|
876
|
-
* console.error('Failed to get
|
|
1308
|
+
* console.error('Failed to get schemas:', error.message);
|
|
877
1309
|
* }
|
|
878
1310
|
* }
|
|
879
1311
|
* ```
|
|
880
1312
|
*/
|
|
881
|
-
const
|
|
1313
|
+
const getSchemas = async ({ url, baseUrl, fetcher,...requestConfig }) => {
|
|
882
1314
|
try {
|
|
883
|
-
new URL(baseUrl);
|
|
1315
|
+
new URL(url ?? baseUrl);
|
|
884
1316
|
} catch (error$1) {
|
|
885
|
-
throw new ThunderIDAPIError(`Invalid
|
|
1317
|
+
throw new ThunderIDAPIError(`Invalid URL provided. ${error$1?.toString()}`, "getSchemas-ValidationError-001", "javascript", 400, "The provided `url` or `baseUrl` path does not adhere to the URL schema.");
|
|
886
1318
|
}
|
|
887
|
-
const queryParams = new URLSearchParams(Object.fromEntries(Object.entries({
|
|
888
|
-
filter,
|
|
889
|
-
limit: limit.toString(),
|
|
890
|
-
recursive: recursive.toString()
|
|
891
|
-
}).filter(([, value]) => Boolean(value))));
|
|
892
1319
|
const fetchFn = fetcher || fetch;
|
|
893
|
-
const resolvedUrl = `${baseUrl}/
|
|
1320
|
+
const resolvedUrl = url ?? `${baseUrl}/scim2/Schemas`;
|
|
894
1321
|
const requestInit = {
|
|
895
1322
|
...requestConfig,
|
|
896
1323
|
headers: {
|
|
897
|
-
...requestConfig.headers,
|
|
898
1324
|
Accept: "application/json",
|
|
899
|
-
"Content-Type": "application/json"
|
|
1325
|
+
"Content-Type": "application/json",
|
|
1326
|
+
...requestConfig.headers
|
|
900
1327
|
},
|
|
901
1328
|
method: "GET"
|
|
902
1329
|
};
|
|
903
1330
|
try {
|
|
904
1331
|
const response = await fetchFn(resolvedUrl, requestInit);
|
|
905
|
-
if (!response?.ok) throw new ThunderIDAPIError(await response.text(), "
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1332
|
+
if (!response?.ok) throw new ThunderIDAPIError(await response.text(), "getSchemas-ResponseError-001", "javascript", response.status, response.statusText, "Failed to fetch SCIM2 schemas");
|
|
1333
|
+
return await response.json();
|
|
1334
|
+
} catch (error$1) {
|
|
1335
|
+
if (error$1 instanceof ThunderIDAPIError) throw error$1;
|
|
1336
|
+
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "getSchemas-NetworkError-001", "javascript", 0, "Network Error");
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
var getSchemas_default = getSchemas;
|
|
1340
|
+
|
|
1341
|
+
//#endregion
|
|
1342
|
+
//#region src/api/getAllOrganizations.ts
|
|
1343
|
+
/**
|
|
1344
|
+
* Retrieves all organizations with pagination support.
|
|
1345
|
+
*
|
|
1346
|
+
* @param config - Configuration object containing baseUrl, optional query parameters, and request config.
|
|
1347
|
+
* @returns A promise that resolves with the paginated organizations information.
|
|
1348
|
+
* @example
|
|
1349
|
+
* ```typescript
|
|
1350
|
+
* // Using default fetch
|
|
1351
|
+
* try {
|
|
1352
|
+
* const response = await getAllOrganizations({
|
|
1353
|
+
* baseUrl: "https://localhost:8090",
|
|
1354
|
+
* filter: "",
|
|
1355
|
+
* limit: 10,
|
|
1356
|
+
* recursive: false
|
|
1357
|
+
* });
|
|
1358
|
+
* console.log(response.organizations);
|
|
1359
|
+
* } catch (error) {
|
|
1360
|
+
* if (error instanceof ThunderIDAPIError) {
|
|
1361
|
+
* console.error('Failed to get organizations:', error.message);
|
|
1362
|
+
* }
|
|
1363
|
+
* }
|
|
1364
|
+
* ```
|
|
1365
|
+
*
|
|
1366
|
+
* @example
|
|
1367
|
+
* ```typescript
|
|
1368
|
+
* // Using custom fetcher (e.g., axios-based httpClient)
|
|
1369
|
+
* try {
|
|
1370
|
+
* const response = await getAllOrganizations({
|
|
1371
|
+
* baseUrl: "https://localhost:8090",
|
|
1372
|
+
* filter: "",
|
|
1373
|
+
* limit: 10,
|
|
1374
|
+
* recursive: false,
|
|
1375
|
+
* fetcher: async (url, config) => {
|
|
1376
|
+
* const response = await httpClient({
|
|
1377
|
+
* url,
|
|
1378
|
+
* method: config.method,
|
|
1379
|
+
* headers: config.headers,
|
|
1380
|
+
* ...config
|
|
1381
|
+
* });
|
|
1382
|
+
* // Convert axios-like response to fetch-like Response
|
|
1383
|
+
* return {
|
|
1384
|
+
* ok: response.status >= 200 && response.status < 300,
|
|
1385
|
+
* status: response.status,
|
|
1386
|
+
* statusText: response.statusText,
|
|
1387
|
+
* json: () => Promise.resolve(response.data),
|
|
1388
|
+
* text: () => Promise.resolve(typeof response.data === 'string' ? response.data : JSON.stringify(response.data))
|
|
1389
|
+
* } as Response;
|
|
1390
|
+
* }
|
|
1391
|
+
* });
|
|
1392
|
+
* console.log(response.organizations);
|
|
1393
|
+
* } catch (error) {
|
|
1394
|
+
* if (error instanceof ThunderIDAPIError) {
|
|
1395
|
+
* console.error('Failed to get organizations:', error.message);
|
|
1396
|
+
* }
|
|
1397
|
+
* }
|
|
1398
|
+
* ```
|
|
1399
|
+
*/
|
|
1400
|
+
const getAllOrganizations = async ({ baseUrl, filter = "", limit = 10, recursive = false, fetcher,...requestConfig }) => {
|
|
1401
|
+
try {
|
|
1402
|
+
new URL(baseUrl);
|
|
1403
|
+
} catch (error$1) {
|
|
1404
|
+
throw new ThunderIDAPIError(`Invalid base URL provided. ${error$1?.toString()}`, "getAllOrganizations-ValidationError-001", "javascript", 400, "The provided `baseUrl` does not adhere to the URL schema.");
|
|
1405
|
+
}
|
|
1406
|
+
const queryParams = new URLSearchParams(Object.fromEntries(Object.entries({
|
|
1407
|
+
filter,
|
|
1408
|
+
limit: limit.toString(),
|
|
1409
|
+
recursive: recursive.toString()
|
|
1410
|
+
}).filter(([, value]) => Boolean(value))));
|
|
1411
|
+
const fetchFn = fetcher || fetch;
|
|
1412
|
+
const resolvedUrl = `${baseUrl}/api/server/v1/organizations?${queryParams.toString()}`;
|
|
1413
|
+
const requestInit = {
|
|
1414
|
+
...requestConfig,
|
|
1415
|
+
headers: {
|
|
1416
|
+
...requestConfig.headers,
|
|
1417
|
+
Accept: "application/json",
|
|
1418
|
+
"Content-Type": "application/json"
|
|
1419
|
+
},
|
|
1420
|
+
method: "GET"
|
|
1421
|
+
};
|
|
1422
|
+
try {
|
|
1423
|
+
const response = await fetchFn(resolvedUrl, requestInit);
|
|
1424
|
+
if (!response?.ok) throw new ThunderIDAPIError(await response.text(), "getAllOrganizations-ResponseError-001", "javascript", response.status, response.statusText, "Failed to get organizations");
|
|
1425
|
+
const data = await response.json();
|
|
1426
|
+
return {
|
|
1427
|
+
hasMore: data.hasMore,
|
|
1428
|
+
nextCursor: data.nextCursor,
|
|
910
1429
|
organizations: data.organizations || [],
|
|
911
1430
|
totalCount: data.totalCount
|
|
912
1431
|
};
|
|
@@ -1448,42 +1967,6 @@ const updateMeProfile = async ({ url, baseUrl, payload, fetcher,...requestConfig
|
|
|
1448
1967
|
};
|
|
1449
1968
|
var updateMeProfile_default = updateMeProfile;
|
|
1450
1969
|
|
|
1451
|
-
//#endregion
|
|
1452
|
-
//#region src/models/platforms.ts
|
|
1453
|
-
/**
|
|
1454
|
-
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
|
|
1455
|
-
*
|
|
1456
|
-
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
1457
|
-
* Version 2.0 (the "License"); you may not use this file except
|
|
1458
|
-
* in compliance with the License.
|
|
1459
|
-
* You may obtain a copy of the License at
|
|
1460
|
-
*
|
|
1461
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1462
|
-
*
|
|
1463
|
-
* Unless required by applicable law or agreed to in writing,
|
|
1464
|
-
* software distributed under the License is distributed on an
|
|
1465
|
-
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
1466
|
-
* KIND, either express or implied. See the License for the
|
|
1467
|
-
* specific language governing permissions and limitations
|
|
1468
|
-
* under the License.
|
|
1469
|
-
*/
|
|
1470
|
-
/**
|
|
1471
|
-
* Enumeration of supported identity platforms.
|
|
1472
|
-
*
|
|
1473
|
-
* - `ThunderID`: Represents the ThunderID identity platform.
|
|
1474
|
-
* - `IdentityServer`: Represents WSO2 Identity Server (on-prem or custom domains).
|
|
1475
|
-
* - `Unknown`: Used when the platform cannot be determined from the configuration.
|
|
1476
|
-
*/
|
|
1477
|
-
let Platform = /* @__PURE__ */ function(Platform$1) {
|
|
1478
|
-
/** ThunderID identity platform */
|
|
1479
|
-
Platform$1["ThunderID"] = "THUNDERID";
|
|
1480
|
-
/** WSO2 Identity Server (on-prem or custom domains) */
|
|
1481
|
-
Platform$1["IdentityServer"] = "IDENTITY_SERVER";
|
|
1482
|
-
/** Unknown or unsupported platform */
|
|
1483
|
-
Platform$1["Unknown"] = "UNKNOWN";
|
|
1484
|
-
return Platform$1;
|
|
1485
|
-
}({});
|
|
1486
|
-
|
|
1487
1970
|
//#endregion
|
|
1488
1971
|
//#region src/utils/logger.ts
|
|
1489
1972
|
const PREFIX = "⚡ ThunderID";
|
|
@@ -1790,114 +2273,6 @@ const createPackageComponentLogger = (packageName, component) => {
|
|
|
1790
2273
|
return createPackageLogger(packageName).child(component);
|
|
1791
2274
|
};
|
|
1792
2275
|
|
|
1793
|
-
//#endregion
|
|
1794
|
-
//#region src/errors/ThunderIDRuntimeError.ts
|
|
1795
|
-
/**
|
|
1796
|
-
* Base class for all runtime errors in ThunderID. This class extends ThunderIDError
|
|
1797
|
-
* and adds support for additional error details. Use this class for errors that occur
|
|
1798
|
-
* during runtime execution that are not related to API calls.
|
|
1799
|
-
*
|
|
1800
|
-
* @example
|
|
1801
|
-
* ```typescript
|
|
1802
|
-
* throw new ThunderIDRuntimeError(
|
|
1803
|
-
* "Failed to parse configuration",
|
|
1804
|
-
* "CONFIG_PARSE_ERROR",
|
|
1805
|
-
* { invalidField: "redirectUri" }
|
|
1806
|
-
* );
|
|
1807
|
-
* ```
|
|
1808
|
-
*/
|
|
1809
|
-
var ThunderIDRuntimeError = class extends ThunderIDError {
|
|
1810
|
-
/**
|
|
1811
|
-
* Creates an instance of ThunderIDRuntimeError.
|
|
1812
|
-
*
|
|
1813
|
-
* @param message - Human-readable description of the error
|
|
1814
|
-
* @param code - A unique error code that identifies the error type
|
|
1815
|
-
* @param details - Additional details about the error that might be helpful for debugging
|
|
1816
|
-
* @param origin - Optional. The SDK origin (e.g. 'react', 'vue'). Defaults to generic 'ThunderID'
|
|
1817
|
-
* @constructor
|
|
1818
|
-
*/
|
|
1819
|
-
constructor(message, code, origin, details) {
|
|
1820
|
-
super(message, code, origin);
|
|
1821
|
-
this.details = details;
|
|
1822
|
-
Object.defineProperty(this, "name", {
|
|
1823
|
-
configurable: true,
|
|
1824
|
-
value: "ThunderIDRuntimeError",
|
|
1825
|
-
writable: true
|
|
1826
|
-
});
|
|
1827
|
-
}
|
|
1828
|
-
/**
|
|
1829
|
-
* Returns a string representation of the runtime error
|
|
1830
|
-
* @returns Formatted error string with name, code, details, and message
|
|
1831
|
-
*/
|
|
1832
|
-
toString() {
|
|
1833
|
-
const details = this.details ? `\nDetails: ${JSON.stringify(this.details, null, 2)}` : "";
|
|
1834
|
-
return `[${this.name}] (code="${this.code}")${details}\nMessage: ${this.message}`;
|
|
1835
|
-
}
|
|
1836
|
-
};
|
|
1837
|
-
|
|
1838
|
-
//#endregion
|
|
1839
|
-
//#region src/utils/isRecognizedBaseUrlPattern.ts
|
|
1840
|
-
/**
|
|
1841
|
-
* Utility to determine if sensible ThunderID fallbacks can be used based on the given base URL.
|
|
1842
|
-
*
|
|
1843
|
-
* This checks if the URL follows the standard ThunderID pattern: /t/{orgHandle}
|
|
1844
|
-
* Returns true if sensible fallbacks (like deriving organization handle, tenant, etc.) can be used, false otherwise.
|
|
1845
|
-
*
|
|
1846
|
-
* @param baseUrl - The base URL of the ThunderID identity server (string or undefined)
|
|
1847
|
-
* @returns boolean - true if sensible fallbacks can be used, false otherwise
|
|
1848
|
-
*
|
|
1849
|
-
* @example
|
|
1850
|
-
* isRecognizedBaseUrlPattern('https://localhost:8090/t/dxlab'); // true
|
|
1851
|
-
* isRecognizedBaseUrlPattern('https://custom.example.com/auth'); // false
|
|
1852
|
-
*/
|
|
1853
|
-
const isRecognizedBaseUrlPattern = (baseUrl) => {
|
|
1854
|
-
if (!baseUrl) throw new ThunderIDRuntimeError("Base URL is required to derive if the `baseUrl` is recognized.", "isRecognizedBaseUrlPattern-ValidationError-001", "javascript", "A valid base URL must be provided to derive if the `baseUrl` is recognized to use the sensible fallbacks.");
|
|
1855
|
-
let parsedUrl;
|
|
1856
|
-
try {
|
|
1857
|
-
parsedUrl = new URL(baseUrl);
|
|
1858
|
-
} catch (error$1) {
|
|
1859
|
-
throw new ThunderIDRuntimeError(`Invalid base URL format: ${baseUrl}`, "isRecognizedBaseUrlPattern-ValidationError-002", "javascript", "The provided base URL does not conform to valid URL syntax.");
|
|
1860
|
-
}
|
|
1861
|
-
const pathSegments = parsedUrl.pathname?.split("/")?.filter((segment) => segment?.length > 0);
|
|
1862
|
-
if (pathSegments.length < 2 || pathSegments[0] !== "t") {
|
|
1863
|
-
logger_default.warn("[isRecognizedBaseUrlPattern] The provided base URL does not follow the expected URL pattern (/t/{orgHandle}).");
|
|
1864
|
-
return false;
|
|
1865
|
-
}
|
|
1866
|
-
return true;
|
|
1867
|
-
};
|
|
1868
|
-
var isRecognizedBaseUrlPattern_default = isRecognizedBaseUrlPattern;
|
|
1869
|
-
|
|
1870
|
-
//#endregion
|
|
1871
|
-
//#region src/utils/identifyPlatform.ts
|
|
1872
|
-
/**
|
|
1873
|
-
* Identifies the platform based on the given base URL.
|
|
1874
|
-
*
|
|
1875
|
-
* If the URL is recognized and matches the ThunderID domain, returns Platform.ThunderID.
|
|
1876
|
-
* Otherwise, returns Platform.IdentityServer.
|
|
1877
|
-
*
|
|
1878
|
-
* @param baseUrl - The base URL to check
|
|
1879
|
-
* @returns Platform enum value
|
|
1880
|
-
*/
|
|
1881
|
-
const identifyPlatform = (config) => {
|
|
1882
|
-
const { baseUrl } = config;
|
|
1883
|
-
try {
|
|
1884
|
-
if (isRecognizedBaseUrlPattern_default(baseUrl)) {
|
|
1885
|
-
try {
|
|
1886
|
-
const url = new URL(baseUrl);
|
|
1887
|
-
if (/\.thunderid\.io$/i.test(url.hostname) || /thunderid\.io$/i.test(url.hostname)) return Platform.ThunderID;
|
|
1888
|
-
} catch {
|
|
1889
|
-
logger_default.debug(`[identifyPlatform] Could not identify platform from the base URL: ${baseUrl}. Defaulting to WSO2 Identity Server as the platform.`);
|
|
1890
|
-
}
|
|
1891
|
-
return Platform.IdentityServer;
|
|
1892
|
-
}
|
|
1893
|
-
return Platform.Unknown;
|
|
1894
|
-
} catch (error$1) {
|
|
1895
|
-
logger_default.debug(`[identifyPlatform] Error identifying platform from base URL: ${baseUrl}. Error: ${error$1.message}`);
|
|
1896
|
-
return Platform.Unknown;
|
|
1897
|
-
}
|
|
1898
|
-
};
|
|
1899
|
-
var identifyPlatform_default = identifyPlatform;
|
|
1900
|
-
|
|
1901
2276
|
//#endregion
|
|
1902
2277
|
//#region src/api/getBrandingPreference.ts
|
|
1903
2278
|
/**
|
|
@@ -1978,575 +2353,28 @@ const getBrandingPreference = async ({ baseUrl, locale, name, type, fetcher,...r
|
|
|
1978
2353
|
...requestConfig.headers
|
|
1979
2354
|
},
|
|
1980
2355
|
method: "GET"
|
|
1981
|
-
};
|
|
1982
|
-
try {
|
|
1983
|
-
const response = await fetchFn(resolvedUrl, requestInit);
|
|
1984
|
-
if (!response?.ok) {
|
|
1985
|
-
const errorText = await response.text();
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
}
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
return await response.json();
|
|
2002
|
-
} catch (error$1) {
|
|
2003
|
-
if (error$1 instanceof ThunderIDAPIError) throw error$1;
|
|
2004
|
-
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "getBrandingPreference-NetworkError-001", "javascript", 0, "Network Error");
|
|
2005
|
-
}
|
|
2006
|
-
};
|
|
2007
|
-
var getBrandingPreference_default = getBrandingPreference;
|
|
2008
|
-
|
|
2009
|
-
//#endregion
|
|
2010
|
-
//#region src/models/v2/embedded-signin-flow-v2.ts
|
|
2011
|
-
/**
|
|
2012
|
-
* Status enumeration for ThunderID embedded sign-in flow operations.
|
|
2013
|
-
*
|
|
2014
|
-
* These statuses indicate the current state of the sign-in flow and determine
|
|
2015
|
-
* the next action required by the client application. Each status provides
|
|
2016
|
-
* specific guidance on how to proceed with the authentication process.
|
|
2017
|
-
*
|
|
2018
|
-
* @example
|
|
2019
|
-
* ```typescript
|
|
2020
|
-
* switch (response.flowStatus) {
|
|
2021
|
-
* case EmbeddedSignInFlowStatus.Incomplete:
|
|
2022
|
-
* // More user input needed - render form components
|
|
2023
|
-
* break;
|
|
2024
|
-
* case EmbeddedSignInFlowStatus.Complete:
|
|
2025
|
-
* // Authentication successful - handle completion
|
|
2026
|
-
* break;
|
|
2027
|
-
* case EmbeddedSignInFlowStatus.Error:
|
|
2028
|
-
* // Authentication failed - show error message
|
|
2029
|
-
* break;
|
|
2030
|
-
* }
|
|
2031
|
-
* ```
|
|
2032
|
-
*
|
|
2033
|
-
* @experimental Part of the new ThunderID API
|
|
2034
|
-
*/
|
|
2035
|
-
let EmbeddedSignInFlowStatus$1 = /* @__PURE__ */ function(EmbeddedSignInFlowStatus$2) {
|
|
2036
|
-
/**
|
|
2037
|
-
* Sign-in flow completed successfully.
|
|
2038
|
-
*
|
|
2039
|
-
* The user has been authenticated and the flow can proceed to
|
|
2040
|
-
* OAuth2 completion or redirection. Check for redirectUrl or
|
|
2041
|
-
* assertion data in the response.
|
|
2042
|
-
*/
|
|
2043
|
-
EmbeddedSignInFlowStatus$2["Complete"] = "COMPLETE";
|
|
2044
|
-
/**
|
|
2045
|
-
* Sign-in flow encountered an error.
|
|
2046
|
-
*
|
|
2047
|
-
* Authentication failed due to invalid credentials, system error,
|
|
2048
|
-
* or other issues. Check error details in the response and handle
|
|
2049
|
-
* appropriately (retry, show error message, etc.).
|
|
2050
|
-
*/
|
|
2051
|
-
EmbeddedSignInFlowStatus$2["Error"] = "ERROR";
|
|
2052
|
-
/**
|
|
2053
|
-
* Sign-in flow requires additional user input.
|
|
2054
|
-
*
|
|
2055
|
-
* More authentication steps are needed. The response will contain
|
|
2056
|
-
* components in data.meta.components that should be rendered to
|
|
2057
|
-
* collect additional user input (e.g., MFA, password, etc.).
|
|
2058
|
-
*/
|
|
2059
|
-
EmbeddedSignInFlowStatus$2["Incomplete"] = "INCOMPLETE";
|
|
2060
|
-
return EmbeddedSignInFlowStatus$2;
|
|
2061
|
-
}({});
|
|
2062
|
-
/**
|
|
2063
|
-
* Type enumeration for ThunderID embedded sign-in flow responses.
|
|
2064
|
-
*
|
|
2065
|
-
* Determines the nature of the flow response and how the client should
|
|
2066
|
-
* handle the returned data. This affects both UI rendering and flow
|
|
2067
|
-
* continuation logic.
|
|
2068
|
-
*
|
|
2069
|
-
* @experimental Part of the new ThunderID API
|
|
2070
|
-
*/
|
|
2071
|
-
let EmbeddedSignInFlowType$1 = /* @__PURE__ */ function(EmbeddedSignInFlowType$2) {
|
|
2072
|
-
/**
|
|
2073
|
-
* Response requires external redirection.
|
|
2074
|
-
*
|
|
2075
|
-
* Used for social login providers, external identity providers,
|
|
2076
|
-
* or other flows that require navigating to an external URL.
|
|
2077
|
-
* The response will contain redirection information.
|
|
2078
|
-
*/
|
|
2079
|
-
EmbeddedSignInFlowType$2["Redirection"] = "REDIRECTION";
|
|
2080
|
-
/**
|
|
2081
|
-
* Response contains view components for rendering.
|
|
2082
|
-
*
|
|
2083
|
-
* Standard embedded flow response containing UI components
|
|
2084
|
-
* that should be rendered within the current application
|
|
2085
|
-
* context. Most common type for embedded authentication.
|
|
2086
|
-
*/
|
|
2087
|
-
EmbeddedSignInFlowType$2["View"] = "VIEW";
|
|
2088
|
-
return EmbeddedSignInFlowType$2;
|
|
2089
|
-
}({});
|
|
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
|
-
|
|
2131
|
-
//#endregion
|
|
2132
|
-
//#region src/api/v2/executeEmbeddedSignInFlowV2.ts
|
|
2133
|
-
const executeEmbeddedSignInFlowV2 = async ({ url, baseUrl, payload, authId,...requestConfig }) => {
|
|
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.");
|
|
2135
|
-
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2136
|
-
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2137
|
-
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
2138
|
-
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2139
|
-
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
2140
|
-
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
2141
|
-
...basePayload,
|
|
2142
|
-
verbose: true
|
|
2143
|
-
} : basePayload;
|
|
2144
|
-
const response = await fetch(endpoint, {
|
|
2145
|
-
...requestConfig,
|
|
2146
|
-
body: JSON.stringify(requestPayload),
|
|
2147
|
-
headers: {
|
|
2148
|
-
Accept: "application/json",
|
|
2149
|
-
"Content-Type": "application/json",
|
|
2150
|
-
...requestConfig.headers
|
|
2151
|
-
},
|
|
2152
|
-
method: requestConfig.method || "POST"
|
|
2153
|
-
});
|
|
2154
|
-
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedSignInFlow-ResponseError-001", "javascript", response.status, response.statusText, "Authorization request failed");
|
|
2155
|
-
const flowResponse = await response.json();
|
|
2156
|
-
if (flowResponse.flowStatus === EmbeddedSignInFlowStatus$1.Complete && flowResponse.assertion && authId) try {
|
|
2157
|
-
const oauth2Response = await fetch(`${baseUrl}/oauth2/auth/callback`, {
|
|
2158
|
-
body: JSON.stringify({
|
|
2159
|
-
assertion: flowResponse.assertion,
|
|
2160
|
-
authId
|
|
2161
|
-
}),
|
|
2162
|
-
credentials: "include",
|
|
2163
|
-
headers: {
|
|
2164
|
-
Accept: "application/json",
|
|
2165
|
-
"Content-Type": "application/json",
|
|
2166
|
-
...requestConfig.headers
|
|
2167
|
-
},
|
|
2168
|
-
method: "POST"
|
|
2169
|
-
});
|
|
2170
|
-
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignInFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
2171
|
-
const oauth2Result = await oauth2Response.json();
|
|
2172
|
-
return {
|
|
2173
|
-
flowStatus: flowResponse.flowStatus,
|
|
2174
|
-
redirectUrl: oauth2Result["redirect_uri"]
|
|
2175
|
-
};
|
|
2176
|
-
} catch (authError) {
|
|
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");
|
|
2179
|
-
}
|
|
2180
|
-
return flowResponse;
|
|
2181
|
-
};
|
|
2182
|
-
var executeEmbeddedSignInFlowV2_default = executeEmbeddedSignInFlowV2;
|
|
2183
|
-
|
|
2184
|
-
//#endregion
|
|
2185
|
-
//#region src/models/v2/embedded-signup-flow-v2.ts
|
|
2186
|
-
/**
|
|
2187
|
-
* Status enumeration for ThunderID embedded sign-up flow operations.
|
|
2188
|
-
*
|
|
2189
|
-
* These statuses indicate the current state of the registration flow and determine
|
|
2190
|
-
* the next action required by the client application. Each status provides specific
|
|
2191
|
-
* guidance on how to proceed with the user registration process.
|
|
2192
|
-
*
|
|
2193
|
-
* @example
|
|
2194
|
-
* ```typescript
|
|
2195
|
-
* switch (response.flowStatus) {
|
|
2196
|
-
* case EmbeddedSignUpFlowStatus.Incomplete:
|
|
2197
|
-
* // More user input needed - render registration form components
|
|
2198
|
-
* break;
|
|
2199
|
-
* case EmbeddedSignUpFlowStatus.Complete:
|
|
2200
|
-
* // Registration successful - handle completion
|
|
2201
|
-
* break;
|
|
2202
|
-
* case EmbeddedSignUpFlowStatus.Error:
|
|
2203
|
-
* // Registration failed - show error details
|
|
2204
|
-
* const errorResponse = response as EmbeddedSignUpFlowErrorResponse;
|
|
2205
|
-
* showError(errorResponse.error.description.defaultValue);
|
|
2206
|
-
* break;
|
|
2207
|
-
* }
|
|
2208
|
-
* ```
|
|
2209
|
-
*
|
|
2210
|
-
* @experimental Part of the new ThunderID API
|
|
2211
|
-
*/
|
|
2212
|
-
let EmbeddedSignUpFlowStatus = /* @__PURE__ */ function(EmbeddedSignUpFlowStatus$1) {
|
|
2213
|
-
/**
|
|
2214
|
-
* Sign-up flow completed successfully.
|
|
2215
|
-
*
|
|
2216
|
-
* The user has successfully registered and the flow can proceed to
|
|
2217
|
-
* OAuth2 completion or redirection. Check for redirectUrl or assertion
|
|
2218
|
-
* data in the response for next steps.
|
|
2219
|
-
*/
|
|
2220
|
-
EmbeddedSignUpFlowStatus$1["Complete"] = "COMPLETE";
|
|
2221
|
-
/**
|
|
2222
|
-
* Sign-up flow encountered an error and cannot proceed.
|
|
2223
|
-
*
|
|
2224
|
-
* Registration failed due to validation errors, duplicate user,
|
|
2225
|
-
* system errors, or other issues. The response will be of type
|
|
2226
|
-
* `EmbeddedSignUpFlowErrorResponse` containing detailed failure
|
|
2227
|
-
* information that can be displayed to the user.
|
|
2228
|
-
*
|
|
2229
|
-
* @see {@link EmbeddedSignUpFlowErrorResponse} for error response structure
|
|
2230
|
-
*/
|
|
2231
|
-
EmbeddedSignUpFlowStatus$1["Error"] = "ERROR";
|
|
2232
|
-
/**
|
|
2233
|
-
* Sign-up flow requires additional user input.
|
|
2234
|
-
*
|
|
2235
|
-
* More registration steps are needed. The response will contain
|
|
2236
|
-
* components in data.meta.components that should be rendered to
|
|
2237
|
-
* collect additional user information (e.g., profile data, verification).
|
|
2238
|
-
*/
|
|
2239
|
-
EmbeddedSignUpFlowStatus$1["Incomplete"] = "INCOMPLETE";
|
|
2240
|
-
return EmbeddedSignUpFlowStatus$1;
|
|
2241
|
-
}({});
|
|
2242
|
-
/**
|
|
2243
|
-
* Type enumeration for ThunderID embedded sign-up flow responses.
|
|
2244
|
-
*
|
|
2245
|
-
* Determines the nature of the registration flow response and how the client
|
|
2246
|
-
* should handle the returned data. This affects both UI rendering and flow
|
|
2247
|
-
* continuation logic during the user registration process.
|
|
2248
|
-
*
|
|
2249
|
-
* @experimental Part of the new ThunderID API
|
|
2250
|
-
*/
|
|
2251
|
-
let EmbeddedSignUpFlowType = /* @__PURE__ */ function(EmbeddedSignUpFlowType$1) {
|
|
2252
|
-
/**
|
|
2253
|
-
* Response requires external redirection.
|
|
2254
|
-
*
|
|
2255
|
-
* Used for social registration providers, external identity providers,
|
|
2256
|
-
* or other flows that require navigating to an external URL during
|
|
2257
|
-
* the registration process. The response will contain redirection information.
|
|
2258
|
-
*/
|
|
2259
|
-
EmbeddedSignUpFlowType$1["Redirection"] = "REDIRECTION";
|
|
2260
|
-
/**
|
|
2261
|
-
* Response contains view components for rendering.
|
|
2262
|
-
*
|
|
2263
|
-
* Standard embedded registration flow response containing UI components
|
|
2264
|
-
* that should be rendered within the current application context.
|
|
2265
|
-
* Most common type for embedded user registration.
|
|
2266
|
-
*/
|
|
2267
|
-
EmbeddedSignUpFlowType$1["View"] = "VIEW";
|
|
2268
|
-
return EmbeddedSignUpFlowType$1;
|
|
2269
|
-
}({});
|
|
2270
|
-
|
|
2271
|
-
//#endregion
|
|
2272
|
-
//#region src/api/v2/executeEmbeddedSignUpFlowV2.ts
|
|
2273
|
-
const executeEmbeddedSignUpFlowV2 = async ({ url, baseUrl, payload, authId,...requestConfig }) => {
|
|
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.");
|
|
2275
|
-
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2276
|
-
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2277
|
-
const isNewFlowStart = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload;
|
|
2278
|
-
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2279
|
-
const basePayload = isNewFlowStart ? injectRequestedPermissions_default(cleanPayload) : cleanPayload;
|
|
2280
|
-
const requestPayload = isNewFlowStart || hasOnlyFlowId ? {
|
|
2281
|
-
...basePayload,
|
|
2282
|
-
verbose: true
|
|
2283
|
-
} : basePayload;
|
|
2284
|
-
const response = await fetch(endpoint, {
|
|
2285
|
-
...requestConfig,
|
|
2286
|
-
body: JSON.stringify(requestPayload),
|
|
2287
|
-
headers: {
|
|
2288
|
-
Accept: "application/json",
|
|
2289
|
-
"Content-Type": "application/json",
|
|
2290
|
-
...requestConfig.headers
|
|
2291
|
-
},
|
|
2292
|
-
method: requestConfig.method || "POST"
|
|
2293
|
-
});
|
|
2294
|
-
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedSignUpFlow-ResponseError-001", "javascript", response.status, response.statusText, "Registration request failed");
|
|
2295
|
-
const flowResponse = await response.json();
|
|
2296
|
-
if (flowResponse.flowStatus === EmbeddedSignUpFlowStatus.Complete && flowResponse.assertion && authId) try {
|
|
2297
|
-
const oauth2Response = await fetch(`${baseUrl}/oauth2/auth/callback`, {
|
|
2298
|
-
body: JSON.stringify({
|
|
2299
|
-
assertion: flowResponse.assertion,
|
|
2300
|
-
authId
|
|
2301
|
-
}),
|
|
2302
|
-
credentials: "include",
|
|
2303
|
-
headers: {
|
|
2304
|
-
Accept: "application/json",
|
|
2305
|
-
"Content-Type": "application/json",
|
|
2306
|
-
...requestConfig.headers
|
|
2307
|
-
},
|
|
2308
|
-
method: "POST"
|
|
2309
|
-
});
|
|
2310
|
-
if (!oauth2Response.ok) throw new ThunderIDAPIError(await oauth2Response.text(), "executeEmbeddedSignUpFlow-OAuth2Error-002", "javascript", oauth2Response.status, oauth2Response.statusText, "OAuth2 authorization failed");
|
|
2311
|
-
const oauth2Result = await oauth2Response.json();
|
|
2312
|
-
return {
|
|
2313
|
-
flowStatus: flowResponse.flowStatus,
|
|
2314
|
-
redirectUrl: oauth2Result["redirect_uri"]
|
|
2315
|
-
};
|
|
2316
|
-
} catch (authError) {
|
|
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");
|
|
2319
|
-
}
|
|
2320
|
-
return flowResponse;
|
|
2321
|
-
};
|
|
2322
|
-
var executeEmbeddedSignUpFlowV2_default = executeEmbeddedSignUpFlowV2;
|
|
2323
|
-
|
|
2324
|
-
//#endregion
|
|
2325
|
-
//#region src/api/v2/executeEmbeddedRecoveryFlowV2.ts
|
|
2326
|
-
/**
|
|
2327
|
-
* Executes an embedded recovery flow by sending a request to the flow execution endpoint.
|
|
2328
|
-
*
|
|
2329
|
-
* This function handles password-recovery and account-recovery flows driven by the
|
|
2330
|
-
* ThunderID server. The server returns UI components for each step (e.g. username
|
|
2331
|
-
* collection, OTP verification, password reset) and this function forwards the
|
|
2332
|
-
* user's responses back to the server.
|
|
2333
|
-
*
|
|
2334
|
-
* @param requestConfig - Request configuration containing URL, payload, and optional headers.
|
|
2335
|
-
* @returns A promise that resolves with the flow execution response.
|
|
2336
|
-
* @throws ThunderIDAPIError when the request fails or a payload is missing.
|
|
2337
|
-
*
|
|
2338
|
-
* @example
|
|
2339
|
-
* ```typescript
|
|
2340
|
-
* // Initiate recovery flow
|
|
2341
|
-
* const response = await executeEmbeddedRecoveryFlowV2({
|
|
2342
|
-
* baseUrl: 'https://localhost:8090',
|
|
2343
|
-
* payload: {
|
|
2344
|
-
* flowType: 'RECOVERY',
|
|
2345
|
-
* applicationId: 'my-app-id',
|
|
2346
|
-
* },
|
|
2347
|
-
* });
|
|
2348
|
-
*
|
|
2349
|
-
* // Continue recovery flow with user input
|
|
2350
|
-
* const nextResponse = await executeEmbeddedRecoveryFlowV2({
|
|
2351
|
-
* baseUrl: 'https://localhost:8090',
|
|
2352
|
-
* payload: {
|
|
2353
|
-
* executionId: response.executionId,
|
|
2354
|
-
* action: 'submit',
|
|
2355
|
-
* inputs: { username: 'user@example.com' },
|
|
2356
|
-
* challengeToken: response.challengeToken,
|
|
2357
|
-
* },
|
|
2358
|
-
* });
|
|
2359
|
-
* ```
|
|
2360
|
-
*/
|
|
2361
|
-
const executeEmbeddedRecoveryFlowV2 = async ({ url, baseUrl, payload,...requestConfig }) => {
|
|
2362
|
-
if (!payload) throw new ThunderIDAPIError("Recovery payload is required", "executeEmbeddedRecoveryFlow-ValidationError-002", "javascript", 400, "If a recovery payload is not provided, the request cannot be constructed correctly.");
|
|
2363
|
-
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2364
|
-
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2365
|
-
const hasOnlyAppIdAndFlowType = typeof cleanPayload === "object" && cleanPayload !== null && "applicationId" in cleanPayload && "flowType" in cleanPayload && Object.keys(cleanPayload).length === 2;
|
|
2366
|
-
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2367
|
-
const requestPayload = hasOnlyAppIdAndFlowType || hasOnlyFlowId ? {
|
|
2368
|
-
...cleanPayload,
|
|
2369
|
-
verbose: true
|
|
2370
|
-
} : cleanPayload;
|
|
2371
|
-
const response = await fetch(endpoint, {
|
|
2372
|
-
...requestConfig,
|
|
2373
|
-
body: JSON.stringify(requestPayload),
|
|
2374
|
-
headers: {
|
|
2375
|
-
Accept: "application/json",
|
|
2376
|
-
"Content-Type": "application/json",
|
|
2377
|
-
...requestConfig.headers
|
|
2378
|
-
},
|
|
2379
|
-
method: requestConfig.method || "POST"
|
|
2380
|
-
});
|
|
2381
|
-
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedRecoveryFlow-ResponseError-001", "javascript", response.status, response.statusText, "Recovery request failed");
|
|
2382
|
-
return await response.json();
|
|
2383
|
-
};
|
|
2384
|
-
var executeEmbeddedRecoveryFlowV2_default = executeEmbeddedRecoveryFlowV2;
|
|
2385
|
-
|
|
2386
|
-
//#endregion
|
|
2387
|
-
//#region src/api/v2/executeEmbeddedUserOnboardingFlowV2.ts
|
|
2388
|
-
/**
|
|
2389
|
-
* Executes an embedded user onboarding flow by sending a request to the flow execution endpoint.
|
|
2390
|
-
*
|
|
2391
|
-
* This function handles both:
|
|
2392
|
-
* - Admin flow: Initiates onboarding, collects user details, generates invite link
|
|
2393
|
-
* - End-user flow: Validates invite token and allows password setting
|
|
2394
|
-
*
|
|
2395
|
-
* @param requestConfig - Request configuration object containing URL, payload, and optional auth token.
|
|
2396
|
-
* @returns A promise that resolves with the flow execution response.
|
|
2397
|
-
* @throws ThunderIDAPIError when the request fails or URL is invalid.
|
|
2398
|
-
*
|
|
2399
|
-
* @example
|
|
2400
|
-
* ```typescript
|
|
2401
|
-
* // Admin initiating user onboarding (requires auth token)
|
|
2402
|
-
* const response = await executeEmbeddedUserOnboardingFlowV2({
|
|
2403
|
-
* baseUrl: "https://api.thunder.io",
|
|
2404
|
-
* payload: {
|
|
2405
|
-
* flowType: "USER_ONBOARDING"
|
|
2406
|
-
* },
|
|
2407
|
-
* headers: {
|
|
2408
|
-
* Authorization: `Bearer ${accessToken}`
|
|
2409
|
-
* }
|
|
2410
|
-
* });
|
|
2411
|
-
*
|
|
2412
|
-
* // End-user accepting invite (no auth required)
|
|
2413
|
-
* const response = await executeEmbeddedUserOnboardingFlowV2({
|
|
2414
|
-
* baseUrl: "https://api.thunder.io",
|
|
2415
|
-
* payload: {
|
|
2416
|
-
* executionId: "flow-id-from-url",
|
|
2417
|
-
* inputs: { inviteToken: "token-from-url" }
|
|
2418
|
-
* }
|
|
2419
|
-
* });
|
|
2420
|
-
* ```
|
|
2421
|
-
*/
|
|
2422
|
-
const executeEmbeddedUserOnboardingFlowV2 = async ({ url, baseUrl, payload,...requestConfig }) => {
|
|
2423
|
-
if (!payload) throw new ThunderIDAPIError("User onboarding payload is required", "executeEmbeddedUserOnboardingFlow-ValidationError-002", "javascript", 400, "If a user onboarding payload is not provided, the request cannot be constructed correctly.");
|
|
2424
|
-
const endpoint = url ?? `${baseUrl}/flow/execute`;
|
|
2425
|
-
const cleanPayload = typeof payload === "object" && payload !== null ? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "verbose")) : payload;
|
|
2426
|
-
const hasOnlyFlowType = typeof cleanPayload === "object" && cleanPayload !== null && "flowType" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2427
|
-
const hasOnlyFlowId = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && Object.keys(cleanPayload).length === 1;
|
|
2428
|
-
const hasFlowIdWithInputs = typeof cleanPayload === "object" && cleanPayload !== null && "executionId" in cleanPayload && "inputs" in cleanPayload;
|
|
2429
|
-
const requestPayload = hasOnlyFlowType || hasOnlyFlowId || hasFlowIdWithInputs ? {
|
|
2430
|
-
...cleanPayload,
|
|
2431
|
-
verbose: true
|
|
2432
|
-
} : cleanPayload;
|
|
2433
|
-
if ("flowType" in requestPayload && requestPayload["flowType"] !== EmbeddedFlowType.UserOnboarding) requestPayload["flowType"] = EmbeddedFlowType.UserOnboarding;
|
|
2434
|
-
const response = await fetch(endpoint, {
|
|
2435
|
-
...requestConfig,
|
|
2436
|
-
body: JSON.stringify(requestPayload),
|
|
2437
|
-
headers: {
|
|
2438
|
-
Accept: "application/json",
|
|
2439
|
-
"Content-Type": "application/json",
|
|
2440
|
-
...requestConfig.headers
|
|
2441
|
-
},
|
|
2442
|
-
method: requestConfig.method || "POST"
|
|
2443
|
-
});
|
|
2444
|
-
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "executeEmbeddedUserOnboardingFlow-ResponseError-001", "javascript", response.status, response.statusText, "User onboarding request failed");
|
|
2445
|
-
return await response.json();
|
|
2446
|
-
};
|
|
2447
|
-
var executeEmbeddedUserOnboardingFlowV2_default = executeEmbeddedUserOnboardingFlowV2;
|
|
2448
|
-
|
|
2449
|
-
//#endregion
|
|
2450
|
-
//#region src/api/v2/getFlowMetaV2.ts
|
|
2451
|
-
/**
|
|
2452
|
-
* Fetches aggregated flow metadata from the `GET /flow/meta` endpoint.
|
|
2453
|
-
*
|
|
2454
|
-
* The response includes:
|
|
2455
|
-
* - Application or OU details depending on the `type` parameter
|
|
2456
|
-
* - Resolved design configuration (theme and layout)
|
|
2457
|
-
* - i18n translations filtered by `language` and `namespace`
|
|
2458
|
-
* - Registration flow enablement status
|
|
2459
|
-
*
|
|
2460
|
-
* @param config - Request configuration including `baseUrl`/`url`, and optional
|
|
2461
|
-
* `type`, `id`, `language`, and `namespace` filters. When `type`
|
|
2462
|
-
* and `id` are omitted the server returns i18n-only metadata.
|
|
2463
|
-
* @returns A promise that resolves to the {@link FlowMetadataResponse}.
|
|
2464
|
-
*
|
|
2465
|
-
* @throws {ThunderIDAPIError} When the server returns a non-OK response.
|
|
2466
|
-
*
|
|
2467
|
-
* @example
|
|
2468
|
-
* ```typescript
|
|
2469
|
-
* import getFlowMetaV2 from './api/v2/getFlowMetaV2';
|
|
2470
|
-
* import { FlowMetaType } from './models/v2/flow-meta-v2';
|
|
2471
|
-
*
|
|
2472
|
-
* const meta = await getFlowMetaV2({
|
|
2473
|
-
* baseUrl: 'https://localhost:8090',
|
|
2474
|
-
* type: FlowMetaType.App,
|
|
2475
|
-
* id: '60a9b38b-6eba-9f9e-55f9-267067de4680',
|
|
2476
|
-
* language: 'en',
|
|
2477
|
-
* namespace: 'auth',
|
|
2478
|
-
* });
|
|
2479
|
-
*
|
|
2480
|
-
* console.log(meta.application?.name);
|
|
2481
|
-
* console.log(meta.i18n.translations);
|
|
2482
|
-
* ```
|
|
2483
|
-
*
|
|
2484
|
-
* @experimental This function targets the ThunderID V2 platform API
|
|
2485
|
-
*/
|
|
2486
|
-
const getFlowMetaV2 = async ({ url, baseUrl, type, id, language, namespace,...requestConfig }) => {
|
|
2487
|
-
const queryParams = new URLSearchParams({
|
|
2488
|
-
...id ? { id } : {},
|
|
2489
|
-
...type ? { type } : {},
|
|
2490
|
-
...language ? { language } : {},
|
|
2491
|
-
...namespace ? { namespace } : {}
|
|
2492
|
-
});
|
|
2493
|
-
const endpoint = `${url ?? `${baseUrl}/flow/meta`}?${queryParams.toString()}`;
|
|
2494
|
-
const response = await fetch(endpoint, {
|
|
2495
|
-
...requestConfig,
|
|
2496
|
-
headers: {
|
|
2497
|
-
Accept: "application/json",
|
|
2498
|
-
...requestConfig.headers
|
|
2499
|
-
},
|
|
2500
|
-
method: "GET"
|
|
2501
|
-
});
|
|
2502
|
-
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "getFlowMetaV2-ResponseError-001", "javascript", response.status, response.statusText, "Flow metadata request failed");
|
|
2503
|
-
return await response.json();
|
|
2504
|
-
};
|
|
2505
|
-
var getFlowMetaV2_default = getFlowMetaV2;
|
|
2506
|
-
|
|
2507
|
-
//#endregion
|
|
2508
|
-
//#region src/api/v2/getOrganizationUnitChildren.ts
|
|
2509
|
-
/**
|
|
2510
|
-
* Retrieves the child organization units of a given parent OU.
|
|
2511
|
-
*
|
|
2512
|
-
* @param config - Request configuration including `baseUrl`/`url`, `organizationUnitId`,
|
|
2513
|
-
* and optional `limit`/`offset` pagination parameters.
|
|
2514
|
-
* @returns A promise that resolves with the paginated list of child organization units.
|
|
2515
|
-
*
|
|
2516
|
-
* @throws {ThunderIDAPIError} When the server returns a non-OK response.
|
|
2517
|
-
*
|
|
2518
|
-
* @example
|
|
2519
|
-
* ```typescript
|
|
2520
|
-
* const children = await getOrganizationUnitChildren({
|
|
2521
|
-
* baseUrl: 'https://localhost:8090',
|
|
2522
|
-
* organizationUnitId: '0d5e071b-d3d3-475d-b3c6-1a20ee2fa9b1',
|
|
2523
|
-
* limit: 10,
|
|
2524
|
-
* offset: 0,
|
|
2525
|
-
* });
|
|
2526
|
-
* console.log(children.organizationUnits);
|
|
2527
|
-
* ```
|
|
2528
|
-
*
|
|
2529
|
-
* @experimental This function targets the ThunderID V2 platform API
|
|
2530
|
-
*/
|
|
2531
|
-
const getOrganizationUnitChildren = async ({ url, baseUrl, organizationUnitId, limit = 10, offset = 0,...requestConfig }) => {
|
|
2532
|
-
if (!organizationUnitId) throw new ThunderIDAPIError("Organization Unit ID is required", "getOrganizationUnitChildren-ValidationError-001", "javascript", 400, "If an organization unit ID is not provided, the request cannot be constructed correctly.");
|
|
2533
|
-
const queryParams = new URLSearchParams({
|
|
2534
|
-
limit: String(limit),
|
|
2535
|
-
offset: String(offset)
|
|
2536
|
-
});
|
|
2537
|
-
const endpoint = url ?? `${baseUrl}/organization-units/${organizationUnitId}/ous?${queryParams.toString()}`;
|
|
2538
|
-
const response = await fetch(endpoint, {
|
|
2539
|
-
...requestConfig,
|
|
2540
|
-
headers: {
|
|
2541
|
-
Accept: "application/json",
|
|
2542
|
-
...requestConfig.headers
|
|
2543
|
-
},
|
|
2544
|
-
method: "GET"
|
|
2545
|
-
});
|
|
2546
|
-
if (!response.ok) throw new ThunderIDAPIError(await response.text(), "getOrganizationUnitChildren-ResponseError-001", "javascript", response.status, response.statusText, "Failed to fetch organization unit children");
|
|
2547
|
-
return await response.json();
|
|
2356
|
+
};
|
|
2357
|
+
try {
|
|
2358
|
+
const response = await fetchFn(resolvedUrl, requestInit);
|
|
2359
|
+
if (!response?.ok) {
|
|
2360
|
+
const errorText = await response.text();
|
|
2361
|
+
let errorDescription;
|
|
2362
|
+
try {
|
|
2363
|
+
const errorBody = JSON.parse(errorText);
|
|
2364
|
+
errorDescription = errorBody?.description || errorBody?.message || errorText;
|
|
2365
|
+
} catch {
|
|
2366
|
+
errorDescription = errorText;
|
|
2367
|
+
}
|
|
2368
|
+
logger_default.warn(`[BrandingError] ${errorDescription} To resolve this issue, please configure branding preferences in the ThunderID console. If you want to suppress this warning and stop fetching branding preferences, set \`<ThunderIDProvider>\` -> \`preferences\` -> \`theme\` -> \`inheritFromBranding\` to false.`);
|
|
2369
|
+
throw new ThunderIDAPIError(errorText, "getBrandingPreference-ResponseError-001", "javascript", response.status, response.statusText, "Failed to get branding preference");
|
|
2370
|
+
}
|
|
2371
|
+
return await response.json();
|
|
2372
|
+
} catch (error$1) {
|
|
2373
|
+
if (error$1 instanceof ThunderIDAPIError) throw error$1;
|
|
2374
|
+
throw new ThunderIDAPIError(`Network or parsing error: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`, "getBrandingPreference-NetworkError-001", "javascript", 0, "Network Error");
|
|
2375
|
+
}
|
|
2548
2376
|
};
|
|
2549
|
-
var
|
|
2377
|
+
var getBrandingPreference_default = getBrandingPreference;
|
|
2550
2378
|
|
|
2551
2379
|
//#endregion
|
|
2552
2380
|
//#region src/constants/ApplicationNativeAuthenticationConstants.ts
|
|
@@ -2688,198 +2516,52 @@ const VendorConstants = { VENDOR_PREFIX: "thunderid" };
|
|
|
2688
2516
|
var VendorConstants_default = VendorConstants;
|
|
2689
2517
|
|
|
2690
2518
|
//#endregion
|
|
2691
|
-
//#region src/
|
|
2692
|
-
let EmbeddedSignInFlowStatus = /* @__PURE__ */ function(EmbeddedSignInFlowStatus$2) {
|
|
2693
|
-
EmbeddedSignInFlowStatus$2["FailCompleted"] = "FAIL_COMPLETED";
|
|
2694
|
-
EmbeddedSignInFlowStatus$2["FailIncomplete"] = "FAIL_INCOMPLETE";
|
|
2695
|
-
EmbeddedSignInFlowStatus$2["Incomplete"] = "INCOMPLETE";
|
|
2696
|
-
EmbeddedSignInFlowStatus$2["SuccessCompleted"] = "SUCCESS_COMPLETED";
|
|
2697
|
-
return EmbeddedSignInFlowStatus$2;
|
|
2698
|
-
}({});
|
|
2699
|
-
let EmbeddedSignInFlowType = /* @__PURE__ */ function(EmbeddedSignInFlowType$2) {
|
|
2700
|
-
EmbeddedSignInFlowType$2["Authentication"] = "AUTHENTICATION";
|
|
2701
|
-
return EmbeddedSignInFlowType$2;
|
|
2702
|
-
}({});
|
|
2703
|
-
let EmbeddedSignInFlowStepType = /* @__PURE__ */ function(EmbeddedSignInFlowStepType$1) {
|
|
2704
|
-
EmbeddedSignInFlowStepType$1["AuthenticatorPrompt"] = "AUTHENTICATOR_PROMPT";
|
|
2705
|
-
EmbeddedSignInFlowStepType$1["MultiOptionsPrompt"] = "MULTI_OPTIONS_PROMPT";
|
|
2706
|
-
return EmbeddedSignInFlowStepType$1;
|
|
2707
|
-
}({});
|
|
2708
|
-
let EmbeddedSignInFlowAuthenticatorParamType = /* @__PURE__ */ function(EmbeddedSignInFlowAuthenticatorParamType$1) {
|
|
2709
|
-
EmbeddedSignInFlowAuthenticatorParamType$1["Integer"] = "INTEGER";
|
|
2710
|
-
EmbeddedSignInFlowAuthenticatorParamType$1["MultiValued"] = "MULTI_VALUED";
|
|
2711
|
-
EmbeddedSignInFlowAuthenticatorParamType$1["String"] = "STRING";
|
|
2712
|
-
return EmbeddedSignInFlowAuthenticatorParamType$1;
|
|
2713
|
-
}({});
|
|
2714
|
-
let EmbeddedSignInFlowAuthenticatorExtendedParamType = /* @__PURE__ */ function(EmbeddedSignInFlowAuthenticatorExtendedParamType$1) {
|
|
2715
|
-
EmbeddedSignInFlowAuthenticatorExtendedParamType$1["Otp"] = "OTPCode";
|
|
2716
|
-
return EmbeddedSignInFlowAuthenticatorExtendedParamType$1;
|
|
2717
|
-
}({});
|
|
2718
|
-
let EmbeddedSignInFlowAuthenticatorKnownIdPType = /* @__PURE__ */ function(EmbeddedSignInFlowAuthenticatorKnownIdPType$1) {
|
|
2719
|
-
EmbeddedSignInFlowAuthenticatorKnownIdPType$1["Local"] = "LOCAL";
|
|
2720
|
-
return EmbeddedSignInFlowAuthenticatorKnownIdPType$1;
|
|
2721
|
-
}({});
|
|
2722
|
-
let EmbeddedSignInFlowAuthenticatorPromptType = /* @__PURE__ */ function(EmbeddedSignInFlowAuthenticatorPromptType$1) {
|
|
2723
|
-
/**
|
|
2724
|
-
* Prompt for internal system use, such as API keys or tokens.
|
|
2725
|
-
*/
|
|
2726
|
-
EmbeddedSignInFlowAuthenticatorPromptType$1["InternalPrompt"] = "INTERNAL_PROMPT";
|
|
2727
|
-
/**
|
|
2728
|
-
* Prompt for redirection to another page or service.
|
|
2729
|
-
*/
|
|
2730
|
-
EmbeddedSignInFlowAuthenticatorPromptType$1["RedirectionPrompt"] = "REDIRECTION_PROMPT";
|
|
2731
|
-
/**
|
|
2732
|
-
* Prompt for user input, typically for username/password or similar credentials.
|
|
2733
|
-
*/
|
|
2734
|
-
EmbeddedSignInFlowAuthenticatorPromptType$1["UserPrompt"] = "USER_PROMPT";
|
|
2735
|
-
return EmbeddedSignInFlowAuthenticatorPromptType$1;
|
|
2736
|
-
}({});
|
|
2737
|
-
|
|
2738
|
-
//#endregion
|
|
2739
|
-
//#region src/models/v2/embedded-flow-v2.ts
|
|
2519
|
+
//#region src/errors/ThunderIDRuntimeError.ts
|
|
2740
2520
|
/**
|
|
2741
|
-
*
|
|
2742
|
-
*
|
|
2743
|
-
*
|
|
2744
|
-
* as part of the embedded authentication flows. Each type corresponds
|
|
2745
|
-
* to a specific UI element with its own behavior and properties.
|
|
2521
|
+
* Base class for all runtime errors in ThunderID. This class extends ThunderIDError
|
|
2522
|
+
* and adds support for additional error details. Use this class for errors that occur
|
|
2523
|
+
* during runtime execution that are not related to API calls.
|
|
2746
2524
|
*
|
|
2747
2525
|
* @example
|
|
2748
2526
|
* ```typescript
|
|
2749
|
-
*
|
|
2750
|
-
*
|
|
2751
|
-
*
|
|
2752
|
-
*
|
|
2753
|
-
*
|
|
2754
|
-
* }
|
|
2527
|
+
* throw new ThunderIDRuntimeError(
|
|
2528
|
+
* "Failed to parse configuration",
|
|
2529
|
+
* "CONFIG_PARSE_ERROR",
|
|
2530
|
+
* { invalidField: "redirectUri" }
|
|
2531
|
+
* );
|
|
2755
2532
|
* ```
|
|
2756
|
-
*
|
|
2757
|
-
* @experimental This API may change in future versions
|
|
2758
|
-
*/
|
|
2759
|
-
let EmbeddedFlowComponentType$1 = /* @__PURE__ */ function(EmbeddedFlowComponentType$2) {
|
|
2760
|
-
/** Interactive action component (buttons, links) for user interactions */
|
|
2761
|
-
EmbeddedFlowComponentType$2["Action"] = "ACTION";
|
|
2762
|
-
/** Container block component that groups other components */
|
|
2763
|
-
EmbeddedFlowComponentType$2["Block"] = "BLOCK";
|
|
2764
|
-
/** Consent component for displaying consent purposes and attributes */
|
|
2765
|
-
EmbeddedFlowComponentType$2["Consent"] = "CONSENT";
|
|
2766
|
-
/** Copyable text display component that shows text with a copy-to-clipboard action */
|
|
2767
|
-
EmbeddedFlowComponentType$2["CopyableText"] = "COPYABLE_TEXT";
|
|
2768
|
-
/** Divider component for visual separation of content */
|
|
2769
|
-
EmbeddedFlowComponentType$2["Divider"] = "DIVIDER";
|
|
2770
|
-
/** Email input field with validation for email addresses. */
|
|
2771
|
-
EmbeddedFlowComponentType$2["EmailInput"] = "EMAIL_INPUT";
|
|
2772
|
-
/** Icon display component for rendering named vector icons */
|
|
2773
|
-
EmbeddedFlowComponentType$2["Icon"] = "ICON";
|
|
2774
|
-
/** Image display component for logos and illustrations */
|
|
2775
|
-
EmbeddedFlowComponentType$2["Image"] = "IMAGE";
|
|
2776
|
-
/** One-time password input field for multi-factor authentication */
|
|
2777
|
-
EmbeddedFlowComponentType$2["OtpInput"] = "OTP_INPUT";
|
|
2778
|
-
/** Organization unit tree picker for selecting an OU */
|
|
2779
|
-
EmbeddedFlowComponentType$2["OuSelect"] = "OU_SELECT";
|
|
2780
|
-
/** Password input field with masking for sensitive data */
|
|
2781
|
-
EmbeddedFlowComponentType$2["PasswordInput"] = "PASSWORD_INPUT";
|
|
2782
|
-
/** Phone number input field with country code support */
|
|
2783
|
-
EmbeddedFlowComponentType$2["PhoneInput"] = "PHONE_INPUT";
|
|
2784
|
-
/** Rich text display component that renders formatted HTML content */
|
|
2785
|
-
EmbeddedFlowComponentType$2["RichText"] = "RICH_TEXT";
|
|
2786
|
-
/** Select/dropdown input component for single choice selection */
|
|
2787
|
-
EmbeddedFlowComponentType$2["Select"] = "SELECT";
|
|
2788
|
-
/** Stack layout component for arranging children in a row or column */
|
|
2789
|
-
EmbeddedFlowComponentType$2["Stack"] = "STACK";
|
|
2790
|
-
/** Text display component for labels, headings, and messages */
|
|
2791
|
-
EmbeddedFlowComponentType$2["Text"] = "TEXT";
|
|
2792
|
-
/** Standard text input field for user data entry */
|
|
2793
|
-
EmbeddedFlowComponentType$2["TextInput"] = "TEXT_INPUT";
|
|
2794
|
-
/** Timer component for displaying a countdown */
|
|
2795
|
-
EmbeddedFlowComponentType$2["Timer"] = "TIMER";
|
|
2796
|
-
/** QR code display component for wallet-based flows (e.g. OpenID4VP) */
|
|
2797
|
-
EmbeddedFlowComponentType$2["QrCode"] = "QR_CODE";
|
|
2798
|
-
return EmbeddedFlowComponentType$2;
|
|
2799
|
-
}({});
|
|
2800
|
-
/**
|
|
2801
|
-
* Action variant types for buttons and interactive elements.
|
|
2802
|
-
*
|
|
2803
|
-
* @experimental This API may change in future versions
|
|
2804
|
-
*/
|
|
2805
|
-
let EmbeddedFlowActionVariant = /* @__PURE__ */ function(EmbeddedFlowActionVariant$1) {
|
|
2806
|
-
/** Danger action button for destructive operations */
|
|
2807
|
-
EmbeddedFlowActionVariant$1["Danger"] = "DANGER";
|
|
2808
|
-
/** Info action button for informational purposes */
|
|
2809
|
-
EmbeddedFlowActionVariant$1["Info"] = "INFO";
|
|
2810
|
-
/** Link-styled action button */
|
|
2811
|
-
EmbeddedFlowActionVariant$1["Link"] = "LINK";
|
|
2812
|
-
/** Outlined action button for secondary emphasis */
|
|
2813
|
-
EmbeddedFlowActionVariant$1["Outlined"] = "OUTLINED";
|
|
2814
|
-
/** Primary action button with highest visual emphasis */
|
|
2815
|
-
EmbeddedFlowActionVariant$1["Primary"] = "PRIMARY";
|
|
2816
|
-
/** Secondary action button with moderate visual emphasis */
|
|
2817
|
-
EmbeddedFlowActionVariant$1["Secondary"] = "SECONDARY";
|
|
2818
|
-
/** Success action button for positive confirmations */
|
|
2819
|
-
EmbeddedFlowActionVariant$1["Success"] = "SUCCESS";
|
|
2820
|
-
/** Tertiary action button with minimal visual emphasis */
|
|
2821
|
-
EmbeddedFlowActionVariant$1["Tertiary"] = "TERTIARY";
|
|
2822
|
-
/** Warning action button for cautionary actions */
|
|
2823
|
-
EmbeddedFlowActionVariant$1["Warning"] = "WARNING";
|
|
2824
|
-
return EmbeddedFlowActionVariant$1;
|
|
2825
|
-
}({});
|
|
2826
|
-
/**
|
|
2827
|
-
* Text variant types for typography components.
|
|
2828
|
-
*
|
|
2829
|
-
* @experimental This API may change in future versions
|
|
2830
|
-
*/
|
|
2831
|
-
let EmbeddedFlowTextVariant = /* @__PURE__ */ function(EmbeddedFlowTextVariant$1) {
|
|
2832
|
-
/** Primary body text for main content */
|
|
2833
|
-
EmbeddedFlowTextVariant$1["Body1"] = "BODY_1";
|
|
2834
|
-
/** Secondary body text for supplementary content */
|
|
2835
|
-
EmbeddedFlowTextVariant$1["Body2"] = "BODY_2";
|
|
2836
|
-
/** Text styled for button labels */
|
|
2837
|
-
EmbeddedFlowTextVariant$1["ButtonText"] = "BUTTON_TEXT";
|
|
2838
|
-
/** Small caption text for annotations and descriptions */
|
|
2839
|
-
EmbeddedFlowTextVariant$1["Caption"] = "CAPTION";
|
|
2840
|
-
/** Largest heading level for main titles */
|
|
2841
|
-
EmbeddedFlowTextVariant$1["Heading1"] = "HEADING_1";
|
|
2842
|
-
/** Second level heading for major sections */
|
|
2843
|
-
EmbeddedFlowTextVariant$1["Heading2"] = "HEADING_2";
|
|
2844
|
-
/** Third level heading for subsections */
|
|
2845
|
-
EmbeddedFlowTextVariant$1["Heading3"] = "HEADING_3";
|
|
2846
|
-
/** Fourth level heading for minor sections */
|
|
2847
|
-
EmbeddedFlowTextVariant$1["Heading4"] = "HEADING_4";
|
|
2848
|
-
/** Fifth level heading for detailed sections */
|
|
2849
|
-
EmbeddedFlowTextVariant$1["Heading5"] = "HEADING_5";
|
|
2850
|
-
/** Smallest heading level for fine-grained sections */
|
|
2851
|
-
EmbeddedFlowTextVariant$1["Heading6"] = "HEADING_6";
|
|
2852
|
-
/** Overline text for labels and categories */
|
|
2853
|
-
EmbeddedFlowTextVariant$1["Overline"] = "OVERLINE";
|
|
2854
|
-
/** Primary subtitle text with larger emphasis */
|
|
2855
|
-
EmbeddedFlowTextVariant$1["Subtitle1"] = "SUBTITLE_1";
|
|
2856
|
-
/** Secondary subtitle text with moderate emphasis */
|
|
2857
|
-
EmbeddedFlowTextVariant$1["Subtitle2"] = "SUBTITLE_2";
|
|
2858
|
-
return EmbeddedFlowTextVariant$1;
|
|
2859
|
-
}({});
|
|
2860
|
-
/**
|
|
2861
|
-
* Event types for action components.
|
|
2862
|
-
*
|
|
2863
|
-
* @experimental This API may change in future versions
|
|
2864
2533
|
*/
|
|
2865
|
-
|
|
2866
|
-
/**
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2534
|
+
var ThunderIDRuntimeError = class extends ThunderIDError {
|
|
2535
|
+
/**
|
|
2536
|
+
* Creates an instance of ThunderIDRuntimeError.
|
|
2537
|
+
*
|
|
2538
|
+
* @param message - Human-readable description of the error
|
|
2539
|
+
* @param code - A unique error code that identifies the error type
|
|
2540
|
+
* @param details - Additional details about the error that might be helpful for debugging
|
|
2541
|
+
* @param origin - Optional. The SDK origin (e.g. 'react', 'vue'). Defaults to generic 'ThunderID'
|
|
2542
|
+
* @constructor
|
|
2543
|
+
*/
|
|
2544
|
+
constructor(message, code, origin, details) {
|
|
2545
|
+
super(message, code, origin);
|
|
2546
|
+
this.details = details;
|
|
2547
|
+
Object.defineProperty(this, "name", {
|
|
2548
|
+
configurable: true,
|
|
2549
|
+
value: "ThunderIDRuntimeError",
|
|
2550
|
+
writable: true
|
|
2551
|
+
});
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Returns a string representation of the runtime error
|
|
2555
|
+
* @returns Formatted error string with name, code, details, and message
|
|
2556
|
+
*/
|
|
2557
|
+
toString() {
|
|
2558
|
+
const details = this.details ? `\nDetails: ${JSON.stringify(this.details, null, 2)}` : "";
|
|
2559
|
+
return `[${this.name}] (code="${this.code}")${details}\nMessage: ${this.message}`;
|
|
2560
|
+
}
|
|
2561
|
+
};
|
|
2880
2562
|
|
|
2881
2563
|
//#endregion
|
|
2882
|
-
//#region src/models/
|
|
2564
|
+
//#region src/models/embedded-recovery-flow.ts
|
|
2883
2565
|
/**
|
|
2884
2566
|
* Status enumeration for the embedded recovery flow operations.
|
|
2885
2567
|
*
|
|
@@ -2920,7 +2602,7 @@ let EmbeddedRecoveryFlowType = /* @__PURE__ */ function(EmbeddedRecoveryFlowType
|
|
|
2920
2602
|
}({});
|
|
2921
2603
|
|
|
2922
2604
|
//#endregion
|
|
2923
|
-
//#region src/models/
|
|
2605
|
+
//#region src/models/flow-meta.ts
|
|
2924
2606
|
/**
|
|
2925
2607
|
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
2926
2608
|
*
|
|
@@ -3246,13 +2928,6 @@ var DefaultCrypto = class {
|
|
|
3246
2928
|
}
|
|
3247
2929
|
};
|
|
3248
2930
|
|
|
3249
|
-
//#endregion
|
|
3250
|
-
//#region src/models/agent.ts
|
|
3251
|
-
let AgentConfig;
|
|
3252
|
-
(function(_AgentConfig) {
|
|
3253
|
-
_AgentConfig.DEFAULT_AUTHENTICATOR_NAME = "Username & Password";
|
|
3254
|
-
})(AgentConfig || (AgentConfig = {}));
|
|
3255
|
-
|
|
3256
2931
|
//#endregion
|
|
3257
2932
|
//#region src/models/store.ts
|
|
3258
2933
|
/**
|
|
@@ -4224,10 +3899,10 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4224
3899
|
signInSilently(_options) {
|
|
4225
3900
|
throw new Error("Method not implemented.");
|
|
4226
3901
|
}
|
|
4227
|
-
signUp(
|
|
3902
|
+
signUp(_options) {
|
|
4228
3903
|
throw new Error("Method not implemented.");
|
|
4229
3904
|
}
|
|
4230
|
-
recover(
|
|
3905
|
+
recover() {
|
|
4231
3906
|
throw new Error("Method not implemented.");
|
|
4232
3907
|
}
|
|
4233
3908
|
switchOrganization(_organization, _sessionId) {
|
|
@@ -4597,40 +4272,11 @@ var ThunderIDJavaScriptClient = class {
|
|
|
4597
4272
|
const error$1 = Boolean(url.searchParams.get("error"));
|
|
4598
4273
|
return stateParam ? stateParam === OIDCRequestConstants_default.Params.SIGN_OUT_SUCCESS && error$1 : false;
|
|
4599
4274
|
}
|
|
4600
|
-
async getAgentToken(agentConfig) {
|
|
4601
|
-
const authorizeURL = new URL(await this.getSignInUrl({ response_mode: "direct" }));
|
|
4602
|
-
const authorizeResponse = await initializeEmbeddedSignInFlow_default({
|
|
4603
|
-
payload: Object.fromEntries(authorizeURL.searchParams.entries()),
|
|
4604
|
-
url: `${authorizeURL.origin}${authorizeURL.pathname}`
|
|
4605
|
-
});
|
|
4606
|
-
const authenticatorName = agentConfig.authenticatorName ?? AgentConfig.DEFAULT_AUTHENTICATOR_NAME;
|
|
4607
|
-
const targetAuthenticator = authorizeResponse.nextStep.authenticators.find((auth) => auth.authenticator === authenticatorName);
|
|
4608
|
-
if (!targetAuthenticator) throw new Error(`Authenticator '${authenticatorName}' not found among authentication steps.`);
|
|
4609
|
-
const authnResponse = await executeEmbeddedSignInFlow_default({
|
|
4610
|
-
baseUrl: this.baseURL,
|
|
4611
|
-
payload: {
|
|
4612
|
-
flowId: authorizeResponse.flowId,
|
|
4613
|
-
selectedAuthenticator: {
|
|
4614
|
-
authenticatorId: targetAuthenticator.authenticatorId,
|
|
4615
|
-
params: {
|
|
4616
|
-
password: agentConfig.agentSecret,
|
|
4617
|
-
username: agentConfig.agentID
|
|
4618
|
-
}
|
|
4619
|
-
}
|
|
4620
|
-
}
|
|
4621
|
-
});
|
|
4622
|
-
if (authnResponse.flowStatus !== EmbeddedSignInFlowStatus.SuccessCompleted) throw new Error("Agent authentication failed.");
|
|
4623
|
-
return this.requestAccessToken(authnResponse.authData["code"], authnResponse.authData["session_state"], authnResponse.authData["state"]);
|
|
4624
|
-
}
|
|
4625
4275
|
async getOBOSignInURL(agentConfig) {
|
|
4626
4276
|
const authURL = await this.getSignInUrl({ requested_actor: agentConfig.agentID });
|
|
4627
4277
|
if (authURL) return authURL.toString();
|
|
4628
4278
|
throw new Error("Could not build Authorize URL");
|
|
4629
4279
|
}
|
|
4630
|
-
async getOBOToken(agentConfig, authCodeResponse) {
|
|
4631
|
-
const agentToken = await this.getAgentToken(agentConfig);
|
|
4632
|
-
return this.requestAccessToken(authCodeResponse.code, authCodeResponse.session_state, authCodeResponse.state, void 0, { params: { actor_token: agentToken.accessToken } });
|
|
4633
|
-
}
|
|
4634
4280
|
};
|
|
4635
4281
|
var ThunderIDJavaScriptClient_default = ThunderIDJavaScriptClient;
|
|
4636
4282
|
|
|
@@ -5349,6 +4995,38 @@ const deriveOrganizationHandleFromBaseUrl = (baseUrl) => {
|
|
|
5349
4995
|
};
|
|
5350
4996
|
var deriveOrganizationHandleFromBaseUrl_default = deriveOrganizationHandleFromBaseUrl;
|
|
5351
4997
|
|
|
4998
|
+
//#endregion
|
|
4999
|
+
//#region src/utils/isRecognizedBaseUrlPattern.ts
|
|
5000
|
+
/**
|
|
5001
|
+
* Utility to determine if sensible ThunderID fallbacks can be used based on the given base URL.
|
|
5002
|
+
*
|
|
5003
|
+
* This checks if the URL follows the standard ThunderID pattern: /t/{orgHandle}
|
|
5004
|
+
* Returns true if sensible fallbacks (like deriving organization handle, tenant, etc.) can be used, false otherwise.
|
|
5005
|
+
*
|
|
5006
|
+
* @param baseUrl - The base URL of the ThunderID identity server (string or undefined)
|
|
5007
|
+
* @returns boolean - true if sensible fallbacks can be used, false otherwise
|
|
5008
|
+
*
|
|
5009
|
+
* @example
|
|
5010
|
+
* isRecognizedBaseUrlPattern('https://localhost:8090/t/dxlab'); // true
|
|
5011
|
+
* isRecognizedBaseUrlPattern('https://custom.example.com/auth'); // false
|
|
5012
|
+
*/
|
|
5013
|
+
const isRecognizedBaseUrlPattern = (baseUrl) => {
|
|
5014
|
+
if (!baseUrl) throw new ThunderIDRuntimeError("Base URL is required to derive if the `baseUrl` is recognized.", "isRecognizedBaseUrlPattern-ValidationError-001", "javascript", "A valid base URL must be provided to derive if the `baseUrl` is recognized to use the sensible fallbacks.");
|
|
5015
|
+
let parsedUrl;
|
|
5016
|
+
try {
|
|
5017
|
+
parsedUrl = new URL(baseUrl);
|
|
5018
|
+
} catch (error$1) {
|
|
5019
|
+
throw new ThunderIDRuntimeError(`Invalid base URL format: ${baseUrl}`, "isRecognizedBaseUrlPattern-ValidationError-002", "javascript", "The provided base URL does not conform to valid URL syntax.");
|
|
5020
|
+
}
|
|
5021
|
+
const pathSegments = parsedUrl.pathname?.split("/")?.filter((segment) => segment?.length > 0);
|
|
5022
|
+
if (pathSegments.length < 2 || pathSegments[0] !== "t") {
|
|
5023
|
+
logger_default.warn("[isRecognizedBaseUrlPattern] The provided base URL does not follow the expected URL pattern (/t/{orgHandle}).");
|
|
5024
|
+
return false;
|
|
5025
|
+
}
|
|
5026
|
+
return true;
|
|
5027
|
+
};
|
|
5028
|
+
var isRecognizedBaseUrlPattern_default = isRecognizedBaseUrlPattern;
|
|
5029
|
+
|
|
5352
5030
|
//#endregion
|
|
5353
5031
|
//#region src/utils/flattenUserSchema.ts
|
|
5354
5032
|
/**
|
|
@@ -5697,14 +5375,14 @@ var generateFlattenedUserProfile_default = generateFlattenedUserProfile;
|
|
|
5697
5375
|
* If the baseUrl is recognized (standard ThunderID pattern), constructs the sign-up URL.
|
|
5698
5376
|
* Otherwise, returns an empty string.
|
|
5699
5377
|
*
|
|
5700
|
-
* @param
|
|
5378
|
+
* @param config - The ThunderID client configuration
|
|
5701
5379
|
* @returns The sign-up URL if baseUrl is recognized, otherwise an empty string
|
|
5702
5380
|
*/
|
|
5703
5381
|
const getRedirectBasedSignUpUrl = (config) => {
|
|
5704
5382
|
const { baseUrl } = config;
|
|
5705
5383
|
if (!isRecognizedBaseUrlPattern_default(baseUrl)) return "";
|
|
5706
5384
|
let signUpBaseUrl = baseUrl;
|
|
5707
|
-
|
|
5385
|
+
try {
|
|
5708
5386
|
const url$1 = new URL(baseUrl);
|
|
5709
5387
|
if (/([a-z0-9-]+\.)*api\.thunderid\.io$/i.test(url$1.hostname)) {
|
|
5710
5388
|
url$1.hostname = url$1.hostname.replace("api.", "accounts.");
|
|
@@ -5722,7 +5400,7 @@ const getRedirectBasedSignUpUrl = (config) => {
|
|
|
5722
5400
|
var getRedirectBasedSignUpUrl_default = getRedirectBasedSignUpUrl;
|
|
5723
5401
|
|
|
5724
5402
|
//#endregion
|
|
5725
|
-
//#region src/utils/
|
|
5403
|
+
//#region src/utils/isEmojiUri.ts
|
|
5726
5404
|
/**
|
|
5727
5405
|
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
5728
5406
|
*
|
|
@@ -5758,7 +5436,7 @@ const isEmojiUri = (uri) => typeof uri === "string" && uri.startsWith(EMOJI_URI_
|
|
|
5758
5436
|
var isEmojiUri_default = isEmojiUri;
|
|
5759
5437
|
|
|
5760
5438
|
//#endregion
|
|
5761
|
-
//#region src/utils/
|
|
5439
|
+
//#region src/utils/extractEmojiFromUri.ts
|
|
5762
5440
|
/**
|
|
5763
5441
|
* Extracts the emoji character from an `emoji:` URI.
|
|
5764
5442
|
*
|
|
@@ -5811,18 +5489,6 @@ var extractEmojiFromUri_default = extractEmojiFromUri;
|
|
|
5811
5489
|
const removeTrailingSlash = (path) => path.endsWith("/") ? path.slice(0, -1) : path;
|
|
5812
5490
|
var removeTrailingSlash_default = removeTrailingSlash;
|
|
5813
5491
|
|
|
5814
|
-
//#endregion
|
|
5815
|
-
//#region src/utils/resolveFieldType.ts
|
|
5816
|
-
const resolveFieldType = (field) => {
|
|
5817
|
-
if (field.type === EmbeddedSignInFlowAuthenticatorParamType.String) {
|
|
5818
|
-
if (field.param === EmbeddedSignInFlowAuthenticatorExtendedParamType.Otp) return FieldType.Otp;
|
|
5819
|
-
if (field?.confidential) return FieldType.Password;
|
|
5820
|
-
return FieldType.Text;
|
|
5821
|
-
}
|
|
5822
|
-
throw new ThunderIDRuntimeError(`Field type is not supported: ${field.type}`, "resolveFieldType-Invalid-001", "javascript", "The provided field type is not supported. Please check the field configuration.");
|
|
5823
|
-
};
|
|
5824
|
-
var resolveFieldType_default = resolveFieldType;
|
|
5825
|
-
|
|
5826
5492
|
//#endregion
|
|
5827
5493
|
//#region src/utils/resolveFieldName.ts
|
|
5828
5494
|
const resolveFieldName = (field) => {
|
|
@@ -5832,7 +5498,7 @@ const resolveFieldName = (field) => {
|
|
|
5832
5498
|
var resolveFieldName_default = resolveFieldName;
|
|
5833
5499
|
|
|
5834
5500
|
//#endregion
|
|
5835
|
-
//#region src/utils/
|
|
5501
|
+
//#region src/utils/resolveMeta.ts
|
|
5836
5502
|
/**
|
|
5837
5503
|
* Resolves a dot-path expression against a FlowMetadataResponse object.
|
|
5838
5504
|
*
|
|
@@ -5859,7 +5525,7 @@ function resolveMeta(path, meta) {
|
|
|
5859
5525
|
}
|
|
5860
5526
|
|
|
5861
5527
|
//#endregion
|
|
5862
|
-
//#region src/utils/
|
|
5528
|
+
//#region src/utils/parseFlowTemplateLiteral.ts
|
|
5863
5529
|
/**
|
|
5864
5530
|
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
5865
5531
|
*
|
|
@@ -5955,7 +5621,7 @@ function parseFlowTemplateLiteral(content) {
|
|
|
5955
5621
|
}
|
|
5956
5622
|
|
|
5957
5623
|
//#endregion
|
|
5958
|
-
//#region src/utils/
|
|
5624
|
+
//#region src/utils/resolveFlowTemplateLiterals.ts
|
|
5959
5625
|
/**
|
|
5960
5626
|
* Global version of {@link FLOW_TEMPLATE_LITERAL_REGEX} for use with `String.prototype.replace`.
|
|
5961
5627
|
*/
|
|
@@ -5992,7 +5658,7 @@ function resolveFlowTemplateLiterals(text, { t, meta }) {
|
|
|
5992
5658
|
}
|
|
5993
5659
|
|
|
5994
5660
|
//#endregion
|
|
5995
|
-
//#region src/utils/
|
|
5661
|
+
//#region src/utils/countryCodeToFlagEmoji.ts
|
|
5996
5662
|
/**
|
|
5997
5663
|
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
5998
5664
|
*
|
|
@@ -6022,7 +5688,7 @@ function countryCodeToFlagEmoji(countryCode) {
|
|
|
6022
5688
|
}
|
|
6023
5689
|
|
|
6024
5690
|
//#endregion
|
|
6025
|
-
//#region src/utils/
|
|
5691
|
+
//#region src/utils/resolveLocaleDisplayName.ts
|
|
6026
5692
|
/**
|
|
6027
5693
|
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
6028
5694
|
*
|
|
@@ -6060,7 +5726,7 @@ function resolveLocaleDisplayName(locale, displayLocale) {
|
|
|
6060
5726
|
}
|
|
6061
5727
|
|
|
6062
5728
|
//#endregion
|
|
6063
|
-
//#region src/utils/
|
|
5729
|
+
//#region src/utils/resolveLocaleEmoji.ts
|
|
6064
5730
|
/**
|
|
6065
5731
|
* Maps BCP 47 language subtags to ISO 3166-1 alpha-2 country codes used for
|
|
6066
5732
|
* flag emoji resolution when no country subtag is present in the locale.
|
|
@@ -6125,6 +5791,81 @@ function resolveLocaleEmoji(locale) {
|
|
|
6125
5791
|
}
|
|
6126
5792
|
var resolveLocaleEmoji_default = resolveLocaleEmoji;
|
|
6127
5793
|
|
|
5794
|
+
//#endregion
|
|
5795
|
+
//#region src/utils/evaluateValidationRule.ts
|
|
5796
|
+
/**
|
|
5797
|
+
* Default i18n fallback keys returned when a `ValidationRule.message` is not provided.
|
|
5798
|
+
* Match the server-side defaults so a flow author who omits `message` sees the same
|
|
5799
|
+
* string regardless of whether the rule was evaluated client-side or server-side.
|
|
5800
|
+
*/
|
|
5801
|
+
const DEFAULT_VALIDATION_MESSAGE_KEYS = {
|
|
5802
|
+
regex: "validation.pattern.invalid",
|
|
5803
|
+
minLength: "validation.minLength.invalid",
|
|
5804
|
+
maxLength: "validation.maxLength.invalid"
|
|
5805
|
+
};
|
|
5806
|
+
/**
|
|
5807
|
+
* Evaluates a single validation rule against the given input value.
|
|
5808
|
+
*
|
|
5809
|
+
* Returns `null` when the rule passes, or the rule's `message` (or the default
|
|
5810
|
+
* fallback key if `message` is absent) when it fails.
|
|
5811
|
+
*
|
|
5812
|
+
* Behavior notes:
|
|
5813
|
+
* - **regex**: an invalid regex pattern (one that cannot be compiled) is treated as
|
|
5814
|
+
* **passing** on the client. This is lenient — the server is authoritative and
|
|
5815
|
+
* will still enforce the rule if it can compile the pattern. Failing closed in the
|
|
5816
|
+
* SDK risks denial-of-service for misconfigured flows.
|
|
5817
|
+
* - **minLength / maxLength**: compared against `value.length`. A non-numeric `value`
|
|
5818
|
+
* on the rule is treated as the rule passing.
|
|
5819
|
+
* - Unknown rule types are treated as passing (forward compatibility with future types).
|
|
5820
|
+
*/
|
|
5821
|
+
const evaluateValidationRule = (rule, value) => {
|
|
5822
|
+
const fail = () => rule.message ?? DEFAULT_VALIDATION_MESSAGE_KEYS[rule.type];
|
|
5823
|
+
switch (rule.type) {
|
|
5824
|
+
case "regex": {
|
|
5825
|
+
if (typeof rule.value !== "string" || rule.value === "") return null;
|
|
5826
|
+
let re;
|
|
5827
|
+
try {
|
|
5828
|
+
re = new RegExp(rule.value);
|
|
5829
|
+
} catch {
|
|
5830
|
+
return null;
|
|
5831
|
+
}
|
|
5832
|
+
return re.test(value) ? null : fail();
|
|
5833
|
+
}
|
|
5834
|
+
case "minLength":
|
|
5835
|
+
if (typeof rule.value !== "number" || Number.isNaN(rule.value)) return null;
|
|
5836
|
+
return value.length >= rule.value ? null : fail();
|
|
5837
|
+
case "maxLength":
|
|
5838
|
+
if (typeof rule.value !== "number" || Number.isNaN(rule.value)) return null;
|
|
5839
|
+
return value.length <= rule.value ? null : fail();
|
|
5840
|
+
default: return null;
|
|
5841
|
+
}
|
|
5842
|
+
};
|
|
5843
|
+
var evaluateValidationRule_default = evaluateValidationRule;
|
|
5844
|
+
|
|
5845
|
+
//#endregion
|
|
5846
|
+
//#region src/utils/buildValidatorFromRules.ts
|
|
5847
|
+
/**
|
|
5848
|
+
* Composes an array of `ValidationRule`s into a single validator function suitable for
|
|
5849
|
+
* `useForm`'s `FormField.validator` slot.
|
|
5850
|
+
*
|
|
5851
|
+
* The composed validator evaluates rules in declaration order and returns the **first**
|
|
5852
|
+
* failing rule's message — matching the SDK's render-prop shape of a single string per
|
|
5853
|
+
* field. When all rules pass it returns `null`.
|
|
5854
|
+
*
|
|
5855
|
+
* Returns `null` when no rules are supplied so callers can compose conditionally.
|
|
5856
|
+
*/
|
|
5857
|
+
const buildValidatorFromRules = (rules) => {
|
|
5858
|
+
if (!rules || rules.length === 0) return null;
|
|
5859
|
+
return (value) => {
|
|
5860
|
+
for (const rule of rules) {
|
|
5861
|
+
const message = evaluateValidationRule_default(rule, value);
|
|
5862
|
+
if (message !== null) return message;
|
|
5863
|
+
}
|
|
5864
|
+
return null;
|
|
5865
|
+
};
|
|
5866
|
+
};
|
|
5867
|
+
var buildValidatorFromRules_default = buildValidatorFromRules;
|
|
5868
|
+
|
|
6128
5869
|
//#endregion
|
|
6129
5870
|
//#region src/utils/withVendorCSSClassPrefix.ts
|
|
6130
5871
|
/**
|
|
@@ -6426,6 +6167,9 @@ const en_US = {
|
|
|
6426
6167
|
"elements.fields.organization.select.label": "Select Organization",
|
|
6427
6168
|
"elements.fields.organization.select.placeholder": "Choose an organization",
|
|
6428
6169
|
"validations.required.field.error": "This field is required",
|
|
6170
|
+
"validation.pattern.invalid": "This value does not match the required format.",
|
|
6171
|
+
"validation.minLength.invalid": "This value is too short.",
|
|
6172
|
+
"validation.maxLength.invalid": "This value is too long.",
|
|
6429
6173
|
"signin.heading": "Sign In",
|
|
6430
6174
|
"signin.subheading": "Welcome back! Please sign in to continue.",
|
|
6431
6175
|
"signup.heading": "Sign Up",
|
|
@@ -6536,6 +6280,9 @@ const fr_FR = {
|
|
|
6536
6280
|
"elements.fields.organization.select.label": "Sélectionner l'organisation",
|
|
6537
6281
|
"elements.fields.organization.select.placeholder": "Choisissez une organisation",
|
|
6538
6282
|
"validations.required.field.error": "Ce champ est obligatoire",
|
|
6283
|
+
"validation.pattern.invalid": "Cette valeur ne correspond pas au format requis.",
|
|
6284
|
+
"validation.minLength.invalid": "Cette valeur est trop courte.",
|
|
6285
|
+
"validation.maxLength.invalid": "Cette valeur est trop longue.",
|
|
6539
6286
|
"signin.heading": "Se connecter",
|
|
6540
6287
|
"signin.subheading": "Entrez vos identifiants pour continuer.",
|
|
6541
6288
|
"signup.heading": "S'inscrire",
|
|
@@ -6646,6 +6393,9 @@ const te_IN = {
|
|
|
6646
6393
|
"elements.fields.organization.select.label": "ఆర్గనైజేషన్ను ఎంచుకోండి",
|
|
6647
6394
|
"elements.fields.organization.select.placeholder": "సంస్థను ఎంచుకోండి",
|
|
6648
6395
|
"validations.required.field.error": "ఈ ఫీల్డ్ అవసరం",
|
|
6396
|
+
"validation.pattern.invalid": "ఈ విలువ అవసరమైన ఆకృతికి సరిపోలడం లేదు.",
|
|
6397
|
+
"validation.minLength.invalid": "ఈ విలువ చాలా చిన్నది.",
|
|
6398
|
+
"validation.maxLength.invalid": "ఈ విలువ చాలా పెద్దది.",
|
|
6649
6399
|
"signin.heading": "సైన్ ఇన్ చేయండి",
|
|
6650
6400
|
"signin.subheading": "కొనసాగించడానికి మీ వివరాలు ఇవ్వండి.",
|
|
6651
6401
|
"signup.heading": "సైన్ అప్ చేయండి",
|
|
@@ -6756,6 +6506,9 @@ const hi_IN = {
|
|
|
6756
6506
|
"elements.fields.organization.select.label": "संगठन चुनें",
|
|
6757
6507
|
"elements.fields.organization.select.placeholder": "एक संगठन चुनें",
|
|
6758
6508
|
"validations.required.field.error": "यह फील्ड आवश्यक है",
|
|
6509
|
+
"validation.pattern.invalid": "यह मान आवश्यक प्रारूप से मेल नहीं खाता।",
|
|
6510
|
+
"validation.minLength.invalid": "यह मान बहुत छोटा है।",
|
|
6511
|
+
"validation.maxLength.invalid": "यह मान बहुत लंबा है।",
|
|
6759
6512
|
"signin.heading": "साइन इन",
|
|
6760
6513
|
"signin.subheading": "जारी रखने के लिए अपनी प्रमाणिक जानकारी दर्ज करें।",
|
|
6761
6514
|
"signup.heading": "साइन अप",
|
|
@@ -6866,6 +6619,9 @@ const pt_BR = {
|
|
|
6866
6619
|
"elements.fields.organization.select.label": "Selecionar Organização",
|
|
6867
6620
|
"elements.fields.organization.select.placeholder": "Selecione uma organização",
|
|
6868
6621
|
"validations.required.field.error": "Este campo é obrigatório",
|
|
6622
|
+
"validation.pattern.invalid": "Este valor não corresponde ao formato necessário.",
|
|
6623
|
+
"validation.minLength.invalid": "Este valor é muito curto.",
|
|
6624
|
+
"validation.maxLength.invalid": "Este valor é muito longo.",
|
|
6869
6625
|
"signin.heading": "Entrar",
|
|
6870
6626
|
"signin.subheading": "Digite suas credencias para continuar.",
|
|
6871
6627
|
"signup.heading": "Cadastra-se",
|
|
@@ -6976,6 +6732,9 @@ const pt_PT = {
|
|
|
6976
6732
|
"elements.fields.organization.select.label": "Selecionar Organização",
|
|
6977
6733
|
"elements.fields.organization.select.placeholder": "Selecione uma organização",
|
|
6978
6734
|
"validations.required.field.error": "Este campo é obrigatório",
|
|
6735
|
+
"validation.pattern.invalid": "Este valor não corresponde ao formato necessário.",
|
|
6736
|
+
"validation.minLength.invalid": "Este valor é demasiado curto.",
|
|
6737
|
+
"validation.maxLength.invalid": "Este valor é demasiado longo.",
|
|
6979
6738
|
"signin.heading": "Iniciar Sessão",
|
|
6980
6739
|
"signin.subheading": "Introduza as suas credenciais para continuar.",
|
|
6981
6740
|
"signup.heading": "Registar-se",
|
|
@@ -7086,6 +6845,9 @@ const ta_IN = {
|
|
|
7086
6845
|
"elements.fields.organization.select.label": "அமைப்பை தேர்ந்தெடு",
|
|
7087
6846
|
"elements.fields.organization.select.placeholder": "அமைப்பை தெரிந்தெடுக்கவும்",
|
|
7088
6847
|
"validations.required.field.error": "இந்த புலம் தேவை",
|
|
6848
|
+
"validation.pattern.invalid": "இந்த மதிப்பு தேவையான வடிவத்துடன் பொருந்தவில்லை.",
|
|
6849
|
+
"validation.minLength.invalid": "இந்த மதிப்பு மிகவும் குறுகியது.",
|
|
6850
|
+
"validation.maxLength.invalid": "இந்த மதிப்பு மிகவும் நீளமானது.",
|
|
7089
6851
|
"signin.heading": "உள்நுழை",
|
|
7090
6852
|
"signin.subheading": "தொடர உங்கள் சான்றுகளை உள்ளிடவும்.",
|
|
7091
6853
|
"signup.heading": "பதிவு செய்",
|
|
@@ -7196,6 +6958,9 @@ const si_LK = {
|
|
|
7196
6958
|
"elements.fields.organization.select.label": "සංවිධානය තෝරන්න",
|
|
7197
6959
|
"elements.fields.organization.select.placeholder": "සංවිධානයක් සැළුම් කරන්න",
|
|
7198
6960
|
"validations.required.field.error": "මෙම ක්ෂේත්රය අවශ්යයි",
|
|
6961
|
+
"validation.pattern.invalid": "මෙම අගය අවශ්ය ආකෘතියට නොගැලපේ.",
|
|
6962
|
+
"validation.minLength.invalid": "මෙම අගය ඉතා කෙටියි.",
|
|
6963
|
+
"validation.maxLength.invalid": "මෙම අගය ඉතා දිගයි.",
|
|
7199
6964
|
"signin.heading": "ලොග් වෙන්න",
|
|
7200
6965
|
"signin.subheading": "ඉදිරියට යාමට ඔබේ සත්යාපන තොරතුරු ඇතුළත් කරන්න.",
|
|
7201
6966
|
"signup.heading": "ලියාපදිංචි වන්න",
|
|
@@ -7351,4 +7116,4 @@ const normalizeTranslations = (translations) => {
|
|
|
7351
7116
|
var normalizeTranslations_default = normalizeTranslations;
|
|
7352
7117
|
|
|
7353
7118
|
//#endregion
|
|
7354
|
-
export { ApplicationNativeAuthenticationConstants_default as ApplicationNativeAuthenticationConstants, AuthenticationHelper_default as AuthenticationHelper, DEFAULT_THEME, EMOJI_URI_SCHEME, EmbeddedFlowActionVariant
|
|
7119
|
+
export { ApplicationNativeAuthenticationConstants_default as ApplicationNativeAuthenticationConstants, AuthenticationHelper_default as AuthenticationHelper, DEFAULT_THEME, DEFAULT_VALIDATION_MESSAGE_KEYS, EMOJI_URI_SCHEME, EmbeddedFlowActionVariant, EmbeddedFlowComponentType, EmbeddedFlowEventType, EmbeddedFlowResponseType, EmbeddedFlowTextVariant, EmbeddedFlowType, EmbeddedRecoveryFlowStatus, EmbeddedRecoveryFlowType, EmbeddedSignInFlowStatus, EmbeddedSignInFlowType, EmbeddedSignUpFlowStatus, EmbeddedSignUpFlowType, FieldType, FlowMetaType, FlowMode, HttpClient, IsomorphicCrypto, OIDCRequestConstants_default as OIDCRequestConstants, StorageManager_default as StorageManager, ThunderIDAPIError, ThunderIDAuthException, ThunderIDError, ThunderIDJavaScriptClient_default as ThunderIDJavaScriptClient, ThunderIDRuntimeError, TokenConstants_default as TokenConstants, TranslationBundleConstants_default as TranslationBundleConstants, VendorConstants_default as VendorConstants, WellKnownSchemaIds, arrayBufferToBase64url_default as arrayBufferToBase64url, base64urlToArrayBuffer_default as base64urlToArrayBuffer, bem_default as bem, buildValidatorFromRules_default as buildValidatorFromRules, configure as configureLogger, countryCodeToFlagEmoji, createComponentLogger, createLogger, createOrganization_default as createOrganization, createPackageComponentLogger, createPackageLogger, createPatchOperations, createTheme_default as createTheme, debug, deepMerge_default as deepMerge, deriveOrganizationHandleFromBaseUrl_default as deriveOrganizationHandleFromBaseUrl, error, evaluateValidationRule_default as evaluateValidationRule, executeEmbeddedRecoveryFlow_default as executeEmbeddedRecoveryFlow, executeEmbeddedSignInFlow_default as executeEmbeddedSignInFlow, executeEmbeddedSignUpFlow_default as executeEmbeddedSignUpFlow, executeEmbeddedUserOnboardingFlow_default as executeEmbeddedUserOnboardingFlow, extractEmojiFromUri_default as extractEmojiFromUri, extractPkceStorageKeyFromState_default as extractPkceStorageKeyFromState, extractUserClaimsFromIdToken_default as extractUserClaimsFromIdToken, flattenUserSchema_default as flattenUserSchema, formatDate_default as formatDate, generateFlattenedUserProfile_default as generateFlattenedUserProfile, generateUserProfile_default as generateUserProfile, get_default as get, getAllOrganizations_default as getAllOrganizations, getBrandingPreference_default as getBrandingPreference, getDefaultI18nBundles_default as getDefaultI18nBundles, getFlowMeta_default as getFlowMeta, getLatestStateParam_default as getLatestStateParam, getMeOrganizations_default as getMeOrganizations, getOrganization_default as getOrganization, getOrganizationUnitChildren_default as getOrganizationUnitChildren, getRedirectBasedSignUpUrl_default as getRedirectBasedSignUpUrl, getSchemas_default as getSchemas, getScim2Me_default as getScim2Me, getUserInfo_default as getUserInfo, info, isEmojiUri_default as isEmojiUri, isEmpty_default as isEmpty, isRecognizedBaseUrlPattern_default as isRecognizedBaseUrlPattern, logger_default as logger, normalizeTranslations_default as normalizeTranslations, processOpenIDScopes_default as processOpenIDScopes, processUsername_default as processUsername, removeTrailingSlash_default as removeTrailingSlash, resolveFieldName_default as resolveFieldName, resolveFlowTemplateLiterals, resolveLocaleDisplayName, resolveLocaleEmoji_default as resolveLocaleEmoji, resolveMeta, set_default as set, transformBrandingPreferenceToTheme_default as transformBrandingPreferenceToTheme, updateMeProfile_default as updateMeProfile, updateOrganization_default as updateOrganization, warn, withVendorCSSClassPrefix_default as withVendorCSSClassPrefix };
|