Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimum password length + Static Pages fixes #11474

Merged
merged 11 commits into from
Oct 30, 2019
18 changes: 18 additions & 0 deletions test/api/v3/integration/user/auth/POST-register_local.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,24 @@ describe('POST /user/auth/local/register', () => {
});
});

it('requires minimum length for the password', async () => {
const username = generateRandomUserName();
const email = `${username}@example.com`;
const password = '1234567';
const confirmPassword = '1234567';

await expect(api.post('/user/auth/local/register', {
username,
email,
password,
confirmPassword,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});

it('requires a username', async () => {
const email = `${generateRandomUserName()}@example.com`;
const password = 'password';
Expand Down
14 changes: 14 additions & 0 deletions test/api/v3/integration/user/auth/PUT-user_update_password.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ describe('PUT /user/auth/update-password', async () => {
});
});

it('returns an error when newPassword is too short', async () => {
const body = {
password,
newPassword: '1234567',
confirmPassword: '1234567',
};

await expect(user.put(ENDPOINT, body)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});

it('returns an error when confirmPassword is missing', async () => {
const body = {
password,
Expand Down
22 changes: 15 additions & 7 deletions website/client/src/assets/scss/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
@include btn-focus-hover-shadow();
}

&:hover:not(.btn-flat):not(.disabled) {
&:hover:not(.btn-flat):not(.disabled):not(:disabled) {
@include btn-focus-hover-shadow();
border-color: transparent;
}
Expand Down Expand Up @@ -49,7 +49,7 @@
background: $purple-200;
}

&:hover:not(:disabled), &:active, &.active, &:focus {
&:hover:not(:disabled):not(.disabled), &:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled), &:focus:not(:disabled):not(.disabled) {
background: #5d3b9c !important;
color: $white;
}
Expand All @@ -59,7 +59,7 @@
color: $gray-50;
background: $white !important;

&:hover:not(:disabled):not(.disabled), &:active, &.active, &:focus {
&:hover:not(:disabled):not(.disabled), &:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled), &:focus:not(:disabled):not(.disabled) {
color: $purple-200 !important;
}

Expand All @@ -80,7 +80,7 @@
background: $green-100;
}

&:hover:not(:disabled), &:active, &.active {
&:hover:not(:disabled):not(.disabled), &:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled) {
background: $green-50;
}
}
Expand All @@ -96,8 +96,12 @@
background: $blue-50;
}

&:hover:not(:disabled), &:active, &.active {
background: $blue-100;
&:hover:not(:disabled):not(.disabled) {
background-color: $blue-100;
}

&:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled) {
background: $blue-50;
}
}

Expand All @@ -108,7 +112,11 @@
background: $red-50;
}

&:hover:not(:disabled), &:active, &.active {
&:hover:not(:disabled):not(.disabled) {
background: $red-100;
}

&:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled) {
background: $red-100;
}
}
Expand Down
17 changes: 17 additions & 0 deletions website/client/src/assets/scss/form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ input, textarea, input.form-control, textarea.form-control {
padding-right: 40px;
background-image: url(~@/assets/svg/for-css/alert.svg);
background-size: 16px 16px;
border-color: $red-100 !important;
}
}

Expand Down Expand Up @@ -276,3 +277,19 @@ $bg-disabled-control: #34303a;
.toggle-switch-container.no-margin {
margin-top: 0 !important;
}



// Disable default style Firefox for invalid elements.
// Selectors taken from view-source:resource://gre-resources/forms.css on Firefox
:not(output):-moz-ui-invalid {
box-shadow: none;
}

:not(output):-moz-ui-invalid:-moz-focusring {
box-shadow: none;
}

output:-moz-ui-invalid {
color: inherit;
}
43 changes: 40 additions & 3 deletions website/client/src/components/auth/authForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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>
Expand All @@ -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';

Expand Down Expand Up @@ -223,20 +249,31 @@ export default {
return isEmail(this.email);
},
emailInvalid () {
if (this.email.length <= 3) return false;
return !this.emailValid;
},
usernameValid () {
if (this.username.length < 1) return false;
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;
},
},
Expand Down
61 changes: 47 additions & 14 deletions website/client/src/components/auth/registerLoginReset.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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}"
Expand Down Expand Up @@ -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"
Expand All @@ -145,34 +154,40 @@
<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"
v-html="$t('termsAndAgreement')"
></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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -512,7 +531,6 @@
color: #fff;
font-size: 90%;
width: 100%;
text-align: center;
}
</style>

Expand All @@ -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';
Expand Down Expand Up @@ -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;
Expand All @@ -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: {
Expand Down
Loading