- added backup codes for 2 factor authentication
Some checks failed
CI Pipeline / japa-tests (push) Failing after 58s

- npm updates
- coverage validation: elevation ust be positive, depth must be negative
- vinejs-provider.js: get enabled extensions from database, not via validOptions.extnames
- vue components for backup codes: e.g.: PersonalSettings.vue
- validate spaital coverage in leaflet map: draw.component.vue, map.component.vue
- add backup code authentication into Login.vue
- preset to use no preferred reviewer: Release.vue
- 2 new vinejs validation rules: file_scan.ts and file-length.ts
This commit is contained in:
Kaimbacher 2024-07-08 13:52:20 +02:00
parent ac473b1e72
commit 005df2e454
32 changed files with 1416 additions and 526 deletions

View file

@ -29,6 +29,7 @@ import { computed, Ref } from 'vue';
import { usePage } from '@inertiajs/vue3';
import FormValidationErrors from '@/Components/FormValidationErrors.vue';
import PersonalTotpSettings from '@/Components/PersonalTotpSettings.vue';
// import PersonalSettings from '@/Components/PersonalSettings.vue';
// import { MainService } from '@/Stores/main';
// const mainService = MainService();
@ -47,9 +48,9 @@ defineProps({
code: {
type: Object,
},
recoveryCodes: {
type: Array<string>,
default: () => [],
backupState: {
type: Object,
default: () => ({}),
},
errors: {
type: Object,
@ -211,7 +212,10 @@ const flash: Ref<any> = computed(() => {
<PersonalTotpSettings :twoFactorEnabled="twoFactorEnabled"/>
<PersonalTotpSettings :twoFactorEnabled="twoFactorEnabled" :backupState="backupState">
</PersonalTotpSettings>
<!-- <PersonalSettings :state="backupState"/> -->
<!-- <CardBox v-if="!props.twoFactorEnabled" title="Two-Factor Authentication" :icon="mdiInformation" form
@submit.prevent="enableTwoFactorAuthentication()">
<div class="text-lg font-medium text-gray-900">

View file

@ -1,4 +1,3 @@
<template>
<LayoutGuest>
@ -11,8 +10,7 @@
<!-- <span class="self-center text-2xl font-bold whitespace-nowrap">Tethys</span> -->
</a>
<CardBox v-if="isTwoFactorAuthNeeded == false" :class="cardClass" form
@submit.prevent="submit">
<CardBox v-if="isTwoFactorAuthNeeded == false" :class="cardClass" form @submit.prevent="submit">
<FormValidationErrors v-bind:errors="errors" />
<NotificationBarInCard v-if="status" color="info">
@ -47,8 +45,8 @@
<!-- buttons -->
<BaseButtons>
<BaseButton type="submit" color="info" label=" Login to your account" :class="{ 'opacity-25': form.processing }"
v-bind:disabled="form.processing" />
<BaseButton type="submit" color="info" label=" Login to your account"
:class="{ 'opacity-25': form.processing }" v-bind:disabled="form.processing" />
<!-- <button type="submit" v-bind:disabled="form.processing" :class="{ 'opacity-25': form.processing }"
class="text-white bg-cyan-600 hover:bg-cyan-700 focus:ring-4 focus:ring-cyan-200 font-medium rounded-lg text-base px-5 py-3 w-full sm:w-auto text-center">
Login to your account
@ -66,10 +64,29 @@
<CardBox v-else-if="isTwoFactorAuthNeeded" :icon="mdiTwoFactorAuthentication" :class="cardClass" form
@submit.prevent="submitFa2Form">
<FormField label="2FA Code" label-for="code" help="Please enter 2factor code">
<!-- authentication method menu -->
<div class="lex flex-col md:flex-row mb-3">
<label for="authmethod-option-one" class="pure-radio">
<input id="authmethod-option-one" type="radio" v-model="authMethod" value="code" />
use 2fa app
</label>
<label for="authmethod-option-two" class="pure-radio">
<input id="authmethod-option-two" type="radio" v-model="authMethod" value="backupCode" />
use backup code
</label>
</div>
<FormField v-if="authMethod === 'code'" label="2FA Code" label-for="code" help="Please enter 2factor code">
<FormControl v-model="fa2Form.code" :icon="mdiAccount" id="code" type="tel" required />
</FormField>
<FormField v-if="authMethod === 'backupCode'" label="Backup Code" label-for="backupCode" help="Please enter backup code">
<FormControl v-model="fa2Form.backup_code" :icon="mdiAccount" id="backupCode" type="tel" required />
</FormField>
<div v-if="flash && flash.message" class="flex flex-col mt-6 animate-fade-in">
<div class="bg-yellow-500 border-l-4 border-orange-400 text-white p-4" role="alert">
<p class="font-bold">Be Warned</p>
@ -85,8 +102,8 @@
class="text-white bg-cyan-600 hover:bg-cyan-700 focus:ring-4 focus:ring-cyan-200 font-medium rounded-lg text-base px-5 py-3 w-full sm:w-auto text-center">
Verify
</button> -->
<BaseButton type="submit" :icon="mdiContentSaveCheck" color="info" label=" Login to your account" :class="{ 'opacity-25': fa2Form.processing }"
v-bind:disabled="fa2Form.processing" />
<BaseButton type="submit" :icon="mdiContentSaveCheck" color="info" label=" Login to your account"
:class="{ 'opacity-25': fa2Form.processing }" v-bind:disabled="fa2Form.processing" />
</BaseButtons>
<!-- <Link :href="stardust.route('app.register.show')"> Register </Link> -->
@ -136,6 +153,15 @@ const user_id: Ref<any> = computed(() => {
const isTwoFactorAuthNeeded = ref(false);
const authMethod = ref('code');
watch(authMethod, (currentValue) => {
if (currentValue == 'code') {
fa2Form.backup_code = undefined;
} else if (currentValue == 'backupCode') {
fa2Form.code = undefined;
}
});
// const user_id: ComputedRef<number> = computed(() => {
// return usePage().props.flash.user_id as number;
// });
@ -230,7 +256,7 @@ const submit = async () => {
remember: form.remember && form.remember.length ? 'on' : '',
}))
.post('/app/login', {
// .post(stardust.route('login.store'), {
// .post(stardust.route('login.store'), {
onFinish: () => {
form.reset('password');
},
@ -240,14 +266,15 @@ const submit = async () => {
const fa2Form: InertiaForm = useForm(() => ({
code: '',
remember: [],
backup_code: '',
// remember: [],
login_id: ''
}));
const submitFa2Form = async () => {
await fa2Form
.transform((data: InertiaForm) => ({
...data,
remember: fa2Form.remember && fa2Form.remember.length ? 'on' : '',
// remember: fa2Form.remember && fa2Form.remember.length ? 'on' : '',
login_id: user_id.value
}))
.post(stardust.route('login.twoFactorChallenge'), {