@thunderid/react 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/api/{getScim2Me.d.ts → getUsersMe.d.ts} +11 -11
  2. package/dist/api/{getScim2Me.d.ts.map → getUsersMe.d.ts.map} +1 -1
  3. package/dist/api/{getScim2Me.js → getUsersMe.js} +12 -12
  4. package/dist/api/{getScim2Me.js.map → getUsersMe.js.map} +1 -1
  5. package/dist/api/updateMeProfile.d.ts +5 -5
  6. package/dist/api/updateMeProfile.js +6 -6
  7. package/dist/api/updateMeProfile.js.map +1 -1
  8. package/dist/cjs/api/{getScim2Me.cjs → getUsersMe.cjs} +11 -11
  9. package/dist/cjs/api/{getScim2Me.cjs.map → getUsersMe.cjs.map} +1 -1
  10. package/dist/cjs/api/updateMeProfile.cjs +6 -6
  11. package/dist/cjs/api/updateMeProfile.cjs.map +1 -1
  12. package/dist/cjs/components/presentation/UserProfile/BaseUserProfile.cjs +48 -58
  13. package/dist/cjs/components/presentation/UserProfile/BaseUserProfile.cjs.map +1 -1
  14. package/dist/cjs/components/presentation/UserProfile/UserProfile.cjs +21 -8
  15. package/dist/cjs/components/presentation/UserProfile/UserProfile.cjs.map +1 -1
  16. package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs +9 -1
  17. package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
  18. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs +52 -9
  19. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs.map +1 -1
  20. package/dist/cjs/components/presentation/auth/InviteUser/BaseInviteUser.cjs +11 -1
  21. package/dist/cjs/components/presentation/auth/InviteUser/BaseInviteUser.cjs.map +1 -1
  22. package/dist/cjs/components/presentation/auth/Recovery/BaseRecovery.cjs +18 -14
  23. package/dist/cjs/components/presentation/auth/Recovery/BaseRecovery.cjs.map +1 -1
  24. package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs +35 -9
  25. package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs.map +1 -1
  26. package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs +18 -13
  27. package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs.map +1 -1
  28. package/dist/cjs/components/primitives/AffixedField/AffixedField.cjs +88 -0
  29. package/dist/cjs/components/primitives/AffixedField/AffixedField.cjs.map +1 -0
  30. package/dist/cjs/components/primitives/AffixedField/AffixedField.styles.cjs +130 -0
  31. package/dist/cjs/components/primitives/AffixedField/AffixedField.styles.cjs.map +1 -0
  32. package/dist/cjs/contexts/ComponentRenderer/ComponentRendererContext.cjs.map +1 -1
  33. package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs +1 -0
  34. package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs.map +1 -1
  35. package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs +23 -7
  36. package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
  37. package/dist/cjs/contexts/User/UserContext.cjs +0 -1
  38. package/dist/cjs/contexts/User/UserContext.cjs.map +1 -1
  39. package/dist/cjs/contexts/User/UserProvider.cjs +0 -2
  40. package/dist/cjs/contexts/User/UserProvider.cjs.map +1 -1
  41. package/dist/cjs/contexts/User/useUser.cjs +0 -1
  42. package/dist/cjs/contexts/User/useUser.cjs.map +1 -1
  43. package/dist/cjs/index.cjs +2 -2
  44. package/dist/cjs/utils/composeAffixedInputs.cjs +74 -0
  45. package/dist/cjs/utils/composeAffixedInputs.cjs.map +1 -0
  46. package/dist/components/presentation/UserProfile/BaseUserProfile.d.ts +0 -20
  47. package/dist/components/presentation/UserProfile/BaseUserProfile.d.ts.map +1 -1
  48. package/dist/components/presentation/UserProfile/BaseUserProfile.js +50 -60
  49. package/dist/components/presentation/UserProfile/BaseUserProfile.js.map +1 -1
  50. package/dist/components/presentation/UserProfile/UserProfile.d.ts +1 -1
  51. package/dist/components/presentation/UserProfile/UserProfile.d.ts.map +1 -1
  52. package/dist/components/presentation/UserProfile/UserProfile.js +22 -9
  53. package/dist/components/presentation/UserProfile/UserProfile.js.map +1 -1
  54. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
  55. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js +9 -1
  56. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
  57. package/dist/components/presentation/auth/AuthOptionFactory.d.ts +12 -4
  58. package/dist/components/presentation/auth/AuthOptionFactory.d.ts.map +1 -1
  59. package/dist/components/presentation/auth/AuthOptionFactory.js +52 -9
  60. package/dist/components/presentation/auth/AuthOptionFactory.js.map +1 -1
  61. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.d.ts.map +1 -1
  62. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.js +11 -1
  63. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.js.map +1 -1
  64. package/dist/components/presentation/auth/Recovery/BaseRecovery.d.ts.map +1 -1
  65. package/dist/components/presentation/auth/Recovery/BaseRecovery.js +19 -15
  66. package/dist/components/presentation/auth/Recovery/BaseRecovery.js.map +1 -1
  67. package/dist/components/presentation/auth/SignIn/BaseSignIn.d.ts.map +1 -1
  68. package/dist/components/presentation/auth/SignIn/BaseSignIn.js +37 -11
  69. package/dist/components/presentation/auth/SignIn/BaseSignIn.js.map +1 -1
  70. package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts.map +1 -1
  71. package/dist/components/presentation/auth/SignUp/BaseSignUp.js +18 -13
  72. package/dist/components/presentation/auth/SignUp/BaseSignUp.js.map +1 -1
  73. package/dist/components/primitives/AffixedField/AffixedField.d.ts +52 -0
  74. package/dist/components/primitives/AffixedField/AffixedField.d.ts.map +1 -0
  75. package/dist/components/primitives/AffixedField/AffixedField.js +83 -0
  76. package/dist/components/primitives/AffixedField/AffixedField.js.map +1 -0
  77. package/dist/components/primitives/AffixedField/AffixedField.styles.d.ts +25 -0
  78. package/dist/components/primitives/AffixedField/AffixedField.styles.d.ts.map +1 -0
  79. package/dist/components/primitives/AffixedField/AffixedField.styles.js +127 -0
  80. package/dist/components/primitives/AffixedField/AffixedField.styles.js.map +1 -0
  81. package/dist/components/primitives/AffixedField/index.d.ts +20 -0
  82. package/dist/components/primitives/AffixedField/index.d.ts.map +1 -0
  83. package/dist/components/primitives/Dialog/Dialog.js +3 -3
  84. package/dist/components/primitives/Dialog/Dialog.js.map +1 -1
  85. package/dist/contexts/ComponentRenderer/ComponentRendererContext.d.ts +1 -0
  86. package/dist/contexts/ComponentRenderer/ComponentRendererContext.d.ts.map +1 -1
  87. package/dist/contexts/ComponentRenderer/ComponentRendererContext.js.map +1 -1
  88. package/dist/contexts/ThunderID/ThunderIDContext.d.ts +1 -0
  89. package/dist/contexts/ThunderID/ThunderIDContext.d.ts.map +1 -1
  90. package/dist/contexts/ThunderID/ThunderIDContext.js +1 -0
  91. package/dist/contexts/ThunderID/ThunderIDContext.js.map +1 -1
  92. package/dist/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
  93. package/dist/contexts/ThunderID/ThunderIDProvider.js +23 -7
  94. package/dist/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
  95. package/dist/contexts/User/UserContext.d.ts +1 -2
  96. package/dist/contexts/User/UserContext.d.ts.map +1 -1
  97. package/dist/contexts/User/UserContext.js +0 -1
  98. package/dist/contexts/User/UserContext.js.map +1 -1
  99. package/dist/contexts/User/UserProvider.d.ts +0 -1
  100. package/dist/contexts/User/UserProvider.d.ts.map +1 -1
  101. package/dist/contexts/User/UserProvider.js +0 -2
  102. package/dist/contexts/User/UserProvider.js.map +1 -1
  103. package/dist/contexts/User/useUser.d.ts +0 -1
  104. package/dist/contexts/User/useUser.d.ts.map +1 -1
  105. package/dist/contexts/User/useUser.js +0 -1
  106. package/dist/contexts/User/useUser.js.map +1 -1
  107. package/dist/index.d.ts +2 -2
  108. package/dist/index.js +2 -2
  109. package/dist/utils/composeAffixedInputs.d.ts +52 -0
  110. package/dist/utils/composeAffixedInputs.d.ts.map +1 -0
  111. package/dist/utils/composeAffixedInputs.js +70 -0
  112. package/dist/utils/composeAffixedInputs.js.map +1 -0
  113. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"BaseUserProfile.cjs","names":["fieldsToSkip: string[]","readonlyFields: string[]","BaseUserProfile: FC<BaseUserProfileProps>","useTheme","useTranslation","shouldShowField: any","toggleFieldEdit: any","getFieldPlaceholder: any","fieldLabel: any","formatLabel: any","styles: any","useStyles","ObjectDisplay: FC<{data: unknown}>","keys: any","current: any","i: any","key: any","handleFieldSave: any","fieldName: string","fieldValue: any","payload: Record<string, any>","WellKnownSchemaIds","handleFieldCancel: any","currentUser: any","currentUser","mergedMappings: Record<string, string | string[]>","label: any","displayValue: string","displayValue","hasValues: any","isEditable: any","isEditable","currentValue: any","fieldValues: string[]","MultiInput","Button","commonProps: any","field: ReactElement","TextField","DatePicker","Checkbox","hasValue: any","isFieldEditing: any","isReadonlyField: any","tempEditedUser: any","containerClasses: any","displayName: any","getDisplayName","profileEntries: any","Avatar","getMappedUserProfileValue","Typography","Divider","profileContent: any","CardPrimitive","AlertPrimitive","value: any","schemaWithValue: any","DialogPrimitive"],"sources":["../../../../../src/components/presentation/UserProfile/BaseUserProfile.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {cx} from '@emotion/css';\nimport {User, withVendorCSSClassPrefix, WellKnownSchemaIds, bem, Preferences} from '@thunderid/browser';\nimport {FC, ReactElement, useState, useCallback} from 'react';\nimport useStyles from './BaseUserProfile.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useTranslation from '../../../hooks/useTranslation';\nimport getDisplayName from '../../../utils/getDisplayName';\nimport getMappedUserProfileValue from '../../../utils/getMappedUserProfileValue';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\nimport {Avatar} from '../../primitives/Avatar/Avatar';\nimport Button from '../../primitives/Button/Button';\nimport CardPrimitive from '../../primitives/Card/Card';\nimport Checkbox from '../../primitives/Checkbox/Checkbox';\nimport DatePicker from '../../primitives/DatePicker/DatePicker';\nimport DialogPrimitive from '../../primitives/Dialog/Dialog';\nimport Divider from '../../primitives/Divider/Divider';\nimport MultiInput from '../../primitives/MultiInput/MultiInput';\nimport TextField from '../../primitives/TextField/TextField';\nimport Typography from '../../primitives/Typography/Typography';\n\ninterface ExtendedFlatSchema {\n path?: string;\n schemaId?: string;\n}\n\ninterface Schema extends ExtendedFlatSchema {\n caseExact?: boolean;\n description?: string;\n displayName?: string;\n displayOrder?: string;\n multiValued?: boolean;\n mutability?: string;\n name?: string;\n required?: boolean;\n returned?: string;\n subAttributes?: Schema[];\n type?: string;\n uniqueness?: string;\n value?: any;\n}\n\nexport interface BaseUserProfileProps {\n attributeMapping?: {\n [key: string]: string | string[] | undefined;\n firstName?: string | string[];\n lastName?: string | string[];\n picture?: string | string[];\n username?: string | string[];\n };\n cardLayout?: boolean;\n className?: string;\n displayNameAttributes?: string[];\n editable?: boolean;\n error?: string | null;\n fallback?: ReactElement | null;\n flattenedProfile?: User;\n hideFields?: string[];\n isLoading?: boolean;\n mode?: 'inline' | 'popup';\n onOpenChange?: (open: boolean) => void;\n onUpdate?: (payload: any) => Promise<void>;\n open?: boolean;\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 profile?: User;\n schemas?: Schema[];\n showFields?: string[];\n\n title?: string;\n}\n\n// Fields to skip based on schema.name\nconst fieldsToSkip: string[] = [\n 'roles.default',\n 'active',\n 'groups',\n 'accountLocked',\n 'accountDisabled',\n 'oneTimePassword',\n 'userSourceId',\n 'idpType',\n 'localCredentialExists',\n 'active',\n 'ResourceType',\n 'ExternalID',\n 'MetaData',\n 'verifiedMobileNumbers',\n 'verifiedEmailAddresses',\n 'phoneNumbers.mobile',\n 'emailAddresses',\n 'preferredMFAOption',\n];\n\n// Fields that should be readonly\nconst readonlyFields: string[] = ['username', 'userName', 'user_name'];\n\nconst BaseUserProfile: FC<BaseUserProfileProps> = ({\n fallback = null,\n className = '',\n cardLayout = true,\n profile,\n schemas = [],\n flattenedProfile,\n mode = 'inline',\n title,\n attributeMapping = {},\n editable = true,\n onOpenChange,\n onUpdate,\n open = false,\n error = null,\n isLoading = false,\n preferences,\n showFields = [],\n hideFields = [],\n displayNameAttributes = [],\n}: BaseUserProfileProps): ReactElement | null => {\n const {theme, colorScheme} = useTheme();\n const [editedUser, setEditedUser] = useState(flattenedProfile || profile);\n const [editingFields, setEditingFields] = useState<Record<string, boolean>>({});\n const {t} = useTranslation(preferences?.i18n);\n\n /**\n * Determines if a field should be visible based on showFields, hideFields, and fieldsToSkip arrays.\n * Priority order:\n * 1. fieldsToSkip (always hidden) - highest priority\n * 2. hideFields (explicitly hidden)\n * 3. showFields (explicitly shown, if array is not empty)\n * 4. Default behavior (show all fields not in fieldsToSkip)\n */\n const shouldShowField: any = useCallback(\n (fieldName: string): boolean => {\n // Always skip fields in the hardcoded fieldsToSkip array\n if (fieldsToSkip.includes(fieldName)) {\n return false;\n }\n\n // If hideFields is provided and contains this field, hide it\n if (hideFields.length > 0 && hideFields.includes(fieldName)) {\n return false;\n }\n\n // If showFields is provided and not empty, only show fields in that array\n if (showFields.length > 0) {\n return showFields.includes(fieldName);\n }\n\n return true;\n },\n [showFields, hideFields],\n );\n\n const PencilIcon = (): any => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z\" />\n </svg>\n );\n\n const toggleFieldEdit: any = useCallback((fieldName: string) => {\n setEditingFields((prev: any) => ({\n ...prev,\n [fieldName]: !prev[fieldName],\n }));\n }, []);\n\n const getFieldPlaceholder: any = useCallback((schema: Schema): string => {\n const {type, displayName, description, name} = schema;\n\n const fieldLabel: any = displayName || description || name || 'value';\n\n switch (type) {\n case 'DATE_TIME':\n return `Enter your ${fieldLabel.toLowerCase()}`;\n case 'BOOLEAN':\n return `Select ${fieldLabel.toLowerCase()}`;\n case 'COMPLEX':\n return `Enter ${fieldLabel.toLowerCase()} details`;\n default:\n return `Enter your ${fieldLabel.toLowerCase()}`;\n }\n }, []);\n\n const formatLabel: any = useCallback(\n (key: string): string =>\n key\n .split(/(?=[A-Z])|_/)\n .map((word: any) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' '),\n [],\n );\n\n const styles: any = useStyles(theme, colorScheme);\n\n const ObjectDisplay: FC<{data: unknown}> = ({data}: {data: unknown}): ReactElement | null => {\n if (!data || typeof data !== 'object') return null;\n\n return (\n <table className={styles.value}>\n <tbody>\n {Object.entries(data).map(([key, value]: any) => (\n <tr key={key}>\n <td className={styles.objectKey}>\n <strong>{formatLabel(key)}:</strong>\n </td>\n <td className={styles.objectValue}>\n {typeof value === 'object' ? <ObjectDisplay data={value} /> : String(value)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n };\n\n function set(obj: Record<string, any>, path: string, value: any): void {\n const keys: any = path.split('.');\n let current: any = obj;\n\n for (let i: any = 0; i < keys.length; i += 1) {\n const key: any = keys[i];\n\n if (i === keys.length - 1) {\n current[key] = value;\n } else {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {};\n }\n current = current[key];\n }\n }\n }\n\n const handleFieldSave: any = useCallback(\n (schema: Schema): void => {\n if (!onUpdate || !schema.name) return;\n\n const fieldName: string = schema.name;\n let fieldValue: any;\n if (editedUser && fieldName && editedUser[fieldName] !== undefined) {\n fieldValue = editedUser[fieldName];\n } else if (flattenedProfile?.[fieldName] !== undefined) {\n fieldValue = flattenedProfile[fieldName];\n } else {\n fieldValue = '';\n }\n\n if (Array.isArray(fieldValue)) {\n fieldValue = fieldValue.filter((v: any) => v !== undefined && v !== null && v !== '');\n }\n\n let payload: Record<string, any> = {};\n\n // SCIM Patch Operation Logic:\n // - Fields from core schema (urn:ietf:params:scim:schemas:core:2.0:User)\n // should be sent directly: {\"name\":{\"givenName\":\"John\"}}\n // - Fields from extension schemas (like urn:scim:wso2:schema)\n // should be nested under the schema namespace: {\"urn:scim:wso2:schema\":{\"country\":\"Sri Lanka\"}}\n if (schema.schemaId && schema.schemaId !== WellKnownSchemaIds.User) {\n // For non-core schemas, nest the field under the schema namespace\n payload = {\n [schema.schemaId]: {\n [fieldName]: fieldValue,\n },\n };\n } else {\n // For core schema or fields without schemaId, use the field path directly\n // This handles complex paths like \"name.givenName\" correctly\n set(payload, fieldName, fieldValue);\n }\n\n onUpdate(payload);\n\n toggleFieldEdit(fieldName);\n },\n [editedUser, flattenedProfile, onUpdate, toggleFieldEdit],\n );\n\n const handleFieldCancel: any = useCallback(\n (fieldName: string) => {\n const currentUser: any = flattenedProfile || profile;\n setEditedUser((prev: any) => ({\n ...prev,\n [fieldName]: currentUser[fieldName],\n }));\n toggleFieldEdit(fieldName);\n },\n [flattenedProfile, profile, toggleFieldEdit],\n );\n\n const defaultAttributeMappings: Record<string, string | string[]> = {\n email: ['emails', 'email'],\n firstName: ['name.givenName', 'given_name'],\n lastName: ['name.familyName', 'family_name'],\n picture: ['profile', 'profileUrl', 'picture', 'URL'],\n username: ['userName', 'username', 'user_name'],\n };\n\n const mergedMappings: Record<string, string | string[]> = Object.fromEntries(\n Object.entries({...defaultAttributeMappings, ...attributeMapping}).filter(\n (entry): entry is [string, string | string[]] => entry[1] !== undefined,\n ),\n );\n\n const renderSchemaField = (\n schema: Schema,\n isEditing: boolean,\n onEditValue?: (value: any) => void,\n onStartEdit?: () => void,\n ): ReactElement | null => {\n if (!schema) return null;\n const {value, displayName, description, name, type, required, mutability, subAttributes, multiValued} = schema;\n const label: any = displayName || description || name || '';\n\n if (subAttributes && Array.isArray(subAttributes)) {\n return (\n <>\n {subAttributes.map((subAttr: any, index: any) => {\n let displayValue: string;\n if (Array.isArray(subAttr.value)) {\n displayValue = subAttr.value\n .map((item: any) => (typeof item === 'object' ? JSON.stringify(item) : String(item)))\n .join(', ');\n } else if (typeof subAttr.value === 'object') {\n displayValue = JSON.stringify(subAttr.value);\n } else {\n displayValue = String(subAttr.value);\n }\n\n return (\n <div key={index} className={styles.field}>\n <span className={styles.label}>{subAttr.displayName || subAttr.description || ''}</span>\n <div className={styles.value}>{displayValue}</div>\n </div>\n );\n })}\n </>\n );\n }\n\n if (Array.isArray(value) || multiValued) {\n const hasValues: any = Array.isArray(value)\n ? value.length > 0\n : value !== undefined && value !== null && value !== '';\n const isEditable: any = editable && mutability !== 'READ_ONLY' && !readonlyFields.includes(name || '');\n\n if (isEditing && onEditValue && isEditable) {\n let currentValue: any;\n if (editedUser && name && editedUser[name] !== undefined) {\n currentValue = editedUser[name];\n } else if (flattenedProfile && name && flattenedProfile[name] !== undefined) {\n currentValue = flattenedProfile[name];\n } else {\n currentValue = value;\n }\n\n let fieldValues: string[];\n if (Array.isArray(currentValue)) {\n fieldValues = currentValue.map(String);\n } else if (currentValue !== undefined && currentValue !== null && currentValue !== '') {\n fieldValues = [String(currentValue)];\n } else {\n fieldValues = [];\n }\n\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={styles.value}>\n <MultiInput\n values={fieldValues}\n onChange={(newValues: any): void => {\n if (multiValued || Array.isArray(currentValue)) {\n onEditValue(newValues);\n } else {\n onEditValue(newValues[0] || '');\n }\n }}\n placeholder={getFieldPlaceholder(schema)}\n fieldType={type as 'STRING' | 'DATE_TIME' | 'BOOLEAN'}\n type={type === 'DATE_TIME' ? 'date' : 'text'}\n required={required}\n />\n </div>\n </>\n );\n }\n\n let displayValue: string;\n if (hasValues) {\n if (Array.isArray(value)) {\n displayValue = value\n .map((item: any) => (typeof item === 'object' ? JSON.stringify(item) : String(item)))\n .join(', ');\n } else {\n displayValue = String(value);\n }\n } else if (isEditable) {\n displayValue = getFieldPlaceholder(schema);\n } else {\n displayValue = '-';\n }\n\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={cx(styles.value, !hasValues ? styles.valuePlaceholder : '')}>\n {!hasValues && isEditable && onStartEdit ? (\n <Button\n onClick={onStartEdit}\n variant=\"text\"\n color=\"secondary\"\n size=\"small\"\n title=\"Click to edit\"\n className={styles.editButton}\n >\n {displayValue}\n </Button>\n ) : (\n displayValue\n )}\n </div>\n </>\n );\n }\n if (type === 'COMPLEX' && typeof value === 'object') {\n return <ObjectDisplay data={value} />;\n }\n\n if (isEditing && onEditValue && mutability !== 'READ_ONLY' && !readonlyFields.includes(name || '')) {\n let fieldValue: any;\n if (editedUser && name && editedUser[name] !== undefined) {\n fieldValue = editedUser[name];\n } else if (flattenedProfile && name && flattenedProfile[name] !== undefined) {\n fieldValue = flattenedProfile[name];\n } else {\n fieldValue = value || '';\n }\n\n const commonProps: any = {\n label: undefined,\n onChange: (e: any) => onEditValue(e.target ? e.target.value : e),\n placeholder: getFieldPlaceholder(schema),\n required,\n value: fieldValue,\n // Removed inline style, use .styles.ts for marginBottom if needed\n };\n let field: ReactElement;\n switch (type) {\n case 'STRING':\n field = <TextField {...commonProps} />;\n break;\n case 'DATE_TIME':\n field = <DatePicker {...commonProps} />;\n break;\n case 'BOOLEAN':\n field = (\n <Checkbox\n {...commonProps}\n checked={!!fieldValue}\n onChange={(e: any): void => {\n onEditValue(e.target.checked);\n }}\n />\n );\n break;\n case 'COMPLEX':\n field = (\n <textarea\n value={fieldValue}\n onChange={(e: any): void => onEditValue(e.target.value)}\n placeholder={getFieldPlaceholder(schema)}\n required={required}\n className={styles.complexTextarea}\n />\n );\n break;\n default:\n field = <TextField {...commonProps} />;\n }\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={styles.value}>{field}</div>\n </>\n );\n }\n\n const hasValue: any = value !== undefined && value !== null && value !== '';\n const isEditable: any = editable && mutability !== 'READ_ONLY' && !readonlyFields.includes(name || '');\n\n let displayValue: string;\n if (hasValue) {\n displayValue = String(value);\n } else if (isEditable) {\n displayValue = getFieldPlaceholder(schema);\n } else {\n displayValue = '-';\n }\n\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={cx(styles.value, !hasValue ? styles.valuePlaceholder : '')}>\n {!hasValue && isEditable && onStartEdit ? (\n <Button\n onClick={onStartEdit}\n variant=\"text\"\n color=\"secondary\"\n size=\"small\"\n title=\"Click to edit\"\n className={styles.editButton}\n >\n {displayValue}\n </Button>\n ) : (\n displayValue\n )}\n </div>\n </>\n );\n };\n\n const renderUserInfo = (schema: Schema): any => {\n if (!schema?.name) return null;\n\n const hasValue: any = schema.value !== undefined && schema.value !== '' && schema.value !== null;\n const isFieldEditing: any = editingFields[schema.name];\n const isReadonlyField: any = readonlyFields.includes(schema.name);\n\n const shouldShow: any = hasValue || isFieldEditing || (editable && schema.mutability === 'READ_WRITE');\n\n if (!shouldShow) {\n return null;\n }\n\n return (\n <div className={styles.field}>\n <div className={styles.fieldInner}>\n {renderSchemaField(\n schema,\n isFieldEditing,\n (value: any) => {\n const tempEditedUser: any = {...editedUser};\n tempEditedUser[schema.name!] = value;\n setEditedUser(tempEditedUser);\n },\n () => toggleFieldEdit(schema.name),\n )}\n </div>\n {editable && schema.mutability !== 'READ_ONLY' && !isReadonlyField && (\n <div className={styles.fieldActions}>\n {isFieldEditing && (\n <>\n <Button size=\"small\" color=\"primary\" variant=\"solid\" onClick={(): any => handleFieldSave(schema)}>\n Save\n </Button>\n <Button\n size=\"small\"\n color=\"secondary\"\n variant=\"solid\"\n onClick={(): any => handleFieldCancel(schema.name)}\n >\n Cancel\n </Button>\n </>\n )}\n {!isFieldEditing && hasValue && (\n <Button\n size=\"small\"\n color=\"tertiary\"\n variant=\"icon\"\n onClick={(): any => toggleFieldEdit(schema.name)}\n title=\"Edit\"\n className={styles.editButton}\n >\n <PencilIcon />\n </Button>\n )}\n </div>\n )}\n </div>\n );\n };\n\n if (!profile && !flattenedProfile) {\n return fallback;\n }\n\n const containerClasses: any = cx(\n styles.root,\n cardLayout ? styles.card : '',\n withVendorCSSClassPrefix('user-profile'),\n className,\n );\n\n const currentUser: any = flattenedProfile || profile;\n\n const renderProfileWithoutSchemas = (): any => {\n if (!currentUser) return null;\n\n const displayName: any = getDisplayName(mergedMappings, profile!, displayNameAttributes);\n\n const profileEntries: any = Object.entries(currentUser)\n .filter(([key, value]: [string, any]) => {\n if (!shouldShowField(key)) return false;\n\n return value !== undefined && value !== '' && value !== null;\n })\n .sort(([a]: [string, ...any[]], [b]: [string, ...any[]]) => a.localeCompare(b));\n\n return (\n <>\n <div className={styles.profileSummary}>\n <Avatar\n imageUrl={getMappedUserProfileValue('picture', mergedMappings, currentUser)}\n name={displayName}\n size={70}\n alt={`${displayName}'s avatar`}\n isLoading={isLoading}\n />\n <Typography variant=\"h3\" fontWeight=\"medium\">\n {displayName}\n </Typography>\n {getMappedUserProfileValue('email', mergedMappings, currentUser) && (\n <Typography variant=\"body2\" color=\"textSecondary\">\n {getMappedUserProfileValue('email', mergedMappings, currentUser)}\n </Typography>\n )}\n </div>\n <Divider />\n {profileEntries.map(([key, value]: any, index: any) => (\n <div key={key}>\n <div className={styles.sectionRow}>\n <div className={styles.sectionLabel}>{formatLabel(key)}</div>\n <div className={styles.sectionValue}>\n {typeof value === 'object' ? <ObjectDisplay data={value} /> : String(value)}\n </div>\n </div>\n {index < profileEntries.length - 1 && <Divider />}\n </div>\n ))}\n </>\n );\n };\n\n const profileContent: any = (\n <CardPrimitive className={containerClasses}>\n {error && (\n <AlertPrimitive\n variant=\"error\"\n className={cx(withVendorCSSClassPrefix(bem('user-profile', 'alert')), styles.alert)}\n >\n <AlertPrimitive.Title>{t('errors.heading') || 'Error'}</AlertPrimitive.Title>\n <AlertPrimitive.Description>{error}</AlertPrimitive.Description>\n </AlertPrimitive>\n )}\n {schemas && schemas.length > 0 && (\n <div className={styles.header}>\n <Avatar\n imageUrl={getMappedUserProfileValue('picture', mergedMappings, currentUser)}\n name={getDisplayName(mergedMappings, profile!)}\n size={80}\n alt={`${getDisplayName(mergedMappings, profile!)}'s avatar`}\n isLoading={isLoading}\n />\n </div>\n )}\n <div className={styles.infoContainer}>\n {schemas && schemas.length > 0\n ? schemas\n .filter((schema: any) => {\n if (!schema.name || !shouldShowField(schema.name)) return false;\n\n if (!editable) {\n const value: any = flattenedProfile && schema.name ? flattenedProfile[schema.name] : undefined;\n return value !== undefined && value !== '' && value !== null;\n }\n\n return true;\n })\n .sort((a: any, b: any) => {\n const orderA: any = a.displayOrder ? parseInt(a.displayOrder, 10) : 999;\n const orderB: any = b.displayOrder ? parseInt(b.displayOrder, 10) : 999;\n return orderA - orderB;\n })\n .map((schema: any, index: any) => {\n const value: any = flattenedProfile && schema.name ? flattenedProfile[schema.name] : undefined;\n const schemaWithValue: any = {\n ...schema,\n value,\n };\n\n return (\n <div key={schema.name || index} className={styles.info}>\n {renderUserInfo(schemaWithValue)}\n </div>\n );\n })\n : renderProfileWithoutSchemas()}\n </div>\n </CardPrimitive>\n );\n\n if (mode === 'popup') {\n return (\n <DialogPrimitive open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Content>\n <DialogPrimitive.Heading>{title ?? t('user.profile.heading')}</DialogPrimitive.Heading>\n <div className={styles.popup}>{profileContent}</div>\n </DialogPrimitive.Content>\n </DialogPrimitive>\n );\n }\n\n return profileContent;\n};\n\nexport default BaseUserProfile;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BaseUserProfile.cjs","names":["fieldsToSkip: string[]","readonlyFields: string[]","BaseUserProfile: FC<BaseUserProfileProps>","useTheme","useTranslation","shouldShowField: any","toggleFieldEdit: any","getFieldPlaceholder: any","fieldLabel: any","formatLabel: any","styles: any","useStyles","ObjectDisplay: FC<{data: unknown}>","keys: any","current: any","i: any","key: any","handleFieldSave: any","fieldName: string","fieldValue: any","payload: Record<string, any>","handleFieldCancel: any","currentUser: any","currentUser","mergedMappings: Record<string, string | string[]>","label: any","displayValue: string","displayValue","hasValues: any","isEditable: any","isEditable","currentValue: any","fieldValues: string[]","MultiInput","Button","commonProps: any","field: ReactElement","TextField","DatePicker","Checkbox","hasValue: any","isFieldEditing: any","isReadonlyField: any","tempEditedUser: any","containerClasses: any","displayName: any","getDisplayName","profileEntries: any","Avatar","getMappedUserProfileValue","Typography","Divider","schemaWithValue: any","profileContent: any","CardPrimitive","AlertPrimitive","DialogPrimitive"],"sources":["../../../../../src/components/presentation/UserProfile/BaseUserProfile.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {cx} from '@emotion/css';\nimport {User, withVendorCSSClassPrefix, bem, Preferences, startCase} from '@thunderid/browser';\nimport {FC, ReactElement, useState, useCallback, useEffect} from 'react';\nimport useStyles from './BaseUserProfile.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useTranslation from '../../../hooks/useTranslation';\nimport getDisplayName from '../../../utils/getDisplayName';\nimport getMappedUserProfileValue from '../../../utils/getMappedUserProfileValue';\nimport AlertPrimitive from '../../primitives/Alert/Alert';\nimport {Avatar} from '../../primitives/Avatar/Avatar';\nimport Button from '../../primitives/Button/Button';\nimport CardPrimitive from '../../primitives/Card/Card';\nimport Checkbox from '../../primitives/Checkbox/Checkbox';\nimport DatePicker from '../../primitives/DatePicker/DatePicker';\nimport DialogPrimitive from '../../primitives/Dialog/Dialog';\nimport Divider from '../../primitives/Divider/Divider';\nimport MultiInput from '../../primitives/MultiInput/MultiInput';\nimport TextField from '../../primitives/TextField/TextField';\nimport Typography from '../../primitives/Typography/Typography';\n\ninterface ExtendedFlatSchema {\n path?: string;\n schemaId?: string;\n}\n\ninterface Schema extends ExtendedFlatSchema {\n caseExact?: boolean;\n description?: string;\n displayName?: string;\n displayOrder?: string;\n multiValued?: boolean;\n mutability?: string;\n name?: string;\n required?: boolean;\n returned?: string;\n subAttributes?: Schema[];\n type?: string;\n uniqueness?: string;\n value?: any;\n}\n\nexport interface BaseUserProfileProps {\n attributeMapping?: {\n [key: string]: string | string[] | undefined;\n firstName?: string | string[];\n lastName?: string | string[];\n picture?: string | string[];\n username?: string | string[];\n };\n cardLayout?: boolean;\n className?: string;\n displayNameAttributes?: string[];\n editable?: boolean;\n error?: string | null;\n fallback?: ReactElement | null;\n flattenedProfile?: User;\n hideFields?: string[];\n isLoading?: boolean;\n mode?: 'inline' | 'popup';\n onOpenChange?: (open: boolean) => void;\n onUpdate?: (payload: any) => Promise<void>;\n open?: boolean;\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 profile?: User;\n showFields?: string[];\n\n title?: string;\n}\n\n// Fields to skip based on schema.name\nconst fieldsToSkip: string[] = [\n 'roles.default',\n 'active',\n 'groups',\n 'accountLocked',\n 'accountDisabled',\n 'oneTimePassword',\n 'userSourceId',\n 'idpType',\n 'localCredentialExists',\n 'active',\n 'ResourceType',\n 'ExternalID',\n 'MetaData',\n 'verifiedMobileNumbers',\n 'verifiedEmailAddresses',\n 'phoneNumbers.mobile',\n 'emailAddresses',\n 'preferredMFAOption',\n 'attributes',\n 'picture',\n 'isReadOnly',\n 'isReadonly',\n];\n\n// Fields that should be readonly\nconst readonlyFields: string[] = ['attributes', 'id', 'isReadOnly', 'ouId', 'username'];\n\nconst BaseUserProfile: FC<BaseUserProfileProps> = ({\n fallback = null,\n className = '',\n cardLayout = true,\n profile,\n flattenedProfile,\n mode = 'inline',\n title,\n attributeMapping = {},\n editable = true,\n onOpenChange,\n onUpdate,\n open = false,\n error = null,\n isLoading = false,\n preferences,\n showFields = [],\n hideFields = [],\n displayNameAttributes = [],\n}: BaseUserProfileProps): ReactElement | null => {\n const {theme, colorScheme} = useTheme();\n const [editedUser, setEditedUser] = useState(flattenedProfile || profile);\n const [editingFields, setEditingFields] = useState<Record<string, boolean>>({});\n const {t} = useTranslation(preferences?.i18n);\n\n useEffect(() => {\n const nextUser = flattenedProfile ?? profile;\n if (!nextUser) return;\n\n setEditedUser((prev: any) => {\n if (!prev) return nextUser;\n\n const updated = {...nextUser};\n Object.keys(prev).forEach((key) => {\n if (editingFields[key]) {\n updated[key] = prev[key];\n }\n });\n return updated;\n });\n }, [flattenedProfile, profile, editingFields]);\n\n /**\n * Determines if a field should be visible based on showFields, hideFields, and fieldsToSkip arrays.\n * Priority order:\n * 1. fieldsToSkip (always hidden) - highest priority\n * 2. hideFields (explicitly hidden)\n * 3. showFields (explicitly shown, if array is not empty)\n * 4. Default behavior (show all fields not in fieldsToSkip)\n */\n const shouldShowField: any = useCallback(\n (fieldName: string): boolean => {\n // Always skip fields in the hardcoded fieldsToSkip array\n if (fieldsToSkip.includes(fieldName)) {\n return false;\n }\n\n // If hideFields is provided and contains this field, hide it\n if (hideFields.length > 0 && hideFields.includes(fieldName)) {\n return false;\n }\n\n // If showFields is provided and not empty, only show fields in that array\n if (showFields.length > 0) {\n return showFields.includes(fieldName);\n }\n\n return true;\n },\n [showFields, hideFields],\n );\n\n const PencilIcon = (): any => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z\" />\n </svg>\n );\n\n const toggleFieldEdit: any = useCallback((fieldName: string) => {\n setEditingFields((prev: any) => ({\n ...prev,\n [fieldName]: !prev[fieldName],\n }));\n }, []);\n\n const getFieldPlaceholder: any = useCallback((schema: Schema): string => {\n const {type, displayName, description, name} = schema;\n\n const fieldLabel: any = displayName || description || name || 'value';\n\n switch (type) {\n case 'DATE_TIME':\n return `Enter your ${fieldLabel.toLowerCase()}`;\n case 'BOOLEAN':\n return `Select ${fieldLabel.toLowerCase()}`;\n case 'COMPLEX':\n return `Enter ${fieldLabel.toLowerCase()} details`;\n default:\n return `Enter your ${fieldLabel.toLowerCase()}`;\n }\n }, []);\n\n const formatLabel: any = useCallback(\n (key: string): string =>\n key\n .split(/(?=[A-Z])|_/)\n .map((word: any) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' '),\n [],\n );\n\n const styles: any = useStyles(theme, colorScheme);\n\n const ObjectDisplay: FC<{data: unknown}> = ({data}: {data: unknown}): ReactElement | null => {\n if (!data || typeof data !== 'object') return null;\n\n return (\n <table className={styles.value}>\n <tbody>\n {Object.entries(data).map(([key, value]: any) => (\n <tr key={key}>\n <td className={styles.objectKey}>\n <strong>{formatLabel(key)}:</strong>\n </td>\n <td className={styles.objectValue}>\n {typeof value === 'object' ? <ObjectDisplay data={value} /> : String(value)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n };\n\n function set(obj: Record<string, any>, path: string, value: any): void {\n const keys: any = path.split('.');\n let current: any = obj;\n\n for (let i: any = 0; i < keys.length; i += 1) {\n const key: any = keys[i];\n\n if (i === keys.length - 1) {\n current[key] = value;\n } else {\n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {};\n }\n current = current[key];\n }\n }\n }\n\n const handleFieldSave: any = useCallback(\n (schema: Schema): void => {\n if (!onUpdate || !schema.name) return;\n\n const fieldName: string = schema.name;\n let fieldValue: any;\n if (editedUser && fieldName && editedUser[fieldName] !== undefined) {\n fieldValue = editedUser[fieldName];\n } else if (flattenedProfile?.[fieldName] !== undefined) {\n fieldValue = flattenedProfile[fieldName];\n } else {\n fieldValue = '';\n }\n\n if (Array.isArray(fieldValue)) {\n fieldValue = fieldValue.filter((v: any) => v !== undefined && v !== null && v !== '');\n }\n\n let payload: Record<string, any> = {};\n set(payload, fieldName, fieldValue);\n\n onUpdate(payload);\n\n toggleFieldEdit(fieldName);\n },\n [editedUser, flattenedProfile, onUpdate, toggleFieldEdit],\n );\n\n const handleFieldCancel: any = useCallback(\n (fieldName: string) => {\n const currentUser: any = flattenedProfile || profile;\n setEditedUser((prev: any) => ({\n ...prev,\n [fieldName]: currentUser[fieldName],\n }));\n toggleFieldEdit(fieldName);\n },\n [flattenedProfile, profile, toggleFieldEdit],\n );\n\n const defaultAttributeMappings: Record<string, string | string[]> = {\n email: ['emails', 'email'],\n firstName: ['name.givenName', 'given_name'],\n lastName: ['name.familyName', 'family_name'],\n picture: ['profile', 'profileUrl', 'picture', 'URL'],\n username: ['userName', 'username', 'user_name'],\n };\n\n const mergedMappings: Record<string, string | string[]> = Object.fromEntries(\n Object.entries({...defaultAttributeMappings, ...attributeMapping}).filter(\n (entry): entry is [string, string | string[]] => entry[1] !== undefined,\n ),\n );\n\n const renderSchemaField = (\n schema: Schema,\n isEditing: boolean,\n onEditValue?: (value: any) => void,\n onStartEdit?: () => void,\n ): ReactElement | null => {\n if (!schema) return null;\n const {value, displayName, description, name, type, required, mutability, subAttributes, multiValued} = schema;\n const label: any = displayName || description || (name ? startCase(name) : '');\n\n if (subAttributes && Array.isArray(subAttributes)) {\n return (\n <>\n {subAttributes.map((subAttr: any, index: any) => {\n let displayValue: string;\n if (Array.isArray(subAttr.value)) {\n displayValue = subAttr.value\n .map((item: any) => (typeof item === 'object' ? JSON.stringify(item) : String(item)))\n .join(', ');\n } else if (typeof subAttr.value === 'object') {\n displayValue = JSON.stringify(subAttr.value);\n } else {\n displayValue = String(subAttr.value);\n }\n\n return (\n <div key={index} className={styles.field}>\n <span className={styles.label}>{subAttr.displayName || subAttr.description || ''}</span>\n <div className={styles.value}>{displayValue}</div>\n </div>\n );\n })}\n </>\n );\n }\n\n if (Array.isArray(value) || multiValued) {\n const hasValues: any = Array.isArray(value)\n ? value.length > 0\n : value !== undefined && value !== null && value !== '';\n const isEditable: any = editable && mutability !== 'READ_ONLY' && !readonlyFields.includes(name || '');\n\n if (isEditing && onEditValue && isEditable) {\n let currentValue: any;\n if (editedUser && name && editedUser[name] !== undefined) {\n currentValue = editedUser[name];\n } else if (flattenedProfile && name && flattenedProfile[name] !== undefined) {\n currentValue = flattenedProfile[name];\n } else {\n currentValue = value;\n }\n\n let fieldValues: string[];\n if (Array.isArray(currentValue)) {\n fieldValues = currentValue.map(String);\n } else if (currentValue !== undefined && currentValue !== null && currentValue !== '') {\n fieldValues = [String(currentValue)];\n } else {\n fieldValues = [];\n }\n\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={styles.value}>\n <MultiInput\n values={fieldValues}\n onChange={(newValues: any): void => {\n if (multiValued || Array.isArray(currentValue)) {\n onEditValue(newValues);\n } else {\n onEditValue(newValues[0] || '');\n }\n }}\n placeholder={getFieldPlaceholder(schema)}\n fieldType={type as 'STRING' | 'DATE_TIME' | 'BOOLEAN'}\n type={type === 'DATE_TIME' ? 'date' : 'text'}\n required={required}\n />\n </div>\n </>\n );\n }\n\n let displayValue: string;\n if (hasValues) {\n if (Array.isArray(value)) {\n displayValue = value\n .map((item: any) => (typeof item === 'object' ? JSON.stringify(item) : String(item)))\n .join(', ');\n } else {\n displayValue = String(value);\n }\n } else if (isEditable) {\n displayValue = getFieldPlaceholder(schema);\n } else {\n displayValue = '-';\n }\n\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={cx(styles.value, !hasValues ? styles.valuePlaceholder : '')}>\n {!hasValues && isEditable && onStartEdit ? (\n <Button\n onClick={onStartEdit}\n variant=\"text\"\n color=\"secondary\"\n size=\"small\"\n title=\"Click to edit\"\n className={styles.editButton}\n >\n {displayValue}\n </Button>\n ) : (\n displayValue\n )}\n </div>\n </>\n );\n }\n if (type === 'COMPLEX' && typeof value === 'object') {\n return <ObjectDisplay data={value} />;\n }\n\n if (isEditing && onEditValue && mutability !== 'READ_ONLY' && !readonlyFields.includes(name || '')) {\n let fieldValue: any;\n if (editedUser && name && editedUser[name] !== undefined) {\n fieldValue = editedUser[name];\n } else if (flattenedProfile && name && flattenedProfile[name] !== undefined) {\n fieldValue = flattenedProfile[name];\n } else {\n fieldValue = value || '';\n }\n\n const commonProps: any = {\n label: undefined,\n onChange: (e: any) => onEditValue(e.target ? e.target.value : e),\n placeholder: getFieldPlaceholder(schema),\n required,\n value: fieldValue,\n // Removed inline style, use .styles.ts for marginBottom if needed\n };\n let field: ReactElement;\n switch (type) {\n case 'STRING':\n field = <TextField {...commonProps} />;\n break;\n case 'DATE_TIME':\n field = <DatePicker {...commonProps} />;\n break;\n case 'BOOLEAN':\n field = (\n <Checkbox\n {...commonProps}\n checked={!!fieldValue}\n onChange={(e: any): void => {\n onEditValue(e.target.checked);\n }}\n />\n );\n break;\n case 'COMPLEX':\n field = (\n <textarea\n value={fieldValue}\n onChange={(e: any): void => onEditValue(e.target.value)}\n placeholder={getFieldPlaceholder(schema)}\n required={required}\n className={styles.complexTextarea}\n />\n );\n break;\n default:\n field = <TextField {...commonProps} />;\n }\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={styles.value}>{field}</div>\n </>\n );\n }\n\n const hasValue: any = value !== undefined && value !== null && value !== '';\n const isEditable: any = editable && mutability !== 'READ_ONLY' && !readonlyFields.includes(name || '');\n\n let displayValue: string;\n if (hasValue) {\n displayValue = String(value);\n } else if (isEditable) {\n displayValue = getFieldPlaceholder(schema);\n } else {\n displayValue = '-';\n }\n\n return (\n <>\n <span className={styles.label}>{label}</span>\n <div className={cx(styles.value, !hasValue ? styles.valuePlaceholder : '')}>\n {!hasValue && isEditable && onStartEdit ? (\n <Button\n onClick={onStartEdit}\n variant=\"text\"\n color=\"secondary\"\n size=\"small\"\n title=\"Click to edit\"\n className={styles.editButton}\n >\n {displayValue}\n </Button>\n ) : (\n displayValue\n )}\n </div>\n </>\n );\n };\n\n const renderUserInfo = (schema: Schema): any => {\n if (!schema?.name) return null;\n\n const hasValue: any = schema.value !== undefined && schema.value !== '' && schema.value !== null;\n const isFieldEditing: any = editingFields[schema.name];\n const isReadonlyField: any = readonlyFields.includes(schema.name);\n\n const shouldShow: any = hasValue || isFieldEditing || (editable && schema.mutability === 'READ_WRITE');\n\n if (!shouldShow) {\n return null;\n }\n\n return (\n <div className={styles.field}>\n <div className={styles.fieldInner}>\n {renderSchemaField(\n schema,\n isFieldEditing,\n (value: any) => {\n const tempEditedUser: any = {...editedUser};\n tempEditedUser[schema.name!] = value;\n setEditedUser(tempEditedUser);\n },\n () => toggleFieldEdit(schema.name),\n )}\n </div>\n {editable && schema.mutability !== 'READ_ONLY' && !isReadonlyField && (\n <div className={styles.fieldActions}>\n {isFieldEditing && (\n <>\n <Button size=\"small\" color=\"primary\" variant=\"solid\" onClick={(): any => handleFieldSave(schema)}>\n Save\n </Button>\n <Button\n size=\"small\"\n color=\"secondary\"\n variant=\"solid\"\n onClick={(): any => handleFieldCancel(schema.name)}\n >\n Cancel\n </Button>\n </>\n )}\n {!isFieldEditing && hasValue && (\n <Button\n size=\"small\"\n color=\"tertiary\"\n variant=\"icon\"\n onClick={(): any => toggleFieldEdit(schema.name)}\n title=\"Edit\"\n className={styles.editButton}\n >\n <PencilIcon />\n </Button>\n )}\n </div>\n )}\n </div>\n );\n };\n\n if (!profile && !flattenedProfile) {\n return fallback;\n }\n\n const containerClasses: any = cx(\n styles.root,\n cardLayout ? styles.card : '',\n withVendorCSSClassPrefix('user-profile'),\n className,\n );\n\n const currentUser: any = flattenedProfile || profile;\n\n const renderProfileWithoutSchemas = (): any => {\n if (!currentUser) return null;\n\n const displayName: any = getDisplayName(mergedMappings, profile!, displayNameAttributes);\n\n const profileEntries: any = Object.entries(currentUser)\n .filter(([key, value]: [string, any]) => {\n if (!shouldShowField(key)) return false;\n\n return value !== undefined && value !== '' && value !== null;\n })\n .sort(([a]: [string, ...any[]], [b]: [string, ...any[]]) => a.localeCompare(b));\n\n return (\n <>\n <div className={styles.profileSummary}>\n <Avatar\n imageUrl={getMappedUserProfileValue('picture', mergedMappings, currentUser)}\n name={displayName}\n size={70}\n alt={`${displayName}'s avatar`}\n isLoading={isLoading}\n />\n <Typography variant=\"h3\" fontWeight=\"medium\">\n {displayName}\n </Typography>\n {getMappedUserProfileValue('email', mergedMappings, currentUser) && (\n <Typography variant=\"body2\" color=\"textSecondary\">\n {getMappedUserProfileValue('email', mergedMappings, currentUser)}\n </Typography>\n )}\n </div>\n <Divider />\n {profileEntries.map(([key, value]: any) => {\n const isReadonly = readonlyFields.includes(key);\n const schema: Schema = {name: key, mutability: isReadonly ? 'READ_ONLY' : 'READ_WRITE'};\n const schemaWithValue: any = {...schema, value};\n\n return (\n <div key={key} className={styles.info}>\n {renderUserInfo(schemaWithValue)}\n </div>\n );\n })}\n </>\n );\n };\n\n const profileContent: any = (\n <CardPrimitive className={containerClasses}>\n {error && (\n <AlertPrimitive\n variant=\"error\"\n className={cx(withVendorCSSClassPrefix(bem('user-profile', 'alert')), styles.alert)}\n >\n <AlertPrimitive.Title>{t('errors.heading') || 'Error'}</AlertPrimitive.Title>\n <AlertPrimitive.Description>{error}</AlertPrimitive.Description>\n </AlertPrimitive>\n )}\n <div className={styles.infoContainer}>{renderProfileWithoutSchemas()}</div>\n </CardPrimitive>\n );\n\n if (mode === 'popup') {\n return (\n <DialogPrimitive open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Content>\n <DialogPrimitive.Heading>{title ?? t('user.profile.heading')}</DialogPrimitive.Heading>\n <div className={styles.popup}>{profileContent}</div>\n </DialogPrimitive.Content>\n </DialogPrimitive>\n );\n }\n\n return profileContent;\n};\n\nexport default BaseUserProfile;\n"],"mappings":"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"}
