@thunderid/react 1.17.0 → 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.
- package/dist/cjs/components/account/VerifyAttribute/BaseVerifyAttribute.cjs +6 -1
- package/dist/cjs/components/account/VerifyAttribute/BaseVerifyAttribute.cjs.map +1 -1
- package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs +5 -0
- package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
- package/dist/cjs/components/auth/InviteUser/BaseInviteUser.cjs +8 -0
- package/dist/cjs/components/auth/InviteUser/BaseInviteUser.cjs.map +1 -1
- package/dist/cjs/components/auth/Recovery/BaseRecovery.cjs +9 -1
- package/dist/cjs/components/auth/Recovery/BaseRecovery.cjs.map +1 -1
- package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs +11 -4
- package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs.map +1 -1
- package/dist/cjs/components/auth/SignUp/BaseSignUp.cjs +9 -1
- package/dist/cjs/components/auth/SignUp/BaseSignUp.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +3 -1
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
- package/dist/cjs/contexts/ComponentRenderer/ComponentRendererContext.cjs.map +1 -1
- package/dist/cjs/hooks/auth/useStepExpiry.cjs +25 -0
- package/dist/cjs/hooks/auth/useStepExpiry.cjs.map +1 -0
- package/dist/cjs/hooks/useForm.cjs +2 -0
- package/dist/cjs/hooks/useForm.cjs.map +1 -1
- package/dist/components/account/VerifyAttribute/BaseVerifyAttribute.d.ts.map +1 -1
- package/dist/components/account/VerifyAttribute/BaseVerifyAttribute.js +6 -1
- package/dist/components/account/VerifyAttribute/BaseVerifyAttribute.js.map +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +5 -0
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
- package/dist/components/auth/InviteUser/BaseInviteUser.d.ts.map +1 -1
- package/dist/components/auth/InviteUser/BaseInviteUser.js +8 -0
- package/dist/components/auth/InviteUser/BaseInviteUser.js.map +1 -1
- package/dist/components/auth/Recovery/BaseRecovery.d.ts.map +1 -1
- package/dist/components/auth/Recovery/BaseRecovery.js +9 -1
- package/dist/components/auth/Recovery/BaseRecovery.js.map +1 -1
- package/dist/components/auth/SignIn/BaseSignIn.d.ts.map +1 -1
- package/dist/components/auth/SignIn/BaseSignIn.js +11 -4
- package/dist/components/auth/SignIn/BaseSignIn.js.map +1 -1
- package/dist/components/auth/SignUp/BaseSignUp.d.ts.map +1 -1
- package/dist/components/auth/SignUp/BaseSignUp.js +9 -1
- package/dist/components/auth/SignUp/BaseSignUp.js.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.d.ts +20 -0
- package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.js +3 -1
- package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
- package/dist/contexts/ComponentRenderer/ComponentRendererContext.d.ts +2 -15
- package/dist/contexts/ComponentRenderer/ComponentRendererContext.d.ts.map +1 -1
- package/dist/contexts/ComponentRenderer/ComponentRendererContext.js.map +1 -1
- package/dist/hooks/auth/useStepExpiry.d.ts +17 -0
- package/dist/hooks/auth/useStepExpiry.d.ts.map +1 -0
- package/dist/hooks/auth/useStepExpiry.js +23 -0
- package/dist/hooks/auth/useStepExpiry.js.map +1 -0
- package/dist/hooks/useForm.d.ts +6 -0
- package/dist/hooks/useForm.d.ts.map +1 -1
- package/dist/hooks/useForm.js +3 -1
- package/dist/hooks/useForm.js.map +1 -1
- 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":"AAGA,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAM5B,WAAW,EACX,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAAgB,SAAS,EAAgE,MAAM,OAAO,CAAC;
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqGA,MAAMA,uBAA8C,EAClD,cACA,UACA,SACA,cACA,YACA,OAAO,eACP,YAAY,IACZ,iBAAiB,IACjB,kBAAkB,IAClB,iBAAiB,IACjB,mBAAmB,IACnB,OAAO,UACP,UAAU,YACV,eACA,UACA,YAAY,MACZ,eAAe,MACf,8BAA8B,YACO;CACrC,MAAM,EAAC,OAAO,gBAAeC,kBAAU;CACvC,MAAMC,kBAAwC,WAAWC,iCAAyB;CAClF,MAAM,EAAC,MAAKC,wBAAgB;CAC5B,MAAM,EAAC,UAAU,cAAc,OAAO,WAAW,UAAU,cAAc,YAAY,kBAAiBC,iBAAS;CAC/G,MAAM,EAAC,MAAM,WAAUC,sBAAc;CACrC,MAAMC,SAAcC,0BAAU,OAAO,YAAY;CAEjD,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,MAAM;CACjE,MAAM,CAAC,aAAa,kBAAkB,SAA8C,KAAK;CACzF,MAAM,CAAC,UAAU,eAAe,SAAuB,KAAK;CAE5D,MAAMC,6BAAkC,OAAO,MAAM;CACrD,MAAMC,oBAAyB,OAAsB,KAAK;CAE1D,MAAMC,cAAmB,aACtB,UAAe;EACd,MAAMC,eAAuB,oBAAoB,OAAO,EAAE;AAC1D,cAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,aAAa,CAAC;AACrE,iBAAe;AACf,aAAW;GAAC,SAAS;GAAc,MAAM;GAAQ,CAAC;IAEpD;EAAC;EAAG;EAAY;EAAc,CAC/B;CAED,MAAMC,6BAAkC,aACrC,aAAyE;AACxE,MAAI,UAAU,MAAM,cAAc,MAAM,QAAQ,SAAS,KAAK,WAAW,CACvE,QAAO;AAGT,MAAI,UAAU,MAAM;GAClB,MAAM,EAAC,eAAc,sBACnB,UACA,GACA;IAAC,iBAAiB;IAAsC,qBAAqB;IAAM,EACnF,KACD;AAED,UAAO;IAAC,GAAG;IAAU,MAAM;KAAC,GAAG,SAAS;KAAkB;KAAkB;IAAC;;AAG/E,SAAO;IAET,CAAC,GAAG,KAAK,CACV;CAED,MAAMC,oBAAyB,aAC5B,eAAmC;EAClC,MAAMC,SAAsB,EAAE;EAE9B,MAAM,qBAAqB,UAAsB;AAC/C,SAAM,SAAS,cAAmB;AAChC,QACE,UAAU,SAAS,0BAA0B,aAC7C,UAAU,SAAS,0BAA0B,iBAC7C,UAAU,SAAS,0BAA0B,cAC7C,UAAU,SAAS,0BAA0B,UAC7C,UAAU,SAAS,0BAA0B,WAC7C;KACA,MAAMC,YAAiB,UAAU,OAAO,UAAU;KAClD,MAAM,gBAAgB,wBAAwB,UAAU,WAAW;AACnE,YAAO,KAAK;MACV,cAAc;MACd,MAAM;MACN,UAAU,UAAU,YAAY;MAChC,YAAY,UAAkB;AAC5B,WAAI,UAAU,aAAa,CAAC,SAAS,MAAM,MAAM,KAAK,IACpD,QAAO,EAAE,mCAAmC;AAG9C,WAAI,iBAAiB,OAAO;QAC1B,MAAM,cAAc,cAAc,MAAM;AACxC,YAAI,YACF,QAAO,EAAE,YAAY;;AAIzB,YACG,UAAU,SAAS,0BAA0B,cAAc,UAAU,YAAY,YAClF,SACA,CAAC,6BAA6B,KAAK,MAAM,CAEzC,QAAO,EAAE,sBAAsB;AAEjC,cAAO;;MAEV,CAAC;;AAGJ,QAAI,UAAU,cAAc,MAAM,QAAQ,UAAU,WAAW,CAC7D,mBAAkB,UAAU,WAAW;KAEzC;;AAGJ,oBAAkB,WAAW;AAC7B,SAAO;IAET,CAAC,EAAE,CACJ;CAgBD,MAAM,EACJ,QAAQ,YACR,SAAS,eACT,QAAQ,YACR,SAAS,aACT,UAAU,cACV,YAAY,gBACZ,kBACA,WAAW,eACX,aAAa,iBACb,cACA,gBACA,OAAO,cArBS,QAAgC;EAChD,QANsB,cACf,aAAa,MAAM,aAAa,kBAAkB,YAAY,KAAK,WAAW,GAAG,EAAE,EAC1F,CAAC,aAAa,kBAAkB,CACjC;EAIC,eAAe,EAAE;EACjB,iBAAiB,EAAE,mCAAmC;EACtD;EACA,gBAAgB;EAChB,kBAAkB;EACnB,CAAC;AAoBF,iBAAgB;AACd,mBAAiB;EACjB,MAAMC,uBAAiD,aAAa,OAAc;AAClF,MAAI,CAAC,uBAAuB,oBAAoB,WAAW,EACzD;EAEF,MAAMC,SAAiC,EAAE;EACzC,MAAMC,UAAmC,EAAE;AAC3C,OAAK,MAAM,MAAM,oBACf,KAAI,EAAE,GAAG,cAAc,SAAS;AAC9B,UAAO,GAAG,cAAc,GAAG;AAC3B,WAAQ,GAAG,cAAc;;AAG7B,mBAAiB,QAAQ;AACzB,gBAAc,OAAO;IACpB;EAAC;EAAa;EAAe;EAAkB;EAAgB,CAAC;CAEnE,MAAMC,kBAAuB,aAC1B,iBAA+C;EAC9C,MAAMC,SAAc,kBAAkB,aAAa,MAAM,cAAc,EAAE,CAAC;EAC1E,MAAMC,gBAAwC,EAAE;AAChD,SAAO,SAAS,UAAe;AAC7B,iBAAc,MAAM,QAAQ,MAAM,gBAAgB;IAClD;AACF,aAAW;AACX,SAAO,KAAK,cAAc,CAAC,SAAS,QAAa,aAAa,KAAK,cAAc,KAAK,CAAC;IAEzF;EAAC;EAAmB;EAAW;EAAa,CAC7C;CAED,MAAM,qBAAqB,MAAc,UAAwB;AAC/D,eAAa,MAAM,MAAM;;CAG3B,MAAM,mBAAmB,SAAuB;AAC9C,iBAAe,MAAM,KAAK;;CAG5B,MAAM,eAAe,OAAO,WAAgB,MAA4B,mBAA4C;AAClH,MAAI,CAAC,YAAa;AAElB,MAAI,CAAC,gBAAgB;AACnB,mBAAgB;AAEhB,OAAI,CADgD,cAAc,CAClD,QAAS;;AAG3B,eAAa,KAAK;AAClB,cAAY,KAAK;AACjB,iBAAe;AAEf,MAAI;GACF,MAAMC,eAAgD,OAClDC,6BAAqB,MAAgC,OAAO,GAC5D;GAEJ,MAAMC,iBAAsC,EAAE;AAC9C,OAAI,aACF,QAAO,QAAQ,aAAa,CAAC,SAAS,CAAC,KAAK,WAA0B;AACpE,QAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,GACrD,gBAAe,OAAO;KAExB;GAGJ,MAAMC,UAAuC;IAC3C,GAAI,YAAY,eAAe,EAAC,aAAa,YAAY,aAAY;IACrE,GAAI,UAAU,MAAM,EAAC,QAAQ,UAAU,IAAG;IAC1C,GAAI,kBAAkB,UAAU,EAAC,gBAAgB,kBAAkB,SAAQ,GAAG,EAAE;IAChF,QAAQ;IACT;GAED,MAAMC,cAAmB,MAAM,WAAW,QAAQ;AAClD,OAAI,CAAC,YAAa;GAClB,MAAMC,WAAgB,2BAA2B,YAAY;AAC7D,kBAAe,SAAS;AAExB,OAAI,SAAS,mBAAmB,OAC9B,mBAAkB,UAAU,SAAS,kBAAkB;AAGzD,OAAI,SAAS,eAAe,2BAA2B,OAAO;AAC5D,gBAAY,SAAS;AACrB,cAAU,IAAI,MAAM,oBAAoB,UAAU,EAAE,CAAC,CAAC;AACtD;;AAGF,OAAI,SAAS,eAAe,2BAA2B,UAAU;AAC/D,iBAAa,SAAS;AACtB;;AAGF,OAAI,SAAS,eAAe,2BAA2B,YAAY;AACjE,mBAAe,SAAS;AACxB,oBAAgB,SAAS;AAIzB,QAAI,UAAU,MACZ,aAAY,SAAS;;WAGlB,KAAK;AACZ,eAAY,IAAI;AAChB,aAAU,IAAa;YACf;AACR,gBAAa,MAAM;;;CAIvB,MAAMC,mBAAwB,GAC5B;EACE,yBAAyB,WAAW;EACpC,yBAAyB,aAAa,OAAO;EAC7C,yBAAyB,aAAa,UAAU;EACjD,EACD,UACD;CAED,MAAMC,eAAoB,GACxB;EACE,yBAAyB,kBAAkB;EAC3C,SAAS,WAAW,yBAAyB,yBAAyB;EACtE,SAAS,WAAW,yBAAyB,yBAAyB;EACvE,EACD,eACD;CAED,MAAMC,gBAAqB,GACzB;EACE,yBAAyB,mBAAmB;EAC5C,SAAS,WAAW,yBAAyB,0BAA0B;EACvE,SAAS,WAAW,yBAAyB,0BAA0B;EACxE,EACD,gBACD;CAED,MAAMC,eAAoB,GAAG,CAAC,yBAAyB,kBAAkB,CAAC,EAAE,eAAe;CAC3F,MAAMC,iBAAsB,GAAG,CAAC,yBAAyB,qBAAqB,CAAC,EAAE,iBAAiB;CAElG,MAAMC,mBAAwB,aAC3B,eACC,yBACE,YACA,YACA,eACA,YACA,WACA,aACA,WACA,mBACA;EACE,kBAAkB;EAClB,QAAQ;EACR,iBAAiB;EACjB,gBAAgB;EAChB;EACA,aAAa;EACb,UAAU;EACV;EACA;EACA;EACD,CACF,EACH;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,iBAAgB;AACd,MAAI,iBAAiB,CAAC,qBAAqB,CAAC,2BAA2B,SAAS;AAC9E,8BAA2B,UAAU;AAErC,IAAC,YAA2B;AAC1B,iBAAa,KAAK;AAClB,gBAAY,KAAK;AACjB,mBAAe;AAEf,QAAI;KACF,MAAMP,cAAmB,MAAM,gBAAgB;AAC/C,SAAI,CAAC,YAAa;KAClB,MAAMC,WAAgB,2BAA2B,YAAY;AAE7D,SAAI,SAAS,mBAAmB,OAC9B,mBAAkB,UAAU,SAAS,kBAAkB;AAGzD,SAAI,SAAS,eAAe,2BAA2B,OAAO;AAC5D,kBAAY,SAAS;AACrB,gBAAU,IAAI,MAAM,oBAAoB,UAAU,EAAE,CAAC,CAAC;;AAGxD,oBAAe,SAAS;AACxB,0BAAqB,KAAK;AAC1B,oBAAe,SAAS;AAExB,SAAI,SAAS,eAAe,2BAA2B,UAAU;AAC/D,mBAAa,SAAS;AACtB;;AAGF,SAAI,SAAS,eAAe,2BAA2B,YAAY;AACjE,sBAAgB,SAAS;AAIzB,UAAI,UAAU,MACZ,aAAY,SAAS;;aAGlB,KAAK;AACZ,iBAAY,IAAI;AAChB,eAAU,IAAa;cACf;AACR,kBAAa,MAAM;;OAEnB;;IAEL;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,UAAU;AACZ,MAAI,OAAO,aAAa,WAqBtB,QAAO,oBAAC;GAAI,WAAW;aAAoB,SApBE;IAC3C,YAAY,aAAa,MAAM,cAAc,EAAE;IAC/C,OAAO;IACP,aAAa;IACb;IACA;IACA;IACA,SAAS;IACT,UAAU,gBAAgB,EAAE;IAC5B;IACA,UAAU,gBAAgB,EAAE,sBAAsB;IAClD,OAAO,aAAa,EAAE,mBAAmB;IACzC,SAAS;IACT,oBAA6E;KAC3E,MAAMO,SAA0C,cAAc;AAC9D,YAAO;MAAC,aAAa,OAAO;MAAQ,SAAS,OAAO;MAAQ;;IAE9D,QAAQ;IACT,CAEuE;IAAO;AAGjF,SAAO,oBAAC;GAAI,WAAW;GAAmB;IAAe;;AAG3D,KAAI,CAAC,qBAAqB,UACxB,QACE,oBAACC;EAAc,WAAW,GAAG,kBAAkB,OAAO,KAAK;EAAW;YACpE,oBAACA,aAAc,qBACb,oBAAC;GAAI,WAAW,OAAO;aACrB,oBAACC,mBAAQ,MAAK,WAAW;IACrB,GACgB;GACV;AAIpB,KAAI,CAAC,YACH,QACE,oBAACD;EAAc,WAAW,GAAG,kBAAkB,OAAO,KAAK;EAAW;YACpE,oBAACA,aAAc,qBACb,qBAACE;GAAe,SAAQ;GAAQ,WAAW;cACzC,oBAACA,cAAe,mBAAO,EAAE,iBAAiB,GAAwB,EAClE,oBAACA,cAAe,yBAAa,EAAE,8CAA8C,GAA8B;IAC5F,GACK;GACV;CAKpB,MAAM,EAAC,OAAO,UAAU,8BAA6BC,iCADrB,YAAY,MAAM,cAAc,EAAE,EAGhE,WACA,cACA,EAAE,mBAAmB,EACrB,EAAE,sBAAsB,CACzB;AAED,QACE,qBAACH;EAAc,WAAW,GAAG,kBAAkB,OAAO,KAAK;EAAW;cAClE,aAAa,iBACb,qBAACA,aAAc;GAAO,WAAW,OAAO;cACrC,aACC,oBAACA,aAAc;IAAM,OAAO;IAAG,WAAW,OAAO;cAC9C;KACmB,EAEvB,gBACC,oBAACI;IAAW,SAAQ;IAAQ,WAAW,OAAO;cAC3C;KACU;IAEM,EAEzB,qBAACJ,aAAc;GACZ,iBACC,oBAAC;IAAI,WAAW,OAAO;cACrB,oBAACE;KAAe,SAAQ;KAAQ,WAAW,GAAG,OAAO,iBAAiB,eAAe;eACnF,oBAACA,cAAe,yBAAa,cAAc,UAAqC;MACjE;KACb;GAEP,gBAAgB,aAAa,SAAS,KACrC,oBAAC;IAAI,WAAW,OAAO;cACpB,aAAa,KAAK,SAAc,UAC/B,oBAACA;KAEC,SAAS,QAAQ,MAAM,aAAa,KAAK,UAAU,UAAU;KAC7D,WAAW,GAAG,OAAO,iBAAiB,eAAe;eAErD,oBAACA,cAAe,yBAAa,QAAQ,UAAqC;OAJrE,QAAQ,MAAM,MAKJ,CACjB;KACE;GAER,oBAAC;IAAI,WAAW,OAAO;cACpB,6BAA6B,0BAA0B,SAAS,IAC/D,iBAAiB,0BAA0B,GAE3C,oBAACA;KAAe,SAAQ;eACtB,oBAACE;MAAW,SAAQ;gBAAS,EAAE,2CAA2C;OAAc;MACzE;KAEf;MACgB;GACV;;;;;;AAQpB,MAAMC,gBAAuC,EAC3C,aACA,WAAW,KACX,GAAG,WACkC;CACrC,MAAM,EAAC,OAAO,gBAAexC,kBAAU;CACvC,MAAMM,SAAcC,0BAAU,OAAO,YAAY;CAEjD,MAAMkC,UACJ,qBAAC,oBACE,YACC,oBAAC;EAAI,WAAW,OAAO;YACrB,oBAACC,gBAAK,MAAK,UAAU;GACjB,EAER,oBAACC,kCACC,oBAAC;EAA8B;EAAU,GAAI;GAAQ,GACxC,IACX;AAGR,KAAI,CAAC,YAAa,QAAO;AAEzB,QAAO,oBAACC,oCAA4B;EAAS,OAAO;YAAc;GAA+C;;AAGnH,2BAAe"}
|
|
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":"AAGA,OAAO,EAEL,yBAAyB,EACzB,qBAAqB,EACrB,UAAU,EACV,oBAAoB,EACpB,WAAW,EAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAA+E,SAAS,EAAC,MAAM,OAAO,CAAC;
|
|
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
|
-
|
|
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
|
-
|
|
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,
|