import { useHttp } from '@inertiajs/vue3'; import type { ComputedRef, Ref } from 'vue'; import { computed, ref } from 'vue'; import { qrCode, recoveryCodes, secretKey } from '@/routes/two-factor'; export type UseTwoFactorAuthReturn = { qrCodeSvg: Ref; manualSetupKey: Ref; recoveryCodesList: Ref; errors: Ref; hasSetupData: ComputedRef; clearSetupData: () => void; clearErrors: () => void; clearTwoFactorAuthData: () => void; fetchQrCode: () => Promise; fetchSetupKey: () => Promise; fetchSetupData: () => Promise; fetchRecoveryCodes: () => Promise; }; const errors = ref([]); const manualSetupKey = ref(null); const qrCodeSvg = ref(null); const recoveryCodesList = ref([]); const hasSetupData = computed( () => qrCodeSvg.value !== null && manualSetupKey.value !== null, ); export const useTwoFactorAuth = (): UseTwoFactorAuthReturn => { const http = useHttp(); const fetchQrCode = async (): Promise => { try { const { svg } = (await http.submit(qrCode())) as { svg: string; url: string; }; qrCodeSvg.value = svg; } catch { errors.value.push('Failed to fetch QR code'); qrCodeSvg.value = null; } }; const fetchSetupKey = async (): Promise => { try { const { secretKey: key } = (await http.submit(secretKey())) as { secretKey: string; }; manualSetupKey.value = key; } catch { errors.value.push('Failed to fetch a setup key'); manualSetupKey.value = null; } }; const clearSetupData = (): void => { manualSetupKey.value = null; qrCodeSvg.value = null; clearErrors(); }; const clearErrors = (): void => { errors.value = []; }; const clearTwoFactorAuthData = (): void => { clearSetupData(); clearErrors(); recoveryCodesList.value = []; }; const fetchRecoveryCodes = async (): Promise => { try { clearErrors(); recoveryCodesList.value = (await http.submit( recoveryCodes(), )) as string[]; } catch { errors.value.push('Failed to fetch recovery codes'); recoveryCodesList.value = []; } }; const fetchSetupData = async (): Promise => { try { clearErrors(); await Promise.all([fetchQrCode(), fetchSetupKey()]); } catch { qrCodeSvg.value = null; manualSetupKey.value = null; } }; return { qrCodeSvg, manualSetupKey, recoveryCodesList, errors, hasSetupData, clearSetupData, clearErrors, clearTwoFactorAuthData, fetchQrCode, fetchSetupKey, fetchSetupData, fetchRecoveryCodes, }; };