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

Filament Breezy Laravel Package

jeffgreco13/filament-breezy

Enhanced security for Filament v4 panels. Adds a customizable profile page with avatar, password updates, two-factor authentication with recovery codes, passkeys, Sanctum token management, and active browser session controls. Installs in minutes.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire it up (5 minutes):

composer require jeffgreco13/filament-breezy
php artisan breezy:install

Register the plugin on the panel you want secured:

use Jeffgreco13\FilamentBreezy\BreezyCore;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            BreezyCore::make()->myProfile(),
        ]);
}

Then make the styles actually work — this is the step people skip and then file "the plugin looks broken" issues. In your custom theme (resources/css/filament/admin/theme.css):

@source '../../../../vendor/jeffgreco13/filament-breezy/resources/**/*';

Rebuild assets (npm run build) and clear caches.

Where to look first:

  • vendor/jeffgreco13/filament-breezy/src/BreezyCore.php — the entire public API is one fluent class. Read it top to bottom; it's the real documentation. Every myProfile*, enable*, password* method you can call is there.
  • vendor/jeffgreco13/filament-breezy/src/Livewire/ — the My Profile components (PersonalInfo, UpdatePassword, TwoFactorAuthentication, SanctumTokens, BrowserSessions, passkeys). These are your extension points.
  • vendor/jeffgreco13/filament-breezy/src/Actions/ — password-confirmation action used to gate sensitive operations.
  • The breezy:install command output — check what it published (config/migrations) rather than assuming.

First real use case: turn on the My Profile page for a v4 admin panel, verify /admin/my-profile renders with personal info + update password, then add Jeffgreco13\FilamentBreezy\Traits\TwoFactorAuthenticatable to your User model and call ->enableTwoFactorAuthentication() on the plugin. That single trait + flag gets you TOTP with recovery codes, and is usually the whole reason a team reaches for this package.

Implementation Patterns

Configure per panel, not globally. BreezyCore::make() returns a fresh instance, so an admin panel and a customer panel can have different profile slugs, different 2FA enforcement, and different guards:

->authGuard('customers') // must be a guard whose model extends Authenticatable
->plugin(
    BreezyCore::make()
        ->myProfile(
            shouldRegisterUserMenu: true,
            userMenuLabel: 'Account',
            shouldRegisterNavigation: false,
            navigationGroup: 'Settings',
            hasAvatars: true,
            slug: 'account',
        )
        ->passwordUpdateRules(
            rules: [Password::default()->mixedCase()->uncompromised(3)],
            requiresCurrentPassword: true,
        )
        ->enableTwoFactorAuthentication(force: true, scopeToPanel: true)
)

Trim the profile page instead of rebuilding it. Most teams don't want all five cards. Use withoutMyProfileComponents(['update_password', 'sanctum_tokens']) to remove what you don't need, and myProfileComponents([...]) to append or override by key:

->myProfileComponents([
    'update_password' => MyCustomPassword::class, // override by key
    MyCustomComponent::class,                    // append
])

Key-based override is the cheapest customization path — you inherit all the behavior, override one method, done.

Custom profile card (the standard extension pattern). Extend MyProfileComponent, declare public array $only to whitelist the columns you save, and use statePath('data') — the base class expects that shape:

class JobTitle extends MyProfileComponent
{
    protected string $view = 'livewire.job-title';
    public array $only = ['job_title'];
    public array $data;

    public function mount(): void
    {
        $this->user = Filament::getCurrentPanel()->auth()->user();
        $this->form->fill($this->user->only($this->only));
    }

    public function form(Schema $schema): Schema
    {
        return $schema->components([
            TextInput::make('job_title')->required(),
        ])->statePath('data');
    }

    public function submit(): void
    {
        $this->user->update(collect($this->form->getState())->only($this->only)->all());
        Notification::make()->success()->title('Saved')->send();
    }
}

Use <x-filament::section> in the Blade view so it visually matches the surrounding cards without custom CSS.

Partial override beats full rewrite. For PersonalInfo, extend the class and override getProfileFormComponents() / sendNotification() rather than reimplementing the component. Keep $this->getCurrentPasswordComponent() in the returned array — it's what forces re-authentication when the email changes.

