@heavybit/logger-ts 1.0.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 +458 -0
- package/dist/config/index.d.ts +34 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +204 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/aopLogger.d.ts +44 -0
- package/dist/lib/aopLogger.d.ts.map +1 -0
- package/dist/lib/aopLogger.js +269 -0
- package/dist/lib/aopLogger.js.map +1 -0
- package/dist/lib/aopLoggerUtils.d.ts +54 -0
- package/dist/lib/aopLoggerUtils.d.ts.map +1 -0
- package/dist/lib/aopLoggerUtils.js +195 -0
- package/dist/lib/aopLoggerUtils.js.map +1 -0
- package/dist/lib/logger.d.ts +22 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +253 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/middleware/loggingMiddleware.d.ts +27 -0
- package/dist/middleware/loggingMiddleware.d.ts.map +1 -0
- package/dist/middleware/loggingMiddleware.js +225 -0
- package/dist/middleware/loggingMiddleware.js.map +1 -0
- package/dist/types/index.d.ts +208 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/sanitize.d.ts +26 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +132 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.morganStyleMiddleware = exports.errorLoggingMiddleware = exports.loggingMiddleware = exports.createLoggingMiddleware = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const logger_1 = require("../lib/logger");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const sanitize_1 = require("../utils/sanitize");
|
|
8
|
+
/**
|
|
9
|
+
* Filter sensitive data from request body
|
|
10
|
+
*/
|
|
11
|
+
const filterSensitiveBody = (body) => {
|
|
12
|
+
return (0, sanitize_1.sanitizeData)(body);
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Filter sensitive headers
|
|
16
|
+
*/
|
|
17
|
+
const filterSensitiveHeaders = (headers) => {
|
|
18
|
+
return (0, sanitize_1.sanitizeHeaders)(headers);
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Create the Express logging middleware with configuration options
|
|
22
|
+
*
|
|
23
|
+
* @param options - Middleware configuration options
|
|
24
|
+
* @returns Express middleware function
|
|
25
|
+
*/
|
|
26
|
+
const createLoggingMiddleware = (options = {}) => {
|
|
27
|
+
const { skipEndpoints = [], logRequestBody = true, logResponseBody = false, requestIdGenerator = uuid_1.v4, additionalFields, } = options;
|
|
28
|
+
return (req, res, next) => {
|
|
29
|
+
const logger = (0, logger_1.getLogger)();
|
|
30
|
+
const config = (0, config_1.getConfig)();
|
|
31
|
+
// Get health check endpoint from config or options
|
|
32
|
+
const healthCheckEndpoint = config.healthCheckEndpoint || '/health';
|
|
33
|
+
const allSkipEndpoints = [...skipEndpoints, healthCheckEndpoint];
|
|
34
|
+
// Check if this endpoint should be skipped
|
|
35
|
+
if (allSkipEndpoints.some((endpoint) => req.path === endpoint || req.path.startsWith(endpoint))) {
|
|
36
|
+
return next();
|
|
37
|
+
}
|
|
38
|
+
// Generate unique request ID
|
|
39
|
+
const requestId = requestIdGenerator();
|
|
40
|
+
req.requestId = requestId;
|
|
41
|
+
// Store request body for logging
|
|
42
|
+
const requestBody = req.body;
|
|
43
|
+
// Capture start time
|
|
44
|
+
const startTime = Date.now();
|
|
45
|
+
req.startTime = startTime;
|
|
46
|
+
// Log incoming request
|
|
47
|
+
const logRequest = () => {
|
|
48
|
+
if (req.url && req.method) {
|
|
49
|
+
const logData = {
|
|
50
|
+
level: 'info',
|
|
51
|
+
message: 'Incoming request',
|
|
52
|
+
requestId,
|
|
53
|
+
method: req.method,
|
|
54
|
+
url: req.originalUrl,
|
|
55
|
+
timestamp: new Date().toISOString(),
|
|
56
|
+
};
|
|
57
|
+
// Add headers if not too large
|
|
58
|
+
const filteredHeaders = filterSensitiveHeaders(req.headers);
|
|
59
|
+
if (Object.keys(filteredHeaders).length <= 20) {
|
|
60
|
+
logData.headers = filteredHeaders;
|
|
61
|
+
}
|
|
62
|
+
// Add body if enabled
|
|
63
|
+
if (logRequestBody && requestBody && Object.keys(requestBody).length > 0) {
|
|
64
|
+
logData.body = filterSensitiveBody(requestBody);
|
|
65
|
+
}
|
|
66
|
+
// Add additional fields if provided
|
|
67
|
+
if (additionalFields) {
|
|
68
|
+
const extra = additionalFields(req);
|
|
69
|
+
Object.assign(logData, extra);
|
|
70
|
+
}
|
|
71
|
+
logger.info((0, logger_1.formatLogEntry)(logData));
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
// Log the incoming request
|
|
75
|
+
logRequest();
|
|
76
|
+
// Capture response body if enabled
|
|
77
|
+
let responseBody = '';
|
|
78
|
+
if (logResponseBody) {
|
|
79
|
+
const originalWrite = res.write.bind(res);
|
|
80
|
+
const originalEnd = res.end.bind(res);
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
82
|
+
res.write = function (chunk, ...args) {
|
|
83
|
+
if (chunk) {
|
|
84
|
+
responseBody += String(chunk);
|
|
85
|
+
}
|
|
86
|
+
return originalWrite(chunk, ...args);
|
|
87
|
+
};
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
+
res.end = function (chunk, ...args) {
|
|
90
|
+
if (chunk && typeof chunk !== 'function') {
|
|
91
|
+
responseBody += String(chunk);
|
|
92
|
+
}
|
|
93
|
+
return originalEnd(chunk, ...args);
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Event listener for when the response finishes
|
|
97
|
+
res.on('finish', () => {
|
|
98
|
+
const duration = Date.now() - startTime;
|
|
99
|
+
const logLevel = res.statusCode >= 400 ? 'error' : 'info';
|
|
100
|
+
const logData = {
|
|
101
|
+
level: logLevel,
|
|
102
|
+
message: 'Request completed',
|
|
103
|
+
requestId,
|
|
104
|
+
method: req.method,
|
|
105
|
+
url: req.originalUrl,
|
|
106
|
+
statusCode: res.statusCode,
|
|
107
|
+
responseTime: `${duration}ms`,
|
|
108
|
+
timestamp: new Date().toISOString(),
|
|
109
|
+
};
|
|
110
|
+
// Include request body for error responses
|
|
111
|
+
if (logLevel === 'error' && requestBody && Object.keys(requestBody).length > 0) {
|
|
112
|
+
logData.body = filterSensitiveBody(requestBody);
|
|
113
|
+
}
|
|
114
|
+
// Include response body if captured
|
|
115
|
+
if (logResponseBody && responseBody) {
|
|
116
|
+
try {
|
|
117
|
+
const parsedBody = JSON.parse(responseBody);
|
|
118
|
+
logData.body = {
|
|
119
|
+
...(logData.body || {}),
|
|
120
|
+
response: (0, sanitize_1.sanitizeData)(parsedBody),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Response is not JSON, skip
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Add additional fields
|
|
128
|
+
if (additionalFields) {
|
|
129
|
+
const extra = additionalFields(req);
|
|
130
|
+
Object.assign(logData, extra);
|
|
131
|
+
}
|
|
132
|
+
logger.log(logLevel, (0, logger_1.formatLogEntry)(logData));
|
|
133
|
+
});
|
|
134
|
+
// Event listener for response errors
|
|
135
|
+
res.on('error', (err) => {
|
|
136
|
+
const duration = Date.now() - startTime;
|
|
137
|
+
logger.error((0, logger_1.formatLogEntry)({
|
|
138
|
+
level: 'error',
|
|
139
|
+
message: 'Request failed',
|
|
140
|
+
requestId,
|
|
141
|
+
method: req.method,
|
|
142
|
+
url: req.originalUrl,
|
|
143
|
+
statusCode: res.statusCode,
|
|
144
|
+
responseTime: `${duration}ms`,
|
|
145
|
+
error: err.message,
|
|
146
|
+
body: filterSensitiveBody(requestBody),
|
|
147
|
+
timestamp: new Date().toISOString(),
|
|
148
|
+
}));
|
|
149
|
+
});
|
|
150
|
+
next();
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
exports.createLoggingMiddleware = createLoggingMiddleware;
|
|
154
|
+
/**
|
|
155
|
+
* Default logging middleware (uses default configuration)
|
|
156
|
+
*/
|
|
157
|
+
exports.loggingMiddleware = (0, exports.createLoggingMiddleware)();
|
|
158
|
+
/**
|
|
159
|
+
* Error logging middleware for Express error handling
|
|
160
|
+
*/
|
|
161
|
+
const errorLoggingMiddleware = (err, req, _res, next) => {
|
|
162
|
+
const logger = (0, logger_1.getLogger)();
|
|
163
|
+
const startTime = req.startTime || Date.now();
|
|
164
|
+
const duration = Date.now() - startTime;
|
|
165
|
+
logger.error((0, logger_1.formatLogEntry)({
|
|
166
|
+
level: 'error',
|
|
167
|
+
message: 'Unhandled error',
|
|
168
|
+
requestId: req.requestId,
|
|
169
|
+
method: req.method,
|
|
170
|
+
url: req.originalUrl,
|
|
171
|
+
statusCode: err.statusCode || err.status || 500,
|
|
172
|
+
responseTime: `${duration}ms`,
|
|
173
|
+
error: err.message,
|
|
174
|
+
body: (0, sanitize_1.sanitizeData)(req.body),
|
|
175
|
+
timestamp: new Date().toISOString(),
|
|
176
|
+
}));
|
|
177
|
+
// Pass to next error handler
|
|
178
|
+
next(err);
|
|
179
|
+
};
|
|
180
|
+
exports.errorLoggingMiddleware = errorLoggingMiddleware;
|
|
181
|
+
/**
|
|
182
|
+
* Morgan-style request logging format
|
|
183
|
+
* Returns a middleware that logs in a standardized format
|
|
184
|
+
*/
|
|
185
|
+
const morganStyleMiddleware = (format = 'dev') => {
|
|
186
|
+
return (req, res, next) => {
|
|
187
|
+
const logger = (0, logger_1.getLogger)();
|
|
188
|
+
const startTime = Date.now();
|
|
189
|
+
const requestId = (0, uuid_1.v4)();
|
|
190
|
+
req.requestId = requestId;
|
|
191
|
+
res.on('finish', () => {
|
|
192
|
+
const duration = Date.now() - startTime;
|
|
193
|
+
let logMessage = '';
|
|
194
|
+
switch (format) {
|
|
195
|
+
case 'combined':
|
|
196
|
+
logMessage = `${req.ip} - - [${new Date().toISOString()}] "${req.method} ${req.originalUrl} HTTP/${req.httpVersion}" ${res.statusCode} - "${req.get('referer') || '-'}" "${req.get('user-agent') || '-'}"`;
|
|
197
|
+
break;
|
|
198
|
+
case 'common':
|
|
199
|
+
logMessage = `${req.ip} - - [${new Date().toISOString()}] "${req.method} ${req.originalUrl} HTTP/${req.httpVersion}" ${res.statusCode} -`;
|
|
200
|
+
break;
|
|
201
|
+
case 'dev':
|
|
202
|
+
logMessage = `${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms`;
|
|
203
|
+
break;
|
|
204
|
+
case 'short':
|
|
205
|
+
logMessage = `${req.ip} ${req.method} ${req.originalUrl} ${res.statusCode} - ${duration}ms`;
|
|
206
|
+
break;
|
|
207
|
+
case 'tiny':
|
|
208
|
+
logMessage = `${req.method} ${req.originalUrl} ${res.statusCode} - ${duration}ms`;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
const level = res.statusCode >= 400 ? 'error' : 'info';
|
|
212
|
+
logger.log(level, logMessage, {
|
|
213
|
+
requestId,
|
|
214
|
+
method: req.method,
|
|
215
|
+
url: req.originalUrl,
|
|
216
|
+
statusCode: res.statusCode,
|
|
217
|
+
responseTime: `${duration}ms`,
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
next();
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
exports.morganStyleMiddleware = morganStyleMiddleware;
|
|
224
|
+
exports.default = exports.loggingMiddleware;
|
|
225
|
+
//# sourceMappingURL=loggingMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggingMiddleware.js","sourceRoot":"","sources":["../../src/middleware/loggingMiddleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import winston from 'winston';
|
|
3
|
+
/**
|
|
4
|
+
* Supported log levels
|
|
5
|
+
*/
|
|
6
|
+
export type LogLevel = 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly';
|
|
7
|
+
/**
|
|
8
|
+
* Types of application classes for context-aware logging
|
|
9
|
+
*/
|
|
10
|
+
export type ClassType = 'controllers' | 'services' | 'repositories' | 'utils' | 'middleware' | 'routes' | 'configuration' | 'validators' | 'eventListeners' | 'helpers' | 'jobs' | 'models' | 'transformers' | 'default' | 'unknown';
|
|
11
|
+
/**
|
|
12
|
+
* Log output targets
|
|
13
|
+
*/
|
|
14
|
+
export type LogTarget = 'stdout' | 'file' | 'both';
|
|
15
|
+
/**
|
|
16
|
+
* Configuration for file-based logging
|
|
17
|
+
*/
|
|
18
|
+
export interface FileLogConfig {
|
|
19
|
+
/** Directory for log files (default: 'logs') */
|
|
20
|
+
directory: string;
|
|
21
|
+
/** Maximum size of log file before rotation (default: '50m') */
|
|
22
|
+
maxSize: string;
|
|
23
|
+
/** Maximum retention period for log files (default: '30d') */
|
|
24
|
+
maxFiles: string;
|
|
25
|
+
/** Whether to compress archived logs (default: true) */
|
|
26
|
+
zippedArchive: boolean;
|
|
27
|
+
/** Date pattern for log file naming (default: 'YYYY-MM-DD') */
|
|
28
|
+
datePattern: string;
|
|
29
|
+
/** Log level for file output (default: 'info') */
|
|
30
|
+
level: LogLevel;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Configuration for console/stdout logging
|
|
34
|
+
*/
|
|
35
|
+
export interface ConsoleLogConfig {
|
|
36
|
+
/** Whether to colorize console output (default: true in development) */
|
|
37
|
+
colorize: boolean;
|
|
38
|
+
/** Log level for console output (default: 'debug') */
|
|
39
|
+
level: LogLevel;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Main logger configuration
|
|
43
|
+
*/
|
|
44
|
+
export interface LoggerConfig {
|
|
45
|
+
/** Where to output logs: 'stdout', 'file', or 'both' */
|
|
46
|
+
target: LogTarget;
|
|
47
|
+
/** Default log level if not specified by class type */
|
|
48
|
+
defaultLevel: LogLevel;
|
|
49
|
+
/** Console/stdout configuration */
|
|
50
|
+
console: ConsoleLogConfig;
|
|
51
|
+
/** File logging configuration */
|
|
52
|
+
file: FileLogConfig;
|
|
53
|
+
/** Log levels per class type */
|
|
54
|
+
classLevels: Partial<Record<ClassType, LogLevel>>;
|
|
55
|
+
/** Application name for log identification */
|
|
56
|
+
appName?: string;
|
|
57
|
+
/** Environment name (development, staging, production) */
|
|
58
|
+
environment?: string;
|
|
59
|
+
/** Custom sensitive fields to redact */
|
|
60
|
+
sensitiveFields?: string[];
|
|
61
|
+
/** Health check endpoint to skip logging */
|
|
62
|
+
healthCheckEndpoint?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Base log entry structure
|
|
66
|
+
*/
|
|
67
|
+
export interface BaseLogEntry {
|
|
68
|
+
level?: LogLevel;
|
|
69
|
+
message: string;
|
|
70
|
+
timestamp?: string;
|
|
71
|
+
[key: string]: unknown;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* HTTP request log entry
|
|
75
|
+
*/
|
|
76
|
+
export interface RequestLogEntry extends BaseLogEntry {
|
|
77
|
+
requestId?: string;
|
|
78
|
+
method?: string;
|
|
79
|
+
url?: string;
|
|
80
|
+
statusCode?: number;
|
|
81
|
+
responseTime?: string;
|
|
82
|
+
body?: Record<string, unknown>;
|
|
83
|
+
headers?: Record<string, unknown>;
|
|
84
|
+
error?: string | Error;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* AOP context for method logging
|
|
88
|
+
*/
|
|
89
|
+
export interface AOPContext {
|
|
90
|
+
methodName: string;
|
|
91
|
+
methodType: string;
|
|
92
|
+
classType: ClassType;
|
|
93
|
+
className: string;
|
|
94
|
+
startTime: number;
|
|
95
|
+
endTime?: number;
|
|
96
|
+
executionTime?: number;
|
|
97
|
+
url?: string;
|
|
98
|
+
method?: string;
|
|
99
|
+
body?: Record<string, unknown>;
|
|
100
|
+
result?: unknown;
|
|
101
|
+
responseBody?: unknown;
|
|
102
|
+
statusCode?: number;
|
|
103
|
+
message?: string;
|
|
104
|
+
error?: Error;
|
|
105
|
+
level?: LogLevel;
|
|
106
|
+
logType?: 'info' | 'error';
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Advice type for AOP logging
|
|
110
|
+
*/
|
|
111
|
+
export type AdviceType = 'before' | 'after' | 'around';
|
|
112
|
+
/**
|
|
113
|
+
* Advice phase during execution
|
|
114
|
+
*/
|
|
115
|
+
export type AdvicePhase = 'before' | 'after' | 'error';
|
|
116
|
+
/**
|
|
117
|
+
* Advice function signature
|
|
118
|
+
*/
|
|
119
|
+
export type AdviceFunction = (context: AOPContext, phase: AdvicePhase) => void;
|
|
120
|
+
/**
|
|
121
|
+
* Extended Express Request with logging properties
|
|
122
|
+
*/
|
|
123
|
+
export interface LoggingRequest extends Request {
|
|
124
|
+
requestId?: string;
|
|
125
|
+
startTime?: number;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Middleware function type
|
|
129
|
+
*/
|
|
130
|
+
export type LoggingMiddleware = (req: LoggingRequest, res: Response, next: NextFunction) => void;
|
|
131
|
+
/**
|
|
132
|
+
* Middleware configuration options
|
|
133
|
+
*/
|
|
134
|
+
export interface MiddlewareOptions {
|
|
135
|
+
/** Endpoints to skip logging */
|
|
136
|
+
skipEndpoints?: string[];
|
|
137
|
+
/** Whether to log request body */
|
|
138
|
+
logRequestBody?: boolean;
|
|
139
|
+
/** Whether to log response body */
|
|
140
|
+
logResponseBody?: boolean;
|
|
141
|
+
/** Custom request ID generator */
|
|
142
|
+
requestIdGenerator?: () => string;
|
|
143
|
+
/** Additional fields to extract from request */
|
|
144
|
+
additionalFields?: (req: Request) => Record<string, unknown>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Extended Winston logger with custom methods
|
|
148
|
+
*/
|
|
149
|
+
export interface ExtendedLogger extends winston.Logger {
|
|
150
|
+
/** Log with request context */
|
|
151
|
+
logRequest(entry: RequestLogEntry): void;
|
|
152
|
+
/** Log with custom metadata */
|
|
153
|
+
logWithMeta(level: LogLevel, message: string, meta?: Record<string, unknown>): void;
|
|
154
|
+
/** Get the current configuration */
|
|
155
|
+
getConfig(): LoggerConfig;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Object with string keys and any values (for sanitization)
|
|
159
|
+
*/
|
|
160
|
+
export type SanitizableObject = Record<string, unknown>;
|
|
161
|
+
/**
|
|
162
|
+
* Result of log formatting
|
|
163
|
+
*/
|
|
164
|
+
export interface FormattedLogEntry {
|
|
165
|
+
level: LogLevel;
|
|
166
|
+
message: string;
|
|
167
|
+
requestId: string;
|
|
168
|
+
method: string;
|
|
169
|
+
methodName: string;
|
|
170
|
+
url: string;
|
|
171
|
+
statusCode: string;
|
|
172
|
+
responseTime: string;
|
|
173
|
+
timestamp: string;
|
|
174
|
+
body: Record<string, unknown>;
|
|
175
|
+
error: string;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Environment variable names used by the logger
|
|
179
|
+
*/
|
|
180
|
+
export interface LoggerEnvVars {
|
|
181
|
+
LOG_TARGET: LogTarget;
|
|
182
|
+
LOG_TO_FILE: 'true' | 'false';
|
|
183
|
+
LOG_TO_CONSOLE: 'true' | 'false';
|
|
184
|
+
LOG_LEVEL: LogLevel;
|
|
185
|
+
LOG_DIR: string;
|
|
186
|
+
LOG_MAX_SIZE: string;
|
|
187
|
+
LOG_MAX_FILES: string;
|
|
188
|
+
LOG_DATE_PATTERN: string;
|
|
189
|
+
LOG_COLORIZE: 'true' | 'false';
|
|
190
|
+
LOG_LEVEL_CONTROLLERS: LogLevel;
|
|
191
|
+
LOG_LEVEL_SERVICES: LogLevel;
|
|
192
|
+
LOG_LEVEL_REPOSITORIES: LogLevel;
|
|
193
|
+
LOG_LEVEL_UTILS: LogLevel;
|
|
194
|
+
LOG_LEVEL_MIDDLEWARE: LogLevel;
|
|
195
|
+
LOG_LEVEL_ROUTES: LogLevel;
|
|
196
|
+
LOG_LEVEL_CONFIGURATION: LogLevel;
|
|
197
|
+
LOG_LEVEL_VALIDATORS: LogLevel;
|
|
198
|
+
LOG_LEVEL_EVENT_LISTENERS: LogLevel;
|
|
199
|
+
LOG_LEVEL_HELPERS: LogLevel;
|
|
200
|
+
LOG_LEVEL_JOBS: LogLevel;
|
|
201
|
+
LOG_LEVEL_MODELS: LogLevel;
|
|
202
|
+
LOG_LEVEL_TRANSFORMERS: LogLevel;
|
|
203
|
+
LOG_LEVEL_DEFAULT: LogLevel;
|
|
204
|
+
APP_NAME: string;
|
|
205
|
+
NODE_ENV: string;
|
|
206
|
+
HEALTHCHECK_ENDPOINT: string;
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SanitizableObject } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Recursively sanitize data by masking sensitive fields
|
|
4
|
+
*
|
|
5
|
+
* @param data - The data to sanitize
|
|
6
|
+
* @param sensitiveFields - Optional custom list of sensitive fields
|
|
7
|
+
* @param seen - Internal set to track circular references
|
|
8
|
+
* @returns Sanitized copy of the data
|
|
9
|
+
*/
|
|
10
|
+
export declare const sanitizeData: <T extends SanitizableObject | unknown>(data: T, sensitiveFields?: string[], seen?: WeakSet<object>) => T;
|
|
11
|
+
/**
|
|
12
|
+
* Sanitize headers, specifically targeting authorization-type headers
|
|
13
|
+
*/
|
|
14
|
+
export declare const sanitizeHeaders: (headers: Record<string, string | string[] | undefined>) => Record<string, string | string[] | undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* Truncate large values to prevent log bloat
|
|
17
|
+
*/
|
|
18
|
+
export declare const truncateValue: (value: unknown, maxLength?: number) => unknown;
|
|
19
|
+
/**
|
|
20
|
+
* Deep clone and sanitize for logging
|
|
21
|
+
*/
|
|
22
|
+
export declare const prepareForLogging: <T extends SanitizableObject>(data: T, options?: {
|
|
23
|
+
sensitiveFields?: string[];
|
|
24
|
+
truncateLength?: number;
|
|
25
|
+
}) => T;
|
|
26
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAa7C;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,iBAAiB,GAAG,OAAO,EAChE,MAAM,CAAC,EACP,kBAAkB,MAAM,EAAE,EAC1B,OAAM,OAAO,CAAC,MAAM,CAAiB,KACpC,CA6CF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,KACrD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CA6B9C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,OAAO,EACd,YAAW,MAAa,KACvB,OAUF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,iBAAiB,EAC3D,MAAM,CAAC,EACP,UAAU;IACR,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,KACA,CAwBF,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prepareForLogging = exports.truncateValue = exports.sanitizeHeaders = exports.sanitizeData = void 0;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
/**
|
|
6
|
+
* Check if a key matches any sensitive field (case-insensitive)
|
|
7
|
+
*/
|
|
8
|
+
const isSensitiveField = (key, sensitiveFields) => {
|
|
9
|
+
const lowerKey = key.toLowerCase();
|
|
10
|
+
return sensitiveFields.some((field) => field.toLowerCase() === lowerKey || lowerKey.includes(field.toLowerCase()));
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Recursively sanitize data by masking sensitive fields
|
|
14
|
+
*
|
|
15
|
+
* @param data - The data to sanitize
|
|
16
|
+
* @param sensitiveFields - Optional custom list of sensitive fields
|
|
17
|
+
* @param seen - Internal set to track circular references
|
|
18
|
+
* @returns Sanitized copy of the data
|
|
19
|
+
*/
|
|
20
|
+
const sanitizeData = (data, sensitiveFields, seen = new WeakSet()) => {
|
|
21
|
+
// Return primitives and null/undefined as-is
|
|
22
|
+
if (data === null || data === undefined) {
|
|
23
|
+
return data;
|
|
24
|
+
}
|
|
25
|
+
if (typeof data !== 'object') {
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
// Prevent circular references
|
|
29
|
+
if (seen.has(data)) {
|
|
30
|
+
return '[CIRCULAR REFERENCE]';
|
|
31
|
+
}
|
|
32
|
+
seen.add(data);
|
|
33
|
+
// Get sensitive fields from config or use provided/default
|
|
34
|
+
const fieldsToMask = sensitiveFields || (0, config_1.getConfig)()?.sensitiveFields || config_1.DEFAULT_SENSITIVE_FIELDS;
|
|
35
|
+
// Handle arrays
|
|
36
|
+
if (Array.isArray(data)) {
|
|
37
|
+
return data.map((item) => (0, exports.sanitizeData)(item, fieldsToMask, seen));
|
|
38
|
+
}
|
|
39
|
+
// Handle objects
|
|
40
|
+
const sanitized = {};
|
|
41
|
+
for (const [key, value] of Object.entries(data)) {
|
|
42
|
+
if (isSensitiveField(key, fieldsToMask)) {
|
|
43
|
+
// Mask sensitive string values
|
|
44
|
+
if (typeof value === 'string') {
|
|
45
|
+
sanitized[key] = '[REDACTED]';
|
|
46
|
+
}
|
|
47
|
+
else if (value !== null && value !== undefined) {
|
|
48
|
+
sanitized[key] = '[REDACTED]';
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
sanitized[key] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (typeof value === 'object' && value !== null) {
|
|
55
|
+
sanitized[key] = (0, exports.sanitizeData)(value, fieldsToMask, seen);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
sanitized[key] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return sanitized;
|
|
62
|
+
};
|
|
63
|
+
exports.sanitizeData = sanitizeData;
|
|
64
|
+
/**
|
|
65
|
+
* Sanitize headers, specifically targeting authorization-type headers
|
|
66
|
+
*/
|
|
67
|
+
const sanitizeHeaders = (headers) => {
|
|
68
|
+
const sensitiveHeaders = [
|
|
69
|
+
'authorization',
|
|
70
|
+
'x-api-key',
|
|
71
|
+
'x-auth-token',
|
|
72
|
+
'cookie',
|
|
73
|
+
'set-cookie',
|
|
74
|
+
'x-access-token',
|
|
75
|
+
'x-refresh-token',
|
|
76
|
+
];
|
|
77
|
+
const sanitized = { ...headers };
|
|
78
|
+
for (const header of sensitiveHeaders) {
|
|
79
|
+
if (sanitized[header]) {
|
|
80
|
+
sanitized[header] = '[REDACTED]';
|
|
81
|
+
}
|
|
82
|
+
// Also check lowercase and uppercase variants
|
|
83
|
+
const lowerHeader = header.toLowerCase();
|
|
84
|
+
const upperHeader = header.toUpperCase();
|
|
85
|
+
if (sanitized[lowerHeader]) {
|
|
86
|
+
sanitized[lowerHeader] = '[REDACTED]';
|
|
87
|
+
}
|
|
88
|
+
if (sanitized[upperHeader]) {
|
|
89
|
+
sanitized[upperHeader] = '[REDACTED]';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return sanitized;
|
|
93
|
+
};
|
|
94
|
+
exports.sanitizeHeaders = sanitizeHeaders;
|
|
95
|
+
/**
|
|
96
|
+
* Truncate large values to prevent log bloat
|
|
97
|
+
*/
|
|
98
|
+
const truncateValue = (value, maxLength = 1000) => {
|
|
99
|
+
if (typeof value === 'string' && value.length > maxLength) {
|
|
100
|
+
return `${value.substring(0, maxLength)}... [TRUNCATED: ${value.length} chars]`;
|
|
101
|
+
}
|
|
102
|
+
if (Array.isArray(value) && value.length > 100) {
|
|
103
|
+
return [...value.slice(0, 100), `... [TRUNCATED: ${value.length} items]`];
|
|
104
|
+
}
|
|
105
|
+
return value;
|
|
106
|
+
};
|
|
107
|
+
exports.truncateValue = truncateValue;
|
|
108
|
+
/**
|
|
109
|
+
* Deep clone and sanitize for logging
|
|
110
|
+
*/
|
|
111
|
+
const prepareForLogging = (data, options) => {
|
|
112
|
+
const sanitized = (0, exports.sanitizeData)(data, options?.sensitiveFields);
|
|
113
|
+
if (options?.truncateLength) {
|
|
114
|
+
const truncate = (obj) => {
|
|
115
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
116
|
+
return (0, exports.truncateValue)(obj, options.truncateLength);
|
|
117
|
+
}
|
|
118
|
+
if (Array.isArray(obj)) {
|
|
119
|
+
return obj.map(truncate);
|
|
120
|
+
}
|
|
121
|
+
const result = {};
|
|
122
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
123
|
+
result[key] = truncate(value);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
};
|
|
127
|
+
return truncate(sanitized);
|
|
128
|
+
}
|
|
129
|
+
return sanitized;
|
|
130
|
+
};
|
|
131
|
+
exports.prepareForLogging = prepareForLogging;
|
|
132
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"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"}
|