Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Password Strength Bundle Laravel Package

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+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. 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.

  2. 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;
    
    • Key Config: Adjust minScore (0–100) to balance security and usability. Defaults to 70.
  3. Where to Look First:


Implementation Patterns

Common Workflows

  1. 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.',
            ]),
        ],
    ]);
    
  2. Dynamic Rules: Use PasswordRequirements for granular control (e.g., enforce uppercase letters):

    #[PasswordRequirements(
        minLength: 12,
        requirements: [
            'uppercase' => 1,
            'lowercase' => 1,
            'digit' => 1,
        ]
    )]
    private $password;
    
  3. API Validation: Validate DTOs or API requests:

    use Symfony\Component\Validator\Constraints as Assert;
    
    class LoginDto {
        #[Assert\NotBlank]
        #[PasswordStrength(minScore: 60)]
        public string $password;
    }
    
  4. 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 }
    
  5. 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'
    

Integration Tips

  • Translation: Override messages in translations/messages.{locale}.yml:
    password_strength:
        too_short: "Le mot de passe doit contenir au moins {length} caractères."
    
  • Testing: Use PasswordStrengthValidator directly in PHPUnit:
    $validator = $this->getContainer()->get('rollerworks_password_strength.validator.password_strength');
    $errors = $validator->validate('weak', new PasswordStrength());
    
  • Performance: Cache blacklist files if frequently used (e.g., with Symfony\Component\Cache).

Gotchas and Tips

Pitfalls

  1. Unicode Handling:

    • The validator counts Unicode characters (e.g., é = 1 char). Test with non-ASCII passwords.
    • Fix: Ensure mbstring is enabled (php -m | grep mbstring).
  2. Constructor Changes (v4.0+):

    • Constraints now require keyword arguments (e.g., new PasswordStrength(minScore: 70)).
    • Migration: Update all constraint instantiations to avoid TypeError.
  3. Blacklist File Format:

    • Each line = one blacklisted password. Empty lines or comments (#) are ignored.
    • Tip: Use trim() when reading the file to avoid whitespace issues.
  4. Score Calculation:

    • Scores are not additive. A password with minScore: 100 must meet all criteria (e.g., length + complexity).
    • Debug: Temporarily set minScore: 0 to see raw scores for each rule.
  5. Symfony 6+ Deprecations:

    • Avoid Extension::prepend() in custom extensions. Use Extension::load() instead.
    • Example:
      // Old (deprecated)
      $container->loadFromExtension('rollerworks_password_strength', [...]);
      
      // New
      $loader->load([...], $resource);
      

Debugging

  • Enable Validation Groups: Use groups: ['registration'] to validate only during registration (avoids redundant checks).
  • Log Scores: Override the validator to log scores:
    public function validate($value, Constraint $constraint): void {
        $score = $this->calculateScore($value, $constraint);
        error_log("Password score: $score");
        // ... rest of validation
    }
    
  • Disable Rules Temporarily: Set minScore: 0 to bypass validation during development.

Extension Points

  1. 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']
    
  2. 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);
        }
    }
    
  3. 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'
    

Pro Tips

  • Progressive Strength: Use minScore tiers (e.g., 60 for login, 80 for admin passwords).
  • User Feedback: Return detailed feedback via Constraint::message:
    new PasswordStrength([
        'minScore' => 70,
        'messages' => [
            'tooWeak' => 'Password must include: uppercase, lowercase, and a number.',
        ],
    ]);
    
  • Benchmarking: Test password generation tools (e.g., zxcvbn) against this validator’s scores for consistency.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
escalated-dev/escalated-laravel
escalated-dev/locale
vusys/laravel-runabout
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
directorytree/opensearch-client
directorytree/opensearch-adapter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php