update PasswordForm and views with validations

This commit is contained in:
Axolotle 2020-10-30 17:23:24 +01:00
parent 1a19f9ef21
commit 6cb9089604
3 changed files with 95 additions and 127 deletions

View file

@ -1,119 +1,84 @@
<template> <template>
<b-card header-tag="h2" class="basic-form"> <card-form
<template v-slot:header> :title="title" icon="key-modern" :submit-text="submitText"
<h2><icon iname="key-modern" /> {{ title }}</h2> :validation="$v" :server-error="serverError"
</template> @submit.prevent="onSubmit"
>
<b-form id="password-form" @submit.prevent="onSubmit"> <template #disclaimer>
<b-alert variant="warning" show> <b-alert variant="warning" show>
{{ $t('good_practices_about_admin_password') }} {{ $t('good_practices_about_admin_password') }}
</b-alert> </b-alert>
<slot name="disclaimer" />
<slot name="message" />
<hr> <hr>
{{ $v.form.currentPassword }}
<slot name="input" />
<!-- PASSWORD -->
<input-helper
id="password" type="password" :label="$t('password_new')"
v-model="form.password" :placeholder="$t('tools_adminpw_new_placeholder')"
:state="isValid.password" :error="error.password"
@input="validateNewPassword"
/>
<!-- PASSWORD CONFIRMATION -->
<input-helper
id="confirmation" type="password" :label="$t('password_confirmation')"
v-model="form.confirmation" :placeholder="$t('tools_adminpw_confirm_placeholder')"
:state="isValid.confirmation" :error="$t('passwords_dont_match')"
@input="validateNewPassword"
/>
</b-form>
<template v-slot:footer>
<b-button
type="submit" form="password-form" variant="success"
:disabled="!everythingValid"
>
{{ submitText ? submitText : $t('save') }}
</b-button>
</template> </template>
</b-card>
<slot name="extra-fields" v-bind="{ v: $v, fields, form }" />
<!-- ADMIN PASSWORD -->
<form-field v-bind="fields.password" v-model="form.password" :validation="$v.form.password" />
<!-- ADMIN PASSWORD CONFIRMATION -->
<form-field v-bind="fields.confirmation" v-model="form.confirmation" :validation="$v.form.confirmation" />
</card-form>
</template> </template>
<script> <script>
import InputHelper from '@/components/InputHelper' import { validationMixin } from 'vuelidate'
import { required, minLength, sameAs } from '@/helpers/validators'
export default { export default {
name: 'PasswordForm', name: 'PasswordForm',
props: { props: {
title: { title: { type: String, required: true },
type: String, submitText: { type: String, default: null },
required: true serverError: { type: String, default: '' },
}, extra: { type: Object, default: () => ({ form: {}, fields: {}, validations: {} }) }
submitText: {
type: String,
default: null
},
isValid: {
type: Object,
default: () => ({
password: null,
confirmation: null
})
},
error: {
type: Object,
default: () => ({
password: '',
confirmation: ''
})
}
}, },
data () { data () {
return { return {
form: { form: {
password: '', password: '',
confirmation: '' confirmation: '',
...this.extra.form
},
fields: {
password: {
label: this.$i18n.t('password'),
props: { id: 'password', type: 'password', placeholder: '••••••••' }
},
confirmation: {
label: this.$i18n.t('password_confirmation'),
props: { id: 'confirmation', type: 'password', placeholder: '••••••••' }
},
...this.extra.fields
} }
} }
}, },
computed: { validations () {
everythingValid () { return {
for (const key in this.isValid) { form: {
if (this.form[key] === '') return false password: { required, passwordLenght: minLength(8) },
if (this.isValid[key] === false) return false confirmation: { required, passwordMatch: sameAs('password') },
...this.extra.validations
} }
return true
} }
}, },
methods: { methods: {
onSubmit () { onSubmit () {
if (this.everythingValid) { this.$emit('submit', this.form)
this.$emit('submit', this.form.password)
} }
}, },
isValidPassword (password) { mixins: [validationMixin]
return password.length >= 8 ? null : false
},
validateNewPassword () {
const { password, confirmation } = this.form
this.error.password = this.$i18n.t('passwords_too_short')
this.isValid.password = this.isValidPassword(password)
this.isValid.confirmation = password === confirmation ? null : false
}
},
components: {
InputHelper
}
} }
</script> </script>

View file

