nextjs-secure 0.5.0 → 0.7.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 +736 -688
- package/dist/audit.cjs +1337 -0
- package/dist/audit.cjs.map +1 -0
- package/dist/audit.d.cts +679 -0
- package/dist/audit.d.ts +679 -0
- package/dist/audit.js +1300 -0
- package/dist/audit.js.map +1 -0
- package/dist/bot.cjs +1521 -0
- package/dist/bot.cjs.map +1 -0
- package/dist/bot.d.cts +567 -0
- package/dist/bot.d.ts +567 -0
- package/dist/bot.js +1484 -0
- package/dist/bot.js.map +1 -0
- package/dist/index.cjs +2850 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2784 -10
- package/dist/index.js.map +1 -1
- package/package.json +26 -1
package/dist/audit.d.cts
ADDED
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
import { NextRequest } from 'next/server';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Log severity levels
|
|
5
|
+
*/
|
|
6
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'critical';
|
|
7
|
+
/**
|
|
8
|
+
* Security event types
|
|
9
|
+
*/
|
|
10
|
+
type SecurityEventType = 'auth.login' | 'auth.logout' | 'auth.failed' | 'auth.token_expired' | 'auth.token_invalid' | 'auth.permission_denied' | 'ratelimit.exceeded' | 'ratelimit.warning' | 'csrf.invalid' | 'csrf.missing' | 'xss.detected' | 'sqli.detected' | 'validation.failed' | 'file.rejected' | 'ip.blocked' | 'ip.suspicious' | 'request.malformed' | 'request.timeout' | 'error.unhandled' | 'error.internal' | 'custom';
|
|
11
|
+
/**
|
|
12
|
+
* Log entry base
|
|
13
|
+
*/
|
|
14
|
+
interface LogEntry {
|
|
15
|
+
id: string;
|
|
16
|
+
timestamp: Date;
|
|
17
|
+
level: LogLevel;
|
|
18
|
+
message: string;
|
|
19
|
+
category?: string;
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Request log entry
|
|
24
|
+
*/
|
|
25
|
+
interface RequestLogEntry extends LogEntry {
|
|
26
|
+
type: 'request';
|
|
27
|
+
request: {
|
|
28
|
+
id: string;
|
|
29
|
+
method: string;
|
|
30
|
+
url: string;
|
|
31
|
+
path: string;
|
|
32
|
+
query?: Record<string, string>;
|
|
33
|
+
headers?: Record<string, string>;
|
|
34
|
+
ip?: string;
|
|
35
|
+
userAgent?: string;
|
|
36
|
+
contentType?: string;
|
|
37
|
+
contentLength?: number;
|
|
38
|
+
};
|
|
39
|
+
response?: {
|
|
40
|
+
status: number;
|
|
41
|
+
headers?: Record<string, string>;
|
|
42
|
+
duration: number;
|
|
43
|
+
contentLength?: number;
|
|
44
|
+
};
|
|
45
|
+
user?: {
|
|
46
|
+
id?: string;
|
|
47
|
+
email?: string;
|
|
48
|
+
role?: string;
|
|
49
|
+
};
|
|
50
|
+
error?: {
|
|
51
|
+
name: string;
|
|
52
|
+
message: string;
|
|
53
|
+
stack?: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Security event entry
|
|
58
|
+
*/
|
|
59
|
+
interface SecurityEventEntry extends LogEntry {
|
|
60
|
+
type: 'security';
|
|
61
|
+
event: SecurityEventType;
|
|
62
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
63
|
+
source: {
|
|
64
|
+
ip?: string;
|
|
65
|
+
userAgent?: string;
|
|
66
|
+
userId?: string;
|
|
67
|
+
};
|
|
68
|
+
target?: {
|
|
69
|
+
resource?: string;
|
|
70
|
+
action?: string;
|
|
71
|
+
userId?: string;
|
|
72
|
+
};
|
|
73
|
+
details?: Record<string, unknown>;
|
|
74
|
+
mitigated?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Audit log entry (union type)
|
|
78
|
+
*/
|
|
79
|
+
type AuditLogEntry = RequestLogEntry | SecurityEventEntry;
|
|
80
|
+
/**
|
|
81
|
+
* Log store interface
|
|
82
|
+
*/
|
|
83
|
+
interface LogStore {
|
|
84
|
+
write(entry: AuditLogEntry): Promise<void>;
|
|
85
|
+
query?(options: LogQueryOptions): Promise<AuditLogEntry[]>;
|
|
86
|
+
flush?(): Promise<void>;
|
|
87
|
+
close?(): Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Log query options
|
|
91
|
+
*/
|
|
92
|
+
interface LogQueryOptions {
|
|
93
|
+
level?: LogLevel | LogLevel[];
|
|
94
|
+
type?: 'request' | 'security';
|
|
95
|
+
event?: SecurityEventType | SecurityEventType[];
|
|
96
|
+
startTime?: Date;
|
|
97
|
+
endTime?: Date;
|
|
98
|
+
ip?: string;
|
|
99
|
+
userId?: string;
|
|
100
|
+
limit?: number;
|
|
101
|
+
offset?: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Log formatter interface
|
|
105
|
+
*/
|
|
106
|
+
interface LogFormatter {
|
|
107
|
+
format(entry: AuditLogEntry): string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* PII field configuration
|
|
111
|
+
*/
|
|
112
|
+
interface PIIConfig {
|
|
113
|
+
fields: string[];
|
|
114
|
+
mode: 'mask' | 'hash' | 'remove';
|
|
115
|
+
maskChar?: string;
|
|
116
|
+
maskLength?: number;
|
|
117
|
+
preserveLength?: boolean;
|
|
118
|
+
customRedactor?: (value: string, field: string) => string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Audit middleware configuration
|
|
122
|
+
*/
|
|
123
|
+
interface AuditConfig {
|
|
124
|
+
enabled?: boolean;
|
|
125
|
+
store: LogStore;
|
|
126
|
+
formatter?: LogFormatter;
|
|
127
|
+
level?: LogLevel;
|
|
128
|
+
include?: {
|
|
129
|
+
ip?: boolean;
|
|
130
|
+
userAgent?: boolean;
|
|
131
|
+
headers?: boolean | string[];
|
|
132
|
+
query?: boolean;
|
|
133
|
+
body?: boolean | string[];
|
|
134
|
+
response?: boolean;
|
|
135
|
+
responseBody?: boolean;
|
|
136
|
+
duration?: boolean;
|
|
137
|
+
user?: boolean;
|
|
138
|
+
};
|
|
139
|
+
exclude?: {
|
|
140
|
+
paths?: string[];
|
|
141
|
+
methods?: string[];
|
|
142
|
+
statusCodes?: number[];
|
|
143
|
+
};
|
|
144
|
+
pii?: PIIConfig;
|
|
145
|
+
getUser?: (req: NextRequest) => Promise<{
|
|
146
|
+
id?: string;
|
|
147
|
+
email?: string;
|
|
148
|
+
role?: string;
|
|
149
|
+
} | null>;
|
|
150
|
+
requestIdHeader?: string;
|
|
151
|
+
generateRequestId?: () => string;
|
|
152
|
+
onError?: (error: Error, entry: Partial<AuditLogEntry>) => void;
|
|
153
|
+
skip?: (req: NextRequest) => boolean | Promise<boolean>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Security event configuration
|
|
157
|
+
*/
|
|
158
|
+
interface SecurityEventConfig {
|
|
159
|
+
store: LogStore;
|
|
160
|
+
formatter?: LogFormatter;
|
|
161
|
+
defaultSeverity?: 'low' | 'medium' | 'high' | 'critical';
|
|
162
|
+
onEvent?: (event: SecurityEventEntry) => void | Promise<void>;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Console store options
|
|
166
|
+
*/
|
|
167
|
+
interface ConsoleStoreOptions {
|
|
168
|
+
colorize?: boolean;
|
|
169
|
+
timestamp?: boolean;
|
|
170
|
+
pretty?: boolean;
|
|
171
|
+
level?: LogLevel;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* File store options
|
|
175
|
+
*/
|
|
176
|
+
interface FileStoreOptions {
|
|
177
|
+
path: string;
|
|
178
|
+
maxSize?: number;
|
|
179
|
+
maxFiles?: number;
|
|
180
|
+
compress?: boolean;
|
|
181
|
+
rotationInterval?: 'hourly' | 'daily' | 'weekly';
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Memory store options
|
|
185
|
+
*/
|
|
186
|
+
interface MemoryStoreOptions {
|
|
187
|
+
maxEntries?: number;
|
|
188
|
+
ttl?: number;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* External service store options
|
|
192
|
+
*/
|
|
193
|
+
interface ExternalStoreOptions {
|
|
194
|
+
endpoint: string;
|
|
195
|
+
apiKey?: string;
|
|
196
|
+
headers?: Record<string, string>;
|
|
197
|
+
batchSize?: number;
|
|
198
|
+
flushInterval?: number;
|
|
199
|
+
retryAttempts?: number;
|
|
200
|
+
timeout?: number;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* In-memory log store with LRU eviction
|
|
205
|
+
* Useful for development and testing
|
|
206
|
+
*/
|
|
207
|
+
declare class MemoryStore implements LogStore {
|
|
208
|
+
private entries;
|
|
209
|
+
private readonly maxEntries;
|
|
210
|
+
private readonly ttl;
|
|
211
|
+
constructor(options?: MemoryStoreOptions);
|
|
212
|
+
write(entry: AuditLogEntry): Promise<void>;
|
|
213
|
+
query(options?: LogQueryOptions): Promise<AuditLogEntry[]>;
|
|
214
|
+
flush(): Promise<void>;
|
|
215
|
+
close(): Promise<void>;
|
|
216
|
+
/**
|
|
217
|
+
* Get all entries (for testing)
|
|
218
|
+
*/
|
|
219
|
+
getEntries(): AuditLogEntry[];
|
|
220
|
+
/**
|
|
221
|
+
* Clear all entries
|
|
222
|
+
*/
|
|
223
|
+
clear(): void;
|
|
224
|
+
/**
|
|
225
|
+
* Get entry count
|
|
226
|
+
*/
|
|
227
|
+
size(): number;
|
|
228
|
+
/**
|
|
229
|
+
* Clean expired entries
|
|
230
|
+
*/
|
|
231
|
+
private cleanExpired;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Create a memory store
|
|
235
|
+
*/
|
|
236
|
+
declare function createMemoryStore(options?: MemoryStoreOptions): MemoryStore;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Console log store
|
|
240
|
+
* Outputs formatted logs to console
|
|
241
|
+
*/
|
|
242
|
+
declare class ConsoleStore implements LogStore {
|
|
243
|
+
private readonly colorize;
|
|
244
|
+
private readonly showTimestamp;
|
|
245
|
+
private readonly pretty;
|
|
246
|
+
private readonly minLevel;
|
|
247
|
+
constructor(options?: ConsoleStoreOptions);
|
|
248
|
+
write(entry: AuditLogEntry): Promise<void>;
|
|
249
|
+
flush(): Promise<void>;
|
|
250
|
+
close(): Promise<void>;
|
|
251
|
+
/**
|
|
252
|
+
* Format entry in compact single-line format
|
|
253
|
+
*/
|
|
254
|
+
private formatCompact;
|
|
255
|
+
/**
|
|
256
|
+
* Format entry in pretty multi-line format
|
|
257
|
+
*/
|
|
258
|
+
private formatPretty;
|
|
259
|
+
/**
|
|
260
|
+
* Apply color if enabled
|
|
261
|
+
*/
|
|
262
|
+
private color;
|
|
263
|
+
/**
|
|
264
|
+
* Color log level
|
|
265
|
+
*/
|
|
266
|
+
private colorLevel;
|
|
267
|
+
/**
|
|
268
|
+
* Color HTTP status
|
|
269
|
+
*/
|
|
270
|
+
private colorStatus;
|
|
271
|
+
/**
|
|
272
|
+
* Color severity
|
|
273
|
+
*/
|
|
274
|
+
private colorSeverity;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Create a console store
|
|
278
|
+
*/
|
|
279
|
+
declare function createConsoleStore(options?: ConsoleStoreOptions): ConsoleStore;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* External HTTP log store
|
|
283
|
+
* Sends logs to external services (Datadog, Sentry, custom endpoints)
|
|
284
|
+
*/
|
|
285
|
+
declare class ExternalStore implements LogStore {
|
|
286
|
+
private readonly endpoint;
|
|
287
|
+
private readonly headers;
|
|
288
|
+
private readonly batchSize;
|
|
289
|
+
private readonly flushInterval;
|
|
290
|
+
private readonly retryAttempts;
|
|
291
|
+
private readonly timeout;
|
|
292
|
+
private buffer;
|
|
293
|
+
private flushTimer;
|
|
294
|
+
private isFlushing;
|
|
295
|
+
constructor(options: ExternalStoreOptions);
|
|
296
|
+
write(entry: AuditLogEntry): Promise<void>;
|
|
297
|
+
flush(): Promise<void>;
|
|
298
|
+
close(): Promise<void>;
|
|
299
|
+
/**
|
|
300
|
+
* Send entries to external endpoint
|
|
301
|
+
*/
|
|
302
|
+
private send;
|
|
303
|
+
/**
|
|
304
|
+
* Serialize entry for transmission
|
|
305
|
+
*/
|
|
306
|
+
private serialize;
|
|
307
|
+
/**
|
|
308
|
+
* Sleep helper
|
|
309
|
+
*/
|
|
310
|
+
private sleep;
|
|
311
|
+
/**
|
|
312
|
+
* Get buffer size (for monitoring)
|
|
313
|
+
*/
|
|
314
|
+
getBufferSize(): number;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Create an external store
|
|
318
|
+
*/
|
|
319
|
+
declare function createExternalStore(options: ExternalStoreOptions): ExternalStore;
|
|
320
|
+
/**
|
|
321
|
+
* Create a Datadog store
|
|
322
|
+
*/
|
|
323
|
+
declare function createDatadogStore(options: {
|
|
324
|
+
apiKey: string;
|
|
325
|
+
site?: 'datadoghq.com' | 'datadoghq.eu' | 'us3.datadoghq.com' | 'us5.datadoghq.com';
|
|
326
|
+
service?: string;
|
|
327
|
+
source?: string;
|
|
328
|
+
tags?: string[];
|
|
329
|
+
batchSize?: number;
|
|
330
|
+
flushInterval?: number;
|
|
331
|
+
}): ExternalStore;
|
|
332
|
+
/**
|
|
333
|
+
* Create a multi-store that writes to multiple stores
|
|
334
|
+
*/
|
|
335
|
+
declare class MultiStore implements LogStore {
|
|
336
|
+
private stores;
|
|
337
|
+
constructor(stores: LogStore[]);
|
|
338
|
+
write(entry: AuditLogEntry): Promise<void>;
|
|
339
|
+
query(options: Parameters<NonNullable<LogStore['query']>>[0]): Promise<AuditLogEntry[]>;
|
|
340
|
+
flush(): Promise<void>;
|
|
341
|
+
close(): Promise<void>;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Create a multi-store
|
|
345
|
+
*/
|
|
346
|
+
declare function createMultiStore(stores: LogStore[]): MultiStore;
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* JSON formatter - outputs logs as JSON strings
|
|
350
|
+
*/
|
|
351
|
+
declare class JSONFormatter implements LogFormatter {
|
|
352
|
+
private readonly pretty;
|
|
353
|
+
private readonly includeTimestamp;
|
|
354
|
+
constructor(options?: {
|
|
355
|
+
pretty?: boolean;
|
|
356
|
+
includeTimestamp?: boolean;
|
|
357
|
+
});
|
|
358
|
+
format(entry: AuditLogEntry): string;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Text formatter - outputs logs as human-readable text
|
|
362
|
+
*/
|
|
363
|
+
declare class TextFormatter implements LogFormatter {
|
|
364
|
+
private readonly template;
|
|
365
|
+
private readonly dateFormat;
|
|
366
|
+
constructor(options?: {
|
|
367
|
+
template?: string;
|
|
368
|
+
dateFormat?: 'iso' | 'utc' | 'local';
|
|
369
|
+
});
|
|
370
|
+
format(entry: AuditLogEntry): string;
|
|
371
|
+
private formatDate;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* CLF (Common Log Format) formatter
|
|
375
|
+
* Apache/Nginx style: host ident authuser date request status bytes
|
|
376
|
+
*/
|
|
377
|
+
declare class CLFFormatter implements LogFormatter {
|
|
378
|
+
format(entry: AuditLogEntry): string;
|
|
379
|
+
private formatCLFDate;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Structured formatter for ELK/Splunk
|
|
383
|
+
* Outputs key=value pairs
|
|
384
|
+
*/
|
|
385
|
+
declare class StructuredFormatter implements LogFormatter {
|
|
386
|
+
private readonly delimiter;
|
|
387
|
+
private readonly kvSeparator;
|
|
388
|
+
constructor(options?: {
|
|
389
|
+
delimiter?: string;
|
|
390
|
+
kvSeparator?: string;
|
|
391
|
+
});
|
|
392
|
+
format(entry: AuditLogEntry): string;
|
|
393
|
+
private pair;
|
|
394
|
+
private escape;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Create a JSON formatter
|
|
398
|
+
*/
|
|
399
|
+
declare function createJSONFormatter(options?: {
|
|
400
|
+
pretty?: boolean;
|
|
401
|
+
}): JSONFormatter;
|
|
402
|
+
/**
|
|
403
|
+
* Create a text formatter
|
|
404
|
+
*/
|
|
405
|
+
declare function createTextFormatter(options?: {
|
|
406
|
+
template?: string;
|
|
407
|
+
dateFormat?: 'iso' | 'utc' | 'local';
|
|
408
|
+
}): TextFormatter;
|
|
409
|
+
/**
|
|
410
|
+
* Create a CLF formatter
|
|
411
|
+
*/
|
|
412
|
+
declare function createCLFFormatter(): CLFFormatter;
|
|
413
|
+
/**
|
|
414
|
+
* Create a structured formatter
|
|
415
|
+
*/
|
|
416
|
+
declare function createStructuredFormatter(options?: {
|
|
417
|
+
delimiter?: string;
|
|
418
|
+
kvSeparator?: string;
|
|
419
|
+
}): StructuredFormatter;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Default PII fields to redact
|
|
423
|
+
*/
|
|
424
|
+
declare const DEFAULT_PII_FIELDS: string[];
|
|
425
|
+
/**
|
|
426
|
+
* Mask a value with asterisks
|
|
427
|
+
*/
|
|
428
|
+
declare function mask(value: string, options?: {
|
|
429
|
+
char?: string;
|
|
430
|
+
preserveLength?: boolean;
|
|
431
|
+
showFirst?: number;
|
|
432
|
+
showLast?: number;
|
|
433
|
+
}): string;
|
|
434
|
+
/**
|
|
435
|
+
* Simple hash function for Edge Runtime compatibility
|
|
436
|
+
* Uses a fast, deterministic string hash (not cryptographic)
|
|
437
|
+
*/
|
|
438
|
+
declare function hash(value: string, salt?: string): string;
|
|
439
|
+
/**
|
|
440
|
+
* Redact a single value
|
|
441
|
+
*/
|
|
442
|
+
declare function redactValue(value: unknown, field: string, config: PIIConfig): unknown;
|
|
443
|
+
/**
|
|
444
|
+
* Redact PII from an object recursively
|
|
445
|
+
*/
|
|
446
|
+
declare function redactObject<T>(obj: T, config: PIIConfig, path?: string): T;
|
|
447
|
+
/**
|
|
448
|
+
* Create a redactor function with preset config
|
|
449
|
+
*/
|
|
450
|
+
declare function createRedactor(config?: Partial<PIIConfig>): <T>(obj: T) => T;
|
|
451
|
+
/**
|
|
452
|
+
* Redact sensitive headers
|
|
453
|
+
*/
|
|
454
|
+
declare function redactHeaders(headers: Record<string, string>, sensitiveHeaders?: string[]): Record<string, string>;
|
|
455
|
+
/**
|
|
456
|
+
* Redact query parameters
|
|
457
|
+
*/
|
|
458
|
+
declare function redactQuery(query: Record<string, string>, sensitiveParams?: string[]): Record<string, string>;
|
|
459
|
+
/**
|
|
460
|
+
* Redact email (show only domain)
|
|
461
|
+
*/
|
|
462
|
+
declare function redactEmail(email: string): string;
|
|
463
|
+
/**
|
|
464
|
+
* Redact credit card number (show last 4 digits)
|
|
465
|
+
*/
|
|
466
|
+
declare function redactCreditCard(cardNumber: string): string;
|
|
467
|
+
/**
|
|
468
|
+
* Redact phone number
|
|
469
|
+
*/
|
|
470
|
+
declare function redactPhone(phone: string): string;
|
|
471
|
+
/**
|
|
472
|
+
* Redact IP address (show only first two octets for IPv4)
|
|
473
|
+
*/
|
|
474
|
+
declare function redactIP(ip: string): string;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Security event tracker
|
|
478
|
+
*/
|
|
479
|
+
declare class SecurityEventTracker {
|
|
480
|
+
private store;
|
|
481
|
+
private defaultSeverity;
|
|
482
|
+
private onEvent?;
|
|
483
|
+
constructor(config: SecurityEventConfig);
|
|
484
|
+
/**
|
|
485
|
+
* Track a security event
|
|
486
|
+
*/
|
|
487
|
+
track(options: {
|
|
488
|
+
event: SecurityEventType;
|
|
489
|
+
message: string;
|
|
490
|
+
severity?: 'low' | 'medium' | 'high' | 'critical';
|
|
491
|
+
source?: {
|
|
492
|
+
ip?: string;
|
|
493
|
+
userAgent?: string;
|
|
494
|
+
userId?: string;
|
|
495
|
+
};
|
|
496
|
+
target?: {
|
|
497
|
+
resource?: string;
|
|
498
|
+
action?: string;
|
|
499
|
+
userId?: string;
|
|
500
|
+
};
|
|
501
|
+
details?: Record<string, unknown>;
|
|
502
|
+
mitigated?: boolean;
|
|
503
|
+
metadata?: Record<string, unknown>;
|
|
504
|
+
}): Promise<SecurityEventEntry>;
|
|
505
|
+
/**
|
|
506
|
+
* Track failed authentication
|
|
507
|
+
*/
|
|
508
|
+
authFailed(options: {
|
|
509
|
+
ip?: string;
|
|
510
|
+
userAgent?: string;
|
|
511
|
+
email?: string;
|
|
512
|
+
reason?: string;
|
|
513
|
+
metadata?: Record<string, unknown>;
|
|
514
|
+
}): Promise<SecurityEventEntry>;
|
|
515
|
+
/**
|
|
516
|
+
* Track successful login
|
|
517
|
+
*/
|
|
518
|
+
authLogin(options: {
|
|
519
|
+
userId: string;
|
|
520
|
+
ip?: string;
|
|
521
|
+
userAgent?: string;
|
|
522
|
+
method?: string;
|
|
523
|
+
metadata?: Record<string, unknown>;
|
|
524
|
+
}): Promise<SecurityEventEntry>;
|
|
525
|
+
/**
|
|
526
|
+
* Track logout
|
|
527
|
+
*/
|
|
528
|
+
authLogout(options: {
|
|
529
|
+
userId: string;
|
|
530
|
+
ip?: string;
|
|
531
|
+
reason?: 'user' | 'timeout' | 'forced';
|
|
532
|
+
metadata?: Record<string, unknown>;
|
|
533
|
+
}): Promise<SecurityEventEntry>;
|
|
534
|
+
/**
|
|
535
|
+
* Track permission denied
|
|
536
|
+
*/
|
|
537
|
+
permissionDenied(options: {
|
|
538
|
+
userId?: string;
|
|
539
|
+
ip?: string;
|
|
540
|
+
resource: string;
|
|
541
|
+
action: string;
|
|
542
|
+
requiredRole?: string;
|
|
543
|
+
metadata?: Record<string, unknown>;
|
|
544
|
+
}): Promise<SecurityEventEntry>;
|
|
545
|
+
/**
|
|
546
|
+
* Track rate limit exceeded
|
|
547
|
+
*/
|
|
548
|
+
rateLimitExceeded(options: {
|
|
549
|
+
ip?: string;
|
|
550
|
+
userId?: string;
|
|
551
|
+
endpoint: string;
|
|
552
|
+
limit: number;
|
|
553
|
+
window: string;
|
|
554
|
+
metadata?: Record<string, unknown>;
|
|
555
|
+
}): Promise<SecurityEventEntry>;
|
|
556
|
+
/**
|
|
557
|
+
* Track CSRF validation failure
|
|
558
|
+
*/
|
|
559
|
+
csrfInvalid(options: {
|
|
560
|
+
ip?: string;
|
|
561
|
+
userId?: string;
|
|
562
|
+
endpoint: string;
|
|
563
|
+
reason?: string;
|
|
564
|
+
metadata?: Record<string, unknown>;
|
|
565
|
+
}): Promise<SecurityEventEntry>;
|
|
566
|
+
/**
|
|
567
|
+
* Track XSS detection
|
|
568
|
+
*/
|
|
569
|
+
xssDetected(options: {
|
|
570
|
+
ip?: string;
|
|
571
|
+
userId?: string;
|
|
572
|
+
field: string;
|
|
573
|
+
payload?: string;
|
|
574
|
+
endpoint: string;
|
|
575
|
+
metadata?: Record<string, unknown>;
|
|
576
|
+
}): Promise<SecurityEventEntry>;
|
|
577
|
+
/**
|
|
578
|
+
* Track SQL injection detection
|
|
579
|
+
*/
|
|
580
|
+
sqliDetected(options: {
|
|
581
|
+
ip?: string;
|
|
582
|
+
userId?: string;
|
|
583
|
+
field: string;
|
|
584
|
+
pattern: string;
|
|
585
|
+
severity?: 'low' | 'medium' | 'high';
|
|
586
|
+
endpoint: string;
|
|
587
|
+
metadata?: Record<string, unknown>;
|
|
588
|
+
}): Promise<SecurityEventEntry>;
|
|
589
|
+
/**
|
|
590
|
+
* Track IP block
|
|
591
|
+
*/
|
|
592
|
+
ipBlocked(options: {
|
|
593
|
+
ip: string;
|
|
594
|
+
reason: string;
|
|
595
|
+
duration?: number;
|
|
596
|
+
metadata?: Record<string, unknown>;
|
|
597
|
+
}): Promise<SecurityEventEntry>;
|
|
598
|
+
/**
|
|
599
|
+
* Track suspicious activity
|
|
600
|
+
*/
|
|
601
|
+
suspicious(options: {
|
|
602
|
+
ip?: string;
|
|
603
|
+
userId?: string;
|
|
604
|
+
activity: string;
|
|
605
|
+
severity?: 'low' | 'medium' | 'high' | 'critical';
|
|
606
|
+
details?: Record<string, unknown>;
|
|
607
|
+
metadata?: Record<string, unknown>;
|
|
608
|
+
}): Promise<SecurityEventEntry>;
|
|
609
|
+
/**
|
|
610
|
+
* Track custom event
|
|
611
|
+
*/
|
|
612
|
+
custom(options: {
|
|
613
|
+
message: string;
|
|
614
|
+
severity?: 'low' | 'medium' | 'high' | 'critical';
|
|
615
|
+
source?: {
|
|
616
|
+
ip?: string;
|
|
617
|
+
userAgent?: string;
|
|
618
|
+
userId?: string;
|
|
619
|
+
};
|
|
620
|
+
target?: {
|
|
621
|
+
resource?: string;
|
|
622
|
+
action?: string;
|
|
623
|
+
};
|
|
624
|
+
details?: Record<string, unknown>;
|
|
625
|
+
metadata?: Record<string, unknown>;
|
|
626
|
+
}): Promise<SecurityEventEntry>;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Create a security event tracker
|
|
630
|
+
*/
|
|
631
|
+
declare function createSecurityTracker(config: SecurityEventConfig): SecurityEventTracker;
|
|
632
|
+
/**
|
|
633
|
+
* Standalone function to track security events
|
|
634
|
+
*/
|
|
635
|
+
declare function trackSecurityEvent(store: LogStore, options: {
|
|
636
|
+
event: SecurityEventType;
|
|
637
|
+
message: string;
|
|
638
|
+
severity?: 'low' | 'medium' | 'high' | 'critical';
|
|
639
|
+
source?: {
|
|
640
|
+
ip?: string;
|
|
641
|
+
userAgent?: string;
|
|
642
|
+
userId?: string;
|
|
643
|
+
};
|
|
644
|
+
target?: {
|
|
645
|
+
resource?: string;
|
|
646
|
+
action?: string;
|
|
647
|
+
userId?: string;
|
|
648
|
+
};
|
|
649
|
+
details?: Record<string, unknown>;
|
|
650
|
+
metadata?: Record<string, unknown>;
|
|
651
|
+
}): Promise<SecurityEventEntry>;
|
|
652
|
+
|
|
653
|
+
type RouteHandler = (req: NextRequest) => Response | Promise<Response>;
|
|
654
|
+
/**
|
|
655
|
+
* Audit logging middleware
|
|
656
|
+
*/
|
|
657
|
+
declare function withAuditLog(handler: RouteHandler, config: AuditConfig): RouteHandler;
|
|
658
|
+
/**
|
|
659
|
+
* Create audit middleware with default console logging
|
|
660
|
+
*/
|
|
661
|
+
declare function createAuditMiddleware(config: Partial<AuditConfig> & {
|
|
662
|
+
store: AuditConfig['store'];
|
|
663
|
+
}): (handler: RouteHandler) => RouteHandler;
|
|
664
|
+
/**
|
|
665
|
+
* Request logger that adds request ID to response headers
|
|
666
|
+
*/
|
|
667
|
+
declare function withRequestId(handler: RouteHandler, options?: {
|
|
668
|
+
headerName?: string;
|
|
669
|
+
generateId?: () => string;
|
|
670
|
+
}): RouteHandler;
|
|
671
|
+
/**
|
|
672
|
+
* Simple request timing middleware
|
|
673
|
+
*/
|
|
674
|
+
declare function withTiming(handler: RouteHandler, options?: {
|
|
675
|
+
headerName?: string;
|
|
676
|
+
log?: boolean;
|
|
677
|
+
}): RouteHandler;
|
|
678
|
+
|
|
679
|
+
export { type AuditConfig, type AuditLogEntry, CLFFormatter, ConsoleStore, type ConsoleStoreOptions, DEFAULT_PII_FIELDS, ExternalStore, type ExternalStoreOptions, type FileStoreOptions, JSONFormatter, type LogEntry, type LogFormatter, type LogLevel, type LogQueryOptions, type LogStore, MemoryStore, type MemoryStoreOptions, MultiStore, type PIIConfig, type RequestLogEntry, type SecurityEventConfig, type SecurityEventEntry, SecurityEventTracker, type SecurityEventType, StructuredFormatter, TextFormatter, createAuditMiddleware, createCLFFormatter, createConsoleStore, createDatadogStore, createExternalStore, createJSONFormatter, createMemoryStore, createMultiStore, createRedactor, createSecurityTracker, createStructuredFormatter, createTextFormatter, hash, mask, redactCreditCard, redactEmail, redactHeaders, redactIP, redactObject, redactPhone, redactQuery, redactValue, trackSecurityEvent, withAuditLog, withRequestId, withTiming };
|