{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "use-two-factor-auth", "dependencies": [ "@inertiajs/react" ], "registryDependencies": [], "files": [ { "path": "registry/new-york-v4/hooks/use-two-factor-auth.ts", "content": "import { useHttp } from \"@inertiajs/react\";\nimport { useCallback, useState } from \"react\";\nimport { qrCode, recoveryCodes, secretKey } from \"@/routes/two-factor\";\n\nexport type UseTwoFactorAuthReturn = {\n qrCodeSvg: string | null;\n manualSetupKey: string | null;\n recoveryCodesList: string[];\n hasSetupData: boolean;\n errors: string[];\n clearErrors: () => void;\n clearSetupData: () => void;\n clearTwoFactorAuthData: () => void;\n fetchQrCode: () => Promise;\n fetchSetupKey: () => Promise;\n fetchSetupData: () => Promise;\n fetchRecoveryCodes: () => Promise;\n};\n\nexport const OTP_MAX_LENGTH = 6;\n\nexport const useTwoFactorAuth = (): UseTwoFactorAuthReturn => {\n const { submit } = useHttp();\n\n const [qrCodeSvg, setQrCodeSvg] = useState(null);\n const [manualSetupKey, setManualSetupKey] = useState(null);\n const [recoveryCodesList, setRecoveryCodesList] = useState([]);\n const [errors, setErrors] = useState([]);\n\n const hasSetupData = qrCodeSvg !== null && manualSetupKey !== null;\n\n const clearErrors = useCallback((): void => {\n setErrors([]);\n }, []);\n\n const clearSetupData = useCallback((): void => {\n setManualSetupKey(null);\n setQrCodeSvg(null);\n setRecoveryCodesList([]);\n setErrors([]);\n }, []);\n\n const clearTwoFactorAuthData = useCallback((): void => {\n setManualSetupKey(null);\n setQrCodeSvg(null);\n setErrors([]);\n setRecoveryCodesList([]);\n }, []);\n\n const fetchQrCode = useCallback(async (): Promise => {\n try {\n const { svg } = (await submit(qrCode())) as {\n svg: string;\n url: string;\n };\n\n setQrCodeSvg(svg);\n } catch {\n setErrors((prev) => [...prev, \"Failed to fetch QR code\"]);\n setQrCodeSvg(null);\n }\n }, [submit]);\n\n const fetchSetupKey = useCallback(async (): Promise => {\n try {\n const { secretKey: key } = (await submit(secretKey())) as {\n secretKey: string;\n };\n\n setManualSetupKey(key);\n } catch {\n setErrors((prev) => [...prev, \"Failed to fetch a setup key\"]);\n setManualSetupKey(null);\n }\n }, [submit]);\n\n const fetchRecoveryCodes = useCallback(async (): Promise => {\n try {\n setErrors([]);\n const codes = (await submit(recoveryCodes())) as string[];\n setRecoveryCodesList(codes);\n } catch {\n setErrors((prev) => [...prev, \"Failed to fetch recovery codes\"]);\n setRecoveryCodesList([]);\n }\n }, [submit]);\n\n const fetchSetupData = useCallback(async (): Promise => {\n try {\n setErrors([]);\n await Promise.all([fetchQrCode(), fetchSetupKey(), fetchRecoveryCodes()]);\n } catch {\n setQrCodeSvg(null);\n setManualSetupKey(null);\n setRecoveryCodesList([]);\n }\n }, [fetchQrCode, fetchRecoveryCodes, fetchSetupKey]);\n\n return {\n qrCodeSvg,\n manualSetupKey,\n recoveryCodesList,\n hasSetupData,\n errors,\n clearErrors,\n clearSetupData,\n clearTwoFactorAuthData,\n fetchQrCode,\n fetchSetupKey,\n fetchSetupData,\n fetchRecoveryCodes,\n };\n};\n", "type": "registry:hook" } ], "type": "registry:hook" }