Better Auth Audit Logs Plugin
This package, `better-auth-audit-logs`, provides a plug-in for the `better-auth` authentication library, designed to automatically capture and store authentication lifecycle events. It is currently at version 0.3.0 and appears to have a fairly active release cadence, with several minor versions released recently. Key features include automatic logging of auth events (like sign-in, sign-up, password changes) with associated metadata such as IP address and user agent, support for custom storage backends (Prisma, Drizzle, MongoDB examples are provided), and PII redaction capabilities. It differentiates itself by offering a zero-config setup for automatic event capture when integrated with `better-auth`, and exposing query endpoints for retrieving logs, including the ability to insert custom audit entries for non-auth related administrative actions. It relies on `better-auth` for its core functionality and `zod` for schema validation.
Common errors
-
Error: Cannot find module 'better-auth-audit-logs/client'
cause Incorrect import path for the client-side plugin, or missing package installation.fixEnsure `better-auth-audit-logs` is installed and the client plugin is imported as `import { auditLogClient } from 'better-auth-audit-logs/client';`. -
Error: 'auditLog' table not found or column missing in database.
cause Database migrations for the audit log schema have not been generated or applied.fixRun `npx @better-auth/cli generate` to create the migration files, then apply them using your ORM's migration command (e.g., `npx prisma migrate dev`). -
TypeError: Cannot read properties of undefined (reading 'auditLog') on authClient
cause The `auditLogClient()` plugin was not correctly registered with `createAuthClient`.fixEnsure `auditLogClient()` is included in the `plugins` array when calling `createAuthClient({ plugins: [auditLogClient()] })`. -
ZodError: Validation failed: Expected string, received undefined at 'action'
cause When manually inserting an audit log, a required field (like `action`, `status`, `severity`) was omitted or provided with an incorrect type.fixReview the `insertAuditLog` call and ensure all required fields are present and conform to the expected schema (e.g., `action: 'some-action'`, `status: 'success'`, `severity: 'low'`).
Warnings
- breaking The default `modelName` for the audit log table changed from `audit_log` to `auditLog` to improve compatibility with Prisma adapters.
- gotcha Requires `better-auth >= 1.0.0` and `typescript >= 5`. Older versions of `better-auth` are not compatible and will likely lead to runtime errors due to API mismatches.
- gotcha The audit log plugin adds an `auditLog` table to your database. You must run `npx @better-auth/cli generate` after installing to create the necessary migrations for your database adapter.
- gotcha The client-side `auditLogClient` plugin must be imported from `better-auth-audit-logs/client`.
Install
-
npm install better-auth-audit-logs -
yarn add better-auth-audit-logs -
pnpm add better-auth-audit-logs
Imports
- auditLog
const { auditLog } = require('better-auth-audit-logs');import { auditLog } from 'better-auth-audit-logs'; - auditLogClient
import { auditLogClient } from 'better-auth-audit-logs';import { auditLogClient } from 'better-auth-audit-logs/client'; - AuditLogSchema
import type { AuditLogSchema } from 'better-auth-audit-logs';
Quickstart
import { betterAuth } from 'better-auth';
import { auditLog } from 'better-auth-audit-logs';
// Initialize Better Auth with the audit log plugin
export const auth = betterAuth({
plugins: [auditLog()],
// Assuming other Better Auth configurations here, e.g., adapters
// adapter: someAdapter(...),
});
// In a separate script or CLI for database migrations:
// Make sure to have `@better-auth/cli` installed.
// Run `npx @better-auth/cli generate`
// This command will generate database migrations for the `auditLog` table.
// Subsequently, run your database migration command (e.g., `npx prisma migrate dev` for Prisma).
// Example of client-side usage (e.g., in a React component or API handler)
import { createAuthClient } from 'better-auth/client';
import { auditLogClient } from 'better-auth-audit-logs/client';
const authClient = createAuthClient({
plugins: [auditLogClient()],
});
async function fetchAuditLogs() {
try {
const { data } = await authClient.auditLog.listAuditLogs({
query: { status: 'failed', limit: 5, action: 'sign-in:email' },
});
console.log('Recent failed sign-ins:', data);
await authClient.auditLog.insertAuditLog({
action: 'admin:user-delete',
status: 'success',
severity: 'high',
metadata: { deletedUserId: 'user-xyz', adminId: 'admin-abc' },
});
console.log('Manually logged an admin action.');
} catch (error) {
console.error('Error fetching or inserting audit logs:', error);
}
}
// Call the function, typically triggered by a user action or on mount
// fetchAuditLogs();