@thunderid/react 1.10.1 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/cjs/components/account/UserProfile/BaseUserProfile.cjs +1 -1
  2. package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs +1 -1
  3. package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.cjs +61 -0
  4. package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.cjs.map +1 -0
  5. package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.styles.cjs +26 -0
  6. package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.styles.cjs.map +1 -0
  7. package/dist/cjs/components/auth/DeviceGrant/DeviceGrant.cjs +192 -0
  8. package/dist/cjs/components/auth/DeviceGrant/DeviceGrant.cjs.map +1 -0
  9. package/dist/cjs/components/auth/InviteUser/BaseInviteUser.cjs +1 -1
  10. package/dist/cjs/components/auth/Recovery/BaseRecovery.cjs +2 -2
  11. package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs +15 -4
  12. package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs.map +1 -1
  13. package/dist/cjs/components/auth/SignUp/BaseSignUp.cjs +2 -2
  14. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +17 -2
  15. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
  16. package/dist/cjs/components/auth/flow/Consent.cjs +1 -1
  17. package/dist/cjs/components/primitives/Alert/Alert.cjs +1 -1
  18. package/dist/cjs/components/primitives/Card/Card.cjs +1 -1
  19. package/dist/cjs/components/primitives/Typography/Typography.styles.cjs +3 -0
  20. package/dist/cjs/components/primitives/Typography/Typography.styles.cjs.map +1 -1
  21. package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs +1 -0
  22. package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs.map +1 -1
  23. package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs +3 -0
  24. package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
  25. package/dist/cjs/hooks/management/useGrantedPermissions.cjs +6 -5
  26. package/dist/cjs/hooks/management/useGrantedPermissions.cjs.map +1 -1
  27. package/dist/cjs/index.cjs +6 -2
  28. package/dist/components/account/UserProfile/BaseUserProfile.js +1 -1
  29. package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +1 -1
  30. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.d.ts +17 -0
  31. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.d.ts.map +1 -0
  32. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.js +58 -0
  33. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.js.map +1 -0
  34. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.d.ts +4 -0
  35. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.d.ts.map +1 -0
  36. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.js +24 -0
  37. package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.js.map +1 -0
  38. package/dist/components/auth/DeviceGrant/DeviceGrant.d.ts +37 -0
  39. package/dist/components/auth/DeviceGrant/DeviceGrant.d.ts.map +1 -0
  40. package/dist/components/auth/DeviceGrant/DeviceGrant.js +188 -0
  41. package/dist/components/auth/DeviceGrant/DeviceGrant.js.map +1 -0
  42. package/dist/components/auth/InviteUser/BaseInviteUser.js +1 -1
  43. package/dist/components/auth/Recovery/BaseRecovery.js +2 -2
  44. package/dist/components/auth/SignIn/BaseSignIn.d.ts +4 -0
  45. package/dist/components/auth/SignIn/BaseSignIn.d.ts.map +1 -1
  46. package/dist/components/auth/SignIn/BaseSignIn.js +16 -5
  47. package/dist/components/auth/SignIn/BaseSignIn.js.map +1 -1
  48. package/dist/components/auth/SignUp/BaseSignUp.js +2 -2
  49. package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
  50. package/dist/components/auth/flow/AuthOptionFactory.js +17 -2
  51. package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
  52. package/dist/components/auth/flow/Consent.js +1 -1
  53. package/dist/components/primitives/Alert/Alert.js +1 -1
  54. package/dist/components/primitives/Card/Card.js +1 -1
  55. package/dist/components/primitives/Typography/Typography.styles.d.ts.map +1 -1
  56. package/dist/components/primitives/Typography/Typography.styles.js +3 -0
  57. package/dist/components/primitives/Typography/Typography.styles.js.map +1 -1
  58. package/dist/contexts/ThunderID/ThunderIDContext.d.ts +6 -0
  59. package/dist/contexts/ThunderID/ThunderIDContext.d.ts.map +1 -1
  60. package/dist/contexts/ThunderID/ThunderIDContext.js +1 -0
  61. package/dist/contexts/ThunderID/ThunderIDContext.js.map +1 -1
  62. package/dist/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
  63. package/dist/contexts/ThunderID/ThunderIDProvider.js +3 -0
  64. package/dist/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
  65. package/dist/hooks/management/useGrantedPermissions.d.ts +2 -1
  66. package/dist/hooks/management/useGrantedPermissions.d.ts.map +1 -1
  67. package/dist/hooks/management/useGrantedPermissions.js +7 -6
  68. package/dist/hooks/management/useGrantedPermissions.js.map +1 -1
  69. package/dist/index.d.ts +4 -0
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +5 -3
  72. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"AuthOptionFactory.js","names":["logger: ReturnType<typeof createPackageComponentLogger>","richTextClassCache: string | undefined","authOptionIconClassCache: string | undefined","providerId: any","providerMatches: any","theme: any","customRenderers: ComponentRendererMap","key: string | number","customRenderer: ComponentRenderer | undefined","rendered: ReactElement | null","identifier: string","isTouched: boolean","value: string","error: string","fieldType: string","hasPrefixes: boolean","hasPostfix: boolean","prefixStateKey: string","postfixStateKey: string","defaultPrefixValue: string","selectedPrefix: string","AffixedField","reportedLength: number","otpLength: number | undefined","numericOnly: boolean","actionId: string","eventType: string","buttonText: string","componentVariant: string","shouldSkipValidation: boolean","buttonType: HTMLButtonElement['type']","hasInvalidConsentApproval: boolean","isConsentApprovalBlocked","formData: Record<string, any>","consentPrompt: ConsentPromptData | undefined","isDeny: boolean","decisions: ConsentDecisions","socialButtonClassName: string","GoogleButton","GitHubButton","FacebookButton","MicrosoftButton","LinkedInButton","SignInWithEthereumButton","SmsOtpButton","startIconEl: ReactElement | null","endIconEl: ReactElement | null","Button","variant: any","textAlignClass: string","Typography","Divider","selectOptions: any","Select","DatePicker","BaseUserSelect","BaseAuthFlowSelect","BaseUserTypeSelect","formClass: string","blockComponents: any","richTextAction: EmbeddedFlowComponentAction | undefined","syntheticAction: EmbeddedFlowComponent","formData: Record<string, string>","handleRichTextClick: React.MouseEventHandler<HTMLDivElement> | undefined","anchor: HTMLAnchorElement | null","handleRichTextKeyDown: React.KeyboardEventHandler<HTMLDivElement> | undefined","explicitHeight: string","explicitWidth: string","ImageComponent","iconName: string","IconComponent: any","flowIconRegistry","direction: string","gap: number","align: string","justify: string","rawItems: string | number | undefined","parsedItems: number","items: number | null","isColumn: boolean","gridJustify: string","track: string","stackClass: string","stackChildren: (ReactElement | null)[]","consentPromptRawData: ConsentPromptData | string | undefined","Consent","textTemplate: string","timeoutMs: number","FlowTimer","sourceKey: string | undefined","CopyableText","pairs: KeyValuePair[]","KeyValueList"],"sources":["../../../../src/components/auth/flow/AuthOptionFactory.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport type {CSSInterpolation} from '@emotion/css/create-instance';\nimport {\n ConsentConstants,\n FieldType,\n FlowMetadataResponse,\n EmbeddedFlowComponent,\n EmbeddedFlowComponentAction,\n EmbeddedFlowComponentType,\n EmbeddedFlowTextVariant,\n EmbeddedFlowEventType,\n createPackageComponentLogger,\n resolveFlowTemplateLiterals,\n resolveEmojiUrisInHtml,\n ConsentPurposeData,\n ConsentPromptData,\n ConsentDecisions,\n ConsentPurposeDecision,\n ConsentAttributeElement,\n OrganizationUnitListResponse,\n PrefixOption,\n KeyValuePair,\n parseKeyValuePairs,\n FetchAuthFlows,\n FetchUserTypes,\n FetchUsers,\n getConsentElementDecision,\n} from '@thunderid/browser';\nimport DOMPurify from 'dompurify';\nimport {ChangeEvent, cloneElement, CSSProperties, FormEvent, ReactElement} from 'react';\nimport Consent from './Consent';\nimport {getConsentOptionalKey} from './ConsentCheckboxList';\nimport {createField} from './FieldFactory';\nimport FlowTimer from './FlowTimer';\nimport ImageComponent from './ImageComponent';\nimport {\n ComponentRenderer,\n ComponentRenderContext,\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport {UseTranslation} from '../../../hooks/useTranslation';\nimport {css, cx} from '../../../styles/emotion';\nimport {affixPostfixKey, affixPrefixKey} from '../../../utils/composeAffixedInputs';\nimport isConsentApprovalBlocked from '../../../utils/isConsentApprovalBlocked';\nimport AffixedField from '../../primitives/AffixedField/AffixedField';\nimport BaseAuthFlowSelect from '../../primitives/AuthFlowSelect/BaseAuthFlowSelect';\nimport Button from '../../primitives/Button/Button';\nimport CopyableText from '../../primitives/CopyableText/CopyableText';\nimport DatePicker from '../../primitives/DatePicker/DatePicker';\nimport Divider from '../../primitives/Divider/Divider';\nimport flowIconRegistry from '../../primitives/Icons/flowIconRegistry';\nimport KeyValueList from '../../primitives/KeyValueList/KeyValueList';\nimport Select from '../../primitives/Select/Select';\nimport Typography from '../../primitives/Typography/Typography';\nimport {TypographyVariant} from '../../primitives/Typography/Typography.styles';\nimport BaseUserSelect, {BaseUserSelectProps} from '../../primitives/UserSelect/BaseUserSelect';\nimport BaseUserTypeSelect from '../../primitives/UserTypeSelect/BaseUserTypeSelect';\nimport FacebookButton from '../buttons/FacebookButton';\nimport GitHubButton from '../buttons/GitHubButton';\nimport GoogleButton from '../buttons/GoogleButton';\nimport LinkedInButton from '../buttons/LinkedInButton';\nimport MicrosoftButton from '../buttons/MicrosoftButton';\nimport SignInWithEthereumButton from '../buttons/SignInWithEthereumButton';\nimport SmsOtpButton from '../buttons/SmsOtpButton';\n\nconst logger: ReturnType<typeof createPackageComponentLogger> = createPackageComponentLogger(\n '@thunderid/react',\n 'AuthOptionFactory',\n);\n\n/**\n * Replaces `emoji:` URIs embedded in HTML before DOMPurify sanitization.\n *\n * DOMPurify strips unknown URI schemes from attributes (e.g. `src=\"emoji:🦊\"` → `src=\"\"`).\n * This function converts:\n * - `<img src=\"emoji:X\" alt=\"Y\">` → `<span role=\"img\" aria-label=\"Y\">X</span>`\n * - Any remaining `emoji:X` text occurrences → `X`\n */\n\n// This module's functions (renderSignInComponents, etc.) are called imperatively from a\n// component's render, not React components/hooks themselves — so these classes can't be computed\n// at module scope: that runs at import time, before <ThunderIDProvider> has had a chance to\n// configure Emotion's CSP nonce, which would insert them into an un-nonced <style> tag. Instead\n// they're computed lazily, on first actual use (still just once — Emotion's own cache dedupes any\n// further calls to a no-op after that).\nlet richTextClassCache: string | undefined;\n\n/** Ensures rich-text content (including all inner elements from the server) always word-wraps. */\nfunction getRichTextClass(): string {\n richTextClassCache ??= css`\n overflow-wrap: anywhere;\n & * {\n overflow-wrap: anywhere;\n word-break: break-word;\n }\n & .rich-text-align-left {\n text-align: left;\n }\n & .rich-text-align-center {\n text-align: center;\n }\n & .rich-text-align-right {\n text-align: right;\n }\n & .rich-text-align-justify {\n text-align: justify;\n }\n & a,\n & .rich-text-link {\n text-decoration: underline;\n }\n & span[role='img'] {\n display: inline-block;\n }\n `;\n return richTextClassCache;\n}\n\nlet authOptionIconClassCache: string | undefined;\n\nfunction getAuthOptionIconClass(): string {\n authOptionIconClassCache ??= css({height: '1.25em', objectFit: 'contain', width: '1.25em'});\n return authOptionIconClassCache;\n}\n\nexport type AuthType = 'signin' | 'signup' | 'recovery';\n\n/**\n * Get the appropriate FieldType for an input component.\n */\n/** Upper bound on STACK grid slots, so a mistyped `items` cannot render thousands of cells. */\nconst MAX_STACK_ITEMS = 12;\n\nconst getFieldType = (variant: EmbeddedFlowComponentType): FieldType => {\n switch (variant) {\n case EmbeddedFlowComponentType.EmailInput:\n return FieldType.Email;\n case EmbeddedFlowComponentType.PhoneInput:\n return FieldType.Tel;\n case EmbeddedFlowComponentType.PasswordInput:\n return FieldType.Password;\n case EmbeddedFlowComponentType.TextInput:\n default:\n return FieldType.Text;\n }\n};\n\n/**\n * Get typography variant from component variant.\n */\nconst getTypographyVariant = (variant: string): any => {\n const variantMap: Record<EmbeddedFlowTextVariant, TypographyVariant> = {\n BODY_1: 'body1',\n BODY_2: 'body2',\n BUTTON_TEXT: 'button',\n CAPTION: 'caption',\n HEADING_1: 'h1',\n HEADING_2: 'h2',\n HEADING_3: 'h3',\n HEADING_4: 'h4',\n HEADING_5: 'h5',\n HEADING_6: 'h6',\n OVERLINE: 'overline',\n SUBTITLE_1: 'subtitle1',\n SUBTITLE_2: 'subtitle2',\n };\n\n return variantMap[variant] || 'h3';\n};\n\n/**\n * Check if a button text or action matches a social provider.\n */\nconst matchesSocialProvider = (\n actionId: string,\n eventType: string,\n buttonText: string,\n provider: string,\n authType: AuthType,\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n _componentVariant?: string,\n): boolean => {\n const providerId: any = `${provider}_auth`;\n const providerMatches: any = actionId === providerId || eventType === providerId;\n\n // Social buttons usually have \"Sign in with X\" or \"Continue with X\" text,\n // so also check button text for the provider name to increase chances of correct detection (especially for signup flows where action IDs are less standardized)\n if (buttonText.toLowerCase().includes(provider)) {\n return true;\n }\n\n // For signup, also check button text\n if (authType === 'signup') {\n return providerMatches || buttonText.toLowerCase().includes(provider);\n }\n\n return providerMatches;\n};\n\n/**\n * Create an auth component from flow component configuration.\n */\nconst createAuthComponentFromFlow = (\n component: EmbeddedFlowComponent,\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n authType: AuthType,\n options: {\n /** @internal Passed from the host React component so hooks aren't called inside a loop. */\n _customRenderers?: ComponentRendererMap;\n /** @internal Passed from the host React component so hooks aren't called inside a loop. */\n _theme?: any;\n /** Additional data from the flow response, used for different dynamic data */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n /** Current consent purpose being rendered. Set by CONSENT_PURPOSE block iteration. */\n currentConsentPurpose?: ConsentPurposeData;\n inStack?: boolean;\n inputClassName?: string;\n /** Flag to determine if the step timeline has expired */\n isTimeoutDisabled?: boolean;\n key?: string | number;\n /** Data source for AUTH_FLOW_SELECT fields. */\n fetchAuthFlows?: FetchAuthFlows;\n /** Data source for USER_SELECT fields. */\n fetchUsers?: FetchUsers;\n /** Data source for USER_TYPE_SELECT fields. */\n fetchUserTypes?: FetchUserTypes;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n /** Called with the error of a failed picker load. The form itself shows no error for it. */\n onPickerError?: (error: Error) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n } = {},\n): ReactElement | null => {\n const theme: any = options._theme;\n const customRenderers: ComponentRendererMap = options._customRenderers ?? {};\n\n const key: string | number = options.key || component.id;\n\n const customRenderer: ComponentRenderer | undefined =\n customRenderers[component.id] ?? customRenderers[component.type];\n if (customRenderer) {\n const renderCtx: ComponentRenderContext = {\n additionalData: options.additionalData,\n authType,\n formErrors,\n formValues,\n isFormValid,\n isLoading,\n meta: options.meta,\n resetForm,\n onInputBlur: options.onInputBlur,\n onInputChange,\n onSubmit: options.onSubmit,\n touchedFields,\n };\n // Key the element here so a renderer does not have to, as the built-in cases below do.\n const rendered: ReactElement | null = customRenderer(component, renderCtx);\n\n return rendered ? cloneElement(rendered, {key}) : null;\n }\n\n /** Resolve any remaining {{t()}} or {{meta()}} template expressions in a string at render time. */\n const resolve = (text: string | undefined): string => {\n if (!text || (!options.t && !options.meta)) {\n return text || '';\n }\n return resolveFlowTemplateLiterals(text, {meta: options.meta, t: options.t || ((k: string): string => k)});\n };\n\n // The props a flow gives each of the resource pickers (USER_SELECT, AUTH_FLOW_SELECT, USER_TYPE_SELECT).\n const resourceSelectProps = (): Omit<BaseUserSelectProps, 'fetchUsers' | 'mapping'> => {\n const identifier: string = component.ref!;\n const isTouched: boolean = touchedFields[identifier] || false;\n\n return {\n className: cx(options.inputClassName, component.classes),\n component,\n error: isTouched ? formErrors[identifier] : undefined,\n id: component.id,\n label: resolve(component.label) || '',\n name: identifier,\n onBlur: (): void => options.onInputBlur?.(identifier),\n onChange: (event: ChangeEvent<HTMLSelectElement>): void => onInputChange(identifier, event.target.value),\n onError: options.onPickerError,\n placeholder: resolve(component.placeholder),\n required: component.required,\n value: formValues[identifier] || '',\n };\n };\n\n // A component type this render cannot draw is logged and left out.\n const skipUnsupported = (typeName: string): null => {\n logger.warn(`${typeName} component type is not supported. Skipping render.`);\n\n return null;\n };\n\n switch (component.type) {\n case EmbeddedFlowComponentType.TextInput:\n case EmbeddedFlowComponentType.PasswordInput:\n case EmbeddedFlowComponentType.EmailInput:\n case EmbeddedFlowComponentType.PhoneInput: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n const fieldType: string = getFieldType(component.type);\n\n // Prefix/postfix are accepted on any text-family input. When either is present,\n // route to AffixedField so the leading affix renders and submit-time composition\n // is picked up by composeAffixedInputs via the sentinel keys.\n // Both string.length and Array.length are defined, so a single truthy+length\n // check covers `prefixes?: string | PrefixOption[]`.\n const hasPrefixes: boolean = !!component.prefixes && component.prefixes.length > 0;\n const hasPostfix: boolean = typeof component.postfix === 'string' && component.postfix.length > 0;\n\n if (hasPrefixes || hasPostfix) {\n const prefixStateKey: string = affixPrefixKey(identifier, options.vendor);\n const postfixStateKey: string = affixPostfixKey(identifier, options.vendor);\n const defaultPrefixValue: string = hasPrefixes\n ? typeof component.prefixes === 'string'\n ? component.prefixes\n : (component.prefixes as PrefixOption[])[0].value\n : '';\n const selectedPrefix: string = formValues[prefixStateKey] ?? defaultPrefixValue;\n\n return (\n <AffixedField\n key={key}\n className={cx(options.inputClassName, component.classes)}\n id={component.id}\n label={resolve(component.label) || ''}\n name={identifier}\n placeholder={resolve(component.placeholder) || ''}\n required={component.required || false}\n error={error}\n value={value}\n type={fieldType}\n prefixes={component.prefixes}\n prefixValue={selectedPrefix}\n onChange={(e: ChangeEvent<HTMLInputElement>): void => onInputChange(identifier, e.target.value)}\n onBlur={(): void => options.onInputBlur?.(identifier)}\n onPrefixChange={(newPrefix: string): void => onInputChange(prefixStateKey, newPrefix)}\n onFocus={(): void => {\n if (hasPrefixes && formValues[prefixStateKey] === undefined) {\n onInputChange(prefixStateKey, defaultPrefixValue);\n }\n if (hasPostfix && formValues[postfixStateKey] === undefined) {\n onInputChange(postfixStateKey, component.postfix!);\n }\n }}\n />\n );\n }\n\n const field: any = createField({\n className: cx(options.inputClassName, component.classes),\n error,\n id: component.id,\n label: resolve(component.label) || '',\n name: identifier,\n onBlur: () => options.onInputBlur?.(identifier),\n onChange: (newValue: string) => onInputChange(identifier, newValue),\n placeholder: resolve(component.placeholder) || '',\n required: component.required || false,\n type: fieldType as FieldType,\n value,\n });\n\n return cloneElement(field, {key});\n }\n\n case EmbeddedFlowComponentType.OtpInput: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n\n // The server reports the length and character set of the code it generated, so the field\n // matches the OTP the user received. An older server omits both and the defaults apply.\n const reportedLength: number = Number(options.additionalData?.['otpLength']);\n const otpLength: number | undefined =\n Number.isInteger(reportedLength) && reportedLength > 0 ? reportedLength : undefined;\n const numericOnly: boolean = options.additionalData?.['otpNumericOnly'] !== 'false';\n\n const field: any = createField({\n className: cx(options.inputClassName, component.classes),\n error,\n id: component.id,\n label: resolve(component.label) || '',\n length: otpLength,\n name: identifier,\n numericOnly,\n onBlur: () => options.onInputBlur?.(identifier),\n onChange: (newValue: string) => onInputChange(identifier, newValue),\n placeholder: resolve(component.placeholder) || '',\n required: component.required || false,\n type: FieldType.Otp,\n value,\n });\n\n return cloneElement(field, {key});\n }\n\n case EmbeddedFlowComponentType.Action: {\n const actionId: string = component.id;\n const eventType: string = component.eventType || '';\n const buttonText: string = resolve(component.label);\n const componentVariant: string = component.variant || '';\n\n // Only validate on submit type events.\n const shouldSkipValidation: boolean = eventType.toUpperCase() !== EmbeddedFlowEventType.Submit;\n\n // Determine the button type based on the event type. Default to 'submit' if not recognized.\n const buttonTypeEnum = {\n [EmbeddedFlowEventType.Submit]: 'submit',\n [EmbeddedFlowEventType.Reset]: 'reset',\n [EmbeddedFlowEventType.Cancel]: 'button',\n [EmbeddedFlowEventType.Trigger]: 'button',\n [EmbeddedFlowEventType.Back]: 'button',\n };\n const buttonType: HTMLButtonElement['type'] = buttonTypeEnum[eventType.toUpperCase()] ?? 'submit';\n\n // Approval waits while an approved authorization detail shows a modified value that cannot be submitted.\n const hasInvalidConsentApproval: boolean =\n !shouldSkipValidation &&\n componentVariant.toLowerCase() === 'primary' &&\n isConsentApprovalBlocked(\n (options.additionalData?.['consentPrompt'] as ConsentPromptData | undefined)?.purposes ?? [],\n formValues,\n );\n\n const handleClick = (): any => {\n if (options.onSubmit) {\n const formData: Record<string, any> = {};\n Object.keys(formValues).forEach((field: any) => {\n // Include all values, even empty strings, to ensure proper submission\n formData[field] = formValues[field];\n });\n\n // For consent actions, build the consent_decisions JSON from the form values.\n // The allow action captures per-attribute choices; the deny action sends\n // all purposes as rejected so the backend ConsentExecutor can fail the flow.\n const consentPrompt: ConsentPromptData | undefined = options.additionalData?.['consentPrompt'] as\n | ConsentPromptData\n | undefined;\n if (consentPrompt && eventType.toUpperCase() === EmbeddedFlowEventType.Submit) {\n const isDeny: boolean = componentVariant.toLowerCase() !== 'primary';\n const decisions: ConsentDecisions = {\n approved: !isDeny,\n ...(isDeny ? {reason: ConsentConstants.REASON_USER_DENIED} : {}),\n purposes: consentPrompt.purposes.map(\n (p: ConsentPurposeData): ConsentPurposeDecision => ({\n approved: !isDeny,\n elements: [\n // Permission purposes carry no essential elements, so the server sends null here\n ...(p.essential ?? []).map((e): ConsentAttributeElement => ({approved: !isDeny, name: e.name})),\n ...(p.optional ?? []).map(\n (e): ConsentAttributeElement =>\n getConsentElementDecision(\n p.purposeId,\n e,\n !isDeny && formValues[getConsentOptionalKey(p.purposeId, e.name)] === 'true',\n formValues,\n ),\n ),\n ],\n purposeName: p.purposeName!,\n }),\n ),\n };\n formData['consent_decisions'] = JSON.stringify(decisions);\n }\n\n // For submit events, pass the form data to the onSubmit callback. For other event types, reset the form and call onSubmit with an empty data object.\n if (eventType.toUpperCase() === EmbeddedFlowEventType.Submit) {\n options.onSubmit(component, formData, shouldSkipValidation);\n } else {\n resetForm();\n options.onSubmit(component, {}, shouldSkipValidation);\n }\n }\n };\n\n // Render branded social login buttons for known action IDs\n\n const socialButtonClassName: string = cx(options.buttonClassName, component.classes);\n\n if (matchesSocialProvider(actionId, eventType, buttonText, 'google', authType, componentVariant)) {\n return <GoogleButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'github', authType, componentVariant)) {\n return <GitHubButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'facebook', authType, componentVariant)) {\n return <FacebookButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'microsoft', authType, componentVariant)) {\n return <MicrosoftButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'linkedin', authType, componentVariant)) {\n return <LinkedInButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'ethereum', authType, componentVariant)) {\n return (\n <SignInWithEthereumButton\n key={key}\n id={component.id}\n onClick={handleClick}\n className={socialButtonClassName}\n />\n );\n }\n if (actionId === 'prompt_mobile' || eventType === 'prompt_mobile') {\n return <SmsOtpButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n\n const startIconEl: ReactElement | null = component.startIcon ? (\n <img src={component.startIcon} alt=\"\" aria-hidden=\"true\" className={getAuthOptionIconClass()} />\n ) : null;\n\n const endIconEl: ReactElement | null = component.endIcon ? (\n <img src={component.endIcon} alt=\"\" aria-hidden=\"true\" className={getAuthOptionIconClass()} />\n ) : null;\n\n return (\n <Button\n fullWidth\n key={key}\n id={component.id}\n onClick={handleClick}\n disabled={\n isLoading ||\n (!isFormValid && !shouldSkipValidation) ||\n hasInvalidConsentApproval ||\n options.isTimeoutDisabled ||\n (component as any).config?.disabled\n }\n className={cx(options.buttonClassName, component.classes)}\n data-testid=\"thunderid-signin-submit\"\n variant={component.variant?.toLowerCase() === 'primary' ? 'solid' : 'outline'}\n color={component.variant?.toLowerCase() === 'primary' ? 'primary' : 'secondary'}\n startIcon={startIconEl}\n endIcon={endIconEl}\n type={buttonType}\n >\n {buttonText || 'Submit'}\n </Button>\n );\n }\n\n case EmbeddedFlowComponentType.Text: {\n const variant: any = getTypographyVariant(component.variant!);\n const textAlignClass: string = css({\n marginBottom: 2,\n textAlign:\n typeof component?.align === 'string' ? (component.align as React.CSSProperties['textAlign']) : 'left',\n });\n return (\n <Typography key={key} id={component.id} className={cx(component.classes, textAlignClass)} variant={variant}>\n {resolve(component.label)}\n </Typography>\n );\n }\n\n case EmbeddedFlowComponentType.Divider: {\n return <Divider key={key}>{resolve(component.label) || ''}</Divider>;\n }\n\n case EmbeddedFlowComponentType.Select: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n\n // Options are pre-sanitized by flowTransformer to {value: string, label: string} format\n const selectOptions: any = (component.options || []).map((opt: any) => ({\n label: typeof opt === 'string' ? opt : String(opt.label ?? opt.value ?? ''),\n value: typeof opt === 'string' ? opt : String(opt.value ?? ''),\n }));\n\n return (\n <Select\n key={key}\n id={component.id}\n name={identifier}\n label={resolve(component.label) || ''}\n placeholder={resolve(component.placeholder)}\n required={component.required}\n options={selectOptions}\n value={value}\n error={error}\n onChange={(e: any): void => onInputChange(identifier, e.target.value)}\n onBlur={(): any => options.onInputBlur?.(identifier)}\n className={cx(options.inputClassName, component.classes)}\n />\n );\n }\n\n case EmbeddedFlowComponentType.DateInput: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n\n return (\n <DatePicker\n key={key}\n id={component.id}\n name={identifier}\n label={resolve(component.label) || ''}\n placeholder={resolve(component.placeholder)}\n required={component.required}\n dateFormat={component.dateFormat}\n value={value}\n error={error}\n onChange={(e: any): void => onInputChange(identifier, e.target.value)}\n onBlur={(): any => options.onInputBlur?.(identifier)}\n className={cx(options.inputClassName, component.classes)}\n />\n );\n }\n\n case EmbeddedFlowComponentType.OuSelect:\n return skipUnsupported('OU_SELECT');\n\n // The resource pickers load with a signed-in user's access token, so without a data source, which is every flow\n // except InviteUser, they are not drawn.\n case EmbeddedFlowComponentType.UserSelect:\n return options.fetchUsers ? (\n <BaseUserSelect key={key} {...resourceSelectProps()} fetchUsers={options.fetchUsers} />\n ) : (\n skipUnsupported('USER_SELECT')\n );\n\n case EmbeddedFlowComponentType.AuthFlowSelect:\n return options.fetchAuthFlows ? (\n <BaseAuthFlowSelect key={key} {...resourceSelectProps()} fetchAuthFlows={options.fetchAuthFlows} />\n ) : (\n skipUnsupported('AUTH_FLOW_SELECT')\n );\n\n case EmbeddedFlowComponentType.UserTypeSelect:\n return options.fetchUserTypes ? (\n <BaseUserTypeSelect key={key} {...resourceSelectProps()} fetchUserTypes={options.fetchUserTypes} />\n ) : (\n skipUnsupported('USER_TYPE_SELECT')\n );\n\n case EmbeddedFlowComponentType.Block: {\n if (component.components && component.components.length > 0) {\n const formClass: string = css({\n display: 'flex',\n flexDirection: 'column',\n gap: `calc(${theme?.vars?.spacing?.unit ?? '4px'} * 2)`,\n });\n\n const blockComponents: any = component.components\n .map((childComponent: any, index: any) =>\n createAuthComponentFromFlow(\n childComponent,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n authType,\n {\n ...options,\n key: childComponent.id || `${component.id}_${index}`,\n },\n ),\n )\n .filter(Boolean);\n\n // The submit button's `type=\"submit\"` (and pressing Enter in a field) would\n // otherwise trigger the browser's native form submission — a GET request to\n // the current URL with all field values (including passwords) as query params.\n // Actual submission is handled entirely via `onClick`/`onSubmit` above.\n return (\n <form\n id={component.id}\n key={key}\n className={cx(component.classes, formClass)}\n onSubmit={(event: FormEvent<HTMLFormElement>): void => event.preventDefault()}\n >\n {blockComponents}\n </form>\n );\n }\n return null;\n }\n\n case EmbeddedFlowComponentType.RichText: {\n const richTextAction: EmbeddedFlowComponentAction | undefined = component.action;\n\n const dispatchRichTextAction = (): void => {\n if (!richTextAction || !options.onSubmit) {\n return;\n }\n const eventTypeValue = String(richTextAction.eventType ?? EmbeddedFlowEventType.Submit);\n const shouldSkipValidation: boolean = eventTypeValue.toUpperCase() === String(EmbeddedFlowEventType.Trigger);\n const syntheticAction: EmbeddedFlowComponent = {\n eventType: eventTypeValue,\n id: `${component.id}_action`,\n ref: richTextAction.ref,\n type: EmbeddedFlowComponentType.Action,\n };\n const formData: Record<string, string> = {};\n Object.keys(formValues).forEach((field: string) => {\n formData[field] = formValues[field];\n });\n options.onSubmit(syntheticAction, formData, shouldSkipValidation);\n };\n\n // Sentinel-anchor contract: only anchors carrying `data-action-ref` equal to\n // richTextAction.ref dispatch the action. Anchors without the sentinel (or with\n // a non-matching one) are treated as ordinary links and are ignored here.\n const isMatchingSentinelAnchor = (anchor: HTMLAnchorElement): boolean =>\n anchor.getAttribute('data-action-ref') === richTextAction?.ref;\n\n const handleRichTextClick: React.MouseEventHandler<HTMLDivElement> | undefined = richTextAction\n ? (event: React.MouseEvent<HTMLDivElement>): void => {\n const anchor: HTMLAnchorElement | null = (event.target as HTMLElement).closest('a');\n if (!anchor || !isMatchingSentinelAnchor(anchor)) {\n return;\n }\n event.preventDefault();\n dispatchRichTextAction();\n }\n : undefined;\n\n const handleRichTextKeyDown: React.KeyboardEventHandler<HTMLDivElement> | undefined = richTextAction\n ? (event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (event.key !== 'Enter' && event.key !== ' ') {\n return;\n }\n const anchor: HTMLAnchorElement | null = (event.target as HTMLElement).closest('a');\n if (!anchor || !isMatchingSentinelAnchor(anchor)) {\n return;\n }\n event.preventDefault();\n dispatchRichTextAction();\n }\n : undefined;\n\n return (\n // Sentinel anchors are made keyboard-operable via the container's onKeyDown\n // (Enter/Space activate the matching anchor). Authors should ensure the anchor\n // is focusable (`href` or `tabIndex`); the click+keydown delegation covers both\n // pointer and keyboard activation once focus lands on the anchor.\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n key={key}\n className={getRichTextClass()}\n onClick={handleRichTextClick}\n onKeyDown={handleRichTextKeyDown}\n // Manually sanitizes with `DOMPurify`.\n // IMPORTANT: DO NOT REMOVE OR MODIFY THIS SANITIZATION STEP.\n dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(resolveEmojiUrisInHtml(resolve(component.label)))}}\n />\n );\n }\n\n case EmbeddedFlowComponentType.Image: {\n const explicitHeight: string = resolve(component.height?.toString());\n const explicitWidth: string = resolve(component.width?.toString());\n return (\n <ImageComponent\n key={key}\n component={\n {\n config: {\n alt: resolve(component.alt) || resolve(component.label) || 'Image',\n height: explicitHeight || (options.inStack ? '50' : 'auto'),\n src: resolve(component.src),\n width: explicitWidth || (options.inStack ? '50' : '100%'),\n },\n } as any\n }\n formErrors={undefined!}\n formValues={undefined!}\n isFormValid={false}\n isLoading={false}\n onInputChange={(): void => {\n throw new Error('Function not implemented.');\n }}\n touchedFields={undefined!}\n />\n );\n }\n\n case EmbeddedFlowComponentType.Icon: {\n const iconName: string = component.name || '';\n const IconComponent: any = flowIconRegistry[iconName];\n if (!IconComponent) {\n logger.warn(`Unknown icon name: \"${iconName}\". Skipping render.`);\n return null;\n }\n return <IconComponent key={key} size={component.size || 24} color={component.color || 'currentColor'} />;\n }\n\n case EmbeddedFlowComponentType.Stack: {\n const direction: string = (component as any).direction || 'row';\n const gap: number = (component as any).gap ?? 2;\n const align: string = (component as any).align || 'center';\n const justify: string = (component as any).justify || 'flex-start';\n\n // `items` is the number of slots across the main axis and `direction` picks\n // that axis: with `row` it is the column count (items: 2 with four buttons\n // renders a 2 x 2 grid), and with `column` it is the row count and children\n // flow into further columns. Fewer than two slots keeps the flex layout, so\n // stacks authored before grid support are unaffected.\n const rawItems: string | number | undefined = component.items;\n const parsedItems: number =\n typeof rawItems === 'string' ? Number(rawItems) : typeof rawItems === 'number' ? rawItems : NaN;\n const items: number | null =\n Number.isFinite(parsedItems) && Math.floor(parsedItems) >= 2\n ? Math.min(Math.floor(parsedItems), MAX_STACK_ITEMS)\n : null;\n // CSS Grid has no reverse auto-flow, so the reverse variants fall back to\n // their base axis rather than silently becoming a row.\n const isColumn: boolean = direction.startsWith('column');\n const gridJustify: string = component.justify ?? 'stretch';\n // Equal `1fr` tracks fill the container, leaving `justify-content` no free\n // space to distribute. Content-sized tracks restore it, so every justify\n // value has a visible effect while the default stays an even split.\n const track: string = gridJustify === 'stretch' ? '1fr' : 'auto';\n\n const stackStyle: CSSProperties =\n items !== null\n ? {\n alignItems: component.align ?? 'stretch',\n display: 'grid',\n gap: `${gap * 0.5}rem`,\n gridAutoFlow: isColumn ? 'column' : 'row',\n justifyContent: gridJustify,\n width: '100%',\n ...(isColumn\n ? {gridTemplateRows: `repeat(${items}, ${track})`}\n : {gridTemplateColumns: `repeat(${items}, ${track})`}),\n }\n : {\n alignItems: align,\n display: 'flex',\n flexDirection: direction as CSSProperties['flexDirection'],\n flexWrap: 'wrap',\n gap: `${gap * 0.5}rem`,\n justifyContent: justify,\n };\n\n const stackClass: string = css(stackStyle as CSSInterpolation);\n\n const stackChildren: (ReactElement | null)[] = component.components\n ? component.components.map((childComponent: any, index: number) =>\n createAuthComponentFromFlow(\n childComponent,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n authType,\n {\n ...options,\n inStack: true,\n key: childComponent.id || `${component.id}_${index}`,\n },\n ),\n )\n : [];\n\n return (\n <div key={key} id={component.id} className={cx(component.classes, stackClass)}>\n {stackChildren}\n </div>\n );\n }\n\n case EmbeddedFlowComponentType.Consent: {\n const consentPromptRawData: ConsentPromptData | string | undefined = options.additionalData?.['consentPrompt'];\n\n return (\n <Consent\n key={key}\n consentData={consentPromptRawData as any}\n formValues={formValues}\n onInputChange={onInputChange}\n t={options.t}\n />\n );\n }\n\n case EmbeddedFlowComponentType.Timer: {\n const textTemplate: string = resolve((component as any).label) || 'Time remaining: {time}';\n const timeoutMs: number = Number(options.additionalData?.['stepTimeout']) || 0;\n const expiresIn: number = timeoutMs > 0 ? Math.max(0, Math.floor((timeoutMs - Date.now()) / 1000)) : 0;\n\n return <FlowTimer key={key} expiresIn={expiresIn} textTemplate={textTemplate} />;\n }\n\n case EmbeddedFlowComponentType.CopyableText: {\n const sourceKey: string | undefined = (component as any).source;\n const value: string = sourceKey && options.additionalData ? String(options.additionalData[sourceKey] ?? '') : '';\n const labelText: string | undefined = resolve((component as any).label) || undefined;\n\n return <CopyableText key={key} label={labelText} masked={Boolean(component.masked)} value={value} />;\n }\n\n case EmbeddedFlowComponentType.KeyValueList: {\n const sourceKey: string | undefined = component.source;\n const pairs: KeyValuePair[] = parseKeyValuePairs(\n sourceKey && options.additionalData ? options.additionalData[sourceKey] : undefined,\n ).map((pair: KeyValuePair) => ({...pair, label: resolve(pair.label)}));\n\n // An empty panel tells the user nothing, so a list with no pairs renders nothing at all.\n if (pairs.length === 0) {\n return null;\n }\n\n return <KeyValueList key={key} label={resolve(component.label) || undefined} pairs={pairs} />;\n }\n\n default:\n // Gracefully handle unsupported component types by returning null\n logger.warn(`Unsupported component type: ${component.type}. Skipping render.`);\n return null;\n }\n};\n\n/**\n * Processes an array of components and renders them as React elements for sign-in.\n */\nexport const renderSignInComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n inputClassName?: string;\n /** Flag to determine if the step timeline has expired */\n isTimeoutDisabled?: boolean;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'signin',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n\n/**\n * Processes an array of components and renders them as React elements for sign-up.\n */\nexport const renderSignUpComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n inputClassName?: string;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'signup',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n\n/**\n * Processes an array of components and renders them as React elements for recovery flow.\n */\nexport const renderRecoveryComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n inputClassName?: string;\n /** Flag to determine if the step timeline has expired */\n isTimeoutDisabled?: boolean;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'recovery',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n\n/**\n * Processes an array of components and renders them as React elements for invite user.\n * This is used by both InviteUser and AcceptInvite components.\n */\nexport const renderInviteUserComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n /** Function to fetch child organization units for OU_SELECT components. */\n fetchOrganizationUnitChildren?: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse>;\n inputClassName?: string;\n /** Data source for AUTH_FLOW_SELECT fields. */\n fetchAuthFlows?: FetchAuthFlows;\n /** Data source for USER_SELECT fields. */\n fetchUsers?: FetchUsers;\n /** Data source for USER_TYPE_SELECT fields. */\n fetchUserTypes?: FetchUserTypes;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n /** Called with the error of a failed picker load. The form itself shows no error for it. */\n onPickerError?: (error: Error) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'signup',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n"],"mappings":"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Aa,0BACX,YACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YAqBA,WACG,KAAK,WAAgB,UACpB,4BACE,WACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,UACA;CACE,GAAG;CACH,KAAK,UAAU,MAAM;CACtB,CACF,CACF,CACA,QAAQ,MAAyB,MAAM,KAAK;;;;AAKjD,MAAa,4BACX,YACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YAuBA,WACG,KAAK,WAAgB,UACpB,4BACE,WACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YACA;CACE,GAAG;CACH,KAAK,UAAU,MAAM;CACtB,CACF,CACF,CACA,QAAQ,MAAyB,MAAM,KAAK;;;;;AAMjD,MAAa,8BACX,YACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YAmCA,WACG,KAAK,WAAgB,UACpB,4BACE,WACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,UACA;CACE,GAAG;CACH,KAAK,UAAU,MAAM;CACtB,CACF,CACF,CACA,QAAQ,MAAyB,MAAM,KAAK"}
