# All files / js/composables useTwoFactorAuth.ts

0% Statements 0/35
0% Branches 0/4
0% Functions 0/9
0% Lines 0/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88

     import { qrCode, recoveryCodes, secretKey } from '@/routes/two-factor';
    import { computed, ref } from 'vue';

    const fetchJson = async <T>(url: string): Promise<T> => {
        const response = await fetch(url, {
            headers: { Accept: 'application/json' },
        });

        if (!response.ok) {
            throw new Error(`Failed to fetch: ${response.status}`);
        }

        return response.json();
    };

    const qrCodeSvg = ref<string | null>(null);
    const manualSetupKey = ref<string | null>(null);
    const recoveryCodesList = ref<string[]>([]);

    const hasSetupData = computed<boolean>(
        () => qrCodeSvg.value !== null && manualSetupKey.value !== null,
    );

    export const useTwoFactorAuth = () => {
        const fetchQrCode = async (): Promise<void> => {
            const { svg } = await fetchJson<{ svg: string; url: string }>(
                qrCode.url(),
            );

            qrCodeSvg.value = svg;
        };

        const fetchSetupKey = async (): Promise<void> => {
            const { secretKey: key } = await fetchJson<{ secretKey: string }>(
                secretKey.url(),
            );

            manualSetupKey.value = key;
        };

        const clearSetupData = (): void => {
            manualSetupKey.value = null;
            qrCodeSvg.value = null;
        };

        const clearTwoFactorAuthData = (): void => {
            clearSetupData();

            recoveryCodesList.value = [];
        };

        const fetchRecoveryCodes = async (): Promise<void> => {
            try {
                recoveryCodesList.value = await fetchJson<string[]>(
                    recoveryCodes.url(),
                );
            } catch (error) {
                console.error('Failed to fetch recovery codes:', error);

                recoveryCodesList.value = [];
            }
        };

        const fetchSetupData = async (): Promise<void> => {
            try {
                await Promise.all([fetchQrCode(), fetchSetupKey()]);
            } catch (error) {
                console.error('Failed to fetch setup data:', error);

                qrCodeSvg.value = null;
                manualSetupKey.value = null;
            }
        };

        return {
            qrCodeSvg,
            manualSetupKey,
            recoveryCodesList,
            hasSetupData,
            clearSetupData,
            clearTwoFactorAuthData,
            fetchQrCode,
            fetchSetupKey,
            fetchSetupData,
            fetchRecoveryCodes,
        };
    };