@thunderid/react 0.3.7 → 0.5.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/auth/Callback/OAuthCallback.cjs +10 -4
- package/dist/cjs/components/auth/Callback/OAuthCallback.cjs.map +1 -1
- package/dist/cjs/components/auth/Callback/TokenCallback.cjs +8 -7
- package/dist/cjs/components/auth/Callback/TokenCallback.cjs.map +1 -1
- package/dist/cjs/components/factories/FieldFactory.cjs +2 -1
- package/dist/cjs/components/factories/FieldFactory.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs +4 -3
- package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs +56 -33
- package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs +5 -1
- package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignIn/SignIn.cjs +7 -6
- package/dist/cjs/components/presentation/auth/SignIn/SignIn.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs +5 -1
- package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs.map +1 -1
- package/dist/cjs/components/primitives/FormControl/FormControl.cjs +2 -1
- package/dist/cjs/components/primitives/FormControl/FormControl.cjs.map +1 -1
- package/dist/cjs/components/primitives/Typography/Typography.cjs.map +1 -1
- package/dist/cjs/contexts/I18n/I18nProvider.cjs +2 -3
- package/dist/cjs/contexts/I18n/I18nProvider.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs +4 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs +5 -2
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
- package/dist/cjs/utils/oauth.cjs +3 -2
- package/dist/cjs/utils/oauth.cjs.map +1 -1
- package/dist/components/auth/Callback/OAuthCallback.d.ts.map +1 -1
- package/dist/components/auth/Callback/OAuthCallback.js +12 -6
- package/dist/components/auth/Callback/OAuthCallback.js.map +1 -1
- package/dist/components/auth/Callback/TokenCallback.d.ts.map +1 -1
- package/dist/components/auth/Callback/TokenCallback.js +8 -7
- package/dist/components/auth/Callback/TokenCallback.js.map +1 -1
- package/dist/components/factories/FieldFactory.d.ts +4 -0
- package/dist/components/factories/FieldFactory.d.ts.map +1 -1
- package/dist/components/factories/FieldFactory.js +2 -1
- package/dist/components/factories/FieldFactory.js.map +1 -1
- package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
- package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js +4 -3
- package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
- package/dist/components/presentation/auth/AuthOptionFactory.d.ts.map +1 -1
- package/dist/components/presentation/auth/AuthOptionFactory.js +57 -34
- package/dist/components/presentation/auth/AuthOptionFactory.js.map +1 -1
- package/dist/components/presentation/auth/SignIn/BaseSignIn.d.ts +4 -0
- package/dist/components/presentation/auth/SignIn/BaseSignIn.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignIn/BaseSignIn.js +5 -1
- package/dist/components/presentation/auth/SignIn/BaseSignIn.js.map +1 -1
- package/dist/components/presentation/auth/SignIn/SignIn.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignIn/SignIn.js +7 -6
- package/dist/components/presentation/auth/SignIn/SignIn.js.map +1 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts +4 -0
- package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.js +5 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.js.map +1 -1
- package/dist/components/primitives/FormControl/FormControl.d.ts +4 -0
- package/dist/components/primitives/FormControl/FormControl.d.ts.map +1 -1
- package/dist/components/primitives/FormControl/FormControl.js +2 -1
- package/dist/components/primitives/FormControl/FormControl.js.map +1 -1
- package/dist/components/primitives/Typography/Typography.d.ts +4 -0
- package/dist/components/primitives/Typography/Typography.d.ts.map +1 -1
- package/dist/components/primitives/Typography/Typography.js.map +1 -1
- package/dist/contexts/I18n/I18nProvider.d.ts +6 -0
- package/dist/contexts/I18n/I18nProvider.d.ts.map +1 -1
- package/dist/contexts/I18n/I18nProvider.js +3 -4
- package/dist/contexts/I18n/I18nProvider.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts +5 -0
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.js +3 -1
- package/dist/contexts/ThunderID/ThunderIDContext.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.js +6 -3
- package/dist/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
- package/dist/utils/oauth.d.ts +2 -1
- package/dist/utils/oauth.d.ts.map +1 -1
- package/dist/utils/oauth.js +4 -3
- package/dist/utils/oauth.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseSignIn.js","names":["BaseSignInContent: FC<BaseSignInProps>","useThunderID","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","styles: any","useStyles","isLoading: boolean","handleError: any","errorMessage: string","extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[]","fields: FormField[]","identifier: string","filteredInputs: Record<string, any>","payload: EmbeddedSignInFlowRequest","containerClasses: any","inputClasses: any","buttonClasses: any","messageClasses: any","renderComponents: any","renderProps: BaseSignInRenderProps","result: any","CardPrimitive","Spinner","AlertPrimitive","Typography","BaseSignIn: FC<BaseSignInProps>","content: ReactElement","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../../src/components/presentation/auth/SignIn/BaseSignIn.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025-2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {cx} from '@emotion/css';\nimport {\n withVendorCSSClassPrefix,\n EmbeddedSignInFlowRequest,\n EmbeddedFlowComponent,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n} from '@thunderid/browser';\nimport {FC, useState, useCallback, useContext, ReactElement, ReactNode} from 'react';\nimport useStyles from './BaseSignIn.styles';\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 {FormField, useForm} from '../../../../hooks/useForm';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {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 {renderSignInComponents} from '../AuthOptionFactory';\n\n/**\n * Render props for custom UI rendering\n */\nexport interface BaseSignInRenderProps {\n /**\n * Flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * API error (if any)\n */\n error?: Error | null;\n\n /**\n * Field validation errors\n */\n fieldErrors: Record<string, string>;\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: EmbeddedFlowComponent, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state\n */\n isLoading: boolean;\n\n /**\n * Flag indicating if the step timer has reached zero\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Whether the form is valid\n */\n isValid: boolean;\n\n /**\n * Flow messages\n */\n messages: {message: string; type: string}[];\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Flow subtitle\n */\n subtitle: string;\n\n /**\n * Flow title\n */\n title: string;\n\n /**\n * Touched fields\n */\n touched: Record<string, boolean>;\n\n /**\n * Function to validate the form\n */\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n\n /**\n * Form values\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseSignIn component.\n */\nexport interface BaseSignInProps {\n /**\n * Additional data from the flow response.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Custom CSS class name for the submit button.\n */\n buttonClassName?: string;\n\n /**\n * Render props function for custom UI\n */\n children?: (props: BaseSignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Array of flow components to render.\n */\n components?: EmbeddedFlowComponent[];\n\n /**\n * Error object to display\n */\n error?: Error | null;\n\n /**\n * Custom CSS class name for error messages.\n */\n errorClassName?: string;\n\n /**\n * Custom CSS class name for form inputs.\n */\n inputClassName?: string;\n\n /**\n * Flag to determine if the component is ready to be rendered.\n */\n isLoading?: boolean;\n\n /**\n * Timer flag disabling actions\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Custom CSS class name for info messages.\n */\n messageClassName?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Function to handle form submission.\n * @param payload - The form data to submit.\n * @param component - The component that triggered the submission.\n */\n onSubmit?: (payload: EmbeddedSignInFlowRequest, component: EmbeddedFlowComponent) => Promise<void>;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\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 * Field-level validation errors returned by the server in `data.fieldErrors` on the\n * most recent flow response. The component collapses these into the form's\n * `fieldErrors` state (first error per field wins), surfacing them through the same\n * render-prop / UI path as client-side validation errors. The full array is preserved\n * here for advanced consumers that want every failing rule per field.\n */\n serverFieldErrors?: FieldError[] | null;\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 * Internal component that consumes FlowContext and renders the sign-in UI.\n */\nconst BaseSignInContent: FC<BaseSignInProps> = ({\n components = [],\n onSubmit,\n onError,\n error: externalError,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isLoading: externalIsLoading,\n children,\n additionalData = {},\n isTimeoutDisabled = false,\n}: BaseSignInProps): ReactElement => {\n const {meta} = useThunderID();\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const isLoading: boolean = externalIsLoading || isSubmitting;\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);\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Clear existing messages and add the error message\n clearMessages();\n addMessage({\n message: errorMessage,\n type: 'error',\n });\n },\n [t, addMessage, clearMessages],\n );\n\n /**\n * Extract form fields from flow components\n */\n const extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[] = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: EmbeddedFlowComponent[]): any => {\n comps.forEach((component: any) => {\n if (\n component.type === 'TEXT_INPUT' ||\n component.type === 'PASSWORD_INPUT' ||\n component.type === 'EMAIL_INPUT' ||\n component.type === 'PHONE_INPUT' ||\n component.type === 'OTP_INPUT'\n ) {\n const identifier: string = component.ref;\n fields.push({\n initialValue: '',\n name: identifier,\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 // Add email validation if it's an email field\n if (\n (component.type === 'EMAIL_INPUT' || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n\n return null;\n },\n });\n }\n if (component.components) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(flowComponents);\n return fields;\n },\n [t],\n );\n\n const formFields: FormField[] = components ? extractFormFields(components) : [];\n\n const form: ReturnType<typeof useForm> = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\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 validateForm,\n touchAllFields,\n } = form;\n\n /**\n * Handle input value changes.\n * Only updates the value without marking as touched.\n * Touched state is set on blur to avoid premature validation.\n */\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n /**\n * Handle input blur event.\n * Marks the field as touched, which triggers validation.\n */\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n /**\n * Handle component submission (for buttons and actions).\n */\n const handleSubmit = async (\n component: EmbeddedFlowComponent,\n data?: Record<string, any>,\n skipValidation?: boolean,\n ): Promise<void> => {\n // Only validate for form submit actions, skip for social/trigger actions\n if (!skipValidation) {\n // Mark all fields as touched before validation\n touchAllFields();\n\n const validation: ReturnType<typeof validateForm> = validateForm();\n\n if (!validation.isValid) {\n return;\n }\n }\n\n setIsSubmitting(true);\n setApiError(null);\n clearMessages();\n\n try {\n // Filter out empty or undefined input values\n const filteredInputs: Record<string, any> = {};\n if (data) {\n Object.keys(data).forEach((key: any) => {\n if (data[key] !== undefined && data[key] !== null && data[key] !== '') {\n filteredInputs[key] = data[key];\n }\n });\n }\n\n let payload: EmbeddedSignInFlowRequest = {};\n\n // For V2, we always send inputs and action\n payload = {\n ...payload,\n ...(component.id && {action: component.id}),\n inputs: filteredInputs,\n };\n\n await onSubmit?.(payload, component);\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n // Generate CSS classes\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin'),\n withVendorCSSClassPrefix(`signin--${size}`),\n withVendorCSSClassPrefix(`signin--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__input'),\n size === 'small' && withVendorCSSClassPrefix('signin__input--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__button'),\n size === 'small' && withVendorCSSClassPrefix('signin__button--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__button--large'),\n ],\n buttonClassName,\n );\n\n const messageClasses: any = cx([withVendorCSSClassPrefix('signin__messages')], messageClassName);\n\n /**\n * Render components based on flow data using the factory\n */\n const renderComponents: any = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): ReactElement[] =>\n renderSignInComponents(\n flowComponents,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n isTimeoutDisabled,\n meta,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n },\n ),\n [\n additionalData,\n customRenderers,\n formValues,\n touchedFields,\n formErrors,\n isFormValid,\n meta,\n t,\n theme,\n isLoading,\n size,\n variant,\n inputClasses,\n buttonClasses,\n handleInputBlur,\n handleSubmit,\n isTimeoutDisabled,\n ],\n );\n\n // If render props are provided, use them\n if (children) {\n const renderProps: BaseSignInRenderProps = {\n components,\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isTimeoutDisabled,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle ?? '',\n title: flowTitle || t('signin.heading'),\n touched: touchedFields,\n validateForm: () => {\n const result: any = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return (\n <div className={containerClasses} data-testid=\"thunderid-signin\">\n {children(renderProps)}\n </div>\n );\n }\n\n // Default UI rendering\n if (isLoading) {\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} data-testid=\"thunderid-signin\" variant={variant}>\n <CardPrimitive.Content>\n <div style={{display: 'flex', justifyContent: 'center', padding: '2rem'}}>\n <Spinner />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!components || components.length === 0) {\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} data-testid=\"thunderid-signin\" variant={variant}>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.signin.components.not.available')}</Typography>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n return (\n <CardPrimitive className={cx(containerClasses, styles.card)} data-testid=\"thunderid-signin\" variant={variant}>\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: any) => (\n <AlertPrimitive\n key={index}\n variant={message.type === '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}>{renderComponents(components)}</div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * Base SignIn component that provides generic authentication flow.\n * This component handles component-driven UI rendering and can transform input\n * structure to component-driven format automatically.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { BaseSignIn } from '@thunderid/react';\n *\n * const MySignIn = () => {\n * return (\n * <BaseSignIn\n * components={components}\n * onSubmit={async (payload) => {\n * return await handleAuth(payload);\n * }}\n * onSuccess={(authData) => {\n * console.log('Success:', authData);\n * }}\n * className=\"max-w-md mx-auto\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * <BaseSignIn components={components} onSubmit={handleSubmit}>\n * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (\n * <div className=\"custom-form\">\n * <input\n * name=\"username\"\n * value={values.username || ''}\n * onChange={(e) => handleInputChange('username', e.target.value)}\n * />\n * {errors.username && <span>{errors.username}</span>}\n * <button\n * onClick={() => handleSubmit(components[0], values)}\n * disabled={isLoading}\n * >\n * Sign In\n * </button>\n * </div>\n * )}\n * </BaseSignIn>\n * ```\n */\nconst BaseSignIn: FC<BaseSignInProps> = ({preferences, ...rest}: BaseSignInProps): ReactElement => {\n const content: ReactElement = (\n <FlowProvider>\n <BaseSignInContent {...rest} />\n </FlowProvider>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseSignIn;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BaseSignIn.js","names":["BaseSignInContent: FC<BaseSignInProps>","useThunderID","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","useTranslation","useFlow","styles: any","useStyles","isLoading: boolean","handleError: any","errorMessage: string","extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[]","fields: FormField[]","identifier: string","filteredInputs: Record<string, any>","payload: EmbeddedSignInFlowRequest","containerClasses: any","inputClasses: any","buttonClasses: any","messageClasses: any","renderComponents: any","renderProps: BaseSignInRenderProps","result: any","CardPrimitive","Spinner","AlertPrimitive","Typography","BaseSignIn: FC<BaseSignInProps>","content: ReactElement","FlowProvider","ComponentPreferencesContext"],"sources":["../../../../../src/components/presentation/auth/SignIn/BaseSignIn.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025-2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {cx} from '@emotion/css';\nimport {\n withVendorCSSClassPrefix,\n EmbeddedSignInFlowRequest,\n EmbeddedFlowComponent,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n} from '@thunderid/browser';\nimport {FC, useState, useCallback, useContext, ReactElement, ReactNode} from 'react';\nimport useStyles from './BaseSignIn.styles';\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 {FormField, useForm} from '../../../../hooks/useForm';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {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 {renderSignInComponents} from '../AuthOptionFactory';\n\n/**\n * Render props for custom UI rendering\n */\nexport interface BaseSignInRenderProps {\n /**\n * Flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * API error (if any)\n */\n error?: Error | null;\n\n /**\n * Field validation errors\n */\n fieldErrors: Record<string, string>;\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: EmbeddedFlowComponent, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state\n */\n isLoading: boolean;\n\n /**\n * Flag indicating if the step timer has reached zero\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Whether the form is valid\n */\n isValid: boolean;\n\n /**\n * Flow messages\n */\n messages: {message: string; type: string}[];\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Flow subtitle\n */\n subtitle: string;\n\n /**\n * Flow title\n */\n title: string;\n\n /**\n * Touched fields\n */\n touched: Record<string, boolean>;\n\n /**\n * Function to validate the form\n */\n validateForm: () => {fieldErrors: Record<string, string>; isValid: boolean};\n\n /**\n * Form values\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseSignIn component.\n */\nexport interface BaseSignInProps {\n /**\n * Additional data from the flow response.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Custom CSS class name for the submit button.\n */\n buttonClassName?: string;\n\n /**\n * Render props function for custom UI\n */\n children?: (props: BaseSignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Array of flow components to render.\n */\n components?: EmbeddedFlowComponent[];\n\n /**\n * Error object to display\n */\n error?: Error | null;\n\n /**\n * Custom CSS class name for error messages.\n */\n errorClassName?: string;\n\n /**\n * Custom CSS class name for form inputs.\n */\n inputClassName?: string;\n\n /**\n * Flag to determine if the component is ready to be rendered.\n */\n isLoading?: boolean;\n\n /**\n * Timer flag disabling actions\n */\n isTimeoutDisabled?: boolean;\n\n /**\n * Custom CSS class name for info messages.\n */\n messageClassName?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Function to handle form submission.\n * @param payload - The form data to submit.\n * @param component - The component that triggered the submission.\n */\n onSubmit?: (payload: EmbeddedSignInFlowRequest, component: EmbeddedFlowComponent) => Promise<void>;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\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 * HTML id attribute for the form container.\n */\n id?: string;\n\n /**\n * Field-level validation errors returned by the server in `data.fieldErrors` on the\n * most recent flow response. The component collapses these into the form's\n * `fieldErrors` state (first error per field wins), surfacing them through the same\n * render-prop / UI path as client-side validation errors. The full array is preserved\n * here for advanced consumers that want every failing rule per field.\n */\n serverFieldErrors?: FieldError[] | null;\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 * Internal component that consumes FlowContext and renders the sign-in UI.\n */\nconst BaseSignInContent: FC<BaseSignInProps> = ({\n components = [],\n onSubmit,\n onError,\n error: externalError,\n id,\n className = '',\n inputClassName = '',\n buttonClassName = '',\n messageClassName = '',\n size = 'medium',\n variant = 'outlined',\n isLoading: externalIsLoading,\n children,\n additionalData = {},\n isTimeoutDisabled = false,\n}: BaseSignInProps): ReactElement => {\n const {meta} = useThunderID();\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const {t} = useTranslation();\n const {subtitle: flowSubtitle, title: flowTitle, messages: flowMessages, addMessage, clearMessages} = useFlow();\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [apiError, setApiError] = useState<Error | null>(null);\n\n const isLoading: boolean = externalIsLoading || isSubmitting;\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);\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Clear existing messages and add the error message\n clearMessages();\n addMessage({\n message: errorMessage,\n type: 'error',\n });\n },\n [t, addMessage, clearMessages],\n );\n\n /**\n * Extract form fields from flow components\n */\n const extractFormFields: (components: EmbeddedFlowComponent[]) => FormField[] = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): FormField[] => {\n const fields: FormField[] = [];\n\n const processComponents = (comps: EmbeddedFlowComponent[]): any => {\n comps.forEach((component: any) => {\n if (\n component.type === 'TEXT_INPUT' ||\n component.type === 'PASSWORD_INPUT' ||\n component.type === 'EMAIL_INPUT' ||\n component.type === 'PHONE_INPUT' ||\n component.type === 'OTP_INPUT'\n ) {\n const identifier: string = component.ref;\n fields.push({\n initialValue: '',\n name: identifier,\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 // Add email validation if it's an email field\n if (\n (component.type === 'EMAIL_INPUT' || component.variant === 'EMAIL') &&\n value &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n ) {\n return t('field.email.invalid');\n }\n\n return null;\n },\n });\n }\n if (component.components) {\n processComponents(component.components);\n }\n });\n };\n\n processComponents(flowComponents);\n return fields;\n },\n [t],\n );\n\n const formFields: FormField[] = components ? extractFormFields(components) : [];\n\n const form: ReturnType<typeof useForm> = useForm<Record<string, string>>({\n fields: formFields,\n initialValues: {},\n requiredMessage: t('validations.required.field.error'),\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 validateForm,\n touchAllFields,\n } = form;\n\n /**\n * Handle input value changes.\n * Only updates the value without marking as touched.\n * Touched state is set on blur to avoid premature validation.\n */\n const handleInputChange = (name: string, value: string): void => {\n setFormValue(name, value);\n };\n\n /**\n * Handle input blur event.\n * Marks the field as touched, which triggers validation.\n */\n const handleInputBlur = (name: string): void => {\n setFormTouched(name, true);\n };\n\n /**\n * Handle component submission (for buttons and actions).\n */\n const handleSubmit = async (\n component: EmbeddedFlowComponent,\n data?: Record<string, any>,\n skipValidation?: boolean,\n ): Promise<void> => {\n // Only validate for form submit actions, skip for social/trigger actions\n if (!skipValidation) {\n // Mark all fields as touched before validation\n touchAllFields();\n\n const validation: ReturnType<typeof validateForm> = validateForm();\n\n if (!validation.isValid) {\n return;\n }\n }\n\n setIsSubmitting(true);\n setApiError(null);\n clearMessages();\n\n try {\n // Filter out empty or undefined input values\n const filteredInputs: Record<string, any> = {};\n if (data) {\n Object.keys(data).forEach((key: any) => {\n if (data[key] !== undefined && data[key] !== null && data[key] !== '') {\n filteredInputs[key] = data[key];\n }\n });\n }\n\n let payload: EmbeddedSignInFlowRequest = {};\n\n // For V2, we always send inputs and action\n payload = {\n ...payload,\n ...(component.id && {action: component.id}),\n inputs: filteredInputs,\n };\n\n await onSubmit?.(payload, component);\n } catch (err) {\n handleError(err);\n onError?.(err as Error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n // Generate CSS classes\n const containerClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin'),\n withVendorCSSClassPrefix(`signin--${size}`),\n withVendorCSSClassPrefix(`signin--${variant}`),\n ],\n className,\n );\n\n const inputClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__input'),\n size === 'small' && withVendorCSSClassPrefix('signin__input--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__input--large'),\n ],\n inputClassName,\n );\n\n const buttonClasses: any = cx(\n [\n withVendorCSSClassPrefix('signin__button'),\n size === 'small' && withVendorCSSClassPrefix('signin__button--small'),\n size === 'large' && withVendorCSSClassPrefix('signin__button--large'),\n ],\n buttonClassName,\n );\n\n const messageClasses: any = cx([withVendorCSSClassPrefix('signin__messages')], messageClassName);\n\n /**\n * Render components based on flow data using the factory\n */\n const renderComponents: any = useCallback(\n (flowComponents: EmbeddedFlowComponent[]): ReactElement[] =>\n renderSignInComponents(\n flowComponents,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData,\n buttonClassName: buttonClasses,\n inputClassName: inputClasses,\n isTimeoutDisabled,\n meta,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n },\n ),\n [\n additionalData,\n customRenderers,\n formValues,\n touchedFields,\n formErrors,\n isFormValid,\n meta,\n t,\n theme,\n isLoading,\n size,\n variant,\n inputClasses,\n buttonClasses,\n handleInputBlur,\n handleSubmit,\n isTimeoutDisabled,\n ],\n );\n\n // If render props are provided, use them\n if (children) {\n const renderProps: BaseSignInRenderProps = {\n components,\n error: apiError,\n fieldErrors: formErrors,\n handleInputChange,\n handleSubmit,\n isLoading,\n isTimeoutDisabled,\n isValid: isFormValid,\n messages: flowMessages || [],\n meta,\n subtitle: flowSubtitle ?? '',\n title: flowTitle || t('signin.heading'),\n touched: touchedFields,\n validateForm: () => {\n const result: any = validateForm();\n return {fieldErrors: result.errors, isValid: result.isValid};\n },\n values: formValues,\n };\n\n return (\n <div id={id} className={containerClasses} data-testid=\"thunderid-signin\">\n {children(renderProps)}\n </div>\n );\n }\n\n // Default UI rendering\n if (isLoading) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <div style={{display: 'flex', justifyContent: 'center', padding: '2rem'}}>\n <Spinner />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n if (!components || components.length === 0) {\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\n >\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">{t('errors.signin.components.not.available')}</Typography>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n return (\n <CardPrimitive\n id={id}\n className={cx(containerClasses, styles.card)}\n data-testid=\"thunderid-signin\"\n variant={variant}\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: any) => (\n <AlertPrimitive\n key={index}\n variant={message.type === '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}>{renderComponents(components)}</div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\n/**\n * Base SignIn component that provides generic authentication flow.\n * This component handles component-driven UI rendering and can transform input\n * structure to component-driven format automatically.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { BaseSignIn } from '@thunderid/react';\n *\n * const MySignIn = () => {\n * return (\n * <BaseSignIn\n * components={components}\n * onSubmit={async (payload) => {\n * return await handleAuth(payload);\n * }}\n * onSuccess={(authData) => {\n * console.log('Success:', authData);\n * }}\n * className=\"max-w-md mx-auto\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * <BaseSignIn components={components} onSubmit={handleSubmit}>\n * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (\n * <div className=\"custom-form\">\n * <input\n * name=\"username\"\n * value={values.username || ''}\n * onChange={(e) => handleInputChange('username', e.target.value)}\n * />\n * {errors.username && <span>{errors.username}</span>}\n * <button\n * onClick={() => handleSubmit(components[0], values)}\n * disabled={isLoading}\n * >\n * Sign In\n * </button>\n * </div>\n * )}\n * </BaseSignIn>\n * ```\n */\nconst BaseSignIn: FC<BaseSignInProps> = ({preferences, ...rest}: BaseSignInProps): ReactElement => {\n const content: ReactElement = (\n <FlowProvider>\n <BaseSignInContent {...rest} />\n </FlowProvider>\n );\n\n if (!preferences) return content;\n\n return <ComponentPreferencesContext.Provider value={preferences}>{content}</ComponentPreferencesContext.Provider>;\n};\n\nexport default BaseSignIn;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignIn/SignIn.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAGL,qBAAqB,EAGrB,yBAAyB,EAIzB,oBAAoB,EACpB,WAAW,EAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAA6C,SAAS,EAAC,MAAM,OAAO,CAAC;AAE/E,OAAmB,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAQzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErC;;OAEG;IACH,UAAU,EAAE,qBAAqB,EAAE,CAAC;IAEpC;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,SAAS,CAAC;IAEnD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpD;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;CACtC;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignIn/SignIn.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAGL,qBAAqB,EAGrB,yBAAyB,EAIzB,oBAAoB,EACpB,WAAW,EAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAA6C,SAAS,EAAC,MAAM,OAAO,CAAC;AAE/E,OAAmB,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAQzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErC;;OAEG;IACH,UAAU,EAAE,qBAAqB,EAAE,CAAC;IAEpC;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,SAAS,CAAC;IAEnD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpD;;;;OAIG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;CACtC;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAqxB3B,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -72,7 +72,7 @@ import { Fragment, jsx } from "react/jsx-runtime";
|
|
|
72
72
|
* ```
|
|
73
73
|
*/
|
|
74
74
|
const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, variant, children }) => {
|
|
75
|
-
const { applicationId, afterSignInUrl, signIn, isInitialized, isLoading, meta, getStorageManager, scopes } = useThunderID_default();
|
|
75
|
+
const { applicationId, afterSignInUrl, signIn, isInitialized, isLoading, meta, getStorageManager, scopes, vendor } = useThunderID_default();
|
|
76
76
|
const { t } = useTranslation_default(preferences?.i18n);
|
|
77
77
|
const [components, setComponents] = useState([]);
|
|
78
78
|
const [additionalData, setAdditionalData] = useState({});
|
|
@@ -101,8 +101,8 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
101
101
|
*/
|
|
102
102
|
const setExecutionId = (executionId) => {
|
|
103
103
|
setCurrentExecutionId(executionId);
|
|
104
|
-
if (executionId) sessionStorage.setItem(
|
|
105
|
-
else sessionStorage.removeItem(
|
|
104
|
+
if (executionId) sessionStorage.setItem(`${vendor}_execution_id`, executionId);
|
|
105
|
+
else sessionStorage.removeItem(`${vendor}_execution_id`);
|
|
106
106
|
};
|
|
107
107
|
/**
|
|
108
108
|
* Restore any challenge token persisted before an OAuth redirect.
|
|
@@ -229,7 +229,7 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
229
229
|
if (response.executionId) setExecutionId(response.executionId);
|
|
230
230
|
await setChallengeToken(response.challengeToken ?? null);
|
|
231
231
|
await handleAuthId(getUrlParams().authId);
|
|
232
|
-
initiateOAuthRedirect(redirectURL);
|
|
232
|
+
initiateOAuthRedirect(redirectURL, vendor);
|
|
233
233
|
return true;
|
|
234
234
|
}
|
|
235
235
|
}
|
|
@@ -254,7 +254,7 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
254
254
|
setExecutionId(null);
|
|
255
255
|
await setChallengeToken(null);
|
|
256
256
|
setIsFlowInitialized(false);
|
|
257
|
-
sessionStorage.removeItem(
|
|
257
|
+
sessionStorage.removeItem(`${vendor}_execution_id`);
|
|
258
258
|
try {
|
|
259
259
|
await (await getStorageManager())?.removeHybridDataParameter?.("authId");
|
|
260
260
|
} catch {
|
|
@@ -280,7 +280,7 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
280
280
|
setServerFieldErrors(null);
|
|
281
281
|
await handleAuthId(urlParams.authId);
|
|
282
282
|
const effectiveApplicationId = applicationId || urlParams.applicationId;
|
|
283
|
-
const storedExecutionId = !urlParams.executionId ? sessionStorage.getItem(
|
|
283
|
+
const storedExecutionId = !urlParams.executionId ? sessionStorage.getItem(`${vendor}_execution_id`) : null;
|
|
284
284
|
const resumeExecutionId = urlParams.executionId || storedExecutionId;
|
|
285
285
|
if (!resumeExecutionId && !effectiveApplicationId) {
|
|
286
286
|
const error = new ThunderIDRuntimeError("Either executionId or applicationId is required for authentication", "SIGN_IN_ERROR", "react");
|
|
@@ -492,6 +492,7 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
492
492
|
};
|
|
493
493
|
useOAuthCallback({
|
|
494
494
|
currentExecutionId,
|
|
495
|
+
executionIdStorageKey: `${vendor}_execution_id`,
|
|
495
496
|
isInitialized: isInitialized && !isLoading && isStorageReady,
|
|
496
497
|
isSubmitting,
|
|
497
498
|
onError: (err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.js","names":["SignIn: FC<SignInProps>","useThunderID","useTranslation","challengeTokenRef: any","initializationAttemptedRef: any","oauthCodeProcessedRef: any","passkeyProcessedRef: any","tempData: any","storageManager: any","urlParams: any","url: any","redirectURL: any","err: any","finalRedirectUrl: any","effectiveApplicationId: any","storedExecutionId: any","resumeExecutionId: any","error: any","response: EmbeddedSignInFlowResponse","currentUrlParams: any","timeoutMs: number","remaining: number","errorMessage: string","timerId: any","effectiveExecutionId: any","processedInputs: Record<string, any>","consentPromptRawData: any","purposes: any[]","found: any","submitAction: any","decisions: any","effectiveExecutionIdForPasskey: any","responseFieldErrors: FieldError[] | undefined","inputs: Record<string, string>","passkeyResponse: any","passkeyResponseObj: any","renderPropFieldErrors: Record<string, string>","BaseSignIn"],"sources":["../../../../../src/components/presentation/auth/SignIn/SignIn.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025-2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {\n ThunderIDRuntimeError,\n ThunderIDAPIError,\n EmbeddedFlowComponent,\n EmbeddedFlowType,\n EmbeddedSignInFlowResponse,\n EmbeddedSignInFlowRequest,\n EmbeddedSignInFlowStatus,\n EmbeddedSignInFlowType,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n logger,\n} from '@thunderid/browser';\nimport {FC, ReactElement, useState, useEffect, useRef, ReactNode} from 'react';\n// eslint-disable-next-line import/no-named-as-default\nimport BaseSignIn, {BaseSignInProps} from './BaseSignIn';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\nimport {useOAuthCallback} from '../../../../hooks/useOAuthCallback';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {extractErrorMessage, normalizeFlowResponse} from '../../../../utils/flowTransformer';\nimport {initiateOAuthRedirect} from '../../../../utils/oauth';\nimport {handlePasskeyAuthentication, handlePasskeyRegistration} from '../../../../utils/passkey';\n\n/**\n * Render props function parameters\n */\nexport interface SignInRenderProps {\n /**\n * Additional data from the flow response containing contextual information\n * like consent prompt details and session timeouts.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Current flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * Current error if any\n */\n error: Error | null;\n\n /**\n * Server-side field-level validation errors from the most recent flow response,\n * collapsed to one message per field (first error wins). Empty when no validation\n * failures are active. Render-prop consumers should display these alongside their\n * own client-side validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Function to manually initialize the flow\n */\n initialize: () => Promise<void>;\n\n /**\n * Whether the flow has been initialized\n */\n isInitialized: boolean;\n\n /**\n * Loading state indicator\n */\n isLoading: boolean;\n\n /**\n * Flag indicating whether the flow step timeout has expired.\n * Consuming components can use this to disable submit buttons.\n */\n isTimeoutDisabled?: 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 * Function to submit authentication data (primary)\n */\n onSubmit: (payload: EmbeddedSignInFlowRequest) => Promise<void>;\n}\n\n/**\n * Props for the SignIn component.\n * Matches the interface from the main SignIn component for consistency.\n */\nexport interface SignInProps {\n /**\n * Render props function for custom UI\n */\n children?: (props: SignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\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 * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: BaseSignInProps['variant'];\n}\n\n/**\n * State for tracking passkey registration\n */\ninterface PasskeyState {\n actionId: string | null;\n challenge: string | null;\n creationOptions: string | null;\n error: Error | null;\n executionId: string | null;\n isActive: boolean;\n}\n\n/**\n * A component-driven SignIn component that provides authentication flow with pre-built styling.\n * This component handles the flow API calls for authentication and delegates UI logic to BaseSignIn.\n * It automatically transforms simple input-based responses into component-driven UI format.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { SignIn } from '@thunderid/react/component-driven';\n *\n * const App = () => {\n * return (\n * <SignIn\n * onSuccess={(authData) => {\n * console.log('Authentication successful:', authData);\n * }}\n * onError={(error) => {\n * console.error('Authentication failed:', error);\n * }}\n * size=\"medium\"\n * variant=\"outlined\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * import { SignIn } from '@thunderid/react/component-driven';\n *\n * const App = () => {\n * return (\n * <SignIn\n * onSuccess={(authData) => console.log('Success:', authData)}\n * onError={(error) => console.error('Error:', error)}\n * >\n * {({signIn, isLoading, components, error, isInitialized}) => (\n * <div className=\"custom-signin\">\n * <h1>Custom Sign In</h1>\n * {!isInitialized ? (\n * <p>Initializing...</p>\n * ) : error ? (\n * <div className=\"error\">{error.message}</div>\n * ) : (\n * <form onSubmit={(e) => {\n * e.preventDefault();\n * signIn({inputs: {username: 'user', password: 'pass'}});\n * }}>\n * <button type=\"submit\" disabled={isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign In'}\n * </button>\n * </form>\n * )}\n * </div>\n * )}\n * </SignIn>\n * );\n * };\n * ```\n */\nconst SignIn: FC<SignInProps> = ({\n className,\n preferences,\n size = 'medium',\n onSuccess,\n onError,\n variant,\n children,\n}: SignInProps): ReactElement => {\n const {applicationId, afterSignInUrl, signIn, isInitialized, isLoading, meta, getStorageManager, scopes} =\n useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n\n // State management for the flow\n const [components, setComponents] = useState<EmbeddedFlowComponent[]>([]);\n const [additionalData, setAdditionalData] = useState<Record<string, any>>({});\n // Server-side validation errors from the most recent flow response. Updated on every\n // submission; cleared when the next submission begins so stale errors don't linger.\n const [serverFieldErrors, setServerFieldErrors] = useState<FieldError[] | null>(null);\n const [currentExecutionId, setCurrentExecutionId] = useState<string | null>(null);\n const challengeTokenRef: any = useRef<string | null>(null);\n const [isStorageReady, setIsStorageReady] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [flowError, setFlowError] = useState<Error | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isTimeoutDisabled, setIsTimeoutDisabled] = useState<boolean>(false);\n const [passkeyState, setPasskeyState] = useState<PasskeyState>({\n actionId: null,\n challenge: null,\n creationOptions: null,\n error: null,\n executionId: null,\n isActive: false,\n });\n const initializationAttemptedRef: any = useRef(false);\n const oauthCodeProcessedRef: any = useRef(false);\n const passkeyProcessedRef: any = useRef(false);\n /**\n * Sets executionId between sessionStorage and state.\n * This ensures both are always in sync.\n */\n const setExecutionId = (executionId: string | null): void => {\n setCurrentExecutionId(executionId);\n if (executionId) {\n sessionStorage.setItem('thunderid_execution_id', executionId);\n } else {\n sessionStorage.removeItem('thunderid_execution_id');\n }\n };\n\n /**\n * Restore any challenge token persisted before an OAuth redirect.\n * Waits for SDK initialization before reading from storage.\n */\n useEffect(() => {\n if (!isInitialized) 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 } finally {\n setIsStorageReady(true);\n }\n })();\n }, [isInitialized]);\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 * Clear all flow-related storage and state.\n */\n const clearFlowState = async (): Promise<void> => {\n setExecutionId(null);\n await setChallengeToken(null);\n setIsFlowInitialized(false);\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.removeHybridDataParameter?.('authId');\n } catch {\n logger.warn('Failed to clear authId from hybrid storage.');\n }\n setIsTimeoutDisabled(false);\n // Reset refs to allow new flows to start properly\n oauthCodeProcessedRef.current = false;\n };\n\n /**\n * Parse URL parameters used in flows.\n */\n const getUrlParams = (): any => {\n const urlParams: any = new URL(window?.location?.href ?? '').searchParams;\n\n return {\n applicationId: urlParams.get('applicationId'),\n authId: urlParams.get('authId'),\n code: urlParams.get('code'),\n error: urlParams.get('error'),\n errorDescription: urlParams.get('error_description'),\n executionId: urlParams.get('executionId'),\n nonce: urlParams.get('nonce'),\n state: urlParams.get('state'),\n };\n };\n\n /**\n * Handle authId from URL and persist it via the storage manager so it survives URL cleanup.\n * ThunderIDReactClient.signIn() reads authId from storageManager.getHybridDataParameter('authId'),\n * not from raw sessionStorage, so we must use the same storage path here.\n */\n const handleAuthId = async (authId: string | null): Promise<void> => {\n if (authId) {\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.setHybridDataParameter?.('authId', authId);\n } catch {\n logger.warn('Failed to store authId in hybrid storage.');\n }\n }\n };\n\n /**\n * Clean up OAuth-related URL parameters from the browser URL.\n */\n const cleanupOAuthUrlParams = (includeNonce = false): void => {\n if (!window?.location?.href) return;\n const url: any = new URL(window.location.href);\n url.searchParams.delete('error');\n url.searchParams.delete('error_description');\n url.searchParams.delete('code');\n url.searchParams.delete('state');\n if (includeNonce) {\n url.searchParams.delete('nonce');\n }\n window?.history?.replaceState({}, '', url.toString());\n };\n\n /**\n * Clean up flow-related URL parameters (executionId, authId) from the browser URL.\n * Used after executionId is set in state to prevent using invalidated executionId from URL.\n */\n const cleanupFlowUrlParams = (): void => {\n if (!window?.location?.href) return;\n const url: any = new URL(window.location.href);\n url.searchParams.delete('executionId');\n url.searchParams.delete('authId');\n url.searchParams.delete('applicationId');\n window?.history?.replaceState({}, '', url.toString());\n };\n\n /**\n * Set error state and call onError callback.\n * Ensures isFlowInitialized is true so errors can be displayed in the UI.\n */\n const setError = (error: Error): void => {\n setFlowError(error);\n setIsFlowInitialized(true);\n onError?.(error);\n };\n\n /**\n * Handle OAuth error from URL parameters.\n * Clears flow state, creates error, and cleans up URL.\n */\n const handleOAuthError = (error: string, errorDescription: string | null): void => {\n clearFlowState();\n const errorMessage: any = errorDescription || `OAuth error: ${error}`;\n const err: any = new ThunderIDRuntimeError(errorMessage, 'SIGN_IN_ERROR', 'react');\n setError(err);\n cleanupOAuthUrlParams(true);\n };\n\n /**\n * Handle REDIRECTION response by storing flow state and redirecting to OAuth provider.\n */\n const handleRedirection = async (response: EmbeddedSignInFlowResponse): Promise<boolean> => {\n if (response.type === EmbeddedSignInFlowType.Redirection) {\n const redirectURL: any = (response.data as any)?.redirectURL || (response as any)?.redirectURL;\n\n if (redirectURL && window?.location) {\n if (response.executionId) {\n setExecutionId(response.executionId);\n }\n await setChallengeToken(response.challengeToken ?? null);\n\n const urlParams: any = getUrlParams();\n await handleAuthId(urlParams.authId);\n\n initiateOAuthRedirect(redirectURL);\n return true;\n }\n }\n return false;\n };\n\n /**\n * Handle terminal flow responses (Error and Complete) shared by initializeFlow and handleSubmit.\n * Throws on an Error status so the caller's catch block can propagate it to BaseSignIn.\n * Returns true when a Complete status was handled (caller should return), false otherwise.\n */\n const handleTerminalResponse = async (response: EmbeddedSignInFlowResponse): Promise<boolean> => {\n // Handle Error flow status - flow has failed and is invalidated\n if (response.flowStatus === EmbeddedSignInFlowStatus.Error) {\n await clearFlowState();\n const err: any = new Error(extractErrorMessage(response, t));\n setError(err);\n cleanupFlowUrlParams();\n // Throw the error so it's caught by the catch block and propagated to BaseSignIn\n throw err;\n }\n\n if (response.flowStatus === EmbeddedSignInFlowStatus.Complete) {\n // Get redirectUrl from response (from /oauth2/auth/callback) or fall back to afterSignInUrl\n const redirectUrl: any = (response as any)?.redirectUrl || (response as any)?.redirect_uri;\n const finalRedirectUrl: any = redirectUrl || afterSignInUrl;\n\n // Clear submitting state before redirect\n setIsSubmitting(false);\n\n // Clear all OAuth-related storage on successful completion\n setExecutionId(null);\n await setChallengeToken(null);\n setIsFlowInitialized(false);\n sessionStorage.removeItem('thunderid_execution_id');\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.removeHybridDataParameter?.('authId');\n } catch {\n logger.warn('Failed to clear authId from hybrid storage after completion.');\n }\n\n // Clean up OAuth URL params before redirect\n cleanupOAuthUrlParams(true);\n\n if (onSuccess) {\n onSuccess({\n redirectUrl: finalRedirectUrl,\n ...(response.data || {}),\n });\n }\n\n if (finalRedirectUrl && window?.location) {\n window.location.href = finalRedirectUrl;\n }\n\n return true;\n }\n\n return false;\n };\n\n /**\n * Initialize the authentication flow.\n * Priority: executionId > applicationId (from context) > applicationId (from URL)\n */\n const initializeFlow = async (): Promise<void> => {\n const urlParams: any = getUrlParams();\n\n // Reset OAuth code processed ref when starting a new flow\n oauthCodeProcessedRef.current = false;\n // Clear stale serverFieldErrors so the new flow doesn't inherit them via render-prop.\n setServerFieldErrors(null);\n\n await handleAuthId(urlParams.authId);\n\n const effectiveApplicationId: any = applicationId || urlParams.applicationId;\n\n // On a page refresh the executionId is no longer in the URL (it is scrubbed by\n // cleanupFlowUrlParams after the first load). Fall back to the executionId persisted in\n // sessionStorage so the in-progress flow can be resumed instead of starting a new flow.\n // This is required for authorization_code apps where direct new-flow initiation is blocked\n // server-side and the flow must be initiated through the OAuth /authorize endpoint.\n const storedExecutionId: any = !urlParams.executionId ? sessionStorage.getItem('thunderid_execution_id') : null;\n const resumeExecutionId: any = urlParams.executionId || storedExecutionId;\n\n if (!resumeExecutionId && !effectiveApplicationId) {\n const error: any = new ThunderIDRuntimeError(\n 'Either executionId or applicationId is required for authentication',\n 'SIGN_IN_ERROR',\n 'react',\n );\n setError(error);\n throw error;\n }\n\n try {\n setFlowError(null);\n\n let response: EmbeddedSignInFlowResponse;\n\n if (resumeExecutionId) {\n try {\n response = (await signIn({\n executionId: resumeExecutionId,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n })) as EmbeddedSignInFlowResponse;\n } catch (resumeError) {\n // Only treat a stale/expired session (HTTP 400 from the server, meaning the stored\n // executionId is no longer valid) as a recoverable condition. Transient failures\n // such as 5xx server errors or network errors are rethrown so they surface correctly.\n const isStaleSession: boolean =\n storedExecutionId &&\n resumeExecutionId === storedExecutionId &&\n resumeError instanceof ThunderIDAPIError &&\n resumeError.statusCode === 400;\n\n if (isStaleSession) {\n setExecutionId(null);\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.removeHybridDataParameter?.('authId');\n } catch {\n logger.warn('Failed to clear authId from hybrid storage.');\n }\n if (!effectiveApplicationId) {\n const expiredError: any = new ThunderIDRuntimeError(\n t('errors.signin.session.expired') ||\n 'Your session has expired. Please return to the application and sign in again.',\n 'SIGN_IN_ERROR',\n 'react',\n );\n setError(expiredError);\n return;\n }\n response = (await signIn({\n applicationId: effectiveApplicationId,\n flowType: EmbeddedFlowType.Authentication,\n ...(scopes && {scopes}),\n })) as EmbeddedSignInFlowResponse;\n } else {\n throw resumeError;\n }\n }\n } else {\n response = (await signIn({\n applicationId: effectiveApplicationId,\n flowType: EmbeddedFlowType.Authentication,\n ...(scopes && {scopes}),\n })) as EmbeddedSignInFlowResponse;\n }\n\n if (await handleRedirection(response)) {\n return;\n }\n\n // Handle a flow that completes (or errors) on the very first step — e.g. a reused SSO\n // session lets the backend return COMPLETE immediately with no UI components. Without\n // this the UI would fall through with no components and spin forever.\n if (await handleTerminalResponse(response)) {\n return;\n }\n\n const {\n executionId: normalizedExecutionId,\n components: normalizedComponents,\n additionalData: normalizedAdditionalData,\n } = normalizeFlowResponse(\n response,\n t,\n {\n resolveTranslations: false,\n },\n meta,\n );\n\n await setChallengeToken(response.challengeToken ?? null);\n\n if (normalizedExecutionId && normalizedComponents) {\n setExecutionId(normalizedExecutionId);\n setComponents(normalizedComponents);\n setAdditionalData(normalizedAdditionalData ?? {});\n setIsFlowInitialized(true);\n setIsTimeoutDisabled(false);\n // Clean up executionId from URL after setting it in state\n cleanupFlowUrlParams();\n }\n } catch (error) {\n const err: any = error;\n await clearFlowState();\n\n setError(err instanceof ThunderIDRuntimeError ? err : new Error(extractErrorMessage(err, t)));\n initializationAttemptedRef.current = false;\n }\n };\n\n /**\n * Initialize the flow and handle cleanup of stale flow state.\n */\n useEffect(() => {\n const urlParams: any = getUrlParams();\n\n // Check for OAuth error in URL\n if (urlParams.error) {\n handleOAuthError(urlParams.error, urlParams.errorDescription);\n return;\n }\n\n handleAuthId(urlParams.authId);\n\n // Skip OAuth code processing - let the dedicated OAuth useEffect handle it\n // No action needed here as the dedicated useEffect will handle it\n }, []);\n\n useEffect(() => {\n // Only initialize if we're not processing an OAuth callback or submission.\n // Wait for isStorageReady so the challenge token is restored from storage before\n // we attempt to resume a persisted executionId — the server requires it.\n const currentUrlParams: any = getUrlParams();\n if (\n isInitialized &&\n isStorageReady &&\n !isLoading &&\n !isFlowInitialized &&\n !initializationAttemptedRef.current &&\n !currentExecutionId &&\n !currentUrlParams.code &&\n !currentUrlParams.state &&\n !isSubmitting &&\n !oauthCodeProcessedRef.current\n ) {\n initializationAttemptedRef.current = true;\n initializeFlow();\n }\n }, [isInitialized, isStorageReady, isLoading, isFlowInitialized, currentExecutionId]);\n\n /**\n * Handle step timeout if configured in additionalData.\n */\n useEffect(() => {\n const timeoutMs: number = Number(additionalData?.['stepTimeout']) || 0;\n if (timeoutMs <= 0 || !isFlowInitialized) {\n setIsTimeoutDisabled(false);\n return undefined;\n }\n\n const remaining: number = Math.max(0, Math.floor((timeoutMs - Date.now()) / 1000));\n\n const handleTimeout = (): void => {\n const errorMessage: string = t('errors.signin.timeout') || 'Time allowed to complete the step has expired.';\n setError(new Error(errorMessage));\n setIsTimeoutDisabled(true);\n };\n\n if (remaining <= 0) {\n handleTimeout();\n return undefined;\n }\n\n const timerId: any = setTimeout(() => {\n handleTimeout();\n }, remaining * 1000);\n\n return () => clearTimeout(timerId);\n }, [additionalData?.['stepTimeout'], isFlowInitialized, t]);\n\n /**\n * Handle form submission from BaseSignIn or render props.\n */\n const handleSubmit = async (payload: EmbeddedSignInFlowRequest): Promise<void> => {\n // Use executionId from payload if available, otherwise fall back to currentExecutionId\n const effectiveExecutionId: any = payload.executionId || currentExecutionId;\n\n if (!effectiveExecutionId) {\n throw new Error('No active flow ID');\n }\n\n const processedInputs: Record<string, any> = {...payload.inputs};\n\n // Auto-compile consent decisions if we are currently on a consent prompt step\n if (additionalData?.['consentPrompt']) {\n try {\n const consentPromptRawData: any = additionalData['consentPrompt'];\n const purposes: any[] =\n typeof consentPromptRawData === 'string'\n ? JSON.parse(consentPromptRawData)\n : consentPromptRawData.purposes || consentPromptRawData;\n\n // Find the action component to determine if it was a deny action\n let isDeny = false;\n if (payload.action) {\n // Flatten components to find the action\n const findAction = (comps: any[]): any => {\n if (!comps || comps.length === 0) return null;\n\n const found: any = comps.find((c: any) => c.id === payload.action);\n if (found) return found;\n\n return comps.reduce((acc: any, c: any) => {\n if (acc) return acc;\n if (c.components) return findAction(c.components);\n return null;\n }, null);\n };\n\n const submitAction: any = findAction(components);\n\n if (submitAction && submitAction.variant?.toLowerCase() !== 'primary') {\n isDeny = true;\n }\n }\n\n const decisions: any = {\n purposes: purposes.map((p: any) => ({\n approved: !isDeny,\n elements: [\n ...(p.essential || []).map((e: any) => ({\n approved: !isDeny,\n name: e.name,\n })),\n ...(p.optional || []).map((e: any) => {\n const key = `__consent_opt__${p.purposeId}__${e.name}`;\n return {\n approved: isDeny ? false : processedInputs[key] !== 'false',\n name: e.name,\n };\n }),\n ],\n purposeName: p.purposeName,\n })),\n };\n processedInputs['consent_decisions'] = JSON.stringify(decisions);\n\n // Cleanup temporary consent tracking fields from inputs\n Object.keys(processedInputs).forEach((key: string) => {\n if (key.startsWith('__consent_opt__')) {\n delete processedInputs[key];\n }\n });\n } catch (e) {\n // Failed to construct consent_decisions payload automatically\n }\n }\n\n try {\n setIsSubmitting(true);\n setFlowError(null);\n // Clear any field errors from the previous response before the new round-trip.\n setServerFieldErrors(null);\n\n const response: EmbeddedSignInFlowResponse = (await signIn({\n executionId: effectiveExecutionId,\n ...payload,\n inputs: processedInputs,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n })) as EmbeddedSignInFlowResponse;\n\n if (await handleRedirection(response)) {\n return;\n }\n if (\n response.data?.additionalData?.['passkeyChallenge'] ||\n response.data?.additionalData?.['passkeyCreationOptions']\n ) {\n const {passkeyChallenge, passkeyCreationOptions}: any = response.data.additionalData;\n const effectiveExecutionIdForPasskey: any = response.executionId || effectiveExecutionId;\n\n // Reset passkey processed ref to allow processing\n passkeyProcessedRef.current = false;\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Set passkey state to trigger the passkey\n setPasskeyState({\n actionId: 'submit',\n challenge: passkeyChallenge,\n creationOptions: passkeyCreationOptions,\n error: null,\n executionId: effectiveExecutionIdForPasskey,\n isActive: true,\n });\n setIsSubmitting(false);\n\n return;\n }\n\n const {\n executionId: normalizedExecutionId,\n components: normalizedComponents,\n additionalData: normalizedAdditionalData,\n } = normalizeFlowResponse(\n response,\n t,\n {\n resolveTranslations: false,\n },\n meta,\n );\n\n // Handle terminal flow statuses (Error throws, Complete redirects and returns true).\n if (await handleTerminalResponse(response)) {\n return;\n }\n\n // Always update challenge token on any INCOMPLETE response — token rotates every step.\n await setChallengeToken(response.challengeToken ?? null);\n\n // Update executionId if response contains a new one\n if (normalizedExecutionId && normalizedComponents) {\n setExecutionId(normalizedExecutionId);\n setComponents(normalizedComponents);\n setAdditionalData(normalizedAdditionalData ?? {});\n setIsTimeoutDisabled(false);\n // Ensure flow is marked as initialized when we have components\n setIsFlowInitialized(true);\n // Clean up executionId from URL after setting it in state\n cleanupFlowUrlParams();\n\n // Surface server-side validation failures so BaseSignIn can inject them into\n // the form-level fieldErrors state used by the render-prop / default UI.\n const responseFieldErrors: FieldError[] | undefined = (response.data as any)?.fieldErrors;\n if (responseFieldErrors && responseFieldErrors.length > 0) {\n setServerFieldErrors(responseFieldErrors);\n }\n\n // Display error from INCOMPLETE response\n if ((response as any)?.error) {\n setFlowError(new Error(extractErrorMessage(response, t)));\n }\n }\n } catch (error) {\n const err: any = error;\n await clearFlowState();\n\n setError(err instanceof ThunderIDRuntimeError ? err : new Error(extractErrorMessage(err, t)));\n return;\n } finally {\n setIsSubmitting(false);\n }\n };\n\n /**\n * Handle authentication errors.\n */\n const handleError = (error: Error): void => {\n setError(error);\n };\n\n useOAuthCallback({\n currentExecutionId,\n isInitialized: isInitialized && !isLoading && isStorageReady,\n isSubmitting,\n onError: (err: any) => {\n clearFlowState();\n setError(err instanceof Error ? err : new Error(String(err)));\n },\n onSubmit: async (payload: any) => handleSubmit({executionId: payload.executionId, inputs: payload.inputs}),\n processedRef: oauthCodeProcessedRef,\n setExecutionId,\n });\n\n /**\n * Handle passkey authentication/registration when passkey state becomes active.\n * This effect auto-triggers the browser passkey popup and submits the result.\n */\n useEffect(() => {\n if (\n !passkeyState.isActive ||\n (!passkeyState.challenge && !passkeyState.creationOptions) ||\n !passkeyState.executionId\n ) {\n return;\n }\n\n // Prevent re-processing\n if (passkeyProcessedRef.current) {\n return;\n }\n passkeyProcessedRef.current = true;\n\n const performPasskeyProcess = async (): Promise<void> => {\n let inputs: Record<string, string>;\n\n if (passkeyState.challenge) {\n const passkeyResponse: any = await handlePasskeyAuthentication(passkeyState.challenge);\n const passkeyResponseObj: any = JSON.parse(passkeyResponse);\n\n inputs = {\n authenticatorData: passkeyResponseObj.response.authenticatorData,\n clientDataJSON: passkeyResponseObj.response.clientDataJSON,\n credentialId: passkeyResponseObj.id,\n signature: passkeyResponseObj.response.signature,\n userHandle: passkeyResponseObj.response.userHandle,\n };\n } else if (passkeyState.creationOptions) {\n const passkeyResponse: any = await handlePasskeyRegistration(passkeyState.creationOptions);\n const passkeyResponseObj: any = JSON.parse(passkeyResponse);\n\n inputs = {\n attestationObject: passkeyResponseObj.response.attestationObject,\n clientDataJSON: passkeyResponseObj.response.clientDataJSON,\n credentialId: passkeyResponseObj.id,\n };\n } else {\n throw new Error('No passkey challenge or creation options available');\n }\n\n await handleSubmit({\n executionId: passkeyState.executionId ?? undefined,\n inputs,\n });\n };\n\n performPasskeyProcess()\n .then(() => {\n setPasskeyState({\n actionId: null,\n challenge: null,\n creationOptions: null,\n error: null,\n executionId: null,\n isActive: false,\n });\n })\n .catch((error: any) => {\n setPasskeyState((prev: any) => ({...prev, error: error as Error, isActive: false}));\n setFlowError(error as Error);\n onError?.(error as Error);\n });\n }, [passkeyState.isActive, passkeyState.challenge, passkeyState.creationOptions, passkeyState.executionId]);\n\n if (children) {\n // Collapse the server FieldError[] array to a single message per field map for\n // render-prop consumers. First error per field wins. Multi-error cases per\n // field are rare in practice (server typically returns one rule failure per\n // field in current flows) and consumers needing the full array can still read\n // it from the raw flow response.\n const renderPropFieldErrors: Record<string, string> = {};\n if (serverFieldErrors) {\n for (const fe of serverFieldErrors) {\n if (!(fe.identifier in renderPropFieldErrors)) {\n renderPropFieldErrors[fe.identifier] = fe.message;\n }\n }\n }\n\n const renderProps: SignInRenderProps = {\n additionalData,\n components,\n error: flowError,\n fieldErrors: renderPropFieldErrors,\n initialize: initializeFlow,\n isInitialized: isFlowInitialized,\n isLoading: isLoading || isSubmitting || !isInitialized,\n isTimeoutDisabled,\n meta,\n onSubmit: handleSubmit,\n };\n\n return <>{children(renderProps)}</>;\n }\n // Otherwise, render the default BaseSignIn component\n return (\n <BaseSignIn\n additionalData={additionalData}\n components={components}\n isLoading={isLoading || !isInitialized || !isFlowInitialized}\n isTimeoutDisabled={isTimeoutDisabled}\n onSubmit={handleSubmit}\n onError={handleError}\n error={flowError}\n className={className}\n size={size}\n variant={variant}\n preferences={preferences}\n serverFieldErrors={serverFieldErrors}\n />\n );\n};\n\nexport default SignIn;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SignIn.js","names":["SignIn: FC<SignInProps>","useThunderID","useTranslation","challengeTokenRef: any","initializationAttemptedRef: any","oauthCodeProcessedRef: any","passkeyProcessedRef: any","tempData: any","storageManager: any","urlParams: any","url: any","redirectURL: any","err: any","finalRedirectUrl: any","effectiveApplicationId: any","storedExecutionId: any","resumeExecutionId: any","error: any","response: EmbeddedSignInFlowResponse","currentUrlParams: any","timeoutMs: number","remaining: number","errorMessage: string","timerId: any","effectiveExecutionId: any","processedInputs: Record<string, any>","consentPromptRawData: any","purposes: any[]","found: any","submitAction: any","decisions: any","effectiveExecutionIdForPasskey: any","responseFieldErrors: FieldError[] | undefined","inputs: Record<string, string>","passkeyResponse: any","passkeyResponseObj: any","renderPropFieldErrors: Record<string, string>","BaseSignIn"],"sources":["../../../../../src/components/presentation/auth/SignIn/SignIn.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025-2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {\n ThunderIDRuntimeError,\n ThunderIDAPIError,\n EmbeddedFlowComponent,\n EmbeddedFlowType,\n EmbeddedSignInFlowResponse,\n EmbeddedSignInFlowRequest,\n EmbeddedSignInFlowStatus,\n EmbeddedSignInFlowType,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n logger,\n} from '@thunderid/browser';\nimport {FC, ReactElement, useState, useEffect, useRef, ReactNode} from 'react';\n// eslint-disable-next-line import/no-named-as-default\nimport BaseSignIn, {BaseSignInProps} from './BaseSignIn';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\nimport {useOAuthCallback} from '../../../../hooks/useOAuthCallback';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {extractErrorMessage, normalizeFlowResponse} from '../../../../utils/flowTransformer';\nimport {initiateOAuthRedirect} from '../../../../utils/oauth';\nimport {handlePasskeyAuthentication, handlePasskeyRegistration} from '../../../../utils/passkey';\n\n/**\n * Render props function parameters\n */\nexport interface SignInRenderProps {\n /**\n * Additional data from the flow response containing contextual information\n * like consent prompt details and session timeouts.\n */\n additionalData?: Record<string, any>;\n\n /**\n * Current flow components\n */\n components: EmbeddedFlowComponent[];\n\n /**\n * Current error if any\n */\n error: Error | null;\n\n /**\n * Server-side field-level validation errors from the most recent flow response,\n * collapsed to one message per field (first error wins). Empty when no validation\n * failures are active. Render-prop consumers should display these alongside their\n * own client-side validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Function to manually initialize the flow\n */\n initialize: () => Promise<void>;\n\n /**\n * Whether the flow has been initialized\n */\n isInitialized: boolean;\n\n /**\n * Loading state indicator\n */\n isLoading: boolean;\n\n /**\n * Flag indicating whether the flow step timeout has expired.\n * Consuming components can use this to disable submit buttons.\n */\n isTimeoutDisabled?: 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 * Function to submit authentication data (primary)\n */\n onSubmit: (payload: EmbeddedSignInFlowRequest) => Promise<void>;\n}\n\n/**\n * Props for the SignIn component.\n * Matches the interface from the main SignIn component for consistency.\n */\nexport interface SignInProps {\n /**\n * Render props function for custom UI\n */\n children?: (props: SignInRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name for the form container.\n */\n className?: string;\n\n /**\n * Callback function called when authentication fails.\n * @param error - The error that occurred during authentication.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback function called when authentication is successful.\n * @param authData - The authentication data returned upon successful completion.\n */\n onSuccess?: (authData: Record<string, any>) => void;\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 * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: BaseSignInProps['variant'];\n}\n\n/**\n * State for tracking passkey registration\n */\ninterface PasskeyState {\n actionId: string | null;\n challenge: string | null;\n creationOptions: string | null;\n error: Error | null;\n executionId: string | null;\n isActive: boolean;\n}\n\n/**\n * A component-driven SignIn component that provides authentication flow with pre-built styling.\n * This component handles the flow API calls for authentication and delegates UI logic to BaseSignIn.\n * It automatically transforms simple input-based responses into component-driven UI format.\n *\n * @example\n * // Default UI\n * ```tsx\n * import { SignIn } from '@thunderid/react/component-driven';\n *\n * const App = () => {\n * return (\n * <SignIn\n * onSuccess={(authData) => {\n * console.log('Authentication successful:', authData);\n * }}\n * onError={(error) => {\n * console.error('Authentication failed:', error);\n * }}\n * size=\"medium\"\n * variant=\"outlined\"\n * />\n * );\n * };\n * ```\n *\n * @example\n * // Custom UI with render props\n * ```tsx\n * import { SignIn } from '@thunderid/react/component-driven';\n *\n * const App = () => {\n * return (\n * <SignIn\n * onSuccess={(authData) => console.log('Success:', authData)}\n * onError={(error) => console.error('Error:', error)}\n * >\n * {({signIn, isLoading, components, error, isInitialized}) => (\n * <div className=\"custom-signin\">\n * <h1>Custom Sign In</h1>\n * {!isInitialized ? (\n * <p>Initializing...</p>\n * ) : error ? (\n * <div className=\"error\">{error.message}</div>\n * ) : (\n * <form onSubmit={(e) => {\n * e.preventDefault();\n * signIn({inputs: {username: 'user', password: 'pass'}});\n * }}>\n * <button type=\"submit\" disabled={isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign In'}\n * </button>\n * </form>\n * )}\n * </div>\n * )}\n * </SignIn>\n * );\n * };\n * ```\n */\nconst SignIn: FC<SignInProps> = ({\n className,\n preferences,\n size = 'medium',\n onSuccess,\n onError,\n variant,\n children,\n}: SignInProps): ReactElement => {\n const {applicationId, afterSignInUrl, signIn, isInitialized, isLoading, meta, getStorageManager, scopes, vendor} =\n useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n\n // State management for the flow\n const [components, setComponents] = useState<EmbeddedFlowComponent[]>([]);\n const [additionalData, setAdditionalData] = useState<Record<string, any>>({});\n // Server-side validation errors from the most recent flow response. Updated on every\n // submission; cleared when the next submission begins so stale errors don't linger.\n const [serverFieldErrors, setServerFieldErrors] = useState<FieldError[] | null>(null);\n const [currentExecutionId, setCurrentExecutionId] = useState<string | null>(null);\n const challengeTokenRef: any = useRef<string | null>(null);\n const [isStorageReady, setIsStorageReady] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [flowError, setFlowError] = useState<Error | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isTimeoutDisabled, setIsTimeoutDisabled] = useState<boolean>(false);\n const [passkeyState, setPasskeyState] = useState<PasskeyState>({\n actionId: null,\n challenge: null,\n creationOptions: null,\n error: null,\n executionId: null,\n isActive: false,\n });\n const initializationAttemptedRef: any = useRef(false);\n const oauthCodeProcessedRef: any = useRef(false);\n const passkeyProcessedRef: any = useRef(false);\n /**\n * Sets executionId between sessionStorage and state.\n * This ensures both are always in sync.\n */\n const setExecutionId = (executionId: string | null): void => {\n setCurrentExecutionId(executionId);\n if (executionId) {\n sessionStorage.setItem(`${vendor}_execution_id`, executionId);\n } else {\n sessionStorage.removeItem(`${vendor}_execution_id`);\n }\n };\n\n /**\n * Restore any challenge token persisted before an OAuth redirect.\n * Waits for SDK initialization before reading from storage.\n */\n useEffect(() => {\n if (!isInitialized) 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 } finally {\n setIsStorageReady(true);\n }\n })();\n }, [isInitialized]);\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 * Clear all flow-related storage and state.\n */\n const clearFlowState = async (): Promise<void> => {\n setExecutionId(null);\n await setChallengeToken(null);\n setIsFlowInitialized(false);\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.removeHybridDataParameter?.('authId');\n } catch {\n logger.warn('Failed to clear authId from hybrid storage.');\n }\n setIsTimeoutDisabled(false);\n // Reset refs to allow new flows to start properly\n oauthCodeProcessedRef.current = false;\n };\n\n /**\n * Parse URL parameters used in flows.\n */\n const getUrlParams = (): any => {\n const urlParams: any = new URL(window?.location?.href ?? '').searchParams;\n\n return {\n applicationId: urlParams.get('applicationId'),\n authId: urlParams.get('authId'),\n code: urlParams.get('code'),\n error: urlParams.get('error'),\n errorDescription: urlParams.get('error_description'),\n executionId: urlParams.get('executionId'),\n nonce: urlParams.get('nonce'),\n state: urlParams.get('state'),\n };\n };\n\n /**\n * Handle authId from URL and persist it via the storage manager so it survives URL cleanup.\n * ThunderIDReactClient.signIn() reads authId from storageManager.getHybridDataParameter('authId'),\n * not from raw sessionStorage, so we must use the same storage path here.\n */\n const handleAuthId = async (authId: string | null): Promise<void> => {\n if (authId) {\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.setHybridDataParameter?.('authId', authId);\n } catch {\n logger.warn('Failed to store authId in hybrid storage.');\n }\n }\n };\n\n /**\n * Clean up OAuth-related URL parameters from the browser URL.\n */\n const cleanupOAuthUrlParams = (includeNonce = false): void => {\n if (!window?.location?.href) return;\n const url: any = new URL(window.location.href);\n url.searchParams.delete('error');\n url.searchParams.delete('error_description');\n url.searchParams.delete('code');\n url.searchParams.delete('state');\n if (includeNonce) {\n url.searchParams.delete('nonce');\n }\n window?.history?.replaceState({}, '', url.toString());\n };\n\n /**\n * Clean up flow-related URL parameters (executionId, authId) from the browser URL.\n * Used after executionId is set in state to prevent using invalidated executionId from URL.\n */\n const cleanupFlowUrlParams = (): void => {\n if (!window?.location?.href) return;\n const url: any = new URL(window.location.href);\n url.searchParams.delete('executionId');\n url.searchParams.delete('authId');\n url.searchParams.delete('applicationId');\n window?.history?.replaceState({}, '', url.toString());\n };\n\n /**\n * Set error state and call onError callback.\n * Ensures isFlowInitialized is true so errors can be displayed in the UI.\n */\n const setError = (error: Error): void => {\n setFlowError(error);\n setIsFlowInitialized(true);\n onError?.(error);\n };\n\n /**\n * Handle OAuth error from URL parameters.\n * Clears flow state, creates error, and cleans up URL.\n */\n const handleOAuthError = (error: string, errorDescription: string | null): void => {\n clearFlowState();\n const errorMessage: any = errorDescription || `OAuth error: ${error}`;\n const err: any = new ThunderIDRuntimeError(errorMessage, 'SIGN_IN_ERROR', 'react');\n setError(err);\n cleanupOAuthUrlParams(true);\n };\n\n /**\n * Handle REDIRECTION response by storing flow state and redirecting to OAuth provider.\n */\n const handleRedirection = async (response: EmbeddedSignInFlowResponse): Promise<boolean> => {\n if (response.type === EmbeddedSignInFlowType.Redirection) {\n const redirectURL: any = (response.data as any)?.redirectURL || (response as any)?.redirectURL;\n\n if (redirectURL && window?.location) {\n if (response.executionId) {\n setExecutionId(response.executionId);\n }\n await setChallengeToken(response.challengeToken ?? null);\n\n const urlParams: any = getUrlParams();\n await handleAuthId(urlParams.authId);\n\n initiateOAuthRedirect(redirectURL, vendor);\n return true;\n }\n }\n return false;\n };\n\n /**\n * Handle terminal flow responses (Error and Complete) shared by initializeFlow and handleSubmit.\n * Throws on an Error status so the caller's catch block can propagate it to BaseSignIn.\n * Returns true when a Complete status was handled (caller should return), false otherwise.\n */\n const handleTerminalResponse = async (response: EmbeddedSignInFlowResponse): Promise<boolean> => {\n // Handle Error flow status - flow has failed and is invalidated\n if (response.flowStatus === EmbeddedSignInFlowStatus.Error) {\n await clearFlowState();\n const err: any = new Error(extractErrorMessage(response, t));\n setError(err);\n cleanupFlowUrlParams();\n // Throw the error so it's caught by the catch block and propagated to BaseSignIn\n throw err;\n }\n\n if (response.flowStatus === EmbeddedSignInFlowStatus.Complete) {\n // Get redirectUrl from response (from /oauth2/auth/callback) or fall back to afterSignInUrl\n const redirectUrl: any = (response as any)?.redirectUrl || (response as any)?.redirect_uri;\n const finalRedirectUrl: any = redirectUrl || afterSignInUrl;\n\n // Clear submitting state before redirect\n setIsSubmitting(false);\n\n // Clear all OAuth-related storage on successful completion\n setExecutionId(null);\n await setChallengeToken(null);\n setIsFlowInitialized(false);\n sessionStorage.removeItem(`${vendor}_execution_id`);\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.removeHybridDataParameter?.('authId');\n } catch {\n logger.warn('Failed to clear authId from hybrid storage after completion.');\n }\n\n // Clean up OAuth URL params before redirect\n cleanupOAuthUrlParams(true);\n\n if (onSuccess) {\n onSuccess({\n redirectUrl: finalRedirectUrl,\n ...(response.data || {}),\n });\n }\n\n if (finalRedirectUrl && window?.location) {\n window.location.href = finalRedirectUrl;\n }\n\n return true;\n }\n\n return false;\n };\n\n /**\n * Initialize the authentication flow.\n * Priority: executionId > applicationId (from context) > applicationId (from URL)\n */\n const initializeFlow = async (): Promise<void> => {\n const urlParams: any = getUrlParams();\n\n // Reset OAuth code processed ref when starting a new flow\n oauthCodeProcessedRef.current = false;\n // Clear stale serverFieldErrors so the new flow doesn't inherit them via render-prop.\n setServerFieldErrors(null);\n\n await handleAuthId(urlParams.authId);\n\n const effectiveApplicationId: any = applicationId || urlParams.applicationId;\n\n // On a page refresh the executionId is no longer in the URL (it is scrubbed by\n // cleanupFlowUrlParams after the first load). Fall back to the executionId persisted in\n // sessionStorage so the in-progress flow can be resumed instead of starting a new flow.\n // This is required for authorization_code apps where direct new-flow initiation is blocked\n // server-side and the flow must be initiated through the OAuth /authorize endpoint.\n const storedExecutionId: any = !urlParams.executionId ? sessionStorage.getItem(`${vendor}_execution_id`) : null;\n const resumeExecutionId: any = urlParams.executionId || storedExecutionId;\n\n if (!resumeExecutionId && !effectiveApplicationId) {\n const error: any = new ThunderIDRuntimeError(\n 'Either executionId or applicationId is required for authentication',\n 'SIGN_IN_ERROR',\n 'react',\n );\n setError(error);\n throw error;\n }\n\n try {\n setFlowError(null);\n\n let response: EmbeddedSignInFlowResponse;\n\n if (resumeExecutionId) {\n try {\n response = (await signIn({\n executionId: resumeExecutionId,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n })) as EmbeddedSignInFlowResponse;\n } catch (resumeError) {\n // Only treat a stale/expired session (HTTP 400 from the server, meaning the stored\n // executionId is no longer valid) as a recoverable condition. Transient failures\n // such as 5xx server errors or network errors are rethrown so they surface correctly.\n const isStaleSession: boolean =\n storedExecutionId &&\n resumeExecutionId === storedExecutionId &&\n resumeError instanceof ThunderIDAPIError &&\n resumeError.statusCode === 400;\n\n if (isStaleSession) {\n setExecutionId(null);\n try {\n const storageManager: any = await getStorageManager();\n await storageManager?.removeHybridDataParameter?.('authId');\n } catch {\n logger.warn('Failed to clear authId from hybrid storage.');\n }\n if (!effectiveApplicationId) {\n const expiredError: any = new ThunderIDRuntimeError(\n t('errors.signin.session.expired') ||\n 'Your session has expired. Please return to the application and sign in again.',\n 'SIGN_IN_ERROR',\n 'react',\n );\n setError(expiredError);\n return;\n }\n response = (await signIn({\n applicationId: effectiveApplicationId,\n flowType: EmbeddedFlowType.Authentication,\n ...(scopes && {scopes}),\n })) as EmbeddedSignInFlowResponse;\n } else {\n throw resumeError;\n }\n }\n } else {\n response = (await signIn({\n applicationId: effectiveApplicationId,\n flowType: EmbeddedFlowType.Authentication,\n ...(scopes && {scopes}),\n })) as EmbeddedSignInFlowResponse;\n }\n\n if (await handleRedirection(response)) {\n return;\n }\n\n // Handle a flow that completes (or errors) on the very first step — e.g. a reused SSO\n // session lets the backend return COMPLETE immediately with no UI components. Without\n // this the UI would fall through with no components and spin forever.\n if (await handleTerminalResponse(response)) {\n return;\n }\n\n const {\n executionId: normalizedExecutionId,\n components: normalizedComponents,\n additionalData: normalizedAdditionalData,\n } = normalizeFlowResponse(\n response,\n t,\n {\n resolveTranslations: false,\n },\n meta,\n );\n\n await setChallengeToken(response.challengeToken ?? null);\n\n if (normalizedExecutionId && normalizedComponents) {\n setExecutionId(normalizedExecutionId);\n setComponents(normalizedComponents);\n setAdditionalData(normalizedAdditionalData ?? {});\n setIsFlowInitialized(true);\n setIsTimeoutDisabled(false);\n // Clean up executionId from URL after setting it in state\n cleanupFlowUrlParams();\n }\n } catch (error) {\n const err: any = error;\n await clearFlowState();\n\n setError(err instanceof ThunderIDRuntimeError ? err : new Error(extractErrorMessage(err, t)));\n initializationAttemptedRef.current = false;\n }\n };\n\n /**\n * Initialize the flow and handle cleanup of stale flow state.\n */\n useEffect(() => {\n const urlParams: any = getUrlParams();\n\n // Check for OAuth error in URL\n if (urlParams.error) {\n handleOAuthError(urlParams.error, urlParams.errorDescription);\n return;\n }\n\n handleAuthId(urlParams.authId);\n\n // Skip OAuth code processing - let the dedicated OAuth useEffect handle it\n // No action needed here as the dedicated useEffect will handle it\n }, []);\n\n useEffect(() => {\n // Only initialize if we're not processing an OAuth callback or submission.\n // Wait for isStorageReady so the challenge token is restored from storage before\n // we attempt to resume a persisted executionId — the server requires it.\n const currentUrlParams: any = getUrlParams();\n if (\n isInitialized &&\n isStorageReady &&\n !isLoading &&\n !isFlowInitialized &&\n !initializationAttemptedRef.current &&\n !currentExecutionId &&\n !currentUrlParams.code &&\n !currentUrlParams.state &&\n !isSubmitting &&\n !oauthCodeProcessedRef.current\n ) {\n initializationAttemptedRef.current = true;\n initializeFlow();\n }\n }, [isInitialized, isStorageReady, isLoading, isFlowInitialized, currentExecutionId]);\n\n /**\n * Handle step timeout if configured in additionalData.\n */\n useEffect(() => {\n const timeoutMs: number = Number(additionalData?.['stepTimeout']) || 0;\n if (timeoutMs <= 0 || !isFlowInitialized) {\n setIsTimeoutDisabled(false);\n return undefined;\n }\n\n const remaining: number = Math.max(0, Math.floor((timeoutMs - Date.now()) / 1000));\n\n const handleTimeout = (): void => {\n const errorMessage: string = t('errors.signin.timeout') || 'Time allowed to complete the step has expired.';\n setError(new Error(errorMessage));\n setIsTimeoutDisabled(true);\n };\n\n if (remaining <= 0) {\n handleTimeout();\n return undefined;\n }\n\n const timerId: any = setTimeout(() => {\n handleTimeout();\n }, remaining * 1000);\n\n return () => clearTimeout(timerId);\n }, [additionalData?.['stepTimeout'], isFlowInitialized, t]);\n\n /**\n * Handle form submission from BaseSignIn or render props.\n */\n const handleSubmit = async (payload: EmbeddedSignInFlowRequest): Promise<void> => {\n // Use executionId from payload if available, otherwise fall back to currentExecutionId\n const effectiveExecutionId: any = payload.executionId || currentExecutionId;\n\n if (!effectiveExecutionId) {\n throw new Error('No active flow ID');\n }\n\n const processedInputs: Record<string, any> = {...payload.inputs};\n\n // Auto-compile consent decisions if we are currently on a consent prompt step\n if (additionalData?.['consentPrompt']) {\n try {\n const consentPromptRawData: any = additionalData['consentPrompt'];\n const purposes: any[] =\n typeof consentPromptRawData === 'string'\n ? JSON.parse(consentPromptRawData)\n : consentPromptRawData.purposes || consentPromptRawData;\n\n // Find the action component to determine if it was a deny action\n let isDeny = false;\n if (payload.action) {\n // Flatten components to find the action\n const findAction = (comps: any[]): any => {\n if (!comps || comps.length === 0) return null;\n\n const found: any = comps.find((c: any) => c.id === payload.action);\n if (found) return found;\n\n return comps.reduce((acc: any, c: any) => {\n if (acc) return acc;\n if (c.components) return findAction(c.components);\n return null;\n }, null);\n };\n\n const submitAction: any = findAction(components);\n\n if (submitAction && submitAction.variant?.toLowerCase() !== 'primary') {\n isDeny = true;\n }\n }\n\n const decisions: any = {\n purposes: purposes.map((p: any) => ({\n approved: !isDeny,\n elements: [\n ...(p.essential || []).map((e: any) => ({\n approved: !isDeny,\n name: e.name,\n })),\n ...(p.optional || []).map((e: any) => {\n const key = `__consent_opt__${p.purposeId}__${e.name}`;\n return {\n approved: isDeny ? false : processedInputs[key] !== 'false',\n name: e.name,\n };\n }),\n ],\n purposeName: p.purposeName,\n })),\n };\n processedInputs['consent_decisions'] = JSON.stringify(decisions);\n\n // Cleanup temporary consent tracking fields from inputs\n Object.keys(processedInputs).forEach((key: string) => {\n if (key.startsWith('__consent_opt__')) {\n delete processedInputs[key];\n }\n });\n } catch (e) {\n // Failed to construct consent_decisions payload automatically\n }\n }\n\n try {\n setIsSubmitting(true);\n setFlowError(null);\n // Clear any field errors from the previous response before the new round-trip.\n setServerFieldErrors(null);\n\n const response: EmbeddedSignInFlowResponse = (await signIn({\n executionId: effectiveExecutionId,\n ...payload,\n inputs: processedInputs,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n })) as EmbeddedSignInFlowResponse;\n\n if (await handleRedirection(response)) {\n return;\n }\n if (\n response.data?.additionalData?.['passkeyChallenge'] ||\n response.data?.additionalData?.['passkeyCreationOptions']\n ) {\n const {passkeyChallenge, passkeyCreationOptions}: any = response.data.additionalData;\n const effectiveExecutionIdForPasskey: any = response.executionId || effectiveExecutionId;\n\n // Reset passkey processed ref to allow processing\n passkeyProcessedRef.current = false;\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Set passkey state to trigger the passkey\n setPasskeyState({\n actionId: 'submit',\n challenge: passkeyChallenge,\n creationOptions: passkeyCreationOptions,\n error: null,\n executionId: effectiveExecutionIdForPasskey,\n isActive: true,\n });\n setIsSubmitting(false);\n\n return;\n }\n\n const {\n executionId: normalizedExecutionId,\n components: normalizedComponents,\n additionalData: normalizedAdditionalData,\n } = normalizeFlowResponse(\n response,\n t,\n {\n resolveTranslations: false,\n },\n meta,\n );\n\n // Handle terminal flow statuses (Error throws, Complete redirects and returns true).\n if (await handleTerminalResponse(response)) {\n return;\n }\n\n // Always update challenge token on any INCOMPLETE response — token rotates every step.\n await setChallengeToken(response.challengeToken ?? null);\n\n // Update executionId if response contains a new one\n if (normalizedExecutionId && normalizedComponents) {\n setExecutionId(normalizedExecutionId);\n setComponents(normalizedComponents);\n setAdditionalData(normalizedAdditionalData ?? {});\n setIsTimeoutDisabled(false);\n // Ensure flow is marked as initialized when we have components\n setIsFlowInitialized(true);\n // Clean up executionId from URL after setting it in state\n cleanupFlowUrlParams();\n\n // Surface server-side validation failures so BaseSignIn can inject them into\n // the form-level fieldErrors state used by the render-prop / default UI.\n const responseFieldErrors: FieldError[] | undefined = (response.data as any)?.fieldErrors;\n if (responseFieldErrors && responseFieldErrors.length > 0) {\n setServerFieldErrors(responseFieldErrors);\n }\n\n // Display error from INCOMPLETE response\n if ((response as any)?.error) {\n setFlowError(new Error(extractErrorMessage(response, t)));\n }\n }\n } catch (error) {\n const err: any = error;\n await clearFlowState();\n\n setError(err instanceof ThunderIDRuntimeError ? err : new Error(extractErrorMessage(err, t)));\n return;\n } finally {\n setIsSubmitting(false);\n }\n };\n\n /**\n * Handle authentication errors.\n */\n const handleError = (error: Error): void => {\n setError(error);\n };\n\n useOAuthCallback({\n currentExecutionId,\n executionIdStorageKey: `${vendor}_execution_id`,\n isInitialized: isInitialized && !isLoading && isStorageReady,\n isSubmitting,\n onError: (err: any) => {\n clearFlowState();\n setError(err instanceof Error ? err : new Error(String(err)));\n },\n onSubmit: async (payload: any) => handleSubmit({executionId: payload.executionId, inputs: payload.inputs}),\n processedRef: oauthCodeProcessedRef,\n setExecutionId,\n });\n\n /**\n * Handle passkey authentication/registration when passkey state becomes active.\n * This effect auto-triggers the browser passkey popup and submits the result.\n */\n useEffect(() => {\n if (\n !passkeyState.isActive ||\n (!passkeyState.challenge && !passkeyState.creationOptions) ||\n !passkeyState.executionId\n ) {\n return;\n }\n\n // Prevent re-processing\n if (passkeyProcessedRef.current) {\n return;\n }\n passkeyProcessedRef.current = true;\n\n const performPasskeyProcess = async (): Promise<void> => {\n let inputs: Record<string, string>;\n\n if (passkeyState.challenge) {\n const passkeyResponse: any = await handlePasskeyAuthentication(passkeyState.challenge);\n const passkeyResponseObj: any = JSON.parse(passkeyResponse);\n\n inputs = {\n authenticatorData: passkeyResponseObj.response.authenticatorData,\n clientDataJSON: passkeyResponseObj.response.clientDataJSON,\n credentialId: passkeyResponseObj.id,\n signature: passkeyResponseObj.response.signature,\n userHandle: passkeyResponseObj.response.userHandle,\n };\n } else if (passkeyState.creationOptions) {\n const passkeyResponse: any = await handlePasskeyRegistration(passkeyState.creationOptions);\n const passkeyResponseObj: any = JSON.parse(passkeyResponse);\n\n inputs = {\n attestationObject: passkeyResponseObj.response.attestationObject,\n clientDataJSON: passkeyResponseObj.response.clientDataJSON,\n credentialId: passkeyResponseObj.id,\n };\n } else {\n throw new Error('No passkey challenge or creation options available');\n }\n\n await handleSubmit({\n executionId: passkeyState.executionId ?? undefined,\n inputs,\n });\n };\n\n performPasskeyProcess()\n .then(() => {\n setPasskeyState({\n actionId: null,\n challenge: null,\n creationOptions: null,\n error: null,\n executionId: null,\n isActive: false,\n });\n })\n .catch((error: any) => {\n setPasskeyState((prev: any) => ({...prev, error: error as Error, isActive: false}));\n setFlowError(error as Error);\n onError?.(error as Error);\n });\n }, [passkeyState.isActive, passkeyState.challenge, passkeyState.creationOptions, passkeyState.executionId]);\n\n if (children) {\n // Collapse the server FieldError[] array to a single message per field map for\n // render-prop consumers. First error per field wins. Multi-error cases per\n // field are rare in practice (server typically returns one rule failure per\n // field in current flows) and consumers needing the full array can still read\n // it from the raw flow response.\n const renderPropFieldErrors: Record<string, string> = {};\n if (serverFieldErrors) {\n for (const fe of serverFieldErrors) {\n if (!(fe.identifier in renderPropFieldErrors)) {\n renderPropFieldErrors[fe.identifier] = fe.message;\n }\n }\n }\n\n const renderProps: SignInRenderProps = {\n additionalData,\n components,\n error: flowError,\n fieldErrors: renderPropFieldErrors,\n initialize: initializeFlow,\n isInitialized: isFlowInitialized,\n isLoading: isLoading || isSubmitting || !isInitialized,\n isTimeoutDisabled,\n meta,\n onSubmit: handleSubmit,\n };\n\n return <>{children(renderProps)}</>;\n }\n // Otherwise, render the default BaseSignIn component\n return (\n <BaseSignIn\n additionalData={additionalData}\n components={components}\n isLoading={isLoading || !isInitialized || !isFlowInitialized}\n isTimeoutDisabled={isTimeoutDisabled}\n onSubmit={handleSubmit}\n onError={handleError}\n error={flowError}\n className={className}\n size={size}\n variant={variant}\n preferences={preferences}\n serverFieldErrors={serverFieldErrors}\n />\n );\n};\n\nexport default SignIn;\n"],"mappings":"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"}
|
|
@@ -109,6 +109,10 @@ export interface BaseSignUpProps {
|
|
|
109
109
|
* Custom CSS class name for error messages.
|
|
110
110
|
*/
|
|
111
111
|
errorClassName?: string;
|
|
112
|
+
/**
|
|
113
|
+
* HTML id attribute for the form container.
|
|
114
|
+
*/
|
|
115
|
+
id?: string;
|
|
112
116
|
/**
|
|
113
117
|
* Custom CSS class name for form inputs.
|
|
114
118
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseSignUp.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignUp/BaseSignUp.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"BaseSignUp.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/SignUp/BaseSignUp.tsx"],"names":[],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ const logger$1 = createPackageComponentLogger("@thunderid/react", "BaseSignUp");
|
|
|
26
26
|
/**
|
|
27
27
|
* Internal component that consumes FlowContext and renders the sign-up UI.
|
|
28
28
|
*/
|
|
29
|
-
const BaseSignUpContent = ({ afterSignUpUrl, onInitialize, onSubmit, onError, onFlowChange, onComplete, error: externalError, className = "", inputClassName = "", buttonClassName = "", errorClassName = "", messageClassName = "", size = "medium", variant = "outlined", isInitialized, children, showTitle = true, showSubtitle = true }) => {
|
|
29
|
+
const BaseSignUpContent = ({ afterSignUpUrl, onInitialize, onSubmit, onError, onFlowChange, onComplete, error: externalError, id, className = "", inputClassName = "", buttonClassName = "", errorClassName = "", messageClassName = "", size = "medium", variant = "outlined", isInitialized, children, showTitle = true, showSubtitle = true }) => {
|
|
30
30
|
const { theme, colorScheme } = useTheme_default();
|
|
31
31
|
const customRenderers = useContext(ComponentRendererContext_default);
|
|
32
32
|
const { t } = useTranslation_default();
|
|
@@ -585,6 +585,7 @@ const BaseSignUpContent = ({ afterSignUpUrl, onInitialize, onSubmit, onError, on
|
|
|
585
585
|
t
|
|
586
586
|
]);
|
|
587
587
|
if (children) return /* @__PURE__ */ jsx("div", {
|
|
588
|
+
id,
|
|
588
589
|
className: containerClasses,
|
|
589
590
|
children: children({
|
|
590
591
|
components: (currentFlow?.data)?.components || [],
|
|
@@ -609,6 +610,7 @@ const BaseSignUpContent = ({ afterSignUpUrl, onInitialize, onSubmit, onError, on
|
|
|
609
610
|
})
|
|
610
611
|
});
|
|
611
612
|
if (!isFlowInitialized && isLoading) return /* @__PURE__ */ jsx(Card_default, {
|
|
613
|
+
id,
|
|
612
614
|
className: cx(containerClasses, styles.card),
|
|
613
615
|
variant,
|
|
614
616
|
children: /* @__PURE__ */ jsx(Card_default.Content, { children: /* @__PURE__ */ jsx("div", {
|
|
@@ -617,6 +619,7 @@ const BaseSignUpContent = ({ afterSignUpUrl, onInitialize, onSubmit, onError, on
|
|
|
617
619
|
}) })
|
|
618
620
|
});
|
|
619
621
|
if (!currentFlow) return /* @__PURE__ */ jsx(Card_default, {
|
|
622
|
+
id,
|
|
620
623
|
className: cx(containerClasses, styles.card),
|
|
621
624
|
variant,
|
|
622
625
|
children: /* @__PURE__ */ jsx(Card_default.Content, { children: /* @__PURE__ */ jsxs(Alert_default, {
|
|
@@ -627,6 +630,7 @@ const BaseSignUpContent = ({ afterSignUpUrl, onInitialize, onSubmit, onError, on
|
|
|
627
630
|
});
|
|
628
631
|
const { title, subtitle, componentsWithoutHeadings } = getAuthComponentHeadings_default(currentFlow.data?.components || [], flowTitle, flowSubtitle, t("signup.heading"), t("signup.subheading"));
|
|
629
632
|
return /* @__PURE__ */ jsxs(Card_default, {
|
|
633
|
+
id,
|
|
630
634
|
className: cx(containerClasses, styles.card),
|
|
631
635
|
variant,
|
|
632
636
|
children: [(showTitle || showSubtitle) && /* @__PURE__ */ jsxs(Card_default.Header, {
|