init laravel
This commit is contained in:
111
resources/js/hooks/use-two-factor-auth.ts
Normal file
111
resources/js/hooks/use-two-factor-auth.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { useHttp } from '@inertiajs/react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { qrCode, recoveryCodes, secretKey } from '@/routes/two-factor';
|
||||
|
||||
export type UseTwoFactorAuthReturn = {
|
||||
qrCodeSvg: string | null;
|
||||
manualSetupKey: string | null;
|
||||
recoveryCodesList: string[];
|
||||
hasSetupData: boolean;
|
||||
errors: string[];
|
||||
clearErrors: () => void;
|
||||
clearSetupData: () => void;
|
||||
clearTwoFactorAuthData: () => void;
|
||||
fetchQrCode: () => Promise<void>;
|
||||
fetchSetupKey: () => Promise<void>;
|
||||
fetchSetupData: () => Promise<void>;
|
||||
fetchRecoveryCodes: () => Promise<void>;
|
||||
};
|
||||
|
||||
export const OTP_MAX_LENGTH = 6;
|
||||
|
||||
export const useTwoFactorAuth = (): UseTwoFactorAuthReturn => {
|
||||
const { submit } = useHttp();
|
||||
|
||||
const [qrCodeSvg, setQrCodeSvg] = useState<string | null>(null);
|
||||
const [manualSetupKey, setManualSetupKey] = useState<string | null>(null);
|
||||
const [recoveryCodesList, setRecoveryCodesList] = useState<string[]>([]);
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
|
||||
const hasSetupData = qrCodeSvg !== null && manualSetupKey !== null;
|
||||
|
||||
const clearErrors = useCallback((): void => {
|
||||
setErrors([]);
|
||||
}, []);
|
||||
|
||||
const clearSetupData = useCallback((): void => {
|
||||
setManualSetupKey(null);
|
||||
setQrCodeSvg(null);
|
||||
setErrors([]);
|
||||
}, []);
|
||||
|
||||
const clearTwoFactorAuthData = useCallback((): void => {
|
||||
setManualSetupKey(null);
|
||||
setQrCodeSvg(null);
|
||||
setErrors([]);
|
||||
setRecoveryCodesList([]);
|
||||
}, []);
|
||||
|
||||
const fetchQrCode = useCallback(async (): Promise<void> => {
|
||||
try {
|
||||
const { svg } = (await submit(qrCode())) as {
|
||||
svg: string;
|
||||
url: string;
|
||||
};
|
||||
|
||||
setQrCodeSvg(svg);
|
||||
} catch {
|
||||
setErrors((prev) => [...prev, 'Failed to fetch QR code']);
|
||||
setQrCodeSvg(null);
|
||||
}
|
||||
}, [submit]);
|
||||
|
||||
const fetchSetupKey = useCallback(async (): Promise<void> => {
|
||||
try {
|
||||
const { secretKey: key } = (await submit(secretKey())) as {
|
||||
secretKey: string;
|
||||
};
|
||||
|
||||
setManualSetupKey(key);
|
||||
} catch {
|
||||
setErrors((prev) => [...prev, 'Failed to fetch a setup key']);
|
||||
setManualSetupKey(null);
|
||||
}
|
||||
}, [submit]);
|
||||
|
||||
const fetchRecoveryCodes = useCallback(async (): Promise<void> => {
|
||||
try {
|
||||
setErrors([]);
|
||||
const codes = (await submit(recoveryCodes())) as string[];
|
||||
setRecoveryCodesList(codes);
|
||||
} catch {
|
||||
setErrors((prev) => [...prev, 'Failed to fetch recovery codes']);
|
||||
setRecoveryCodesList([]);
|
||||
}
|
||||
}, [submit]);
|
||||
|
||||
const fetchSetupData = useCallback(async (): Promise<void> => {
|
||||
try {
|
||||
setErrors([]);
|
||||
await Promise.all([fetchQrCode(), fetchSetupKey()]);
|
||||
} catch {
|
||||
setQrCodeSvg(null);
|
||||
setManualSetupKey(null);
|
||||
}
|
||||
}, [fetchQrCode, fetchSetupKey]);
|
||||
|
||||
return {
|
||||
qrCodeSvg,
|
||||
manualSetupKey,
|
||||
recoveryCodesList,
|
||||
hasSetupData,
|
||||
errors,
|
||||
clearErrors,
|
||||
clearSetupData,
|
||||
clearTwoFactorAuthData,
|
||||
fetchQrCode,
|
||||
fetchSetupKey,
|
||||
fetchSetupData,
|
||||
fetchRecoveryCodes,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user