mirror of
https://github.com/Bubka/2FAuth.git
synced 2024-11-26 10:15:40 +01:00
Add rules and live validation to Password Field component
This commit is contained in:
parent
f2c90fb924
commit
acdaa73e62
@ -1,25 +1,30 @@
|
||||
<template>
|
||||
<div class="field" :class="{ 'pt-3' : hasOffset }">
|
||||
<label :for="this.inputId(inputType,fieldName)" class="label" v-html="label"></label>
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
<input :disabled="isDisabled" :id="this.inputId(inputType,fieldName)" :type="inputType" class="input" v-model="form[fieldName]" :placeholder="placeholder" v-bind="$attrs" v-on:change="$emit('field-changed', form[fieldName])"/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a v-if="!showPassword" class="button is-dark field-lock" @click="showPassword = true" :title="$t('auth.forms.reveal_password')">
|
||||
<span class="icon">
|
||||
<font-awesome-icon :icon="['fas', 'eye-slash']" />
|
||||
</span>
|
||||
</a>
|
||||
<a v-else class="button is-dark field-lock" @click="showPassword = false" :title="$t('auth.forms.hide_password')">
|
||||
<span class="icon">
|
||||
<font-awesome-icon :icon="['fas', 'eye']" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<label :for="this.inputId('password',fieldName)" class="label" v-html="label"></label>
|
||||
<div class="control has-icons-right">
|
||||
<input :disabled="isDisabled" :id="this.inputId('password',fieldName)" :type="currentType" class="input" v-model="form[fieldName]" :placeholder="placeholder" v-bind="$attrs" v-on:change="$emit('field-changed', form[fieldName])"/>
|
||||
<span v-if="currentType == 'password'" class="icon is-small is-right is-clickable" @click="currentType = 'text'" :title="$t('auth.forms.reveal_password')">
|
||||
<font-awesome-icon :icon="['fas', 'eye-slash']" />
|
||||
</span>
|
||||
<span v-else class="icon is-small is-right is-clickable" @click="currentType = 'password'" :title="$t('auth.forms.hide_password')">
|
||||
<font-awesome-icon :icon="['fas', 'eye']" />
|
||||
</span>
|
||||
</div>
|
||||
<field-error :form="form" :field="fieldName" />
|
||||
<p class="help" v-html="help" v-if="help"></p>
|
||||
<div v-if="showRules" class="columns is-mobile is-size-7 mt-0">
|
||||
<div class="column is-one-third">
|
||||
<span class="has-text-weight-semibold">{{ $t("auth.forms.mandatory_rules") }}</span><br />
|
||||
<span class="is-underscored" :class="{'has-background-success-dark is-dot' : IsLongEnough}"></span>{{ $t('auth.forms.is_long_enough') }}<br/>
|
||||
</div>
|
||||
<div class="column">
|
||||
<span class="has-text-weight-semibold">{{ $t("auth.forms.optional_rules_you_should_follow") }}</span><br />
|
||||
<span class="is-underscored" :class="{'has-background-success-dark is-dot' : hasLowerCase}"></span>{{ $t('auth.forms.has_lower_case') }}<br/>
|
||||
<span class="is-underscored" :class="{'has-background-success-dark is-dot' : hasUpperCase}"></span>{{ $t('auth.forms.has_upper_case') }}<br/>
|
||||
<span class="is-underscored" :class="{'has-background-success-dark is-dot' : hasSpecialChar}"></span>{{ $t('auth.forms.has_special_char') }}<br/>
|
||||
<span class="is-underscored" :class="{'has-background-success-dark is-dot' : hasNumber}"></span>{{ $t('auth.forms.has_number') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -30,9 +35,28 @@
|
||||
|
||||
data() {
|
||||
return {
|
||||
currentType: this.inputType
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
hasLowerCase() {
|
||||
return /[a-z]/.test(this.form[this.fieldName])
|
||||
},
|
||||
hasUpperCase() {
|
||||
return /[A-Z]/.test(this.form[this.fieldName])
|
||||
},
|
||||
hasNumber() {
|
||||
return /[0-9]/.test(this.form[this.fieldName])
|
||||
},
|
||||
hasSpecialChar() {
|
||||
return /[^A-Za-z0-9]/.test(this.form[this.fieldName])
|
||||
},
|
||||
IsLongEnough() {
|
||||
return this.form[this.fieldName].length >= 8
|
||||
},
|
||||
},
|
||||
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
@ -47,7 +71,7 @@
|
||||
|
||||
inputType: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
default: 'password'
|
||||
},
|
||||
|
||||
form: {
|
||||
@ -73,7 +97,12 @@
|
||||
isDisabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
showRules: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
@ -19,7 +19,7 @@
|
||||
<div v-if="isTesting" class="notification is-warning has-text-centered is-radiusless" v-html="$t('auth.forms.welcome_to_testing_app_use_those_credentials')" />
|
||||
<form id="frmLegacyLogin" @submit.prevent="handleSubmit" @keydown="form.onKeydown($event)">
|
||||
<form-field :form="form" fieldName="email" inputType="email" :label="$t('auth.forms.email')" autofocus />
|
||||
<form-field :form="form" fieldName="password" inputType="password" :label="$t('auth.forms.password')" />
|
||||
<form-password-field :form="form" fieldName="password" :label="$t('auth.forms.password')" />
|
||||
<form-buttons :isBusy="form.isBusy" :caption="$t('auth.sign_in')" :submitId="'btnSignIn'"/>
|
||||
</form>
|
||||
<div class="nav-links">
|
||||
|
@ -25,8 +25,8 @@
|
||||
<form @submit.prevent="handleRegisterSubmit" @keydown="registerForm.onKeydown($event)">
|
||||
<form-field :form="registerForm" fieldName="name" inputType="text" :label="$t('auth.forms.name')" autofocus />
|
||||
<form-field :form="registerForm" fieldName="email" inputType="email" :label="$t('auth.forms.email')" />
|
||||
<form-field :form="registerForm" fieldName="password" inputType="password" :label="$t('auth.forms.password')" />
|
||||
<form-field :form="registerForm" fieldName="password_confirmation" inputType="password" :label="$t('auth.forms.confirm_password')" />
|
||||
<form-password-field :form="registerForm" fieldName="password" :showRules="true" :label="$t('auth.forms.password')" />
|
||||
<!-- <form-field :form="registerForm" fieldName="password_confirmation" inputType="password" :label="$t('auth.forms.confirm_password')" /> -->
|
||||
<form-buttons :isBusy="registerForm.isBusy" :isDisabled="registerForm.isDisabled" :caption="$t('auth.register')" :submitId="'btnRegister'" />
|
||||
</form>
|
||||
<div class="nav-links">
|
||||
@ -66,6 +66,7 @@
|
||||
*/
|
||||
async handleRegisterSubmit(e) {
|
||||
e.preventDefault()
|
||||
this.registerForm.password_confirmation = this.registerForm.password
|
||||
|
||||
this.registerForm.post('/user', {returnError: true})
|
||||
.then(response => {
|
||||
|
@ -16,7 +16,7 @@
|
||||
<form @submit.prevent="submitPassword" @keydown="formPassword.onKeydown($event)">
|
||||
<h4 class="title is-4 pt-6 has-text-grey-light">{{ $t('settings.change_password') }}</h4>
|
||||
<fieldset :disabled="isRemoteUser">
|
||||
<form-field :form="formPassword" fieldName="password" inputType="password" :label="$t('auth.forms.new_password')" />
|
||||
<form-password-field :form="formPassword" fieldName="password" :showRules="true" :label="$t('auth.forms.new_password')" />
|
||||
<form-field :form="formPassword" fieldName="password_confirmation" inputType="password" :label="$t('auth.forms.confirm_new_password')" />
|
||||
<form-field :form="formPassword" fieldName="currentPassword" inputType="password" :label="$t('auth.forms.current_password.label')" :help="$t('auth.forms.current_password.help')" />
|
||||
<form-buttons :isBusy="formPassword.isBusy" :caption="$t('auth.forms.change_password')" />
|
||||
|
@ -102,13 +102,20 @@
|
||||
'profile_saved' => 'Profile successfully updated!',
|
||||
'welcome_to_demo_app_use_those_credentials' => 'Welcome to the 2FAuth demo.<br><br>You can connect using the email address <strong>demo@2fauth.app</strong> and the password <strong>demo</strong>',
|
||||
'welcome_to_testing_app_use_those_credentials' => 'Welcome to the 2FAuth testing instance.<br><br>Use email address <strong>testing@2fauth.app</strong> and password <strong>password</strong>',
|
||||
'register_punchline' => 'Welcome to 2FAuth.<br/>You need an account to go further. Fill this form to register yourself, and please, choose a strong password, 2FA data are sensitives.',
|
||||
'register_punchline' => 'Welcome to <b>2FAuth</b>.<br/>You need an account to go further, please register yourself.',
|
||||
'reset_punchline' => '2FAuth will send you a password reset link to this address. Click the link in the received email to set a new password.',
|
||||
'name_this_device' => 'Name this device',
|
||||
'delete_account' => 'Delete account',
|
||||
'delete_your_account' => 'Delete your account',
|
||||
'delete_your_account_and_reset_all_data' => 'This will reset 2FAuth. Your user account will be deleted as well as all 2FA data. There is no going back.',
|
||||
'user_account_successfully_deleted' => 'User account successfully deleted',
|
||||
'has_lower_case' => 'Has lower case',
|
||||
'has_upper_case' => 'Has upper case',
|
||||
'has_special_char' => 'Has special char',
|
||||
'has_number' => 'Has number',
|
||||
'is_long_enough' => '8 characters min.',
|
||||
'mandatory_rules' => 'Mandatory rules',
|
||||
'optional_rules_you_should_follow' => 'Optional rules (highly recommanded)',
|
||||
],
|
||||
|
||||
];
|
||||
|
13
resources/sass/app.scss
vendored
13
resources/sass/app.scss
vendored
@ -386,6 +386,19 @@ figure.no-icon {
|
||||
color: hsl(0, 0%, 48%);
|
||||
}
|
||||
|
||||
.is-underscored {
|
||||
border-bottom: 1px solid hsl(0, 0%, 29%);
|
||||
height: 0.6rem;
|
||||
width: 0.6rem;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.is-underscored.is-dot {
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.is-toggle.buttons,
|
||||
.is-toggle.buttons a.button {
|
||||
margin-bottom: 0 !important;
|
||||
|
Loading…
Reference in New Issue
Block a user