1
+ {"version":3,"file":"AuthOptionFactory.js","names":["logger: ReturnType<typeof createPackageComponentLogger>","richTextClassCache: string | undefined","authOptionIconClassCache: string | undefined","providerId: any","providerMatches: any","theme: any","customRenderers: ComponentRendererMap","key: string | number","customRenderer: ComponentRenderer | undefined","rendered: ReactElement | null","identifier: string","isTouched: boolean","value: string","error: string","fieldType: string","hasPrefixes: boolean","hasPostfix: boolean","prefixStateKey: string","postfixStateKey: string","defaultPrefixValue: string","selectedPrefix: string","AffixedField","reportedLength: number","otpLength: number | undefined","numericOnly: boolean","actionId: string","eventType: string","buttonText: string","componentVariant: string","shouldSkipValidation: boolean","buttonType: HTMLButtonElement['type']","hasInvalidConsentApproval: boolean","isConsentApprovalBlocked","formData: Record<string, any>","consentPrompt: ConsentPromptData | undefined","isDeny: boolean","decisions: ConsentDecisions","socialButtonClassName: string","GoogleButton","GitHubButton","FacebookButton","MicrosoftButton","LinkedInButton","SignInWithEthereumButton","SmsOtpButton","startIconEl: ReactElement | null","endIconEl: ReactElement | null","Button","variant: any","color: TypographyColor | undefined","textAlignClass: string","Typography","Divider","selectOptions: any","Select","DatePicker","BaseUserSelect","BaseAuthFlowSelect","BaseUserTypeSelect","formClass: string","blockComponents: any","richTextAction: EmbeddedFlowComponentAction | undefined","syntheticAction: EmbeddedFlowComponent","formData: Record<string, string>","handleRichTextClick: React.MouseEventHandler<HTMLDivElement> | undefined","anchor: HTMLAnchorElement | null","handleRichTextKeyDown: React.KeyboardEventHandler<HTMLDivElement> | undefined","explicitHeight: string","explicitWidth: string","ImageComponent","iconName: string","IconComponent: any","flowIconRegistry","direction: string","gap: number","align: string","justify: string","rawItems: string | number | undefined","parsedItems: number","items: number | null","isColumn: boolean","gridJustify: string","track: string","stackClass: string","stackChildren: (ReactElement | null)[]","consentPromptRawData: ConsentPromptData | string | undefined","Consent","textTemplate: string","timeoutMs: number","FlowTimer","sourceKey: string | undefined","CopyableText","pairs: KeyValuePair[]","KeyValueList"],"sources":["../../../../src/components/auth/flow/AuthOptionFactory.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport type {CSSInterpolation} from '@emotion/css/create-instance';\nimport {\n ConsentConstants,\n FieldType,\n FlowMetadataResponse,\n EmbeddedFlowComponent,\n EmbeddedFlowComponentAction,\n EmbeddedFlowComponentType,\n EmbeddedFlowTextVariant,\n EmbeddedFlowEventType,\n createPackageComponentLogger,\n resolveFlowTemplateLiterals,\n resolveEmojiUrisInHtml,\n ConsentPurposeData,\n ConsentPromptData,\n ConsentDecisions,\n ConsentPurposeDecision,\n ConsentAttributeElement,\n OrganizationUnitListResponse,\n PrefixOption,\n KeyValuePair,\n parseKeyValuePairs,\n FetchAuthFlows,\n FetchUserTypes,\n FetchUsers,\n getConsentElementDecision,\n} from '@thunderid/browser';\nimport DOMPurify from 'dompurify';\nimport {ChangeEvent, cloneElement, CSSProperties, FormEvent, MouseEvent, ReactElement} from 'react';\nimport Consent from './Consent';\nimport {getConsentOptionalKey} from './ConsentCheckboxList';\nimport {createField} from './FieldFactory';\nimport FlowTimer from './FlowTimer';\nimport ImageComponent from './ImageComponent';\nimport {\n ComponentRenderer,\n ComponentRenderContext,\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport {UseTranslation} from '../../../hooks/useTranslation';\nimport {css, cx} from '../../../styles/emotion';\nimport {affixPostfixKey, affixPrefixKey} from '../../../utils/composeAffixedInputs';\nimport isConsentApprovalBlocked from '../../../utils/isConsentApprovalBlocked';\nimport AffixedField from '../../primitives/AffixedField/AffixedField';\nimport BaseAuthFlowSelect from '../../primitives/AuthFlowSelect/BaseAuthFlowSelect';\nimport Button from '../../primitives/Button/Button';\nimport CopyableText from '../../primitives/CopyableText/CopyableText';\nimport DatePicker from '../../primitives/DatePicker/DatePicker';\nimport Divider from '../../primitives/Divider/Divider';\nimport flowIconRegistry from '../../primitives/Icons/flowIconRegistry';\nimport KeyValueList from '../../primitives/KeyValueList/KeyValueList';\nimport Select from '../../primitives/Select/Select';\nimport Typography from '../../primitives/Typography/Typography';\nimport {TypographyColor, TypographyVariant} from '../../primitives/Typography/Typography.styles';\nimport BaseUserSelect, {BaseUserSelectProps} from '../../primitives/UserSelect/BaseUserSelect';\nimport BaseUserTypeSelect from '../../primitives/UserTypeSelect/BaseUserTypeSelect';\nimport FacebookButton from '../buttons/FacebookButton';\nimport GitHubButton from '../buttons/GitHubButton';\nimport GoogleButton from '../buttons/GoogleButton';\nimport LinkedInButton from '../buttons/LinkedInButton';\nimport MicrosoftButton from '../buttons/MicrosoftButton';\nimport SignInWithEthereumButton from '../buttons/SignInWithEthereumButton';\nimport SmsOtpButton from '../buttons/SmsOtpButton';\n\nconst logger: ReturnType<typeof createPackageComponentLogger> = createPackageComponentLogger(\n '@thunderid/react',\n 'AuthOptionFactory',\n);\n\n/**\n * Replaces `emoji:` URIs embedded in HTML before DOMPurify sanitization.\n *\n * DOMPurify strips unknown URI schemes from attributes (e.g. `src=\"emoji:🦊\"` → `src=\"\"`).\n * This function converts:\n * - `<img src=\"emoji:X\" alt=\"Y\">` → `<span role=\"img\" aria-label=\"Y\">X</span>`\n * - Any remaining `emoji:X` text occurrences → `X`\n */\n\n// This module's functions (renderSignInComponents, etc.) are called imperatively from a\n// component's render, not React components/hooks themselves — so these classes can't be computed\n// at module scope: that runs at import time, before <ThunderIDProvider> has had a chance to\n// configure Emotion's CSP nonce, which would insert them into an un-nonced <style> tag. Instead\n// they're computed lazily, on first actual use (still just once — Emotion's own cache dedupes any\n// further calls to a no-op after that).\nlet richTextClassCache: string | undefined;\n\n/** Ensures rich-text content (including all inner elements from the server) always word-wraps. */\nfunction getRichTextClass(): string {\n richTextClassCache ??= css`\n overflow-wrap: anywhere;\n & * {\n overflow-wrap: anywhere;\n word-break: break-word;\n }\n & .rich-text-align-left {\n text-align: left;\n }\n & .rich-text-align-center {\n text-align: center;\n }\n & .rich-text-align-right {\n text-align: right;\n }\n & .rich-text-align-justify {\n text-align: justify;\n }\n & a,\n & .rich-text-link {\n text-decoration: underline;\n }\n & span[role='img'] {\n display: inline-block;\n }\n `;\n return richTextClassCache;\n}\n\nlet authOptionIconClassCache: string | undefined;\n\nfunction getAuthOptionIconClass(): string {\n authOptionIconClassCache ??= css({height: '1.25em', objectFit: 'contain', width: '1.25em'});\n return authOptionIconClassCache;\n}\n\nexport type AuthType = 'signin' | 'signup' | 'recovery';\n\n/**\n * Get the appropriate FieldType for an input component.\n */\n/** Upper bound on STACK grid slots, so a mistyped `items` cannot render thousands of cells. */\nconst MAX_STACK_ITEMS = 12;\n\nconst getFieldType = (variant: EmbeddedFlowComponentType): FieldType => {\n switch (variant) {\n case EmbeddedFlowComponentType.EmailInput:\n return FieldType.Email;\n case EmbeddedFlowComponentType.PhoneInput:\n return FieldType.Tel;\n case EmbeddedFlowComponentType.PasswordInput:\n return FieldType.Password;\n case EmbeddedFlowComponentType.TextInput:\n default:\n return FieldType.Text;\n }\n};\n\n/**\n * Get typography variant from component variant.\n */\nconst getTypographyVariant = (variant: string): any => {\n const variantMap: Record<EmbeddedFlowTextVariant, TypographyVariant> = {\n BODY_1: 'body1',\n BODY_2: 'body2',\n BUTTON_TEXT: 'button',\n CAPTION: 'caption',\n HEADING_1: 'h1',\n HEADING_2: 'h2',\n HEADING_3: 'h3',\n HEADING_4: 'h4',\n HEADING_5: 'h5',\n HEADING_6: 'h6',\n OVERLINE: 'overline',\n SUBTITLE_1: 'subtitle1',\n SUBTITLE_2: 'subtitle2',\n };\n\n return variantMap[variant] || 'h3';\n};\n\n/** Maps flow text color values to SDK typography color variants. */\nconst getTypographyColor = (color?: string): TypographyColor | undefined => {\n switch (color?.toUpperCase()) {\n case 'ERROR':\n return 'error';\n case 'WARNING':\n return 'warning';\n case 'SUCCESS':\n return 'success';\n case 'INFO':\n return 'info';\n case 'PRIMARY':\n return 'primary';\n case 'SECONDARY':\n return 'secondary';\n default:\n return undefined;\n }\n};\n\n/**\n * Check if a button text or action matches a social provider.\n */\nconst matchesSocialProvider = (\n actionId: string,\n eventType: string,\n buttonText: string,\n provider: string,\n authType: AuthType,\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n _componentVariant?: string,\n): boolean => {\n const providerId: any = `${provider}_auth`;\n const providerMatches: any = actionId === providerId || eventType === providerId;\n\n // Social buttons usually have \"Sign in with X\" or \"Continue with X\" text,\n // so also check button text for the provider name to increase chances of correct detection (especially for signup flows where action IDs are less standardized)\n if (buttonText.toLowerCase().includes(provider)) {\n return true;\n }\n\n // For signup, also check button text\n if (authType === 'signup') {\n return providerMatches || buttonText.toLowerCase().includes(provider);\n }\n\n return providerMatches;\n};\n\n/**\n * Create an auth component from flow component configuration.\n */\nconst createAuthComponentFromFlow = (\n component: EmbeddedFlowComponent,\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n authType: AuthType,\n options: {\n /** @internal Passed from the host React component so hooks aren't called inside a loop. */\n _customRenderers?: ComponentRendererMap;\n /** @internal Passed from the host React component so hooks aren't called inside a loop. */\n _theme?: any;\n /** Additional data from the flow response, used for different dynamic data */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n /** Current consent purpose being rendered. Set by CONSENT_PURPOSE block iteration. */\n currentConsentPurpose?: ConsentPurposeData;\n inStack?: boolean;\n inputClassName?: string;\n /** Flag to determine if the step timeline has expired */\n isTimeoutDisabled?: boolean;\n key?: string | number;\n /** Data source for AUTH_FLOW_SELECT fields. */\n fetchAuthFlows?: FetchAuthFlows;\n /** Data source for USER_SELECT fields. */\n fetchUsers?: FetchUsers;\n /** Data source for USER_TYPE_SELECT fields. */\n fetchUserTypes?: FetchUserTypes;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n /** Called with the error of a failed picker load. The form itself shows no error for it. */\n onPickerError?: (error: Error) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n } = {},\n): ReactElement | null => {\n const theme: any = options._theme;\n const customRenderers: ComponentRendererMap = options._customRenderers ?? {};\n\n const key: string | number = options.key || component.id;\n\n const customRenderer: ComponentRenderer | undefined =\n customRenderers[component.id] ?? customRenderers[component.type];\n if (customRenderer) {\n const renderCtx: ComponentRenderContext = {\n additionalData: options.additionalData,\n authType,\n formErrors,\n formValues,\n isFormValid,\n isLoading,\n meta: options.meta,\n resetForm,\n onInputBlur: options.onInputBlur,\n onInputChange,\n onSubmit: options.onSubmit,\n touchedFields,\n };\n // Key the element here so a renderer does not have to, as the built-in cases below do.\n const rendered: ReactElement | null = customRenderer(component, renderCtx);\n\n return rendered ? cloneElement(rendered, {key}) : null;\n }\n\n /** Resolve any remaining {{t()}} or {{meta()}} template expressions in a string at render time. */\n const resolve = (text: string | undefined): string => {\n if (!text || (!options.t && !options.meta)) {\n return text || '';\n }\n return resolveFlowTemplateLiterals(text, {meta: options.meta, t: options.t || ((k: string): string => k)});\n };\n\n // The props a flow gives each of the resource pickers (USER_SELECT, AUTH_FLOW_SELECT, USER_TYPE_SELECT).\n const resourceSelectProps = (): Omit<BaseUserSelectProps, 'fetchUsers' | 'mapping'> => {\n const identifier: string = component.ref!;\n const isTouched: boolean = touchedFields[identifier] || false;\n\n return {\n className: cx(options.inputClassName, component.classes),\n component,\n error: isTouched ? formErrors[identifier] : undefined,\n id: component.id,\n label: resolve(component.label) || '',\n name: identifier,\n onBlur: (): void => options.onInputBlur?.(identifier),\n onChange: (event: ChangeEvent<HTMLSelectElement>): void => onInputChange(identifier, event.target.value),\n onError: options.onPickerError,\n placeholder: resolve(component.placeholder),\n required: component.required,\n value: formValues[identifier] || '',\n };\n };\n\n // A component type this render cannot draw is logged and left out.\n const skipUnsupported = (typeName: string): null => {\n logger.warn(`${typeName} component type is not supported. Skipping render.`);\n\n return null;\n };\n\n switch (component.type) {\n case EmbeddedFlowComponentType.TextInput:\n case EmbeddedFlowComponentType.PasswordInput:\n case EmbeddedFlowComponentType.EmailInput:\n case EmbeddedFlowComponentType.PhoneInput: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n const fieldType: string = getFieldType(component.type);\n\n // Prefix/postfix are accepted on any text-family input. When either is present,\n // route to AffixedField so the leading affix renders and submit-time composition\n // is picked up by composeAffixedInputs via the sentinel keys.\n // Both string.length and Array.length are defined, so a single truthy+length\n // check covers `prefixes?: string | PrefixOption[]`.\n const hasPrefixes: boolean = !!component.prefixes && component.prefixes.length > 0;\n const hasPostfix: boolean = typeof component.postfix === 'string' && component.postfix.length > 0;\n\n if (hasPrefixes || hasPostfix) {\n const prefixStateKey: string = affixPrefixKey(identifier, options.vendor);\n const postfixStateKey: string = affixPostfixKey(identifier, options.vendor);\n const defaultPrefixValue: string = hasPrefixes\n ? typeof component.prefixes === 'string'\n ? component.prefixes\n : (component.prefixes as PrefixOption[])[0].value\n : '';\n const selectedPrefix: string = formValues[prefixStateKey] ?? defaultPrefixValue;\n\n return (\n <AffixedField\n key={key}\n className={cx(options.inputClassName, component.classes)}\n id={component.id}\n label={resolve(component.label) || ''}\n name={identifier}\n placeholder={resolve(component.placeholder) || ''}\n required={component.required || false}\n error={error}\n value={value}\n type={fieldType}\n prefixes={component.prefixes}\n prefixValue={selectedPrefix}\n onChange={(e: ChangeEvent<HTMLInputElement>): void => onInputChange(identifier, e.target.value)}\n onBlur={(): void => options.onInputBlur?.(identifier)}\n onPrefixChange={(newPrefix: string): void => onInputChange(prefixStateKey, newPrefix)}\n onFocus={(): void => {\n if (hasPrefixes && formValues[prefixStateKey] === undefined) {\n onInputChange(prefixStateKey, defaultPrefixValue);\n }\n if (hasPostfix && formValues[postfixStateKey] === undefined) {\n onInputChange(postfixStateKey, component.postfix!);\n }\n }}\n />\n );\n }\n\n const field: any = createField({\n className: cx(options.inputClassName, component.classes),\n error,\n id: component.id,\n label: resolve(component.label) || '',\n name: identifier,\n onBlur: () => options.onInputBlur?.(identifier),\n onChange: (newValue: string) => onInputChange(identifier, newValue),\n placeholder: resolve(component.placeholder) || '',\n required: component.required || false,\n type: fieldType as FieldType,\n value,\n });\n\n return cloneElement(field, {key});\n }\n\n case EmbeddedFlowComponentType.OtpInput: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n\n // The server reports the length and character set of the code it generated, so the field\n // matches the OTP the user received. An older server omits both and the defaults apply.\n const reportedLength: number = Number(options.additionalData?.['otpLength']);\n const otpLength: number | undefined =\n Number.isInteger(reportedLength) && reportedLength > 0 ? reportedLength : undefined;\n const numericOnly: boolean = options.additionalData?.['otpNumericOnly'] !== 'false';\n\n const field: any = createField({\n className: cx(options.inputClassName, component.classes),\n error,\n id: component.id,\n label: resolve(component.label) || '',\n length: otpLength,\n name: identifier,\n numericOnly,\n onBlur: () => options.onInputBlur?.(identifier),\n onChange: (newValue: string) => onInputChange(identifier, newValue),\n placeholder: resolve(component.placeholder) || '',\n required: component.required || false,\n type: FieldType.Otp,\n value,\n });\n\n return cloneElement(field, {key});\n }\n\n case EmbeddedFlowComponentType.Action: {\n const actionId: string = component.id;\n const eventType: string = component.eventType || '';\n const buttonText: string = resolve(component.label);\n const componentVariant: string = component.variant || '';\n\n // Only validate on submit type events.\n const shouldSkipValidation: boolean = eventType.toUpperCase() !== EmbeddedFlowEventType.Submit;\n\n // Determine the button type based on the event type. Default to 'submit' if not recognized.\n const buttonTypeEnum = {\n [EmbeddedFlowEventType.Submit]: 'submit',\n [EmbeddedFlowEventType.Reset]: 'reset',\n [EmbeddedFlowEventType.Cancel]: 'button',\n [EmbeddedFlowEventType.Trigger]: 'button',\n [EmbeddedFlowEventType.Back]: 'button',\n };\n const buttonType: HTMLButtonElement['type'] = buttonTypeEnum[eventType.toUpperCase()] ?? 'submit';\n\n // Approval waits while an approved authorization detail shows a modified value that cannot be submitted.\n const hasInvalidConsentApproval: boolean =\n !shouldSkipValidation &&\n componentVariant.toLowerCase() === 'primary' &&\n isConsentApprovalBlocked(\n (options.additionalData?.['consentPrompt'] as ConsentPromptData | undefined)?.purposes ?? [],\n formValues,\n );\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>): void => {\n // Flow actions are handled by the SDK. Cancel the native button action before\n // onSubmit can switch steps or replace the form; otherwise the browser tries to\n // submit a form that React has already disconnected from the document.\n event.preventDefault();\n\n if (options.onSubmit) {\n const formData: Record<string, any> = {};\n Object.keys(formValues).forEach((field: any) => {\n // Include all values, even empty strings, to ensure proper submission\n formData[field] = formValues[field];\n });\n\n // For consent actions, build the consent_decisions JSON from the form values.\n // The allow action captures per-attribute choices; the deny action sends\n // all purposes as rejected so the backend ConsentExecutor can fail the flow.\n const consentPrompt: ConsentPromptData | undefined = options.additionalData?.['consentPrompt'] as\n | ConsentPromptData\n | undefined;\n if (consentPrompt && eventType.toUpperCase() === EmbeddedFlowEventType.Submit) {\n const isDeny: boolean = componentVariant.toLowerCase() !== 'primary';\n const decisions: ConsentDecisions = {\n approved: !isDeny,\n ...(isDeny ? {reason: ConsentConstants.REASON_USER_DENIED} : {}),\n purposes: consentPrompt.purposes.map(\n (p: ConsentPurposeData): ConsentPurposeDecision => ({\n approved: !isDeny,\n elements: [\n // Permission purposes carry no essential elements, so the server sends null here\n ...(p.essential ?? []).map((e): ConsentAttributeElement => ({approved: !isDeny, name: e.name})),\n ...(p.optional ?? []).map(\n (e): ConsentAttributeElement =>\n getConsentElementDecision(\n p.purposeId,\n e,\n !isDeny && formValues[getConsentOptionalKey(p.purposeId, e.name)] === 'true',\n formValues,\n ),\n ),\n ],\n purposeName: p.purposeName!,\n }),\n ),\n };\n formData['consent_decisions'] = JSON.stringify(decisions);\n }\n\n // For submit events, pass the form data to the onSubmit callback. For other event types, reset the form and call onSubmit with an empty data object.\n if (eventType.toUpperCase() === EmbeddedFlowEventType.Submit) {\n options.onSubmit(component, formData, shouldSkipValidation);\n } else {\n resetForm();\n options.onSubmit(component, {}, shouldSkipValidation);\n }\n }\n };\n\n // Render branded social login buttons for known action IDs\n\n const socialButtonClassName: string = cx(options.buttonClassName, component.classes);\n\n if (matchesSocialProvider(actionId, eventType, buttonText, 'google', authType, componentVariant)) {\n return <GoogleButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'github', authType, componentVariant)) {\n return <GitHubButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'facebook', authType, componentVariant)) {\n return <FacebookButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'microsoft', authType, componentVariant)) {\n return <MicrosoftButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'linkedin', authType, componentVariant)) {\n return <LinkedInButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n if (matchesSocialProvider(actionId, eventType, buttonText, 'ethereum', authType, componentVariant)) {\n return (\n <SignInWithEthereumButton\n key={key}\n id={component.id}\n onClick={handleClick}\n className={socialButtonClassName}\n />\n );\n }\n if (actionId === 'prompt_mobile' || eventType === 'prompt_mobile') {\n return <SmsOtpButton key={key} id={component.id} onClick={handleClick} className={socialButtonClassName} />;\n }\n\n const startIconEl: ReactElement | null = component.startIcon ? (\n <img src={component.startIcon} alt=\"\" aria-hidden=\"true\" className={getAuthOptionIconClass()} />\n ) : null;\n\n const endIconEl: ReactElement | null = component.endIcon ? (\n <img src={component.endIcon} alt=\"\" aria-hidden=\"true\" className={getAuthOptionIconClass()} />\n ) : null;\n\n return (\n <Button\n fullWidth\n key={key}\n id={component.id}\n onClick={handleClick}\n disabled={\n isLoading ||\n (!isFormValid && !shouldSkipValidation) ||\n hasInvalidConsentApproval ||\n options.isTimeoutDisabled ||\n (component as any).config?.disabled\n }\n className={cx(options.buttonClassName, component.classes)}\n data-testid=\"thunderid-signin-submit\"\n variant={component.variant?.toLowerCase() === 'primary' ? 'solid' : 'outline'}\n color={component.variant?.toLowerCase() === 'primary' ? 'primary' : 'secondary'}\n startIcon={startIconEl}\n endIcon={endIconEl}\n type={buttonType}\n >\n {buttonText || 'Submit'}\n </Button>\n );\n }\n\n case EmbeddedFlowComponentType.Text: {\n const variant: any = getTypographyVariant(component.variant!);\n const color: TypographyColor | undefined = getTypographyColor(component.color);\n const textAlignClass: string = css({\n marginBottom: 2,\n textAlign:\n typeof component?.align === 'string' ? (component.align as React.CSSProperties['textAlign']) : 'left',\n });\n return (\n <Typography\n key={key}\n id={component.id}\n className={cx(component.classes, textAlignClass)}\n variant={variant}\n color={color}\n >\n {resolve(component.label)}\n </Typography>\n );\n }\n\n case EmbeddedFlowComponentType.Divider: {\n return <Divider key={key}>{resolve(component.label) || ''}</Divider>;\n }\n\n case EmbeddedFlowComponentType.Select: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n\n // Options are pre-sanitized by flowTransformer to {value: string, label: string} format\n const selectOptions: any = (component.options || []).map((opt: any) => ({\n label: typeof opt === 'string' ? opt : String(opt.label ?? opt.value ?? ''),\n value: typeof opt === 'string' ? opt : String(opt.value ?? ''),\n }));\n\n return (\n <Select\n key={key}\n id={component.id}\n name={identifier}\n label={resolve(component.label) || ''}\n placeholder={resolve(component.placeholder)}\n required={component.required}\n options={selectOptions}\n value={value}\n error={error}\n onChange={(e: any): void => onInputChange(identifier, e.target.value)}\n onBlur={(): any => options.onInputBlur?.(identifier)}\n className={cx(options.inputClassName, component.classes)}\n />\n );\n }\n\n case EmbeddedFlowComponentType.DateInput: {\n const identifier: string = component.ref!;\n const value: string = formValues[identifier] || '';\n const isTouched: boolean = touchedFields[identifier] || false;\n const error: string = isTouched ? formErrors[identifier] : undefined!;\n\n return (\n <DatePicker\n key={key}\n id={component.id}\n name={identifier}\n label={resolve(component.label) || ''}\n placeholder={resolve(component.placeholder)}\n required={component.required}\n dateFormat={component.dateFormat}\n value={value}\n error={error}\n onChange={(e: any): void => onInputChange(identifier, e.target.value)}\n onBlur={(): any => options.onInputBlur?.(identifier)}\n className={cx(options.inputClassName, component.classes)}\n />\n );\n }\n\n case EmbeddedFlowComponentType.OuSelect:\n return skipUnsupported('OU_SELECT');\n\n // The resource pickers load with a signed-in user's access token, so without a data source, which is every flow\n // except InviteUser, they are not drawn.\n case EmbeddedFlowComponentType.UserSelect:\n return options.fetchUsers ? (\n <BaseUserSelect key={key} {...resourceSelectProps()} fetchUsers={options.fetchUsers} />\n ) : (\n skipUnsupported('USER_SELECT')\n );\n\n case EmbeddedFlowComponentType.AuthFlowSelect:\n return options.fetchAuthFlows ? (\n <BaseAuthFlowSelect key={key} {...resourceSelectProps()} fetchAuthFlows={options.fetchAuthFlows} />\n ) : (\n skipUnsupported('AUTH_FLOW_SELECT')\n );\n\n case EmbeddedFlowComponentType.UserTypeSelect:\n return options.fetchUserTypes ? (\n <BaseUserTypeSelect key={key} {...resourceSelectProps()} fetchUserTypes={options.fetchUserTypes} />\n ) : (\n skipUnsupported('USER_TYPE_SELECT')\n );\n\n case EmbeddedFlowComponentType.Block: {\n if (component.components && component.components.length > 0) {\n const formClass: string = css({\n display: 'flex',\n flexDirection: 'column',\n gap: `calc(${theme?.vars?.spacing?.unit ?? '4px'} * 2)`,\n });\n\n const blockComponents: any = component.components\n .map((childComponent: any, index: any) =>\n createAuthComponentFromFlow(\n childComponent,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n authType,\n {\n ...options,\n key: childComponent.id || `${component.id}_${index}`,\n },\n ),\n )\n .filter(Boolean);\n\n // The submit button's `type=\"submit\"` (and pressing Enter in a field) would\n // otherwise trigger the browser's native form submission — a GET request to\n // the current URL with all field values (including passwords) as query params.\n // Actual submission is handled entirely via `onClick`/`onSubmit` above.\n return (\n <form\n id={component.id}\n key={key}\n className={cx(component.classes, formClass)}\n onSubmit={(event: FormEvent<HTMLFormElement>): void => event.preventDefault()}\n >\n {blockComponents}\n </form>\n );\n }\n return null;\n }\n\n case EmbeddedFlowComponentType.RichText: {\n const richTextAction: EmbeddedFlowComponentAction | undefined = component.action;\n\n const dispatchRichTextAction = (): void => {\n if (!richTextAction || !options.onSubmit) {\n return;\n }\n const eventTypeValue = String(richTextAction.eventType ?? EmbeddedFlowEventType.Submit);\n const shouldSkipValidation: boolean = eventTypeValue.toUpperCase() === String(EmbeddedFlowEventType.Trigger);\n const syntheticAction: EmbeddedFlowComponent = {\n eventType: eventTypeValue,\n id: `${component.id}_action`,\n ref: richTextAction.ref,\n type: EmbeddedFlowComponentType.Action,\n };\n const formData: Record<string, string> = {};\n Object.keys(formValues).forEach((field: string) => {\n formData[field] = formValues[field];\n });\n options.onSubmit(syntheticAction, formData, shouldSkipValidation);\n };\n\n // Sentinel-anchor contract: only anchors carrying `data-action-ref` equal to\n // richTextAction.ref dispatch the action. Anchors without the sentinel (or with\n // a non-matching one) are treated as ordinary links and are ignored here.\n const isMatchingSentinelAnchor = (anchor: HTMLAnchorElement): boolean =>\n anchor.getAttribute('data-action-ref') === richTextAction?.ref;\n\n const handleRichTextClick: React.MouseEventHandler<HTMLDivElement> | undefined = richTextAction\n ? (event: React.MouseEvent<HTMLDivElement>): void => {\n const anchor: HTMLAnchorElement | null = (event.target as HTMLElement).closest('a');\n if (!anchor || !isMatchingSentinelAnchor(anchor)) {\n return;\n }\n event.preventDefault();\n dispatchRichTextAction();\n }\n : undefined;\n\n const handleRichTextKeyDown: React.KeyboardEventHandler<HTMLDivElement> | undefined = richTextAction\n ? (event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (event.key !== 'Enter' && event.key !== ' ') {\n return;\n }\n const anchor: HTMLAnchorElement | null = (event.target as HTMLElement).closest('a');\n if (!anchor || !isMatchingSentinelAnchor(anchor)) {\n return;\n }\n event.preventDefault();\n dispatchRichTextAction();\n }\n : undefined;\n\n return (\n // Sentinel anchors are made keyboard-operable via the container's onKeyDown\n // (Enter/Space activate the matching anchor). Authors should ensure the anchor\n // is focusable (`href` or `tabIndex`); the click+keydown delegation covers both\n // pointer and keyboard activation once focus lands on the anchor.\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n key={key}\n className={getRichTextClass()}\n onClick={handleRichTextClick}\n onKeyDown={handleRichTextKeyDown}\n // Manually sanitizes with `DOMPurify`.\n // IMPORTANT: DO NOT REMOVE OR MODIFY THIS SANITIZATION STEP.\n dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(resolveEmojiUrisInHtml(resolve(component.label)))}}\n />\n );\n }\n\n case EmbeddedFlowComponentType.Image: {\n const explicitHeight: string = resolve(component.height?.toString());\n const explicitWidth: string = resolve(component.width?.toString());\n return (\n <ImageComponent\n key={key}\n component={\n {\n config: {\n alt: resolve(component.alt) || resolve(component.label) || 'Image',\n height: explicitHeight || (options.inStack ? '50' : 'auto'),\n src: resolve(component.src),\n width: explicitWidth || (options.inStack ? '50' : '100%'),\n },\n } as any\n }\n formErrors={undefined!}\n formValues={undefined!}\n isFormValid={false}\n isLoading={false}\n onInputChange={(): void => {\n throw new Error('Function not implemented.');\n }}\n touchedFields={undefined!}\n />\n );\n }\n\n case EmbeddedFlowComponentType.Icon: {\n const iconName: string = component.name || '';\n const IconComponent: any = flowIconRegistry[iconName];\n if (!IconComponent) {\n logger.warn(`Unknown icon name: \"${iconName}\". Skipping render.`);\n return null;\n }\n return <IconComponent key={key} size={component.size || 24} color={component.color || 'currentColor'} />;\n }\n\n case EmbeddedFlowComponentType.Stack: {\n const direction: string = (component as any).direction || 'row';\n const gap: number = (component as any).gap ?? 2;\n const align: string = (component as any).align || 'center';\n const justify: string = (component as any).justify || 'flex-start';\n\n // `items` is the number of slots across the main axis and `direction` picks\n // that axis: with `row` it is the column count (items: 2 with four buttons\n // renders a 2 x 2 grid), and with `column` it is the row count and children\n // flow into further columns. Fewer than two slots keeps the flex layout, so\n // stacks authored before grid support are unaffected.\n const rawItems: string | number | undefined = component.items;\n const parsedItems: number =\n typeof rawItems === 'string' ? Number(rawItems) : typeof rawItems === 'number' ? rawItems : NaN;\n const items: number | null =\n Number.isFinite(parsedItems) && Math.floor(parsedItems) >= 2\n ? Math.min(Math.floor(parsedItems), MAX_STACK_ITEMS)\n : null;\n // CSS Grid has no reverse auto-flow, so the reverse variants fall back to\n // their base axis rather than silently becoming a row.\n const isColumn: boolean = direction.startsWith('column');\n const gridJustify: string = component.justify ?? 'stretch';\n // Equal `1fr` tracks fill the container, leaving `justify-content` no free\n // space to distribute. Content-sized tracks restore it, so every justify\n // value has a visible effect while the default stays an even split.\n const track: string = gridJustify === 'stretch' ? '1fr' : 'auto';\n\n const stackStyle: CSSProperties =\n items !== null\n ? {\n alignItems: component.align ?? 'stretch',\n display: 'grid',\n gap: `${gap * 0.5}rem`,\n gridAutoFlow: isColumn ? 'column' : 'row',\n justifyContent: gridJustify,\n width: '100%',\n ...(isColumn\n ? {gridTemplateRows: `repeat(${items}, ${track})`}\n : {gridTemplateColumns: `repeat(${items}, ${track})`}),\n }\n : {\n alignItems: align,\n display: 'flex',\n flexDirection: direction as CSSProperties['flexDirection'],\n flexWrap: 'wrap',\n gap: `${gap * 0.5}rem`,\n justifyContent: justify,\n };\n\n const stackClass: string = css(stackStyle as CSSInterpolation);\n\n const stackChildren: (ReactElement | null)[] = component.components\n ? component.components.map((childComponent: any, index: number) =>\n createAuthComponentFromFlow(\n childComponent,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n authType,\n {\n ...options,\n inStack: true,\n key: childComponent.id || `${component.id}_${index}`,\n },\n ),\n )\n : [];\n\n return (\n <div key={key} id={component.id} className={cx(component.classes, stackClass)}>\n {stackChildren}\n </div>\n );\n }\n\n case EmbeddedFlowComponentType.Consent: {\n const consentPromptRawData: ConsentPromptData | string | undefined = options.additionalData?.['consentPrompt'];\n\n return (\n <Consent\n key={key}\n consentData={consentPromptRawData as any}\n formValues={formValues}\n onInputChange={onInputChange}\n t={options.t}\n />\n );\n }\n\n case EmbeddedFlowComponentType.Timer: {\n const textTemplate: string = resolve((component as any).label) || 'Time remaining: {time}';\n const timeoutMs: number = Number(options.additionalData?.['stepTimeout']) || 0;\n const expiresIn: number = timeoutMs > 0 ? Math.max(0, Math.floor((timeoutMs - Date.now()) / 1000)) : 0;\n\n return <FlowTimer key={key} expiresIn={expiresIn} textTemplate={textTemplate} />;\n }\n\n case EmbeddedFlowComponentType.CopyableText: {\n const sourceKey: string | undefined = (component as any).source;\n const value: string = sourceKey && options.additionalData ? String(options.additionalData[sourceKey] ?? '') : '';\n const labelText: string | undefined = resolve((component as any).label) || undefined;\n\n return <CopyableText key={key} label={labelText} masked={Boolean(component.masked)} value={value} />;\n }\n\n case EmbeddedFlowComponentType.KeyValueList: {\n const sourceKey: string | undefined = component.source;\n const pairs: KeyValuePair[] = parseKeyValuePairs(\n sourceKey && options.additionalData ? options.additionalData[sourceKey] : undefined,\n ).map((pair: KeyValuePair) => ({...pair, label: resolve(pair.label)}));\n\n // An empty panel tells the user nothing, so a list with no pairs renders nothing at all.\n if (pairs.length === 0) {\n return null;\n }\n\n return <KeyValueList key={key} label={resolve(component.label) || undefined} pairs={pairs} />;\n }\n\n default:\n // Gracefully handle unsupported component types by returning null\n logger.warn(`Unsupported component type: ${component.type}. Skipping render.`);\n return null;\n }\n};\n\n/**\n * Processes an array of components and renders them as React elements for sign-in.\n */\nexport const renderSignInComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n inputClassName?: string;\n /** Flag to determine if the step timeline has expired */\n isTimeoutDisabled?: boolean;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'signin',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n\n/**\n * Processes an array of components and renders them as React elements for sign-up.\n */\nexport const renderSignUpComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n inputClassName?: string;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'signup',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n\n/**\n * Processes an array of components and renders them as React elements for recovery flow.\n */\nexport const renderRecoveryComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n inputClassName?: string;\n /** Flag to determine if the step timeline has expired */\n isTimeoutDisabled?: boolean;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'recovery',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n\n/**\n * Processes an array of components and renders them as React elements for invite user.\n * This is used by both InviteUser and AcceptInvite components.\n */\nexport const renderInviteUserComponents = (\n components: EmbeddedFlowComponent[],\n formValues: Record<string, string>,\n touchedFields: Record<string, boolean>,\n formErrors: Record<string, string>,\n isLoading: boolean,\n isFormValid: boolean,\n resetForm: () => void,\n onInputChange: (name: string, value: string) => void,\n options?: {\n /** @internal */\n _customRenderers?: ComponentRendererMap;\n /** @internal */\n _theme?: any;\n /** Additional data from the flow response */\n additionalData?: Record<string, any>;\n buttonClassName?: string;\n /** Function to fetch child organization units for OU_SELECT components. */\n fetchOrganizationUnitChildren?: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse>;\n inputClassName?: string;\n /** Data source for AUTH_FLOW_SELECT fields. */\n fetchAuthFlows?: FetchAuthFlows;\n /** Data source for USER_SELECT fields. */\n fetchUsers?: FetchUsers;\n /** Data source for USER_TYPE_SELECT fields. */\n fetchUserTypes?: FetchUserTypes;\n /** Flow metadata for resolving {{meta(...)}} expressions at render time */\n meta?: FlowMetadataResponse | null;\n onInputBlur?: (name: string) => void;\n /** Called with the error of a failed picker load. The form itself shows no error for it. */\n onPickerError?: (error: Error) => void;\n onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>, skipValidation?: boolean) => void;\n size?: 'small' | 'medium' | 'large';\n /** Translation function for resolving {{t(...)}} expressions at render time */\n t?: UseTranslation['t'];\n variant?: any;\n /** Vendor namespace used to derive affix sentinel keys for prefix/postfix-bearing inputs. */\n vendor?: string;\n },\n): ReactElement[] =>\n components\n .map((component: any, index: any) =>\n createAuthComponentFromFlow(\n component,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n onInputChange,\n 'signup',\n {\n ...options,\n key: component.id || index,\n },\n ),\n )\n .filter((x): x is ReactElement => x !== null);\n"],"mappings":"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AAK,oBAAoB;AAC9E,UAAO;;;;;;AAOb,MAAa,0BACX,YACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YAuBA,WACG,KAAK,WAAgB,UACpB,4BACE,WACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,UACA;CACE,GAAG;CACH,KAAK,UAAU,MAAM;CACtB,CACF,CACF,CACA,QAAQ,MAAyB,MAAM,KAAK;;;;AAKjD,MAAa,0BACX,YACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YAqBA,WACG,KAAK,WAAgB,UACpB,4BACE,WACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,UACA;CACE,GAAG;CACH,KAAK,UAAU,MAAM;CACtB,CACF,CACF,CACA,QAAQ,MAAyB,MAAM,KAAK;;;;AAKjD,MAAa,4BACX,YACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YAuBA,WACG,KAAK,WAAgB,UACpB,4BACE,WACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YACA;CACE,GAAG;CACH,KAAK,UAAU,MAAM;CACtB,CACF,CACF,CACA,QAAQ,MAAyB,MAAM,KAAK;;;;;AAMjD,MAAa,8BACX,YACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,YAmCA,WACG,KAAK,WAAgB,UACpB,4BACE,WACA,YACA,eACA,YACA,WACA,aACA,WACA,eACA,UACA;CACE,GAAG;CACH,KAAK,UAAU,MAAM;CACtB,CACF,CACF,CACA,QAAQ,MAAyB,MAAM,KAAK"}
@@ -1,6 +1,6 @@
1
1
  import { css } from "../../../styles/emotion.js";
2
- import Info_default from "../../primitives/Icons/Info.js";
3
2
  import Typography_default from "../../primitives/Typography/Typography.js";
3
+ import Info_default from "../../primitives/Icons/Info.js";
4
4
  import Toggle_default from "../../primitives/Toggle/Toggle.js";
5
5
  import ConsentCheckboxList_default, { getConsentOptionalKey } from "./ConsentCheckboxList.js";
6
6
  import ConsentAuthorizationDetail_default from "./ConsentAuthorizationDetail.js";
@@ -1,11 +1,11 @@
1
1
  import { cx } from "../../../styles/emotion.js";
2
2
  import useTheme_default from "../../../contexts/Theme/useTheme.js";
3
+ import Typography_default from "../Typography/Typography.js";
3
4
  import Alert_styles_default from "./Alert.styles.js";
4
5
  import CircleAlert_default from "../Icons/CircleAlert.js";
5
6
  import CircleCheck_default from "../Icons/CircleCheck.js";
6
7
  import Info_default from "../Icons/Info.js";
7
8
  import TriangleAlert_default from "../Icons/TriangleAlert.js";
8
- import Typography_default from "../Typography/Typography.js";
9
9
  import { bem, withVendorCSSClassPrefix } from "@thunderid/browser";
10
10
  import { createContext, forwardRef, useContext } from "react";
11
11
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,7 +1,7 @@
1
1
  import { cx } from "../../../styles/emotion.js";
2
2
  import useTheme_default from "../../../contexts/Theme/useTheme.js";
3
- import Typography_default from "../Typography/Typography.js";
4
3
  import Card_styles_default from "./Card.styles.js";
4
+ import Typography_default from "../Typography/Typography.js";
5
5
  import { bem, withVendorCSSClassPrefix } from "@thunderid/browser";
6
6
  import { forwardRef } from "react";
7
7
  import { jsx } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"Typography.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Typography/Typography.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC,MAAM,MAAM,iBAAiB,GACzB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,WAAW,GACX,WAAW,GACX,OAAO,GACP,OAAO,GACP,SAAS,GACT,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAEtE,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,OAAO,GACP,SAAS,GACT,SAAS,GACT,MAAM,GACN,aAAa,GACb,eAAe,GACf,SAAS,CAAC;AAEd;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,SAAS,GACb,OAAO,KAAK,EACZ,aAAa,MAAM,EACnB,SAAS,iBAAiB,EAC1B,OAAO,eAAe,EACtB,OAAO,eAAe,EACtB,QAAQ,OAAO,EACf,QAAQ,OAAO,EACf,cAAc,OAAO,EACrB,aAAa,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,EAC/D,WAAW,MAAM,GAAG,MAAM,EAC1B,aAAa,MAAM,GAAG,MAAM,KAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CA2RyF,CAAC;AAElH,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"Typography.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Typography/Typography.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC,MAAM,MAAM,iBAAiB,GACzB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,WAAW,GACX,WAAW,GACX,OAAO,GACP,OAAO,GACP,SAAS,GACT,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAEtE,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,OAAO,GACP,SAAS,GACT,SAAS,GACT,MAAM,GACN,aAAa,GACb,eAAe,GACf,SAAS,CAAC;AAEd;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,SAAS,GACb,OAAO,KAAK,EACZ,aAAa,MAAM,EACnB,SAAS,iBAAiB,EAC1B,OAAO,eAAe,EACtB,OAAO,eAAe,EACtB,QAAQ,OAAO,EACf,QAAQ,OAAO,EACf,cAAc,OAAO,EACrB,aAAa,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,EAC/D,WAAW,MAAM,GAAG,MAAM,EAC1B,aAAa,MAAM,GAAG,MAAM,KAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAiSyF,CAAC;AAElH,eAAe,SAAS,CAAC"}
@@ -23,6 +23,9 @@ const useStyles = (theme, colorScheme, variant, align, color, noWrap, inline, gu
23
23
  case "primary": return theme.colors.primary.main;
24
24
  case "secondary": return theme.colors.secondary.main;
25
25
  case "error": return theme.colors.error.main;
26
+ case "success": return theme.colors.success.main;
27
+ case "warning": return theme.colors.warning.main;
28
+ case "info": return theme.colors.info.main;
26
29
  case "textPrimary": return theme.colors.text.primary;
27
30
  case "textSecondary": return theme.colors.text.secondary;
28
31
  case "inherit": return "inherit";
@@ -1 +1 @@
1
- {"version":3,"file":"Typography.styles.js","names":["variantStyles: Record<string, string | number>","colorValue: string","typography: string","typographyNoWrap: string","typographyInline: string","typographyGutterBottom: string","typographyH1: string","typographyH2: string","typographyH3: string","typographyH4: string","typographyH5: string","typographyH6: string","typographySubtitle1: string","typographySubtitle2: string","typographyBody1: string","typographyBody2: string","typographyCaption: string","typographyOverline: string"],"sources":["../../../../src/components/primitives/Typography/Typography.styles.ts"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\nimport {css} from '../../../styles/emotion';\n\nexport type TypographyVariant =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n | 'subtitle1'\n | 'subtitle2'\n | 'body1'\n | 'body2'\n | 'caption'\n | 'overline'\n | 'button';\n\nexport type TypographyAlign = 'left' | 'center' | 'right' | 'justify';\n\nexport type TypographyColor =\n | 'primary'\n | 'secondary'\n | 'error'\n | 'success'\n | 'warning'\n | 'info'\n | 'textPrimary'\n | 'textSecondary'\n | 'inherit';\n\n/**\n * Creates styles for the Typography component using BEM methodology\n * @param theme - The theme object containing design tokens\n * @param colorScheme - The current color scheme (used for memoization)\n * @param variant - The typography variant\n * @param align - Text alignment\n * @param color - Color variant\n * @param noWrap - Whether text should be truncated with ellipsis\n * @param inline - Whether text should be displayed inline\n * @param gutterBottom - Whether to add bottom margin\n * @param fontWeight - Custom font weight\n * @param fontSize - Custom font size\n * @param lineHeight - Custom line height\n * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (\n theme: Theme,\n colorScheme: string,\n variant: TypographyVariant,\n align: TypographyAlign,\n color: TypographyColor,\n noWrap: boolean,\n inline: boolean,\n gutterBottom: boolean,\n fontWeight?: 'normal' | 'medium' | 'semibold' | 'bold' | number,\n fontSize?: string | number,\n lineHeight?: string | number,\n): Record<string, string> =>\n useMemo(() => {\n const getColorValue = (colorVariant: TypographyColor): string => {\n switch (colorVariant) {\n case 'primary':\n return theme.colors.primary.main;\n case 'secondary':\n return theme.colors.secondary.main;\n case 'error':\n return theme.colors.error.main;\n case 'textPrimary':\n return theme.colors.text.primary;\n case 'textSecondary':\n return theme.colors.text.secondary;\n case 'inherit':\n return 'inherit';\n default:\n return theme.colors.text.primary;\n }\n };\n\n const getVariantStyles = (variantName: TypographyVariant): Record<string, string | number> => {\n switch (variantName) {\n case 'h1':\n return {\n fontSize: theme.vars.typography.fontSizes['3xl'],\n fontWeight: 600,\n letterSpacing: '-0.00735em',\n lineHeight: 1.235,\n };\n case 'h2':\n return {\n fontSize: theme.vars.typography.fontSizes['2xl'],\n fontWeight: 600,\n letterSpacing: '0em',\n lineHeight: 1.334,\n };\n case 'h3':\n return {\n fontSize: theme.vars.typography.fontSizes.xl,\n fontWeight: 600,\n letterSpacing: '0.0075em',\n lineHeight: 1.6,\n };\n case 'h4':\n return {\n fontSize: theme.vars.typography.fontSizes.lg,\n fontWeight: 600,\n letterSpacing: '0.00938em',\n lineHeight: 1.5,\n };\n case 'h5':\n return {\n fontSize: theme.vars.typography.fontSizes.md,\n fontWeight: 600,\n letterSpacing: '0em',\n lineHeight: 1.334,\n };\n case 'h6':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 500,\n letterSpacing: '0.0075em',\n lineHeight: 1.6,\n };\n case 'subtitle1':\n return {\n fontSize: theme.vars.typography.fontSizes.md,\n fontWeight: 400,\n letterSpacing: '0.00938em',\n lineHeight: 1.75,\n };\n case 'subtitle2':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 500,\n letterSpacing: '0.00714em',\n lineHeight: 1.57,\n };\n case 'body1':\n return {\n fontSize: theme.vars.typography.fontSizes.md,\n fontWeight: 400,\n letterSpacing: '0.00938em',\n lineHeight: 1.5,\n };\n case 'body2':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 400,\n letterSpacing: '0.01071em',\n lineHeight: 1.43,\n };\n case 'caption':\n return {\n fontSize: theme.vars.typography.fontSizes.xs,\n fontWeight: 400,\n letterSpacing: '0.03333em',\n lineHeight: 1.66,\n };\n case 'overline':\n return {\n fontSize: theme.vars.typography.fontSizes.xs,\n fontWeight: 400,\n letterSpacing: '0.08333em',\n lineHeight: 2.66,\n textTransform: 'uppercase' as const,\n };\n case 'button':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 500,\n letterSpacing: '0.02857em',\n lineHeight: 1.75,\n textTransform: 'uppercase' as const,\n };\n default:\n return {};\n }\n };\n\n const variantStyles: Record<string, string | number> = getVariantStyles(variant);\n const colorValue: string = getColorValue(color);\n\n const typography: string = css`\n margin: 0;\n font-family: ${theme.vars.typography.fontFamily};\n color: ${colorValue};\n text-align: ${align};\n display: ${inline ? 'inline' : 'block'};\n ${variantStyles['fontSize'] ? `font-size: ${variantStyles['fontSize']};` : ''}\n ${variantStyles['fontWeight'] ? `font-weight: ${variantStyles['fontWeight']};` : ''}\n ${variantStyles['lineHeight'] ? `line-height: ${variantStyles['lineHeight']};` : ''}\n ${variantStyles['letterSpacing'] ? `letter-spacing: ${variantStyles['letterSpacing']};` : ''}\n ${variantStyles['textTransform'] ? `text-transform: ${variantStyles['textTransform']};` : ''}\n\n /* Custom overrides */\n ${fontWeight ? `font-weight: ${fontWeight} !important;` : ''}\n ${fontSize ? `font-size: ${typeof fontSize === 'number' ? `${fontSize}px` : fontSize} !important;` : ''}\n ${lineHeight ? `line-height: ${lineHeight} !important;` : ''}\n\n /* Conditional styles */\n ${noWrap\n ? `\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `\n : ''}\n\n ${gutterBottom\n ? `\n margin-bottom: ${theme.spacing.unit}px;\n `\n : ''}\n `;\n\n const typographyNoWrap: string = css`\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `;\n\n const typographyInline: string = css`\n display: inline;\n `;\n\n const typographyGutterBottom: string = css`\n margin-bottom: ${theme.spacing.unit}px;\n `;\n\n const typographyH1: string = css`\n font-size: ${theme.vars.typography.fontSizes['3xl']};\n font-weight: 600;\n line-height: 1.235;\n letter-spacing: -0.00735em;\n `;\n\n const typographyH2: string = css`\n font-size: ${theme.vars.typography.fontSizes['2xl']};\n font-weight: 600;\n line-height: 1.334;\n letter-spacing: 0em;\n `;\n\n const typographyH3: string = css`\n font-size: ${theme.vars.typography.fontSizes.xl};\n font-weight: 600;\n line-height: 1.6;\n letter-spacing: 0.0075em;\n `;\n\n const typographyH4: string = css`\n font-size: ${theme.vars.typography.fontSizes.lg};\n font-weight: 600;\n line-height: 1.5;\n letter-spacing: 0.00938em;\n `;\n\n const typographyH5: string = css`\n font-size: ${theme.vars.typography.fontSizes.md};\n font-weight: 600;\n line-height: 1.334;\n letter-spacing: 0em;\n `;\n\n const typographyH6: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 500;\n line-height: 1.6;\n letter-spacing: 0.0075em;\n `;\n\n const typographySubtitle1: string = css`\n font-size: ${theme.vars.typography.fontSizes.md};\n font-weight: 400;\n line-height: 1.75;\n letter-spacing: 0.00938em;\n `;\n\n const typographySubtitle2: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 500;\n line-height: 1.57;\n letter-spacing: 0.00714em;\n `;\n\n const typographyBody1: string = css`\n font-size: ${theme.vars.typography.fontSizes.md};\n font-weight: 400;\n line-height: 1.5;\n letter-spacing: 0.00938em;\n `;\n\n const typographyBody2: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 400;\n line-height: 1.43;\n letter-spacing: 0.01071em;\n `;\n\n const typographyCaption: string = css`\n font-size: ${theme.vars.typography.fontSizes.xs};\n font-weight: 400;\n line-height: 1.66;\n letter-spacing: 0.03333em;\n `;\n\n const typographyOverline: string = css`\n font-size: ${theme.vars.typography.fontSizes.xs};\n font-weight: 400;\n line-height: 2.66;\n letter-spacing: 0.08333em;\n text-transform: uppercase;\n `;\n\n const typographyButton: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 500;\n line-height: 1.75;\n letter-spacing: 0.02857em;\n text-transform: uppercase;\n `;\n\n return {\n typography,\n typographyBody1,\n typographyBody2,\n typographyButton,\n typographyCaption,\n typographyGutterBottom,\n typographyH1,\n typographyH2,\n typographyH3,\n typographyH4,\n typographyH5,\n typographyH6,\n typographyInline,\n typographyNoWrap,\n typographyOverline,\n typographySubtitle1,\n typographySubtitle2,\n };\n }, [theme, colorScheme, variant, align, color, noWrap, inline, gutterBottom, fontWeight, fontSize, lineHeight]);\n\nexport default useStyles;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Typography.styles.js","names":["variantStyles: Record<string, string | number>","colorValue: string","typography: string","typographyNoWrap: string","typographyInline: string","typographyGutterBottom: string","typographyH1: string","typographyH2: string","typographyH3: string","typographyH4: string","typographyH5: string","typographyH6: string","typographySubtitle1: string","typographySubtitle2: string","typographyBody1: string","typographyBody2: string","typographyCaption: string","typographyOverline: string"],"sources":["../../../../src/components/primitives/Typography/Typography.styles.ts"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\nimport {css} from '../../../styles/emotion';\n\nexport type TypographyVariant =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n | 'subtitle1'\n | 'subtitle2'\n | 'body1'\n | 'body2'\n | 'caption'\n | 'overline'\n | 'button';\n\nexport type TypographyAlign = 'left' | 'center' | 'right' | 'justify';\n\nexport type TypographyColor =\n | 'primary'\n | 'secondary'\n | 'error'\n | 'success'\n | 'warning'\n | 'info'\n | 'textPrimary'\n | 'textSecondary'\n | 'inherit';\n\n/**\n * Creates styles for the Typography component using BEM methodology\n * @param theme - The theme object containing design tokens\n * @param colorScheme - The current color scheme (used for memoization)\n * @param variant - The typography variant\n * @param align - Text alignment\n * @param color - Color variant\n * @param noWrap - Whether text should be truncated with ellipsis\n * @param inline - Whether text should be displayed inline\n * @param gutterBottom - Whether to add bottom margin\n * @param fontWeight - Custom font weight\n * @param fontSize - Custom font size\n * @param lineHeight - Custom line height\n * @returns Object containing CSS class names for component styling\n */\nconst useStyles = (\n theme: Theme,\n colorScheme: string,\n variant: TypographyVariant,\n align: TypographyAlign,\n color: TypographyColor,\n noWrap: boolean,\n inline: boolean,\n gutterBottom: boolean,\n fontWeight?: 'normal' | 'medium' | 'semibold' | 'bold' | number,\n fontSize?: string | number,\n lineHeight?: string | number,\n): Record<string, string> =>\n useMemo(() => {\n const getColorValue = (colorVariant: TypographyColor): string => {\n switch (colorVariant) {\n case 'primary':\n return theme.colors.primary.main;\n case 'secondary':\n return theme.colors.secondary.main;\n case 'error':\n return theme.colors.error.main;\n case 'success':\n return theme.colors.success.main;\n case 'warning':\n return theme.colors.warning.main;\n case 'info':\n return theme.colors.info.main;\n case 'textPrimary':\n return theme.colors.text.primary;\n case 'textSecondary':\n return theme.colors.text.secondary;\n case 'inherit':\n return 'inherit';\n default:\n return theme.colors.text.primary;\n }\n };\n\n const getVariantStyles = (variantName: TypographyVariant): Record<string, string | number> => {\n switch (variantName) {\n case 'h1':\n return {\n fontSize: theme.vars.typography.fontSizes['3xl'],\n fontWeight: 600,\n letterSpacing: '-0.00735em',\n lineHeight: 1.235,\n };\n case 'h2':\n return {\n fontSize: theme.vars.typography.fontSizes['2xl'],\n fontWeight: 600,\n letterSpacing: '0em',\n lineHeight: 1.334,\n };\n case 'h3':\n return {\n fontSize: theme.vars.typography.fontSizes.xl,\n fontWeight: 600,\n letterSpacing: '0.0075em',\n lineHeight: 1.6,\n };\n case 'h4':\n return {\n fontSize: theme.vars.typography.fontSizes.lg,\n fontWeight: 600,\n letterSpacing: '0.00938em',\n lineHeight: 1.5,\n };\n case 'h5':\n return {\n fontSize: theme.vars.typography.fontSizes.md,\n fontWeight: 600,\n letterSpacing: '0em',\n lineHeight: 1.334,\n };\n case 'h6':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 500,\n letterSpacing: '0.0075em',\n lineHeight: 1.6,\n };\n case 'subtitle1':\n return {\n fontSize: theme.vars.typography.fontSizes.md,\n fontWeight: 400,\n letterSpacing: '0.00938em',\n lineHeight: 1.75,\n };\n case 'subtitle2':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 500,\n letterSpacing: '0.00714em',\n lineHeight: 1.57,\n };\n case 'body1':\n return {\n fontSize: theme.vars.typography.fontSizes.md,\n fontWeight: 400,\n letterSpacing: '0.00938em',\n lineHeight: 1.5,\n };\n case 'body2':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 400,\n letterSpacing: '0.01071em',\n lineHeight: 1.43,\n };\n case 'caption':\n return {\n fontSize: theme.vars.typography.fontSizes.xs,\n fontWeight: 400,\n letterSpacing: '0.03333em',\n lineHeight: 1.66,\n };\n case 'overline':\n return {\n fontSize: theme.vars.typography.fontSizes.xs,\n fontWeight: 400,\n letterSpacing: '0.08333em',\n lineHeight: 2.66,\n textTransform: 'uppercase' as const,\n };\n case 'button':\n return {\n fontSize: theme.vars.typography.fontSizes.sm,\n fontWeight: 500,\n letterSpacing: '0.02857em',\n lineHeight: 1.75,\n textTransform: 'uppercase' as const,\n };\n default:\n return {};\n }\n };\n\n const variantStyles: Record<string, string | number> = getVariantStyles(variant);\n const colorValue: string = getColorValue(color);\n\n const typography: string = css`\n margin: 0;\n font-family: ${theme.vars.typography.fontFamily};\n color: ${colorValue};\n text-align: ${align};\n display: ${inline ? 'inline' : 'block'};\n ${variantStyles['fontSize'] ? `font-size: ${variantStyles['fontSize']};` : ''}\n ${variantStyles['fontWeight'] ? `font-weight: ${variantStyles['fontWeight']};` : ''}\n ${variantStyles['lineHeight'] ? `line-height: ${variantStyles['lineHeight']};` : ''}\n ${variantStyles['letterSpacing'] ? `letter-spacing: ${variantStyles['letterSpacing']};` : ''}\n ${variantStyles['textTransform'] ? `text-transform: ${variantStyles['textTransform']};` : ''}\n\n /* Custom overrides */\n ${fontWeight ? `font-weight: ${fontWeight} !important;` : ''}\n ${fontSize ? `font-size: ${typeof fontSize === 'number' ? `${fontSize}px` : fontSize} !important;` : ''}\n ${lineHeight ? `line-height: ${lineHeight} !important;` : ''}\n\n /* Conditional styles */\n ${noWrap\n ? `\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `\n : ''}\n\n ${gutterBottom\n ? `\n margin-bottom: ${theme.spacing.unit}px;\n `\n : ''}\n `;\n\n const typographyNoWrap: string = css`\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `;\n\n const typographyInline: string = css`\n display: inline;\n `;\n\n const typographyGutterBottom: string = css`\n margin-bottom: ${theme.spacing.unit}px;\n `;\n\n const typographyH1: string = css`\n font-size: ${theme.vars.typography.fontSizes['3xl']};\n font-weight: 600;\n line-height: 1.235;\n letter-spacing: -0.00735em;\n `;\n\n const typographyH2: string = css`\n font-size: ${theme.vars.typography.fontSizes['2xl']};\n font-weight: 600;\n line-height: 1.334;\n letter-spacing: 0em;\n `;\n\n const typographyH3: string = css`\n font-size: ${theme.vars.typography.fontSizes.xl};\n font-weight: 600;\n line-height: 1.6;\n letter-spacing: 0.0075em;\n `;\n\n const typographyH4: string = css`\n font-size: ${theme.vars.typography.fontSizes.lg};\n font-weight: 600;\n line-height: 1.5;\n letter-spacing: 0.00938em;\n `;\n\n const typographyH5: string = css`\n font-size: ${theme.vars.typography.fontSizes.md};\n font-weight: 600;\n line-height: 1.334;\n letter-spacing: 0em;\n `;\n\n const typographyH6: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 500;\n line-height: 1.6;\n letter-spacing: 0.0075em;\n `;\n\n const typographySubtitle1: string = css`\n font-size: ${theme.vars.typography.fontSizes.md};\n font-weight: 400;\n line-height: 1.75;\n letter-spacing: 0.00938em;\n `;\n\n const typographySubtitle2: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 500;\n line-height: 1.57;\n letter-spacing: 0.00714em;\n `;\n\n const typographyBody1: string = css`\n font-size: ${theme.vars.typography.fontSizes.md};\n font-weight: 400;\n line-height: 1.5;\n letter-spacing: 0.00938em;\n `;\n\n const typographyBody2: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 400;\n line-height: 1.43;\n letter-spacing: 0.01071em;\n `;\n\n const typographyCaption: string = css`\n font-size: ${theme.vars.typography.fontSizes.xs};\n font-weight: 400;\n line-height: 1.66;\n letter-spacing: 0.03333em;\n `;\n\n const typographyOverline: string = css`\n font-size: ${theme.vars.typography.fontSizes.xs};\n font-weight: 400;\n line-height: 2.66;\n letter-spacing: 0.08333em;\n text-transform: uppercase;\n `;\n\n const typographyButton: string = css`\n font-size: ${theme.vars.typography.fontSizes.sm};\n font-weight: 500;\n line-height: 1.75;\n letter-spacing: 0.02857em;\n text-transform: uppercase;\n `;\n\n return {\n typography,\n typographyBody1,\n typographyBody2,\n typographyButton,\n typographyCaption,\n typographyGutterBottom,\n typographyH1,\n typographyH2,\n typographyH3,\n typographyH4,\n typographyH5,\n typographyH6,\n typographyInline,\n typographyNoWrap,\n typographyOverline,\n typographySubtitle1,\n typographySubtitle2,\n };\n }, [theme, colorScheme, variant, align, color, noWrap, inline, gutterBottom, fontWeight, fontSize, lineHeight]);\n\nexport default useStyles;\n"],"mappings":"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"}
@@ -41,6 +41,12 @@ export type ThunderIDContextProps = {
41
41
  * @returns A promise that resolves to the access token.
42
42
  */
43
43
  getAccessToken: () => Promise<string>;
44
+ /**
45
+ * Retrieves the permissions the signed-in user's access token grants. In backend mode they come from
46
+ * the backend's session, so the token stays on the backend.
47
+ * @returns A promise that resolves to the granted permissions.
48
+ */
49
+ getGrantedPermissions: () => Promise<string[]>;
44
50
  /**
45
51
  * Function to retrieve the decoded ID token.
46
52
  * This function decodes the ID token and returns its payload.
@@ -1 +1 @@
1
- {"version":3,"file":"ThunderIDContext.d.ts","sourceRoot":"","sources":["../../../src/contexts/ThunderID/ThunderIDContext.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,mBAAmB,EAEnB,UAAU,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,0BAA0B,EAC1B,aAAa,EAEb,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,OAAO,EAAgB,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AACzD,OAAO,oBAAoB,MAAM,4BAA4B,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,oBAAoB,CAAC,aAAa,CAAC,CAAC;IAClD,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC;;OAEG;IACH,SAAS,EAAE;QACT;;;;WAIG;QACH,SAAS,EAAE,wBAAwB,GAAG,IAAI,CAAC;KAC5C,CAAC;IACF;;;;OAIG;IACH,aAAa,EAAE,CAAC,MAAM,EAAE,0BAA0B,KAAK,OAAO,CAAC,aAAa,GAAG,QAAQ,CAAC,CAAC;IACzF;;;;;OAKG;IACH,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C;;;;;OAKG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC;;;OAGG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9E;;;;OAIG;IACH,IAAI,EAAE;QACJ;;;WAGG;QACH,OAAO,CAAC,EAAE,UAAU,CAAC;QACrB;;;;WAIG;QACH,OAAO,EAAE,CAAC,aAAa,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E;;;;WAIG;QACH,UAAU,EAAE,CAAC,cAAc,CAAC,EAAE,iBAAiB,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;KACpF,CAAC;IACF;;;OAGG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAElC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC;;;;;;;;OAQG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1E;;OAEG;IACH,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,2BAA2B,KAAK,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAE1F;;;;;;;;;;;OAWG;IACH,2BAA2B,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,CAAC;IAElE;;;;OAIG;IACH,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAEvC;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACb,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,CAAC;IAEF;;;OAGG;IACH,cAAc,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IAEvD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;;;;OAIG;IACH,OAAO,EAAE,GAAG,CAAC;IAEb;;;OAGG;IACH,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAEzC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAE9B,IAAI,EAAE,GAAG,CAAC;IAEV;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI,CAAC;IAEnD;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;AAE/C;;GAEG;AACH,QAAA,MAAM,gBAAgB,EAAE,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAwC1D,CAAC;AAIH,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"ThunderIDContext.d.ts","sourceRoot":"","sources":["../../../src/contexts/ThunderID/ThunderIDContext.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ const ThunderIDContext = createContext({
16
16
  discovery: { wellKnown: null },
17
17
  exchangeToken: null,
18
18
  getAccessToken: null,
19
+ getGrantedPermissions: null,
19
20
  getDecodedIdToken: null,
20
21
  getIdToken: null,
21
22
  getStorageManager: () => Promise.resolve(null),
@@ -1 +1 @@
1
- {"version":3,"file":"ThunderIDContext.js","names":["ThunderIDContext: Context<ThunderIDContextProps | null>"],"sources":["../../../src/contexts/ThunderID/ThunderIDContext.ts"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ResourceInvalidator,\n fallbackResourceInvalidator,\n ApiFetcher,\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n FlowMetadataResponse,\n HttpRequestConfig,\n HttpResponse,\n IdToken,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n StorageManager,\n TokenExchangeRequestConfig,\n TokenResponse,\n VendorConstants,\n AttributeSchema,\n} from '@thunderid/browser';\nimport {Context, createContext} from 'react';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\n\n/**\n * Props interface of {@link ThunderIDContext}\n */\nexport type ThunderIDContextProps = {\n afterSignInUrl: string | undefined;\n applicationId: string | undefined;\n baseUrl: string | undefined;\n clientId: string | undefined;\n /**\n * Optional endpoint URL overrides from the client config. Used to resolve resource-server\n * endpoints (e.g. flow/user-management) independently of `baseUrl` — see `resolveResourceEndpoint`.\n */\n endpoints?: ThunderIDReactConfig['endpoints'];\n preferences?: ThunderIDReactConfig['preferences'];\n scopes: string | string[] | undefined;\n /**\n * OIDC discovery data.\n */\n discovery: {\n /**\n * The response from the `.well-known/openid-configuration` endpoint.\n * Contains server capabilities, supported endpoints, and metadata.\n * `null` while loading or when discovery has not been fetched.\n */\n wellKnown: OIDCDiscoveryApiResponse | null;\n };\n /**\n * Swaps the current access token with a new one based on the provided configuration (with a grant type).\n * @param config - Configuration for the token exchange request.\n * @returns A promise that resolves to the token response or the raw response.\n */\n exchangeToken: (config: TokenExchangeRequestConfig) => Promise<TokenResponse | Response>;\n /**\n * Retrieves the access token stored in the storage.\n * This function retrieves the access token and returns it.\n * @remarks This does not work in the `webWorker` or any other worker environment.\n * @returns A promise that resolves to the access token.\n */\n getAccessToken: () => Promise<string>;\n /**\n * Function to retrieve the decoded ID token.\n * This function decodes the ID token and returns its payload.\n * It can be used to access user claims and other information contained in the ID token.\n *\n * @returns A promise that resolves to the decoded ID token payload.\n */\n getDecodedIdToken: () => Promise<IdToken>;\n /**\n * Function to retrieve the ID token.\n * This function retrieves the ID token and returns it.\n *\n * @returns A promise that resolves to the ID token.\n */\n getIdToken: () => Promise<string>;\n /**\n * Returns the underlying StorageManager instance for reading and writing SDK-managed storage.\n * Resolves to `null` where the SDK has no browser storage (the context default, and `@thunderid/nextjs`).\n */\n getStorageManager: () => Promise<StorageManager<ThunderIDReactConfig> | null>;\n /**\n * HTTP request function to make API calls.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n http: {\n /**\n * Transport supplied through `ThunderIDProvider`'s `http.fetcher` prop, used by the management\n * hooks. `undefined` means the hooks fall back to the SDK's authenticated HTTP client.\n */\n fetcher?: ApiFetcher;\n /**\n * Makes an HTTP request using the provided configuration.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n request: (requestConfig?: HttpRequestConfig) => Promise<HttpResponse<any>>;\n /**\n * Makes multiple HTTP requests based on the provided configuration.\n * @param requestConfigs - Set of configurations for the HTTP requests.\n * @returns A promise that resolves to an array of HTTP responses.\n */\n requestAll: (requestConfigs?: HttpRequestConfig[]) => Promise<HttpResponse<any>[]>;\n };\n /**\n * Coordinates refetching between the management hooks: a successful mutation invalidates the\n * queries whose data it changed.\n */\n invalidator?: ResourceInvalidator;\n /**\n * Instance ID for multi-instance support.\n */\n instanceId: number;\n isInitialized: boolean;\n /**\n * Flag indicating whether the SDK is working in the background.\n */\n isLoading: boolean;\n /**\n * Flag indicating whether flow metadata is currently being fetched.\n */\n isMetaLoading: boolean;\n /**\n * Flag indicating whether the user is signed in or not.\n */\n isSignedIn: boolean;\n\n /**\n * Flow metadata returned by `GET /flow/meta` (v2 platform only).\n * `null` while loading or when `resolveFromMeta` is disabled.\n */\n meta: FlowMetadataResponse | null;\n\n organizationHandle: string | undefined;\n\n /**\n * Re-initializes the client with a new configuration.\n *\n * @remarks\n * This can be partial configuration to update only specific fields.\n *\n * @param config - New configuration to re-initialize the client with.\n * @returns Promise resolving to boolean indicating success.\n */\n reInitialize: (config: Partial<ThunderIDReactConfig>) => Promise<boolean>;\n\n /**\n * Recovery function to initiate the account/password recovery flow.\n */\n recover: (payload?: EmbeddedRecoveryFlowRequest) => Promise<EmbeddedRecoveryFlowResponse>;\n\n /**\n * Resolves `{{ t(key) }}` and `{{ meta(path) }}` template expressions in a string,\n * using the current i18n translation function and flow metadata from context.\n *\n * Useful in render-props patterns where consumers need to expand template strings\n * that come from the server (e.g. component labels, placeholders, headings).\n *\n * @example\n * const {resolveFlowTemplateLiterals} = useThunderID();\n * resolveFlowTemplateLiterals('{{ t(signin.heading.label) }}') // → 'Sign In'\n * resolveFlowTemplateLiterals('Login to {{ meta(application.name) }}') // → 'Login to My App'\n */\n resolveFlowTemplateLiterals: (text: string | undefined) => string;\n\n /**\n * Sign-in function to initiate the authentication process.\n * @remark This is the programmatic version of the `SignInButton` component.\n * TODO: Fix the types.\n */\n signIn: (...args: any) => Promise<any>;\n\n /**\n * Optional additional parameters to be sent in the sign-in request.\n * This can include custom parameters that your authorization server supports.\n * These parameters will be included in the authorization request sent to the server.\n * If not provided, no additional parameters will be sent.\n *\n * @example\n * signInOptions: { prompt: \"login\", fidp: \"OrganizationSSO\" }\n */\n signInOptions?: SignInOptions;\n\n /**\n * Optional token request configuration. params are appended to the token endpoint POST body.\n *\n * @example\n * tokenRequest: { params: { resource: \"https://api.example.com\" } }\n */\n tokenRequest?: {\n params?: Record<string, unknown>;\n };\n\n /**\n * Silent sign-in function to re-authenticate the user without user interaction.\n * @remark This is the programmatic version of the `SilentSignIn` component.\n */\n signInSilently: ThunderIDReactClient['signInSilently'];\n\n signInUrl: string | undefined;\n /**\n * Sign-out function to terminate the authentication session.\n * @remark This is the programmatic version of the `SignOutButton` component.\n * FIXME: Fix the types.\n */\n signOut: any;\n\n /**\n * Sign-up function to initiate the registration process.\n * @remark This is the programmatic version of the `SignUpButton` component.\n */\n signUp: (...args: any[]) => Promise<any>;\n\n signUpUrl: string | undefined;\n\n user: any;\n\n /**\n * Schema metadata for the user type returned by GET /users/me/meta.\n */\n userSchema: Record<string, AttributeSchema> | null;\n\n /**\n * Vendor/brand namespace used to prefix storage keys, cookie names, and CSS class names.\n * Resolved from the `vendor` config option, defaulting to `'thunderid'`.\n */\n vendor: string;\n} & Pick<ThunderIDReactClient, 'clearSession'>;\n\n/**\n * Context object for managing the Authentication flow builder core context.\n */\nconst ThunderIDContext: Context<ThunderIDContextProps | null> = createContext<null | ThunderIDContextProps>({\n afterSignInUrl: undefined,\n applicationId: undefined,\n baseUrl: undefined,\n clearSession: () => {},\n clientId: undefined,\n preferences: undefined,\n scopes: undefined,\n discovery: {\n wellKnown: null,\n },\n exchangeToken: null as unknown as ThunderIDContextProps['exchangeToken'],\n getAccessToken: null as unknown as ThunderIDContextProps['getAccessToken'],\n getDecodedIdToken: null as unknown as ThunderIDContextProps['getDecodedIdToken'],\n getIdToken: null as unknown as ThunderIDContextProps['getIdToken'],\n getStorageManager: () => Promise.resolve(null),\n http: {\n request: () => null as unknown as Promise<HttpResponse<any>>,\n requestAll: () => null as unknown as Promise<HttpResponse<any>[]>,\n },\n instanceId: 0,\n invalidator: fallbackResourceInvalidator,\n isInitialized: false,\n isLoading: true,\n isMetaLoading: false,\n isSignedIn: false,\n meta: null,\n organizationHandle: undefined,\n reInitialize: null as unknown as ThunderIDContextProps['reInitialize'],\n recover: () => Promise.resolve({} as any),\n resolveFlowTemplateLiterals: (text: string | undefined) => text ?? '',\n signIn: () => Promise.resolve({} as any),\n signInSilently: () => Promise.resolve({} as any),\n signInUrl: undefined,\n signOut: () => Promise.resolve({} as any),\n signUp: () => Promise.resolve({} as any),\n signUpUrl: undefined,\n user: null,\n userSchema: null,\n vendor: VendorConstants.VENDOR_PREFIX,\n});\n\nThunderIDContext.displayName = 'ThunderIDContext';\n\nexport default ThunderIDContext;\n"],"mappings":";;;;;;;AA4OA,MAAMA,mBAA0D,cAA4C;CAC1G,gBAAgB;CAChB,eAAe;CACf,SAAS;CACT,oBAAoB;CACpB,UAAU;CACV,aAAa;CACb,QAAQ;CACR,WAAW,EACT,WAAW,MACZ;CACD,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,YAAY;CACZ,yBAAyB,QAAQ,QAAQ,KAAK;CAC9C,MAAM;EACJ,eAAe;EACf,kBAAkB;EACnB;CACD,YAAY;CACZ,aAAa;CACb,eAAe;CACf,WAAW;CACX,eAAe;CACf,YAAY;CACZ,MAAM;CACN,oBAAoB;CACpB,cAAc;CACd,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,8BAA8B,SAA6B,QAAQ;CACnE,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,sBAAsB,QAAQ,QAAQ,EAAE,CAAQ;CAChD,WAAW;CACX,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,WAAW;CACX,MAAM;CACN,YAAY;CACZ,QAAQ,gBAAgB;CACzB,CAAC;AAEF,iBAAiB,cAAc;AAE/B,+BAAe"}
1
+ {"version":3,"file":"ThunderIDContext.js","names":["ThunderIDContext: Context<ThunderIDContextProps | null>"],"sources":["../../../src/contexts/ThunderID/ThunderIDContext.ts"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ResourceInvalidator,\n fallbackResourceInvalidator,\n ApiFetcher,\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n FlowMetadataResponse,\n HttpRequestConfig,\n HttpResponse,\n IdToken,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n StorageManager,\n TokenExchangeRequestConfig,\n TokenResponse,\n VendorConstants,\n AttributeSchema,\n} from '@thunderid/browser';\nimport {Context, createContext} from 'react';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\n\n/**\n * Props interface of {@link ThunderIDContext}\n */\nexport type ThunderIDContextProps = {\n afterSignInUrl: string | undefined;\n applicationId: string | undefined;\n baseUrl: string | undefined;\n clientId: string | undefined;\n /**\n * Optional endpoint URL overrides from the client config. Used to resolve resource-server\n * endpoints (e.g. flow/user-management) independently of `baseUrl` — see `resolveResourceEndpoint`.\n */\n endpoints?: ThunderIDReactConfig['endpoints'];\n preferences?: ThunderIDReactConfig['preferences'];\n scopes: string | string[] | undefined;\n /**\n * OIDC discovery data.\n */\n discovery: {\n /**\n * The response from the `.well-known/openid-configuration` endpoint.\n * Contains server capabilities, supported endpoints, and metadata.\n * `null` while loading or when discovery has not been fetched.\n */\n wellKnown: OIDCDiscoveryApiResponse | null;\n };\n /**\n * Swaps the current access token with a new one based on the provided configuration (with a grant type).\n * @param config - Configuration for the token exchange request.\n * @returns A promise that resolves to the token response or the raw response.\n */\n exchangeToken: (config: TokenExchangeRequestConfig) => Promise<TokenResponse | Response>;\n /**\n * Retrieves the access token stored in the storage.\n * This function retrieves the access token and returns it.\n * @remarks This does not work in the `webWorker` or any other worker environment.\n * @returns A promise that resolves to the access token.\n */\n getAccessToken: () => Promise<string>;\n /**\n * Retrieves the permissions the signed-in user's access token grants. In backend mode they come from\n * the backend's session, so the token stays on the backend.\n * @returns A promise that resolves to the granted permissions.\n */\n getGrantedPermissions: () => Promise<string[]>;\n /**\n * Function to retrieve the decoded ID token.\n * This function decodes the ID token and returns its payload.\n * It can be used to access user claims and other information contained in the ID token.\n *\n * @returns A promise that resolves to the decoded ID token payload.\n */\n getDecodedIdToken: () => Promise<IdToken>;\n /**\n * Function to retrieve the ID token.\n * This function retrieves the ID token and returns it.\n *\n * @returns A promise that resolves to the ID token.\n */\n getIdToken: () => Promise<string>;\n /**\n * Returns the underlying StorageManager instance for reading and writing SDK-managed storage.\n * Resolves to `null` where the SDK has no browser storage (the context default, and `@thunderid/nextjs`).\n */\n getStorageManager: () => Promise<StorageManager<ThunderIDReactConfig> | null>;\n /**\n * HTTP request function to make API calls.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n http: {\n /**\n * Transport supplied through `ThunderIDProvider`'s `http.fetcher` prop, used by the management\n * hooks. `undefined` means the hooks fall back to the SDK's authenticated HTTP client.\n */\n fetcher?: ApiFetcher;\n /**\n * Makes an HTTP request using the provided configuration.\n * @param requestConfig - Configuration for the HTTP request.\n * @returns A promise that resolves to the HTTP response.\n */\n request: (requestConfig?: HttpRequestConfig) => Promise<HttpResponse<any>>;\n /**\n * Makes multiple HTTP requests based on the provided configuration.\n * @param requestConfigs - Set of configurations for the HTTP requests.\n * @returns A promise that resolves to an array of HTTP responses.\n */\n requestAll: (requestConfigs?: HttpRequestConfig[]) => Promise<HttpResponse<any>[]>;\n };\n /**\n * Coordinates refetching between the management hooks: a successful mutation invalidates the\n * queries whose data it changed.\n */\n invalidator?: ResourceInvalidator;\n /**\n * Instance ID for multi-instance support.\n */\n instanceId: number;\n isInitialized: boolean;\n /**\n * Flag indicating whether the SDK is working in the background.\n */\n isLoading: boolean;\n /**\n * Flag indicating whether flow metadata is currently being fetched.\n */\n isMetaLoading: boolean;\n /**\n * Flag indicating whether the user is signed in or not.\n */\n isSignedIn: boolean;\n\n /**\n * Flow metadata returned by `GET /flow/meta` (v2 platform only).\n * `null` while loading or when `resolveFromMeta` is disabled.\n */\n meta: FlowMetadataResponse | null;\n\n organizationHandle: string | undefined;\n\n /**\n * Re-initializes the client with a new configuration.\n *\n * @remarks\n * This can be partial configuration to update only specific fields.\n *\n * @param config - New configuration to re-initialize the client with.\n * @returns Promise resolving to boolean indicating success.\n */\n reInitialize: (config: Partial<ThunderIDReactConfig>) => Promise<boolean>;\n\n /**\n * Recovery function to initiate the account/password recovery flow.\n */\n recover: (payload?: EmbeddedRecoveryFlowRequest) => Promise<EmbeddedRecoveryFlowResponse>;\n\n /**\n * Resolves `{{ t(key) }}` and `{{ meta(path) }}` template expressions in a string,\n * using the current i18n translation function and flow metadata from context.\n *\n * Useful in render-props patterns where consumers need to expand template strings\n * that come from the server (e.g. component labels, placeholders, headings).\n *\n * @example\n * const {resolveFlowTemplateLiterals} = useThunderID();\n * resolveFlowTemplateLiterals('{{ t(signin.heading.label) }}') // → 'Sign In'\n * resolveFlowTemplateLiterals('Login to {{ meta(application.name) }}') // → 'Login to My App'\n */\n resolveFlowTemplateLiterals: (text: string | undefined) => string;\n\n /**\n * Sign-in function to initiate the authentication process.\n * @remark This is the programmatic version of the `SignInButton` component.\n * TODO: Fix the types.\n */\n signIn: (...args: any) => Promise<any>;\n\n /**\n * Optional additional parameters to be sent in the sign-in request.\n * This can include custom parameters that your authorization server supports.\n * These parameters will be included in the authorization request sent to the server.\n * If not provided, no additional parameters will be sent.\n *\n * @example\n * signInOptions: { prompt: \"login\", fidp: \"OrganizationSSO\" }\n */\n signInOptions?: SignInOptions;\n\n /**\n * Optional token request configuration. params are appended to the token endpoint POST body.\n *\n * @example\n * tokenRequest: { params: { resource: \"https://api.example.com\" } }\n */\n tokenRequest?: {\n params?: Record<string, unknown>;\n };\n\n /**\n * Silent sign-in function to re-authenticate the user without user interaction.\n * @remark This is the programmatic version of the `SilentSignIn` component.\n */\n signInSilently: ThunderIDReactClient['signInSilently'];\n\n signInUrl: string | undefined;\n /**\n * Sign-out function to terminate the authentication session.\n * @remark This is the programmatic version of the `SignOutButton` component.\n * FIXME: Fix the types.\n */\n signOut: any;\n\n /**\n * Sign-up function to initiate the registration process.\n * @remark This is the programmatic version of the `SignUpButton` component.\n */\n signUp: (...args: any[]) => Promise<any>;\n\n signUpUrl: string | undefined;\n\n user: any;\n\n /**\n * Schema metadata for the user type returned by GET /users/me/meta.\n */\n userSchema: Record<string, AttributeSchema> | null;\n\n /**\n * Vendor/brand namespace used to prefix storage keys, cookie names, and CSS class names.\n * Resolved from the `vendor` config option, defaulting to `'thunderid'`.\n */\n vendor: string;\n} & Pick<ThunderIDReactClient, 'clearSession'>;\n\n/**\n * Context object for managing the Authentication flow builder core context.\n */\nconst ThunderIDContext: Context<ThunderIDContextProps | null> = createContext<null | ThunderIDContextProps>({\n afterSignInUrl: undefined,\n applicationId: undefined,\n baseUrl: undefined,\n clearSession: () => {},\n clientId: undefined,\n preferences: undefined,\n scopes: undefined,\n discovery: {\n wellKnown: null,\n },\n exchangeToken: null as unknown as ThunderIDContextProps['exchangeToken'],\n getAccessToken: null as unknown as ThunderIDContextProps['getAccessToken'],\n getGrantedPermissions: null as unknown as ThunderIDContextProps['getGrantedPermissions'],\n getDecodedIdToken: null as unknown as ThunderIDContextProps['getDecodedIdToken'],\n getIdToken: null as unknown as ThunderIDContextProps['getIdToken'],\n getStorageManager: () => Promise.resolve(null),\n http: {\n request: () => null as unknown as Promise<HttpResponse<any>>,\n requestAll: () => null as unknown as Promise<HttpResponse<any>[]>,\n },\n instanceId: 0,\n invalidator: fallbackResourceInvalidator,\n isInitialized: false,\n isLoading: true,\n isMetaLoading: false,\n isSignedIn: false,\n meta: null,\n organizationHandle: undefined,\n reInitialize: null as unknown as ThunderIDContextProps['reInitialize'],\n recover: () => Promise.resolve({} as any),\n resolveFlowTemplateLiterals: (text: string | undefined) => text ?? '',\n signIn: () => Promise.resolve({} as any),\n signInSilently: () => Promise.resolve({} as any),\n signInUrl: undefined,\n signOut: () => Promise.resolve({} as any),\n signUp: () => Promise.resolve({} as any),\n signUpUrl: undefined,\n user: null,\n userSchema: null,\n vendor: VendorConstants.VENDOR_PREFIX,\n});\n\nThunderIDContext.displayName = 'ThunderIDContext';\n\nexport default ThunderIDContext;\n"],"mappings":";;;;;;;AAkPA,MAAMA,mBAA0D,cAA4C;CAC1G,gBAAgB;CAChB,eAAe;CACf,SAAS;CACT,oBAAoB;CACpB,UAAU;CACV,aAAa;CACb,QAAQ;CACR,WAAW,EACT,WAAW,MACZ;CACD,eAAe;CACf,gBAAgB;CAChB,uBAAuB;CACvB,mBAAmB;CACnB,YAAY;CACZ,yBAAyB,QAAQ,QAAQ,KAAK;CAC9C,MAAM;EACJ,eAAe;EACf,kBAAkB;EACnB;CACD,YAAY;CACZ,aAAa;CACb,eAAe;CACf,WAAW;CACX,eAAe;CACf,YAAY;CACZ,MAAM;CACN,oBAAoB;CACpB,cAAc;CACd,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,8BAA8B,SAA6B,QAAQ;CACnE,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,sBAAsB,QAAQ,QAAQ,EAAE,CAAQ;CAChD,WAAW;CACX,eAAe,QAAQ,QAAQ,EAAE,CAAQ;CACzC,cAAc,QAAQ,QAAQ,EAAE,CAAQ;CACxC,WAAW;CACX,MAAM;CACN,YAAY;CACZ,QAAQ,gBAAgB;CACzB,CAAC;AAEF,iBAAiB,cAAc;AAE/B,+BAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../../src/contexts/ThunderID/ThunderIDProvider.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAAC,EAAE,EAAa,iBAAiB,EAAkE,MAAM,OAAO,CAAC;AAKxH,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAezD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE1D,QAAA,MAAM,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,CAgjBpE,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../../src/contexts/ThunderID/ThunderIDProvider.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAAC,EAAE,EAAa,iBAAiB,EAAkE,MAAM,OAAO,CAAC;AAKxH,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAezD;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE1D,QAAA,MAAM,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,CAujBpE,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -256,6 +256,7 @@ const ThunderIDProvider = ({ afterSignInUrl, afterSignOutUrl, baseUrl: initialBa
256
256
  const getDecodedIdToken = useCallback(async () => client.getDecodedIdToken(), [client]);
257
257
  const getIdToken = useCallback(async () => client.getIdToken(), [client]);
258
258
  const getAccessToken = useCallback(async () => client.getAccessToken(), [client]);
259
+ const getGrantedPermissions = useCallback(async () => client.getGrantedPermissions(), [client]);
259
260
  const getStorageManager = useCallback(async () => {
260
261
  const storageManager = storageManagerRef.current ?? await client.getStorageManager();
261
262
  if (storageManager) storageManagerRef.current = storageManager;
@@ -288,6 +289,7 @@ const ThunderIDProvider = ({ afterSignInUrl, afterSignOutUrl, baseUrl: initialBa
288
289
  exchangeToken,
289
290
  getAccessToken,
290
291
  getDecodedIdToken,
292
+ getGrantedPermissions,
291
293
  getIdToken,
292
294
  getStorageManager,
293
295
  http: {
@@ -343,6 +345,7 @@ const ThunderIDProvider = ({ afterSignInUrl, afterSignOutUrl, baseUrl: initialBa
343
345
  exchangeToken,
344
346
  httpOptions?.fetcher,
345
347
  getAccessToken,
348
+ getGrantedPermissions,
346
349
  getStorageManager,
347
350
  instanceId,
348
351
  invalidator,