mcp-cve-intelligence-server-lite-test
Version:
Lite Model Context Protocol server for comprehensive CVE intelligence gathering with multi-source exploit discovery, designed for security professionals and cybersecurity researchers - Alpha Release
169 lines • 5.03 kB
JavaScript
import { createContextLogger } from '../utils/logger.js';
const logger = createContextLogger('TransportSessionManager');
export class TransportSessionManager {
sessions = new Map();
sessionTimeout;
constructor(sessionTimeoutMs = 30 * 60 * 1000) {
this.sessionTimeout = sessionTimeoutMs;
this.startCleanupInterval();
}
/**
* Create a new session
*/
createSession(sessionId, transportType, metadata) {
const sessionInfo = {
sessionId,
transportType,
createdAt: new Date(),
lastActivity: new Date(),
metadata,
};
this.sessions.set(sessionId, sessionInfo);
logger.info('Session created', {
sessionId,
transportType,
totalSessions: this.sessions.size,
});
}
/**
* Update session activity
*/
updateSessionActivity(sessionId) {
const session = this.sessions.get(sessionId);
if (session) {
session.lastActivity = new Date();
}
}
/**
* Remove a session
*/
removeSession(sessionId) {
const removed = this.sessions.delete(sessionId);
if (removed) {
logger.info('Session removed', {
sessionId,
totalSessions: this.sessions.size,
});
}
return removed;
}
/**
* Get session information
*/
getSession(sessionId) {
return this.sessions.get(sessionId);
}
/**
* Get all active sessions
*/
getAllSessions() {
return Array.from(this.sessions.values());
}
/**
* Get sessions by transport type
*/
getSessionsByType(transportType) {
return Array.from(this.sessions.values()).filter(s => s.transportType === transportType);
}
/**
* Get session count
*/
getSessionCount() {
return this.sessions.size;
}
/**
* Get session count by transport type
*/
getSessionCountByType(transportType) {
return this.getSessionsByType(transportType).length;
}
/**
* Check if a session exists
*/
hasSession(sessionId) {
return this.sessions.has(sessionId);
}
/**
* Clean up expired sessions
*/
cleanupExpiredSessions() {
const now = new Date();
const expiredSessions = [];
for (const [sessionId, session] of this.sessions) {
const timeSinceActivity = now.getTime() - session.lastActivity.getTime();
if (timeSinceActivity > this.sessionTimeout) {
expiredSessions.push(sessionId);
}
}
for (const sessionId of expiredSessions) {
this.removeSession(sessionId);
}
if (expiredSessions.length > 0) {
logger.info('Cleaned up expired sessions', {
expiredCount: expiredSessions.length,
remainingSessions: this.sessions.size,
});
}
return expiredSessions.length;
}
/**
* Get session statistics
*/
getSessionStats() {
const sessions = this.getAllSessions();
const now = new Date();
if (sessions.length === 0) {
return {
total: 0,
byType: { stdio: 0, http: 0 },
averageAge: 0,
};
}
const byType = sessions.reduce((acc, session) => {
acc[session.transportType] = (acc[session.transportType] || 0) + 1;
return acc;
}, {});
const ages = sessions.map(s => now.getTime() - s.createdAt.getTime());
const averageAge = ages.reduce((sum, age) => sum + age, 0) / ages.length;
const sortedByCreation = sessions.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
return {
total: sessions.length,
byType,
oldestSession: sortedByCreation[0]?.createdAt,
newestSession: sortedByCreation[sortedByCreation.length - 1]?.createdAt,
averageAge,
};
}
/**
* Start the cleanup interval
*/
startCleanupInterval() {
// Run cleanup every 10 minutes
setInterval(() => {
this.cleanupExpiredSessions();
}, 10 * 60 * 1000);
logger.info('Session cleanup interval started', {
intervalMs: 10 * 60 * 1000,
timeoutMs: this.sessionTimeout,
});
}
/**
* Set session metadata
*/
setSessionMetadata(sessionId, metadata) {
const session = this.sessions.get(sessionId);
if (session) {
session.metadata = { ...session.metadata, ...metadata };
this.updateSessionActivity(sessionId);
return true;
}
return false;
}
/**
* Get session metadata
*/
getSessionMetadata(sessionId) {
return this.sessions.get(sessionId)?.metadata;
}
}
//# sourceMappingURL=transport-session-manager.js.map