@@ -45,18 +45,31 @@ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
45
45
  * />
46
46
  * ```
47
47
  */
48
- const UserProfile = ({ preferences,...rest }) => {
49
- const { baseUrl, instanceId } = require_useThunderID.default();
50
- const { profile, flattenedProfile, schemas, onUpdateProfile } = require_useUser.default();
51
- const { t } = require_useTranslation.default(preferences?.i18n);
48
+ const UserProfile = ({ preferences, editable = true,...rest }) => {
49
+ const { baseUrl, instanceId, preferences: contextPreferences } = require_useThunderID.default();
50
+ const { profile, flattenedProfile, onUpdateProfile } = require_useUser.default();
51
+ const resolvedPreferences = {
52
+ ...contextPreferences,
53
+ ...preferences,
54
+ user: {
55
+ ...contextPreferences?.user,
56
+ ...preferences?.user
57
+ }
58
+ };
59
+ const { t } = require_useTranslation.default(resolvedPreferences?.i18n);
60
+ const isEditableProfile = resolvedPreferences?.user?.fetchUserProfile === false ? false : editable;
52
61
  const [error, setError] = (0, react.useState)(null);
53
62
  const handleProfileUpdate = async (payload) => {
54
63
  setError(null);
55
64
  try {
65
+ const updatedAttributes = (0, __thunderid_browser.deepMerge)(profile?.["attributes"] ?? {}, payload);
66
+ Object.keys(updatedAttributes).forEach((key) => {
67
+ if (updatedAttributes[key] === void 0 || updatedAttributes[key] === null) delete updatedAttributes[key];
68
+ });
56
69
  onUpdateProfile(await require_updateMeProfile.default({
57
70
  baseUrl,
58
71
  instanceId,
59
- payload
72
+ payload: updatedAttributes
60
73
  }));
61
74
  } catch (caughtError) {
62
75
  let message = t("user.profile.update.generic.error");
@@ -67,10 +80,10 @@ const UserProfile = ({ preferences,...rest }) => {
67
80
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_BaseUserProfile.default, {
68
81
  profile: profile ?? void 0,
69
82
  flattenedProfile: flattenedProfile ?? void 0,
70
- schemas: schemas ?? void 0,
71
- onUpdate: handleProfileUpdate,
83
+ editable: isEditableProfile,
84
+ onUpdate: isEditableProfile ? handleProfileUpdate : void 0,
72
85
  error,
73
- preferences,
86
+ preferences: resolvedPreferences,
74
87
  ...rest
75
88
  });
76
89
  };
@@ -1 +1 @@
1
- {"version":3,"file":"UserProfile.cjs","names":["UserProfile: FC<UserProfileProps>","useThunderID","useUser","useTranslation","updateMeProfile","caughtError: unknown","message: string","ThunderIDError","BaseUserProfile"],"sources":["../../../../../src/components/presentation/UserProfile/UserProfile.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {ThunderIDError, User} from '@thunderid/browser';\nimport {FC, ReactElement, useState} from 'react';\n// eslint-disable-next-line import/no-named-as-default\nimport BaseUserProfile, {BaseUserProfileProps} from './BaseUserProfile';\nimport updateMeProfile from '../../../api/updateMeProfile';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport useUser from '../../../contexts/User/useUser';\nimport useTranslation from '../../../hooks/useTranslation';\n\n/**\n * Props for the UserProfile component.\n * Extends BaseUserProfileProps but makes the user prop optional since it will be obtained from useThunderID\n */\nexport type UserProfileProps = Omit<BaseUserProfileProps, 'user' | 'profile' | 'flattenedProfile' | 'schemas'>;\n\n/**\n * UserProfile component displays the authenticated user's profile information in a\n * structured and styled format. It shows user details such as display name, email,\n * username, and other available profile information from ThunderID.\n *\n * This component is the React-specific implementation that uses the BaseUserProfile\n * and automatically retrieves the user data from ThunderID context if not provided.\n *\n * @example\n * ```tsx\n * // Basic usage - will use user from ThunderID context\n * <UserProfile />\n *\n * // With explicit user data\n * <UserProfile user={specificUser} />\n *\n * // With card layout and custom fallback\n * <UserProfile\n * cardLayout={true}\n * fallback={<div>Please sign in to view your profile</div>}\n * />\n *\n * // With field filtering - only show specific fields\n * <UserProfile\n * showFields={['name.givenName', 'name.familyName', 'emails']}\n * />\n *\n * // With field hiding - hide specific fields\n * <UserProfile\n * hideFields={['phoneNumbers', 'addresses']}\n * />\n * ```\n */\nconst UserProfile: FC<UserProfileProps> = ({preferences, ...rest}: UserProfileProps): ReactElement => {\n const {baseUrl, instanceId} = useThunderID();\n const {profile, flattenedProfile, schemas, onUpdateProfile} = useUser();\n const {t} = useTranslation(preferences?.i18n);\n\n const [error, setError] = useState<string | null>(null);\n\n const handleProfileUpdate = async (payload: any): Promise<void> => {\n setError(null);\n\n try {\n const response: User = await updateMeProfile({baseUrl, instanceId, payload});\n onUpdateProfile(response);\n } catch (caughtError: unknown) {\n let message: string = t('user.profile.update.generic.error');\n\n if (caughtError instanceof ThunderIDError) {\n message = caughtError?.message;\n }\n\n setError(message);\n }\n };\n\n return (\n <BaseUserProfile\n profile={profile ?? undefined}\n flattenedProfile={flattenedProfile ?? undefined}\n schemas={schemas ?? undefined}\n onUpdate={handleProfileUpdate}\n error={error}\n preferences={preferences}\n {...rest}\n />\n );\n};\n\nexport default UserProfile;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEA,MAAMA,eAAqC,EAAC,YAAa,GAAG,WAA0C;CACpG,MAAM,EAAC,SAAS,eAAcC,8BAAc;CAC5C,MAAM,EAAC,SAAS,kBAAkB,SAAS,oBAAmBC,yBAAS;CACvE,MAAM,EAAC,MAAKC,+BAAe,aAAa,KAAK;CAE7C,MAAM,CAAC,OAAO,gCAAoC,KAAK;CAEvD,MAAM,sBAAsB,OAAO,YAAgC;AACjE,WAAS,KAAK;AAEd,MAAI;AAEF,mBADuB,MAAMC,gCAAgB;IAAC;IAAS;IAAY;IAAQ,CAAC,CACnD;WAClBC,aAAsB;GAC7B,IAAIC,UAAkB,EAAE,oCAAoC;AAE5D,OAAI,uBAAuBC,mCACzB,WAAU,aAAa;AAGzB,YAAS,QAAQ;;;AAIrB,QACE,2CAACC;EACC,SAAS,WAAW;EACpB,kBAAkB,oBAAoB;EACtC,SAAS,WAAW;EACpB,UAAU;EACH;EACM;EACb,GAAI;GACJ;;AAIN,0BAAe"}
1
+ {"version":3,"file":"UserProfile.cjs","names":["UserProfile: FC<UserProfileProps>","useThunderID","useUser","useTranslation","isEditableProfile: boolean","updatedAttributes: Record<string, unknown>","updateMeProfile","caughtError: unknown","message: string","ThunderIDError","BaseUserProfile"],"sources":["../../../../../src/components/presentation/UserProfile/UserProfile.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {ThunderIDError, User, deepMerge} from '@thunderid/browser';\nimport {FC, ReactElement, useState} from 'react';\n// eslint-disable-next-line import/no-named-as-default\nimport BaseUserProfile, {BaseUserProfileProps} from './BaseUserProfile';\nimport updateMeProfile from '../../../api/updateMeProfile';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport useUser from '../../../contexts/User/useUser';\nimport useTranslation from '../../../hooks/useTranslation';\n\n/**\n * Props for the UserProfile component.\n * Extends BaseUserProfileProps but makes the user prop optional since it will be obtained from useThunderID\n */\nexport type UserProfileProps = Omit<BaseUserProfileProps, 'user' | 'profile' | 'flattenedProfile'>;\n\n/**\n * UserProfile component displays the authenticated user's profile information in a\n * structured and styled format. It shows user details such as display name, email,\n * username, and other available profile information from ThunderID.\n *\n * This component is the React-specific implementation that uses the BaseUserProfile\n * and automatically retrieves the user data from ThunderID context if not provided.\n *\n * @example\n * ```tsx\n * // Basic usage - will use user from ThunderID context\n * <UserProfile />\n *\n * // With explicit user data\n * <UserProfile user={specificUser} />\n *\n * // With card layout and custom fallback\n * <UserProfile\n * cardLayout={true}\n * fallback={<div>Please sign in to view your profile</div>}\n * />\n *\n * // With field filtering - only show specific fields\n * <UserProfile\n * showFields={['name.givenName', 'name.familyName', 'emails']}\n * />\n *\n * // With field hiding - hide specific fields\n * <UserProfile\n * hideFields={['phoneNumbers', 'addresses']}\n * />\n * ```\n */\nconst UserProfile: FC<UserProfileProps> = ({preferences, editable = true, ...rest}: UserProfileProps): ReactElement => {\n const {baseUrl, instanceId, preferences: contextPreferences} = useThunderID();\n const {profile, flattenedProfile, onUpdateProfile} = useUser();\n const resolvedPreferences = {\n ...contextPreferences,\n ...preferences,\n user: {\n ...contextPreferences?.user,\n ...preferences?.user,\n },\n };\n const {t} = useTranslation(resolvedPreferences?.i18n);\n const isEditableProfile: boolean = resolvedPreferences?.user?.fetchUserProfile === false ? false : editable;\n\n const [error, setError] = useState<string | null>(null);\n\n const handleProfileUpdate = async (payload: Record<string, unknown>): Promise<void> => {\n setError(null);\n\n try {\n const updatedAttributes: Record<string, unknown> = deepMerge(\n (profile?.['attributes'] as Record<string, unknown>) ?? {},\n payload,\n );\n\n Object.keys(updatedAttributes).forEach((key) => {\n if (updatedAttributes[key] === undefined || updatedAttributes[key] === null) {\n delete updatedAttributes[key];\n }\n });\n\n const response: User = await updateMeProfile({baseUrl, instanceId, payload: updatedAttributes});\n onUpdateProfile(response);\n } catch (caughtError: unknown) {\n let message: string = t('user.profile.update.generic.error');\n\n if (caughtError instanceof ThunderIDError) {\n message = caughtError?.message;\n }\n\n setError(message);\n }\n };\n\n return (\n <BaseUserProfile\n profile={profile ?? undefined}\n flattenedProfile={flattenedProfile ?? undefined}\n editable={isEditableProfile}\n onUpdate={isEditableProfile ? handleProfileUpdate : undefined}\n error={error}\n preferences={resolvedPreferences}\n {...rest}\n />\n );\n};\n\nexport default UserProfile;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEA,MAAMA,eAAqC,EAAC,aAAa,WAAW,KAAM,GAAG,WAA0C;CACrH,MAAM,EAAC,SAAS,YAAY,aAAa,uBAAsBC,8BAAc;CAC7E,MAAM,EAAC,SAAS,kBAAkB,oBAAmBC,yBAAS;CAC9D,MAAM,sBAAsB;EAC1B,GAAG;EACH,GAAG;EACH,MAAM;GACJ,GAAG,oBAAoB;GACvB,GAAG,aAAa;GACjB;EACF;CACD,MAAM,EAAC,MAAKC,+BAAe,qBAAqB,KAAK;CACrD,MAAMC,oBAA6B,qBAAqB,MAAM,qBAAqB,QAAQ,QAAQ;CAEnG,MAAM,CAAC,OAAO,gCAAoC,KAAK;CAEvD,MAAM,sBAAsB,OAAO,YAAoD;AACrF,WAAS,KAAK;AAEd,MAAI;GACF,MAAMC,uDACH,UAAU,iBAA6C,EAAE,EAC1D,QACD;AAED,UAAO,KAAK,kBAAkB,CAAC,SAAS,QAAQ;AAC9C,QAAI,kBAAkB,SAAS,UAAa,kBAAkB,SAAS,KACrE,QAAO,kBAAkB;KAE3B;AAGF,mBADuB,MAAMC,gCAAgB;IAAC;IAAS;IAAY,SAAS;IAAkB,CAAC,CACtE;WAClBC,aAAsB;GAC7B,IAAIC,UAAkB,EAAE,oCAAoC;AAE5D,OAAI,uBAAuBC,mCACzB,WAAU,aAAa;AAGzB,YAAS,QAAQ;;;AAIrB,QACE,2CAACC;EACC,SAAS,WAAW;EACpB,kBAAkB,oBAAoB;EACtC,UAAU;EACV,UAAU,oBAAoB,sBAAsB;EAC7C;EACP,aAAa;EACb,GAAI;GACJ;;AAIN,0BAAe"}
@@ -320,6 +320,14 @@ const BaseAcceptInvite = ({ executionId, inviteToken, onSubmit, onComplete, onEr
320
320
  normalizeFlowResponseLocal
321
321
  ]);
322
322
  /**
323
+ * reset form values, errors, and touched fields to initial state
324
+ */
325
+ const resetForm = (0, react.useCallback)(() => {
326
+ setFormValues({});
327
+ setFormErrors({});
328
+ setTouchedFields({});
329
+ }, []);
330
+ /**
323
331
  * Validate invite token on component mount.
324
332
  */
325
333
  (0, react.useEffect)(() => {
@@ -481,7 +489,7 @@ const BaseAcceptInvite = ({ executionId, inviteToken, onSubmit, onComplete, onEr
481
489
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Alert.default.Description, { children: apiError.message })
482
490
  })
483
491
  }),
