mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-03-19 00:43:07 +00:00
- Add InstanceContext interface for runtime configuration - Implement dual-mode API client (singleton + instance-specific) - Add secure SHA-256 hashing for cache keys - Implement LRU cache with TTL (100 instances, 30min expiry) - Add comprehensive input validation for URLs and API keys - Sanitize all logging to prevent API key exposure - Fix session context cleanup and memory management - Add comprehensive security and integration tests - Maintain full backward compatibility for single-player usage Security improvements based on code review: - Cache keys are now cryptographically hashed - API credentials never appear in logs - Memory-bounded cache prevents resource exhaustion - Input validation rejects invalid/placeholder values - Proper cleanup of orphaned session contexts 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
import { z } from 'zod';
|
|
import dotenv from 'dotenv';
|
|
import { logger } from '../utils/logger';
|
|
|
|
// n8n API configuration schema
|
|
const n8nApiConfigSchema = z.object({
|
|
N8N_API_URL: z.string().url().optional(),
|
|
N8N_API_KEY: z.string().min(1).optional(),
|
|
N8N_API_TIMEOUT: z.coerce.number().positive().default(30000),
|
|
N8N_API_MAX_RETRIES: z.coerce.number().positive().default(3),
|
|
});
|
|
|
|
// Track if we've loaded env vars
|
|
let envLoaded = false;
|
|
|
|
// Parse and validate n8n API configuration
|
|
export function getN8nApiConfig() {
|
|
// Load environment variables on first access
|
|
if (!envLoaded) {
|
|
dotenv.config();
|
|
envLoaded = true;
|
|
}
|
|
|
|
const result = n8nApiConfigSchema.safeParse(process.env);
|
|
|
|
if (!result.success) {
|
|
return null;
|
|
}
|
|
|
|
const config = result.data;
|
|
|
|
// Check if both URL and API key are provided
|
|
if (!config.N8N_API_URL || !config.N8N_API_KEY) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
baseUrl: config.N8N_API_URL,
|
|
apiKey: config.N8N_API_KEY,
|
|
timeout: config.N8N_API_TIMEOUT,
|
|
maxRetries: config.N8N_API_MAX_RETRIES,
|
|
};
|
|
}
|
|
|
|
// Helper to check if n8n API is configured (lazy check)
|
|
export function isN8nApiConfigured(): boolean {
|
|
const config = getN8nApiConfig();
|
|
return config !== null;
|
|
}
|
|
|
|
/**
|
|
* Create n8n API configuration from instance context
|
|
* Used for flexible instance configuration support
|
|
*/
|
|
export function getN8nApiConfigFromContext(context: {
|
|
n8nApiUrl?: string;
|
|
n8nApiKey?: string;
|
|
n8nApiTimeout?: number;
|
|
n8nApiMaxRetries?: number;
|
|
}): N8nApiConfig | null {
|
|
if (!context.n8nApiUrl || !context.n8nApiKey) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
baseUrl: context.n8nApiUrl,
|
|
apiKey: context.n8nApiKey,
|
|
timeout: context.n8nApiTimeout ?? 30000,
|
|
maxRetries: context.n8nApiMaxRetries ?? 3,
|
|
};
|
|
}
|
|
|
|
// Type export
|
|
export type N8nApiConfig = NonNullable<ReturnType<typeof getN8nApiConfig>>; |