diff --git a/data/nodes.db b/data/nodes.db index b1d06e7..78d433d 100644 Binary files a/data/nodes.db and b/data/nodes.db differ diff --git a/package.runtime.json b/package.runtime.json index bf308fb..80d0c84 100644 --- a/package.runtime.json +++ b/package.runtime.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp-runtime", - "version": "2.15.0", + "version": "2.15.1", "description": "n8n MCP Server Runtime Dependencies Only", "private": true, "dependencies": { diff --git a/tests/integration/n8n-api/utils/cleanup-helpers.ts b/tests/integration/n8n-api/utils/cleanup-helpers.ts index 44e50f3..6d5b71e 100644 --- a/tests/integration/n8n-api/utils/cleanup-helpers.ts +++ b/tests/integration/n8n-api/utils/cleanup-helpers.ts @@ -32,11 +32,18 @@ export async function cleanupOrphanedWorkflows(): Promise { let allWorkflows: any[] = []; let cursor: string | undefined; let pageCount = 0; + const MAX_PAGES = 1000; // Safety limit to prevent infinite loops // Fetch all workflows with pagination try { do { pageCount++; + + if (pageCount > MAX_PAGES) { + logger.error(`Exceeded maximum pages (${MAX_PAGES}). Possible infinite loop or API issue.`); + throw new Error('Pagination safety limit exceeded while fetching workflows'); + } + logger.debug(`Fetching workflows page ${pageCount}...`); const response = await client.listWorkflows({ @@ -101,11 +108,18 @@ export async function cleanupOldExecutions( let allExecutions: any[] = []; let cursor: string | undefined; let pageCount = 0; + const MAX_PAGES = 1000; // Safety limit to prevent infinite loops // Fetch all executions try { do { pageCount++; + + if (pageCount > MAX_PAGES) { + logger.error(`Exceeded maximum pages (${MAX_PAGES}). Possible infinite loop or API issue.`); + throw new Error('Pagination safety limit exceeded while fetching executions'); + } + logger.debug(`Fetching executions page ${pageCount}...`); const response = await client.listExecutions({ @@ -239,9 +253,18 @@ export async function cleanupExecutionsByWorkflow( let cursor: string | undefined; let totalCount = 0; + let pageCount = 0; + const MAX_PAGES = 1000; // Safety limit to prevent infinite loops try { do { + pageCount++; + + if (pageCount > MAX_PAGES) { + logger.error(`Exceeded maximum pages (${MAX_PAGES}). Possible infinite loop or API issue.`); + throw new Error(`Pagination safety limit exceeded while fetching executions for workflow ${workflowId}`); + } + const response = await client.listExecutions({ workflowId, cursor, diff --git a/tests/integration/n8n-api/utils/credentials.ts b/tests/integration/n8n-api/utils/credentials.ts index cb9044a..ea171c9 100644 --- a/tests/integration/n8n-api/utils/credentials.ts +++ b/tests/integration/n8n-api/utils/credentials.ts @@ -39,15 +39,27 @@ export interface N8nTestCredentials { */ export function getN8nCredentials(): N8nTestCredentials { if (process.env.CI) { - // CI: Use GitHub secrets + // CI: Use GitHub secrets - validate required variables first + const url = process.env.N8N_URL; + const apiKey = process.env.N8N_API_KEY; + + if (!url || !apiKey) { + throw new Error( + 'Missing required CI credentials:\n' + + ` N8N_URL: ${url ? 'set' : 'MISSING'}\n` + + ` N8N_API_KEY: ${apiKey ? 'set' : 'MISSING'}\n` + + 'Please configure GitHub secrets for integration tests.' + ); + } + return { - url: process.env.N8N_URL!, - apiKey: process.env.N8N_API_KEY!, + url, + apiKey, webhookWorkflows: { - get: process.env.N8N_TEST_WEBHOOK_GET_ID!, - post: process.env.N8N_TEST_WEBHOOK_POST_ID!, - put: process.env.N8N_TEST_WEBHOOK_PUT_ID!, - delete: process.env.N8N_TEST_WEBHOOK_DELETE_ID! + get: process.env.N8N_TEST_WEBHOOK_GET_ID || '', + post: process.env.N8N_TEST_WEBHOOK_POST_ID || '', + put: process.env.N8N_TEST_WEBHOOK_PUT_ID || '', + delete: process.env.N8N_TEST_WEBHOOK_DELETE_ID || '' }, cleanup: { enabled: true, @@ -56,10 +68,23 @@ export function getN8nCredentials(): N8nTestCredentials { } }; } else { - // Local: Use .env file + // Local: Use .env file - validate required variables first + const url = process.env.N8N_API_URL; + const apiKey = process.env.N8N_API_KEY; + + if (!url || !apiKey) { + throw new Error( + 'Missing required credentials in .env:\n' + + ` N8N_API_URL: ${url ? 'set' : 'MISSING'}\n` + + ` N8N_API_KEY: ${apiKey ? 'set' : 'MISSING'}\n\n` + + 'Please add these to your .env file.\n' + + 'See .env.example for configuration details.' + ); + } + return { - url: process.env.N8N_API_URL!, - apiKey: process.env.N8N_API_KEY!, + url, + apiKey, webhookWorkflows: { get: process.env.N8N_TEST_WEBHOOK_GET_ID || '', post: process.env.N8N_TEST_WEBHOOK_POST_ID || '',