/** * Secure Development Logger * * This logger only works in development mode and sanitizes all sensitive data. * In production, all logging is disabled to prevent credential leaks. */ const isDevelopment = (typeof import.meta !== 'undefined' && import.meta.env?.MODE === 'development') || process.env.NODE_ENV === 'development'; // List of sensitive patterns to redact const SENSITIVE_PATTERNS = [ /api[_-]?key/i, /token/i, /secret/i, /password/i, /auth/i, /credential/i, /bearer/i, /session[_-]?id/i, /user[_-]?id/i, /gemma/i, /supabase/i, /vite_/i ]; // Sanitize sensitive data from objects and strings function sanitizeData(data: any): any { if (data instanceof Error) { return { name: data.name, message: data.message, }; } if (typeof data === 'string') { // Redact sensitive strings for (const pattern of SENSITIVE_PATTERNS) { if (pattern.test(data)) { return '[REDACTED]'; } } return data; } if (typeof data === 'object' && data !== null) { if (Array.isArray(data)) { return data.map(sanitizeData); } const sanitized: any = {}; for (const [key, value] of Object.entries(data)) { // Check if key looks sensitive const isSensitiveKey = SENSITIVE_PATTERNS.some(pattern => pattern.test(key)); if (isSensitiveKey) { sanitized[key] = '[REDACTED]'; } else { sanitized[key] = sanitizeData(value); } } return sanitized; } return data; } // Safe logger that only works in development export const logger = { log: (...args: any[]) => { if (!isDevelopment) return; const sanitizedArgs = args.map(sanitizeData); console.log(...sanitizedArgs); }, error: (...args: any[]) => { if (!isDevelopment) return; const sanitizedArgs = args.map(sanitizeData); console.error(...sanitizedArgs); }, warn: (...args: any[]) => { if (!isDevelopment) return; const sanitizedArgs = args.map(sanitizeData); console.warn(...sanitizedArgs); }, info: (...args: any[]) => { if (!isDevelopment) return; const sanitizedArgs = args.map(sanitizeData); console.info(...sanitizedArgs); }, debug: (...args: any[]) => { if (!isDevelopment) return; const sanitizedArgs = args.map(sanitizeData); console.debug(...sanitizedArgs); } }; // Production-safe performance monitoring export const performanceLogger = { time: (label: string) => { if (!isDevelopment) return; console.time(label); }, timeEnd: (label: string) => { if (!isDevelopment) return; console.timeEnd(label); } }; export default logger;