better-auth-audit-logs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +366 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/memory.d.ts +9 -0
- package/dist/adapters/memory.d.ts.map +1 -0
- package/dist/client.cjs +53 -0
- package/dist/client.d.ts +11 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +13 -0
- package/dist/endpoints/get-log.d.ts +28 -0
- package/dist/endpoints/get-log.d.ts.map +1 -0
- package/dist/endpoints/index.d.ts +4 -0
- package/dist/endpoints/index.d.ts.map +1 -0
- package/dist/endpoints/insert-log.d.ts +45 -0
- package/dist/endpoints/insert-log.d.ts.map +1 -0
- package/dist/endpoints/list-logs.d.ts +41 -0
- package/dist/endpoints/list-logs.d.ts.map +1 -0
- package/dist/hooks/after.d.ts +7 -0
- package/dist/hooks/after.d.ts.map +1 -0
- package/dist/hooks/before.d.ts +8 -0
- package/dist/hooks/before.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/index.cjs +564 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +522 -0
- package/dist/internal.d.ts +16 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/plugin.d.ts +181 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/schema.d.ts +109 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/types.d.ts +88 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/normalize-path.d.ts +2 -0
- package/dist/utils/normalize-path.d.ts.map +1 -0
- package/dist/utils/request-meta.d.ts +6 -0
- package/dist/utils/request-meta.d.ts.map +1 -0
- package/dist/utils/sanitize.d.ts +4 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/severity.d.ts +3 -0
- package/dist/utils/severity.d.ts.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# better-auth-audit-logs
|
|
2
|
+
|
|
3
|
+
Audit log plugin for [Better Auth](https://better-auth.com). Captures auth lifecycle events, stores structured log entries with IP and user agent, and exposes query endpoints — with PII redaction, custom storage backends, and a manual insertion escape hatch.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- `better-auth >= 1.0.0`
|
|
8
|
+
- `typescript >= 5.0`
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# npm
|
|
14
|
+
npm install better-auth-audit-logs
|
|
15
|
+
|
|
16
|
+
# pnpm
|
|
17
|
+
pnpm add better-auth-audit-logs
|
|
18
|
+
|
|
19
|
+
# yarn
|
|
20
|
+
yarn add better-auth-audit-logs
|
|
21
|
+
|
|
22
|
+
# bun
|
|
23
|
+
bun add better-auth-audit-logs
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
### 1. Add the plugin to your auth config
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { betterAuth } from "better-auth";
|
|
32
|
+
import { auditLog } from "better-auth-audit-logs";
|
|
33
|
+
|
|
34
|
+
export const auth = betterAuth({
|
|
35
|
+
// ...
|
|
36
|
+
plugins: [auditLog()],
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Generate and run the migration
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx @better-auth/cli generate
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This adds an `audit_log` table to your database. All columns are indexed for efficient querying.
|
|
47
|
+
|
|
48
|
+
### 3. Add the client plugin (optional)
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createAuthClient } from "better-auth/client";
|
|
52
|
+
import { auditLogClient } from "better-auth-audit-logs/client";
|
|
53
|
+
|
|
54
|
+
export const authClient = createAuthClient({
|
|
55
|
+
plugins: [auditLogClient()],
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## What gets logged
|
|
60
|
+
|
|
61
|
+
All auth `POST` endpoints are captured by default. Destructive events (where session data would be lost after execution) use a `before` hook — all others use `after`.
|
|
62
|
+
|
|
63
|
+
| Event | Path | Notes |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| Sign in | `/sign-in/email`, `/sign-in/social` | `userId` is `null` on failed attempts |
|
|
66
|
+
| Sign up | `/sign-up/email` | |
|
|
67
|
+
| Change password | `/change-password` | |
|
|
68
|
+
| Reset password | `/reset-password` | |
|
|
69
|
+
| Change email | `/change-email` | |
|
|
70
|
+
| Two-factor | `/two-factor/*` | |
|
|
71
|
+
| OAuth callback | `/oauth/callback` | |
|
|
72
|
+
| Sign out | `/sign-out` | Logged **before** session is destroyed |
|
|
73
|
+
| Delete account | `/delete-user` | Logged **before** session is destroyed |
|
|
74
|
+
| Revoke session | `/revoke-session`, `/revoke-sessions`, `/revoke-other-sessions` | Logged **before** session is destroyed |
|
|
75
|
+
|
|
76
|
+
Severity is inferred automatically:
|
|
77
|
+
|
|
78
|
+
| Pattern | Severity |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `ban-user`, `impersonate-user` | `critical` |
|
|
81
|
+
| `delete-user`, `revoke-sessions` | `high` |
|
|
82
|
+
| Failed sign-in | `high` |
|
|
83
|
+
| `sign-in`, `sign-out`, `two-factor` | `medium` |
|
|
84
|
+
| Everything else | `low` |
|
|
85
|
+
|
|
86
|
+
Override severity per-path via the `paths` option.
|
|
87
|
+
|
|
88
|
+
## Configuration
|
|
89
|
+
|
|
90
|
+
All options are optional — defaults are listed below.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
auditLog({
|
|
94
|
+
enabled: true,
|
|
95
|
+
nonBlocking: false,
|
|
96
|
+
paths: [], // empty = capture all POST paths
|
|
97
|
+
piiRedaction: {
|
|
98
|
+
enabled: false,
|
|
99
|
+
strategy: "mask", // "mask" | "hash" | "remove"
|
|
100
|
+
fields: [], // see default field list below
|
|
101
|
+
},
|
|
102
|
+
capture: {
|
|
103
|
+
ipAddress: true,
|
|
104
|
+
userAgent: true,
|
|
105
|
+
requestBody: false,
|
|
106
|
+
},
|
|
107
|
+
retention: undefined, // no automatic cleanup by default
|
|
108
|
+
beforeLog: undefined,
|
|
109
|
+
afterLog: undefined,
|
|
110
|
+
storage: undefined, // uses Better Auth's database by default
|
|
111
|
+
schema: undefined,
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Options reference
|
|
116
|
+
|
|
117
|
+
| Option | Type | Default | Description |
|
|
118
|
+
|---|---|---|---|
|
|
119
|
+
| `enabled` | `boolean` | `true` | Set to `false` to disable all logging without removing the plugin |
|
|
120
|
+
| `nonBlocking` | `boolean` | `false` | Fire-and-forget — log writes never block the auth response |
|
|
121
|
+
| `paths` | `(string \| PathConfig)[]` | `[]` | Restrict logging to specific paths. Empty captures all |
|
|
122
|
+
| `piiRedaction.enabled` | `boolean` | `false` | Redact sensitive fields from request body snapshots |
|
|
123
|
+
| `piiRedaction.strategy` | `"mask" \| "hash" \| "remove"` | `"mask"` | How to redact matched fields |
|
|
124
|
+
| `piiRedaction.fields` | `string[]` | see below | Fields to redact |
|
|
125
|
+
| `capture.ipAddress` | `boolean` | `true` | Capture client IP address |
|
|
126
|
+
| `capture.userAgent` | `boolean` | `true` | Capture `User-Agent` header |
|
|
127
|
+
| `capture.requestBody` | `boolean` | `false` | Include request body snapshot in `metadata` |
|
|
128
|
+
| `retention.enabled` | `boolean` | — | Enable scheduled cleanup |
|
|
129
|
+
| `retention.days` | `number` | — | Delete entries older than N days |
|
|
130
|
+
| `beforeLog` | `function` | — | Intercept entries before write. Return `null` to suppress |
|
|
131
|
+
| `afterLog` | `function` | — | Called after each successful write |
|
|
132
|
+
| `storage` | `AuditLogStorage` | — | Custom storage backend |
|
|
133
|
+
| `schema.auditLog.modelName` | `string` | `"audit_log"` | Override the DB table name |
|
|
134
|
+
| `schema.auditLog.fields` | `Record<string, string>` | — | Rename individual columns |
|
|
135
|
+
|
|
136
|
+
### Path-level config
|
|
137
|
+
|
|
138
|
+
Restrict and customise logging per endpoint:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
auditLog({
|
|
142
|
+
paths: [
|
|
143
|
+
"/sign-in/email",
|
|
144
|
+
"/sign-up/email",
|
|
145
|
+
{ path: "/change-password", config: { severity: "high" } },
|
|
146
|
+
{ path: "/delete-user", config: { capture: { requestBody: true } } },
|
|
147
|
+
],
|
|
148
|
+
})
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### PII redaction
|
|
152
|
+
|
|
153
|
+
When `requestBody` capture is enabled, sensitive fields are redacted before storage. Default fields:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
password, newPassword, token, secret, apiKey, refreshToken, accessToken, code, backupCode, otp
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
auditLog({
|
|
161
|
+
capture: { requestBody: true },
|
|
162
|
+
piiRedaction: {
|
|
163
|
+
enabled: true,
|
|
164
|
+
strategy: "hash", // SHA-256 via Web Crypto
|
|
165
|
+
fields: ["password", "ssn", "creditCard"],
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Strategies: `"mask"` replaces with `***`, `"hash"` replaces with a SHA-256 hex digest, `"remove"` deletes the key entirely.
|
|
171
|
+
|
|
172
|
+
### `beforeLog` / `afterLog`
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
auditLog({
|
|
176
|
+
// Drop entries or modify them before write
|
|
177
|
+
beforeLog: async (entry) => {
|
|
178
|
+
if (entry.userId === "service-account-id") return null;
|
|
179
|
+
return entry;
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
// Forward to an external system after write
|
|
183
|
+
afterLog: async (entry) => {
|
|
184
|
+
await analytics.track("auth.event", entry);
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Custom table name
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
auditLog({
|
|
193
|
+
schema: {
|
|
194
|
+
auditLog: {
|
|
195
|
+
modelName: "auth_events", // maps to auth_events table in DB
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Custom storage
|
|
202
|
+
|
|
203
|
+
Route log writes to any external backend by implementing `AuditLogStorage`:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { auditLog, type AuditLogStorage } from "better-auth-audit-logs";
|
|
207
|
+
|
|
208
|
+
const clickhouse: AuditLogStorage = {
|
|
209
|
+
async write(entry) {
|
|
210
|
+
await fetch("https://ch.example.com/insert", {
|
|
211
|
+
method: "POST",
|
|
212
|
+
body: JSON.stringify(entry),
|
|
213
|
+
});
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
// Optional — enables the built-in query endpoints to work
|
|
217
|
+
async read(options) {
|
|
218
|
+
const rows = await ch.query({ ...options });
|
|
219
|
+
return { entries: rows, total: rows.length };
|
|
220
|
+
},
|
|
221
|
+
async readById(id) {
|
|
222
|
+
return await ch.queryOne({ id });
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
auditLog({ storage: clickhouse })
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
When `storage` is set, the plugin does **not** write to the Better Auth database. The built-in query endpoints (`/audit-log/list`, `/audit-log/:id`) will only work if you implement the optional `read` and `readById` methods.
|
|
230
|
+
|
|
231
|
+
### MemoryStorage (testing)
|
|
232
|
+
|
|
233
|
+
An in-memory adapter included for unit tests:
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
import { betterAuth } from "better-auth";
|
|
237
|
+
import { auditLog, MemoryStorage } from "better-auth-audit-logs";
|
|
238
|
+
|
|
239
|
+
const storage = new MemoryStorage();
|
|
240
|
+
|
|
241
|
+
const auth = betterAuth({
|
|
242
|
+
plugins: [auditLog({ storage })],
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Assert captured entries in tests
|
|
246
|
+
expect(storage.entries).toHaveLength(1);
|
|
247
|
+
expect(storage.entries[0].action).toBe("sign-in:email");
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## API reference
|
|
251
|
+
|
|
252
|
+
Three endpoints are registered under `/audit-log/`. All require an active session.
|
|
253
|
+
|
|
254
|
+
| Endpoint | Method | Description |
|
|
255
|
+
|---|---|---|
|
|
256
|
+
| `/audit-log/list` | `GET` | Paginated entries for the authenticated user |
|
|
257
|
+
| `/audit-log/:id` | `GET` | Single entry by ID |
|
|
258
|
+
| `/audit-log/insert` | `POST` | Manually insert a custom event |
|
|
259
|
+
|
|
260
|
+
Rate limit: 60 requests / 60 seconds per user.
|
|
261
|
+
|
|
262
|
+
### Query parameters — `GET /audit-log/list`
|
|
263
|
+
|
|
264
|
+
| Parameter | Type | Default | Description |
|
|
265
|
+
|---|---|---|---|
|
|
266
|
+
| `userId` | `string` | session user | Filter by user ID |
|
|
267
|
+
| `action` | `string` | — | Exact match, e.g. `sign-in:email` |
|
|
268
|
+
| `status` | `"success" \| "failed"` | — | Filter by outcome |
|
|
269
|
+
| `from` | ISO date string | — | Entries on or after this date |
|
|
270
|
+
| `to` | ISO date string | — | Entries on or before this date |
|
|
271
|
+
| `limit` | `number` | `50` | Max results (1–500) |
|
|
272
|
+
| `offset` | `number` | `0` | Pagination offset |
|
|
273
|
+
|
|
274
|
+
### Manual insert — `POST /audit-log/insert`
|
|
275
|
+
|
|
276
|
+
Log events that originate outside the auth flow (e.g. admin actions, sensitive data exports):
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
await authClient.auditLog.insertAuditLog({
|
|
280
|
+
action: "admin:user-export",
|
|
281
|
+
status: "success",
|
|
282
|
+
severity: "high",
|
|
283
|
+
metadata: { exportedCount: 500, requestedBy: "admin@example.com" },
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Querying via client
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
// List recent failed sign-ins
|
|
291
|
+
const { data } = await authClient.auditLog.listAuditLogs({
|
|
292
|
+
query: { status: "failed", limit: 20 },
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Single entry
|
|
296
|
+
const { data: entry } = await authClient.auditLog.getAuditLog({
|
|
297
|
+
params: { id: "log-entry-id" },
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## TypeScript types
|
|
302
|
+
|
|
303
|
+
```ts
|
|
304
|
+
import type {
|
|
305
|
+
AuditLogEntry,
|
|
306
|
+
AuditLogStorage,
|
|
307
|
+
AuditLogOptions,
|
|
308
|
+
StorageReadOptions,
|
|
309
|
+
StorageReadResult,
|
|
310
|
+
} from "better-auth-audit-logs";
|
|
311
|
+
|
|
312
|
+
interface AuditLogEntry {
|
|
313
|
+
id: string;
|
|
314
|
+
userId: string | null; // null for failed pre-auth attempts
|
|
315
|
+
action: string; // e.g. "sign-in:email", "sign-out"
|
|
316
|
+
status: "success" | "failed";
|
|
317
|
+
severity: "low" | "medium" | "high" | "critical";
|
|
318
|
+
ipAddress: string | null;
|
|
319
|
+
userAgent: string | null; // excluded from API responses by default
|
|
320
|
+
metadata: Record<string, unknown>;
|
|
321
|
+
createdAt: Date;
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Database schema
|
|
326
|
+
|
|
327
|
+
| Column | Type | Notes |
|
|
328
|
+
|---|---|---|
|
|
329
|
+
| `id` | string | Primary key |
|
|
330
|
+
| `userId` | string \| null | FK → `user(id)`, `ON DELETE SET NULL` |
|
|
331
|
+
| `action` | string | Indexed |
|
|
332
|
+
| `status` | string | |
|
|
333
|
+
| `severity` | string | |
|
|
334
|
+
| `ipAddress` | string \| null | |
|
|
335
|
+
| `userAgent` | string \| null | Not returned in API responses |
|
|
336
|
+
| `metadata` | string | Stored as JSON |
|
|
337
|
+
| `createdAt` | date | Indexed |
|
|
338
|
+
|
|
339
|
+
Audit log entries survive user deletion (`ON DELETE SET NULL` on `userId`). This is intentional — deleting a user should not erase the audit trail.
|
|
340
|
+
|
|
341
|
+
## Production
|
|
342
|
+
|
|
343
|
+
Recommended config for production deployments:
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
auditLog({
|
|
347
|
+
nonBlocking: true, // never add latency to auth responses
|
|
348
|
+
piiRedaction: {
|
|
349
|
+
enabled: true,
|
|
350
|
+
strategy: "hash", // pseudonymise rather than mask
|
|
351
|
+
},
|
|
352
|
+
capture: {
|
|
353
|
+
requestBody: false, // only enable if you need body snapshots
|
|
354
|
+
},
|
|
355
|
+
retention: {
|
|
356
|
+
enabled: true,
|
|
357
|
+
days: 90, // comply with your data retention policy
|
|
358
|
+
},
|
|
359
|
+
afterLog: async (entry) => {
|
|
360
|
+
// Forward high-severity events to your alerting system
|
|
361
|
+
if (entry.severity === "critical" || entry.severity === "high") {
|
|
362
|
+
await alerting.emit(entry);
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
})
|
|
366
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AuditLogEntry, AuditLogStorage, StorageReadOptions, StorageReadResult } from "../types";
|
|
2
|
+
export declare class MemoryStorage implements AuditLogStorage {
|
|
3
|
+
readonly entries: AuditLogEntry[];
|
|
4
|
+
write(entry: AuditLogEntry): Promise<void>;
|
|
5
|
+
read(opts: StorageReadOptions): Promise<StorageReadResult>;
|
|
6
|
+
readById(id: string): Promise<AuditLogEntry | null>;
|
|
7
|
+
deleteOlderThan(date: Date): Promise<number>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/adapters/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,CAAM;IAEjC,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,IAAI,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmB1D,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAInD,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CAOnD"}
|
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
8
|
+
var __toCommonJS = (from) => {
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
10
|
+
if (entry)
|
|
11
|
+
return entry;
|
|
12
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
__moduleCache.set(from, entry);
|
|
22
|
+
return entry;
|
|
23
|
+
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
29
|
+
var __export = (target, all) => {
|
|
30
|
+
for (var name in all)
|
|
31
|
+
__defProp(target, name, {
|
|
32
|
+
get: all[name],
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/client.ts
|
|
40
|
+
var exports_client = {};
|
|
41
|
+
__export(exports_client, {
|
|
42
|
+
auditLogClient: () => auditLogClient
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(exports_client);
|
|
45
|
+
var auditLogClient = () => ({
|
|
46
|
+
id: "audit-log",
|
|
47
|
+
$InferServerPlugin: {},
|
|
48
|
+
pathMethods: {
|
|
49
|
+
"/audit-log/list": "GET",
|
|
50
|
+
"/audit-log/:id": "GET",
|
|
51
|
+
"/audit-log/insert": "POST"
|
|
52
|
+
}
|
|
53
|
+
});
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { auditLog } from "./plugin";
|
|
2
|
+
export declare const auditLogClient: () => {
|
|
3
|
+
id: "audit-log";
|
|
4
|
+
$InferServerPlugin: ReturnType<typeof auditLog>;
|
|
5
|
+
pathMethods: {
|
|
6
|
+
"/audit-log/list": "GET";
|
|
7
|
+
"/audit-log/:id": "GET";
|
|
8
|
+
"/audit-log/insert": "POST";
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,cAAc;;wBAGG,UAAU,CAAC,OAAO,QAAQ,CAAC;;;;;;CAMpB,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AuditLogEntry, ResolvedOptions } from "../types";
|
|
2
|
+
export declare function createGetLogEndpoint(opts: ResolvedOptions, modelName: string): import("better-call").StrictEndpoint<"/audit-log/:id", {
|
|
3
|
+
method: "GET";
|
|
4
|
+
use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
5
|
+
session: {
|
|
6
|
+
session: Record<string, any> & {
|
|
7
|
+
id: string;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
updatedAt: Date;
|
|
10
|
+
userId: string;
|
|
11
|
+
expiresAt: Date;
|
|
12
|
+
token: string;
|
|
13
|
+
ipAddress?: string | null | undefined;
|
|
14
|
+
userAgent?: string | null | undefined;
|
|
15
|
+
};
|
|
16
|
+
user: Record<string, any> & {
|
|
17
|
+
id: string;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
updatedAt: Date;
|
|
20
|
+
email: string;
|
|
21
|
+
emailVerified: boolean;
|
|
22
|
+
name: string;
|
|
23
|
+
image?: string | null | undefined;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}>)[];
|
|
27
|
+
}, AuditLogEntry>;
|
|
28
|
+
//# sourceMappingURL=get-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-log.d.ts","sourceRoot":"","sources":["../../src/endpoints/get-log.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE/D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;yBA4C0lB,CAAC;yBAA4C,CAAC;;;;;;;;;qBAAwN,CAAC;;;;kBAD76B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/endpoints/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ResolvedOptions } from "../types";
|
|
3
|
+
export declare function createInsertLogEndpoint(opts: ResolvedOptions, modelName: string): import("better-call").StrictEndpoint<"/audit-log/insert", {
|
|
4
|
+
method: "POST";
|
|
5
|
+
use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
6
|
+
session: {
|
|
7
|
+
session: Record<string, any> & {
|
|
8
|
+
id: string;
|
|
9
|
+
createdAt: Date;
|
|
10
|
+
updatedAt: Date;
|
|
11
|
+
userId: string;
|
|
12
|
+
expiresAt: Date;
|
|
13
|
+
token: string;
|
|
14
|
+
ipAddress?: string | null | undefined;
|
|
15
|
+
userAgent?: string | null | undefined;
|
|
16
|
+
};
|
|
17
|
+
user: Record<string, any> & {
|
|
18
|
+
id: string;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
email: string;
|
|
22
|
+
emailVerified: boolean;
|
|
23
|
+
name: string;
|
|
24
|
+
image?: string | null | undefined;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
}>)[];
|
|
28
|
+
body: z.ZodObject<{
|
|
29
|
+
action: z.ZodString;
|
|
30
|
+
status: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
31
|
+
success: "success";
|
|
32
|
+
failed: "failed";
|
|
33
|
+
}>>>;
|
|
34
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
35
|
+
low: "low";
|
|
36
|
+
medium: "medium";
|
|
37
|
+
high: "high";
|
|
38
|
+
critical: "critical";
|
|
39
|
+
}>>;
|
|
40
|
+
metadata: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
}, {
|
|
43
|
+
success: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
//# sourceMappingURL=insert-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insert-log.d.ts","sourceRoot":"","sources":["../../src/endpoints/insert-log.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAoC,eAAe,EAAE,MAAM,UAAU,CAAC;AAGlF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;yBAwC2oB,CAAC;yBAA4C,CAAC;;;;;;;;;qBAAwN,CAAC;;;;;;;;;;;;;;;;;;;;GADj+B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ResolvedOptions } from "../types";
|
|
3
|
+
export declare function createListLogsEndpoint(opts: ResolvedOptions, modelName: string): import("better-call").StrictEndpoint<"/audit-log/list", {
|
|
4
|
+
method: "GET";
|
|
5
|
+
use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
6
|
+
session: {
|
|
7
|
+
session: Record<string, any> & {
|
|
8
|
+
id: string;
|
|
9
|
+
createdAt: Date;
|
|
10
|
+
updatedAt: Date;
|
|
11
|
+
userId: string;
|
|
12
|
+
expiresAt: Date;
|
|
13
|
+
token: string;
|
|
14
|
+
ipAddress?: string | null | undefined;
|
|
15
|
+
userAgent?: string | null | undefined;
|
|
16
|
+
};
|
|
17
|
+
user: Record<string, any> & {
|
|
18
|
+
id: string;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
email: string;
|
|
22
|
+
emailVerified: boolean;
|
|
23
|
+
name: string;
|
|
24
|
+
image?: string | null | undefined;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
}>)[];
|
|
28
|
+
query: z.ZodObject<{
|
|
29
|
+
userId: z.ZodOptional<z.ZodString>;
|
|
30
|
+
action: z.ZodOptional<z.ZodString>;
|
|
31
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
32
|
+
success: "success";
|
|
33
|
+
failed: "failed";
|
|
34
|
+
}>>;
|
|
35
|
+
from: z.ZodOptional<z.ZodString>;
|
|
36
|
+
to: z.ZodOptional<z.ZodString>;
|
|
37
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
38
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
}, import("..").StorageReadResult>;
|
|
41
|
+
//# sourceMappingURL=list-logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-logs.d.ts","sourceRoot":"","sources":["../../src/endpoints/list-logs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAiB,eAAe,EAAsB,MAAM,UAAU,CAAC;AAEnF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;yBAwDzE,CAAH;yBAEmC,CAAC;;;;;;;;;qBAM7B,CAAT;;;;;;;;;;;;;;;;mCAgBA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HookEndpointContext } from "@better-auth/core";
|
|
2
|
+
import type { ResolvedOptions } from "../types";
|
|
3
|
+
export declare function createAfterHooks(opts: ResolvedOptions, modelName: string): {
|
|
4
|
+
matcher: (context: HookEndpointContext) => boolean;
|
|
5
|
+
handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
|
|
6
|
+
}[];
|
|
7
|
+
//# sourceMappingURL=after.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"after.d.ts","sourceRoot":"","sources":["../../src/hooks/after.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM;uBAGhD,mBAAmB;;IAmD3C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HookEndpointContext } from "@better-auth/core";
|
|
2
|
+
import type { ResolvedOptions } from "../types";
|
|
3
|
+
export declare const BEFORE_PATHS: readonly ["/sign-out", "/delete-user", "/revoke-session", "/revoke-sessions", "/revoke-other-sessions"];
|
|
4
|
+
export declare function createBeforeHooks(opts: ResolvedOptions, modelName: string): {
|
|
5
|
+
matcher: (context: HookEndpointContext) => boolean;
|
|
6
|
+
handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
|
|
7
|
+
}[];
|
|
8
|
+
//# sourceMappingURL=before.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"before.d.ts","sourceRoot":"","sources":["../../src/hooks/before.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhD,eAAO,MAAM,YAAY,yGAMf,CAAC;AAEX,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM;uBAGjD,mBAAmB;;IA2B3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|