484
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [componentsWithoutHeadings && componentsWithoutHeadings.length > 0 ? require_AuthOptionFactory.renderInviteUserComponents(componentsWithoutHeadings, formValues, touchedFields, formErrors, isLoading, isFormValid, handleInputChange, {
492
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [componentsWithoutHeadings && componentsWithoutHeadings.length > 0 ? require_AuthOptionFactory.renderInviteUserComponents(componentsWithoutHeadings, formValues, touchedFields, formErrors, isLoading, isFormValid, resetForm, handleInputChange, {
485
493
  _customRenderers: customRenderers,
486
494
  _theme: theme,
487
495
  onInputBlur: handleInputBlur,
@@ -1 +1 @@
1
- {"version":3,"file":"BaseAcceptInvite.cjs","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","extractErrorMessage","normalizeFlowResponseLocal: any","normalizeFlowResponse","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","renderInviteUserComponents"],"sources":["../../../../../../src/components/presentation/auth/AcceptInvite/BaseAcceptInvite.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025-2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {cx} from '@emotion/css';\nimport {\n 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/useOAuthCallback';\nimport useTranslation from '../../../../hooks/useTranslation';\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 '../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.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 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 ? false : inputs[key] !== 'false', 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 * 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 style={{alignItems: 'center', display: 'flex', flexDirection: 'column', gap: '1rem', padding: '2rem'}}>\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 style={{display: 'flex', justifyContent: 'center', marginTop: '1.5rem'}}>\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 style={{marginBottom: '1rem'}}>\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 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 style={{display: 'flex', justifyContent: 'center', padding: '1rem'}}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n {onGoToSignIn && (\n <div style={{marginTop: '1.5rem', textAlign: 'center'}}>\n <Typography variant=\"body2\">\n Already have an account?{' '}\n <Button variant=\"text\" onClick={onGoToSignIn} style={{minWidth: 'auto', padding: 0}}>\n Sign In\n </Button>\n </Typography>\n </div>\n )}\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\nexport default BaseAcceptInvite;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwQA,MAAMA,oBAA+C,EACnD,aACA,aACA,UACA,YACA,SACA,cACA,cACA,YAAY,IACZ,UACA,aACA,OAAO,UACP,UAAU,YACV,YAAY,MACZ,eAAe,WAC0B;CACzC,MAAM,EAAC,MAAM,eAAe,mBAAmB,WAAUC,8BAAc;CACvE,MAAM,EAAC,MAAKC,+BAAe,aAAa,KAAK;CAC7C,MAAM,EAAC,UAASC,0BAAU;CAC1B,MAAMC,wCAAmDC,yCAAyB;CAClF,MAAMC,SAAcC,wCAAU,OAAO,MAAM,KAAK,OAAO,KAAK,QAAQ;CACpE,MAAM,CAAC,WAAW,oCAAyB,MAAM;CACjD,MAAM,CAAC,mBAAmB,4CAAiC,KAAK;CAChE,MAAM,CAAC,gBAAgB,yCAA8B,MAAM;CAC3D,MAAM,CAAC,YAAY,qCAA0B,MAAM;CACnD,MAAM,CAAC,aAAa,sCAA4D,KAAK;CACrF,MAAM,CAAC,UAAU,mCAAsC,KAAK;CAC5D,MAAM,CAAC,YAAY,qCAAkD,EAAE,CAAC;CACxE,MAAM,CAAC,YAAY,qCAAkD,EAAE,CAAC;CACxE,MAAM,CAAC,eAAe,wCAAsD,EAAE,CAAC;CAC/E,MAAM,CAAC,aAAa,sCAA2B,KAAK;CACpD,MAAM,CAAC,gBAAgB,yCAA8B,MAAM;CAC3D,MAAMC,sCAA+C,KAAK;;;;;;AAO1D,4BAAgB;EACd,MAAMC,uBAAiD,aAAa,OAAc;AAClF,MAAI,CAAC,uBAAuB,oBAAoB,WAAW,EACzD;EAEF,MAAMC,SAAiC,EAAE;EACzC,MAAMC,UAAmC,EAAE;AAC3C,OAAK,MAAM,MAAM,oBACf,KAAI,EAAE,GAAG,cAAc,SAAS;AAC9B,UAAO,GAAG,cAAc,GAAG;AAC3B,WAAQ,GAAG,cAAc;;AAG7B,gBAAc,OAAO;AACrB,oBAAkB,UAAmC;GAAC,GAAG;GAAM,GAAG;GAAQ,EAAE;IAC3E,CAAC,YAAY,CAAC;CAEjB,MAAMC,gDAA0C,MAAM;;;;;AAMtD,4BAAgB;AACd,MAAI,CAAC,cAAe;AAEpB,GAAC,YAA2B;AAC1B,OAAI;IAEF,MAAMC,WAAgB,OADM,MAAM,mBAAmB,GACT,kBAAkB;AAC9D,QAAI,UAAU,eACZ,mBAAkB,UAAU,SAAS;aAE/B;AACR,sBAAkB,KAAK;;MAEvB;IACH,CAAC,cAAc,CAAC;;;;;CAMnB,MAAM,oBAAoB,OAAO,mBAAiD;AAChF,oBAAkB,UAAU;EAC5B,MAAMC,iBAAsB,MAAM,mBAAmB;AACrD,MAAI,eACF,KAAI,eACF,OAAM,eAAe,0BAA0B,kBAAkB,eAAe;MAEhF,OAAM,eAAe,6BAA6B,iBAAiB;;;;;;CASzE,MAAMC,sCACH,UAAe;EACd,MAAMC,eAAuBC,4CAAoB,OAAO,GAAG,yCAAyC;AAGpG,cAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,aAAa,CAAC;AAGrE,YAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,aAAa,CAAC;IAErE,CAAC,GAAG,QAAQ,CACb;;;;;CAMD,MAAMC,qDACH,aAAiE;AAChE,MAAI,CAAC,UAAU,MAAM,MAAM,WACzB,QAAO;AAGT,MAAI;GACF,MAAM,EAAC,6BAAcC,8CACnB,UACA,GACA;IACE,iBAAiB;IACjB,qBAAqB;IACtB,EACD,KACD;AAED,UAAO;IACL,GAAG;IACH,MAAM;KACJ,GAAG,SAAS;KACZ,YAAYC;KACb;IACF;UACK;AAEN,UAAO;;IAGX,CAAC,GAAG,SAAS,CACd;;;;;AAMD,2CAAiB;EACf,oBAAoB,eAAe;EACnC,uBAAuB,GAAG,OAAO;EACjC,eAAe;EACf,kBAAkB;AAChB,wBAAqB,MAAM;AAC3B,iBAAc;;EAEhB,UAAU,UAAe;AACvB,OAAI,CAAC,OAAO,WACV,mBAAkB,KAAK;AAEzB,wBAAqB,MAAM;AAC3B,eAAY,MAAM;;EAEpB,eAAe,aAAkB;AAC/B,kBAAe,SAAS;AACxB,OAAI,SAAS,eAAe,YAAY;AACtC,kBAAc,KAAK;AAEnB,SADoC,SAAS,MAAM,cAAc,SAAS,MAAM,MAAM,cAAc,EAAE,EAC7E,SAAS,EAChC,gBAAe,SAAS;UAErB;AAEL,mBAAe,SAAS;AACxB,kBAAc,EAAE,CAAC;AACjB,kBAAc,EAAE,CAAC;AACjB,qBAAiB,EAAE,CAAC;;;EAGxB,yBAAyB;AACvB,wBAAqB,KAAK;;EAE5B,UAAU,OAAO,YAAiB;GAKhC,MAAMC,WAAgB,2BAJG,MAAM,SAAS;IACtC,GAAG;IACH,GAAI,kBAAkB,UAAU,EAAC,gBAAgB,kBAAkB,SAAQ,GAAG,EAAE;IACjF,CAAC,CAC2D;AAC7D,SAAM,kBAAkB,SAAS,kBAAkB,KAAK;AACxD,UAAO;;EAET;EACD,CAAC;;;;CAKF,MAAMC,4CAAsC,MAAc,UAAkB;AAC1E,iBAAe,UAAe;GAAC,GAAG;IAAO,OAAO;GAAM,EAAE;AAExD,iBAAe,SAAc;GAC3B,MAAMC,YAAiB,EAAC,GAAG,MAAK;AAChC,UAAO,UAAU;AACjB,UAAO;IACP;AACF,iBAAe,KAAK;IACnB,EAAE,CAAC;;;;CAKN,MAAMC,0CAAoC,SAAiB;AACzD,oBAAkB,UAAe;GAAC,GAAG;IAAO,OAAO;GAAK,EAAE;IACzD,EAAE,CAAC;;;;CAKN,MAAMC,uCACH,iBAA0E;EACzE,MAAMf,SAAiC,EAAE;EAEzC,MAAM,sBAAsB,UAAsB;AAChD,SAAM,SAAS,SAAc;AAC3B,SACG,KAAK,SAAS,oBACb,KAAK,SAAS,gBACd,KAAK,SAAS,iBACd,KAAK,SAAS,iBACd,KAAK,SAAS,eACd,KAAK,SAAS,iBAChB,KAAK,KACL;KACA,MAAMgB,QAAa,WAAW,KAAK;AACnC,SAAI,KAAK,aAAa,CAAC,SAAS,MAAM,MAAM,KAAK,IAC/C,QAAO,KAAK,OAAO,EAAE,mCAAmC;cAC/C,OAAO;MAEhB,MAAM,iEAAwC,KAAK,WAAW;AAC9D,UAAI,eAAe;OACjB,MAAM,UAAU,cAAc,MAAM;AACpC,WAAI,QACF,QAAO,KAAK,OAAO,EAAE,QAAQ;;;;AAKrC,QAAI,KAAK,cAAc,MAAM,QAAQ,KAAK,WAAW,CACnD,oBAAmB,KAAK,WAAW;KAErC;;AAGJ,qBAAmBN,aAAW;AAE9B,SAAO;GAAC;GAAQ,SAAS,OAAO,KAAK,OAAO,CAAC,WAAW;GAAE;IAE5D,CAAC,YAAY,EAAE,CAChB;;;;CAKD,MAAMO,sCACJ,OAAO,WAAgB,SAA+B;AACpD,MAAI,CAAC,YACH;EAKF,MAAMC,aAAkB,aADA,YAAY,MAAM,cAAc,EAAE,CACV;AAEhD,MAAI,CAAC,WAAW,SAAS;AACvB,kBAAe,MAAM;AACrB,iBAAc,WAAW,OAAO;GAEhC,MAAMjB,UAAmC,EAAE;AAC3C,UAAO,KAAK,WAAW,OAAO,CAAC,SAAS,QAAa;AACnD,YAAQ,OAAO;KACf;AACF,qBAAkB,UAAe;IAAC,GAAG;IAAM,GAAG;IAAQ,EAAE;AACxD;;AAGF,eAAa,KAAK;AAClB,cAAY,KAAK;AAEjB,MAAI;GAEF,MAAMkB,SAAc,EAAC,GAAI,QAAQ,YAAY;GAK7C,MAAM,wBAAyB,aAAa,MAAM,kBAA0C,EAAE;AAC9F,OAAI,sBAAsB,iBACxB,KAAI;IACF,MAAMC,MAAW,sBAAsB;IACvC,MAAMC,WAAkB,OAAO,QAAQ,WAAW,KAAK,MAAM,IAAI,GAAG,IAAI,YAAY;IACpF,MAAM,SAAS,WAAW,SAAS,aAAa,KAAK;IACrD,MAAM,YAAY,EAChB,UAAU,SAAS,KAAK,OAAY;KAClC,UAAU,CAAC;KACX,aAAa,EAAE;KACf,UAAU,CACR,IAAI,EAAE,aAAa,EAAE,EAAE,KAAK,OAAY;MAAC,UAAU,CAAC;MAAQ,MAAM,EAAE;MAAK,EAAE,EAC3E,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,MAAW;MACpC,MAAM,MAAM,kBAAkB,EAAE,UAAU,IAAI,EAAE;AAChD,aAAO;OAAC,UAAU,SAAS,QAAQ,OAAO,SAAS;OAAS,MAAM,EAAE;OAAK;OACzE,CACH;KACF,EAAE,EACJ;AACD,WAAO,oBAAoB,KAAK,UAAU,UAAU;AACpD,WAAO,KAAK,OAAO,CAAC,SAAS,MAAc;AACzC,SAAI,EAAE,WAAW,kBAAkB,CAAE,QAAO,OAAO;MACnD;WACI;GAKV,MAAMC,UAA+B;IACnC,aAAa,YAAY;IACzB;IACA,SAAS;IACT,GAAI,kBAAkB,UAAU,EAAC,gBAAgB,kBAAkB,SAAQ,GAAG,EAAE;IACjF;AAGD,OAAI,WAAW,GACb,SAAQ,YAAY,UAAU;GAIhC,MAAMX,WAAgB,2BADG,MAAM,SAAS,QAAQ,CACa;AAC7D,kBAAe,SAAS;AAExB,SAAM,kBAAkB,SAAS,kBAAkB,KAAK;AAGxD,OAAI,SAAS,SAAS,eAAe;IACnC,MAAMY,cAAmB,SAAS,MAAM,eAAe,UAAU;AACjE,QAAI,eAAe,OAAO,WAAW,aAAa;AAEhD,yCAAsB,aAAa,OAAO;AAC1C;;;AAKJ,OAAI,SAAS,eAAe,YAAY;AACtC,kBAAc,KAAK;AAEnB,SADoC,SAAS,MAAM,cAAc,SAAS,MAAM,MAAM,cAAc,EAAE,EAC7E,SAAS,EAChC,gBAAe,SAAS;QAExB,eAAc;AAEhB;;AAIF,OAAI,SAAS,eAAe,SAAS;AACnC,gBAAY,SAAS;AACrB;;AAIF,kBAAe,SAAS;AACxB,iBAAc,EAAE,CAAC;AACjB,oBAAiB,EAAE,CAAC;AAGpB,OAAI,UAAU,MACZ,aAAY,SAAS;WAEhB,KAAK;AACZ,eAAY,IAAI;YACR;AACR,gBAAa,MAAM;;IAGvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;;;;AAKD,4BAAgB;AAEd,MAAI,4BAA4B,QAC9B;AAMF,MADmC,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAChE,IAAI,OAAO,CACvB;AAIF,MAAI,CAAC,eAAe,CAAC,aAAa;AAChC,wBAAqB,MAAM;AAC3B,qBAAkB,KAAK;AACvB,+BAAY,IAAI,MAAM,2DAA2D,CAAC;AAClF;;AAGF,8BAA4B,UAAU;AAEtC,GAAC,YAA2B;AAC1B,wBAAqB,KAAK;AAC1B,eAAY,KAAK;AAEjB,OAAI;AAEF,QAAI,YACF,gBAAe,QAAQ,GAAG,OAAO,gBAAgB,YAAY;IAa/D,MAAMZ,WAAgB,2BADG,MAAM,SARV;KACnB;KACA,QAAQ,EACN,aACD;KACD,SAAS;KACV,CAE+C,CACa;AAC7D,mBAAe,SAAS;AAExB,UAAM,kBAAkB,SAAS,kBAAkB,KAAK;AAGxD,QAAI,SAAS,eAAe,SAAS;AACnC,uBAAkB,KAAK;AACvB,iBAAY,SAAS;AACrB;;AAIF,mBAAe,SAAS;AAGxB,QAAI,UAAU,MACZ,aAAY,SAAS;YAEhB,KAAK;AACZ,sBAAkB,KAAK;AACvB,gBAAY,IAAI;aACR;AACR,yBAAqB,MAAM;;MAE3B;IACH;EAAC;EAAa;EAAa;EAAU;EAAc;EAAa;EAA2B,CAAC;;;;CAK/F,MAAMa,0CAAoC,iBAA2D;EACnG,IAAIC;EACJ,IAAIC;AAEJ,eAAW,SAAS,SAAc;AAChC,OAAI,KAAK,SAAS,QAChB;QAAI,KAAK,YAAY,eAAe,CAACC,QACnC,WAAQ,KAAK;cACH,KAAK,YAAY,eAAe,KAAK,YAAY,iBAAiB,CAACC,WAC7E,cAAW,KAAK;;IAGpB;AAEF,SAAO;GAAC;GAAU;GAAM;IACvB,EAAE,CAAC;;;;CAKN,MAAMC,yCACH,iBACCnB,aAAW,QACR,SAAc,EAAE,KAAK,SAAS,WAAW,KAAK,YAAY,eAAe,KAAK,YAAY,cAC5F,EACH,EAAE,CACH;CAGD,MAAMoB,aAAkB,aAAa,MAAM,cAAc,aAAa,MAAM,MAAM,cAAc,EAAE;CAClG,MAAM,EAAC,OAAO,aAAY,gBAAgB,WAAW;CACrD,MAAMC,4BAAiC,eAAe,WAAW;CAIjE,MAAMC,cAA2C;EAC/C,gBAJ2C,aAAa,MAAM,kBAA0C,EAAE;EAK1G;EACA,OAAO;EACP;EACA,aAAa;EACb,YAAY;EACZ;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;EACT;EACA;EACA;EACA;EACA,SAAS;EACT,QAAQ;EACT;AAGD,KAAI,SACF,QAAO,2CAAC;EAAe;YAAY,SAAS,YAAY;GAAO;AAMjE,KAAI,kBACF,QACE,2CAACC;EAAc,iCAAc,WAAW,OAAO,KAAK;EAAW;YAC7D,2CAACA,qBAAc,qBACb,4CAAC;GAAI,OAAO;IAAC,YAAY;IAAU,SAAS;IAAQ,eAAe;IAAU,KAAK;IAAQ,SAAS;IAAO;cACxG,2CAACC,2BAAQ,MAAK,WAAW,EACzB,2CAACC;IAAW,SAAQ;cAAQ;KAA2C;IACnE,GACgB;GACV;AAKpB,KAAI,eACF,QACE,4CAACF;EAAc,iCAAc,WAAW,OAAO,KAAK;EAAW;aAC7D,2CAACA,qBAAc;GAAO,WAAW,OAAO;aACtC,2CAACA,qBAAc;IAAM,OAAO;IAAG,WAAW,OAAO;cAAO;KAElC;IACD,EACvB,4CAACA,qBAAc,sBACb,4CAACG;GAAe,SAAQ;cACtB,2CAACA,sBAAe,mBAAM,4BAA8C,EACpE,2CAACA,sBAAe,yBACb,UAAU,WACT,oGACyB;IACd,EAChB,gBACC,2CAAC;GAAI,OAAO;IAAC,SAAS;IAAQ,gBAAgB;IAAU,WAAW;IAAS;aAC1E,2CAACC;IAAO,SAAQ;IAAU,SAAS;cAAc;KAExC;IACL,IAEc;GACV;AAKpB,QACE,4CAACJ;EAAc,iCAAc,WAAW,OAAO,KAAK;EAAW;cAC3D,aAAa,kBAAkB,SAAS,aACxC,4CAACA,qBAAc;GAAO,WAAW,OAAO;cACrC,aAAa,SACZ,2CAACA,qBAAc;IAAM,OAAO;IAAG,WAAW,OAAO;cAC9C;KACmB,EAEvB,gBAAgB,YACf,2CAACE;IAAW,SAAQ;IAAQ,WAAW,OAAO;cAC3C;KACU;IAEM,EAEzB,4CAACF,qBAAc;GACZ,YACC,2CAAC;IAAI,OAAO,EAAC,cAAc,QAAO;cAChC,2CAACG;KAAe,SAAQ;eACtB,2CAACA,sBAAe,yBAAa,SAAS,UAAqC;MAC5D;KACb;GAER,4CAAC,oBACE,6BAA6B,0BAA0B,SAAS,IAC7DE,qDACE,2BACA,YACA,eACA,YACA,WACA,aACA,mBACA;IACE,kBAAkB;IAClB,QAAQ;IACR,aAAa;IACb,UAAU;IACV;IACA;IACD,CACF,GACD,CAAC,aACC,2CAACF;IAAe,SAAQ;cACtB,2CAACD;KAAW,SAAQ;eAAQ;MAAyC;KACtD,EAEtB,aACC,2CAAC;IAAI,OAAO;KAAC,SAAS;KAAQ,gBAAgB;KAAU,SAAS;KAAO;cACtE,2CAACD,2BAAQ,MAAK,UAAU;KACpB,IAEJ;GACL,gBACC,2CAAC;IAAI,OAAO;KAAC,WAAW;KAAU,WAAW;KAAS;cACpD,4CAACC;KAAW,SAAQ;;MAAQ;MACD;MACzB,2CAACE;OAAO,SAAQ;OAAO,SAAS;OAAc,OAAO;QAAC,UAAU;QAAQ,SAAS;QAAE;iBAAE;QAE5E;;MACE;KACT;MAEc;GACV;;AAIpB,+BAAe"}
1
+ {"version":3,"file":"BaseAcceptInvite.cjs","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","extractErrorMessage","normalizeFlowResponseLocal: any","normalizeFlowResponse","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","renderInviteUserComponents"],"sources":["../../../../../../src/components/presentation/auth/AcceptInvite/BaseAcceptInvite.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025-2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {cx} from '@emotion/css';\nimport {\n 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/useOAuthCallback';\nimport useTranslation from '../../../../hooks/useTranslation';\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 '../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.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 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 ? false : inputs[key] !== 'false', 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 style={{alignItems: 'center', display: 'flex', flexDirection: 'column', gap: '1rem', padding: '2rem'}}>\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 style={{display: 'flex', justifyContent: 'center', marginTop: '1.5rem'}}>\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 style={{marginBottom: '1rem'}}>\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 style={{display: 'flex', justifyContent: 'center', padding: '1rem'}}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n {onGoToSignIn && (\n <div style={{marginTop: '1.5rem', textAlign: 'center'}}>\n <Typography variant=\"body2\">\n Already have an account?{' '}\n <Button variant=\"text\" onClick={onGoToSignIn} style={{minWidth: 'auto', padding: 0}}>\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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"}