moukail/password-reset-mail-bundle
Password Reset Mail Bundle provides ready-to-use password reset email handling for PHP applications, helping you generate reset links and send them to users with minimal setup. Quickly integrate a complete password reset email flow into your app.
This is a Symfony bundle, not a Laravel package. The first thing a Laravel developer must understand is that moukail/password-reset-mail-bundle targets Symfony's kernel/bundle system, not Laravel's service providers, facades, or config/*.php files. There is no PasswordResetMailServiceProvider for Laravel to auto-discover.
Minimal steps if you are evaluating it:
composer require moukail/password-reset-mail-bundle inside a Symfony project (not a Laravel one).config/bundles.php:
return [
Moukail\PasswordResetMailBundle\PasswordResetMailBundle::class => ['all' => true],
];
DependencyInjection/ directory and Resources/config/ — that's where the service id, mailer wiring, hasher wiring, and any parameters live. There is still no published documentation, so the DI extension class is your source of truth.sendResetMail(...)-style method the service exposes.What's new in v1.0.6. The release note is a single token: UserPasswordHasherInterface. That is Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface, shipped in symfony/password-hasher from Symfony 5.3 onward. Two practical takeaways:
EncoderFactoryInterface / UserPasswordEncoderInterface (removed in Symfony 6). That improves the odds it boots on Symfony 6.x — but confirm in composer.json whether it also still requires swiftmailer/swiftmailer, which is a separate, unrelated blocker.UserPasswordHasherInterface (Symfony aliases this to security.user_password_hasher). If you hand-instantiate the service — which the Laravel adapter path forces you to do — you now have one more dependency to supply.If you are on Laravel: the realistic "getting started" is do not install this. Laravel's Password::sendResetLink() and the ResetPassword notification already cover the use case with first-party, maintained code. Only proceed with this bundle if you are porting a Symfony app or explicitly need its exact mail template.
The package still has effectively zero public traction, so treat any pattern here as reverse-engineered rather than documented. The v1.0.6 bump is a positive maintenance signal, but it is a one-line release — not a track record.
Symfony wiring pattern. The intended flow is: form submit → service method that generates a token → mailer service builds an Email → transport sends. With UserPasswordHasherInterface now in play, the likely shape is a constructor like:
public function __construct(
private MailerInterface $mailer,
private UserPasswordHasherInterface $hasher,
// ...token/entity dependencies
) {}
That hasher is plausibly used to hash the reset token at rest rather than storing it in plaintext (Symfony's own ResetPasswordTokenSystem does exactly this). Verify by reading the service class before assuming it — but if true, it's a genuine security improvement over the pre-2022 code.
Container-level integration. Pull the service by id from the container and let autowiring resolve the hasher:
use Moukail\PasswordResetMailBundle\Service\PasswordResetMailer;
public function __construct(private PasswordResetMailer $mailer) {}
Confirm the actual FQCN against Resources/config/services.* — the release changed constructor signatures, and bin/console debug:container / debug:autowiring UserPasswordHasherInterface will show you whether resolution is wired. If autowiring fails after the upgrade, that is the first place to look: you may need an explicit arguments: entry in services.yaml pointing at @security.user_password_hasher.
If you truly need it in Laravel, the pragmatic pattern is a thin adapter — and v1.0.6 makes it slightly more work, not less:
symfony/mailer / symfony/password-hasher versions — use --ignore-platform-req only as a last resort).UserPasswordHasherInterface implementation, so you either write a small adapter class implementing that interface over Laravel's Hash facade, or pull in symfony/password-hasher standalone.Notification or Mailable so the rest of your app talks to Laravel primitives, not the bundle.The adapter path remains fragile and generally not worth it versus writing a 30-line Mailable.
Workflow tip. Fork the repo, pin a version, and re-publish under your own vendor namespace if you depend on it in production. One release after a ~3-year gap does not establish a maintenance cadence — but it does mean the fork-and-pin advice now starts from a Symfony-5.3+-compatible baseline rather than abandoned 2022 code.
config/password-reset-mail.php. Auto-discovery will not find it. You will wire it by hand.UserPasswordHasherInterface. In Symfony this is normally free (the framework aliases it), but it breaks if symfony/security-bundle / symfony/password-hasher isn't installed or is locked to a version outside the bundle's constraint. In Laravel it is not available at all — you must implement it. Symptom of a mismatch: a Cannot autowire service ... references interface UserPasswordHasherInterface error at container compile time.composer.json require before assuming the bundle boots on modern Symfony; a 5.3-era hasher interface alongside a SwiftMailer mailer is entirely possible.composer require moukail/password-reset-mail-bundle:1.0.6) and re-check composer.json diff on every bump — constructor signature changes can happen silently in a patch release, as this one shows.DependencyInjection/*Extension.php), the service XML/YAML under Resources/config/, and any CompilerPass classes. bin/console debug:container --tag=... and debug:autowiring UserPasswordHasherInterface (Symfony) are your fastest paths to the real service id and dependency graph.moukail_password_reset_mail — but verify the exact key in the extension class, not a README (there isn't one). A new constructor argument does not necessarily mean a new config knob; the hasher is container-wired, not configured.random_bytes/bin2hex (not rand/uniqid), that tokens are single-use and expire, and — now plausibly relevant — that the UserPasswordHasherInterface usage actually hashes the token at rest and compares with isPasswordValid rather than storing plaintext and calling the hasher decoratively. Re-check this on the 1.0.6 source; do not infer it from the release note.decorates: in services.yaml), override the hasher binding, or override the bundle's templates under templates/bundles/. There is no Laravel-style extend() hook.Password::sendResetLink, the ResetPassword notification, and a custom Mailable give you maintained, documented, framework-native behavior, and Laravel's token storage is already hashed. v1.0.6 removes one objection to the bundle, but adds a dependency that Laravel simply does not provide.How can I help you explore Laravel packages today?