UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

1 lines 43.9 kB
{"version":3,"file":"passkey-setup.cjs","sources":["../../../../../src/components/auth/user-profile/passkey-setup.tsx"],"sourcesContent":["/**\n * @frank-auth/react - Passkey Setup Component\n *\n * Passkey (WebAuthn/FIDO2) setup and management interface for\n * passwordless authentication with hardware security keys and biometrics.\n */\n\n'use client';\n\nimport React from 'react';\nimport {\n Alert,\n Button,\n Card,\n CardBody,\n CardHeader,\n Chip,\n Divider,\n Dropdown,\n DropdownItem,\n DropdownMenu,\n DropdownTrigger,\n Input,\n Modal,\n ModalBody,\n ModalContent,\n ModalHeader,\n useDisclosure,\n} from '@heroui/react';\nimport {usePasskeys} from '../../../hooks/use-passkeys';\nimport {useConfig} from '../../../hooks/use-config';\n\n// ============================================================================\n// Passkey Setup Interface\n// ============================================================================\n\nexport interface PasskeySetupProps {\n /**\n * Success callback\n */\n onSuccess?: (message: string) => void;\n\n /**\n * Error callback\n */\n onError?: (error: string) => void;\n\n /**\n * Custom className\n */\n className?: string;\n\n /**\n * Whether component is disabled\n */\n isDisabled?: boolean;\n\n /**\n * Component variant\n */\n variant?: 'flat' | 'bordered' | 'shadow';\n\n /**\n * Component size\n */\n size?: 'sm' | 'md' | 'lg';\n\n /**\n * Show registration flow\n */\n showRegistration?: boolean;\n\n /**\n * Show passkey management\n */\n showManagement?: boolean;\n\n /**\n * Maximum number of passkeys\n */\n maxPasskeys?: number;\n\n /**\n * Hide specific sections\n */\n hideSections?: string[];\n\n /**\n * Custom passkey types\n */\n customTypes?: PasskeyTypeConfig[];\n}\n\nexport interface PasskeyTypeConfig {\n key: string;\n name: string;\n description: string;\n icon: React.ReactNode;\n isRecommended?: boolean;\n}\n\n// ============================================================================\n// Passkey Registration Component\n// ============================================================================\n\ninterface PasskeyRegistrationProps {\n onSuccess: (message: string) => void;\n onError: (error: string) => void;\n onClose: () => void;\n isOpen: boolean;\n}\n\nfunction PasskeyRegistration({onSuccess, onError, onClose, isOpen}: PasskeyRegistrationProps) {\n const {registerPasskey, isSupported, isAvailable} = usePasskeys();\n\n const [step, setStep] = React.useState<'intro' | 'name' | 'registering'>('intro');\n const [passkeyName, setPasskeyName] = React.useState('');\n const [isLoading, setIsLoading] = React.useState(false);\n\n // Reset state when modal opens/closes\n React.useEffect(() => {\n if (!isOpen) {\n setStep('intro');\n setPasskeyName('');\n } else {\n // Generate default name based on device\n const deviceInfo = getDeviceInfo();\n setPasskeyName(`${deviceInfo.browser} on ${deviceInfo.os}`);\n }\n }, [isOpen]);\n\n // Get device information for default naming\n const getDeviceInfo = () => {\n const userAgent = navigator.userAgent;\n let browser = 'Unknown Browser';\n let os = 'Unknown OS';\n\n // Detect browser\n if (userAgent.includes('Chrome')) browser = 'Chrome';\n else if (userAgent.includes('Firefox')) browser = 'Firefox';\n else if (userAgent.includes('Safari')) browser = 'Safari';\n else if (userAgent.includes('Edge')) browser = 'Edge';\n\n // Detect OS\n if (userAgent.includes('Windows')) os = 'Windows';\n else if (userAgent.includes('Mac')) os = 'macOS';\n else if (userAgent.includes('Linux')) os = 'Linux';\n else if (userAgent.includes('Android')) os = 'Android';\n else if (userAgent.includes('iOS')) os = 'iOS';\n\n return {browser, os};\n };\n\n // Handle passkey registration\n const handleRegister = async () => {\n if (!passkeyName.trim()) {\n onError('Please enter a name for your passkey');\n return;\n }\n\n try {\n setIsLoading(true);\n setStep('registering');\n\n await registerPasskey(passkeyName.trim());\n onSuccess('Passkey registered successfully');\n onClose();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to register passkey';\n onError(message);\n setStep('name'); // Go back to name step\n } finally {\n setIsLoading(false);\n }\n };\n\n // Check support\n if (!isSupported) {\n return (\n <div className=\"text-center space-y-4\">\n <div className=\"flex items-center justify-center w-16 h-16 bg-danger/10 rounded-full mx-auto\">\n <svg className=\"w-8 h-8 text-danger\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 15.5c-.77.833.192 2.5 1.732 2.5z\"/>\n </svg>\n </div>\n\n <div>\n <h3 className=\"text-lg font-semibold\">Passkeys Not Supported</h3>\n <p className=\"text-sm text-default-500 mt-2\">\n Your browser doesn't support passkeys. Please use a modern browser like Chrome, Firefox, Safari,\n or Edge.\n </p>\n </div>\n\n <Button variant=\"light\" onPress={onClose}>\n Close\n </Button>\n </div>\n );\n }\n\n if (!isAvailable) {\n return (\n <div className=\"text-center space-y-4\">\n <div className=\"flex items-center justify-center w-16 h-16 bg-warning/10 rounded-full mx-auto\">\n <svg className=\"w-8 h-8 text-warning\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 15.5c-.77.833.192 2.5 1.732 2.5z\"/>\n </svg>\n </div>\n\n <div>\n <h3 className=\"text-lg font-semibold\">No Authenticator Available</h3>\n <p className=\"text-sm text-default-500 mt-2\">\n No biometric or security key authenticator is available on this device.\n </p>\n </div>\n\n <Button variant=\"light\" onPress={onClose}>\n Close\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n {step === 'intro' && (\n <div className=\"text-center space-y-4\">\n <div className=\"flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mx-auto\">\n <svg className=\"w-8 h-8 text-primary\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z\"/>\n </svg>\n </div>\n\n <div>\n <h3 className=\"text-lg font-semibold\">Create a Passkey</h3>\n <p className=\"text-sm text-default-500 mt-2\">\n Passkeys are a secure and convenient way to sign in without a password.\n </p>\n </div>\n\n <div className=\"text-left space-y-3\">\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex items-center justify-center w-6 h-6 bg-success text-white text-xs rounded-full flex-shrink-0 mt-0.5\">✓\n </div>\n <div>\n <p className=\"text-sm font-medium\">More secure than passwords</p>\n <p className=\"text-xs text-default-500\">Protected by your device's security</p>\n </div>\n </div>\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex items-center justify-center w-6 h-6 bg-success text-white text-xs rounded-full flex-shrink-0 mt-0.5\">✓\n </div>\n <div>\n <p className=\"text-sm font-medium\">Fast and convenient</p>\n <p className=\"text-xs text-default-500\">Sign in with just your fingerprint or face</p>\n </div>\n </div>\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex items-center justify-center w-6 h-6 bg-success text-white text-xs rounded-full flex-shrink-0 mt-0.5\">✓\n </div>\n <div>\n <p className=\"text-sm font-medium\">Phishing resistant</p>\n <p className=\"text-xs text-default-500\">Can't be stolen or used on fake sites</p>\n </div>\n </div>\n </div>\n\n <Button\n color=\"primary\"\n onPress={() => setStep('name')}\n className=\"w-full\"\n >\n Continue\n </Button>\n </div>\n )}\n\n {step === 'name' && (\n <div className=\"space-y-4\">\n <div className=\"text-center\">\n <h3 className=\"text-lg font-semibold\">Name Your Passkey</h3>\n <p className=\"text-sm text-default-500 mt-2\">\n Give your passkey a name so you can identify it later.\n </p>\n </div>\n\n <Input\n label=\"Passkey Name\"\n placeholder=\"Enter a name for this passkey\"\n value={passkeyName}\n onValueChange={setPasskeyName}\n description=\"For example: 'iPhone Touch ID' or 'YubiKey'\"\n isInvalid={!passkeyName.trim()}\n errorMessage={!passkeyName.trim() ? 'Name is required' : ''}\n />\n\n <div className=\"flex gap-2\">\n <Button\n variant=\"light\"\n onPress={() => setStep('intro')}\n className=\"flex-1\"\n >\n Back\n </Button>\n <Button\n color=\"primary\"\n onPress={handleRegister}\n isDisabled={!passkeyName.trim()}\n className=\"flex-1\"\n >\n Create Passkey\n </Button>\n </div>\n </div>\n )}\n\n {step === 'registering' && (\n <div className=\"text-center space-y-4\">\n <div className=\"flex items-center justify-center w-16 h-16 bg-primary/10 rounded-full mx-auto\">\n <svg className=\"w-8 h-8 text-primary animate-pulse\" fill=\"none\" stroke=\"currentColor\"\n viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z\"/>\n </svg>\n </div>\n\n <div>\n <h3 className=\"text-lg font-semibold\">Creating Passkey...</h3>\n <p className=\"text-sm text-default-500 mt-2\">\n Follow your browser's prompts to complete the setup.\n </p>\n </div>\n\n <Alert color=\"primary\" variant=\"flat\">\n <div className=\"space-y-1\">\n <p className=\"text-sm font-medium\">What to expect:</p>\n <ul className=\"text-xs space-y-1 ml-4\">\n <li>• You may be asked to use your fingerprint, face, or PIN</li>\n <li>• Or insert and tap your security key</li>\n <li>• Allow the browser to create a passkey</li>\n </ul>\n </div>\n </Alert>\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Passkey Management Component\n// ============================================================================\n\ninterface PasskeyItemProps {\n passkey: any;\n onRename: (id: string, newName: string) => void;\n onDelete: (id: string) => void;\n isDisabled?: boolean;\n}\n\nfunction PasskeyItem({passkey, onRename, onDelete, isDisabled}: PasskeyItemProps) {\n const [isEditing, setIsEditing] = React.useState(false);\n const [editName, setEditName] = React.useState(passkey.name);\n\n const handleSaveEdit = () => {\n if (editName.trim() && editName !== passkey.name) {\n onRename(passkey.id, editName.trim());\n }\n setIsEditing(false);\n };\n\n const handleCancelEdit = () => {\n setEditName(passkey.name);\n setIsEditing(false);\n };\n\n const getPasskeyIcon = () => {\n const authenticatorType = passkey.authenticatorType?.toLowerCase() || '';\n\n if (authenticatorType.includes('platform')) {\n // Platform authenticator (Touch ID, Face ID, Windows Hello, etc.)\n return (\n <svg className=\"w-5 h-5 text-primary\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"/>\n </svg>\n );\n } else {\n // Cross-platform authenticator (Security keys, etc.)\n return (\n <svg className=\"w-5 h-5 text-secondary\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z\"/>\n </svg>\n );\n }\n }\n\n const formatDate = (date: string | Date) => {\n return new Date(date).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n };\n\n return (\n <div className=\"flex items-center justify-between p-4 border border-default-200 rounded-lg\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center justify-center w-10 h-10 bg-default-100 rounded-lg\">\n {getPasskeyIcon()}\n </div>\n\n <div className=\"flex flex-col\">\n {isEditing ? (\n <div className=\"flex items-center gap-2\">\n <Input\n value={editName}\n onValueChange={setEditName}\n size=\"sm\"\n className=\"w-48\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleSaveEdit();\n if (e.key === 'Escape') handleCancelEdit();\n }}\n autoFocus\n />\n <Button size=\"sm\" color=\"primary\" onPress={handleSaveEdit}>\n Save\n </Button>\n <Button size=\"sm\" variant=\"light\" onPress={handleCancelEdit}>\n Cancel\n </Button>\n </div>\n ) : (\n <>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium\">{passkey.name}</span>\n {passkey.isPrimary && (\n <Chip size=\"sm\" color=\"primary\" variant=\"flat\">\n Primary\n </Chip>\n )}\n </div>\n <div className=\"flex items-center gap-2 text-xs text-default-500\">\n <span>Created {formatDate(passkey.createdAt)}</span>\n {passkey.lastUsedAt && (\n <>\n <span>•</span>\n <span>Last used {formatDate(passkey.lastUsedAt)}</span>\n </>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n\n {!isEditing && (\n <Dropdown>\n <DropdownTrigger>\n <Button\n isIconOnly\n variant=\"light\"\n size=\"sm\"\n isDisabled={isDisabled}\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z\"/>\n </svg>\n </Button>\n </DropdownTrigger>\n <DropdownMenu>\n <DropdownItem\n key=\"rename\"\n onPress={() => setIsEditing(true)}\n >\n Rename\n </DropdownItem>\n <DropdownItem\n key=\"delete\"\n color=\"danger\"\n onPress={() => onDelete(passkey.id)}\n >\n Delete\n </DropdownItem>\n </DropdownMenu>\n </Dropdown>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Passkey Setup Component\n// ============================================================================\n\nexport function PasskeySetup({\n onSuccess,\n onError,\n className = '',\n isDisabled = false,\n variant = 'bordered',\n size = 'md',\n showRegistration = true,\n showManagement = true,\n maxPasskeys = 10,\n hideSections = [],\n customTypes = [],\n }: PasskeySetupProps) {\n const {\n passkeys,\n isSupported,\n isAvailable,\n deletePasskey,\n renamePasskey,\n passkeyCount,\n isLoading,\n } = usePasskeys();\n\n const {components} = useConfig();\n const registrationModal = useDisclosure();\n\n // Custom component override\n const CustomPasskeySetup = components.PasskeySetup;\n if (CustomPasskeySetup) {\n return <CustomPasskeySetup {...{\n onSuccess, onError, className, isDisabled, variant, size,\n showRegistration, showManagement, maxPasskeys, hideSections, customTypes\n }} />;\n }\n\n // Handle passkey deletion\n const handleDeletePasskey = async (passkeyId: string) => {\n try {\n await deletePasskey(passkeyId);\n onSuccess?.('Passkey deleted successfully');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to delete passkey';\n onError?.(message);\n }\n };\n\n // Handle passkey rename\n const handleRenamePasskey = async (passkeyId: string, newName: string) => {\n try {\n await renamePasskey(passkeyId, newName);\n onSuccess?.('Passkey renamed successfully');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to rename passkey';\n onError?.(message);\n }\n };\n\n return (\n <div className={`space-y-6 ${className}`}>\n {/* Passkey Status */}\n <Card variant={variant}>\n <CardHeader>\n <div className=\"flex items-center justify-between w-full\">\n <div className=\"flex items-center gap-3\">\n <div className={`flex items-center justify-center w-10 h-10 rounded-lg ${\n passkeyCount > 0 ? 'bg-success/10' : 'bg-default/10'\n }`}>\n <svg className={`w-5 h-5 ${passkeyCount > 0 ? 'text-success' : 'text-default-400'}`}\n fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z\"/>\n </svg>\n </div>\n <div>\n <h4 className=\"text-md font-semibold\">Passkeys</h4>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-default-500\">\n {passkeyCount} of {maxPasskeys} passkeys configured\n </span>\n {passkeyCount > 0 && (\n <Chip size=\"sm\" color=\"success\" variant=\"flat\">\n Active\n </Chip>\n )}\n </div>\n </div>\n </div>\n\n {showRegistration && isSupported && isAvailable && passkeyCount < maxPasskeys && (\n <Button\n color=\"primary\"\n size=\"sm\"\n onPress={registrationModal.onOpen}\n isDisabled={isDisabled || isLoading}\n >\n Add Passkey\n </Button>\n )}\n </div>\n </CardHeader>\n\n {passkeyCount === 0 && (\n <>\n <Divider/>\n <CardBody>\n {!isSupported ? (\n <Alert color=\"warning\" variant=\"flat\">\n <div>\n <p className=\"text-sm font-medium\">Passkeys Not Supported</p>\n <p className=\"text-xs mt-1\">\n Your browser doesn't support passkeys. Please use a modern browser.\n </p>\n </div>\n </Alert>\n ) : !isAvailable ? (\n <Alert color=\"warning\" variant=\"flat\">\n <div>\n <p className=\"text-sm font-medium\">No Authenticator Available</p>\n <p className=\"text-xs mt-1\">\n No biometric or security key authenticator is available on this device.\n </p>\n </div>\n </Alert>\n ) : (\n <div className=\"space-y-3\">\n <p className=\"text-sm text-default-600\">\n Passkeys provide a secure and convenient way to sign in without passwords.\n They use your device's built-in security features like fingerprint, face\n recognition, or security keys.\n </p>\n\n <div className=\"flex items-center gap-2\">\n <svg className=\"w-4 h-4 text-primary\" fill=\"none\" stroke=\"currentColor\"\n viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/>\n </svg>\n <p className=\"text-xs text-default-500\">\n Passkeys are more secure than passwords and can't be stolen or phished.\n </p>\n </div>\n </div>\n )}\n </CardBody>\n </>\n )}\n </Card>\n\n {/* Passkey Management */}\n {showManagement && passkeyCount > 0 && !hideSections.includes('management') && (\n <Card variant={variant}>\n <CardHeader>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center justify-center w-10 h-10 bg-primary/10 rounded-lg\">\n <svg className=\"w-5 h-5 text-primary\" fill=\"none\" stroke=\"currentColor\"\n viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2}\n d=\"M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10\"/>\n </svg>\n </div>\n <div>\n <h4 className=\"text-md font-semibold\">Your Passkeys</h4>\n <p className=\"text-sm text-default-500\">\n Manage your registered passkeys\n </p>\n </div>\n </div>\n </CardHeader>\n <Divider/>\n <CardBody>\n <div className=\"space-y-3\">\n {passkeys.map((passkey) => (\n <PasskeyItem\n key={passkey.id}\n passkey={passkey}\n onRename={handleRenamePasskey}\n onDelete={handleDeletePasskey}\n isDisabled={isDisabled}\n />\n ))}\n </div>\n </CardBody>\n </Card>\n )}\n\n {/* Registration Modal */}\n <Modal\n isOpen={registrationModal.isOpen}\n onOpenChange={registrationModal.onOpenChange}\n size=\"md\"\n placement=\"center\"\n hideCloseButton\n >\n <ModalContent>\n {(onClose) => (\n <>\n <ModalHeader/>\n <ModalBody>\n <PasskeyRegistration\n onSuccess={(message) => {\n onSuccess?.(message);\n onClose();\n }}\n onError={(error) => onError?.(error)}\n onClose={onClose}\n isOpen={registrationModal.isOpen}\n />\n </ModalBody>\n </>\n )}\n </ModalContent>\n </Modal>\n </div>\n );\n}\n\n// ============================================================================\n// Export\n// ============================================================================\n\nexport default PasskeySetup;"],"names":["PasskeyRegistration","onSuccess","onError","onClose","isOpen","registerPasskey","isSupported","isAvailable","usePasskeys","step","setStep","React","passkeyName","setPasskeyName","isLoading","setIsLoading","deviceInfo","getDeviceInfo","userAgent","browser","os","handleRegister","error","message","jsxs","jsx","Button","Input","Alert","PasskeyItem","passkey","onRename","onDelete","isDisabled","isEditing","setIsEditing","editName","setEditName","handleSaveEdit","handleCancelEdit","getPasskeyIcon","formatDate","date","e","Fragment","Chip","Dropdown","DropdownTrigger","DropdownMenu","DropdownItem","PasskeySetup","className","variant","size","showRegistration","showManagement","maxPasskeys","hideSections","customTypes","passkeys","deletePasskey","renamePasskey","passkeyCount","components","useConfig","registrationModal","useDisclosure","CustomPasskeySetup","handleDeletePasskey","passkeyId","handleRenamePasskey","newName","Card","CardHeader","Divider","CardBody","Modal","ModalContent","ModalHeader","ModalBody"],"mappings":"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"}