mcp-ssh-tool
Version:
Model Context Protocol (MCP) SSH client server for remote automation
127 lines • 3.53 kB
JavaScript
/**
* 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