@ -17,7 +17,7 @@
<!-- DOMAIN SETUP STEP --> <!-- DOMAIN SETUP STEP -->
<template v-else-if="step === 'domain'"> <template v-else-if="step === 'domain'">
<domain-form :title="$t('postinstall_set_domain')" :submit-text="$t('next')" @submit.prevent="setDomain"> <domain-form :title="$t('postinstall_set_domain')" :submit-text="$t('next')" @submit="setDomain">
<template #disclaimer> <template #disclaimer>
<b-alert variant="warning" show v-t="'postinstall_domain'" /> <b-alert variant="warning" show v-t="'postinstall_domain'" />
</template> </template>
@ -30,8 +30,8 @@
<!-- PASSWORD SETUP STEP --> <!-- PASSWORD SETUP STEP -->
<template v-else-if="step === 'password'"> <template v-else-if="step === 'password'">
<password-form :title="$t('postinstall_set_password')" :submit-text="$t('next')" @submit.prevent="setPassword"> <password-form :title="$t('postinstall_set_password')" :submit-text="$t('next')" @submit="setPassword">
<template v-slot:message> <template #disclaimer>
<b-alert variant="warning" show v-t="'postinstall_password'" /> <b-alert variant="warning" show v-t="'postinstall_password'" />
</template> </template>
</password-form> </password-form>
@ -82,7 +82,7 @@ export default {
this.step = 'password' this.step = 'password'
}, },
setPassword (password) { setPassword ({ password }) {
this.password = password this.password = password
this.$refs['post-install-modal'].show() this.$refs['post-install-modal'].show()
}, },

View file

@ -1,17 +1,13 @@
<template> <template>
<password-form <password-form
:title="$t('postinstall_set_password')" :submit-text="$t('next')" :title="$t('postinstall_set_password')"
:error="error" :is-valid="isValid" :server-error="serverError"
@submit="onSubmit" @submit="onSubmit"
:extra="extra"
> >
<template v-slot:input> <template #extra-fields="{ v, fields, form }">
<!-- CURRENT ADMIN PASSWORD --> <!-- CURRENT ADMIN PASSWORD -->
<input-helper <form-field v-bind="fields.currentPassword" v-model="form.currentPassword" :validation="v.form.currentPassword" />
id="current-password" type="password" :label="$t('tools_adminpw_current')"
v-model="currentPassword" :placeholder="$t('tools_adminpw_current_placeholder')"
:state="isValid.currentPassword" :error="error.currentPassword"
@input="validateCurrentPassword"
/>
<hr> <hr>
</template> </template>
</password-form> </password-form>
@ -19,53 +15,60 @@
<script> <script>
import api from '@/api' import api from '@/api'
import { validationMixin } from 'vuelidate'
import { PasswordForm } from '@/components/reusableForms' import { PasswordForm } from '@/components/reusableForms'
import InputHelper from '@/components/InputHelper' import { required, minLength } from '@/helpers/validators'
export default { export default {
name: 'ToolAdminpw', name: 'ToolAdminpw',
data () { data () {
return { return {
currentPassword: '', serverError: '',
isValid: {
currentPassword: null, extra: {
password: null, form: {
confirmation: null currentPassword: ''
}, },
error: { fields: {
currentPassword: '', currentPassword: {
password: '', label: this.$i18n.t('tools_adminpw_current'),
confirmation: '' description: this.$i18n.t('tools_adminpw_current_placeholder'),
props: { id: 'current-password', type: 'password', placeholder: '••••••••' }
}
},
validations: {
currentPassword: { required, passwordLenght: minLength(8) }
}
} }
} }
}, },
methods: { methods: {
onSubmit (password) { onSubmit ({ password, currentPassword }) {
if (this.isValid.currentPassword === false) return this.serverError = ''
// Use `api.fetch` to avoid automatic redirect on 401 (Unauthorized).
api.post('login', { password: this.currentPassword }).then(() => { api.fetch('POST', 'login', { password: currentPassword }).then(response => {
if (response.status === 401) {
// Dispatch `SERVER_RESPONDED` to hide waiting overlay and display error.
this.$store.dispatch('SERVER_RESPONDED', true)
this.serverError = this.$i18n.t('wrong_password')
} else if (response.ok) {
api.put('adminpw', { new_password: password }).then(() => { api.put('adminpw', { new_password: password }).then(() => {
this.$store.dispatch('DISCONNECT') this.$store.dispatch('DISCONNECT')
}).catch(err => { }).catch(error => {
this.error.password = err.message this.serverError = error.message
this.isValid.password = false
}) })
}).catch(() => { }
this.error.currentPassword = this.$i18n.t('wrong_password')
this.isValid.currentPassword = false
}) })
},
validateCurrentPassword () {
this.error.currentPassword = this.$i18n.t('passwords_too_short')
this.isValid.currentPassword = this.currentPassword.length >= 8 ? null : false
} }
}, },
mixins: [validationMixin],
components: { components: {
InputHelper,
PasswordForm PasswordForm
} }
} }