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

Invitation Bundle Laravel Package

cethyworks/invitation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require cethyworks/invitation-bundle
    

    Add the bundle to AppKernel.php:

    new Cethyworks\InvitationBundle\CethyworksInvitationBundle(),
    
  2. Configure security.yml:

    security:
        providers:
            in_memory_invitation_provider:
                invitation_memory:
                    invitations:
                        - { code: "initial-code" }
        firewalls:
            invitation:
                pattern: ^/private-route
                provider: in_memory_invitation_provider
                guard:
                    authenticator:
                        cethyworks_invitation.authenticator
                anonymous: false
    
  3. First Use Case: Access /private-route?code=initial-code to test the protected route. Replace initial-code with your configured invitation code.


Implementation Patterns

Core Workflow

  1. Define Invitation Codes:

    • Hardcode in security.yml (for testing) or use a database-backed provider (if extended).
    • Example:
      invitations:
          - { code: "dev-team-2024", expires_at: "2024-12-31" }
      
  2. Route Protection:

    • Apply the invitation firewall to any route prefix (e.g., ^/admin).
    • Ensure anonymous: false to block unauthenticated access.
  3. Dynamic Invitation Management:

    • For production, extend the bundle to fetch codes from a database (see Gotchas).
    • Example service to generate codes:
      // src/Service/InvitationService.php
      class InvitationService {
          public function generateCode(): string {
              return Str::random(16);
          }
      }
      
  4. Post-Authentication Logic:

    • Use Symfony’s event system to trigger actions after successful authentication:
      // src/EventListener/InvitationListener.php
      class InvitationListener implements ContainerAwareInterface {
          public function onAuthenticationSuccess(AuthenticationSuccessEvent $event) {
              $user = $event->getAuthenticationToken()->getUser();
              // Log, redirect, or assign roles dynamically.
          }
      }
      
  5. Integration with Forms:

    • Create a custom form to handle invitation codes:
      // src/Form/InvitationType.php
      class InvitationType extends AbstractType {
          public function buildForm(FormBuilderInterface $builder, array $options) {
              $builder->add('code', TextType::class);
          }
      }
      

Gotchas and Tips

Pitfalls

  1. Deprecated Bundle:

    • Last updated in 2017; test thoroughly in your Laravel/Symfony version (if using Symfony 4+).
    • May require polyfills for newer Symfony features (e.g., authenticator changes in Symfony 5+).
  2. In-Memory Provider Limitations:

    • Codes are not persistent across server restarts. For production, extend the provider to use a database:
      # Example: Custom provider (hypothetical)
      providers:
          db_invitation_provider:
              invitation_db:
                  connection: default
                  table: invitation_codes
      
    • Implement a custom InvitationProviderInterface to query your database.
  3. Firewall Configuration:

    • Ensure the pattern in firewalls matches your route exactly (e.g., ^/private vs. ^/private/).
    • Overlapping patterns can cause conflicts; order matters in Symfony’s firewall stack.
  4. Authentication Flow:

    • The bundle uses Symfony’s guard authentication. If you encounter issues, verify:
      • The authenticator service (cethyworks_invitation.authenticator) is properly registered.
      • No other firewall is intercepting the request before the invitation firewall.
  5. CSRF and Invitation Codes:

    • If using forms, ensure CSRF protection is enabled. The bundle does not handle CSRF by default.

Debugging Tips

  1. Check Authentication Events:

    • Enable Symfony’s debug toolbar to inspect SECURITY events during failed logins.
    • Look for AuthenticationFailureEvent or AuthenticationSuccessEvent.
  2. Log Invitation Codes:

    • Temporarily log codes in the authenticator to verify they’re being read correctly:
      // src/Authenticator/InvitationAuthenticator.php (custom)
      public function getCredentials(Request $request) {
          $code = $request->query->get('code');
          $this->logger->debug('Invitation code attempted:', ['code' => $code]);
          return ['code' => $code];
      }
      
  3. Test with curl:

    • Simulate requests to isolate issues:
      curl "http://your-app.test/private-route?code=test123"
      
  4. Database Backend:

    • If extending for a database, ensure your InvitationProvider implements:
      public function loadUserByInvitationCode($code);
      public function refreshUser(UserInterface $user);
      public function supportsClass($class);
      

Extension Points

  1. Custom Invitation Provider:

    • Extend Cethyworks\InvitationBundle\Security\Provider\InvitationProvider to support databases or APIs.
    • Example:
      class DatabaseInvitationProvider extends InvitationProvider {
          public function loadUserByInvitationCode($code) {
              return $this->entityManager->getRepository(User::class)
                  ->findOneBy(['invitationCode' => $code]);
          }
      }
      
  2. Role-Based Access:

    • Assign roles after authentication to gate further access:
      // In your authenticator
      $user->setRoles(['ROLE_INVITED_USER']);
      return new Token($user, null, ['ROLE_INVITED_USER']);
      
  3. Rate Limiting:

    • Combine with Symfony’s rate_limiter to prevent brute-force attacks on invitation codes.
  4. Email Integration:

    • Extend the bundle to send invitation codes via email (requires custom logic since the bundle doesn’t support this natively).
    • Example:
      // src/Command/SendInvitationCommand.php
      class SendInvitationCommand extends Command {
          protected function execute(InputInterface $input, OutputInterface $output) {
              $code = $this->invitationService->generateCode();
              $email = (new Email())
                  ->to('user@example.com')
                  ->subject('Your Invitation Code')
                  ->text($code);
              $this->mailer->send($email);
          }
      }
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware