mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-05 21:13:07 +00:00
fix: update session validation tests to match relaxed validation behavior
- Updated "should return 400 for empty session ID" test to expect "Mcp-Session-Id header is required" instead of "Invalid session ID format" (empty strings are treated as missing headers) - Updated "should return 404 for non-existent session" test to verify any non-empty string format is accepted - Updated "should accept any non-empty string as session ID" test to comprehensively test all session ID formats - All 38 session management tests now pass This aligns with the relaxed session ID validation introduced in PR #309 for multi-tenant support. The server now accepts any non-empty string as a session ID to support various MCP clients (UUIDv4, instance-prefixed, mcp-remote, custom formats). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -780,13 +780,48 @@ describe('HTTP Server Session Management', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 400 for invalid session ID format', async () => {
|
it('should return 404 for non-existent session (any format accepted)', async () => {
|
||||||
|
server = new SingleSessionHTTPServer();
|
||||||
|
await server.start();
|
||||||
|
|
||||||
|
const handler = findHandler('delete', '/mcp');
|
||||||
|
|
||||||
|
// Test various session ID formats - all should pass validation
|
||||||
|
// but return 404 if session doesn't exist
|
||||||
|
const sessionIds = [
|
||||||
|
'invalid-session-id',
|
||||||
|
'instance-user123-abc-uuid',
|
||||||
|
'mcp-remote-session-xyz',
|
||||||
|
'short-id',
|
||||||
|
'12345'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const sessionId of sessionIds) {
|
||||||
|
const { req, res } = createMockReqRes();
|
||||||
|
req.headers = { 'mcp-session-id': sessionId };
|
||||||
|
req.method = 'DELETE';
|
||||||
|
|
||||||
|
await handler(req, res);
|
||||||
|
|
||||||
|
expect(res.status).toHaveBeenCalledWith(404); // Session not found
|
||||||
|
expect(res.json).toHaveBeenCalledWith({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
error: {
|
||||||
|
code: -32001,
|
||||||
|
message: 'Session not found'
|
||||||
|
},
|
||||||
|
id: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return 400 for empty session ID', async () => {
|
||||||
server = new SingleSessionHTTPServer();
|
server = new SingleSessionHTTPServer();
|
||||||
await server.start();
|
await server.start();
|
||||||
|
|
||||||
const handler = findHandler('delete', '/mcp');
|
const handler = findHandler('delete', '/mcp');
|
||||||
const { req, res } = createMockReqRes();
|
const { req, res } = createMockReqRes();
|
||||||
req.headers = { 'mcp-session-id': 'invalid-session-id' };
|
req.headers = { 'mcp-session-id': '' };
|
||||||
req.method = 'DELETE';
|
req.method = 'DELETE';
|
||||||
|
|
||||||
await handler(req, res);
|
await handler(req, res);
|
||||||
@@ -796,7 +831,7 @@ describe('HTTP Server Session Management', () => {
|
|||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
error: {
|
error: {
|
||||||
code: -32602,
|
code: -32602,
|
||||||
message: 'Invalid session ID format'
|
message: 'Mcp-Session-Id header is required'
|
||||||
},
|
},
|
||||||
id: null
|
id: null
|
||||||
});
|
});
|
||||||
@@ -912,40 +947,64 @@ describe('HTTP Server Session Management', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Session ID Validation', () => {
|
describe('Session ID Validation', () => {
|
||||||
it('should validate UUID v4 format correctly', async () => {
|
it('should accept any non-empty string as session ID', async () => {
|
||||||
server = new SingleSessionHTTPServer();
|
server = new SingleSessionHTTPServer();
|
||||||
|
|
||||||
const validUUIDs = [
|
// Valid session IDs - any non-empty string is accepted
|
||||||
'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee', // 8 is valid variant
|
const validSessionIds = [
|
||||||
'12345678-1234-4567-8901-123456789012', // 8 is valid variant
|
// UUIDv4 format (existing format - still valid)
|
||||||
'f47ac10b-58cc-4372-a567-0e02b2c3d479' // a is valid variant
|
'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee',
|
||||||
];
|
'12345678-1234-4567-8901-123456789012',
|
||||||
|
'f47ac10b-58cc-4372-a567-0e02b2c3d479',
|
||||||
|
|
||||||
const invalidUUIDs = [
|
// Instance-prefixed format (multi-tenant)
|
||||||
'invalid-uuid',
|
'instance-user123-abc123-550e8400-e29b-41d4-a716-446655440000',
|
||||||
'aaaaaaaa-bbbb-3ccc-8ddd-eeeeeeeeeeee', // Wrong version (3)
|
|
||||||
'aaaaaaaa-bbbb-4ccc-cddd-eeeeeeeeeeee', // Wrong variant (c)
|
// Custom formats (mcp-remote, proxies, etc.)
|
||||||
|
'mcp-remote-session-xyz',
|
||||||
|
'custom-session-format',
|
||||||
'short-uuid',
|
'short-uuid',
|
||||||
'',
|
'invalid-uuid', // "invalid" UUID is valid as generic string
|
||||||
'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee-extra'
|
'12345',
|
||||||
|
|
||||||
|
// Even "wrong" UUID versions are accepted (relaxed validation)
|
||||||
|
'aaaaaaaa-bbbb-3ccc-8ddd-eeeeeeeeeeee', // UUID v3
|
||||||
|
'aaaaaaaa-bbbb-4ccc-cddd-eeeeeeeeeeee', // Wrong variant
|
||||||
|
'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee-extra', // Extra chars
|
||||||
|
|
||||||
|
// Any non-empty string works
|
||||||
|
'anything-goes'
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const uuid of validUUIDs) {
|
// Invalid session IDs - only empty strings
|
||||||
expect((server as any).isValidSessionId(uuid)).toBe(true);
|
const invalidSessionIds = [
|
||||||
|
''
|
||||||
|
];
|
||||||
|
|
||||||
|
// All non-empty strings should be accepted
|
||||||
|
for (const sessionId of validSessionIds) {
|
||||||
|
expect((server as any).isValidSessionId(sessionId)).toBe(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const uuid of invalidUUIDs) {
|
// Only empty strings should be rejected
|
||||||
expect((server as any).isValidSessionId(uuid)).toBe(false);
|
for (const sessionId of invalidSessionIds) {
|
||||||
|
expect((server as any).isValidSessionId(sessionId)).toBe(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reject requests with invalid session ID format', async () => {
|
it('should accept non-empty strings, reject only empty strings', async () => {
|
||||||
server = new SingleSessionHTTPServer();
|
server = new SingleSessionHTTPServer();
|
||||||
|
|
||||||
// Test the validation method directly
|
// These should all be ACCEPTED (return true) - any non-empty string
|
||||||
expect((server as any).isValidSessionId('invalid-session-id')).toBe(false);
|
expect((server as any).isValidSessionId('invalid-session-id')).toBe(true);
|
||||||
expect((server as any).isValidSessionId('')).toBe(false);
|
expect((server as any).isValidSessionId('short')).toBe(true);
|
||||||
|
expect((server as any).isValidSessionId('instance-user-abc-123')).toBe(true);
|
||||||
|
expect((server as any).isValidSessionId('mcp-remote-xyz')).toBe(true);
|
||||||
|
expect((server as any).isValidSessionId('12345')).toBe(true);
|
||||||
expect((server as any).isValidSessionId('aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee')).toBe(true);
|
expect((server as any).isValidSessionId('aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee')).toBe(true);
|
||||||
|
|
||||||
|
// Only empty string should be REJECTED (return false)
|
||||||
|
expect((server as any).isValidSessionId('')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reject requests with non-existent session ID', async () => {
|
it('should reject requests with non-existent session ID', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user