# All files / js/pages/settings TwoFactor.vue

0% Statements 0/20
0% Branches 0/24
0% Functions 0/13
0% Lines 0/20

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
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122

     <script setup lang="ts">
    import HeadingSmall from '@/components/HeadingSmall.vue';
    import TwoFactorRecoveryCodes from '@/components/TwoFactorRecoveryCodes.vue';
    import TwoFactorSetupModal from '@/components/TwoFactorSetupModal.vue';
    import { Badge } from '@/components/ui/badge';
    import { Button } from '@/components/ui/button';
    import { useTwoFactorAuth } from '@/composables/useTwoFactorAuth';
    import AppLayout from '@/layouts/AppLayout.vue';
    import SettingsLayout from '@/layouts/settings/Layout.vue';
    import { disable, enable, show } from '@/routes/two-factor';
    import { BreadcrumbItem } from '@/types';
    import { Form, Head } from '@inertiajs/vue3';
    import { ShieldBan, ShieldCheck } from 'lucide-vue-next';
    import { onUnmounted, ref } from 'vue';

    interface Props {
        requiresConfirmation?: boolean;
        twoFactorEnabled?: boolean;
    }

    withDefaults(defineProps<Props>(), {
        requiresConfirmation: false,
        twoFactorEnabled: false,
    });

    const breadcrumbs: BreadcrumbItem[] = [
        {
            title: 'Two-Factor Authentication',
            href: show.url(),
        },
    ];

    const { hasSetupData, clearTwoFactorAuthData } = useTwoFactorAuth();
    const showSetupModal = ref<boolean>(false);

    onUnmounted(() => {
        clearTwoFactorAuthData();
    });
    </script>

    <template>
        <AppLayout :breadcrumbs="breadcrumbs">
            <Head title="Two-Factor Authentication" />
            <SettingsLayout>
                <div class="space-y-6">
                    <HeadingSmall
                        title="Two-Factor Authentication"
                        description="Manage your two-factor authentication settings"
                    />

                    <div
                        v-if="!twoFactorEnabled"
                        class="flex flex-col items-start justify-start space-y-4"
                    >
                        <Badge variant="destructive">Disabled</Badge>

                        <p class="text-muted-foreground">
                            When you enable two-factor authentication, you will be
                            prompted for a secure pin during login. This pin can be
                            retrieved from a TOTP-supported application on your
                            phone.
                        </p>

                        <div>
                            <Button
                                v-if="hasSetupData"
                                @click="showSetupModal = true"
                            >
                                <ShieldCheck />Continue Setup
                            </Button>
                            <Form
                                v-else
                                v-bind="enable.form()"
                                @success="showSetupModal = true"
                                #default="{ processing }"
                            >
                                <Button type="submit" :disabled="processing">
                                    <ShieldCheck />Enable 2FA</Button
                                ></Form
                            >
                        </div>
                    </div>

                    <div
                        v-else
                        class="flex flex-col items-start justify-start space-y-4"
                    >
                        <Badge variant="default">Enabled</Badge>

                        <p class="text-muted-foreground">
                            With two-factor authentication enabled, you will be
                            prompted for a secure, random pin during login, which
                            you can retrieve from the TOTP-supported application on
                            your phone.
                        </p>

                        <TwoFactorRecoveryCodes />

                        <div class="relative inline">
                            <Form v-bind="disable.form()" #default="{ processing }">
                                <Button
                                    variant="destructive"
                                    type="submit"
                                    :disabled="processing"
                                >
                                    <ShieldBan />
                                    Disable 2FA
                                </Button>
                            </Form>
                        </div>
                    </div>

                    <TwoFactorSetupModal
                        v-model:isOpen="showSetupModal"
                        :requiresConfirmation="requiresConfirmation"
                        :twoFactorEnabled="twoFactorEnabled"
                    />
                </div>
            </SettingsLayout>
        </AppLayout>
    </template>