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

Jetstream Bridge Laravel Package

liberusoftware/jetstream-bridge

Integration bridge that connects Liberu Software's modular Laravel packages with Jetstream, wiring authentication, teams, profile management and API tokens into one stack. Ships service providers, config and adapters so Jetstream features work consistently across Liberu components.

View on GitHub
Deep Wiki
Context7

Getting Started

The bridge sits between your Laravel app's auth scaffolding (Fortify + Jetstream) and Liberu's identity layer. It ships adapter classes that implement the Fortify action contracts (create user, update profile, update password, reset password, 2FA enable/confirm/disable, email verification) while delegating the actual persistence and business rules to Liberu identity services. In practice: you keep Jetstream's UI and Fortify's routes, and swap the implementation underneath.

Minimal path:

  1. Install alongside the real dependencies. This package is a glue layer — it assumes the identity module and a Jetstream/Fortify app exist.
composer require liberusoftware/jetstream-bridge
php artisan vendor:publish --provider="Liberu\JetstreamBridge\JetstreamBridgeServiceProvider"
  1. Read the service provider first. It's the contract. Look for container bindings / static registrations such as:
// src/JetstreamBridgeServiceProvider.php
$this->app->bind(CreatesNewUsers::class, LiberuCreateNewUser::class);
Jetstream::useUserModel(config('jetstream-bridge.models.user'));

Whatever it binds tells you the extension points. Open src/Actions (or src/Adapters) next — those classes are what you'll subclass when identity rules differ.

  1. Cross-check your configs. Open config/fortify.php and confirm 'actions' => [...] points at the bridge's classes rather than the generated App\Actions\Fortify\* defaults. If the package publishes config/jetstream-bridge.php, check the features, model, and stack keys match what your app already uses (Livewire vs. Inertia changes nothing here, but two_factor_authentication does).

  2. First real use case: registration. Hit /register and confirm a row lands in the identity table(s) with the expected fields (and that any Liberu-side profile/identity records are created in the same transaction). That single flow exercises the adapter, the model binding, and the event wiring — if it works, the rest usually does.

  3. Smoke-test the four core actions before writing any product code: register, update profile, change password, reset password. These are the flows the bridge exists for; everything else is a variation.

Implementation Patterns

Pattern: extend, don't fork. When identity rules diverge (extra fields, tenant assignment, invitation acceptance), subclass the bridge action and re-bind in your own provider. You keep upstream fixes and only own the delta.

namespace App\Auth;

use Liberu\Identity\Actions\CreateNewUser as BaseAction;

class CreateNewUser extends BaseAction
{
    protected function afterCreate($user, array $input): void
    {
        parent::afterCreate($user, $input);

        if ($invite = Invite::findByCode($input['invite_code'] ?? null)) {
            $invite->accept($user);
        }
    }
}

Then rebind in FortifyServiceProvider (or your app provider) so the container resolves your class wherever the bridge bound the base one.

Pattern: keep Fortify config as the single switchboard. Because Fortify reads actions from config and caches it, treat config/fortify.php as the registration point and the bridge as the implementation. One place to look when "the wrong class ran."

'actions' => [
    \App\Auth\CreateNewUser::class      => \Laravel\Fortify\Contracts\CreatesNewUsers::class,
    \Liberu\Identity\Actions\UpdateUserPassword::class => \Laravel\Fortify\Contracts\UpdatesUserPasswords::class,
],

Pattern: profile updates through the identity service, not $user->update(). The bridge's profile action should be your canonical write path — it handles any sync to identity/profile tables. If you're writing a controller or Livewire action that updates a user, route it through the same adapter so you don't get drift between users and identity records.

Pattern: test the adapter, not the UI. Adapter classes have narrow contracts, which makes them easy to test directly without Livewire/Inertia overhead:

public function test_bridge_creates_identity_record()
{
    $user = app(CreatesNewUsers::class)->create([
        'name' => 'A', 'email' => '[email protected]',
        'password' => 'password', 'password_confirmation' => 'password',
    ]);

    $this->assertDatabaseHas('identities', ['user_id' => $user->id]);
    Event::assertDispatched(Registered::class);
}

Pattern: teams / multi-tenant flows. If you're on Jetstream teams, verify the bridge's create-user path runs before team attachment (Jetstream's AddTeamMember listener on the Registered event does the attaching). If the bridge creates the identity synchronously inside create(), order is fine; if it queues a job, you'll need a listener that waits or a ->afterCommit() arrangement.

Pattern: 2FA. Fortify's 2FA actions expect specific columns (two_factor_secret, two_factor_recovery_codes, two_factor_confirmed_at) and a HasTwoFactorAuthentication-style trait. If the bridge points Jetstream at a Liberu user model, check that trait and those columns exist on that model — otherwise enabling 2FA silently no-ops.

Integration tip: pair with laravel/ui-free flows. If you're API-first, the same adapters work behind Sanctum — you lose the Jetstream views but keep the action contracts, which is often the real reason to adopt a bridge like this.

Gotchas and Tips

  • Config caching bites. config('fortify.actions') is read at boot. After changing action bindings, run php artisan config:clear (and optimize:clear in staging). Symptom: "my subclass isn't used" 90% of the time.
  • Two sources of truth for the user model. Jetstream's Jetstream::useUserModel() and the bridge's own model config can disagree, and the resulting bug is confusing (relationships resolve on one class, actions hydrate another). Pick one, and assert it in a test: $this->assertSame(config('jetstream-bridge.models.user'), Jetstream::$userModel) after the provider boots.
  • Event/listener mismatches. Jetstream ships listeners for Registered, Login, Logout, PasswordReset. If the bridge's action dispatches a Liberu event instead of Laravel's Illuminate\Auth\Events\Registered, Jetstream's team-attachment and SendEmailVerificationNotification behavior quietly stops. Grep for event( / dispatch( in the adapter and confirm the canonical Laravel events still fire.
  • Password validation rules. Fortify's Password::defaults() is configured in your FortifyServiceProvider. Bridge actions that validate independently can bypass it. Keep the rule definition in one place and reference it from both sides.
  • Transaction boundaries. If the bridge writes to users and an identity table in separate calls, a mid-flight exception (validation, mail failure, third-party identity API) leaves orphan rows. Prefer wrapping adapter calls in DB::transaction() at the call site if the package doesn't.
  • Debugging technique: app()->bound() / app()->make() in tinker. When an action "isn't doing what the docs say," resolve the contract from the container and dd(get_class(...)) — you'll immediately see whether the bridge or the default got bound, and whether a stray provider re-bound it later.
  • Zero stars means read the source. There's no community knowledge base here. Budget an hour to read the service provider plus the action classes end-to-end before depending on it in production; the description is broad and the actual surface is likely narrower than "Fortify-compatible."
  • Version pinning. Last release is dated 2026-10-27 and dependents are zero, so there's little downstream validation. Pin an exact version in composer.json and add a smoke test on your four core flows so a future release can't break auth silently.
  • Extension points, ranked: (1) subclass the action and rebind via config, (2) Fortify::authenticateUsing() for custom credential logic, (3) publish and override the bridge's config, (4) macro/event hooks. Reaching for (4) before (1) is usually a mistake — you'll be reimplementing what the adapter already does.
  • Don't mix with the default Jetstream install. If you ran jetstream:install and have app/Actions/Fortify/*, decide explicitly which set wins. Half-swapped actions (e.g. bridge's CreateNewUser + default's UpdateUserPassword) is the most common source of "password changes but profile doesn't sync" reports.
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings