@thunderid/react 1.17.1 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/cjs/components/account/VerifyAttribute/BaseVerifyAttribute.cjs +6 -1
  2. package/dist/cjs/components/account/VerifyAttribute/BaseVerifyAttribute.cjs.map +1 -1
  3. package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs +5 -0
  4. package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
  5. package/dist/cjs/components/auth/InviteUser/BaseInviteUser.cjs +8 -0
  6. package/dist/cjs/components/auth/InviteUser/BaseInviteUser.cjs.map +1 -1
  7. package/dist/cjs/components/auth/Recovery/BaseRecovery.cjs +9 -1
  8. package/dist/cjs/components/auth/Recovery/BaseRecovery.cjs.map +1 -1
  9. package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs +11 -4
  10. package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs.map +1 -1
  11. package/dist/cjs/components/auth/SignUp/BaseSignUp.cjs +9 -1
  12. package/dist/cjs/components/auth/SignUp/BaseSignUp.cjs.map +1 -1
  13. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +3 -1
  14. package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
  15. package/dist/cjs/contexts/ComponentRenderer/ComponentRendererContext.cjs.map +1 -1
  16. package/dist/cjs/hooks/auth/useStepExpiry.cjs +25 -0
  17. package/dist/cjs/hooks/auth/useStepExpiry.cjs.map +1 -0
  18. package/dist/cjs/hooks/useForm.cjs +2 -0
  19. package/dist/cjs/hooks/useForm.cjs.map +1 -1
  20. package/dist/components/account/VerifyAttribute/BaseVerifyAttribute.d.ts.map +1 -1
  21. package/dist/components/account/VerifyAttribute/BaseVerifyAttribute.js +6 -1
  22. package/dist/components/account/VerifyAttribute/BaseVerifyAttribute.js.map +1 -1
  23. package/dist/components/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
  24. package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +5 -0
  25. package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
  26. package/dist/components/auth/InviteUser/BaseInviteUser.d.ts.map +1 -1
  27. package/dist/components/auth/InviteUser/BaseInviteUser.js +8 -0
  28. package/dist/components/auth/InviteUser/BaseInviteUser.js.map +1 -1
  29. package/dist/components/auth/Recovery/BaseRecovery.d.ts.map +1 -1
  30. package/dist/components/auth/Recovery/BaseRecovery.js +9 -1
  31. package/dist/components/auth/Recovery/BaseRecovery.js.map +1 -1
  32. package/dist/components/auth/SignIn/BaseSignIn.d.ts.map +1 -1
  33. package/dist/components/auth/SignIn/BaseSignIn.js +11 -4
  34. package/dist/components/auth/SignIn/BaseSignIn.js.map +1 -1
  35. package/dist/components/auth/SignUp/BaseSignUp.d.ts.map +1 -1
  36. package/dist/components/auth/SignUp/BaseSignUp.js +9 -1
  37. package/dist/components/auth/SignUp/BaseSignUp.js.map +1 -1
  38. package/dist/components/auth/flow/AuthOptionFactory.d.ts +20 -0
  39. package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
  40. package/dist/components/auth/flow/AuthOptionFactory.js +3 -1
  41. package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
  42. package/dist/contexts/ComponentRenderer/ComponentRendererContext.d.ts +2 -15
  43. package/dist/contexts/ComponentRenderer/ComponentRendererContext.d.ts.map +1 -1
  44. package/dist/contexts/ComponentRenderer/ComponentRendererContext.js.map +1 -1
  45. package/dist/hooks/auth/useStepExpiry.d.ts +17 -0
  46. package/dist/hooks/auth/useStepExpiry.d.ts.map +1 -0
  47. package/dist/hooks/auth/useStepExpiry.js +23 -0
  48. package/dist/hooks/auth/useStepExpiry.js.map +1 -0
  49. package/dist/hooks/useForm.d.ts +6 -0
  50. package/dist/hooks/useForm.d.ts.map +1 -1
  51. package/dist/hooks/useForm.js +3 -1
  52. package/dist/hooks/useForm.js.map +1 -1
  53. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"BaseInviteUser.js","names":["BaseInviteUser: FC<BaseInviteUserProps>","useThunderID","useTranslation","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","styles: any","useStyles","challengeTokenRef: any","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","initializationAttemptedRef: any","tempData: any","storageManager: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","components","handleInputChange: any","newErrors: any","handleInputBlur: any","validateForm: any","value: any","handleSubmit: any","validation: any","inputs: any","payload: Record<string, any>","response: any","resetFlow: any","components: any","extractHeadings: any","title: string | undefined","subtitle: string | undefined","title","subtitle","filterHeadings: any","renderComponents: any","componentsWithoutHeadings: any","renderProps: BaseInviteUserRenderProps","CardPrimitive","Spinner","AlertPrimitive","Typography"],"sources":["../../../../src/components/auth/InviteUser/BaseInviteUser.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedFlowType,\n FieldError,\n FlowExecutionError,\n FlowMetadataResponse,\n buildValidatorFromRules,\n FetchAuthFlows,\n FetchUsers,\n FetchUserTypes,\n logger,\n OrganizationUnitListResponse,\n Preferences,\n resolveFlowTemplateLiterals,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react';\nimport useStyles from './BaseInviteUser.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../utils/flowTransformer';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderInviteUserComponents} from '../flow/AuthOptionFactory';\n\n/**\n * Flow response structure from the backend.\n */\nexport interface InviteUserFlowResponse {\n challengeToken?: string;\n data?: {\n additionalData?: Record<string, any>;\n components?: any[];\n fieldErrors?: FieldError[];\n meta?: {\n components?: any[];\n };\n };\n error?: FlowExecutionError;\n executionId: string;\n flowStatus: 'INCOMPLETE' | 'COMPLETE' | 'ERROR';\n type?: 'VIEW' | 'REDIRECTION';\n}\n\n/**\n * Render props for custom UI rendering of InviteUser.\n */\nexport interface BaseInviteUserRenderProps {\n /**\n * Additional data from the current flow response (e.g. rootOuId, inviteLink).\n */\n additionalData?: Record<string, any>;\n\n /**\n * Flow components from the current step.\n */\n components: any[];\n\n /**\n * API error (if any).\n */\n error?: Error | null;\n\n /**\n * Current flow execution ID.\n */\n executionId?: string;\n\n /**\n * Field validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Current flow execution ID.\n */\n flowExecId?: string;\n\n /**\n * Function to handle input blur.\n */\n handleInputBlur: (name: string) => void;\n\n /**\n * Function to handle input changes.\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission.\n */\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state.\n */\n isLoading: boolean;\n\n /**\n * Whether the form is valid.\n */\n isValid: boolean;\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Reset the flow to invite another user.\n */\n resetFlow: () => void;\n\n /**\n * Subtitle for the current step.\n */\n subtitle?: string;\n\n /**\n * Title for the current step.\n */\n title?: string;\n\n /**\n * Touched fields.\n */\n touched: Record<string, boolean>;\n\n /**\n * Form values for the current step.\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseInviteUser component.\n */\nexport interface BaseInviteUserProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered.\n */\n children?: (props: BaseInviteUserRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Function to fetch child organization units.\n * When provided, enables the OU tree picker for OU_SELECT components.\n */\n fetchOrganizationUnitChildren?: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse>;\n\n /**\n * Function to load one page of authentication flows.\n * When provided, enables the flow picker for AUTH_FLOW_SELECT components.\n */\n fetchAuthFlows?: FetchAuthFlows;\n /**\n * Function to load one page of users.\n * When provided, enables the user picker for USER_SELECT components.\n */\n fetchUsers?: FetchUsers;\n /**\n * Function to load one page of user types.\n * When provided, enables the user type picker for USER_TYPE_SELECT components.\n */\n fetchUserTypes?: FetchUserTypes;\n\n /**\n * Whether the SDK is initialized.\n */\n isInitialized?: boolean;\n\n /**\n * Callback when an error occurs. It also receives the errors of failed user, flow and user type picker loads,\n * which the form itself does not show.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: InviteUserFlowResponse) => void;\n\n /**\n * Function to initialize the invite user flow.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onInitialize: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Function to submit flow step data.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onSubmit: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Base component for invite user flow.\n * Handles the flow logic for creating a user and generating an invite link.\n *\n * When no children are provided, renders a default UI with:\n * - Loading spinner during initialization\n * - Error alerts for failures\n * - Flow components (user type selection, user details form)\n * - Invite link display with copy functionality\n *\n * Flow steps handled:\n * 1. User type selection (if multiple types available)\n * 2. User details input (username, email)\n * 3. Invite link generation\n */\nconst BaseInviteUser: FC<BaseInviteUserProps> = ({\n onInitialize,\n onSubmit,\n onError,\n onFlowChange,\n className = '',\n children,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n isInitialized = true,\n preferences,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: BaseInviteUserProps): ReactElement => {\n const {meta, isInitialized: isSdkInitialized, getStorageManager} = useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n const [isLoading, setIsLoading] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<InviteUserFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n const [formValues, setFormValues] = useState<Record<string, string>>({});\n const [formErrors, setFormErrors] = useState<Record<string, string>>({});\n const [touchedFields, setTouchedFields] = useState<Record<string, boolean>>({});\n const [isFormValid, setIsFormValid] = useState(true);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n /**\n * Project server-side validation errors from the most recent flow response into the\n * local formErrors state so they render alongside client-side errors. First error\n * per field wins, matching the SDK's single-string-per-field render-prop shape.\n */\n useEffect(() => {\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setFormErrors(errors);\n setTouchedFields((prev: Record<string, boolean>) => ({...prev, ...touched}));\n }, [currentFlow]);\n\n const initializationAttemptedRef: any = useRef(false);\n\n /**\n * Restore any challenge token persisted before an OAuth redirect.\n */\n useEffect(() => {\n if (!isSdkInitialized) return;\n\n (async (): Promise<void> => {\n try {\n const storageManager: any = await getStorageManager();\n const tempData: any = await storageManager?.getTemporaryData();\n if (tempData?.challengeToken) {\n challengeTokenRef.current = tempData.challengeToken as string;\n }\n } catch {\n // StorageManager unavailable — continue without persisted token\n }\n })();\n }, [isSdkInitialized]);\n\n /**\n * Updates challengeTokenRef immediately (stale-closure safe) and persists via\n * the provider's StorageManager so the token survives OAuth redirects.\n */\n const setChallengeToken = async (challengeToken: string | null): Promise<void> => {\n challengeTokenRef.current = challengeToken;\n try {\n const storageManager: any = await getStorageManager();\n if (storageManager) {\n if (challengeToken) {\n await storageManager.setTemporaryDataParameter('challengeToken', challengeToken);\n } else {\n await storageManager.removeTemporaryDataParameter('challengeToken');\n }\n }\n } catch {\n logger.warn('Failed to persist challenge token in storage.');\n }\n };\n\n /**\n * Handle error responses and extract meaningful error messages.\n * Uses the transformer's extractErrorMessage function for consistency.\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t, 'components.inviteUser.errors.generic');\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Call the onError callback if provided\n onError?.(error instanceof Error ? error : new Error(errorMessage));\n },\n [t, onError],\n );\n\n /**\n * Normalize flow response to ensure component-driven format.\n * Transforms data.meta.components to data.components.\n */\n const normalizeFlowResponseLocal: any = useCallback(\n (response: InviteUserFlowResponse): InviteUserFlowResponse => {\n if (!response?.data?.meta?.components) {\n return response;\n }\n\n try {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {\n defaultErrorKey: 'components.inviteUser.errors.generic',\n resolveTranslations: false,\n },\n meta,\n );\n\n return {\n ...response,\n data: {\n ...response.data,\n components: components as any,\n },\n };\n } catch {\n // If transformer throws (e.g., error response), return as-is\n return response;\n }\n },\n [t, children],\n );\n\n /**\n * Handle input value changes.\n */\n const handleInputChange: any = useCallback((name: string, value: string) => {\n setFormValues((prev: any) => ({...prev, [name]: value}));\n // Clear error when user starts typing\n setFormErrors((prev: any) => {\n const newErrors: any = {...prev};\n delete newErrors[name];\n return newErrors;\n });\n }, []);\n\n /**\n * Handle input blur.\n */\n const handleInputBlur: any = useCallback((name: string) => {\n setTouchedFields((prev: any) => ({...prev, [name]: true}));\n }, []);\n\n /**\n * Validate required fields based on components.\n */\n const validateForm: any = useCallback(\n (components: any[]): {errors: Record<string, string>; isValid: boolean} => {\n const errors: Record<string, string> = {};\n\n const validateComponents = (comps: any[]): any => {\n comps.forEach((comp: any) => {\n if (\n (comp.type === 'TEXT_INPUT' ||\n comp.type === 'EMAIL_INPUT' ||\n comp.type === 'SELECT' ||\n comp.type === 'PHONE_INPUT' ||\n comp.type === 'OTP_INPUT' ||\n comp.type === 'DATE_INPUT' ||\n comp.type === 'USER_SELECT' ||\n comp.type === 'AUTH_FLOW_SELECT' ||\n comp.type === 'USER_TYPE_SELECT') &&\n comp.ref\n ) {\n const value: any = formValues[comp.ref];\n if (comp.required && (!value || value.trim() === '')) {\n errors[comp.ref] = `${comp.label || comp.ref} is required`;\n } else {\n // Email validation\n if (comp.type === 'EMAIL_INPUT' && value && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n errors[comp.ref] = 'Please enter a valid email address';\n }\n // Evaluate declarative validation rules from meta.components[].validation.\n if (value && !errors[comp.ref]) {\n const ruleValidator = buildValidatorFromRules(comp.validation);\n if (ruleValidator) {\n const message = ruleValidator(value);\n if (message) {\n errors[comp.ref] = t(message);\n }\n }\n }\n }\n }\n if (comp.components && Array.isArray(comp.components)) {\n validateComponents(comp.components);\n }\n });\n };\n\n validateComponents(components);\n\n return {errors, isValid: Object.keys(errors).length === 0};\n },\n [formValues],\n );\n\n /**\n * Handle form submission.\n */\n const handleSubmit: any = useCallback(\n async (component: any, data?: Record<string, any>) => {\n if (!currentFlow) {\n return;\n }\n\n // Validate form before submission\n const components: any = currentFlow.data?.components || [];\n const validation: any = validateForm(components);\n\n if (!validation.isValid) {\n setFormErrors(validation.errors);\n setIsFormValid(false);\n // Mark all fields as touched\n const touched: Record<string, boolean> = {};\n Object.keys(validation.errors).forEach((key: any) => {\n touched[key] = true;\n });\n setTouchedFields((prev: any) => ({...prev, ...touched}));\n return;\n }\n\n setIsLoading(true);\n setApiError(null);\n setIsFormValid(true);\n\n try {\n // Build payload with form values\n const inputs: any = data || formValues;\n\n const payload: Record<string, any> = {\n executionId: currentFlow.executionId,\n inputs,\n verbose: true,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n };\n\n // Add action ID if component has one\n if (component?.id) {\n payload['action'] = component.id;\n }\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Check for error status\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n return;\n }\n\n // Update current flow and reset form for next step\n setCurrentFlow(response);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [currentFlow, formValues, validateForm, onSubmit, onFlowChange, handleError, normalizeFlowResponseLocal],\n );\n\n /**\n * Reset the flow to invite another user.\n */\n const resetFlow: any = useCallback(() => {\n setIsFlowInitialized(false);\n setCurrentFlow(null);\n setApiError(null);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n initializationAttemptedRef.current = false;\n }, []);\n\n /**\n * reset form values, errors, and touched fields to initial state\n */\n const resetForm = useCallback(() => {\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n setApiError(null);\n setIsFormValid(true);\n }, []);\n\n /**\n * Initialize the flow on component mount.\n */\n useEffect(() => {\n if (isInitialized && !isFlowInitialized && !initializationAttemptedRef.current) {\n initializationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsLoading(true);\n setApiError(null);\n\n try {\n const payload: any = {\n flowType: EmbeddedFlowType.UserOnboarding,\n verbose: true,\n };\n\n const rawResponse: any = await onInitialize(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n await setChallengeToken(response.challengeToken ?? null);\n setCurrentFlow(response);\n setIsFlowInitialized(true);\n onFlowChange?.(response);\n\n // Check for immediate error\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n })();\n }\n }, [isInitialized, isFlowInitialized, onInitialize, onFlowChange, handleError, normalizeFlowResponseLocal]);\n\n /**\n * Recalculate form validity whenever form values or components change.\n * This ensures the submit button is enabled/disabled correctly as the user types.\n */\n useEffect(() => {\n if (currentFlow && isFlowInitialized) {\n const components: any = currentFlow.data?.components || [];\n if (components.length > 0) {\n const validation: any = validateForm(components);\n setIsFormValid(validation.isValid);\n }\n }\n }, [formValues, currentFlow, isFlowInitialized, validateForm]);\n\n /**\n * Extract title and subtitle from components.\n */\n const extractHeadings: any = useCallback(\n (components: any[]): {subtitle?: string; title?: string} => {\n // The flow writes its texts as translation templates, so resolve them here as the field labels are.\n const resolve = (text: string): string => resolveFlowTemplateLiterals(text, {meta, t});\n let title: string | undefined;\n let subtitle: string | undefined;\n\n components.forEach((comp: any) => {\n if (comp.type === 'TEXT') {\n if (comp.variant === 'HEADING_1' && !title) {\n title = comp.label && resolve(comp.label);\n } else if ((comp.variant === 'HEADING_2' || comp.variant === 'SUBTITLE_1') && !subtitle) {\n subtitle = comp.label && resolve(comp.label);\n }\n }\n });\n\n return {subtitle, title};\n },\n [meta, t],\n );\n\n /**\n * Filter out heading components for default rendering.\n */\n const filterHeadings: any = useCallback(\n (components: any[]): any[] =>\n components.filter(\n (comp: any) => !(comp.type === 'TEXT' && (comp.variant === 'HEADING_1' || comp.variant === 'HEADING_2')),\n ),\n [],\n );\n\n /**\n * Render form components using the factory.\n */\n const renderComponents: any = useCallback(\n (components: any[]): ReactElement[] =>\n renderInviteUserComponents(\n components,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData: currentFlow?.data?.additionalData,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n meta,\n onInputBlur: handleInputBlur,\n onPickerError: onError,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n },\n ),\n [\n customRenderers,\n currentFlow?.data?.additionalData,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n meta,\n onError,\n t,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n handleInputChange,\n handleInputBlur,\n handleSubmit,\n size,\n theme,\n variant,\n ],\n );\n\n // Get components from normalized response, with fallback to meta.components\n const components: any = currentFlow?.data?.components || currentFlow?.data?.meta?.components || [];\n const {title, subtitle} = extractHeadings(components);\n const componentsWithoutHeadings: any = filterHeadings(components);\n\n // Render props\n const renderProps: BaseInviteUserRenderProps = {\n additionalData: currentFlow?.data?.additionalData,\n components,\n error: apiError,\n executionId: currentFlow?.executionId,\n fieldErrors: formErrors,\n handleInputBlur,\n handleInputChange,\n handleSubmit,\n isLoading,\n isValid: isFormValid,\n meta,\n resetFlow,\n subtitle,\n title,\n touched: touchedFields,\n values: formValues,\n };\n\n // If children render prop is provided, use it for custom UI\n if (children) {\n return <div className={className}>{children(renderProps)}</div>;\n }\n\n // Default rendering\n\n // Waiting for SDK initialization\n if (!isInitialized) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Loading state during initialization\n if (!isFlowInitialized && isLoading) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Error state during initialization\n if (!currentFlow && apiError) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Title>Error</AlertPrimitive.Title>\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Flow components\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (title || subtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && title && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && subtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {apiError && (\n <div className={(styles as Record<string, string>)['errorContainer']}>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n <div>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0\n ? renderComponents(componentsWithoutHeadings)\n : !isLoading && (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">No form components available</Typography>\n </AlertPrimitive>\n )}\n {isLoading && (\n <div className={(styles as Record<string, string>)['centeredSpinnerContainerSmall']}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\nexport default BaseInviteUser;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BaseInviteUser.js","names":["BaseInviteUser: FC<BaseInviteUserProps>","useThunderID","useTranslation","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","styles: any","useStyles","useStepExpiry","challengeTokenRef: any","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","initializationAttemptedRef: any","tempData: any","storageManager: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","components","handleInputChange: any","newErrors: any","handleInputBlur: any","validateForm: any","value: any","handleSubmit: any","validation: any","inputs: any","payload: Record<string, any>","response: any","resetFlow: any","components: any","extractHeadings: any","title: string | undefined","subtitle: string | undefined","title","subtitle","filterHeadings: any","renderComponents: any","componentsWithoutHeadings: any","renderProps: BaseInviteUserRenderProps","CardPrimitive","Spinner","AlertPrimitive","Typography"],"sources":["../../../../src/components/auth/InviteUser/BaseInviteUser.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedFlowType,\n FieldError,\n FlowExecutionError,\n FlowMetadataResponse,\n buildValidatorFromRules,\n FetchAuthFlows,\n FetchUsers,\n FetchUserTypes,\n logger,\n OrganizationUnitListResponse,\n Preferences,\n resolveFlowTemplateLiterals,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react';\nimport useStyles from './BaseInviteUser.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport useStepExpiry from '../../../hooks/auth/useStepExpiry';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../utils/flowTransformer';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderInviteUserComponents} from '../flow/AuthOptionFactory';\n\n/**\n * Flow response structure from the backend.\n */\nexport interface InviteUserFlowResponse {\n challengeToken?: string;\n data?: {\n additionalData?: Record<string, any>;\n components?: any[];\n fieldErrors?: FieldError[];\n meta?: {\n components?: any[];\n };\n };\n error?: FlowExecutionError;\n executionId: string;\n flowStatus: 'INCOMPLETE' | 'COMPLETE' | 'ERROR';\n type?: 'VIEW' | 'REDIRECTION';\n}\n\n/**\n * Render props for custom UI rendering of InviteUser.\n */\nexport interface BaseInviteUserRenderProps {\n /**\n * Additional data from the current flow response (e.g. rootOuId, inviteLink).\n */\n additionalData?: Record<string, any>;\n\n /**\n * Flow components from the current step.\n */\n components: any[];\n\n /**\n * API error (if any).\n */\n error?: Error | null;\n\n /**\n * Current flow execution ID.\n */\n executionId?: string;\n\n /**\n * Field validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Current flow execution ID.\n */\n flowExecId?: string;\n\n /**\n * Function to handle input blur.\n */\n handleInputBlur: (name: string) => void;\n\n /**\n * Function to handle input changes.\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission.\n */\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state.\n */\n isLoading: boolean;\n\n /**\n * Whether the form is valid.\n */\n isValid: boolean;\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Reset the flow to invite another user.\n */\n resetFlow: () => void;\n\n /**\n * Subtitle for the current step.\n */\n subtitle?: string;\n\n /**\n * Title for the current step.\n */\n title?: string;\n\n /**\n * Touched fields.\n */\n touched: Record<string, boolean>;\n\n /**\n * Form values for the current step.\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseInviteUser component.\n */\nexport interface BaseInviteUserProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered.\n */\n children?: (props: BaseInviteUserRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Function to fetch child organization units.\n * When provided, enables the OU tree picker for OU_SELECT components.\n */\n fetchOrganizationUnitChildren?: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse>;\n\n /**\n * Function to load one page of authentication flows.\n * When provided, enables the flow picker for AUTH_FLOW_SELECT components.\n */\n fetchAuthFlows?: FetchAuthFlows;\n /**\n * Function to load one page of users.\n * When provided, enables the user picker for USER_SELECT components.\n */\n fetchUsers?: FetchUsers;\n /**\n * Function to load one page of user types.\n * When provided, enables the user type picker for USER_TYPE_SELECT components.\n */\n fetchUserTypes?: FetchUserTypes;\n\n /**\n * Whether the SDK is initialized.\n */\n isInitialized?: boolean;\n\n /**\n * Callback when an error occurs. It also receives the errors of failed user, flow and user type picker loads,\n * which the form itself does not show.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: InviteUserFlowResponse) => void;\n\n /**\n * Function to initialize the invite user flow.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onInitialize: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Function to submit flow step data.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onSubmit: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Base component for invite user flow.\n * Handles the flow logic for creating a user and generating an invite link.\n *\n * When no children are provided, renders a default UI with:\n * - Loading spinner during initialization\n * - Error alerts for failures\n * - Flow components (user type selection, user details form)\n * - Invite link display with copy functionality\n *\n * Flow steps handled:\n * 1. User type selection (if multiple types available)\n * 2. User details input (username, email)\n * 3. Invite link generation\n */\nconst BaseInviteUser: FC<BaseInviteUserProps> = ({\n onInitialize,\n onSubmit,\n onError,\n onFlowChange,\n className = '',\n children,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n isInitialized = true,\n preferences,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: BaseInviteUserProps): ReactElement => {\n const {meta, isInitialized: isSdkInitialized, getStorageManager} = useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n const [isLoading, setIsLoading] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<InviteUserFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n const [formValues, setFormValues] = useState<Record<string, string>>({});\n const [formErrors, setFormErrors] = useState<Record<string, string>>({});\n const [touchedFields, setTouchedFields] = useState<Record<string, boolean>>({});\n const [isFormValid, setIsFormValid] = useState(true);\n // A custom renderer can expire the step from the client; it holds until the next step response.\n const {expireStep, isStepExpired} = useStepExpiry(currentFlow);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n /**\n * Project server-side validation errors from the most recent flow response into the\n * local formErrors state so they render alongside client-side errors. First error\n * per field wins, matching the SDK's single-string-per-field render-prop shape.\n */\n useEffect(() => {\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setFormErrors(errors);\n setTouchedFields((prev: Record<string, boolean>) => ({...prev, ...touched}));\n }, [currentFlow]);\n\n const initializationAttemptedRef: any = useRef(false);\n\n /**\n * Restore any challenge token persisted before an OAuth redirect.\n */\n useEffect(() => {\n if (!isSdkInitialized) return;\n\n (async (): Promise<void> => {\n try {\n const storageManager: any = await getStorageManager();\n const tempData: any = await storageManager?.getTemporaryData();\n if (tempData?.challengeToken) {\n challengeTokenRef.current = tempData.challengeToken as string;\n }\n } catch {\n // StorageManager unavailable — continue without persisted token\n }\n })();\n }, [isSdkInitialized]);\n\n /**\n * Updates challengeTokenRef immediately (stale-closure safe) and persists via\n * the provider's StorageManager so the token survives OAuth redirects.\n */\n const setChallengeToken = async (challengeToken: string | null): Promise<void> => {\n challengeTokenRef.current = challengeToken;\n try {\n const storageManager: any = await getStorageManager();\n if (storageManager) {\n if (challengeToken) {\n await storageManager.setTemporaryDataParameter('challengeToken', challengeToken);\n } else {\n await storageManager.removeTemporaryDataParameter('challengeToken');\n }\n }\n } catch {\n logger.warn('Failed to persist challenge token in storage.');\n }\n };\n\n /**\n * Handle error responses and extract meaningful error messages.\n * Uses the transformer's extractErrorMessage function for consistency.\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t, 'components.inviteUser.errors.generic');\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Call the onError callback if provided\n onError?.(error instanceof Error ? error : new Error(errorMessage));\n },\n [t, onError],\n );\n\n /**\n * Normalize flow response to ensure component-driven format.\n * Transforms data.meta.components to data.components.\n */\n const normalizeFlowResponseLocal: any = useCallback(\n (response: InviteUserFlowResponse): InviteUserFlowResponse => {\n if (!response?.data?.meta?.components) {\n return response;\n }\n\n try {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {\n defaultErrorKey: 'components.inviteUser.errors.generic',\n resolveTranslations: false,\n },\n meta,\n );\n\n return {\n ...response,\n data: {\n ...response.data,\n components: components as any,\n },\n };\n } catch {\n // If transformer throws (e.g., error response), return as-is\n return response;\n }\n },\n [t, children],\n );\n\n /**\n * Handle input value changes.\n */\n const handleInputChange: any = useCallback((name: string, value: string) => {\n setFormValues((prev: any) => ({...prev, [name]: value}));\n // Clear error when user starts typing\n setFormErrors((prev: any) => {\n const newErrors: any = {...prev};\n delete newErrors[name];\n return newErrors;\n });\n }, []);\n\n /**\n * Handle input blur.\n */\n const handleInputBlur: any = useCallback((name: string) => {\n setTouchedFields((prev: any) => ({...prev, [name]: true}));\n }, []);\n\n /**\n * Validate required fields based on components.\n */\n const validateForm: any = useCallback(\n (components: any[]): {errors: Record<string, string>; isValid: boolean} => {\n const errors: Record<string, string> = {};\n\n const validateComponents = (comps: any[]): any => {\n comps.forEach((comp: any) => {\n if (\n (comp.type === 'TEXT_INPUT' ||\n comp.type === 'EMAIL_INPUT' ||\n comp.type === 'SELECT' ||\n comp.type === 'PHONE_INPUT' ||\n comp.type === 'OTP_INPUT' ||\n comp.type === 'DATE_INPUT' ||\n comp.type === 'USER_SELECT' ||\n comp.type === 'AUTH_FLOW_SELECT' ||\n comp.type === 'USER_TYPE_SELECT') &&\n comp.ref\n ) {\n const value: any = formValues[comp.ref];\n if (comp.required && (!value || value.trim() === '')) {\n errors[comp.ref] = `${comp.label || comp.ref} is required`;\n } else {\n // Email validation\n if (comp.type === 'EMAIL_INPUT' && value && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n errors[comp.ref] = 'Please enter a valid email address';\n }\n // Evaluate declarative validation rules from meta.components[].validation.\n if (value && !errors[comp.ref]) {\n const ruleValidator = buildValidatorFromRules(comp.validation);\n if (ruleValidator) {\n const message = ruleValidator(value);\n if (message) {\n errors[comp.ref] = t(message);\n }\n }\n }\n }\n }\n if (comp.components && Array.isArray(comp.components)) {\n validateComponents(comp.components);\n }\n });\n };\n\n validateComponents(components);\n\n return {errors, isValid: Object.keys(errors).length === 0};\n },\n [formValues],\n );\n\n /**\n * Handle form submission.\n */\n const handleSubmit: any = useCallback(\n async (component: any, data?: Record<string, any>) => {\n if (!currentFlow) {\n return;\n }\n\n // Validate form before submission\n const components: any = currentFlow.data?.components || [];\n const validation: any = validateForm(components);\n\n if (!validation.isValid) {\n setFormErrors(validation.errors);\n setIsFormValid(false);\n // Mark all fields as touched\n const touched: Record<string, boolean> = {};\n Object.keys(validation.errors).forEach((key: any) => {\n touched[key] = true;\n });\n setTouchedFields((prev: any) => ({...prev, ...touched}));\n return;\n }\n\n setIsLoading(true);\n setApiError(null);\n setIsFormValid(true);\n\n try {\n // Build payload with form values\n const inputs: any = data || formValues;\n\n const payload: Record<string, any> = {\n executionId: currentFlow.executionId,\n inputs,\n verbose: true,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n };\n\n // Add action ID if component has one\n if (component?.id) {\n payload['action'] = component.id;\n }\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Check for error status\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n return;\n }\n\n // Update current flow and reset form for next step\n setCurrentFlow(response);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [currentFlow, formValues, validateForm, onSubmit, onFlowChange, handleError, normalizeFlowResponseLocal],\n );\n\n /**\n * Reset the flow to invite another user.\n */\n const resetFlow: any = useCallback(() => {\n setIsFlowInitialized(false);\n setCurrentFlow(null);\n setApiError(null);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n initializationAttemptedRef.current = false;\n }, []);\n\n /**\n * reset form values, errors, and touched fields to initial state\n */\n const resetForm = useCallback(() => {\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n setApiError(null);\n setIsFormValid(true);\n }, []);\n\n /**\n * Initialize the flow on component mount.\n */\n useEffect(() => {\n if (isInitialized && !isFlowInitialized && !initializationAttemptedRef.current) {\n initializationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsLoading(true);\n setApiError(null);\n\n try {\n const payload: any = {\n flowType: EmbeddedFlowType.UserOnboarding,\n verbose: true,\n };\n\n const rawResponse: any = await onInitialize(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n await setChallengeToken(response.challengeToken ?? null);\n setCurrentFlow(response);\n setIsFlowInitialized(true);\n onFlowChange?.(response);\n\n // Check for immediate error\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n })();\n }\n }, [isInitialized, isFlowInitialized, onInitialize, onFlowChange, handleError, normalizeFlowResponseLocal]);\n\n /**\n * Recalculate form validity whenever form values or components change.\n * This ensures the submit button is enabled/disabled correctly as the user types.\n */\n useEffect(() => {\n if (currentFlow && isFlowInitialized) {\n const components: any = currentFlow.data?.components || [];\n if (components.length > 0) {\n const validation: any = validateForm(components);\n setIsFormValid(validation.isValid);\n }\n }\n }, [formValues, currentFlow, isFlowInitialized, validateForm]);\n\n /**\n * Extract title and subtitle from components.\n */\n const extractHeadings: any = useCallback(\n (components: any[]): {subtitle?: string; title?: string} => {\n // The flow writes its texts as translation templates, so resolve them here as the field labels are.\n const resolve = (text: string): string => resolveFlowTemplateLiterals(text, {meta, t});\n let title: string | undefined;\n let subtitle: string | undefined;\n\n components.forEach((comp: any) => {\n if (comp.type === 'TEXT') {\n if (comp.variant === 'HEADING_1' && !title) {\n title = comp.label && resolve(comp.label);\n } else if ((comp.variant === 'HEADING_2' || comp.variant === 'SUBTITLE_1') && !subtitle) {\n subtitle = comp.label && resolve(comp.label);\n }\n }\n });\n\n return {subtitle, title};\n },\n [meta, t],\n );\n\n /**\n * Filter out heading components for default rendering.\n */\n const filterHeadings: any = useCallback(\n (components: any[]): any[] =>\n components.filter(\n (comp: any) => !(comp.type === 'TEXT' && (comp.variant === 'HEADING_1' || comp.variant === 'HEADING_2')),\n ),\n [],\n );\n\n /**\n * Render form components using the factory.\n */\n const renderComponents: any = useCallback(\n (components: any[]): ReactElement[] =>\n renderInviteUserComponents(\n components,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData: currentFlow?.data?.additionalData,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n isFormComplete: validateForm(components).isValid,\n isTimeoutDisabled: isStepExpired,\n meta,\n onInputBlur: handleInputBlur,\n onPickerError: onError,\n onStepExpire: expireStep,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n },\n ),\n [\n customRenderers,\n currentFlow?.data?.additionalData,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n meta,\n onError,\n t,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n validateForm,\n isStepExpired,\n expireStep,\n handleInputChange,\n handleInputBlur,\n handleSubmit,\n size,\n theme,\n variant,\n ],\n );\n\n // Get components from normalized response, with fallback to meta.components\n const components: any = currentFlow?.data?.components || currentFlow?.data?.meta?.components || [];\n const {title, subtitle} = extractHeadings(components);\n const componentsWithoutHeadings: any = filterHeadings(components);\n\n // Render props\n const renderProps: BaseInviteUserRenderProps = {\n additionalData: currentFlow?.data?.additionalData,\n components,\n error: apiError,\n executionId: currentFlow?.executionId,\n fieldErrors: formErrors,\n handleInputBlur,\n handleInputChange,\n handleSubmit,\n isLoading,\n isValid: isFormValid,\n meta,\n resetFlow,\n subtitle,\n title,\n touched: touchedFields,\n values: formValues,\n };\n\n // If children render prop is provided, use it for custom UI\n if (children) {\n return <div className={className}>{children(renderProps)}</div>;\n }\n\n // Default rendering\n\n // Waiting for SDK initialization\n if (!isInitialized) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Loading state during initialization\n if (!isFlowInitialized && isLoading) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Error state during initialization\n if (!currentFlow && apiError) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Title>Error</AlertPrimitive.Title>\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Flow components\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (title || subtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && title && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && subtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {apiError && (\n <div className={(styles as Record<string, string>)['errorContainer']}>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n <div>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0\n ? renderComponents(componentsWithoutHeadings)\n : !isLoading && (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">No form components available</Typography>\n </AlertPrimitive>\n )}\n {isLoading && (\n <div className={(styles as Record<string, string>)['centeredSpinnerContainerSmall']}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\nexport default BaseInviteUser;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BaseRecovery.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/Recovery/BaseRecovery.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseRecovery.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/Recovery/BaseRecovery.tsx"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import { useForm } from "../../../hooks/useForm.js";
11
11
  import Spinner_default from "../../primitives/Spinner/Spinner.js";
12
12
  import Typography_default from "../../primitives/Typography/Typography.js";
13
13
  import Card_default from "../../primitives/Card/Card.js";
14
+ import useStepExpiry_default from "../../../hooks/auth/useStepExpiry.js";
14
15
  import composeAffixedInputs_default from "../../../utils/composeAffixedInputs.js";
15
16
  import Alert_default from "../../primitives/Alert/Alert.js";
16
17
  import { renderRecoveryComponents } from "../flow/AuthOptionFactory.js";
@@ -98,7 +99,7 @@ const BaseRecoveryContent = ({ onInitialize, onSubmit, onError, onFlowChange, on
98
99
  processComponents(components);
99
100
  return fields;
100
101
  }, [t]);
101
- const { values: formValues, touched: touchedFields, errors: formErrors, isValid: isFormValid, setValue: setFormValue, setTouched: setFormTouched, setTouchedFields, setErrors: setFormErrors, clearErrors: clearFormErrors, validateForm, touchAllFields, reset: resetForm } = useForm({
102
+ const { values: formValues, touched: touchedFields, errors: formErrors, isComplete: isFormComplete, isValid: isFormValid, setValue: setFormValue, setTouched: setFormTouched, setTouchedFields, setErrors: setFormErrors, clearErrors: clearFormErrors, validateForm, touchAllFields, reset: resetForm } = useForm({
102
103
  fields: useMemo(() => currentFlow?.data?.components ? extractFormFields(currentFlow.data.components) : [], [currentFlow, extractFormFields]),
103
104
  initialValues: {},
104
105
  requiredMessage: t("validations.required.field.error"),
@@ -106,6 +107,7 @@ const BaseRecoveryContent = ({ onInitialize, onSubmit, onError, onFlowChange, on
106
107
  validateOnBlur: true,
107
108
  validateOnChange: false
108
109
  });
110
+ const { expireStep, isStepExpired } = useStepExpiry_default(currentFlow);
109
111
  useEffect(() => {
110
112
  clearFormErrors();
111
113
  const responseFieldErrors = (currentFlow?.data)?.fieldErrors;
@@ -212,8 +214,11 @@ const BaseRecoveryContent = ({ onInitialize, onSubmit, onError, onFlowChange, on
212
214
  _theme: theme,
213
215
  buttonClassName: buttonClasses,
214
216
  inputClassName: inputClasses,
217
+ isFormComplete,
218
+ isTimeoutDisabled: isStepExpired,
215
219
  meta,
216
220
  onInputBlur: handleInputBlur,
221
+ onStepExpire: expireStep,
217
222
  onSubmit: handleSubmit,
218
223
  size,
219
224
  variant,
@@ -227,6 +232,9 @@ const BaseRecoveryContent = ({ onInitialize, onSubmit, onError, onFlowChange, on
227
232
  handleSubmit,
228
233
  inputClasses,
229
234
  isFormValid,
235
+ isFormComplete,
236
+ isStepExpired,
237
+ expireStep,
230
238
  meta,
231
239
  isLoading,
232
240
  size,
@@ -1 +1 @@
1
- {"version":3,"file":"BaseRecovery.js","names":["BaseRecoveryContent: FC<BaseRecoveryProps>","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","useThunderID","styles: any","useStyles","initializationAttemptedRef: any","challengeTokenRef: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","extractFormFields: any","fields: FormField[]","fieldName: any","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","setupFormFields: any","fields: any","initialValues: Record<string, string>","composedData: Record<string, any> | undefined","composeAffixedInputs","filteredInputs: Record<string, any>","payload: EmbeddedRecoveryFlowRequest","rawResponse: any","response: any","containerClasses: any","inputClasses: any","buttonClasses: any","errorClasses: any","messageClasses: any","renderComponents: any","result: ReturnType<typeof validateForm>","CardPrimitive","Spinner","AlertPrimitive","getAuthComponentHeadings","Typography","BaseRecovery: FC<BaseRecoveryProps>","content: ReactElement","Logo","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../src/components/auth/Recovery/BaseRecovery.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n EmbeddedRecoveryFlowStatus,\n EmbeddedFlowComponentType,\n FieldError,\n withVendorCSSClassPrefix,\n buildValidatorFromRules,\n Preferences,\n FlowMetadataResponse,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useContext, useEffect, useMemo, useState, useCallback, useRef} from 'react';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport FlowProvider from '../../../contexts/Flow/FlowProvider';\nimport useFlow from '../../../contexts/Flow/useFlow';\nimport ComponentPreferencesContext from '../../../contexts/I18n/ComponentPreferencesContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport {useForm, FormField} from '../../../hooks/useForm';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport composeAffixedInputs from '../../../utils/composeAffixedInputs';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../utils/flowTransformer';\nimport getAuthComponentHeadings from '../../../utils/getAuthComponentHeadings';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Logo from '../../primitives/Logo/Logo';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderRecoveryComponents} from '../flow/AuthOptionFactory';\nimport useStyles from '../SignUp/BaseSignUp.styles';\n\n/**\n * Render props for custom UI rendering.\n */\nexport interface BaseRecoveryRenderProps {\n components: any[];\n error?: Error | null;\n fieldErrors: Record<string, string>;\n handleInputChange: (name: string, value: string) => void;\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n isLoading: boolean;\n isValid: boolean;\n messages: {message: string; type: string}[];\n meta: FlowMetadataResponse | null;\n subtitle: string;\n title: string;\n touched: Record<string, boolean>;\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseRecovery component.\n */\nexport interface BaseRecoveryProps {\n afterRecoveryUrl?: string;\n buttonClassName?: string;\n /**\n * Render props function for custom UI or static content\n */\n children?: ((props: BaseRecoveryRenderProps) => ReactNode) | ReactNode;\n className?: string;\n error?: Error | null;\n errorClassName?: string;\n inputClassName?: string;\n isInitialized?: boolean;\n messageClassName?: string;\n onComplete?: (response: EmbeddedRecoveryFlowResponse) => void;\n onError?: (error: Error) => void;\n onFlowChange?: (response: EmbeddedRecoveryFlowResponse) => void;\n onInitialize?: (payload?: EmbeddedRecoveryFlowRequest) => Promise<EmbeddedRecoveryFlowResponse>;\n onSubmit?: (payload: EmbeddedRecoveryFlowRequest) => Promise<EmbeddedRecoveryFlowResponse>;\n /**\n * Component-level preferences to override global i18n and theme settings.\n */\n preferences?: Preferences;\n /**\n * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n showLogo?: boolean;\n showSubtitle?: boolean;\n showTitle?: boolean;\n size?: 'small' | 'medium' | 'large';\n variant?: CardProps['variant'];\n}\n\n/**\n * Internal component that renders the V2 recovery UI and manages flow state.\n *\n * @internal\n */\nconst BaseRecoveryContent: FC<BaseRecoveryProps> = ({\n onInitialize,\n onSubmit,\n onError,\n onFlowChange,\n onComplete,\n error: externalError,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n errorClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isInitialized,\n children,\n showTitle = true,\n showSubtitle = true,\n revalidateOnChangeAfterBlur = false,\n}: BaseRecoveryProps): ReactElement => {\n const {theme, colorScheme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const {meta, vendor} = useThunderID();\n const styles: any = useStyles(theme, colorScheme);\n\n const [isLoading, setIsLoading] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<EmbeddedRecoveryFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const initializationAttemptedRef: any = useRef(false);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t);\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n clearMessages();\n addMessage({message: errorMessage, type: 'error'});\n },\n [t, addMessage, clearMessages],\n );\n\n const normalizeFlowResponseLocal: any = useCallback(\n (response: EmbeddedRecoveryFlowResponse): EmbeddedRecoveryFlowResponse => {\n if (response?.data?.components && Array.isArray(response.data.components)) {\n return response;\n }\n\n if (response?.data) {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {defaultErrorKey: 'components.recovery.errors.generic', resolveTranslations: false},\n meta,\n );\n\n return {...response, data: {...response.data, components: components as any}};\n }\n\n return response;\n },\n [t, meta],\n );\n\n const extractFormFields: any = useCallback(\n (components: any[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: any[]): any => {\n comps.forEach((component: any) => {\n if (\n component.type === EmbeddedFlowComponentType.TextInput ||\n component.type === EmbeddedFlowComponentType.PasswordInput ||\n component.type === EmbeddedFlowComponentType.EmailInput ||\n component.type === EmbeddedFlowComponentType.Select ||\n component.type === EmbeddedFlowComponentType.DateInput\n ) {\n const fieldName: any = component.ref || component.id;\n const ruleValidator = buildValidatorFromRules(component.validation);\n fields.push({\n initialValue: '',\n name: fieldName,\n required: component.required || false,\n validator: (value: string) => {\n if (component.required && (!value || value.trim() === '')) {\n return t('validations.required.field.error');\n }\n // Evaluate declarative validation rules from meta.components[].validation.\n if (ruleValidator && value) {\n const ruleMessage = ruleValidator(value);\n if (ruleMessage) {\n return t(ruleMessage);\n }\n }\n // Add email validation if it's an email field\n if (\n (component.type === EmbeddedFlowComponentType.EmailInput || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n return null;\n },\n });\n }\n\n if (component.components && Array.isArray(component.components)) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(components);\n return fields;\n },\n [t],\n );\n\n const formFields: any = useMemo(\n () => (currentFlow?.data?.components ? extractFormFields(currentFlow.data.components) : []),\n [currentFlow, extractFormFields],\n );\n\n const form: any = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\n revalidateOnChangeAfterBlur,\n validateOnBlur: true,\n validateOnChange: false,\n });\n\n const {\n values: formValues,\n touched: touchedFields,\n errors: formErrors,\n isValid: isFormValid,\n setValue: setFormValue,\n setTouched: setFormTouched,\n setTouchedFields,\n setErrors: setFormErrors,\n clearErrors: clearFormErrors,\n validateForm,\n touchAllFields,\n reset: resetForm,\n } = form;\n\n // Project server-side fieldErrors from the flow response into form state.\n // `setTouchedFields` avoids re-running client-side validation that would wipe\n // server errors when the client rules happen to pass.\n useEffect(() => {\n clearFormErrors();\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setTouchedFields(touched);\n setFormErrors(errors);\n }, [currentFlow, setFormErrors, setTouchedFields, clearFormErrors]);\n\n const setupFormFields: any = useCallback(\n (flowResponse: EmbeddedRecoveryFlowResponse) => {\n const fields: any = extractFormFields(flowResponse.data?.components || []);\n const initialValues: Record<string, string> = {};\n fields.forEach((field: any) => {\n initialValues[field.name] = field.initialValue || '';\n });\n resetForm();\n Object.keys(initialValues).forEach((key: any) => setFormValue(key, initialValues[key]));\n },\n [extractFormFields, resetForm, setFormValue],\n );\n\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n const handleSubmit = async (component: any, data?: Record<string, any>, skipValidation?: boolean): Promise<void> => {\n if (!currentFlow) return;\n\n if (!skipValidation) {\n touchAllFields();\n const validation: ReturnType<typeof validateForm> = validateForm();\n if (!validation.isValid) return;\n }\n\n setIsLoading(true);\n setApiError(null);\n clearMessages();\n\n try {\n const composedData: Record<string, any> | undefined = data\n ? composeAffixedInputs(data as Record<string, string>, vendor)\n : undefined;\n\n const filteredInputs: Record<string, any> = {};\n if (composedData) {\n Object.entries(composedData).forEach(([key, value]: [string, any]) => {\n if (value !== null && value !== undefined && value !== '') {\n filteredInputs[key] = value;\n }\n });\n }\n\n const payload: EmbeddedRecoveryFlowRequest = {\n ...(currentFlow.executionId && {executionId: currentFlow.executionId}),\n ...(component.id && {action: component.id}),\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n inputs: filteredInputs,\n };\n\n const rawResponse: any = await onSubmit?.(payload);\n if (!rawResponse) return;\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n if (response.challengeToken !== undefined) {\n challengeTokenRef.current = response.challengeToken ?? null;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Error) {\n handleError(response);\n onError?.(new Error(extractErrorMessage(response, t)));\n return;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Complete) {\n onComplete?.(response);\n return;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Incomplete) {\n setCurrentFlow(response);\n setupFormFields(response);\n\n // Display error from INCOMPLETE response\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (response?.error) {\n handleError(response);\n }\n }\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('recovery'),\n withVendorCSSClassPrefix(`recovery--${size}`),\n withVendorCSSClassPrefix(`recovery--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('recovery__input'),\n size === 'small' && withVendorCSSClassPrefix('recovery__input--small'),\n size === 'large' && withVendorCSSClassPrefix('recovery__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('recovery__button'),\n size === 'small' && withVendorCSSClassPrefix('recovery__button--small'),\n size === 'large' && withVendorCSSClassPrefix('recovery__button--large'),\n ],\n buttonClassName,\n );\n\n const errorClasses: any = cx([withVendorCSSClassPrefix('recovery__error')], errorClassName);\n const messageClasses: any = cx([withVendorCSSClassPrefix('recovery__messages')], messageClassName);\n\n const renderComponents: any = useCallback(\n (components: any[]): ReactElement[] =>\n renderRecoveryComponents(\n components,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n meta,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n variant,\n vendor,\n },\n ),\n [\n customRenderers,\n buttonClasses,\n formErrors,\n formValues,\n handleInputBlur,\n handleSubmit,\n inputClasses,\n isFormValid,\n meta,\n isLoading,\n size,\n theme,\n touchedFields,\n variant,\n vendor,\n ],\n );\n\n useEffect(() => {\n if (isInitialized && !isFlowInitialized && !initializationAttemptedRef.current) {\n initializationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsLoading(true);\n setApiError(null);\n clearMessages();\n\n try {\n const rawResponse: any = await onInitialize?.();\n if (!rawResponse) return;\n const response: any = normalizeFlowResponseLocal(rawResponse);\n\n if (response.challengeToken !== undefined) {\n challengeTokenRef.current = response.challengeToken ?? null;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Error) {\n handleError(response);\n onError?.(new Error(extractErrorMessage(response, t)));\n }\n\n setCurrentFlow(response);\n setIsFlowInitialized(true);\n onFlowChange?.(response);\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Complete) {\n onComplete?.(response);\n return;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Incomplete) {\n setupFormFields(response);\n\n // Display error from INCOMPLETE response\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (response?.error) {\n handleError(response);\n }\n }\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsLoading(false);\n }\n })();\n }\n }, [\n isFlowInitialized,\n isInitialized,\n normalizeFlowResponseLocal,\n onComplete,\n onError,\n onFlowChange,\n onInitialize,\n setupFormFields,\n t,\n ]);\n\n if (children) {\n if (typeof children === 'function') {\n const renderProps: BaseRecoveryRenderProps = {\n components: currentFlow?.data?.components || [],\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle || t('recovery.subheading'),\n title: flowTitle || t('recovery.heading'),\n touched: touchedFields,\n validateForm: (): {fieldErrors: Record<string, string>; isValid: boolean} => {\n const result: ReturnType<typeof validateForm> = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return <div className={containerClasses}>{(children as any)(renderProps)}</div>;\n }\n\n return <div className={containerClasses}>{children}</div>;\n }\n\n if (!isFlowInitialized && isLoading) {\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={styles.loadingContainer}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!currentFlow) {\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\" className={errorClasses}>\n <AlertPrimitive.Title>{t('errors.heading')}</AlertPrimitive.Title>\n <AlertPrimitive.Description>{t('errors.recovery.flow.initialization.failure')}</AlertPrimitive.Description>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n const componentsToRender: any = currentFlow.data?.components || [];\n const {title, subtitle, componentsWithoutHeadings} = getAuthComponentHeadings(\n componentsToRender,\n flowTitle,\n flowSubtitle,\n t('recovery.heading'),\n t('recovery.subheading'),\n );\n\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {externalError && (\n <div className={styles.flowMessagesContainer}>\n <AlertPrimitive variant=\"error\" className={cx(styles.flowMessageItem, messageClasses)}>\n <AlertPrimitive.Description>{externalError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n {flowMessages && flowMessages.length > 0 && (\n <div className={styles.flowMessagesContainer}>\n {flowMessages.map((message: any, index: number) => (\n <AlertPrimitive\n key={message.id || index}\n variant={message.type?.toLowerCase() === 'error' ? 'error' : 'info'}\n className={cx(styles.flowMessageItem, messageClasses)}\n >\n <AlertPrimitive.Description>{message.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n ))}\n </div>\n )}\n <div className={styles.contentContainer}>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0 ? (\n renderComponents(componentsWithoutHeadings)\n ) : (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.recovery.components.not.available')}</Typography>\n </AlertPrimitive>\n )}\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * BaseRecovery component for ThunderIDV2 that provides an embedded account/password recovery flow.\n * Accepts API functions as props to maintain framework independence.\n */\nconst BaseRecovery: FC<BaseRecoveryProps> = ({\n preferences,\n showLogo = true,\n ...rest\n}: BaseRecoveryProps): ReactElement => {\n const {theme, colorScheme} = useTheme();\n const styles: any = useStyles(theme, colorScheme);\n\n const content: ReactElement = (\n <div>\n {showLogo && (\n <div className={styles.logoContainer}>\n <Logo size=\"large\" />\n </div>\n )}\n <FlowProvider>\n <BaseRecoveryContent showLogo={showLogo} {...rest} />\n </FlowProvider>\n </div>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseRecovery;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BaseRecovery.js","names":["BaseRecoveryContent: FC<BaseRecoveryProps>","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","useThunderID","styles: any","useStyles","initializationAttemptedRef: any","challengeTokenRef: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","extractFormFields: any","fields: FormField[]","fieldName: any","useStepExpiry","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","setupFormFields: any","fields: any","initialValues: Record<string, string>","composedData: Record<string, any> | undefined","composeAffixedInputs","filteredInputs: Record<string, any>","payload: EmbeddedRecoveryFlowRequest","rawResponse: any","response: any","containerClasses: any","inputClasses: any","buttonClasses: any","errorClasses: any","messageClasses: any","renderComponents: any","result: ReturnType<typeof validateForm>","CardPrimitive","Spinner","AlertPrimitive","getAuthComponentHeadings","Typography","BaseRecovery: FC<BaseRecoveryProps>","content: ReactElement","Logo","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../src/components/auth/Recovery/BaseRecovery.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n EmbeddedRecoveryFlowStatus,\n EmbeddedFlowComponentType,\n FieldError,\n withVendorCSSClassPrefix,\n buildValidatorFromRules,\n Preferences,\n FlowMetadataResponse,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useContext, useEffect, useMemo, useState, useCallback, useRef} from 'react';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport FlowProvider from '../../../contexts/Flow/FlowProvider';\nimport useFlow from '../../../contexts/Flow/useFlow';\nimport ComponentPreferencesContext from '../../../contexts/I18n/ComponentPreferencesContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport useStepExpiry from '../../../hooks/auth/useStepExpiry';\nimport {useForm, FormField} from '../../../hooks/useForm';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport composeAffixedInputs from '../../../utils/composeAffixedInputs';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../utils/flowTransformer';\nimport getAuthComponentHeadings from '../../../utils/getAuthComponentHeadings';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Logo from '../../primitives/Logo/Logo';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderRecoveryComponents} from '../flow/AuthOptionFactory';\nimport useStyles from '../SignUp/BaseSignUp.styles';\n\n/**\n * Render props for custom UI rendering.\n */\nexport interface BaseRecoveryRenderProps {\n components: any[];\n error?: Error | null;\n fieldErrors: Record<string, string>;\n handleInputChange: (name: string, value: string) => void;\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n isLoading: boolean;\n isValid: boolean;\n messages: {message: string; type: string}[];\n meta: FlowMetadataResponse | null;\n subtitle: string;\n title: string;\n touched: Record<string, boolean>;\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseRecovery component.\n */\nexport interface BaseRecoveryProps {\n afterRecoveryUrl?: string;\n buttonClassName?: string;\n /**\n * Render props function for custom UI or static content\n */\n children?: ((props: BaseRecoveryRenderProps) => ReactNode) | ReactNode;\n className?: string;\n error?: Error | null;\n errorClassName?: string;\n inputClassName?: string;\n isInitialized?: boolean;\n messageClassName?: string;\n onComplete?: (response: EmbeddedRecoveryFlowResponse) => void;\n onError?: (error: Error) => void;\n onFlowChange?: (response: EmbeddedRecoveryFlowResponse) => void;\n onInitialize?: (payload?: EmbeddedRecoveryFlowRequest) => Promise<EmbeddedRecoveryFlowResponse>;\n onSubmit?: (payload: EmbeddedRecoveryFlowRequest) => Promise<EmbeddedRecoveryFlowResponse>;\n /**\n * Component-level preferences to override global i18n and theme settings.\n */\n preferences?: Preferences;\n /**\n * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n showLogo?: boolean;\n showSubtitle?: boolean;\n showTitle?: boolean;\n size?: 'small' | 'medium' | 'large';\n variant?: CardProps['variant'];\n}\n\n/**\n * Internal component that renders the V2 recovery UI and manages flow state.\n *\n * @internal\n */\nconst BaseRecoveryContent: FC<BaseRecoveryProps> = ({\n onInitialize,\n onSubmit,\n onError,\n onFlowChange,\n onComplete,\n error: externalError,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n errorClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isInitialized,\n children,\n showTitle = true,\n showSubtitle = true,\n revalidateOnChangeAfterBlur = false,\n}: BaseRecoveryProps): ReactElement => {\n const {theme, colorScheme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const {meta, vendor} = useThunderID();\n const styles: any = useStyles(theme, colorScheme);\n\n const [isLoading, setIsLoading] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<EmbeddedRecoveryFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const initializationAttemptedRef: any = useRef(false);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t);\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n clearMessages();\n addMessage({message: errorMessage, type: 'error'});\n },\n [t, addMessage, clearMessages],\n );\n\n const normalizeFlowResponseLocal: any = useCallback(\n (response: EmbeddedRecoveryFlowResponse): EmbeddedRecoveryFlowResponse => {\n if (response?.data?.components && Array.isArray(response.data.components)) {\n return response;\n }\n\n if (response?.data) {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {defaultErrorKey: 'components.recovery.errors.generic', resolveTranslations: false},\n meta,\n );\n\n return {...response, data: {...response.data, components: components as any}};\n }\n\n return response;\n },\n [t, meta],\n );\n\n const extractFormFields: any = useCallback(\n (components: any[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: any[]): any => {\n comps.forEach((component: any) => {\n if (\n component.type === EmbeddedFlowComponentType.TextInput ||\n component.type === EmbeddedFlowComponentType.PasswordInput ||\n component.type === EmbeddedFlowComponentType.EmailInput ||\n component.type === EmbeddedFlowComponentType.Select ||\n component.type === EmbeddedFlowComponentType.DateInput\n ) {\n const fieldName: any = component.ref || component.id;\n const ruleValidator = buildValidatorFromRules(component.validation);\n fields.push({\n initialValue: '',\n name: fieldName,\n required: component.required || false,\n validator: (value: string) => {\n if (component.required && (!value || value.trim() === '')) {\n return t('validations.required.field.error');\n }\n // Evaluate declarative validation rules from meta.components[].validation.\n if (ruleValidator && value) {\n const ruleMessage = ruleValidator(value);\n if (ruleMessage) {\n return t(ruleMessage);\n }\n }\n // Add email validation if it's an email field\n if (\n (component.type === EmbeddedFlowComponentType.EmailInput || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n return null;\n },\n });\n }\n\n if (component.components && Array.isArray(component.components)) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(components);\n return fields;\n },\n [t],\n );\n\n const formFields: any = useMemo(\n () => (currentFlow?.data?.components ? extractFormFields(currentFlow.data.components) : []),\n [currentFlow, extractFormFields],\n );\n\n const form: any = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\n revalidateOnChangeAfterBlur,\n validateOnBlur: true,\n validateOnChange: false,\n });\n\n const {\n values: formValues,\n touched: touchedFields,\n errors: formErrors,\n isComplete: isFormComplete,\n isValid: isFormValid,\n setValue: setFormValue,\n setTouched: setFormTouched,\n setTouchedFields,\n setErrors: setFormErrors,\n clearErrors: clearFormErrors,\n validateForm,\n touchAllFields,\n reset: resetForm,\n } = form;\n\n // A custom renderer can expire the step from the client; it holds until the next step response.\n const {expireStep, isStepExpired} = useStepExpiry(currentFlow);\n\n // Project server-side fieldErrors from the flow response into form state.\n // `setTouchedFields` avoids re-running client-side validation that would wipe\n // server errors when the client rules happen to pass.\n useEffect(() => {\n clearFormErrors();\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setTouchedFields(touched);\n setFormErrors(errors);\n }, [currentFlow, setFormErrors, setTouchedFields, clearFormErrors]);\n\n const setupFormFields: any = useCallback(\n (flowResponse: EmbeddedRecoveryFlowResponse) => {\n const fields: any = extractFormFields(flowResponse.data?.components || []);\n const initialValues: Record<string, string> = {};\n fields.forEach((field: any) => {\n initialValues[field.name] = field.initialValue || '';\n });\n resetForm();\n Object.keys(initialValues).forEach((key: any) => setFormValue(key, initialValues[key]));\n },\n [extractFormFields, resetForm, setFormValue],\n );\n\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n const handleSubmit = async (component: any, data?: Record<string, any>, skipValidation?: boolean): Promise<void> => {\n if (!currentFlow) return;\n\n if (!skipValidation) {\n touchAllFields();\n const validation: ReturnType<typeof validateForm> = validateForm();\n if (!validation.isValid) return;\n }\n\n setIsLoading(true);\n setApiError(null);\n clearMessages();\n\n try {\n const composedData: Record<string, any> | undefined = data\n ? composeAffixedInputs(data as Record<string, string>, vendor)\n : undefined;\n\n const filteredInputs: Record<string, any> = {};\n if (composedData) {\n Object.entries(composedData).forEach(([key, value]: [string, any]) => {\n if (value !== null && value !== undefined && value !== '') {\n filteredInputs[key] = value;\n }\n });\n }\n\n const payload: EmbeddedRecoveryFlowRequest = {\n ...(currentFlow.executionId && {executionId: currentFlow.executionId}),\n ...(component.id && {action: component.id}),\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n inputs: filteredInputs,\n };\n\n const rawResponse: any = await onSubmit?.(payload);\n if (!rawResponse) return;\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n if (response.challengeToken !== undefined) {\n challengeTokenRef.current = response.challengeToken ?? null;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Error) {\n handleError(response);\n onError?.(new Error(extractErrorMessage(response, t)));\n return;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Complete) {\n onComplete?.(response);\n return;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Incomplete) {\n setCurrentFlow(response);\n setupFormFields(response);\n\n // Display error from INCOMPLETE response\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (response?.error) {\n handleError(response);\n }\n }\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('recovery'),\n withVendorCSSClassPrefix(`recovery--${size}`),\n withVendorCSSClassPrefix(`recovery--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('recovery__input'),\n size === 'small' && withVendorCSSClassPrefix('recovery__input--small'),\n size === 'large' && withVendorCSSClassPrefix('recovery__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('recovery__button'),\n size === 'small' && withVendorCSSClassPrefix('recovery__button--small'),\n size === 'large' && withVendorCSSClassPrefix('recovery__button--large'),\n ],\n buttonClassName,\n );\n\n const errorClasses: any = cx([withVendorCSSClassPrefix('recovery__error')], errorClassName);\n const messageClasses: any = cx([withVendorCSSClassPrefix('recovery__messages')], messageClassName);\n\n const renderComponents: any = useCallback(\n (components: any[]): ReactElement[] =>\n renderRecoveryComponents(\n components,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n isFormComplete,\n isTimeoutDisabled: isStepExpired,\n meta,\n onInputBlur: handleInputBlur,\n onStepExpire: expireStep,\n onSubmit: handleSubmit,\n size,\n variant,\n vendor,\n },\n ),\n [\n customRenderers,\n buttonClasses,\n formErrors,\n formValues,\n handleInputBlur,\n handleSubmit,\n inputClasses,\n isFormValid,\n isFormComplete,\n isStepExpired,\n expireStep,\n meta,\n isLoading,\n size,\n theme,\n touchedFields,\n variant,\n vendor,\n ],\n );\n\n useEffect(() => {\n if (isInitialized && !isFlowInitialized && !initializationAttemptedRef.current) {\n initializationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsLoading(true);\n setApiError(null);\n clearMessages();\n\n try {\n const rawResponse: any = await onInitialize?.();\n if (!rawResponse) return;\n const response: any = normalizeFlowResponseLocal(rawResponse);\n\n if (response.challengeToken !== undefined) {\n challengeTokenRef.current = response.challengeToken ?? null;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Error) {\n handleError(response);\n onError?.(new Error(extractErrorMessage(response, t)));\n }\n\n setCurrentFlow(response);\n setIsFlowInitialized(true);\n onFlowChange?.(response);\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Complete) {\n onComplete?.(response);\n return;\n }\n\n if (response.flowStatus === EmbeddedRecoveryFlowStatus.Incomplete) {\n setupFormFields(response);\n\n // Display error from INCOMPLETE response\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (response?.error) {\n handleError(response);\n }\n }\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsLoading(false);\n }\n })();\n }\n }, [\n isFlowInitialized,\n isInitialized,\n normalizeFlowResponseLocal,\n onComplete,\n onError,\n onFlowChange,\n onInitialize,\n setupFormFields,\n t,\n ]);\n\n if (children) {\n if (typeof children === 'function') {\n const renderProps: BaseRecoveryRenderProps = {\n components: currentFlow?.data?.components || [],\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle || t('recovery.subheading'),\n title: flowTitle || t('recovery.heading'),\n touched: touchedFields,\n validateForm: (): {fieldErrors: Record<string, string>; isValid: boolean} => {\n const result: ReturnType<typeof validateForm> = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return <div className={containerClasses}>{(children as any)(renderProps)}</div>;\n }\n\n return <div className={containerClasses}>{children}</div>;\n }\n\n if (!isFlowInitialized && isLoading) {\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={styles.loadingContainer}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!currentFlow) {\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\" className={errorClasses}>\n <AlertPrimitive.Title>{t('errors.heading')}</AlertPrimitive.Title>\n <AlertPrimitive.Description>{t('errors.recovery.flow.initialization.failure')}</AlertPrimitive.Description>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n const componentsToRender: any = currentFlow.data?.components || [];\n const {title, subtitle, componentsWithoutHeadings} = getAuthComponentHeadings(\n componentsToRender,\n flowTitle,\n flowSubtitle,\n t('recovery.heading'),\n t('recovery.subheading'),\n );\n\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {externalError && (\n <div className={styles.flowMessagesContainer}>\n <AlertPrimitive variant=\"error\" className={cx(styles.flowMessageItem, messageClasses)}>\n <AlertPrimitive.Description>{externalError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n {flowMessages && flowMessages.length > 0 && (\n <div className={styles.flowMessagesContainer}>\n {flowMessages.map((message: any, index: number) => (\n <AlertPrimitive\n key={message.id || index}\n variant={message.type?.toLowerCase() === 'error' ? 'error' : 'info'}\n className={cx(styles.flowMessageItem, messageClasses)}\n >\n <AlertPrimitive.Description>{message.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n ))}\n </div>\n )}\n <div className={styles.contentContainer}>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0 ? (\n renderComponents(componentsWithoutHeadings)\n ) : (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.recovery.components.not.available')}</Typography>\n </AlertPrimitive>\n )}\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * BaseRecovery component for ThunderIDV2 that provides an embedded account/password recovery flow.\n * Accepts API functions as props to maintain framework independence.\n */\nconst BaseRecovery: FC<BaseRecoveryProps> = ({\n preferences,\n showLogo = true,\n ...rest\n}: BaseRecoveryProps): ReactElement => {\n const {theme, colorScheme} = useTheme();\n const styles: any = useStyles(theme, colorScheme);\n\n const content: ReactElement = (\n <div>\n {showLogo && (\n <div className={styles.logoContainer}>\n <Logo size=\"large\" />\n </div>\n )}\n <FlowProvider>\n <BaseRecoveryContent showLogo={showLogo} {...rest} />\n </FlowProvider>\n </div>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseRecovery;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BaseSignIn.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/SignIn/BaseSignIn.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseSignIn.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/SignIn/BaseSignIn.tsx"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ import Spinner_default from "../../primitives/Spinner/Spinner.js";
12
12
  import Typography_default from "../../primitives/Typography/Typography.js";
13
13
  import Card_default from "../../primitives/Card/Card.js";
14
14
  import BaseSignIn_styles_default from "./BaseSignIn.styles.js";
15
+ import useStepExpiry_default from "../../../hooks/auth/useStepExpiry.js";
15
16
  import composeAffixedInputs_default from "../../../utils/composeAffixedInputs.js";
16
17
  import Alert_default from "../../primitives/Alert/Alert.js";
17
18
  import { renderSignInComponents } from "../flow/AuthOptionFactory.js";
@@ -94,7 +95,7 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
94
95
  processComponents(flowComponents);
95
96
  return fields;
96
97
  }, [t]);
97
- const { values: formValues, touched: touchedFields, errors: formErrors, isValid: isFormValid, setValue: setFormValue, setValues: setFormValues, setTouched: setFormTouched, setTouchedFields, setErrors: setFormErrors, clearErrors: clearFormErrors, validateForm, touchAllFields, reset: resetForm, revalidateTouchedFields } = useForm({
98
+ const { values: formValues, touched: touchedFields, errors: formErrors, isComplete: isFormComplete, isValid: isFormValid, setValue: setFormValue, setValues: setFormValues, setTouched: setFormTouched, setTouchedFields, setErrors: setFormErrors, clearErrors: clearFormErrors, validateForm, touchAllFields, reset: resetForm, revalidateTouchedFields } = useForm({
98
99
  fields: useMemo(() => components ? extractFormFields(components) : [], [components, extractFormFields]),
99
100
  initialValues: {},
100
101
  requiredMessage: t("validations.required.field.error"),
@@ -113,6 +114,8 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
113
114
  initialValuesKey,
114
115
  setFormValues
115
116
  ]);
117
+ const { expireStep, isStepExpired } = useStepExpiry_default(components);
118
+ const isStepDisabled = isTimeoutDisabled || isStepExpired;
116
119
  useEffect(() => {
117
120
  clearFormErrors();
118
121
  if (!serverFieldErrors || serverFieldErrors.length === 0) return;
@@ -204,9 +207,11 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
204
207
  additionalData,
205
208
  buttonClassName: buttonClasses,
206
209
  inputClassName: inputClasses,
207
- isTimeoutDisabled,
210
+ isFormComplete,
211
+ isTimeoutDisabled: isStepDisabled,
208
212
  meta,
209
213
  onInputBlur: handleInputBlur,
214
+ onStepExpire: expireStep,
210
215
  onSubmit: handleSubmit,
211
216
  size,
212
217
  t,
@@ -219,6 +224,7 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
219
224
  touchedFields,
220
225
  formErrors,
221
226
  isFormValid,
227
+ isFormComplete,
222
228
  meta,
223
229
  t,
224
230
  theme,
@@ -230,7 +236,8 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
230
236
  buttonClasses,
231
237
  handleInputBlur,
232
238
  handleSubmit,
233
- isTimeoutDisabled
239
+ isStepDisabled,
240
+ expireStep
234
241
  ]);
235
242
  if (children) {
236
243
  const renderProps = {
@@ -241,7 +248,7 @@ const BaseSignInContent = ({ components = [], onSubmit, onError, error: external
241
248
  handleInputChange,
242
249
  handleSubmit,
243
250
  isLoading,
244
- isTimeoutDisabled,
251
+ isTimeoutDisabled: isStepDisabled,
245
252
  isValid: isFormValid,
246
253
  messages: flowMessages || [],
247
254
  meta,