263 lines
14 KiB
Vue
263 lines
14 KiB
Vue
<script setup lang="ts">
|
|
import { useForm } from '@inertiajs/vue3';
|
|
import Button from '@/components/ui/Button.vue';
|
|
import Input from '@/components/ui/Input.vue';
|
|
import Message from '@/components/ui/Message.vue';
|
|
import Tabs from '@/components/ui/Tabs.vue';
|
|
import FeatureToggleCard from '@/components/FeatureToggleCard.vue';
|
|
import SettingsCard from '@/components/SettingsCard.vue';
|
|
import ToggleField from '@/components/ToggleField.vue';
|
|
import { useTranslations } from '@/composables/useVanguard';
|
|
import AppLayout from '@/layouts/AppLayout.vue';
|
|
import { ref } from 'vue';
|
|
|
|
const props = defineProps<{
|
|
values: Record<string, string | number>;
|
|
captchaConfigured: boolean;
|
|
}>();
|
|
|
|
const { __ } = useTranslations();
|
|
|
|
const general = useForm({
|
|
remember_me: Number(props.values.remember_me ?? 0),
|
|
forgot_password: Number(props.values.forgot_password ?? 0),
|
|
login_reset_token_lifetime: String(props.values.login_reset_token_lifetime ?? 30),
|
|
max_active_sessions: String(props.values.max_active_sessions ?? 0),
|
|
});
|
|
|
|
const throttling = useForm({
|
|
throttle_enabled: Number(props.values.throttle_enabled ?? 0),
|
|
throttle_attempts: String(props.values.throttle_attempts ?? 10),
|
|
throttle_lockout_time: String(props.values.throttle_lockout_time ?? 1),
|
|
});
|
|
|
|
const registration = useForm({
|
|
reg_enabled: Number(props.values.reg_enabled ?? 0),
|
|
tos: Number(props.values.tos ?? 0),
|
|
reg_email_confirmation: Number(props.values.reg_email_confirmation ?? 0),
|
|
});
|
|
|
|
function submit(form: { post: (url: string, options: object) => void }) {
|
|
form.post(route('settings.auth.update'), { preserveScroll: true });
|
|
}
|
|
|
|
/**
|
|
* Keys containing quotes or ampersands are declared here rather than inline in
|
|
* the template, so the string handed to __() matches the language file key
|
|
* exactly and is not altered by HTML entity decoding.
|
|
*/
|
|
const labels = {
|
|
rememberMe: __('Allow "Remember Me"'),
|
|
rememberMeHint: __("Should 'Remember Me' checkbox be displayed on login form?"),
|
|
terms: __('Terms & Conditions'),
|
|
};
|
|
|
|
const activeTab = ref('auth');
|
|
|
|
const tabs = [
|
|
{ value: 'auth', label: __('Authentication'), icon: 'fa fa-lock' },
|
|
{ value: 'registration', label: __('Registration'), icon: 'fa fa-user-plus' },
|
|
];
|
|
</script>
|
|
|
|
<template>
|
|
<AppLayout
|
|
:title="__('Authentication Settings')"
|
|
:heading="__('Authentication')"
|
|
:breadcrumbs="[{ label: __('Settings') }, { label: __('Authentication') }]"
|
|
>
|
|
<Tabs v-model="activeTab" :tabs="tabs">
|
|
<template #auth>
|
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<div class="space-y-4">
|
|
<SettingsCard :title="__('General')">
|
|
<form class="space-y-6" @submit.prevent="submit(general)">
|
|
<ToggleField
|
|
v-model="general.remember_me"
|
|
input-id="switch-remember-me"
|
|
:label="labels.rememberMe"
|
|
:description="labels.rememberMeHint"
|
|
/>
|
|
|
|
<ToggleField
|
|
v-model="general.forgot_password"
|
|
input-id="switch-forgot-pass"
|
|
:label="__('Forgot Password')"
|
|
:description="__('Enable/Disable forgot password feature.')"
|
|
/>
|
|
|
|
<div>
|
|
<label for="login_reset_token_lifetime" class="block text-slate-700">
|
|
{{ __('Reset Token Lifetime') }}
|
|
</label>
|
|
<small class="mb-1 block text-slate-500">
|
|
{{ __('Number of minutes that the reset token should be considered valid.') }}
|
|
</small>
|
|
<Input
|
|
id="login_reset_token_lifetime"
|
|
v-model="general.login_reset_token_lifetime"
|
|
class="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="max_active_sessions" class="block text-slate-700">
|
|
{{ __('Max Number of Active Sessions') }}
|
|
</label>
|
|
<small class="mb-1 block text-slate-500">
|
|
{{ __('Maximum number of active sessions per user. Set to 0 to allow unlimited number of active sessions.') }}
|
|
{{ __('Only applies when using database session driver.') }}
|
|
</small>
|
|
<Input
|
|
id="max_active_sessions"
|
|
v-model="general.max_active_sessions"
|
|
class="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<Button
|
|
type="submit"
|
|
:label="__('Update')"
|
|
:loading="general.processing"
|
|
/>
|
|
</form>
|
|
</SettingsCard>
|
|
|
|
<FeatureToggleCard
|
|
:title="__('Two-Factor Authentication')"
|
|
:description="__('Enable/Disable Two-Factor Authentication for the application.')"
|
|
:enabled="Boolean(Number(values['2fa.enabled']))"
|
|
:enable-url="route('settings.auth.2fa.enable')"
|
|
:disable-url="route('settings.auth.2fa.disable')"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<SettingsCard :title="__('Authentication Throttling')">
|
|
<form class="space-y-6" @submit.prevent="submit(throttling)">
|
|
<ToggleField
|
|
v-model="throttling.throttle_enabled"
|
|
input-id="switch-throttle"
|
|
:label="__('Throttle Authentication')"
|
|
:description="__('Should the system throttle authentication attempts?')"
|
|
/>
|
|
|
|
<div>
|
|
<label for="throttle_attempts" class="block text-slate-700">
|
|
{{ __('Maximum Number of Attempts') }}
|
|
</label>
|
|
<small class="mb-1 block text-slate-500">
|
|
{{ __('Maximum number of incorrect login attempts before lockout.') }}
|
|
</small>
|
|
<Input
|
|
id="throttle_attempts"
|
|
v-model="throttling.throttle_attempts"
|
|
class="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="throttle_lockout_time" class="block text-slate-700">
|
|
{{ __('Lockout Time') }}
|
|
</label>
|
|
<small class="mb-1 block text-slate-500">
|
|
{{ __('Number of minutes to lock the user out for after specified maximum number of incorrect login attempts.') }}
|
|
</small>
|
|
<Input
|
|
id="throttle_lockout_time"
|
|
v-model="throttling.throttle_lockout_time"
|
|
class="w-full"
|
|
/>
|
|
</div>
|
|
|
|
<Button
|
|
type="submit"
|
|
:label="__('Update')"
|
|
:loading="throttling.processing"
|
|
/>
|
|
</form>
|
|
</SettingsCard>
|
|
|
|
<FeatureToggleCard
|
|
:title="__('User Confirmation Flow')"
|
|
:description="__('Enable/Disable the user confirmation flow for the application. When enabled, users will be set to Waiting Approval and require admin approval before becoming Active.')"
|
|
:enabled="Boolean(Number(values['approval.enabled']))"
|
|
:enable-url="route('settings.auth.approval.enable')"
|
|
:disable-url="route('settings.auth.approval.disable')"
|
|
/>
|
|
|
|
<FeatureToggleCard
|
|
:title="__('Force Password Change On Next Login')"
|
|
:description="__('Force all the users created manually by admin to reset the password on their first log in to be able to use the application.')"
|
|
:enabled="Boolean(Number(values['password-change.enabled']))"
|
|
:enable-url="route('settings.auth.password-change.enable')"
|
|
:disable-url="route('settings.auth.password-change.disable')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<template #registration>
|
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<SettingsCard :title="__('General')">
|
|
<form class="space-y-6" @submit.prevent="submit(registration)">
|
|
<ToggleField
|
|
v-model="registration.reg_enabled"
|
|
input-id="switch-reg-enabled"
|
|
:label="__('Allow Registration')"
|
|
/>
|
|
|
|
<ToggleField
|
|
v-model="registration.tos"
|
|
input-id="switch-tos"
|
|
:label="labels.terms"
|
|
:description="__('The user has to confirm that he agrees with terms and conditions in order to create an account.')"
|
|
/>
|
|
|
|
<ToggleField
|
|
v-model="registration.reg_email_confirmation"
|
|
input-id="switch-reg-email-confirm"
|
|
:label="__('Email Confirmation')"
|
|
:description="__('Require email confirmation from your newly registered users.')"
|
|
/>
|
|
|
|
<Button
|
|
type="submit"
|
|
:label="__('Update')"
|
|
:loading="registration.processing"
|
|
/>
|
|
</form>
|
|
</SettingsCard>
|
|
|
|
<FeatureToggleCard
|
|
:title="__('Google reCAPTCHA')"
|
|
:description="__('Enable/Disable Google reCAPTCHA during the registration.')"
|
|
:enabled="Boolean(Number(values['registration.captcha.enabled']))"
|
|
:enable-url="route('settings.registration.captcha.enable')"
|
|
:disable-url="route('settings.registration.captcha.disable')"
|
|
>
|
|
<template v-if="!captchaConfigured" #notice>
|
|
<Message severity="info">
|
|
{{ __('To utilize Google reCAPTCHA, please get your') }}
|
|
<code>{{ __('Site Key') }}</code>
|
|
{{ __('and') }} <code>{{ __('Secret Key') }}</code>
|
|
{{ __('from') }}
|
|
<a
|
|
href="https://www.google.com/recaptcha/intro/index.html"
|
|
target="_blank"
|
|
rel="noopener"
|
|
class="font-bold underline"
|
|
>{{ __('reCAPTCHA Website') }}</a>,
|
|
{{ __('and update your') }} <code>RECAPTCHA_SITEKEY</code>
|
|
{{ __('and') }} <code>RECAPTCHA_SECRETKEY</code>
|
|
{{ __('environment variables inside') }} <code>.env</code>
|
|
{{ __('file') }}.
|
|
</Message>
|
|
</template>
|
|
</FeatureToggleCard>
|
|
</div>
|
|
</template>
|
|
</Tabs>
|
|
</AppLayout>
|
|
</template>
|