UNPKG

syntropylog

Version:

An instance manager with observability for Node.js applications

67 lines 2.85 kB
/** * @file src/http/utils/redact.ts * @description Provides utility functions for redacting sensitive information * from objects and headers, crucial for secure logging. */ /** @private The placeholder string used to replace redacted values. */ const REDACTED_PLACEHOLDER = '[REDACTED]'; /** * Deeply clones and redacts sensitive fields from an object or array. * This function is designed to be safe and avoid modifying the original object. * @param {any} data - The object or array to redact. * @param {string[]} [sensitiveFields=[]] - An array of keys (strings) to be redacted, matched case-insensitively. * @param {number} [maxDepth=10] - The maximum recursion depth to prevent infinite loops. * @returns A new object or array with sensitive fields redacted. */ export function redactObject(data, sensitiveFields = [], maxDepth = 10) { const sensitiveSet = new Set(sensitiveFields.map((f) => f.toLowerCase())); const redactRecursive = (currentData, depth) => { if (depth >= maxDepth) { return '[REDACTED_DUE_TO_DEPTH]'; } if (Array.isArray(currentData)) { return currentData.map((item) => redactRecursive(item, depth + 1)); } if (currentData && typeof currentData === 'object' && !Buffer.isBuffer(currentData)) { const clonedObj = {}; for (const key in currentData) { if (Object.prototype.hasOwnProperty.call(currentData, key)) { if (sensitiveSet.has(key.toLowerCase())) { clonedObj[key] = REDACTED_PLACEHOLDER; } else { clonedObj[key] = redactRecursive(currentData[key], depth + 1); } } } return clonedObj; } return currentData; }; return redactRecursive(data, 0); } /** * Redacts sensitive headers from a headers object. * Header names are treated case-insensitively. * @param {Record<string, any>} headers - The headers object (e.g., from an HTTP request). * @param {string[]} [sensitiveHeaders=[]] - An array of header names to redact. * @returns A new headers object with sensitive values redacted. */ export function redactHeaders(headers, sensitiveHeaders = []) { if (!headers || !sensitiveHeaders || sensitiveHeaders.length === 0) { return headers; } const clonedHeaders = {}; const sensitiveSet = new Set(sensitiveHeaders.map((h) => h.toLowerCase())); for (const key in headers) { if (Object.prototype.hasOwnProperty.call(headers, key)) { clonedHeaders[key] = sensitiveSet.has(key.toLowerCase()) ? REDACTED_PLACEHOLDER : headers[key]; } } return clonedHeaders; } //# sourceMappingURL=redact.js.map