Order your cards with the static sorter, from any service provider:

TwoFactorAuthentication::setSort(4);

Defaults are spaced by 10, so custom components slot in between without collisions.

Force 2FA as an onboarding gate. enableTwoFactorAuthentication(force: true) pushes users to the 2FA setup page via the MustTwoFactor middleware before they can reach anything else. If you have multiple panels and want 2FA enrolled once, set scopeToPanel: false; if each panel is its own security boundary, leave it true.

Gate destructive actions with the password-confirmation action. Any "delete account", "revoke all tokens", or "log out other sessions" style button should require a fresh password. Breezy ships an action for this (see src/Actions/), and the same ConfirmPassword pattern is reusable inside your own resources:

Action::make('deleteAccount')
    ->requiresConfirmation()
    ->action(fn () => $this->user->delete())
    ->form(fn () => [$this->getPasswordConfirmationField()]);

Wire it through Filament's password-confirmation middleware (password.confirm) so the session flag is honored for a window rather than on every click.

Sanctum tokens & browser sessions are opt-in value. Add HasApiTokens to your model to make the token card useful; the token is shown once at creation, so build whatever copy/one-time reveal UX you need around it. Browser sessions are a strong fit for "someone logged in from an unknown device" support tickets — logging out other sessions is a one-click support resolution.

Gotchas and Tips

  • Missing Tailwind @source = unstyled plugin. This is the #1 install failure on Filament v4. Add the @source line, rebuild, and hard-refresh before debugging anything else.
  • avatar_url is not created for you. No migration ships for it. Add the column, add it to $fillable, and implement HasAvatar::getFilamentAvatarUrl(). Without the interface the upload saves but nothing renders.
  • Email changes require the current password — by design. If you override getProfileFormComponents() and drop getCurrentPasswordComponent(), you silently remove the account-takeover protection. Keep it.
  • 2FA fails loudly if the trait is missing. TwoFactorAuthenticatable must be on the model behind the panel's guard. If you use a custom guard, verify the guarded model extends Authenticatable and implements FilamentUser — the package doesn't validate this for you.
  • scopeToPanel is a policy decision, not a default. true means users can end up with separate 2FA state per panel — usually surprising. Pick deliberately and document it.
  • Custom MyProfileComponent must set statePath('data') and $only. Forgetting either gives you either empty forms or mass-assignment of fields you didn't intend to expose.
  • Passkeys need a secure context. HTTPS (or localhost), correct APP_URL, and an up-to-date browser. Passkey enrollment failures in local dev are almost always the origin/APP_URL mismatch, not the package.
  • Don't edit vendor. Publish views (--tag="filament-breezy-views") only when you truly need markup changes; published views become yours to maintain and will silently drift from upstream. Prefer myProfileComponents() overrides and class extension. If you do publish, diff against vendor views after every upgrade.
  • Browser sessions depend on your session driver/config. If you're on a non-database session driver, the "other sessions" listing has less to work with — test it on the actual production driver, not just local.
  • Debugging blank/broken profile cards: check Livewire component resolution, then php artisan view:clear / optimize:clear, then look for an exception in storage/logs/laravel.log — Livewire swallows render errors on the profile page more often than you'd expect.
  • Testing: use actingAs($user) and, for password-confirmed actions, hit the confirmation endpoint or session()->put('auth.password_confirmed_at', time()) rather than asserting the modal UI. Testing forced 2FA means asserting the redirect to the 2FA route, not just the component state.
  • Package vs. repo naming: the composer name is jeffgreco13/filament-breezy while the linked repo reads Jacobtims/filament-breezy — a fork/transfer situation. Pin a version in composer.json and read the changelog before bumping; for a security-adjacent package you don't want silent minor upgrades.
  • Overall: high leverage for the effort — one plugin replaces a hand-rolled profile page, password update, 2FA, Sanctum token UI, and session management. Its weak points are all on the "configuration you must remember to do" axis (Tailwind source, avatar column, trait, guard), not in the code itself. Budget an hour for setup plus a proper security pass, and it pays for itself immediately.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle