Skip to content

Commit 757e964

Browse files
authored
feat: implement more comprehensive password validation rules and hints (#90)
Signed-off-by: romanetar <roman_ag@hotmail.com>
1 parent 52dd1b5 commit 757e964

11 files changed

Lines changed: 51 additions & 14 deletions

File tree

Dockerfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ RUN apt-get update && apt-get install -y \
3333

3434
RUN apt clean && rm -rf /var/lib/apt/lists/*
3535

36-
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath sockets gettext apcu
36+
RUN pecl install apcu \
37+
&& docker-php-ext-enable apcu \
38+
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath sockets gettext \
39+
&& pecl clear-cache
40+
3741
# XDEBUG
3842
RUN yes | pecl install ${XDEBUG_VERSION}
3943
COPY docker-compose/php/docker-php-ext-xdebug.ini $PHP_DIR/conf.d/docker-php-ext-xdebug.ini

config/auth.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,9 @@
102102
'password_reset_lifetime' => env('AUTH_PASSWORD_RESET_LIFETIME', 1800),
103103
'password_min_length' => env('AUTH_PASSWORD_MIN_LENGTH', 8),
104104
'password_max_length' => env('AUTH_PASSWORD_MAX_LENGTH', 30),
105-
'password_shape_pattern' => env('AUTH_PASSWORD_SHAPE_PATTERN', '^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-])'),
106-
'password_shape_warning' => env('AUTH_PASSWORD_SHAPE_WARNING', 'Password must include at least one uppercase letter, one lowercase letter, one number, and one special character.'),
105+
'password_allowed_special_characters' => env('AUTH_PASSWORD_ALLOWED_SPECIAL_CHARACTERS', '[A-Za-z0-9#?!@$%^&*-+]'),
106+
'password_shape_pattern' => env('AUTH_PASSWORD_SHAPE_PATTERN', '^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-+])[A-Za-z0-9#?!@$%^&*-+]+$'),
107+
'password_shape_warning' => env('AUTH_PASSWORD_SHAPE_WARNING', 'Password must include at least one uppercase letter, one lowercase letter, one number, and one special character (#?!@$%^&*-+).'),
107108
'verification_email_lifetime' => env("AUTH_VERIFICATION_EMAIL_LIFETIME", 600),
108109
'allows_native_auth' => env('AUTH_ALLOWS_NATIVE_AUTH', 1),
109110
'allows_native_on_config' => env('AUTH_ALLOWS_NATIVE_AUTH_CONFIG', 1),

resources/js/reset_password/reset_password.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ const ResetPasswordPage = ({
167167
<InfoOutlinedIcon fontSize="small"/>
168168
&nbsp;
169169
<Typography variant="body2">
170-
{`The Password must be ${passwordPolicy.min_length}${passwordPolicy.max_length} characters, and ${passwordPolicy.shape_warning}`}
170+
<div dangerouslySetInnerHTML={{ __html: `The Password must be ${passwordPolicy.min_length}${passwordPolicy.max_length} characters, and ${passwordPolicy.shape_warning}` }} />
171171
</Typography>
172172
</Grid>
173173
<Grid item container alignItems="center" justifyContent="center">

resources/js/set_password/set_password.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ const SetPasswordPage = ({
276276
<InfoOutlinedIcon fontSize="small" />
277277
&nbsp;
278278
<Typography variant="body2">
279-
{`The Password must be ${passwordPolicy.min_length}${passwordPolicy.max_length} characters, and ${passwordPolicy.shape_warning}`}
279+
<div dangerouslySetInnerHTML={{ __html: `The Password must be ${passwordPolicy.min_length}${passwordPolicy.max_length} characters, and ${passwordPolicy.shape_warning}` }} />
280280
</Typography>
281281
</Grid>
282282
<Grid item container alignItems="center" justifyContent="center">

resources/js/signup/signup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ const SignUpPage = ({
270270
<InfoOutlinedIcon fontSize="small" />
271271
&nbsp;
272272
<Typography variant="body2">
273-
{`The Password must be ${passwordPolicy.min_length}${passwordPolicy.max_length} characters, and ${passwordPolicy.shape_warning}`}
273+
<div dangerouslySetInnerHTML={{ __html: `The Password must be ${passwordPolicy.min_length}${passwordPolicy.max_length} characters, and ${passwordPolicy.shape_warning}` }} />
274274
</Typography>
275275
</Grid>
276276
<Grid item container alignItems="center" justifyContent="center">

resources/js/validator.js

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
import {ref, string} from "yup";
22

3+
const validatePasswordPattern = (shapePattern, allowed_special_characters, warning) => {
4+
return function(value) {
5+
if (!value) return true;
6+
7+
const pattern = new RegExp(shapePattern);
8+
9+
if (pattern.test(value)) {
10+
return true;
11+
}
12+
13+
// Check invalid characters
14+
const allowedCharsRegEx = new RegExp(allowed_special_characters);
15+
16+
for (let i = 0; i < value.length; i++) {
17+
const char = value[i];
18+
if (!allowedCharsRegEx.test(char)) {
19+
return this.createError({
20+
message: `Invalid character "${char}" at position ${i + 1}`,
21+
path: this.path,
22+
});
23+
}
24+
}
25+
26+
// Check remain requirements
27+
return this.createError({
28+
message: warning,
29+
path: this.path,
30+
});
31+
}
32+
}
33+
334
export const emailValidator = (value) => {
435
return /^\S+@\S+(\.\S+)*$/.test(value)
536
}
@@ -14,17 +45,13 @@ export const buildPasswordValidationSchema = (passwordPolicy, required = false)
1445
})
1546
.min(passwordPolicy.min_length, `Password must be at least ${passwordPolicy.min_length} characters`)
1647
.max(passwordPolicy.max_length, `Password must be at most ${passwordPolicy.max_length} characters`)
17-
.matches(
18-
new RegExp(passwordPolicy.shape_pattern),
19-
passwordPolicy.shape_warning
20-
),
48+
.test('password-requirements', validatePasswordPattern(
49+
passwordPolicy.shape_pattern, passwordPolicy.allowed_special_characters, passwordPolicy.shape_warning)),
2150
password_confirmation: string()
2251
.min(passwordPolicy.min_length, `Password confirmation must be at least ${passwordPolicy.min_length} characters`)
2352
.max(passwordPolicy.max_length, `Password confirmation must be at most ${passwordPolicy.max_length} characters`)
24-
.matches(
25-
new RegExp(passwordPolicy.shape_pattern),
26-
passwordPolicy.shape_warning
27-
)
53+
.test('password-requirements', validatePasswordPattern(
54+
passwordPolicy.shape_pattern, passwordPolicy.allowed_special_characters, passwordPolicy.shape_warning))
2855
.oneOf([ref('password'), null], 'Passwords must match')
2956
};
3057
return res;

resources/views/admin/edit-user.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
min_length: {{ Config::get("auth.password_min_length") }},
6464
max_length: {{ Config::get("auth.password_max_length") }},
6565
shape_pattern: '{{ Config::get("auth.password_shape_pattern") }}',
66+
allowed_special_characters: '{{ Config::get("auth.password_allowed_special_characters") }}',
6667
shape_warning: '{{ Config::get("auth.password_shape_warning") }}'
6768
}
6869

resources/views/auth/passwords/reset.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
min_length: {{ Config::get("auth.password_min_length") }},
2424
max_length: {{ Config::get("auth.password_max_length") }},
2525
shape_pattern: '{{ Config::get("auth.password_shape_pattern") }}',
26+
allowed_special_characters: '{{ Config::get("auth.password_allowed_special_characters") }}',
2627
shape_warning: '{{ Config::get("auth.password_shape_warning") }}'
2728
}
2829
@if ($errors->any())

resources/views/auth/passwords/set.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
min_length: {{ Config::get("auth.password_min_length") }},
2828
max_length: {{ Config::get("auth.password_max_length") }},
2929
shape_pattern: '{{ Config::get("auth.password_shape_pattern") }}',
30+
allowed_special_characters: '{{ Config::get("auth.password_allowed_special_characters") }}',
3031
shape_warning: '{{ Config::get("auth.password_shape_warning") }}'
3132
}
3233
@if ($errors->any())

resources/views/auth/register.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
min_length: {{ Config::get("auth.password_min_length") }},
2828
max_length: {{ Config::get("auth.password_max_length") }},
2929
shape_pattern: '{{ Config::get("auth.password_shape_pattern") }}',
30+
allowed_special_characters: '{{ Config::get("auth.password_allowed_special_characters") }}',
3031
shape_warning: '{{ Config::get("auth.password_shape_warning") }}'
3132
}
3233
@if ($errors->any())

0 commit comments

Comments
 (0)