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

Sessions Devices Filament Laravel Package

liberusoftware/sessions-devices-filament

Filament panel integration for Liberu's sessions and devices package. Adds admin resources to view and revoke active user sessions, inspect logged-in devices, and manage session security from your Filament dashboard, giving Laravel apps a complete session management UI.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the module (this is a Filament plugin, so it belongs alongside your panel provider, not in app/Providers directly):

    composer require liberusoftware/sessions-devices-filament
    
  2. Register the plugin in your panel provider (app/Providers/Filament/AdminPanelProvider.php):

    use Liberu\SessionsDevicesFilament\SessionsDevicesPlugin;
    
    public function panel(Panel $panel): Panel
    {
        return $panel
            // ...
            ->plugin(SessionsDevicesPlugin::make());
    }
    
  3. Publish and run migrations if the module ships its own device/session table (check with php artisan vendor:publish --tag=...; the namespace is typically sessions-devices-filament-config / -migrations). Laravel's own sessions table is usually enough, but device metadata may need its own column or table.

  4. Where to look first

    • src/SessionsDevicesPlugin.php (or similarly named plugin class) — this is the entry point and shows you which resources/pages/widgets get registered.
    • src/Filament/Resources/ — the session and device resources, including their tables, forms, and actions.
    • config/sessions-devices.php (if present) — guard selection, table names, and whether session revocation is enabled.
    • The README.md for any panel-specific registration snippet, since Liberu foundation modules often assume a User model with a specific contract.
  5. First use case: log in as an admin, open the Sessions (or Devices) resource in your panel, and confirm you see the current session for your user. Revoke a session from the row action and refresh the browser on that session's device to verify it works. That single loop — list → inspect → revoke — is the 80% workflow this package exists to support.

Implementation Patterns

Panel-scoped registration. Register the plugin only on the panels that should expose session management. Admin panels get it; tenant-facing panels usually should not. Keeping it off the customer panel is both a security and UX decision.

->plugin(SessionsDevicesPlugin::make())
->plugins([
    // other plugins
])

Per-user device management via relation managers. The most useful integration is attaching a DevicesRelationManager (or the package's equivalent) to your UserResource. This lets support staff open a user record and revoke a suspicious device without leaving the resource:

public static function getRelations(): array
{
    return [
        DevicesRelationManager::class,
    ];
}

Guard awareness. Sessions are per-guard. If you run web and admin guards, confirm the resource filters on the correct guard. Most implementations read config('auth.defaults.guard'); override it via the plugin's fluent API or config if you need the admin guard:

SessionsDevicesPlugin::make()
    ->guard('admin')

Revocation as an action, not a delete. The pattern that works well is a Filament Action on the table row that calls Auth::guard($guard)->logoutUsingId($sessionId) or deletes the session row directly. Wrap it in a confirmation modal and a ->requiresConfirmation() so nobody fat-fingers a logout for a user mid-transaction.

Bulk "log out everywhere". Add a header action to the resource that iterates all sessions for the current user (or a selected user) and invalidates them. This is the pattern support teams ask for most often — pair it with a Notification so the operator sees the count revoked.

Integration with login events. If the package provides a device-tracking listener, ensure App\Listeners\RecordDeviceOnLogin (or the package's listener) is registered against Illuminate\Auth\Events\Login. This is what populates the device table so the Filament view has something useful to show. If the package does not ship it, you write it:

Event::listen(Login::class, function (Login $event) {
    $event->user->devices()->updateOrCreate(
        ['fingerprint' => hash('sha256', request()->userAgent().request()->ip())],
        ['user_agent' => request()->userAgent(), 'ip' => request()->ip(), 'last_seen_at' => now()],
    );
});

Tenant scoping (Filament multi-tenancy). If you use Filament's tenancy, override getEloquentQuery() in the resource to scope sessions to Filament::getTenant(). Without this, an admin in one tenant can see another tenant's sessions — a real vulnerability in multi-tenant setups.

Testing pattern. Use RefreshDatabase, log a user in with actingAs, then hit the resource's index route and assert the session row appears. For revocation tests, use $this->assertGuest() after firing the action via Livewire::test.

Gotchas and Tips

Session driver must be database (or Redis with a compatible store). The resource reads from config('session.driver'). If your app uses file or cookie sessions, the table is empty and the resource silently shows nothing. Check config/session.php before debugging the package.

Filament v3 vs v4 API drift. Liberu foundation modules are frequently pinned to a specific Filament major. If you see Method Filament\Panel::plugin does not exist or missing Action classes, you're on the wrong Filament version. Check composer.json of the package for the filament/filament constraint before upgrading your panel.

Stale session rows. Laravel's sessions table is only cleaned up by the session:prune / GC job. In practice the resource will show dead sessions that have already expired. Filter last_activity in the resource query (e.g. ->where('last_activity', '>=', now()->subMinutes(config('session.lifetime'))->timestamp)) so operators don't try to revoke sessions that no longer exist.

User-agent parsing is fuzzy. Device labels ("Chrome on macOS") are derived from the UA string and will misreport bots, curl requests, and some privacy browsers. Treat the label as a hint, not a guarantee. The ip column is the more reliable signal for "is this me?" — but remember it's behind proxies; use TrustProxies middleware if IPs look wrong.

Guard mismatch when revoking. A common bug: the resource reads from the web guard but you're logged in as an admin user, so the revocation action targets the wrong session store. Confirm the guard is threaded through both the resource query and the action closure. The plugin usually exposes ->guard(...); if not, override the resource.

Authorization is your responsibility. The default policy is often permissive. Add a SessionPolicy (or gate) so only users with manage-sessions permission can revoke other users' sessions. Otherwise any panel user can log out the whole team — see the "bulk logout" pattern above going wrong.

Config caching. If you publish config, php artisan config:clear after edits, and remember config:cache in production will freeze the guard setting. Changing ->guard('admin') in the panel provider is safer than relying on config.

Extending rather than forking. The cleanest customization path is to subclass the resource (extends SessionResource) and override table(), getEloquentQuery(), or the revoke() action, then register your subclass in the panel. Forking the package for one column is a maintenance trap — Liberu modules are small and evolve.

Debugging empty tables. If the page loads but shows no rows: (1) check the session driver, (2) check you actually have an active session (log in in a second browser), (3) php artisan tinker → DB::table('sessions')->count(), (4) confirm the resource's getEloquentQuery() isn't scoped to a tenant you're not in. That order resolves almost every "it's broken" report.

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.
jinas/dhivatar
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