diff --git a/config/auth.php b/config/auth.php index ca6f2558..5da1b184 100644 --- a/config/auth.php +++ b/config/auth.php @@ -102,9 +102,9 @@ 'password_reset_lifetime' => env('AUTH_PASSWORD_RESET_LIFETIME', 1800), 'password_min_length' => env('AUTH_PASSWORD_MIN_LENGTH', 8), 'password_max_length' => env('AUTH_PASSWORD_MAX_LENGTH', 30), - 'password_allowed_special_characters' => env('AUTH_PASSWORD_ALLOWED_SPECIAL_CHARACTERS', '[A-Za-z0-9#?!@$%^&*-+]'), - 'password_shape_pattern' => env('AUTH_PASSWORD_SHAPE_PATTERN', '^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-+])[A-Za-z0-9#?!@$%^&*-+]+$'), - '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 (#?!@$%^&*-+).'), + 'password_allowed_special_characters' => env('AUTH_PASSWORD_ALLOWED_SPECIAL_CHARACTERS', '[A-Za-z0-9#?!@$%^&*+-]'), + 'password_shape_pattern' => env('AUTH_PASSWORD_SHAPE_PATTERN', '^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*+\-])[A-Za-z0-9#?!@$%^&*+\-]+$'), + '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 (#?!@$%^&*+-).'), 'verification_email_lifetime' => env("AUTH_VERIFICATION_EMAIL_LIFETIME", 600), 'allows_native_auth' => env('AUTH_ALLOWS_NATIVE_AUTH', 1), 'allows_native_on_config' => env('AUTH_ALLOWS_NATIVE_AUTH_CONFIG', 1), diff --git a/tests/UserPasswordShapeRegressionTest.php b/tests/UserPasswordShapeRegressionTest.php new file mode 100644 index 00000000..35e39e12 --- /dev/null +++ b/tests/UserPasswordShapeRegressionTest.php @@ -0,0 +1,85 @@ +setPasswordPolicyForTest(); + + // Prevent actually queueing anything (setPassword dispatches AddUserAction) + Queue::fake(); + + $user = new User(); + $user->setEmail('test@example.org'); + + $user->setPassword($plainPassword); + + $this->assertTrue($user->hasPasswordSet()); + $this->assertNotEmpty($user->getPassword()); + + } + + public function test_password_missing_special_character_is_rejected(): void + { + $this->setPasswordPolicyForTest(); + Queue::fake(); + + $user = new User(); + $user->setEmail('test@example.org'); + + $this->expectException(ValidationException::class); + $user->setPassword('Abcdef12'); // no special char + } + + public function test_password_with_hyphen_matches_current_regex(): void + { + $this->setPasswordPolicyForTest(); + + $pattern = Config::get('auth.password_shape_pattern'); + $this->assertSame(1, preg_match("/$pattern/", 'Abcdef1-')); + } +}