UNPKG

mcp-ssh-tool

Version:

Model Context Protocol (MCP) SSH client server for remote automation

127 lines 3.53 kB
/** * Logging utilities with sensitive data redaction */ const SENSITIVE_FIELDS = ['password', 'privateKey', 'passphrase', 'sudoPassword']; const REDACTED = '****'; /** * Redacts sensitive information from an object */ export function redactSensitiveData(obj) { if (obj === null || obj === undefined) { return obj; } if (typeof obj === 'string') { return obj; } if (Array.isArray(obj)) { return obj.map(redactSensitiveData); } if (typeof obj === 'object') { const redacted = {}; for (const [key, value] of Object.entries(obj)) { if (SENSITIVE_FIELDS.includes(key.toLowerCase())) { redacted[key] = value ? REDACTED : value; } else { redacted[key] = redactSensitiveData(value); } } return redacted; } return obj; } /** * Redacts sensitive information from error messages and stack traces */ export function redactErrorMessage(message) { // Common patterns that might contain sensitive data const patterns = [ /password[=:\s]+[^\s]+/gi, /key[=:\s]+[^\s]+/gi, /passphrase[=:\s]+[^\s]+/gi, /-----BEGIN[^-]+-----[\s\S]*?-----END[^-]+-----/gi ]; let redacted = message; for (const pattern of patterns) { redacted = redacted.replace(pattern, REDACTED); } return redacted; } /** * Logger levels */ export var LogLevel; (function (LogLevel) { LogLevel[LogLevel["ERROR"] = 0] = "ERROR"; LogLevel[LogLevel["WARN"] = 1] = "WARN"; LogLevel[LogLevel["INFO"] = 2] = "INFO"; LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG"; })(LogLevel || (LogLevel = {})); /** * Simple logger with redaction */ export class Logger { level; constructor(level = LogLevel.INFO) { this.level = level; } log(level, message, data) { if (level > this.level) { return; } const timestamp = new Date().toISOString(); const levelName = LogLevel[level]; let output = `[${timestamp}] ${levelName}: ${message}`; if (data !== undefined) { const redactedData = redactSensitiveData(data); output += ` ${JSON.stringify(redactedData)}`; } // Write to stderr to avoid interfering with MCP stdio process.stderr.write(output + '\n'); } error(message, data) { const redactedMessage = redactErrorMessage(message); this.log(LogLevel.ERROR, redactedMessage, data); } warn(message, data) { this.log(LogLevel.WARN, message, data); } info(message, data) { this.log(LogLevel.INFO, message, data); } debug(message, data) { this.log(LogLevel.DEBUG, message, data); } } // Global logger instance const LOG_LEVEL_MAP = { 'error': LogLevel.ERROR, 'warn': LogLevel.WARN, 'info': LogLevel.INFO, 'debug': LogLevel.DEBUG }; const envLogLevel = process.env.LOG_LEVEL?.toLowerCase() || 'info'; const logLevel = LOG_LEVEL_MAP[envLogLevel] ?? LogLevel.INFO; export const logger = new Logger(logLevel); /** * Performance measurement utilities */ export class Timer { startTime; constructor() { this.startTime = Date.now(); } elapsed() { return Date.now() - this.startTime; } reset() { this.startTime = Date.now(); } } /** * Creates a timer for measuring operation duration */ export function createTimer() { return new Timer(); } //# sourceMappingURL=logging.js.map