Files
n8n-mcp/src/types/session-state.ts
Romuald Członkowski 05424f66af feat: Session Persistence API for Zero-Downtime Deployments (v2.24.1) (#438)
* feat: Add session persistence API for zero-downtime deployments (v2.24.1)

Implements export/restore functionality for MCP sessions to support container
restarts without losing user sessions. This enables zero-downtime deployments
for multi-tenant platforms and Kubernetes/Docker environments.

New Features:
- exportSessionState() - Export active sessions to JSON
- restoreSessionState() - Restore sessions from exported data
- SessionState type - Serializable session structure
- Comprehensive test suite (22 tests, 100% passing)

Implementation Details:
- Only exports sessions with valid n8nApiUrl and n8nApiKey
- Automatically filters expired sessions (respects sessionTimeout)
- Validates context structure using existing validation
- Handles null/invalid sessions gracefully with warnings
- Enforces MAX_SESSIONS limit during restore (100 sessions)
- Dormant sessions recreate transport/server on first request

Files Modified:
- src/http-server-single-session.ts: Core export/restore logic
- src/mcp-engine.ts: Public API wrapper methods
- src/types/session-state.ts: Type definitions
- tests/: Comprehensive unit tests

Security Note:
Session data contains plaintext n8n API keys. Downstream applications
MUST encrypt session data before persisting to disk.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

* feat: implement 7 critical session persistence API fixes for production readiness

This commit implements all 7 critical fixes identified in the code review
to make the session persistence API production-ready for zero-downtime
container deployments in multi-tenant environments.

Fixes implemented:
1. Made instanceId optional in SessionState interface
2. Removed redundant validation, properly using validateInstanceContext()
3. Fixed race condition in MAX_SESSIONS check using real-time count
4. Added comprehensive security logging with logSecurityEvent() helper
5. Added duplicate session ID detection during export with Set tracking
6. Added date parsing validation with isNaN checks for Invalid Date objects
7. Restructured null checks for proper TypeScript type narrowing

Changes:
- src/types/session-state.ts: Made instanceId optional
- src/http-server-single-session.ts: Implemented all validation and security fixes
- tests/unit/http-server/session-persistence.test.ts: Fixed MAX_SESSIONS test

All 13 session persistence unit tests passing.
All 9 MCP engine session persistence tests passing.

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 18:53:26 +01:00

93 lines
2.5 KiB
TypeScript

/**
* Session persistence types for multi-tenant deployments
*
* These types support exporting and restoring MCP session state across
* container restarts, enabling seamless session persistence in production.
*/
import { InstanceContext } from './instance-context.js';
/**
* Serializable session state for persistence across restarts
*
* This interface represents the minimal state needed to restore an MCP session
* after a container restart. Only the session metadata and instance context are
* persisted - transport and server objects are recreated on the first request.
*
* @example
* // Export sessions before shutdown
* const sessions = server.exportSessionState();
* await saveToEncryptedStorage(sessions);
*
* @example
* // Restore sessions on startup
* const sessions = await loadFromEncryptedStorage();
* const count = server.restoreSessionState(sessions);
* console.log(`Restored ${count} sessions`);
*/
export interface SessionState {
/**
* Unique session identifier
* Format: UUID v4 or custom format from MCP proxy
*/
sessionId: string;
/**
* Session timing metadata for expiration tracking
*/
metadata: {
/**
* When the session was created (ISO 8601 timestamp)
* Used to track total session age
*/
createdAt: string;
/**
* When the session was last accessed (ISO 8601 timestamp)
* Used to determine if session has expired based on timeout
*/
lastAccess: string;
};
/**
* n8n instance context (credentials and configuration)
*
* Contains the n8n API credentials and instance-specific settings.
* This is the critical data needed to reconnect to the correct n8n instance.
*
* Note: API keys are stored in plaintext. The downstream application
* MUST encrypt this data before persisting to disk.
*/
context: {
/**
* n8n instance API URL
* Example: "https://n8n.example.com"
*/
n8nApiUrl: string;
/**
* n8n instance API key (plaintext - encrypt before storage!)
* Example: "n8n_api_1234567890abcdef"
*/
n8nApiKey: string;
/**
* Instance identifier (optional)
* Custom identifier for tracking which n8n instance this session belongs to
*/
instanceId?: string;
/**
* Session-specific ID (optional)
* May differ from top-level sessionId in some proxy configurations
*/
sessionId?: string;
/**
* Additional metadata (optional)
* Extensible field for custom application data
*/
metadata?: Record<string, any>;
};
}