Minimum password length + Static Pages fixes (#11474)

* password min length: server + client side registering

* tweak text, add tests

* misc

* use red border for invalid inputs

* fix auth form for groups

* remove default firefox box shadown on invalid elements

* fix css in authForm

* fix margings

* misc fixes to forms and buttons

* fix typo
This commit is contained in:
Matteo Pagliazzi
2019-10-30 13:47:35 +01:00
committed by GitHub
parent 1cf3ba26b7
commit e1d30eec98
13 changed files with 242 additions and 80 deletions
@@ -46,6 +46,13 @@
:placeholder="$t('usernamePlaceholder')"
:class="{'input-valid': usernameValid, 'input-invalid': usernameInvalid}"
>
<div
v-for="issue in usernameIssues"
:key="issue"
class="input-error"
>
{{ issue }}
</div>
</div>
<div
v-if="!registering"
@@ -97,7 +104,17 @@
class="form-control"
type="password"
:placeholder="$t(registering ? 'passwordPlaceholder' : 'password')"
:class="{
'input-valid': registering ? passwordValid : false,
'input-invalid': registering ? passwordInvalid: false,
}"
>
<div
v-if="passwordInvalid && registering"
class="input-error"
>
{{ $t('minPasswordLength') }}
</div>
</div>
<div
v-if="registering"
@@ -115,6 +132,12 @@
:placeholder="$t('confirmPasswordPlaceholder')"
:class="{'input-invalid': passwordConfirmInvalid, 'input-valid': passwordConfirmValid}"
>
<div
v-if="passwordConfirmInvalid"
class="input-error"
>
{{ $t('passwordConfirmationMatch') }}
</div>
<small
v-once
class="form-text"
@@ -183,8 +206,11 @@
text-align: center;
}
.input-valid {
color: #fff;
.input-error {
margin-top: 0.25em;
font-weight: normal;
font-size: 90%;
width: 100%;
}
}
</style>
@@ -194,7 +220,7 @@ import hello from 'hellojs';
import debounce from 'lodash/debounce';
import isEmail from 'validator/lib/isEmail';
import { setUpAxios } from '@/libs/auth';
import { MINIMUM_PASSWORD_LENGTH } from '@/../../common/script/constants';
import facebookSquareIcon from '@/assets/svg/facebook-square.svg';
import googleIcon from '@/assets/svg/google.svg';
@@ -223,6 +249,7 @@ export default {
return isEmail(this.email);
},
emailInvalid () {
if (this.email.length <= 3) return false;
return !this.emailValid;
},
usernameValid () {
@@ -230,13 +257,23 @@ export default {
return this.usernameIssues.length === 0;
},
usernameInvalid () {
if (this.username.length < 1) return false;
return !this.usernameValid;
},
passwordValid () {
if (this.password.length <= 0) return false;
return this.password.length >= MINIMUM_PASSWORD_LENGTH;
},
passwordInvalid () {
if (this.password.length <= 0) return false;
return this.password.length < MINIMUM_PASSWORD_LENGTH;
},
passwordConfirmValid () {
if (this.passwordConfirm.length <= 3) return false;
return this.passwordConfirm === this.password;
},
passwordConfirmInvalid () {
if (this.passwordConfirm.length <= 3) return false;
return !this.passwordConfirmValid;
},
},
@@ -6,8 +6,7 @@
<form
v-if="!forgotPassword && !resetPasswordSetNewOne"
id="login-form"
@submit.prevent="handleSubmit"
@keyup.enter="handleSubmit"
@submit.prevent.stop="handleSubmit"
>
<div class="text-center">
<div>
@@ -69,7 +68,7 @@
<input
id="usernameInput"
v-model="username"
class="form-control"
class="form-control input-with-error"
type="text"
:placeholder="$t('usernamePlaceholder')"
:class="{'input-valid': usernameValid, 'input-invalid': usernameInvalid}"
@@ -132,7 +131,17 @@
class="form-control"
type="password"
:placeholder="$t(registering ? 'passwordPlaceholder' : 'password')"
:class="{
'input-invalid input-with-error': registering && passwordInvalid,
'input-valid': registering && passwordValid
}"
>
<div
v-if="passwordInvalid && registering"
class="input-error"
>
{{ $t('minPasswordLength') }}
</div>
</div>
<div
v-if="registering"
@@ -145,11 +154,17 @@
<input
id="confirmPasswordInput"
v-model="passwordConfirm"
class="form-control"
class="form-control input-with-error"
type="password"
:placeholder="$t('confirmPasswordPlaceholder')"
:class="{'input-invalid': passwordConfirmInvalid, 'input-valid': passwordConfirmValid}"
>
<div
v-if="passwordConfirmInvalid"
class="input-error"
>
{{ $t('passwordConfirmationMatch') }}
</div>
<small
v-once
class="form-text"
@@ -157,22 +172,22 @@
></small>
</div>
<div class="text-center">
<div
<button
v-if="registering"
v-once
type="submit"
class="btn btn-info"
@click="register()"
:disabled="signupFormInvalid"
>
{{ $t('joinHabitica') }}
</div>
<div
</button>
<button
v-if="!registering"
v-once
type="submit"
class="btn btn-info"
@click="login()"
>
{{ $t('login') }}
</div>
</button>
<div class="toggle-links">
<router-link
v-if="registering"
@@ -426,10 +441,14 @@
color: $white;
}
#usernameInput.input-invalid {
.input-with-error.input-invalid {
margin-bottom: 0.5em;
}
#confirmPasswordInput + .input-error {
margin-bottom: 2em;
}
.form-text {
font-size: 14px;
color: $white;
@@ -480,7 +499,7 @@
background-image: url('~@/assets/images/auth/seamless_mountains_demo.png');
background-repeat: repeat-x;
width: 100%;
height: 500px;
height: 300px;
position: absolute;
z-index: 0;
bottom: 0;
@@ -512,7 +531,6 @@
color: #fff;
font-size: 90%;
width: 100%;
text-align: center;
}
</style>
@@ -522,6 +540,7 @@ import hello from 'hellojs';
import debounce from 'lodash/debounce';
import isEmail from 'validator/lib/isEmail';
import { MINIMUM_PASSWORD_LENGTH } from '@/../../common/script/constants';
import gryphon from '@/assets/svg/gryphon.svg';
import habiticaIcon from '@/assets/svg/habitica-logo.svg';
import facebookSquareIcon from '@/assets/svg/facebook-square.svg';
@@ -580,6 +599,14 @@ export default {
if (this.username.length < 1) return false;
return !this.usernameValid;
},
passwordValid () {
if (this.password.length <= 0) return false;
return this.password.length >= MINIMUM_PASSWORD_LENGTH;
},
passwordInvalid () {
if (this.password.length <= 0) return false;
return this.password.length < MINIMUM_PASSWORD_LENGTH;
},
passwordConfirmValid () {
if (this.passwordConfirm.length <= 3) return false;
return this.passwordConfirm === this.password;
@@ -588,6 +615,12 @@ export default {
if (this.passwordConfirm.length <= 3) return false;
return !this.passwordConfirmValid;
},
signupFormInvalid () {
return this.usernameInvalid
|| this.emailInvalid
|| this.passwordInvalid
|| this.passwordConfirmInvalid;
},
},
watch: {
$route: {