daddl3/email_with_login_link_and_change_password
Installation
composer require daddl3/email-with-login-link-and-change-password
Add the bundle to your config/bundles.php (Symfony) or register the service provider in config/app.php (Laravel via Symfony bridge):
Daddl3\EmailWithLoginLinkAndChangePasswordBundle\Daddl3EmailWithLoginLinkAndChangePasswordBundle::class => ['all' => true],
Configuration Publish the default config:
php artisan vendor:publish --provider="Daddl3\EmailWithLoginLinkAndChangePasswordBundle\Daddl3EmailWithLoginLinkAndChangePasswordBundle" --tag="config"
Update config/daddl3_email_with_login_link_and_change_password.php with your email settings (e.g., mailer transport, from address, expiration_time for login links).
First Use Case Trigger a login link email for a user:
use Daddl3\EmailWithLoginLinkAndChangePasswordBundle\Service\EmailService;
$emailService = app(EmailService::class);
$user = User::find(1); // Replace with your user model
$emailService->sendLoginLinkEmail($user->getEmail());
Sending Login Links
EmailService::sendLoginLinkEmail($email) to generate and send a one-time login link.resources/views/emails/login_link.html.twig in Symfony; adapt for Laravel via resources/views/vendor/email-with-login-link-and-change-password/login_link.blade.php).Password Reset
$emailService->sendPasswordResetEmail($email);
$emailService->validatePasswordResetToken($token, $email);
$emailService->resetPassword($email, $newPassword);
Token Management
$token = $emailService->generateLoginLinkToken($email);
if ($emailService->isLoginLinkValid($token, $email)) {
// Redirect to secure area
}
Laravel-Specific Adaptations
Twig with Laravel’s Blade by creating a custom service provider to bind the EmailService and override template paths.Mail facade for transport if not using Symfony Mailer:
$mailer = app(\Symfony\Component\Mailer\MailerInterface::class);
// Configure Symfony Mailer to use Laravel’s SwiftMailer transport.
Customizing Emails
Daddl3\EmailWithLoginLinkAndChangePasswordBundle\Email\BaseEmail) to add dynamic content:
namespace App\Email;
use Daddl3\EmailWithLoginLinkAndChangePasswordBundle\Email\BaseEmail;
class CustomLoginEmail extends BaseEmail {
public function build(): self {
$this->subject('Custom Login Link');
$this->html('<p>Hello, use this link to login: <a href="{{ link }}">{{ link }}</a></p>');
return $this;
}
}
Token Storage
Token entity). For custom storage (e.g., Redis), implement TokenStorageInterface and update the email_service configuration:
token_storage: App\Services\RedisTokenStorage
Security
throttle middleware or Symfony’s RateLimiter.event(new LoginLinkGenerated($user, $token));
Token Expiration
expiration_time (default: 1 hour). Ensure this aligns with your security policies. Adjust via config:
'expiration_time' => 3600, // 1 hour in seconds
Email Delivery Failures
mailer transport is configured (e.g., smtp, sendmail).from address is valid and not blacklisted.php artisan queue:work if using queues).Token Reuse
$emailService->consumeLoginLinkToken($token, $email);
User Model Requirements
User model must implement getEmail() and setPassword($password). For Laravel, ensure your User model uses HasApiTokens or similar for token storage.Token Validation Errors
'debug' => env('APP_DEBUG', false),
\Log::debug('Token validation', ['token' => $token, 'email' => $email]);
Email Template Issues
php artisan view:clear
$this->get('twig')->addExtension(new \Twig\Extra\Debug\DebugRuntime());
Custom Token Storage
TokenStorageInterface for non-database storage (e.g., Redis, Memcached):
namespace App\Services;
use Daddl3\EmailWithLoginLinkAndChangePasswordBundle\Token\TokenStorageInterface;
class RedisTokenStorage implements TokenStorageInterface {
public function save($token, $email, $expiry): void {
// Redis logic
}
public function find($token): ?string {
// Redis logic
}
public function delete($token): void {
// Redis logic
}
}
Event Listeners
// In EventServiceProvider (Laravel) or symfony/event-dispatcher
protected $listen = [
\Daddl3\EmailWithLoginLinkAndChangePasswordBundle\Event\LoginLinkGenerated::class => [
\App\Listeners\LogLoginLinkGeneration::class,
],
];
API Integration
// routes/api.php
Route::post('/login-link', function (Request $request) {
$emailService = app(EmailService::class);
return $emailService->sendLoginLinkEmail($request->email);
});
Multi-Tenant Support
Token entity to include a tenant_id and filter queries by tenant:
$tokens = Token::where('email', $email)
->where('tenant_id', auth()->tenant()->id)
->first();
How can I help you explore Laravel packages today?