inem0o/user-password-lost-bundle
A Symfony bundle that adds a complete forgotten-password flow to your user accounts: request a reset, email a tokenized link, and let users securely set a new password. Built for quick integration with existing user providers and mailers.
Architecture fit. The package sits at the seam between the host framework's auth stack and Symfony's security primitives. The three changes in 1.0.5 are all Symfony-side alignment work, not feature work: UserPasswordEncoderInterface → UserPasswordHasherInterface (and encodePassword() → hashPassword()), FQCN-based repository lookup (PasswordResetRequest::class), and raised Symfony/PHP floors. That is a plumbing release, which is architecturally good news — it signals the package is tracking upstream contract deprecations rather than accumulating a private fork of them. The caveat is that this seam is the most sensitive part of any auth package: if these Symfony contracts leak into the package's public surface (constructor type-hints, container bindings, extension points users override), then an internal swap becomes an external breaking change.
Integration feasibility. Straightforward for a host on a recent framework line, and effectively blocked below it. UserPasswordHasherInterface::hashPassword() exists from Symfony 5.3 and UserPasswordEncoderInterface is removed in Symfony 6.0, so the "SF / PHP requirements" update is almost certainly a Symfony 6 floor and a PHP 8.1+ floor. That maps to Laravel 9/10/11 being plausible, Laravel 8 being out, and Laravel 9 deployments still on PHP 8.0 being out. The PasswordResetRequest::class change is an internal resolution cleanup with no expected consumer-facing effect unless users rebind or extend the repository.
Technical risk. Moderate, concentrated in three places. (1) Semver: this is a patch version carrying dependency-floor raises and interface renames — treat it as breaking regardless of the number. (2) Auth-path regression: swapping hasher interfaces is mechanical, but if any code path (registration, reset, change-password, API token flows) was missed, the failure mode is silent — either double-hashing or an unhashed credential — rather than a thrown exception. (3) Transitive constraint conflicts: a raised Symfony floor can collide with a host app's other Symfony-dependent packages, and Composer will surface that only at install time.
Key questions. Is this a Laravel package with a Symfony dependency, or a Symfony bundle being evaluated for a Laravel context — the notes read entirely Symfony, which changes the whole compatibility story? Does the package's public API expose UserPasswordHasherInterface or the reset-repository types, or are they internal? What exactly are the new composer.json floors for php and symfony/*? Is there a 1.0.x branch still maintained on Symfony 5 for hosts not ready to move? And why were these shipped as 1.0.5 rather than 1.1.0/2.0.0?
Stack fit. Good fit for Laravel 10/11 on PHP 8.1+, where the framework is already on Symfony 6.2+ and the package's floors are satisfied natively. Poor fit for Laravel 8, and a case-by-case check for Laravel 9 on PHP 8.0. The package is a thin integration layer, not a framework, so it should not drive the host's framework version decision — if it does, that is a signal to defer.
Migration path. This is an in-place dependency bump, not a code migration. Expect no application code changes for consumers who only call the package's public API; expect breakage only where consumers extend or rebind the affected services, which is rare and should be enumerated in release notes but currently is not. Pre-flight: composer why-not against the new constraints, then a clean install in a scratch branch before touching the main tree.
Compatibility. Build the matrix explicitly rather than assuming: Laravel 9 / 10 / 11 × PHP 8.1 / 8.2 / 8.3, plus one negative test on PHP 8.0 to confirm the floor fails loudly and cleanly rather than with a confusing runtime error. Confirm the symfony/security-* version resolves compatibly with what the host already pulls in.
Sequencing.
composer.json between 1.0.4 and 1.0.5 to get the real floors — the release note is too vague to plan against.1.0.5) rather than a caret range, given the patch-level breaking risk.^1.0 if a follow-up release clarifies intent.Maintenance. Net positive over a 6–12 month horizon. Moving off UserPasswordEncoderInterface ahead of its removal keeps the package on a maintained upstream line and avoids a harder forced migration later. The cost is a short-term bump window where the team absorbs an upgrade it did not schedule.
Support. The main support burden is version-skew questions from users who upgrade the package but not PHP, and the failure will present as a confusing install-time conflict. Budget a short internal note and a canned answer; if this is an internal package, add the floors to the README. Longer term, if there is no maintained 1.0.x-on-Symfony-5 branch, hosts frozen on older Laravel will need a fork, which is a real and often underestimated cost.
Scaling. Neutral. Nothing here affects throughput, hashing cost, or connection handling. Password hashing is CPU-bound either way and is already the dominant cost in auth requests.
Failure modes. Ranked by likelihood and severity:
composer.lock before upgrading.Ramp-up. Low. Roughly half a day for an engineer familiar with the codebase to do the diff-audit, run the matrix, and validate the auth flows; the review and canary window is the larger calendar cost. The one thing worth insisting on is a real test of the password-reset path — it is the piece most likely to be assumed working and least likely to be exercised in routine QA.
How can I help you explore Laravel packages today?