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

Zxcvbn Bundle Laravel Package

createnl/zxcvbn-bundle

Symfony bundle integrating zxcvbn-php for password strength scoring with user-data hints, localized feedback (EN/NL/FR), and support for custom matchers. Provides a factory service to create a Zxcvbn instance for easy use in controllers and services.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require createnl/zxcvbn-bundle
    

    Ensure Createnl\ZxcvbnBundle\CreatenlZxcvbnBundle is enabled in config/bundles.php.

  2. First Use Case: Password Strength Validation Inject ZxcvbnFactoryInterface into your controller/service and use it to evaluate password strength:

    use Createnl\ZxcvbnBundle\ZxcvbnFactoryInterface;
    
    public function checkPassword(ZxcvbnFactoryInterface $zxcvbnFactory, string $password) {
        $zxcvbn = $zxcvbnFactory->createZxcvbn();
        $result = $zxcvbn->passwordStrength($password, ['user_data' => ['username', 'email']]);
        return $result['score']; // 0-4
    }
    
  3. Localization

    • Supported languages: en, nl, fr.
    • Override translations in config/packages/createnl_zxcvbn.yaml:
      createnl_zxcvbn:
          locale: 'fr' # or 'nl'
      

Implementation Patterns

Core Workflow: Real-Time Password Feedback

  1. Frontend Integration Use JavaScript (e.g., zxcvbn-js) for client-side feedback, then validate server-side with this bundle. Example:

    // In a Symfony Form Type
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('password', PasswordType::class, [
            'constraints' => [
                new CallbackConstraint(function ($password, ExecutionContextInterface $context) {
                    $zxcvbn = $this->zxcvbnFactory->createZxcvbn();
                    $result = $zxcvbn->passwordStrength($password, ['user_data' => ['username']]);
                    if ($result['score'] < 3) {
                        $context->buildViolation('Password too weak')
                            ->atPath('password')
                            ->addViolation();
                    }
                })
            ]
        ]);
    }
    
  2. Batch Processing User Data For bulk operations (e.g., password resets), cache Zxcvbn instances:

    // Cache the factory for reuse
    $zxcvbn = $zxcvbnFactory->createZxcvbn();
    foreach ($users as $user) {
        $result = $zxcvbn->passwordStrength($newPassword, ['user_data' => [$user->username]]);
        // Store result or trigger actions
    }
    
  3. Custom Feedback Handling Extract feedback for UI display:

    $result = $zxcvbn->passwordStrength($password);
    $feedback = [
        'score' => $result['score'],
        'warning' => $result['feedback']['warning'] ?? null,
        'suggestions' => $result['feedback']['suggestions'] ?? [],
    ];
    return $this->json($feedback);
    

Gotchas and Tips

Pitfalls

  1. User Data Sensitivity

    • Avoid exposing raw user data (e.g., email, username) in logs or error messages. Sanitize or hash sensitive data before passing to passwordStrength().
    • Example:
      $userData = [
          'username' => $user->username,
          'email' => hash('sha256', $user->email), // Hash sensitive fields
      ];
      
  2. Performance with Large Datasets

    • The bundle loads dictionaries (e.g., common passwords) on first use. For high-traffic apps, preload the Zxcvbn instance in a warmup command:
      // bin/console zxcvbn:warmup
      public function handle() {
          $factory = $this->container->get(ZxcvbnFactoryInterface::class);
          $factory->createZxcvbn(); // Trigger lazy loading
      }
      
  3. Localization Quirks

    • Non-supported languages will fall back to English. Override translations before initializing the bundle:
      # config/packages/createnl_zxcvbn.yaml
      createnl_zxcvbn:
          locale: 'es' # Unofficial; will use English fallback
      
    • Contribute missing translations via PR to the bundle repo.

Debugging

  1. Score Discrepancies

    • Client-side (JS) and server-side scores may differ due to:
      • Different dictionaries (e.g., JS uses zxcvbn-dictionary).
      • Case sensitivity or user data formatting.
    • Fix: Standardize input (e.g., lowercase passwords) or use the same dictionary on both sides.
  2. Matcher Conflicts

    • Custom matchers tagged with zxcvbn.matcher may override default behavior. Test isolated matchers:
      // Disable all matchers except your custom one
      $zxcvbn = $zxcvbnFactory->createZxcvbn(['matchers' => [YourMatcher::class]]);
      

Extension Points

  1. Custom Matchers

    • Extend zxcvbn-php's matchers by implementing zxcvbn\MatcherInterface:
      use zxcvbn\MatcherInterface;
      
      class CustomMatcher implements MatcherInterface {
          public function match($password, $userInputs) {
              return ['pattern': 'custom', 'score': 1, 'token': []];
          }
      }
      
    • Register in services.yaml:
      services:
          App\CustomMatcher:
              tags: ['zxcvbn.matcher']
      
  2. Configuration Overrides

    • Override default zxcvbn options (e.g., guesses, feedback):
      createnl_zxcvbn:
          options:
              guesses: 1000000000000 # Adjust for stricter/looser scoring
      
  3. Symfony Event Integration

    • Trigger actions on password events (e.g., weak password detected):
      // src/EventListener/ZxcvbnListener.php
      public function onPasswordSubmit(PasswordEvent $event) {
          $zxcvbn = $this->zxcvbnFactory->createZxcvbn();
          $result = $zxcvbn->passwordStrength($event->getPassword());
          if ($result['score'] < 3) {
              $event->setError('Weak password');
          }
      }
      
    • Dispatch events in your controller:
      $event = new PasswordEvent($password);
      $this->eventDispatcher->dispatch($event);
      if ($event->hasError()) { /* Handle */ }
      

Pro Tips

  • Combine with Symfony Validator Use the bundle’s score in a custom constraint:

    use Symfony\Component\Validator\Constraint;
    
    class MinPasswordStrength extends Constraint {
        public $score;
    
        public function validatedBy() { return static::class; }
    
        public function validate($value, ExecutionContext $context) {
            $result = $this->zxcvbnFactory->createZxcvbn()->passwordStrength($value);
            if ($result['score'] < $this->score) {
                $context->buildViolation($this->message)
                    ->addViolation();
            }
        }
    }
    
  • Logging Feedback Log password strength results (anonymized) for analytics:

    $logger->info('Password strength', [
        'score' => $result['score'],
        'user_id' => $user->id, // Avoid logging sensitive data
    ]);
    
  • Testing Mock ZxcvbnFactoryInterface in tests:

    $mockFactory = $this->createMock(ZxcvbnFactoryInterface::class);
    $mockZxcvbn = $this->createMock(Zxcvbn::class);
    $mockZxcvbn->method('passwordStrength')->willReturn(['score' => 4]);
    $mockFactory->method('createZxcvbn')->willReturn($mockZxcvbn);
    $this->controller->setContainer($this->createMock(ContainerInterface::class));
    $this->controller->setZxcvbnFactory($mockFactory);
    
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle