Weave 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

Laravel Email Change Confirmation Laravel Package

milenmk/laravel-email-change-confirmation

Laravel package for confirming user email address changes. Adds a verification flow (often via signed link/token), protects accounts by requiring confirmation before updating the email, and integrates cleanly with common auth setups in Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require milenmk/laravel-email-change-confirmation
    php artisan vendor:publish --provider="MilenMk\EmailChangeConfirmation\EmailChangeConfirmationServiceProvider" --tag="config"
    php artisan migrate
    
    • Publishes config (config/email-change-confirmation.php) and creates a email_change_confirmations table.
  2. Configure Update config/email-change-confirmation.php with:

    • token_lifetime (default: 24 hours)
    • email_template (path to Blade template)
    • queue (set to true if using queues)
  3. First Use Case Trigger an email change for a user:

    use MilenMk\EmailChangeConfirmation\Facades\EmailChangeConfirmation;
    
    $user = User::find(1);
    EmailChangeConfirmation::sendChangeRequest($user, '[email protected]');
    
    • Checks if the new email is valid and not already in use.
    • Generates a secure token, stores it in the DB, and sends a confirmation email.

Implementation Patterns

Traditional Controller Workflow

  1. Trigger Request

    public function requestEmailChange(Request $request) {
        $validated = $request->validate(['email' => 'required|email']);
        EmailChangeConfirmation::sendChangeRequest(auth()->user(), $validated['email']);
        return back()->with('status', 'Confirmation email sent!');
    }
    
  2. Confirm Change

    public function confirmEmailChange($token) {
        $result = EmailChangeConfirmation::confirmChange($token);
        if ($result->success()) {
            return redirect()->route('dashboard')->with('status', 'Email updated!');
        }
        return back()->withErrors($result->errors());
    }
    
  3. Resend Token

    public function resendConfirmation($token) {
        $result = EmailChangeConfirmation::resendConfirmation($token);
        return back()->with('status', $result->success() ? 'New email sent!' : 'Invalid token.');
    }
    

Livewire Component Integration

  1. Create a Livewire Component

    php artisan make:livewire EmailChangeForm
    
  2. Handle Logic in Component

    use MilenMk\EmailChangeConfirmation\Facades\EmailChangeConfirmation;
    
    public function sendChangeRequest() {
        $validated = $this->validate(['email' => 'required|email']);
        $result = EmailChangeConfirmation::sendChangeRequest(auth()->user(), $validated['email']);
        if ($result->success()) {
            $this->emit('alert', 'Confirmation email sent!');
        } else {
            $this->addError('email', $result->errors()->first());
        }
    }
    
    public function confirmChange($token) {
        $result = EmailChangeConfirmation::confirmChange($token);
        if ($result->success()) {
            $this->emit('alert', 'Email updated!');
            $this->redirect('/dashboard');
        }
    }
    
  3. Blade Template

    <livewire:email-change-form />
    
    @script
        window.addEventListener('alert', (e) => {
            toast(e.detail);
        });
    @endscript
    

Queue Integration

  1. Configure Queue in .env

    QUEUE_CONNECTION=database
    
  2. Dispatch Job Manually

    EmailChangeConfirmation::sendChangeRequest($user, '[email protected]', true); // Force queue
    
  3. Run Worker

    php artisan queue:work
    

Customizing Emails

  1. Publish Views

    php artisan vendor:publish --provider="MilenMk\EmailChangeConfirmation\EmailChangeConfirmationServiceProvider" --tag="views"
    
    • Override resources/views/vendor/email-change-confirmation/email.blade.php.
  2. Pass Custom Data

    EmailChangeConfirmation::sendChangeRequest($user, '[email protected]', [
        'custom_data' => 'Hello, User!'
    ]);
    
    • Access in Blade: @php echo $custom_data @endphp.

Gotchas and Tips

Common Pitfalls

  1. Token Expiry

    • Tokens expire after token_lifetime (default: 24h). Use resendConfirmation() if needed.
    • Debug: Check email_change_confirmations table for expired tokens.
  2. Email Validation

    • The package validates emails before sending. Ensure your User model’s email field allows duplicates during the change process (e.g., unique:users,email is temporarily bypassed).
  3. Queue Delays

    • If using queues, confirm the job is dispatched:
      EmailChangeConfirmation::sendChangeRequest($user, '[email protected]', true); // Force sync for testing
      
    • Check failed_jobs table if emails aren’t sent.
  4. Livewire Token Handling

    • Tokens in URLs may cause issues with Livewire’s reactivity. Pass tokens via hidden inputs or state management:
      public $confirmationToken;
      public function mount($token) {
          $this->confirmationToken = $token;
      }
      

Debugging Tips

  1. Log Token Generation Enable debug mode in config/email-change-confirmation.php:

    'debug' => env('APP_DEBUG', false),
    
    • Logs token creation/confirmation to storage/logs/laravel.log.
  2. Check Database

    SELECT * FROM email_change_confirmations WHERE user_id = 1;
    
    • Verify tokens, emails, and statuses (pending, confirmed, failed).
  3. Test Email Delivery Use Laravel’s Mail::fake() in tests:

    public function test_email_change() {
        Mail::fake();
        $result = EmailChangeConfirmation::sendChangeRequest($user, '[email protected]');
        Mail::assertSent(\MilenMk\EmailChangeConfirmation\Mail\ChangeEmail::class);
    }
    

Extension Points

  1. Custom Events Listen for events in EventServiceProvider:

    protected $listen = [
        \MilenMk\EmailChangeConfirmation\Events\ChangeEmailRequested::class => [
            \App\Listeners\LogEmailChange::class,
        ],
        \MilenMk\EmailChangeConfirmation\Events\ChangeEmailConfirmed::class => [
            \App\Listeners\NotifyAdmin::class,
        ],
    ];
    
  2. Override Confirmation Logic Bind the confirm-change command to a custom handler:

    EmailChangeConfirmation::extend(function ($app) {
        $app->bind(\MilenMk\EmailChangeConfirmation\Contracts\ConfirmationHandler::class, \App\Services\CustomConfirmationHandler::class);
    });
    
  3. Add Metadata to Tokens Extend the email_change_confirmations table and hydrate the model:

    public function boot() {
        \MilenMk\EmailChangeConfirmation\Models\EmailChangeConfirmation::created(function ($model) {
            $model->metadata = ['ip' => request()->ip()];
            $model->save();
        });
    }
    

Configuration Quirks

  1. Token Length

    • Default token length is 60 characters (secure random string). Adjust in config/email-change-confirmation.php:
      'token_length' => 60,
      
  2. Rate Limiting

    • No built-in rate limiting, but add middleware to requestEmailChange:
      Route::middleware(['throttle:5,1'])->group(function () {
          Route::post('/email-change', [EmailChangeController::class, 'requestEmailChange']);
      });
      
  3. Multi-Tenant Support

    • Add tenant_id to the email_change_confirmations table and filter queries:
      EmailChangeConfirmation::where('tenant_id', auth()->tenant()->id)->get();
      
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings