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

Password Bundle Laravel Package

octave/password-bundle

A Symfony bundle for password handling: secure hashing, configurable strength and policy validation, and smooth migration of legacy hashes. Integrates with Symfony's security component to keep authentication modern and consistent across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

The package targets Symfony 4 and advertises itself as "user password utils" — in practice that means a small bundle of services around Symfony's UserPasswordEncoderInterface plus (typically) forgot/reset-password plumbing. Treat it as a thin utility layer, not a full auth system.

Minimal steps:

  1. Confirm the install name. Check the repo's composer.json for the actual name field — it may differ from the path-style octave/password-bundle you see in the URL. Require that exact name:
    composer require octave/password-bundle
    
  2. Register the bundle. In a Symfony 4 app, add it to config/bundles.php:
    Octave\PasswordBundle\OctavePasswordBundle::class => ['all' => true],
    
    (The class name is worth verifying in the bundle's root PHP file — it may be OctavePasswordBundle or PasswordBundle.)
  3. Look here first, in order:
    • composer.json → required symfony/* versions and autoload path. This tells you immediately whether it will even boot on your Symfony version.
    • src/Resources/config/ (or Resources/config/) → the service definitions. This is the authoritative list of what the bundle actually wires up. Everything else is decoration.
    • DependencyInjection/*Extension.php → the config tree, i.e. what keys you can set under octave_password: in config/packages/.
    • src/ → the real logic. With 0 stars and 0 dependents, read it before trusting it.
  4. Verify DI registration before writing any code:
    bin/console debug:container --tag=…        # if the bundle tags services
    bin/console debug:container Octave        # find the encoder service id
    bin/console config:dump-reference octave_password
    
  5. First real use case: inject the bundle's password service into your registration controller and hash the password on user creation:
    public function register(Request $request, UserPasswordEncoderInterface $encoder)
    {
        $user = new User();
        $user->setPassword($encoder->encodePassword($user, $request->request->get('password')));
        // persist…
    }
    
    If the bundle already decorates or aliases UserPasswordEncoderInterface, you may get its behaviour for free — check the extension file rather than assuming.

Implementation Patterns

Treat it as a decorator over Symfony's own encoder. The bundle is only useful if it adds something on top of Symfony's built-in hashing — typically salt handling, a configured algorithm, or migration-on-login (rehash when the cost/algorithm changed). Wire it behind the standard interface so your application code is not coupled to the bundle:

// config/services.yaml
App\Security\PasswordEncoder: ~   # or bind to the bundle's service id

If the bundle exposes a concrete class instead of an interface, define your own interface and adapt — this makes the eventual rip-out trivial.

Registration flow pattern:

  • Create the User entity, set only the raw password temporarily.
  • Encode immediately before flush(), never store raw.
  • Use a PRE_PERSIST Doctrine listener if you want the encoding centralised rather than scattered across controllers.

Reset-password workflow pattern. If the bundle ships token entities/controllers, the usual shape is:

  1. POST /forgot-password → look up user by email, generate token, persist with expiry, send mail.
  2. GET /reset-password/{token} → validate token exists, expiresAt > now(), not already consumed.
  3. POST /reset-password/{token} → encode new password, invalidate token, optionally invalidate all sessions.

If it does not ship this, the "password utils" is likely just the encoder and you are writing the rest yourself — which is fine and often preferable.

Migration-on-login pattern (the one genuinely valuable thing a password bundle can give you):

if ($encoder->isPasswordValid($user, $plain, $user->getSalt())
    && $encoder->needsRehash($user->getPassword())) {
    $user->setPassword($encoder->encodePassword($user, $plain));
}

This lets you raise bcrypt cost or swap algorithms without forcing a reset. Check whether the bundle's service exposes needsRehash — if not, fall back to the framework's.

Integration tip — user provider contract. Symfony 4 expects your User class to implement UserInterface (and usually PasswordAuthenticatedUserInterface on 5.3+). The bundle's utilities assume a salt column exists (getSalt()), so keep it even if you use bcrypt/argon2 where it is unused.

Migration pattern when you outgrow it. Symfony 5.3+ renamed the contract to PasswordHasherInterface and dropped UserPasswordEncoderInterface. Plan the exit: alias the old interface to the new hasher, keep your own thin wrapper, and delete the bundle once your config/bundles.php no longer references it.

Gotchas and Tips

  • Zero stars, zero dependents, low opportunity score — audit before adopting. Read src/ end to end. Specifically look for md5, sha1, uniqid(), rand(), and mt_rand() — old password utilities frequently predate random_bytes() and will silently generate weak reset tokens.
  • Symfony 4 lock-in. The composer.json will likely pin symfony/*: ^4.0. On Symfony 5.3+ UserPasswordEncoderInterface and encodePassword() are deprecated and removed in 6.0; the bundle will either fail to install or emit deprecations on every request. Do not fight Composer with --ignore-platform-reqs — you will get a container that compiles and a runtime that doesn't.
  • Salt column required. Symfony 4's encoder API takes $user->getSalt(). If your User entity dropped the salt column (common in modern apps), every encode/verify call throws. Either keep the column returning null or add an adapter that ignores the argument.
  • Token expiry is your job unless proven otherwise. Check for an expiresAt field and a comparison in the consume path. A token with no expiry is a permanent backdoor if an email inbox is ever compromised.
  • Single-use enforcement. Look for a DELETE or used flag flip inside a transaction with the token read. Without that, a double-click on the reset link races and can double-apply.
  • Config key mismatch. The extension alias (octave_password, octave, or something else) is not necessarily derivable from the package name. Run bin/console config:dump-reference <guess> and, failing that, read DependencyInjection/Configuration.php directly.
  • Debugging DI failures: bin/console debug:container --show-private | grep -i password will tell you whether the service actually made it into the compiled container — often the bundle registers nothing because it is not in bundles.php or the config key is wrong.
  • Email delivery is not the bundle's problem. Anything that sends mail in a Symfony 4 bundle older than Mailer will use SwiftMailer. If your app is on symfony/mailer, expect an incompatible messenger/mailer bridge and plan to override the mailer service.
  • Extension points are usually just service overrides. Small bundles rarely document their overridable services. Find the id in Resources/config/services.xml, then redefine it in your own services.yaml under the same id to swap behaviour — no fork required.
  • Templates are overridable via Twig namespace. If the bundle ships views, @OctavePassword/... is the likely namespace; override by registering the same path earlier in config/packages/twig.yaml rather than editing vendor files.
  • Have an exit plan documented in the README of your own app. With no maintainer activity, the correct day-to-day posture is: wrap it, don't spread it. One service, one interface, so that removing the dependency is a one-file change when you move to PasswordHasherInterface.
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.
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
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin