rollerworks/password-strength-bundle
Symfony bundle integrating Rollerworks PasswordStrengthValidator. Adds configurable password strength constraints to Symfony’s Validator component, providing functionality comparable to the original PasswordStrengthBundle. Requires PHP 8.4+ and Symfony 7.4+.
Installation:
composer require rollerworks/password-strength-bundle
Symfony Flex auto-enables the bundle. For manual setup, register Rollerworks\Bundle\PasswordStrengthBundle\RollerworksPasswordStrengthBundle in config/bundles.php.
First Use Case:
Apply the PasswordStrength constraint to a form field (e.g., registration):
use Rollerworks\PasswordStrengthBundle\Validator\Constraints\PasswordStrength;
#[PasswordStrength(minScore: 70)]
private $plainPassword;
minScore (0–100) to balance security and usability. Defaults to 70.Where to Look First:
config/packages/rollerworks_password_strength.yaml (customize scores, messages, or blacklists).Form Validation:
// src/Form/RegistrationType.php
$builder->add('password', PasswordType::class, [
'constraints' => [
new PasswordStrength([
'minScore' => 80,
'messages' => 'Your password is too weak. Add more complexity.',
]),
],
]);
Dynamic Rules:
Use PasswordRequirements for granular control (e.g., enforce uppercase letters):
#[PasswordRequirements(
minLength: 12,
requirements: [
'uppercase' => 1,
'lowercase' => 1,
'digit' => 1,
]
)]
private $password;
API Validation: Validate DTOs or API requests:
use Symfony\Component\Validator\Constraints as Assert;
class LoginDto {
#[Assert\NotBlank]
#[PasswordStrength(minScore: 60)]
public string $password;
}
Custom Scoring: Extend the validator via events (e.g., penalize repeated characters):
// config/services.yaml
services:
App\EventListener\PasswordStrengthListener:
tags:
- { name: kernel.event_listener, event: password_strength.calculate_score, method: onCalculateScore }
Blacklist Integration: Block common passwords or patterns:
# config/packages/rollerworks_password_strength.yaml
rollerworks_password_strength:
blacklist:
enabled: true
file: '%kernel.project_dir%/config/password_blacklist.txt'
translations/messages.{locale}.yml:
password_strength:
too_short: "Le mot de passe doit contenir au moins {length} caractères."
PasswordStrengthValidator directly in PHPUnit:
$validator = $this->getContainer()->get('rollerworks_password_strength.validator.password_strength');
$errors = $validator->validate('weak', new PasswordStrength());
Symfony\Component\Cache).Unicode Handling:
é = 1 char). Test with non-ASCII passwords.mbstring is enabled (php -m | grep mbstring).Constructor Changes (v4.0+):
new PasswordStrength(minScore: 70)).TypeError.Blacklist File Format:
#) are ignored.trim() when reading the file to avoid whitespace issues.Score Calculation:
minScore: 100 must meet all criteria (e.g., length + complexity).minScore: 0 to see raw scores for each rule.Symfony 6+ Deprecations:
Extension::prepend() in custom extensions. Use Extension::load() instead.// Old (deprecated)
$container->loadFromExtension('rollerworks_password_strength', [...]);
// New
$loader->load([...], $resource);
groups: ['registration'] to validate only during registration (avoids redundant checks).public function validate($value, Constraint $constraint): void {
$score = $this->calculateScore($value, $constraint);
error_log("Password score: $score");
// ... rest of validation
}
minScore: 0 to bypass validation during development.Custom Validators:
Extend PasswordStrengthValidator to add rules (e.g., check for sequential characters):
class CustomPasswordStrengthValidator extends PasswordStrengthValidator {
protected function calculateScore($value, Constraint $constraint): int {
$score = parent::calculateScore($value, $constraint);
if (preg_match('/(?:123|abc)/', $value)) {
$score -= 20;
}
return max(0, $score);
}
}
Register it in services.yaml:
services:
App\Validator\Constraints\CustomPasswordStrengthValidator:
decorates: 'rollerworks_password_strength.validator.password_strength'
arguments: ['@.inner']
Event Listeners:
Hook into password_strength.calculate_score to modify scoring dynamically:
#[Tag(name: 'kernel.event_listener', event: 'password_strength.calculate_score')]
public function onCalculateScore(PasswordStrengthEvent $event): void {
if (str_contains($event->getPassword(), 'admin')) {
$event->setScore(0);
}
}
Configuration Overrides:
Override default scores in config/packages/rollerworks_password_strength.yaml:
rollerworks_password_strength:
scores:
length: 20 # Default: 10
complexity: 30 # Default: 40
blacklist:
enabled: true
file: '%kernel.project_dir%/config/blacklist.txt'
minScore tiers (e.g., 60 for login, 80 for admin passwords).Constraint::message:
new PasswordStrength([
'minScore' => 70,
'messages' => [
'tooWeak' => 'Password must include: uppercase, lowercase, and a number.',
],
]);
zxcvbn) against this validator’s scores for consistency.
How can I help you explore Laravel packages today?