const SENSITIVE_KEYS = new Set([ 'password', 'currentpassword', 'newpassword', 'passwordhash', 'token', 'accesstoken', 'refreshtoken', 'refreshtokenhash', 'authorization', 'cookie', 'cookies', 'setcookie', 'secret', 'pepper', 'jwt', ]); function normalizedKey(key: string): string { return key.replaceAll(/[^a-zA-Z0-9]/g, '').toLowerCase(); } export function sanitizeAuditData( value: unknown, seen = new WeakSet(), ): unknown { if (value === null || value === undefined) return value; if (value instanceof Date) return value.toISOString(); if (Array.isArray(value)) { return value.map((entry) => sanitizeAuditData(entry, seen)); } if (typeof value !== 'object') return value; if (seen.has(value)) return '[CIRCULAR]'; seen.add(value); const sanitized: Record = {}; for (const [key, entry] of Object.entries(value)) { sanitized[key] = SENSITIVE_KEYS.has(normalizedKey(key)) ? '[REDACTED]' : sanitizeAuditData(entry, seen); } return sanitized; }