tapp/nova-authentication-log
Logs authentication activity in Laravel Nova—sign-ins, logouts, failed attempts, and password resets—so you can review user access and security events from a dedicated Nova resource.
Start by treating this as an internal admin surface, not a security product. It is a thin Nova tool that renders authentication events (logins, failed logins, logouts, maybe password changes) for your users. With zero dependents and a single 2023 release, assume the README is incomplete and the source is the documentation.
Minimal setup:
composer require tapp/nova-authentication-log
php artisan vendor:publish --provider="Tapp\NovaAuthenticationLog\ToolServiceProvider"
php artisan migrate
Then register the tool in app/Providers/NovaServiceProvider.php:
public function tools()
{
return [
new \Tapp\NovaAuthenticationLog\NovaAuthenticationLog,
];
}
Where to look first, in this order:
vendor/tapp/nova-authentication-log/src/ — find the tool class, any Nova/*.php resources, and the service provider. The provider tells you what it publishes, what migrations it loads, and whether it registers routes.database/migrations/ inside the package — the table name and columns dictate everything else you'll do (indexes, pruning, joins to users).config/ file after publishing — retention, guards, user_model.routes/ — some Nova tools register their own endpoints; check before you assume it's purely resource-driven.First use case to validate: open the tool in Nova and confirm you see your own most recent login at the top of the list. If the list is empty after you've logged in, the event listener isn't wired up (check EventServiceProvider / the package's listener registration) or the table name doesn't match what the model expects. This one smoke test catches the vast majority of misinstallations.
Per-user history on the User resource. The highest-value integration is usually not the standalone tool page but a HasMany relationship surfaced as a Nova panel on the user detail screen. If the package ships a model (e.g. AuthenticationLog), attach:
// app/Nova/User.php
public function fields(Request $request)
{
return [
// ...
HasMany::make('Authentication Logs', 'authenticationLogs', AuthenticationLog::class),
];
}
If the package doesn't ship a Nova resource, write a small read-only one yourself over its model — Create and Update should be disabled (public static $canCreate = false;), since these rows are append-only by nature.
Gating visibility. Nova tools are visible to every authenticated Nova user unless you intervene. Add a canSee check so support staff don't get raw IP addresses:
public function boot()
{
Nova::script('nova-authentication-log', __DIR__.'/../dist/js/tool.js');
Gate::define('viewAuthenticationLog', fn ($user) => $user->hasRole('admin'));
}
Then override canSee() on the tool class (or wrap the registration in an if) to consult that gate.
Failed-login triage workflow. The day-to-day payoff is a "suspicious activity" view: filter the list to failed attempts in the last 24 hours, group by IP. If the tool's UI doesn't expose filters, add Nova filters backed by the same table — a DateFilter plus a SelectFilter on event type is roughly ten lines and turns the tool from a log viewer into an actual workflow.
Retention as a scheduled job. Authentication logs grow fast on any site with a login form. Assume the package does not prune for you:
// app/Console/Kernel.php
$schedule->call(function () {
DB::table('authentication_logs')
->where('created_at', '<', now()->subDays(90))
->delete();
})->daily();
Make the window a config value, not a literal — compliance teams will ask.
Pair with notifications for real-time response. The Nova tool is pull-based; nobody watches it. Consume the same events in a listener and post to Slack on N failed attempts from one IP within 10 minutes. The package's table is then your audit trail for what the alert was about.
Multi-guard awareness. If you have separate admin and web guards, verify the package records a guard/login_type column. If it doesn't, you'll be unable to distinguish an admin login from a customer login in the UI, which severely limits the tool's usefulness.
Nova 5 compatibility is the biggest risk. Last release was May 2023, which lands in the Nova 4.x era. Nova 5 changed asset registration and tool bootstrapping. Test in a throwaway Nova 5 install before committing; if it breaks, the fix is usually a small composer.json constraint bump plus Nova::script() argument changes — patch it in a fork rather than waiting for upstream.
Table name collisions. If you already use yadahan/laravel-authentication-log or rappasoft/laravel-authentication-log, this package may attempt to create a table with the same or confusingly similar name. Read the migration before running php artisan migrate on production. A duplicate schema with different column semantics is a genuinely painful cleanup.
Do not treat it as tamper-evident. Rows live in your normal database, writable by your app, and the package almost certainly has no hash-chaining or append-only enforcement. For actual security/compliance requirements, ship the logs to an external sink (CloudWatch, S3 with object lock) rather than relying on this table.
IP addresses behind a load balancer. If the package reads request()->ip(), every row will say 10.0.0.x until you configure TrustProxies with your ALB/Cloudflare ranges. Verify by comparing a row against a known real IP before you build any "geo-block this IP" workflow on top of it.
User agent parsing is a hidden dependency. Many of these tools pull in jenssegers/agent or whichbrowser/parser to render "Chrome on macOS." If the browser column is blank, that transitive dependency is missing or the UA is unparseable. Don't treat a blank browser as evidence of a bot.
Indexes matter more than you think. After a few million rows, the default "sort by created_at desc" list view will crawl. Add a composite index on (user_id, created_at) and (created_at) if the migration doesn't. This is the single most common post-rollout complaint.
Deleting users orphans the log. Check the foreign key behavior. You generally want logs to survive user deletion (that's the point of an audit log), so nullOnDelete on user_id plus a stored email snapshot column is the correct design — verify the package does this, and if it doesn't, don't hard-delete users.
No docs means read the tests. If tests/ exists in the package, it's a better specification than the README. If there are no tests either (likely for a 0-star package), pin the exact version in composer.json and budget an hour to read every source file before you depend on it. Given the release cadence, be prepared to vendor or fork it.
Extension point to prefer: wrap, don't modify. Register your own Nova resource over the package's model and hide the vendor tool entirely if the UI doesn't fit. That way a composer update can't break your admin surface.
How can I help you explore Laravel packages today?