@thunderid/react 1.8.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/account/UserProfile/BaseUserProfile.cjs +1 -1
- package/dist/cjs/components/admin/AgentDetails/AgentDetails.cjs +13 -2
- package/dist/cjs/components/admin/AgentDetails/AgentDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/AgentDetails/BaseAgentDetails.cjs +25 -7
- package/dist/cjs/components/admin/AgentDetails/BaseAgentDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/ApplicationDetails/ApplicationDetails.cjs +15 -2
- package/dist/cjs/components/admin/ApplicationDetails/ApplicationDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/ApplicationDetails/BaseApplicationDetails.cjs +24 -7
- package/dist/cjs/components/admin/ApplicationDetails/BaseApplicationDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/GroupMembers/GroupMembers.cjs +2 -1
- package/dist/cjs/components/admin/GroupMembers/GroupMembers.cjs.map +1 -1
- package/dist/cjs/components/admin/RoleAssignments/RoleAssignments.cjs +2 -1
- package/dist/cjs/components/admin/RoleAssignments/RoleAssignments.cjs.map +1 -1
- package/dist/cjs/components/admin/UserDetails/BaseUserDetails.cjs +32 -14
- package/dist/cjs/components/admin/UserDetails/BaseUserDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/UserDetails/UserDetails.cjs +14 -2
- package/dist/cjs/components/admin/UserDetails/UserDetails.cjs.map +1 -1
- package/dist/cjs/components/admin/shared/AccountLifecycleParts.cjs +105 -0
- package/dist/cjs/components/admin/shared/AccountLifecycleParts.cjs.map +1 -0
- package/dist/cjs/components/admin/shared/ApplicationFormFields.cjs +1 -1
- package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs +4 -5
- package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
- package/dist/cjs/components/auth/SignIn/SignIn.cjs +5 -5
- package/dist/cjs/components/auth/SignIn/SignIn.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +4 -5
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/Consent.cjs +53 -28
- package/dist/cjs/components/auth/flow/Consent.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.cjs +104 -0
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.styles.cjs +59 -0
- package/dist/cjs/components/auth/flow/ConsentAuthorizationDetail.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.cjs +171 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.styles.cjs +85 -0
- package/dist/cjs/components/auth/flow/ConsentDetailField.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.cjs +63 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.styles.cjs +83 -0
- package/dist/cjs/components/auth/flow/ConsentDetailText.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/flow/FieldFactory.cjs +1 -1
- package/dist/cjs/components/auth/flow/resolveConsentText.cjs +25 -0
- package/dist/cjs/components/auth/flow/resolveConsentText.cjs.map +1 -0
- package/dist/cjs/components/primitives/KeyValueInput/KeyValueInput.cjs +1 -1
- package/dist/cjs/components/primitives/MultiInput/MultiInput.cjs +1 -1
- package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs +1 -1
- package/dist/cjs/contexts/Theme/ThemeProvider.cjs +36 -6
- package/dist/cjs/contexts/Theme/ThemeProvider.cjs.map +1 -1
- package/dist/cjs/contexts/Theme/ThemeRootContext.cjs +12 -0
- package/dist/cjs/contexts/Theme/ThemeRootContext.cjs.map +1 -0
- package/dist/cjs/hooks/auth/useConsentDetailField.cjs +357 -0
- package/dist/cjs/hooks/auth/useConsentDetailField.cjs.map +1 -0
- package/dist/cjs/hooks/management/useAccountLifecycle.cjs +59 -0
- package/dist/cjs/hooks/management/useAccountLifecycle.cjs.map +1 -0
- package/dist/cjs/index.cjs +66 -1
- package/dist/cjs/utils/formatConsentDetailValue.cjs +26 -0
- package/dist/cjs/utils/formatConsentDetailValue.cjs.map +1 -0
- package/dist/cjs/utils/getConsentDetailLayout.cjs +44 -0
- package/dist/cjs/utils/getConsentDetailLayout.cjs.map +1 -0
- package/dist/cjs/utils/getConsentDetailListDisplay.cjs +30 -0
- package/dist/cjs/utils/getConsentDetailListDisplay.cjs.map +1 -0
- package/dist/cjs/utils/isConsentApprovalBlocked.cjs +41 -0
- package/dist/cjs/utils/isConsentApprovalBlocked.cjs.map +1 -0
- package/dist/cjs/utils/isConsentDetailPlainList.cjs +24 -0
- package/dist/cjs/utils/isConsentDetailPlainList.cjs.map +1 -0
- package/dist/cjs/utils/isConsentDetailStructured.cjs +15 -0
- package/dist/cjs/utils/isConsentDetailStructured.cjs.map +1 -0
- package/dist/cjs/utils/isConsentDetailTextClamped.cjs +25 -0
- package/dist/cjs/utils/isConsentDetailTextClamped.cjs.map +1 -0
- package/dist/components/account/UserProfile/BaseUserProfile.js +1 -1
- package/dist/components/admin/AgentDetails/AgentDetails.d.ts +8 -1
- package/dist/components/admin/AgentDetails/AgentDetails.d.ts.map +1 -1
- package/dist/components/admin/AgentDetails/AgentDetails.js +13 -2
- package/dist/components/admin/AgentDetails/AgentDetails.js.map +1 -1
- package/dist/components/admin/AgentDetails/BaseAgentDetails.d.ts +21 -1
- package/dist/components/admin/AgentDetails/BaseAgentDetails.d.ts.map +1 -1
- package/dist/components/admin/AgentDetails/BaseAgentDetails.js +25 -7
- package/dist/components/admin/AgentDetails/BaseAgentDetails.js.map +1 -1
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.d.ts +15 -1
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.d.ts.map +1 -1
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.js +15 -2
- package/dist/components/admin/ApplicationDetails/ApplicationDetails.js.map +1 -1
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.d.ts +20 -1
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.d.ts.map +1 -1
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.js +24 -7
- package/dist/components/admin/ApplicationDetails/BaseApplicationDetails.js.map +1 -1
- package/dist/components/admin/GroupMembers/GroupMembers.d.ts +7 -0
- package/dist/components/admin/GroupMembers/GroupMembers.d.ts.map +1 -1
- package/dist/components/admin/GroupMembers/GroupMembers.js +2 -1
- package/dist/components/admin/GroupMembers/GroupMembers.js.map +1 -1
- package/dist/components/admin/RoleAssignments/RoleAssignments.d.ts +7 -0
- package/dist/components/admin/RoleAssignments/RoleAssignments.d.ts.map +1 -1
- package/dist/components/admin/RoleAssignments/RoleAssignments.js +2 -1
- package/dist/components/admin/RoleAssignments/RoleAssignments.js.map +1 -1
- package/dist/components/admin/UserDetails/BaseUserDetails.d.ts +22 -1
- package/dist/components/admin/UserDetails/BaseUserDetails.d.ts.map +1 -1
- package/dist/components/admin/UserDetails/BaseUserDetails.js +32 -14
- package/dist/components/admin/UserDetails/BaseUserDetails.js.map +1 -1
- package/dist/components/admin/UserDetails/UserDetails.d.ts +15 -1
- package/dist/components/admin/UserDetails/UserDetails.d.ts.map +1 -1
- package/dist/components/admin/UserDetails/UserDetails.js +14 -2
- package/dist/components/admin/UserDetails/UserDetails.js.map +1 -1
- package/dist/components/admin/shared/AccountLifecycleParts.d.ts +32 -0
- package/dist/components/admin/shared/AccountLifecycleParts.d.ts.map +1 -0
- package/dist/components/admin/shared/AccountLifecycleParts.js +101 -0
- package/dist/components/admin/shared/AccountLifecycleParts.js.map +1 -0
- package/dist/components/admin/shared/ApplicationFormFields.js +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +5 -6
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
- package/dist/components/auth/SignIn/SignIn.d.ts.map +1 -1
- package/dist/components/auth/SignIn/SignIn.js +6 -6
- package/dist/components/auth/SignIn/SignIn.js.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.js +5 -6
- package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
- package/dist/components/auth/flow/Consent.d.ts +6 -0
- package/dist/components/auth/flow/Consent.d.ts.map +1 -1
- package/dist/components/auth/flow/Consent.js +54 -29
- package/dist/components/auth/flow/Consent.js.map +1 -1
- package/dist/components/auth/flow/ConsentAuthorizationDetail.d.ts +68 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.js +100 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.js.map +1 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.d.ts +10 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.js +57 -0
- package/dist/components/auth/flow/ConsentAuthorizationDetail.styles.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.d.ts +39 -0
- package/dist/components/auth/flow/ConsentDetailField.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.js +168 -0
- package/dist/components/auth/flow/ConsentDetailField.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.d.ts +11 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.js +83 -0
- package/dist/components/auth/flow/ConsentDetailField.styles.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.d.ts +53 -0
- package/dist/components/auth/flow/ConsentDetailText.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.js +58 -0
- package/dist/components/auth/flow/ConsentDetailText.js.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.d.ts +20 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.d.ts.map +1 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.js +80 -0
- package/dist/components/auth/flow/ConsentDetailText.styles.js.map +1 -0
- package/dist/components/auth/flow/FieldFactory.js +1 -1
- package/dist/components/auth/flow/resolveConsentText.d.ts +13 -0
- package/dist/components/auth/flow/resolveConsentText.d.ts.map +1 -0
- package/dist/components/auth/flow/resolveConsentText.js +23 -0
- package/dist/components/auth/flow/resolveConsentText.js.map +1 -0
- package/dist/components/primitives/KeyValueInput/KeyValueInput.js +1 -1
- package/dist/components/primitives/MultiInput/MultiInput.js +1 -1
- package/dist/components/primitives/PasswordField/PasswordField.js +1 -1
- package/dist/contexts/Theme/ThemeProvider.d.ts +2 -1
- package/dist/contexts/Theme/ThemeProvider.d.ts.map +1 -1
- package/dist/contexts/Theme/ThemeProvider.js +37 -7
- package/dist/contexts/Theme/ThemeProvider.js.map +1 -1
- package/dist/contexts/Theme/ThemeRootContext.d.ts +11 -0
- package/dist/contexts/Theme/ThemeRootContext.d.ts.map +1 -0
- package/dist/contexts/Theme/ThemeRootContext.js +10 -0
- package/dist/contexts/Theme/ThemeRootContext.js.map +1 -0
- package/dist/hooks/auth/useConsentDetailField.d.ts +130 -0
- package/dist/hooks/auth/useConsentDetailField.d.ts.map +1 -0
- package/dist/hooks/auth/useConsentDetailField.js +354 -0
- package/dist/hooks/auth/useConsentDetailField.js.map +1 -0
- package/dist/hooks/management/useAccountLifecycle.d.ts +49 -0
- package/dist/hooks/management/useAccountLifecycle.d.ts.map +1 -0
- package/dist/hooks/management/useAccountLifecycle.js +56 -0
- package/dist/hooks/management/useAccountLifecycle.js.map +1 -0
- package/dist/index.d.ts +16 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/utils/formatConsentDetailValue.d.ts +16 -0
- package/dist/utils/formatConsentDetailValue.d.ts.map +1 -0
- package/dist/utils/formatConsentDetailValue.js +25 -0
- package/dist/utils/formatConsentDetailValue.js.map +1 -0
- package/dist/utils/getConsentDetailLayout.d.ts +32 -0
- package/dist/utils/getConsentDetailLayout.d.ts.map +1 -0
- package/dist/utils/getConsentDetailLayout.js +43 -0
- package/dist/utils/getConsentDetailLayout.js.map +1 -0
- package/dist/utils/getConsentDetailListDisplay.d.ts +30 -0
- package/dist/utils/getConsentDetailListDisplay.d.ts.map +1 -0
- package/dist/utils/getConsentDetailListDisplay.js +30 -0
- package/dist/utils/getConsentDetailListDisplay.js.map +1 -0
- package/dist/utils/isConsentApprovalBlocked.d.ts +17 -0
- package/dist/utils/isConsentApprovalBlocked.d.ts.map +1 -0
- package/dist/utils/isConsentApprovalBlocked.js +39 -0
- package/dist/utils/isConsentApprovalBlocked.js.map +1 -0
- package/dist/utils/isConsentDetailPlainList.d.ts +15 -0
- package/dist/utils/isConsentDetailPlainList.d.ts.map +1 -0
- package/dist/utils/isConsentDetailPlainList.js +23 -0
- package/dist/utils/isConsentDetailPlainList.js.map +1 -0
- package/dist/utils/isConsentDetailStructured.d.ts +10 -0
- package/dist/utils/isConsentDetailStructured.d.ts.map +1 -0
- package/dist/utils/isConsentDetailStructured.js +14 -0
- package/dist/utils/isConsentDetailStructured.js.map +1 -0
- package/dist/utils/isConsentDetailTextClamped.d.ts +20 -0
- package/dist/utils/isConsentDetailTextClamped.d.ts.map +1 -0
- package/dist/utils/isConsentDetailTextClamped.js +24 -0
- package/dist/utils/isConsentDetailTextClamped.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseAcceptInvite.js","names":["BaseAcceptInvite: FC<BaseAcceptInviteProps>","useThunderID","useTranslation","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","styles: any","useStyles","challengeTokenRef: any","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","tokenValidationAttemptedRef: any","tempData: any","storageManager: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","components","response: any","handleInputChange: any","newErrors: any","handleInputBlur: any","validateForm: any","value: any","handleSubmit: any","validation: any","inputs: any","raw: any","purposes: any[]","payload: Record<string, any>","redirectURL: any","extractHeadings: any","title: string | undefined","subtitle: string | undefined","title","subtitle","filterHeadings: any","components: any","componentsWithoutHeadings: any","renderProps: BaseAcceptInviteRenderProps","CardPrimitive","Spinner","Typography","AlertPrimitive","Button"],"sources":["../../../../src/components/auth/AcceptInvite/BaseAcceptInvite.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ConsentConstants,\n FieldError,\n FlowExecutionError,\n FlowMetadataResponse,\n Preferences,\n buildValidatorFromRules,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react';\nimport useStyles from './BaseAcceptInvite.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport {useOAuthCallback} from '../../../hooks/auth/useOAuthCallback';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../utils/flowTransformer';\nimport {initiateOAuthRedirect} from '../../../utils/oauth';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\nimport Button from '../../primitives/Button/Button';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderInviteUserComponents} from '../flow/AuthOptionFactory';\n\n/**\n * Flow response structure from the backend.\n */\nexport interface AcceptInviteFlowResponse {\n challengeToken?: string;\n data?: {\n additionalData?: Record<string, string>;\n components?: any[];\n fieldErrors?: FieldError[];\n meta?: {\n components?: any[];\n };\n redirectURL?: string;\n };\n error?: FlowExecutionError;\n executionId: string;\n flowStatus: 'INCOMPLETE' | 'COMPLETE' | 'ERROR';\n type?: 'VIEW' | 'REDIRECTION';\n}\n\n/**\n * Render props for custom UI rendering of AcceptInvite.\n */\nexport interface BaseAcceptInviteRenderProps {\n /**\n * Additional data from the current flow step (e.g. consentPrompt for consent nodes).\n */\n additionalData: Record<string, any>;\n\n /**\n * Flow components from the current step.\n */\n components: any[];\n\n /**\n * API error (if any).\n */\n error?: Error | null;\n\n /**\n * Current flow ID from URL.\n */\n executionId?: string;\n\n /**\n * Field validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Navigate to sign in page.\n */\n goToSignIn?: () => void;\n\n /**\n * Function to handle input blur.\n */\n handleInputBlur: (name: string) => void;\n\n /**\n * Function to handle input changes.\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission.\n */\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Invite token from URL.\n */\n inviteToken?: string;\n\n /**\n * Whether the flow has completed successfully.\n */\n isComplete: boolean;\n\n /**\n * Loading state.\n */\n isLoading: boolean;\n\n /**\n * Whether the token validation failed.\n */\n isTokenInvalid: boolean;\n\n /**\n * Whether the form is valid.\n */\n isValid: boolean;\n\n /**\n * Whether the invite token is being validated.\n */\n isValidatingToken: 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 * Subtitle for the current step.\n */\n subtitle?: string;\n\n /**\n * Title for the current step.\n */\n title?: string;\n\n /**\n * Touched fields.\n */\n touched: Record<string, boolean>;\n\n /**\n * Form values for the current step.\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseAcceptInvite component.\n */\nexport interface BaseAcceptInviteProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered.\n */\n children?: (props: BaseAcceptInviteRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Flow ID from the invite link URL.\n */\n executionId?: string;\n\n /**\n * Invite token from the invite link URL.\n */\n inviteToken?: string;\n\n /**\n * Callback when the flow completes successfully.\n */\n onComplete?: () => void;\n\n /**\n * Callback when an error occurs.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: AcceptInviteFlowResponse) => void;\n\n /**\n * Callback to navigate to sign in page.\n */\n onGoToSignIn?: () => void;\n\n /**\n * Function to submit flow step data.\n * This makes a request to the flow/execute endpoint.\n */\n onSubmit: (payload: Record<string, any>) => Promise<AcceptInviteFlowResponse>;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Base component for accept invite flow (end-user).\n * Handles the flow logic for validating an invite token and setting a password.\n *\n * When no children are provided, renders a default UI with:\n * - Loading spinner during token validation\n * - Error alerts for invalid/expired tokens\n * - Password form with validation\n * - Success state with sign-in redirect\n *\n * Flow steps handled:\n * 1. Validate invite token (automatic on mount)\n * 2. Password input\n * 3. Flow completion\n */\nconst BaseAcceptInvite: FC<BaseAcceptInviteProps> = ({\n executionId,\n inviteToken,\n onSubmit,\n onComplete,\n onError,\n onFlowChange,\n onGoToSignIn,\n className = '',\n children,\n preferences,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: BaseAcceptInviteProps): ReactElement => {\n const {meta, isInitialized, getStorageManager, vendor} = useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n const [isLoading, setIsLoading] = useState(false);\n const [isValidatingToken, setIsValidatingToken] = useState(true);\n const [isTokenInvalid, setIsTokenInvalid] = useState(false);\n const [isComplete, setIsComplete] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<AcceptInviteFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n const [formValues, setFormValues] = useState<Record<string, string>>({});\n const [formErrors, setFormErrors] = useState<Record<string, string>>({});\n const [touchedFields, setTouchedFields] = useState<Record<string, boolean>>({});\n const [isFormValid, setIsFormValid] = useState(true);\n const [isStorageReady, setIsStorageReady] = useState(false);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n /**\n * Project server-side validation errors from the most recent flow response into\n * the local formErrors state. First error per field wins; affected fields are\n * marked touched so errors render immediately.\n */\n useEffect(() => {\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setFormErrors(errors);\n setTouchedFields((prev: Record<string, boolean>) => ({...prev, ...touched}));\n }, [currentFlow]);\n\n const tokenValidationAttemptedRef: any = useRef(false);\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 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 };\n\n /**\n * Handle error responses and extract meaningful error messages.\n * Uses the transformer's extractErrorMessage function for consistency.\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t, 'components.acceptInvite.errors.generic');\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Call the onError callback if provided\n onError?.(error instanceof Error ? error : new Error(errorMessage));\n },\n [t, onError],\n );\n\n /**\n * Normalize flow response to ensure component-driven format.\n * Transforms data.meta.components to data.components.\n */\n const normalizeFlowResponseLocal: any = useCallback(\n (response: AcceptInviteFlowResponse): AcceptInviteFlowResponse => {\n if (!response?.data?.meta?.components) {\n return response;\n }\n\n try {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {\n defaultErrorKey: 'components.acceptInvite.errors.generic',\n resolveTranslations: false,\n },\n meta,\n );\n\n return {\n ...response,\n data: {\n ...response.data,\n components: components as any,\n },\n };\n } catch {\n // If transformer throws (e.g., error response), return as-is\n return response;\n }\n },\n [t, children],\n );\n\n /**\n * Handle OAuth callback when returning from OAuth provider.\n * This hook processes the authorization code and continues the flow.\n */\n useOAuthCallback({\n currentExecutionId: executionId ?? null,\n executionIdStorageKey: `${vendor}_execution_id`,\n isInitialized: isStorageReady,\n onComplete: () => {\n setIsValidatingToken(false);\n onComplete?.();\n },\n onError: (error: any) => {\n if (!error?.flowStatus) {\n setIsTokenInvalid(true);\n }\n setIsValidatingToken(false);\n handleError(error);\n },\n onFlowChange: (response: any) => {\n onFlowChange?.(response);\n if (response.flowStatus === 'COMPLETE') {\n setIsComplete(true);\n const completionComponents: any[] = response.data?.components || response.data?.meta?.components || [];\n if (completionComponents.length > 0) {\n setCurrentFlow(response);\n }\n } else {\n // Initialize currentFlow for next steps if not complete\n setCurrentFlow(response);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n }\n },\n onProcessingStart: () => {\n setIsValidatingToken(true);\n },\n onSubmit: async (payload: any) => {\n const rawResponse: any = await onSubmit({\n ...payload,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n });\n const response: any = normalizeFlowResponseLocal(rawResponse);\n await setChallengeToken(response.challengeToken ?? null);\n return response;\n },\n tokenValidationAttemptedRef,\n });\n\n /**\n * Handle input value changes.\n */\n const handleInputChange: any = useCallback((name: string, value: string) => {\n setFormValues((prev: any) => ({...prev, [name]: value}));\n // Clear error when user starts typing\n setFormErrors((prev: any) => {\n const newErrors: any = {...prev};\n delete newErrors[name];\n return newErrors;\n });\n setIsFormValid(true);\n }, []);\n\n /**\n * Handle input blur.\n */\n const handleInputBlur: any = useCallback((name: string) => {\n setTouchedFields((prev: any) => ({...prev, [name]: true}));\n }, []);\n\n /**\n * Validate required fields based on components.\n */\n const validateForm: any = useCallback(\n (components: any[]): {errors: Record<string, string>; isValid: boolean} => {\n const errors: Record<string, string> = {};\n\n const validateComponents = (comps: any[]): any => {\n comps.forEach((comp: any) => {\n if (\n (comp.type === 'PASSWORD_INPUT' ||\n comp.type === 'TEXT_INPUT' ||\n comp.type === 'EMAIL_INPUT' ||\n comp.type === 'PHONE_INPUT' ||\n comp.type === 'OTP_INPUT' ||\n comp.type === 'DATE_INPUT' ||\n comp.type === 'SELECT') &&\n comp.ref\n ) {\n const value: any = formValues[comp.ref];\n if (comp.required && (!value || value.trim() === '')) {\n errors[comp.ref] = t('validations.required.field.error');\n } else if (value) {\n // Evaluate declarative validation rules from meta.components[].validation.\n const ruleValidator = buildValidatorFromRules(comp.validation);\n if (ruleValidator) {\n const message = ruleValidator(value);\n if (message) {\n errors[comp.ref] = t(message);\n }\n }\n }\n }\n if (comp.components && Array.isArray(comp.components)) {\n validateComponents(comp.components);\n }\n });\n };\n\n validateComponents(components);\n\n return {errors, isValid: Object.keys(errors).length === 0};\n },\n [formValues, t],\n );\n\n /**\n * Handle form submission.\n */\n const handleSubmit: any = useCallback(\n async (component: any, data?: Record<string, any>) => {\n if (!currentFlow) {\n return;\n }\n\n // Validate form before submission\n const components: any = currentFlow.data?.components || [];\n const validation: any = validateForm(components);\n\n if (!validation.isValid) {\n setIsFormValid(false);\n setFormErrors(validation.errors);\n // Mark all fields as touched\n const touched: Record<string, boolean> = {};\n Object.keys(validation.errors).forEach((key: any) => {\n touched[key] = true;\n });\n setTouchedFields((prev: any) => ({...prev, ...touched}));\n return;\n }\n\n setIsLoading(true);\n setApiError(null);\n\n try {\n // Build payload with form values\n const inputs: any = {...(data || formValues)};\n\n // Auto-compile consent_decisions if we are on a consent prompt step.\n // Mirrors the same logic in SignIn to ensure the server receives a\n // properly structured JSON payload rather than individual checkbox keys.\n const currentAdditionalData = (currentFlow?.data?.additionalData as Record<string, any>) ?? {};\n if (currentAdditionalData['consentPrompt']) {\n try {\n const raw: any = currentAdditionalData['consentPrompt'];\n const purposes: any[] = typeof raw === 'string' ? JSON.parse(raw) : raw.purposes || raw;\n const isDeny = component?.variant?.toLowerCase() !== 'primary';\n const decisions = {\n approved: !isDeny,\n ...(isDeny ? {reason: ConsentConstants.REASON_USER_DENIED} : {}),\n purposes: purposes.map((p: any) => ({\n approved: !isDeny,\n purposeName: p.purposeName,\n elements: [\n ...(p.essential || []).map((e: any) => ({approved: !isDeny, name: e.name})),\n ...(p.optional || []).map((e: any) => {\n const key = `__consent_opt__${p.purposeId}__${e.name}`;\n return {approved: !isDeny && inputs[key] === 'true', name: e.name};\n }),\n ],\n })),\n };\n inputs.consent_decisions = JSON.stringify(decisions);\n Object.keys(inputs).forEach((k: string) => {\n if (k.startsWith('__consent_opt__')) delete inputs[k];\n });\n } catch {\n // Leave inputs as-is if consent building fails\n }\n }\n\n const payload: Record<string, any> = {\n executionId: currentFlow.executionId,\n inputs,\n verbose: true,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n };\n\n // Add action ID if component has one\n if (component?.id) {\n payload['action'] = component.id;\n }\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Handle OAuth redirect response\n if (response.type === 'REDIRECTION') {\n const redirectURL: any = response.data?.redirectURL || response?.redirectURL;\n if (redirectURL && typeof window !== 'undefined') {\n // Initiate OAuth redirect with secure state management\n initiateOAuthRedirect(redirectURL, vendor);\n return;\n }\n }\n\n // Check for completion\n if (response.flowStatus === 'COMPLETE') {\n setIsComplete(true);\n const completionComponents: any[] = response.data?.components || response.data?.meta?.components || [];\n if (completionComponents.length > 0) {\n setCurrentFlow(response);\n } else {\n onComplete?.();\n }\n return;\n }\n\n // Check for error status\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n return;\n }\n\n // Update current flow and reset form state for next step, preserving input values\n setCurrentFlow(response);\n setFormErrors({});\n setTouchedFields({});\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [\n currentFlow,\n formValues,\n validateForm,\n onSubmit,\n onFlowChange,\n onComplete,\n handleError,\n normalizeFlowResponseLocal,\n ],\n );\n\n /**\n * reset form values, errors, and touched fields to initial state\n */\n const resetForm = useCallback(() => {\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n }, []);\n\n /**\n * Validate invite token on component mount.\n */\n useEffect(() => {\n // Skip validation if already validated\n if (tokenValidationAttemptedRef.current) {\n return;\n }\n\n // If an OAuth code is present, this is a return from an OAuth redirect.\n // useOAuthCallback will handle the code — skip the initial invite validation.\n const urlParams: URLSearchParams = new URLSearchParams(window.location.search);\n if (urlParams.get('code')) {\n return;\n }\n\n // Validate required params for initial invite link\n if (!executionId || !inviteToken) {\n setIsValidatingToken(false);\n setIsTokenInvalid(true);\n handleError(new Error('Invalid invite link. Missing executionId or inviteToken.'));\n return;\n }\n\n tokenValidationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsValidatingToken(true);\n setApiError(null);\n\n try {\n // Store executionId in sessionStorage for OAuth callback\n if (executionId) {\n sessionStorage.setItem(`${vendor}_execution_id`, executionId);\n }\n\n // Send the invite token to validate and continue the flow\n const payload: any = {\n executionId,\n inputs: {\n inviteToken,\n },\n verbose: true,\n };\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Check for error (invalid token)\n if (response.flowStatus === 'ERROR') {\n setIsTokenInvalid(true);\n handleError(response);\n return;\n }\n\n // Token is valid, show the password form\n setCurrentFlow(response);\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n setIsTokenInvalid(true);\n handleError(err);\n } finally {\n setIsValidatingToken(false);\n }\n })();\n }, [executionId, inviteToken, onSubmit, onFlowChange, handleError, normalizeFlowResponseLocal]);\n\n /**\n * Extract title and subtitle from components.\n */\n const extractHeadings: any = useCallback((components: any[]): {subtitle?: string; title?: string} => {\n let title: string | undefined;\n let subtitle: string | undefined;\n\n components.forEach((comp: any) => {\n if (comp.type === 'TEXT') {\n if (comp.variant === 'HEADING_1' && !title) {\n title = comp.label;\n } else if ((comp.variant === 'HEADING_2' || comp.variant === 'SUBTITLE_1') && !subtitle) {\n subtitle = comp.label;\n }\n }\n });\n\n return {subtitle, title};\n }, []);\n\n /**\n * Filter out heading components for default rendering.\n */\n const filterHeadings: any = useCallback(\n (components: any[]): any[] =>\n components.filter(\n (comp: any) => !(comp.type === 'TEXT' && (comp.variant === 'HEADING_1' || comp.variant === 'HEADING_2')),\n ),\n [],\n );\n\n // Get components from normalized response, with fallback to meta.components\n const components: any = currentFlow?.data?.components || currentFlow?.data?.meta?.components || [];\n const {title, subtitle} = extractHeadings(components);\n const componentsWithoutHeadings: any = filterHeadings(components);\n const additionalData: Record<string, any> = (currentFlow?.data?.additionalData as Record<string, any>) ?? {};\n\n // Render props\n const renderProps: BaseAcceptInviteRenderProps = {\n additionalData,\n components,\n error: apiError,\n executionId,\n fieldErrors: formErrors,\n goToSignIn: onGoToSignIn,\n handleInputBlur,\n handleInputChange,\n handleSubmit,\n inviteToken,\n isComplete,\n isLoading,\n isTokenInvalid,\n isValid: isFormValid,\n isValidatingToken,\n meta,\n subtitle,\n title,\n touched: touchedFields,\n values: formValues,\n };\n\n // If children render prop is provided, use it for custom UI\n if (children) {\n return <div className={className}>{children(renderProps)}</div>;\n }\n\n // Default rendering\n\n // Loading state during token validation\n if (isValidatingToken) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['tokenValidationContainer']}>\n <Spinner size=\"medium\" />\n <Typography variant=\"body1\">Validating your invite link...</Typography>\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Invalid token state\n if (isTokenInvalid) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Header className={styles.header}>\n <CardPrimitive.Title level={2} className={styles.title}>\n Invalid Invite Link\n </CardPrimitive.Title>\n </CardPrimitive.Header>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Title>Unable to verify invite</AlertPrimitive.Title>\n <AlertPrimitive.Description>\n {apiError?.message ||\n 'This invite link is invalid or has expired. Please contact your administrator for a new invite.'}\n </AlertPrimitive.Description>\n </AlertPrimitive>\n {onGoToSignIn && (\n <div className={(styles as Record<string, string>)['goToSignInContainer']}>\n <Button variant=\"outline\" onClick={onGoToSignIn}>\n Go to Sign In\n </Button>\n </div>\n )}\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Flow components (password form)\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (title || subtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && title && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && subtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {apiError && (\n <div className={(styles as Record<string, string>)['errorContainer']}>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n <div>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0\n ? renderInviteUserComponents(\n componentsWithoutHeadings,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n variant,\n },\n )\n : !isLoading && (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">No form components available</Typography>\n </AlertPrimitive>\n )}\n {isLoading && (\n <div className={(styles as Record<string, string>)['centeredSpinnerContainerSmall']}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n {onGoToSignIn && (\n <div className={(styles as Record<string, string>)['alreadyHaveAccountContainer']}>\n <Typography variant=\"body2\">\n Already have an account?{' '}\n <Button\n variant=\"text\"\n onClick={onGoToSignIn}\n className={(styles as Record<string, string>)['signInInlineButton']}\n >\n Sign In\n </Button>\n </Typography>\n </div>\n )}\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\nexport default BaseAcceptInvite;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BaseAcceptInvite.js","names":["BaseAcceptInvite: FC<BaseAcceptInviteProps>","useThunderID","useTranslation","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","styles: any","useStyles","challengeTokenRef: any","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","tokenValidationAttemptedRef: any","tempData: any","storageManager: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","components","response: any","handleInputChange: any","newErrors: any","handleInputBlur: any","validateForm: any","value: any","handleSubmit: any","validation: any","inputs: any","raw: any","purposes: any[]","isConsentApprovalBlocked","payload: Record<string, any>","redirectURL: any","extractHeadings: any","title: string | undefined","subtitle: string | undefined","title","subtitle","filterHeadings: any","components: any","componentsWithoutHeadings: any","renderProps: BaseAcceptInviteRenderProps","CardPrimitive","Spinner","Typography","AlertPrimitive","Button"],"sources":["../../../../src/components/auth/AcceptInvite/BaseAcceptInvite.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ConsentConstants,\n FieldError,\n FlowExecutionError,\n FlowMetadataResponse,\n Preferences,\n buildValidatorFromRules,\n CONSENT_INVALID_KEY_PREFIX,\n CONSENT_MODIFIED_KEY_PREFIX,\n getConsentElementDecision,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react';\nimport useStyles from './BaseAcceptInvite.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport {useOAuthCallback} from '../../../hooks/auth/useOAuthCallback';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {cx} from '../../../styles/emotion';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../utils/flowTransformer';\nimport isConsentApprovalBlocked from '../../../utils/isConsentApprovalBlocked';\nimport {initiateOAuthRedirect} from '../../../utils/oauth';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\nimport Button from '../../primitives/Button/Button';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../primitives/Card/Card';\nimport Spinner from '../../primitives/Spinner/Spinner';\nimport Typography from '../../primitives/Typography/Typography';\nimport {renderInviteUserComponents} from '../flow/AuthOptionFactory';\n\n/**\n * Flow response structure from the backend.\n */\nexport interface AcceptInviteFlowResponse {\n challengeToken?: string;\n data?: {\n additionalData?: Record<string, string>;\n components?: any[];\n fieldErrors?: FieldError[];\n meta?: {\n components?: any[];\n };\n redirectURL?: string;\n };\n error?: FlowExecutionError;\n executionId: string;\n flowStatus: 'INCOMPLETE' | 'COMPLETE' | 'ERROR';\n type?: 'VIEW' | 'REDIRECTION';\n}\n\n/**\n * Render props for custom UI rendering of AcceptInvite.\n */\nexport interface BaseAcceptInviteRenderProps {\n /**\n * Additional data from the current flow step (e.g. consentPrompt for consent nodes).\n */\n additionalData: Record<string, any>;\n\n /**\n * Flow components from the current step.\n */\n components: any[];\n\n /**\n * API error (if any).\n */\n error?: Error | null;\n\n /**\n * Current flow ID from URL.\n */\n executionId?: string;\n\n /**\n * Field validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Navigate to sign in page.\n */\n goToSignIn?: () => void;\n\n /**\n * Function to handle input blur.\n */\n handleInputBlur: (name: string) => void;\n\n /**\n * Function to handle input changes.\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission.\n */\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Invite token from URL.\n */\n inviteToken?: string;\n\n /**\n * Whether the flow has completed successfully.\n */\n isComplete: boolean;\n\n /**\n * Loading state.\n */\n isLoading: boolean;\n\n /**\n * Whether the token validation failed.\n */\n isTokenInvalid: boolean;\n\n /**\n * Whether the form is valid.\n */\n isValid: boolean;\n\n /**\n * Whether the invite token is being validated.\n */\n isValidatingToken: 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 * Subtitle for the current step.\n */\n subtitle?: string;\n\n /**\n * Title for the current step.\n */\n title?: string;\n\n /**\n * Touched fields.\n */\n touched: Record<string, boolean>;\n\n /**\n * Form values for the current step.\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseAcceptInvite component.\n */\nexport interface BaseAcceptInviteProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered.\n */\n children?: (props: BaseAcceptInviteRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Flow ID from the invite link URL.\n */\n executionId?: string;\n\n /**\n * Invite token from the invite link URL.\n */\n inviteToken?: string;\n\n /**\n * Callback when the flow completes successfully.\n */\n onComplete?: () => void;\n\n /**\n * Callback when an error occurs.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: AcceptInviteFlowResponse) => void;\n\n /**\n * Callback to navigate to sign in page.\n */\n onGoToSignIn?: () => void;\n\n /**\n * Function to submit flow step data.\n * This makes a request to the flow/execute endpoint.\n */\n onSubmit: (payload: Record<string, any>) => Promise<AcceptInviteFlowResponse>;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Base component for accept invite flow (end-user).\n * Handles the flow logic for validating an invite token and setting a password.\n *\n * When no children are provided, renders a default UI with:\n * - Loading spinner during token validation\n * - Error alerts for invalid/expired tokens\n * - Password form with validation\n * - Success state with sign-in redirect\n *\n * Flow steps handled:\n * 1. Validate invite token (automatic on mount)\n * 2. Password input\n * 3. Flow completion\n */\nconst BaseAcceptInvite: FC<BaseAcceptInviteProps> = ({\n executionId,\n inviteToken,\n onSubmit,\n onComplete,\n onError,\n onFlowChange,\n onGoToSignIn,\n className = '',\n children,\n preferences,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: BaseAcceptInviteProps): ReactElement => {\n const {meta, isInitialized, getStorageManager, vendor} = useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n const [isLoading, setIsLoading] = useState(false);\n const [isValidatingToken, setIsValidatingToken] = useState(true);\n const [isTokenInvalid, setIsTokenInvalid] = useState(false);\n const [isComplete, setIsComplete] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<AcceptInviteFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n const [formValues, setFormValues] = useState<Record<string, string>>({});\n const [formErrors, setFormErrors] = useState<Record<string, string>>({});\n const [touchedFields, setTouchedFields] = useState<Record<string, boolean>>({});\n const [isFormValid, setIsFormValid] = useState(true);\n const [isStorageReady, setIsStorageReady] = useState(false);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n /**\n * Project server-side validation errors from the most recent flow response into\n * the local formErrors state. First error per field wins; affected fields are\n * marked touched so errors render immediately.\n */\n useEffect(() => {\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setFormErrors(errors);\n setTouchedFields((prev: Record<string, boolean>) => ({...prev, ...touched}));\n }, [currentFlow]);\n\n const tokenValidationAttemptedRef: any = useRef(false);\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 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 };\n\n /**\n * Handle error responses and extract meaningful error messages.\n * Uses the transformer's extractErrorMessage function for consistency.\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t, 'components.acceptInvite.errors.generic');\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Call the onError callback if provided\n onError?.(error instanceof Error ? error : new Error(errorMessage));\n },\n [t, onError],\n );\n\n /**\n * Normalize flow response to ensure component-driven format.\n * Transforms data.meta.components to data.components.\n */\n const normalizeFlowResponseLocal: any = useCallback(\n (response: AcceptInviteFlowResponse): AcceptInviteFlowResponse => {\n if (!response?.data?.meta?.components) {\n return response;\n }\n\n try {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {\n defaultErrorKey: 'components.acceptInvite.errors.generic',\n resolveTranslations: false,\n },\n meta,\n );\n\n return {\n ...response,\n data: {\n ...response.data,\n components: components as any,\n },\n };\n } catch {\n // If transformer throws (e.g., error response), return as-is\n return response;\n }\n },\n [t, children],\n );\n\n /**\n * Handle OAuth callback when returning from OAuth provider.\n * This hook processes the authorization code and continues the flow.\n */\n useOAuthCallback({\n currentExecutionId: executionId ?? null,\n executionIdStorageKey: `${vendor}_execution_id`,\n isInitialized: isStorageReady,\n onComplete: () => {\n setIsValidatingToken(false);\n onComplete?.();\n },\n onError: (error: any) => {\n if (!error?.flowStatus) {\n setIsTokenInvalid(true);\n }\n setIsValidatingToken(false);\n handleError(error);\n },\n onFlowChange: (response: any) => {\n onFlowChange?.(response);\n if (response.flowStatus === 'COMPLETE') {\n setIsComplete(true);\n const completionComponents: any[] = response.data?.components || response.data?.meta?.components || [];\n if (completionComponents.length > 0) {\n setCurrentFlow(response);\n }\n } else {\n // Initialize currentFlow for next steps if not complete\n setCurrentFlow(response);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n }\n },\n onProcessingStart: () => {\n setIsValidatingToken(true);\n },\n onSubmit: async (payload: any) => {\n const rawResponse: any = await onSubmit({\n ...payload,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n });\n const response: any = normalizeFlowResponseLocal(rawResponse);\n await setChallengeToken(response.challengeToken ?? null);\n return response;\n },\n tokenValidationAttemptedRef,\n });\n\n /**\n * Handle input value changes.\n */\n const handleInputChange: any = useCallback((name: string, value: string) => {\n setFormValues((prev: any) => ({...prev, [name]: value}));\n // Clear error when user starts typing\n setFormErrors((prev: any) => {\n const newErrors: any = {...prev};\n delete newErrors[name];\n return newErrors;\n });\n setIsFormValid(true);\n }, []);\n\n /**\n * Handle input blur.\n */\n const handleInputBlur: any = useCallback((name: string) => {\n setTouchedFields((prev: any) => ({...prev, [name]: true}));\n }, []);\n\n /**\n * Validate required fields based on components.\n */\n const validateForm: any = useCallback(\n (components: any[]): {errors: Record<string, string>; isValid: boolean} => {\n const errors: Record<string, string> = {};\n\n const validateComponents = (comps: any[]): any => {\n comps.forEach((comp: any) => {\n if (\n (comp.type === 'PASSWORD_INPUT' ||\n comp.type === 'TEXT_INPUT' ||\n comp.type === 'EMAIL_INPUT' ||\n comp.type === 'PHONE_INPUT' ||\n comp.type === 'OTP_INPUT' ||\n comp.type === 'DATE_INPUT' ||\n comp.type === 'SELECT') &&\n comp.ref\n ) {\n const value: any = formValues[comp.ref];\n if (comp.required && (!value || value.trim() === '')) {\n errors[comp.ref] = t('validations.required.field.error');\n } else if (value) {\n // Evaluate declarative validation rules from meta.components[].validation.\n const ruleValidator = buildValidatorFromRules(comp.validation);\n if (ruleValidator) {\n const message = ruleValidator(value);\n if (message) {\n errors[comp.ref] = t(message);\n }\n }\n }\n }\n if (comp.components && Array.isArray(comp.components)) {\n validateComponents(comp.components);\n }\n });\n };\n\n validateComponents(components);\n\n return {errors, isValid: Object.keys(errors).length === 0};\n },\n [formValues, t],\n );\n\n /**\n * Handle form submission.\n */\n const handleSubmit: any = useCallback(\n async (component: any, data?: Record<string, any>) => {\n if (!currentFlow) {\n return;\n }\n\n // Validate form before submission\n const components: any = currentFlow.data?.components || [];\n const validation: any = validateForm(components);\n\n if (!validation.isValid) {\n setIsFormValid(false);\n setFormErrors(validation.errors);\n // Mark all fields as touched\n const touched: Record<string, boolean> = {};\n Object.keys(validation.errors).forEach((key: any) => {\n touched[key] = true;\n });\n setTouchedFields((prev: any) => ({...prev, ...touched}));\n return;\n }\n\n setIsLoading(true);\n setApiError(null);\n\n try {\n // Build payload with form values\n const inputs: any = {...(data || formValues)};\n\n // Auto-compile consent_decisions if we are on a consent prompt step.\n // Mirrors the same logic in SignIn to ensure the server receives a\n // properly structured JSON payload rather than individual checkbox keys.\n const currentAdditionalData = (currentFlow?.data?.additionalData as Record<string, any>) ?? {};\n if (currentAdditionalData['consentPrompt']) {\n try {\n const raw: any = currentAdditionalData['consentPrompt'];\n const purposes: any[] = typeof raw === 'string' ? JSON.parse(raw) : raw.purposes || raw;\n const isDeny = component?.variant?.toLowerCase() !== 'primary';\n // Approval waits while an approved authorization detail shows a value that cannot be submitted\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n if (!isDeny && isConsentApprovalBlocked(purposes, inputs)) {\n return;\n }\n const decisions = {\n approved: !isDeny,\n ...(isDeny ? {reason: ConsentConstants.REASON_USER_DENIED} : {}),\n purposes: purposes.map((p: any) => ({\n approved: !isDeny,\n purposeName: p.purposeName,\n elements: [\n ...(p.essential || []).map((e: any) => ({approved: !isDeny, name: e.name})),\n ...(p.optional || []).map((e: any) => {\n const key = `__consent_opt__${p.purposeId}__${e.name}`;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n return getConsentElementDecision(p.purposeId, e, !isDeny && inputs[key] === 'true', inputs);\n }),\n ],\n })),\n };\n inputs.consent_decisions = JSON.stringify(decisions);\n Object.keys(inputs).forEach((k: string) => {\n if (\n k.startsWith('__consent_opt__') ||\n k.startsWith(CONSENT_MODIFIED_KEY_PREFIX) ||\n k.startsWith(CONSENT_INVALID_KEY_PREFIX)\n ) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n delete inputs[k];\n }\n });\n } catch {\n // Leave inputs as-is if consent building fails\n }\n }\n\n const payload: Record<string, any> = {\n executionId: currentFlow.executionId,\n inputs,\n verbose: true,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n };\n\n // Add action ID if component has one\n if (component?.id) {\n payload['action'] = component.id;\n }\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Handle OAuth redirect response\n if (response.type === 'REDIRECTION') {\n const redirectURL: any = response.data?.redirectURL || response?.redirectURL;\n if (redirectURL && typeof window !== 'undefined') {\n // Initiate OAuth redirect with secure state management\n initiateOAuthRedirect(redirectURL, vendor);\n return;\n }\n }\n\n // Check for completion\n if (response.flowStatus === 'COMPLETE') {\n setIsComplete(true);\n const completionComponents: any[] = response.data?.components || response.data?.meta?.components || [];\n if (completionComponents.length > 0) {\n setCurrentFlow(response);\n } else {\n onComplete?.();\n }\n return;\n }\n\n // Check for error status\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n return;\n }\n\n // Update current flow and reset form state for next step, preserving input values\n setCurrentFlow(response);\n setFormErrors({});\n setTouchedFields({});\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [\n currentFlow,\n formValues,\n validateForm,\n onSubmit,\n onFlowChange,\n onComplete,\n handleError,\n normalizeFlowResponseLocal,\n ],\n );\n\n /**\n * reset form values, errors, and touched fields to initial state\n */\n const resetForm = useCallback(() => {\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n }, []);\n\n /**\n * Validate invite token on component mount.\n */\n useEffect(() => {\n // Skip validation if already validated\n if (tokenValidationAttemptedRef.current) {\n return;\n }\n\n // If an OAuth code is present, this is a return from an OAuth redirect.\n // useOAuthCallback will handle the code — skip the initial invite validation.\n const urlParams: URLSearchParams = new URLSearchParams(window.location.search);\n if (urlParams.get('code')) {\n return;\n }\n\n // Validate required params for initial invite link\n if (!executionId || !inviteToken) {\n setIsValidatingToken(false);\n setIsTokenInvalid(true);\n handleError(new Error('Invalid invite link. Missing executionId or inviteToken.'));\n return;\n }\n\n tokenValidationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsValidatingToken(true);\n setApiError(null);\n\n try {\n // Store executionId in sessionStorage for OAuth callback\n if (executionId) {\n sessionStorage.setItem(`${vendor}_execution_id`, executionId);\n }\n\n // Send the invite token to validate and continue the flow\n const payload: any = {\n executionId,\n inputs: {\n inviteToken,\n },\n verbose: true,\n };\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Check for error (invalid token)\n if (response.flowStatus === 'ERROR') {\n setIsTokenInvalid(true);\n handleError(response);\n return;\n }\n\n // Token is valid, show the password form\n setCurrentFlow(response);\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n setIsTokenInvalid(true);\n handleError(err);\n } finally {\n setIsValidatingToken(false);\n }\n })();\n }, [executionId, inviteToken, onSubmit, onFlowChange, handleError, normalizeFlowResponseLocal]);\n\n /**\n * Extract title and subtitle from components.\n */\n const extractHeadings: any = useCallback((components: any[]): {subtitle?: string; title?: string} => {\n let title: string | undefined;\n let subtitle: string | undefined;\n\n components.forEach((comp: any) => {\n if (comp.type === 'TEXT') {\n if (comp.variant === 'HEADING_1' && !title) {\n title = comp.label;\n } else if ((comp.variant === 'HEADING_2' || comp.variant === 'SUBTITLE_1') && !subtitle) {\n subtitle = comp.label;\n }\n }\n });\n\n return {subtitle, title};\n }, []);\n\n /**\n * Filter out heading components for default rendering.\n */\n const filterHeadings: any = useCallback(\n (components: any[]): any[] =>\n components.filter(\n (comp: any) => !(comp.type === 'TEXT' && (comp.variant === 'HEADING_1' || comp.variant === 'HEADING_2')),\n ),\n [],\n );\n\n // Get components from normalized response, with fallback to meta.components\n const components: any = currentFlow?.data?.components || currentFlow?.data?.meta?.components || [];\n const {title, subtitle} = extractHeadings(components);\n const componentsWithoutHeadings: any = filterHeadings(components);\n const additionalData: Record<string, any> = (currentFlow?.data?.additionalData as Record<string, any>) ?? {};\n\n // Render props\n const renderProps: BaseAcceptInviteRenderProps = {\n additionalData,\n components,\n error: apiError,\n executionId,\n fieldErrors: formErrors,\n goToSignIn: onGoToSignIn,\n handleInputBlur,\n handleInputChange,\n handleSubmit,\n inviteToken,\n isComplete,\n isLoading,\n isTokenInvalid,\n isValid: isFormValid,\n isValidatingToken,\n meta,\n subtitle,\n title,\n touched: touchedFields,\n values: formValues,\n };\n\n // If children render prop is provided, use it for custom UI\n if (children) {\n return <div className={className}>{children(renderProps)}</div>;\n }\n\n // Default rendering\n\n // Loading state during token validation\n if (isValidatingToken) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['tokenValidationContainer']}>\n <Spinner size=\"medium\" />\n <Typography variant=\"body1\">Validating your invite link...</Typography>\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Invalid token state\n if (isTokenInvalid) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Header className={styles.header}>\n <CardPrimitive.Title level={2} className={styles.title}>\n Invalid Invite Link\n </CardPrimitive.Title>\n </CardPrimitive.Header>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Title>Unable to verify invite</AlertPrimitive.Title>\n <AlertPrimitive.Description>\n {apiError?.message ||\n 'This invite link is invalid or has expired. Please contact your administrator for a new invite.'}\n </AlertPrimitive.Description>\n </AlertPrimitive>\n {onGoToSignIn && (\n <div className={(styles as Record<string, string>)['goToSignInContainer']}>\n <Button variant=\"outline\" onClick={onGoToSignIn}>\n Go to Sign In\n </Button>\n </div>\n )}\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Flow components (password form)\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (title || subtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && title && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && subtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {apiError && (\n <div className={(styles as Record<string, string>)['errorContainer']}>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n <div>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0\n ? renderInviteUserComponents(\n componentsWithoutHeadings,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n variant,\n },\n )\n : !isLoading && (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">No form components available</Typography>\n </AlertPrimitive>\n )}\n {isLoading && (\n <div className={(styles as Record<string, string>)['centeredSpinnerContainerSmall']}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n {onGoToSignIn && (\n <div className={(styles as Record<string, string>)['alreadyHaveAccountContainer']}>\n <Typography variant=\"body2\">\n Already have an account?{' '}\n <Button\n variant=\"text\"\n onClick={onGoToSignIn}\n className={(styles as Record<string, string>)['signInInlineButton']}\n >\n Sign In\n </Button>\n </Typography>\n </div>\n )}\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\nexport default BaseAcceptInvite;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/SignIn/SignIn.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,qBAAqB,EAGrB,yBAAyB,EAIzB,oBAAoB,EACpB,WAAW,
|
|
1
|
+
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/SignIn/SignIn.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,qBAAqB,EAGrB,yBAAyB,EAIzB,oBAAoB,EACpB,WAAW,EAKZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,EAAE,EAA6C,SAAS,EAAC,MAAM,OAAO,CAAC;AAE/E,OAAmB,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AASzD;;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;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;CACtC;AAwCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAw2B3B,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import useThunderID_default from "../../../contexts/ThunderID/useThunderID.js";
|
|
2
2
|
import useTranslation_default from "../../../hooks/useTranslation.js";
|
|
3
3
|
import { extractErrorMessage, normalizeFlowResponse } from "../../../utils/flowTransformer.js";
|
|
4
|
+
import isConsentApprovalBlocked_default from "../../../utils/isConsentApprovalBlocked.js";
|
|
4
5
|
import BaseSignIn_default from "./BaseSignIn.js";
|
|
5
6
|
import { useOAuthCallback } from "../../../hooks/auth/useOAuthCallback.js";
|
|
6
7
|
import { initiateOAuthRedirect } from "../../../utils/oauth.js";
|
|
7
8
|
import { handlePasskeyAuthentication, handlePasskeyRegistration } from "../../../utils/passkey.js";
|
|
8
|
-
import { ConsentConstants, EmbeddedFlowType, EmbeddedSignInFlowStatus, EmbeddedSignInFlowType, ThunderIDAPIError, ThunderIDRuntimeError, logger } from "@thunderid/browser";
|
|
9
|
+
import { CONSENT_INVALID_KEY_PREFIX, CONSENT_MODIFIED_KEY_PREFIX, ConsentConstants, EmbeddedFlowType, EmbeddedSignInFlowStatus, EmbeddedSignInFlowType, ThunderIDAPIError, ThunderIDRuntimeError, getConsentElementDecision, logger } from "@thunderid/browser";
|
|
9
10
|
import { useEffect, useRef, useState } from "react";
|
|
10
11
|
import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
11
12
|
|
|
@@ -426,6 +427,7 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
426
427
|
if (submitAction && submitAction.variant?.toLowerCase() !== "primary") isDeny = true;
|
|
427
428
|
}
|
|
428
429
|
if (consentReason === ConsentConstants.REASON_TIMEOUT) isDeny = true;
|
|
430
|
+
if (!isDeny && isConsentApprovalBlocked_default(purposes, processedInputs)) return;
|
|
429
431
|
const reason = consentReason ?? (isDeny ? ConsentConstants.REASON_USER_DENIED : void 0);
|
|
430
432
|
const decisions = {
|
|
431
433
|
approved: !isDeny,
|
|
@@ -437,17 +439,15 @@ const SignIn = ({ className, preferences, size = "medium", onSuccess, onError, v
|
|
|
437
439
|
name: e.name
|
|
438
440
|
})), ...(p.optional || []).map((e) => {
|
|
439
441
|
const key = `__consent_opt__${p.purposeId}__${e.name}`;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
name: e.name
|
|
443
|
-
};
|
|
442
|
+
const approved = !isDeny && processedInputs[key] === "true";
|
|
443
|
+
return getConsentElementDecision(p.purposeId, e, approved, processedInputs);
|
|
444
444
|
})],
|
|
445
445
|
purposeName: p.purposeName
|
|
446
446
|
}))
|
|
447
447
|
};
|
|
448
448
|
processedInputs["consent_decisions"] = JSON.stringify(decisions);
|
|
449
449
|
Object.keys(processedInputs).forEach((key) => {
|
|
450
|
-
if (key.startsWith("__consent_opt__")) delete processedInputs[key];
|
|
450
|
+
if (key.startsWith("__consent_opt__") || key.startsWith(CONSENT_MODIFIED_KEY_PREFIX) || key.startsWith(CONSENT_INVALID_KEY_PREFIX)) delete processedInputs[key];
|
|
451
451
|
});
|
|
452
452
|
} catch (e) {}
|
|
453
453
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.js","names":["submitActions: EmbeddedFlowComponent[]","SignIn: FC<SignInProps>","useThunderID","useTranslation","challengeTokenRef: any","initializationAttemptedRef: any","oauthCodeProcessedRef: any","passkeyProcessedRef: any","tempData: any","storageManager: any","urlParams: any","url: any","redirectURL: any","finalRedirectUrl: any","effectiveApplicationId: any","storedExecutionId: any","resumeExecutionId: any","response: EmbeddedSignInFlowResponse","err: any","currentUrlParams: any","effectiveExecutionId: any","processedInputs: Record<string, any>","consentReason: string | undefined","consentPromptRawData: any","purposes: any[]","found: any","submitAction: any","reason: string | undefined","decisions: any","effectiveExecutionIdForPasskey: any","responseFieldErrors: FieldError[] | undefined","timeoutMs: number","actionId: string | undefined","timerId: ReturnType<typeof setTimeout>","inputs: Record<string, string>","passkeyResponse: any","passkeyResponseObj: any","renderPropFieldErrors: Record<string, string>","BaseSignIn"],"sources":["../../../../src/components/auth/SignIn/SignIn.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ThunderIDRuntimeError,\n ThunderIDAPIError,\n ConsentConstants,\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/auth/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 * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n\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 * Sentinel input key carrying the reason a consent prompt was submitted. It is folded into the\n * compiled `consent_decisions` payload and stripped from the inputs, like `__consent_opt__` keys.\n */\nconst CONSENT_REASON_KEY = '__consent_reason__';\n\n/** Flattens a component tree into a single list, parents before their children. */\nconst flattenComponents = (comps: EmbeddedFlowComponent[] | undefined): EmbeddedFlowComponent[] =>\n (comps ?? []).flatMap((comp: EmbeddedFlowComponent) => [comp, ...flattenComponents(comp.components)]);\n\n/**\n * Finds the action to submit an expired consent prompt with. A non-primary submit action is\n * preferred so the payload reads as a denial, falling back to any submit action because the server\n * needs an action to route the prompt node. Returns undefined when the view has neither.\n */\nconst findConsentSubmitActionId = (comps: EmbeddedFlowComponent[] | undefined): string | undefined => {\n const submitActions: EmbeddedFlowComponent[] = flattenComponents(comps).filter(\n (comp: EmbeddedFlowComponent) => comp.id && comp.eventType?.toUpperCase() === 'SUBMIT',\n );\n const denyAction: EmbeddedFlowComponent | undefined = submitActions.find(\n (comp: EmbeddedFlowComponent) => comp.variant?.toLowerCase() !== 'primary',\n );\n\n return (denyAction ?? submitActions[0])?.id;\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 revalidateOnChangeAfterBlur,\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 // Deadline this component has already auto-submitted for, so a re-run of the timeout effect\n // cannot submit the same expired step twice.\n const timeoutSubmittedForRef = useRef<number | null>(null);\n // The timeout effect is keyed on the deadline alone, so a step that arrives carrying the same\n // deadline would otherwise leave the pending timer holding the previous step's context.\n const timeoutContextRef = useRef<{\n components: EmbeddedFlowComponent[];\n hasConsentPrompt: boolean;\n submit: (payload: EmbeddedSignInFlowRequest) => Promise<void>;\n } | null>(null);\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 // Clear the expired flow state to prevent rendering a stale form with a null executionId.\n // Kept before the first await so callers that do not await this function still apply the\n // reset in one batch, ahead of the setError that follows.\n setExecutionId(null);\n setComponents([]);\n setAdditionalData({});\n setIsFlowInitialized(false);\n await setChallengeToken(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 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 ERROR and COMPLETE responses. Returns true if fully handled.\n * ERROR + executionId: recoverable — session preserved for retry.\n * ERROR + no executionId: terminal — clear state and surface the error.\n */\n const handleTerminalResponse = async (response: EmbeddedSignInFlowResponse): Promise<boolean> => {\n if (response.flowStatus === EmbeddedSignInFlowStatus.Error) {\n // Propagate OAuth error to the client\n if (response.redirectUrl && window?.location) {\n setIsSubmitting(false);\n await clearFlowState();\n cleanupOAuthUrlParams(true);\n onError?.(new Error(extractErrorMessage(response, t)));\n window.location.href = response.redirectUrl;\n\n return true;\n }\n\n if (response.executionId) {\n // Recoverable: session still alive. Show inline error without firing onError.\n setExecutionId(response.executionId);\n await setChallengeToken(response.challengeToken ?? null);\n setIsFlowInitialized(true);\n setFlowError(new Error(extractErrorMessage(response, t)));\n return true;\n }\n // Terminal: backend invalidated the session — clear all state.\n await clearFlowState();\n setError(new Error(extractErrorMessage(response, t)));\n cleanupFlowUrlParams();\n return true;\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\n return;\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 // Only reset the init gate for unrecoverable Error responses so the user can retry;\n // Complete-without-redirect would otherwise kick off a fresh flow unintentionally.\n if (response.flowStatus === EmbeddedSignInFlowStatus.Error && !response.executionId) {\n initializationAttemptedRef.current = 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 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 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 // Read and strip the sentinel up front so it can never reach the wire as an input\n const consentReason: string | undefined = processedInputs[CONSENT_REASON_KEY];\n delete processedInputs[CONSENT_REASON_KEY];\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 // An expired prompt is never an approval, whichever action carried the submission\n if (consentReason === ConsentConstants.REASON_TIMEOUT) {\n isDeny = true;\n }\n\n // An explicit denial carries a reason too, so the server never has to infer one\n const reason: string | undefined = consentReason ?? (isDeny ? ConsentConstants.REASON_USER_DENIED : undefined);\n\n const decisions: any = {\n approved: !isDeny,\n ...(reason ? {reason} : {}),\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 && processedInputs[key] === 'true',\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 // Handle terminal flow statuses before normalization.\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 // 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 step timeout if configured in additionalData.\n *\n * An expired consent prompt is auto-submitted as a denial carrying the timeout reason, because its\n * actions no longer lead anywhere and the user would otherwise be stranded on the prompt. The\n * server discards those decisions and records nothing. Every other kind of step surfaces the\n * expiry error instead.\n */\n timeoutContextRef.current = {\n components,\n hasConsentPrompt: Boolean(additionalData?.['consentPrompt']),\n submit: handleSubmit,\n };\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 handleTimeout = (): void => {\n setIsTimeoutDisabled(true);\n\n const expiredError = (): Error =>\n new Error(t('errors.signin.timeout') || 'Time allowed to complete the step has expired.');\n\n // Read through the ref so the timer always sees the step that is on screen when it fires\n const context = timeoutContextRef.current;\n const actionId: string | undefined = context?.hasConsentPrompt\n ? findConsentSubmitActionId(context.components)\n : undefined;\n\n // Without an action the prompt node cannot be routed, so there is nothing to submit\n if (actionId && context && timeoutSubmittedForRef.current !== timeoutMs) {\n timeoutSubmittedForRef.current = timeoutMs;\n context\n .submit({action: actionId, inputs: {[CONSENT_REASON_KEY]: ConsentConstants.REASON_TIMEOUT}})\n .catch(() => setError(expiredError()));\n return;\n }\n\n setError(expiredError());\n };\n\n const timerId: ReturnType<typeof setTimeout> = setTimeout(handleTimeout, Math.max(0, timeoutMs - Date.now()));\n\n return () => clearTimeout(timerId);\n }, [additionalData?.['stepTimeout'], isFlowInitialized, t]);\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 revalidateOnChangeAfterBlur={revalidateOnChangeAfterBlur}\n serverFieldErrors={serverFieldErrors}\n />\n );\n};\n\nexport default SignIn;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SignIn.js","names":["submitActions: EmbeddedFlowComponent[]","SignIn: FC<SignInProps>","useThunderID","useTranslation","challengeTokenRef: any","initializationAttemptedRef: any","oauthCodeProcessedRef: any","passkeyProcessedRef: any","tempData: any","storageManager: any","urlParams: any","url: any","redirectURL: any","finalRedirectUrl: any","effectiveApplicationId: any","storedExecutionId: any","resumeExecutionId: any","response: EmbeddedSignInFlowResponse","err: any","currentUrlParams: any","effectiveExecutionId: any","processedInputs: Record<string, any>","consentReason: string | undefined","consentPromptRawData: any","purposes: any[]","found: any","submitAction: any","isConsentApprovalBlocked","reason: string | undefined","decisions: any","approved: boolean","effectiveExecutionIdForPasskey: any","responseFieldErrors: FieldError[] | undefined","timeoutMs: number","actionId: string | undefined","timerId: ReturnType<typeof setTimeout>","inputs: Record<string, string>","passkeyResponse: any","passkeyResponseObj: any","renderPropFieldErrors: Record<string, string>","BaseSignIn"],"sources":["../../../../src/components/auth/SignIn/SignIn.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ThunderIDRuntimeError,\n ThunderIDAPIError,\n ConsentConstants,\n EmbeddedFlowComponent,\n EmbeddedFlowType,\n EmbeddedSignInFlowResponse,\n EmbeddedSignInFlowRequest,\n EmbeddedSignInFlowStatus,\n EmbeddedSignInFlowType,\n FieldError,\n FlowMetadataResponse,\n Preferences,\n logger,\n CONSENT_INVALID_KEY_PREFIX,\n CONSENT_MODIFIED_KEY_PREFIX,\n getConsentElementDecision,\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/auth/useOAuthCallback';\nimport useTranslation from '../../../hooks/useTranslation';\nimport {extractErrorMessage, normalizeFlowResponse} from '../../../utils/flowTransformer';\nimport isConsentApprovalBlocked from '../../../utils/isConsentApprovalBlocked';\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 * When a field has been blurred at least once, re-run validation on every subsequent\n * keystroke so a rendered error clears the moment the value becomes valid. Doesn't\n * affect fields that have never been blurred — the user isn't shown errors while\n * initially typing. Default `false` preserves prior behavior.\n */\n revalidateOnChangeAfterBlur?: boolean;\n\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 * Sentinel input key carrying the reason a consent prompt was submitted. It is folded into the\n * compiled `consent_decisions` payload and stripped from the inputs, like `__consent_opt__` keys.\n */\nconst CONSENT_REASON_KEY = '__consent_reason__';\n\n/** Flattens a component tree into a single list, parents before their children. */\nconst flattenComponents = (comps: EmbeddedFlowComponent[] | undefined): EmbeddedFlowComponent[] =>\n (comps ?? []).flatMap((comp: EmbeddedFlowComponent) => [comp, ...flattenComponents(comp.components)]);\n\n/**\n * Finds the action to submit an expired consent prompt with. A non-primary submit action is\n * preferred so the payload reads as a denial, falling back to any submit action because the server\n * needs an action to route the prompt node. Returns undefined when the view has neither.\n */\nconst findConsentSubmitActionId = (comps: EmbeddedFlowComponent[] | undefined): string | undefined => {\n const submitActions: EmbeddedFlowComponent[] = flattenComponents(comps).filter(\n (comp: EmbeddedFlowComponent) => comp.id && comp.eventType?.toUpperCase() === 'SUBMIT',\n );\n const denyAction: EmbeddedFlowComponent | undefined = submitActions.find(\n (comp: EmbeddedFlowComponent) => comp.variant?.toLowerCase() !== 'primary',\n );\n\n return (denyAction ?? submitActions[0])?.id;\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 revalidateOnChangeAfterBlur,\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 // Deadline this component has already auto-submitted for, so a re-run of the timeout effect\n // cannot submit the same expired step twice.\n const timeoutSubmittedForRef = useRef<number | null>(null);\n // The timeout effect is keyed on the deadline alone, so a step that arrives carrying the same\n // deadline would otherwise leave the pending timer holding the previous step's context.\n const timeoutContextRef = useRef<{\n components: EmbeddedFlowComponent[];\n hasConsentPrompt: boolean;\n submit: (payload: EmbeddedSignInFlowRequest) => Promise<void>;\n } | null>(null);\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 // Clear the expired flow state to prevent rendering a stale form with a null executionId.\n // Kept before the first await so callers that do not await this function still apply the\n // reset in one batch, ahead of the setError that follows.\n setExecutionId(null);\n setComponents([]);\n setAdditionalData({});\n setIsFlowInitialized(false);\n await setChallengeToken(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 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 ERROR and COMPLETE responses. Returns true if fully handled.\n * ERROR + executionId: recoverable — session preserved for retry.\n * ERROR + no executionId: terminal — clear state and surface the error.\n */\n const handleTerminalResponse = async (response: EmbeddedSignInFlowResponse): Promise<boolean> => {\n if (response.flowStatus === EmbeddedSignInFlowStatus.Error) {\n // Propagate OAuth error to the client\n if (response.redirectUrl && window?.location) {\n setIsSubmitting(false);\n await clearFlowState();\n cleanupOAuthUrlParams(true);\n onError?.(new Error(extractErrorMessage(response, t)));\n window.location.href = response.redirectUrl;\n\n return true;\n }\n\n if (response.executionId) {\n // Recoverable: session still alive. Show inline error without firing onError.\n setExecutionId(response.executionId);\n await setChallengeToken(response.challengeToken ?? null);\n setIsFlowInitialized(true);\n setFlowError(new Error(extractErrorMessage(response, t)));\n return true;\n }\n // Terminal: backend invalidated the session — clear all state.\n await clearFlowState();\n setError(new Error(extractErrorMessage(response, t)));\n cleanupFlowUrlParams();\n return true;\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\n return;\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 // Only reset the init gate for unrecoverable Error responses so the user can retry;\n // Complete-without-redirect would otherwise kick off a fresh flow unintentionally.\n if (response.flowStatus === EmbeddedSignInFlowStatus.Error && !response.executionId) {\n initializationAttemptedRef.current = 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 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 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 // Read and strip the sentinel up front so it can never reach the wire as an input\n const consentReason: string | undefined = processedInputs[CONSENT_REASON_KEY];\n delete processedInputs[CONSENT_REASON_KEY];\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 // An expired prompt is never an approval, whichever action carried the submission\n if (consentReason === ConsentConstants.REASON_TIMEOUT) {\n isDeny = true;\n }\n\n // Approval waits while an approved authorization detail shows a value that cannot be submitted\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n if (!isDeny && isConsentApprovalBlocked(purposes, processedInputs)) {\n return;\n }\n\n // An explicit denial carries a reason too, so the server never has to infer one\n const reason: string | undefined = consentReason ?? (isDeny ? ConsentConstants.REASON_USER_DENIED : undefined);\n\n const decisions: any = {\n approved: !isDeny,\n ...(reason ? {reason} : {}),\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 const approved: boolean = !isDeny && processedInputs[key] === 'true';\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n return getConsentElementDecision(p.purposeId, e, approved, processedInputs);\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 (\n key.startsWith('__consent_opt__') ||\n key.startsWith(CONSENT_MODIFIED_KEY_PREFIX) ||\n key.startsWith(CONSENT_INVALID_KEY_PREFIX)\n ) {\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 // Handle terminal flow statuses before normalization.\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 // 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 step timeout if configured in additionalData.\n *\n * An expired consent prompt is auto-submitted as a denial carrying the timeout reason, because its\n * actions no longer lead anywhere and the user would otherwise be stranded on the prompt. The\n * server discards those decisions and records nothing. Every other kind of step surfaces the\n * expiry error instead.\n */\n timeoutContextRef.current = {\n components,\n hasConsentPrompt: Boolean(additionalData?.['consentPrompt']),\n submit: handleSubmit,\n };\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 handleTimeout = (): void => {\n setIsTimeoutDisabled(true);\n\n const expiredError = (): Error =>\n new Error(t('errors.signin.timeout') || 'Time allowed to complete the step has expired.');\n\n // Read through the ref so the timer always sees the step that is on screen when it fires\n const context = timeoutContextRef.current;\n const actionId: string | undefined = context?.hasConsentPrompt\n ? findConsentSubmitActionId(context.components)\n : undefined;\n\n // Without an action the prompt node cannot be routed, so there is nothing to submit\n if (actionId && context && timeoutSubmittedForRef.current !== timeoutMs) {\n timeoutSubmittedForRef.current = timeoutMs;\n context\n .submit({action: actionId, inputs: {[CONSENT_REASON_KEY]: ConsentConstants.REASON_TIMEOUT}})\n .catch(() => setError(expiredError()));\n return;\n }\n\n setError(expiredError());\n };\n\n const timerId: ReturnType<typeof setTimeout> = setTimeout(handleTimeout, Math.max(0, timeoutMs - Date.now()));\n\n return () => clearTimeout(timerId);\n }, [additionalData?.['stepTimeout'], isFlowInitialized, t]);\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 revalidateOnChangeAfterBlur={revalidateOnChangeAfterBlur}\n serverFieldErrors={serverFieldErrors}\n />\n );\n};\n\nexport default SignIn;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthOptionFactory.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/flow/AuthOptionFactory.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGL,oBAAoB,EACpB,qBAAqB,EAarB,4BAA4B,EAI5B,cAAc,EACd,cAAc,EACd,UAAU,
|
|
1
|
+
{"version":3,"file":"AuthOptionFactory.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/flow/AuthOptionFactory.tsx"],"names":[],"mappings":"AAIA,OAAO,EAGL,oBAAoB,EACpB,qBAAqB,EAarB,4BAA4B,EAI5B,cAAc,EACd,cAAc,EACd,UAAU,EAEX,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAsD,YAAY,EAAC,MAAM,OAAO,CAAC;AAMxF,OAAO,EAGL,oBAAoB,EACrB,MAAM,8DAA8D,CAAC;AACtE,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAqF7D,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAuzBxD;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,YAAY,qBAAqB,EAAE,EACnC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,WAAW,OAAO,EAClB,aAAa,OAAO,EACpB,WAAW,MAAM,IAAI,EACrB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EACpD,UAAU;IACR,gBAAgB;IAChB,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,gBAAgB;IAChB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,qBAAqB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5G,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,+EAA+E;IAC/E,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KACA,YAAY,EAmBkC,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,YAAY,qBAAqB,EAAE,EACnC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,WAAW,OAAO,EAClB,aAAa,OAAO,EACpB,WAAW,MAAM,IAAI,EACrB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EACpD,UAAU;IACR,gBAAgB;IAChB,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,gBAAgB;IAChB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,qBAAqB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5G,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,+EAA+E;IAC/E,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KACA,YAAY,EAmBkC,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,wBAAwB,GACnC,YAAY,qBAAqB,EAAE,EACnC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,WAAW,OAAO,EAClB,aAAa,OAAO,EACpB,WAAW,MAAM,IAAI,EACrB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EACpD,UAAU;IACR,gBAAgB;IAChB,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,gBAAgB;IAChB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,qBAAqB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5G,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,+EAA+E;IAC/E,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KACA,YAAY,EAmBkC,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,YAAY,qBAAqB,EAAE,EACnC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,WAAW,OAAO,EAClB,aAAa,OAAO,EACpB,WAAW,MAAM,IAAI,EACrB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EACpD,UAAU;IACR,gBAAgB;IAChB,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC,gBAAgB;IAChB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,6BAA6B,CAAC,EAAE,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,2EAA2E;IAC3E,IAAI,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,4FAA4F;IAC5F,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,qBAAqB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5G,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,+EAA+E;IAC/E,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KACA,YAAY,EAmBkC,CAAC"}
|
|
@@ -3,6 +3,7 @@ import Button_default from "../../primitives/Button/Button.js";
|
|
|
3
3
|
import { affixPostfixKey, affixPrefixKey } from "../../../utils/composeAffixedInputs.js";
|
|
4
4
|
import Typography_default from "../../primitives/Typography/Typography.js";
|
|
5
5
|
import { getConsentOptionalKey } from "./ConsentCheckboxList.js";
|
|
6
|
+
import isConsentApprovalBlocked_default from "../../../utils/isConsentApprovalBlocked.js";
|
|
6
7
|
import Consent_default from "./Consent.js";
|
|
7
8
|
import DatePicker_default from "../../primitives/DatePicker/DatePicker.js";
|
|
8
9
|
import Select_default from "../../primitives/Select/Select.js";
|
|
@@ -24,7 +25,7 @@ import LinkedInButton_default from "../buttons/LinkedInButton.js";
|
|
|
24
25
|
import MicrosoftButton_default from "../buttons/MicrosoftButton.js";
|
|
25
26
|
import SignInWithEthereumButton_default from "../buttons/SignInWithEthereumButton.js";
|
|
26
27
|
import SmsOtpButton_default from "../buttons/SmsOtpButton.js";
|
|
27
|
-
import { ConsentConstants, EmbeddedFlowComponentType, EmbeddedFlowEventType, FieldType, createPackageComponentLogger, parseKeyValuePairs, resolveEmojiUrisInHtml, resolveFlowTemplateLiterals } from "@thunderid/browser";
|
|
28
|
+
import { ConsentConstants, EmbeddedFlowComponentType, EmbeddedFlowEventType, FieldType, createPackageComponentLogger, getConsentElementDecision, parseKeyValuePairs, resolveEmojiUrisInHtml, resolveFlowTemplateLiterals } from "@thunderid/browser";
|
|
28
29
|
import { cloneElement } from "react";
|
|
29
30
|
import { jsx } from "react/jsx-runtime";
|
|
30
31
|
import DOMPurify from "dompurify";
|
|
@@ -265,6 +266,7 @@ const createAuthComponentFromFlow = (component, formValues, touchedFields, formE
|
|
|
265
266
|
[EmbeddedFlowEventType.Trigger]: "button",
|
|
266
267
|
[EmbeddedFlowEventType.Back]: "button"
|
|
267
268
|
}[eventType.toUpperCase()] ?? "submit";
|
|
269
|
+
const hasInvalidConsentApproval = !shouldSkipValidation && componentVariant.toLowerCase() === "primary" && isConsentApprovalBlocked_default((options.additionalData?.["consentPrompt"])?.purposes ?? [], formValues);
|
|
268
270
|
const handleClick = () => {
|
|
269
271
|
if (options.onSubmit) {
|
|
270
272
|
const formData = {};
|
|
@@ -282,10 +284,7 @@ const createAuthComponentFromFlow = (component, formValues, touchedFields, formE
|
|
|
282
284
|
elements: [...(p.essential ?? []).map((e) => ({
|
|
283
285
|
approved: !isDeny,
|
|
284
286
|
name: e.name
|
|
285
|
-
})), ...(p.optional ?? []).map((e) => (
|
|
286
|
-
approved: !isDeny && formValues[getConsentOptionalKey(p.purposeId, e.name)] === "true",
|
|
287
|
-
name: e.name
|
|
288
|
-
}))],
|
|
287
|
+
})), ...(p.optional ?? []).map((e) => getConsentElementDecision(p.purposeId, e, !isDeny && formValues[getConsentOptionalKey(p.purposeId, e.name)] === "true", formValues))],
|
|
289
288
|
purposeName: p.purposeName
|
|
290
289
|
}))
|
|
291
290
|
};
|
|
@@ -350,7 +349,7 @@ const createAuthComponentFromFlow = (component, formValues, touchedFields, formE
|
|
|
350
349
|
fullWidth: true,
|
|
351
350
|
id: component.id,
|
|
352
351
|
onClick: handleClick,
|
|
353
|
-
disabled: isLoading || !isFormValid && !shouldSkipValidation || options.isTimeoutDisabled || component.config?.disabled,
|
|
352
|
+
disabled: isLoading || !isFormValid && !shouldSkipValidation || hasInvalidConsentApproval || options.isTimeoutDisabled || component.config?.disabled,
|
|
354
353
|
className: cx(options.buttonClassName, component.classes),
|
|
355
354
|
"data-testid": "thunderid-signin-submit",
|
|
356
355
|
variant: component.variant?.toLowerCase() === "primary" ? "solid" : "outline",
|