Skip to content

Commit 8e3299e

Browse files
committed
fix(auth): accessibility and safety improvements to password reset page
- Add aria-label to password visibility toggle reflecting show/hide state - Add sr-only aria-live region for confirm field match status - Replace dangerouslySetInnerHTML with plain React child for special characters text; use Js::from() in blade template to safely serialize the value without HTML entity encoding - Update password_min_length default from 8 to 10 to match policy
1 parent ba52678 commit 8e3299e

4 files changed

Lines changed: 24 additions & 3 deletions

File tree

config/auth.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100

101101
// in seconds
102102
'password_reset_lifetime' => env('AUTH_PASSWORD_RESET_LIFETIME', 1800),
103-
'password_min_length' => env('AUTH_PASSWORD_MIN_LENGTH', 8),
103+
'password_min_length' => env('AUTH_PASSWORD_MIN_LENGTH', 10),
104104
'password_max_length' => env('AUTH_PASSWORD_MAX_LENGTH', 30),
105105
'password_allowed_special_characters' => env('AUTH_PASSWORD_ALLOWED_SPECIAL_CHARACTERS', '[A-Za-z0-9#?!@$%^&*+-]'),
106106
'password_allowed_special_characters_text' => env('AUTH_PASSWORD_ALLOWED_SPECIAL_CHARACTERS_TEXT', '#?!@$%^&*+-'),

resources/js/reset_password/reset_password.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ const ResetPasswordPage = ({
152152
onClick={() => setShowPassword(!showPassword)}
153153
edge="end"
154154
size="small"
155+
aria-label={showPassword ? "Hide password" : "Show password"}
155156
>
156157
{showPassword ? <VisibilityOff /> : <Visibility />}
157158
</IconButton>
@@ -195,6 +196,14 @@ const ResetPasswordPage = ({
195196
? <CheckCircle style={{ color: '#2e7d32' }} />
196197
: <Cancel style={{ color: '#c62828', opacity: 0.6 }} />
197198
}
199+
<span className={styles.sr_only} aria-live="polite">
200+
{!formik.values.password_confirmation
201+
? ""
202+
: formik.values.password_confirmation === formik.values.password && formik.values.password
203+
? "Passwords match"
204+
: "Passwords do not match"
205+
}
206+
</span>
198207
</InputAdornment>
199208
)
200209
}}
@@ -208,7 +217,7 @@ const ResetPasswordPage = ({
208217
<li key={index}>{item}</li>
209218
))}
210219
</ul>
211-
<p className={styles.password_characters}>Allowed: <span dangerouslySetInnerHTML={{ __html: passwordPolicy.allowed_special_characters_text}} /></p>
220+
<p className={styles.password_characters}>Allowed: <span>{passwordPolicy.allowed_special_characters_text}</span></p>
212221
</Grid>
213222
<Grid item container alignItems="center" justifyContent="center">
214223
<Grid container item justify='center'>

resources/js/reset_password/reset_password.module.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@
8080

8181
}
8282

83+
.sr_only {
84+
position: absolute;
85+
width: 1px;
86+
height: 1px;
87+
padding: 0;
88+
margin: -1px;
89+
overflow: hidden;
90+
clip: rect(0, 0, 0, 0);
91+
white-space: nowrap;
92+
border: 0;
93+
}
94+
8395
.help_link {
8496
margin: 1.5rem 0 0;
8597
text-align: center;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
max_length: {{ Config::get("auth.password_max_length") }},
2525
shape_pattern: '{{ Config::get("auth.password_shape_pattern") }}',
2626
allowed_special_characters: '{{ Config::get("auth.password_allowed_special_characters") }}',
27-
allowed_special_characters_text: '{{ Config::get("auth.password_allowed_special_characters_text") }}',
27+
allowed_special_characters_text: {{ Illuminate\Support\Js::from(Config::get("auth.password_allowed_special_characters_text")) }},
2828
shape_warning: '{{ Config::get("auth.password_shape_warning") }}',
2929
shape_list: '{{ Config::get("auth.password_shape_list") }}'
3030
}

0 commit comments

Comments
 (0)