Avoid optional Fortify route imports
linter / quality (pull_request) Successful in 1m22s
tests / ci (8.4) (pull_request) Successful in 1m35s

This commit is contained in:
2026-05-22 23:33:01 +00:00
parent fd0d6ac6d6
commit 94e32497b0
14 changed files with 76 additions and 32 deletions
@@ -12,7 +12,7 @@ import {
CardTitle,
} from '@/components/ui/card';
import { useTwoFactorAuth } from '@/composables/useTwoFactorAuth';
import { regenerateRecoveryCodes } from '@/routes/two-factor';
import { fortifyRoutes } from '@/lib/fortify';
const { recoveryCodesList, fetchRecoveryCodes, errors } = useTwoFactorAuth();
const isRecoveryCodesVisible = ref<boolean>(false);
@@ -64,7 +64,7 @@ onMounted(async () => {
<Form
v-if="isRecoveryCodesVisible && recoveryCodesList.length"
v-bind="regenerateRecoveryCodes.form()"
:action="fortifyRoutes.twoFactor.recoveryCodes"
method="post"
:options="{ preserveScroll: true }"
@success="fetchRecoveryCodes"
@@ -21,7 +21,7 @@ import {
import { Spinner } from '@/components/ui/spinner';
import { useAppearance } from '@/composables/useAppearance';
import { useTwoFactorAuth } from '@/composables/useTwoFactorAuth';
import { confirm } from '@/routes/two-factor';
import { fortifyRoutes } from '@/lib/fortify';
import type { TwoFactorConfigContent } from '@/types';
type Props = {
@@ -238,7 +238,8 @@ watch(
<template v-else>
<Form
v-bind="confirm.form()"
:action="fortifyRoutes.twoFactor.confirm"
method="post"
error-bag="confirmTwoFactorAuthentication"
reset-on-error
@finish="code = ''"
+4 -4
View File
@@ -1,6 +1,6 @@
import type { ComputedRef, Ref } from 'vue';
import { computed, ref } from 'vue';
import { qrCode, recoveryCodes, secretKey } from '@/routes/two-factor';
import { fortifyRoutes } from '@/lib/fortify';
export type UseTwoFactorAuthReturn = {
qrCodeSvg: Ref<string | null>;
@@ -42,7 +42,7 @@ export const useTwoFactorAuth = (): UseTwoFactorAuthReturn => {
const fetchQrCode = async (): Promise<void> => {
try {
const { svg } = await fetchJson<{ svg: string; url: string }>(
qrCode.url(),
fortifyRoutes.twoFactor.qrCode,
);
qrCodeSvg.value = svg;
@@ -55,7 +55,7 @@ export const useTwoFactorAuth = (): UseTwoFactorAuthReturn => {
const fetchSetupKey = async (): Promise<void> => {
try {
const { secretKey: key } = await fetchJson<{ secretKey: string }>(
secretKey.url(),
fortifyRoutes.twoFactor.secretKey,
);
manualSetupKey.value = key;
@@ -85,7 +85,7 @@ export const useTwoFactorAuth = (): UseTwoFactorAuthReturn => {
try {
clearErrors();
recoveryCodesList.value = await fetchJson<string[]>(
recoveryCodes.url(),
fortifyRoutes.twoFactor.recoveryCodes,
);
} catch {
errors.value.push('Failed to fetch recovery codes');
+25
View File
@@ -0,0 +1,25 @@
export const fortifyRoutes = {
register: {
create: '/register',
store: '/register',
},
password: {
request: '/forgot-password',
email: '/forgot-password',
update: '/reset-password',
confirm: '/user/confirm-password',
reset: (token: string): string => `/reset-password/${encodeURIComponent(token)}`,
},
verification: {
send: '/email/verification-notification',
},
twoFactor: {
challenge: '/two-factor-challenge',
enable: '/user/two-factor-authentication',
disable: '/user/two-factor-authentication',
confirm: '/user/confirmed-two-factor-authentication',
qrCode: '/user/two-factor-qr-code',
recoveryCodes: '/user/two-factor-recovery-codes',
secretKey: '/user/two-factor-secret-key',
},
} as const;
+3 -2
View File
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { Head, Link } from '@inertiajs/vue3';
import { dashboard, login, register } from '@/routes/index';
import { fortifyRoutes } from '@/lib/fortify';
import { dashboard, login } from '@/routes/index';
withDefaults(
defineProps<{
@@ -40,7 +41,7 @@ withDefaults(
</Link>
<Link
v-if="canRegister"
:href="register()"
:href="fortifyRoutes.register.create"
class="inline-block rounded-sm border border-[#19140035] px-5 py-1.5 text-sm leading-normal text-[#1b1b18] hover:border-[#1915014a] dark:border-[#3E3E3A] dark:text-[#EDEDEC] dark:hover:border-[#62605b]"
>
Register
+3 -2
View File
@@ -5,8 +5,8 @@ import PasswordInput from '@/components/PasswordInput.vue';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { fortifyRoutes } from '@/lib/fortify';
import AuthLayout from '@/layouts/AuthLayout.vue';
import { store } from '@/routes/password/confirm';
</script>
<template>
@@ -17,7 +17,8 @@ import { store } from '@/routes/password/confirm';
<Head title="Confirm password" />
<Form
v-bind="store.form()"
:action="fortifyRoutes.password.confirm"
method="post"
reset-on-success
v-slot="{ errors, processing }"
>
+6 -2
View File
@@ -6,9 +6,9 @@ import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { fortifyRoutes } from '@/lib/fortify';
import AuthLayout from '@/layouts/AuthLayout.vue';
import { login } from '@/routes/index';
import { email } from '@/routes/password';
defineProps<{
status?: string;
@@ -30,7 +30,11 @@ defineProps<{
</div>
<div class="space-y-6">
<Form v-bind="email.form()" v-slot="{ errors, processing }">
<Form
:action="fortifyRoutes.password.email"
method="post"
v-slot="{ errors, processing }"
>
<div class="grid gap-2">
<Label for="email">Email address</Label>
<Input
+5 -4
View File
@@ -8,10 +8,9 @@ import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { fortifyRoutes } from '@/lib/fortify';
import AuthBase from '@/layouts/AuthLayout.vue';
import { register } from '@/routes/index';
import { store } from '@/routes/login';
import { request } from '@/routes/password';
defineProps<{
status?: string;
@@ -61,7 +60,7 @@ defineProps<{
<Label for="password">Password</Label>
<TextLink
v-if="canResetPassword"
:href="request()"
:href="fortifyRoutes.password.request"
class="text-sm"
:tabindex="5"
>
@@ -103,7 +102,9 @@ defineProps<{
v-if="canRegister"
>
Don't have an account?
<TextLink :href="register()" :tabindex="5">Sign up</TextLink>
<TextLink :href="fortifyRoutes.register.create" :tabindex="5">
Sign up
</TextLink>
</div>
</Form>
</AuthBase>
+3 -2
View File
@@ -7,9 +7,9 @@ import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { fortifyRoutes } from '@/lib/fortify';
import AuthBase from '@/layouts/AuthLayout.vue';
import { login } from '@/routes/index';
import { store } from '@/routes/register';
</script>
<template>
@@ -20,7 +20,8 @@ import { store } from '@/routes/register';
<Head title="Register" />
<Form
v-bind="store.form()"
:action="fortifyRoutes.register.store"
method="post"
:reset-on-success="['password', 'password_confirmation']"
v-slot="{ errors, processing }"
class="flex flex-col gap-6"
+3 -2
View File
@@ -7,8 +7,8 @@ import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { fortifyRoutes } from '@/lib/fortify';
import AuthLayout from '@/layouts/AuthLayout.vue';
import { update } from '@/routes/password';
const props = defineProps<{
token: string;
@@ -26,7 +26,8 @@ const inputEmail = ref(props.email);
<Head title="Reset password" />
<Form
v-bind="update.form()"
:action="fortifyRoutes.password.update"
method="post"
:transform="(data) => ({ ...data, token, email })"
:reset-on-success="['password', 'password_confirmation']"
v-slot="{ errors, processing }"
@@ -9,8 +9,8 @@ import {
InputOTPGroup,
InputOTPSlot,
} from '@/components/ui/input-otp';
import { fortifyRoutes } from '@/lib/fortify';
import AuthLayout from '@/layouts/AuthLayout.vue';
import { store } from '@/routes/two-factor/login';
import type { TwoFactorConfigContent } from '@/types';
const authConfigContent = computed<TwoFactorConfigContent>(() => {
@@ -52,7 +52,8 @@ const code = ref<string>('');
<div class="space-y-6">
<template v-if="!showRecoveryInput">
<Form
v-bind="store.form()"
:action="fortifyRoutes.twoFactor.challenge"
method="post"
class="space-y-4"
reset-on-error
@error="code = ''"
@@ -99,7 +100,8 @@ const code = ref<string>('');
<template v-else>
<Form
v-bind="store.form()"
:action="fortifyRoutes.twoFactor.challenge"
method="post"
class="space-y-4"
reset-on-error
#default="{ errors, processing, clearErrors }"
+3 -2
View File
@@ -3,9 +3,9 @@ import { Form, Head } from '@inertiajs/vue3';
import TextLink from '@/components/TextLink.vue';
import { Button } from '@/components/ui/button';
import { Spinner } from '@/components/ui/spinner';
import { fortifyRoutes } from '@/lib/fortify';
import AuthLayout from '@/layouts/AuthLayout.vue';
import { logout } from '@/routes/index';
import { send } from '@/routes/verification';
defineProps<{
status?: string;
@@ -28,7 +28,8 @@ defineProps<{
</div>
<Form
v-bind="send.form()"
:action="fortifyRoutes.verification.send"
method="post"
class="space-y-6 text-center"
v-slot="{ processing }"
>
+3 -2
View File
@@ -8,10 +8,10 @@ import InputError from '@/components/InputError.vue';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { fortifyRoutes } from '@/lib/fortify';
import AppLayout from '@/layouts/AppLayout.vue';
import SettingsLayout from '@/layouts/settings/Layout.vue';
import { edit } from '@/routes/profile/index';
import { send } from '@/routes/verification';
import type { BreadcrumbItem } from '@/types';
type Props = {
@@ -84,7 +84,8 @@ const user = computed(() => page.props.auth.user);
<p class="text-muted-foreground -mt-4 text-sm">
Your email address is unverified.
<Link
:href="send()"
:href="fortifyRoutes.verification.send"
method="post"
as="button"
class="text-foreground hover:decoration-current! underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out dark:decoration-neutral-500"
>
+8 -3
View File
@@ -11,10 +11,10 @@ import TwoFactorSetupModal from '@/components/TwoFactorSetupModal.vue';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { useTwoFactorAuth } from '@/composables/useTwoFactorAuth';
import { fortifyRoutes } from '@/lib/fortify';
import AppLayout from '@/layouts/AppLayout.vue';
import SettingsLayout from '@/layouts/settings/Layout.vue';
import { edit } from '@/routes/security/index';
import { disable, enable } from '@/routes/two-factor';
import type { BreadcrumbItem } from '@/types';
type Props = {
@@ -175,7 +175,8 @@ onUnmounted(() => clearTwoFactorAuthData());
</Button>
<Form
v-else
v-bind="enable.form()"
:action="fortifyRoutes.twoFactor.enable"
method="post"
@success="showSetupModal = true"
#default="{ processing }"
>
@@ -197,7 +198,11 @@ onUnmounted(() => clearTwoFactorAuthData());
</p>
<div class="relative inline">
<Form v-bind="disable.form()" #default="{ processing }">
<Form
:action="fortifyRoutes.twoFactor.disable"
method="delete"
#default="{ processing }"
>
<Button
variant="destructive"
type="submit"