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

Verification Code Bundle Laravel Package

creonit/verification-code-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require creonit/verification-code-bundle
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        Creonit\VerificationCodeBundle\CreonitVerificationCodeBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration: Update config/packages/creonit_verification_code.yaml with default values:

    creonit_verification_code:
        generator:
            config:
                length: 6  # Default code length
    
  3. First Use Case: Trigger a verification code for a phone number via the API route:

    POST /api/verification-code/send?scope=phone&key=+1234567890
    
    • The bundle validates the phone number against the regex pattern in scopes.phone.key_pattern.
    • Generates a 6-digit code (default) and stores it in the session or database (if configured).

Implementation Patterns

Core Workflows

  1. Sending Verification Codes: Use the API endpoint to trigger code generation and delivery (e.g., SMS/email):

    // In a controller or service
    $verificationCodeService = $this->get('creonit_verification_code.service');
    $result = $verificationCodeService->send('phone', '+1234567890');
    
    • Parameters:
      • scope: Key from scopes (e.g., phone, email).
      • key: User identifier (e.g., phone number, email).
      • Optional: template (for custom delivery logic).
  2. Validation: Verify a submitted code:

    $isValid = $verificationCodeService->validate('phone', '+1234567890', '123456');
    
    • Returns true if the code matches and hasn’t expired (based on max_age in config).
  3. Custom Scopes: Define new scopes in config/packages/creonit_verification_code.yaml:

    scopes:
        email:
            key_pattern: '/^[^\s@]+@[^\s@]+\.[^\s@]+$/'  # Basic email regex
            max_age: 300  # 5 minutes
            attempt_time: 60  # 1 minute between attempts
    

Integration Tips

  • Delivery Logic: Extend the bundle’s Delivery service to integrate with SMS/email providers (e.g., Twilio, Mailgun). Override:

    // src/Service/VerificationCodeDelivery.php
    use Creonit\VerificationCodeBundle\Delivery\VerificationCodeDeliveryInterface;
    
    class CustomVerificationCodeDelivery implements VerificationCodeDeliveryInterface {
        public function send(string $scope, string $key, string $code): bool {
            // Custom logic (e.g., Twilio API call)
            return true;
        }
    }
    

    Register the service in services.yaml:

    services:
        Creonit\VerificationCodeBundle\Delivery\VerificationCodeDeliveryInterface: '@App\Service\CustomVerificationCodeDelivery'
    
  • Database Storage: By default, codes are stored in the session. For persistence, implement a custom Storage service:

    use Creonit\VerificationCodeBundle\Storage\VerificationCodeStorageInterface;
    
    class DatabaseVerificationCodeStorage implements VerificationCodeStorageInterface {
        public function store(string $scope, string $key, string $code, int $maxAge): void {
            // Save to DB (e.g., using Doctrine)
        }
    
        public function retrieve(string $scope, string $key): ?string {
            // Fetch from DB
        }
    }
    

    Bind it in services.yaml:

    services:
        Creonit\VerificationCodeBundle\Storage\VerificationCodeStorageInterface: '@App\Service\DatabaseVerificationCodeStorage'
    
  • Rate Limiting: Use the attempt_time config to enforce delays between retries. For stricter control, integrate with Laravel’s throttle middleware or a package like spatie/rate-limiter.


Gotchas and Tips

Pitfalls

  1. Regex Patterns:

    • The key_pattern in scopes uses PCRE syntax. Test patterns thoroughly (e.g., +1 (123) 456-7890 vs. +11234567890).
    • Example for international phone numbers:
      key_pattern: '/^\+(?:[0-9] ?){6,14}[0-9]$/'
      
  2. Session Storage:

    • Codes stored in the session expire when the session ends. For long-lived codes (e.g., password resets), use a database-backed storage.
  3. Time Zones:

    • max_age and attempt_time use the server’s time zone. Ensure consistency with config/app.php:
      'timezone' => 'UTC', // or your preferred timezone
      
  4. Custom Generator Validation:

    • If extending AbstractCodeGenerator, always call parent::validateConfig() to inherit default validation:
      protected function validateConfig(array $config) {
          parent::validateConfig($config); // Inherit base validation
          // Add custom checks
      }
      

Debugging

  • Log Delivery Failures: Wrap delivery logic in a try-catch to log errors:

    try {
        $delivery->send($scope, $key, $code);
    } catch (\Exception $e) {
        \Log::error("Failed to send verification code to {$key}: " . $e->getMessage());
    }
    
  • Check Code Expiry: Use Tinker to inspect stored codes (if using session storage):

    php artisan tinker
    >> session()->get('verification_codes');
    

Extension Points

  1. Event Listeners: Subscribe to events for custom logic (e.g., logging, analytics):

    // src/EventListener/VerificationCodeListener.php
    use Creonit\VerificationCodeBundle\Event\VerificationCodeSentEvent;
    
    class VerificationCodeListener {
        public function onCodeSent(VerificationCodeSentEvent $event) {
            // Example: Log to a custom table
            \Log::info("Code sent to {$event->getKey()}");
        }
    }
    

    Register in services.yaml:

    services:
        App\EventListener\VerificationCodeListener:
            tags:
                - { name: kernel.event_listener, event: creonit_verification_code.sent, method: onCodeSent }
    
  2. Dynamic Scopes: Load scopes dynamically (e.g., from a database) by implementing a ScopeProvider:

    use Creonit\VerificationCodeBundle\Provider\ScopeProviderInterface;
    
    class DatabaseScopeProvider implements ScopeProviderInterface {
        public function getScopes(): array {
            return [
                'phone' => [
                    'key_pattern' => '/^\+...$/',
                    'max_age' => 180,
                ],
                // ...
            ];
        }
    }
    

    Bind in services.yaml:

    services:
        Creonit\VerificationCodeBundle\Provider\ScopeProviderInterface: '@App\Service\DatabaseScopeProvider'
    
  3. Testing: Mock the VerificationCodeService in tests:

    $mockService = $this->createMock(VerificationCodeService::class);
    $mockService->method('send')->willReturn(true);
    $this->app->instance('creonit_verification_code.service', $mockService);
    

Configuration Quirks

  • Overriding Defaults: To override the default generator (e.g., NumericCodeGenerator), ensure the service ID matches exactly:

    creonit_verification_code:
        generator:
            service: '@App\MyCodeGenerator'  # Must match the service ID
    
  • Environment-Specific Config: Use Laravel’s environment variables for dynamic values:

    scopes:
        phone:
            max_age: '%env(intVERIFICATION_CODE_MAX_AGE, 180)%'
    
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver