@pan-sec/notebooklm-mcp 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/SECURITY.md +539 -0
- package/dist/auth/auth-manager.d.ts +137 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.js +984 -0
- package/dist/auth/auth-manager.js.map +1 -0
- package/dist/auth/mcp-auth.d.ts +102 -0
- package/dist/auth/mcp-auth.d.ts.map +1 -0
- package/dist/auth/mcp-auth.js +286 -0
- package/dist/auth/mcp-auth.js.map +1 -0
- package/dist/config.d.ts +89 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +216 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +371 -0
- package/dist/index.js.map +1 -0
- package/dist/library/notebook-library.d.ts +70 -0
- package/dist/library/notebook-library.d.ts.map +1 -0
- package/dist/library/notebook-library.js +279 -0
- package/dist/library/notebook-library.js.map +1 -0
- package/dist/library/types.d.ts +67 -0
- package/dist/library/types.d.ts.map +1 -0
- package/dist/library/types.js +8 -0
- package/dist/library/types.js.map +1 -0
- package/dist/resources/resource-handlers.d.ts +22 -0
- package/dist/resources/resource-handlers.d.ts.map +1 -0
- package/dist/resources/resource-handlers.js +216 -0
- package/dist/resources/resource-handlers.js.map +1 -0
- package/dist/session/browser-session.d.ts +108 -0
- package/dist/session/browser-session.d.ts.map +1 -0
- package/dist/session/browser-session.js +621 -0
- package/dist/session/browser-session.js.map +1 -0
- package/dist/session/session-manager.d.ts +77 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +314 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/session-timeout.d.ts +122 -0
- package/dist/session/session-timeout.d.ts.map +1 -0
- package/dist/session/session-timeout.js +281 -0
- package/dist/session/session-timeout.js.map +1 -0
- package/dist/session/shared-context-manager.d.ts +107 -0
- package/dist/session/shared-context-manager.d.ts.map +1 -0
- package/dist/session/shared-context-manager.js +447 -0
- package/dist/session/shared-context-manager.js.map +1 -0
- package/dist/tools/definitions/ask-question.d.ts +8 -0
- package/dist/tools/definitions/ask-question.d.ts.map +1 -0
- package/dist/tools/definitions/ask-question.js +211 -0
- package/dist/tools/definitions/ask-question.js.map +1 -0
- package/dist/tools/definitions/notebook-management.d.ts +3 -0
- package/dist/tools/definitions/notebook-management.d.ts.map +1 -0
- package/dist/tools/definitions/notebook-management.js +243 -0
- package/dist/tools/definitions/notebook-management.js.map +1 -0
- package/dist/tools/definitions/session-management.d.ts +3 -0
- package/dist/tools/definitions/session-management.d.ts.map +1 -0
- package/dist/tools/definitions/session-management.js +41 -0
- package/dist/tools/definitions/session-management.js.map +1 -0
- package/dist/tools/definitions/system.d.ts +3 -0
- package/dist/tools/definitions/system.d.ts.map +1 -0
- package/dist/tools/definitions/system.js +143 -0
- package/dist/tools/definitions/system.js.map +1 -0
- package/dist/tools/definitions.d.ts +12 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +26 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/handlers.d.ts +213 -0
- package/dist/tools/handlers.d.ts.map +1 -0
- package/dist/tools/handlers.js +813 -0
- package/dist/tools/handlers.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/audit-logger.d.ts +140 -0
- package/dist/utils/audit-logger.d.ts.map +1 -0
- package/dist/utils/audit-logger.js +361 -0
- package/dist/utils/audit-logger.js.map +1 -0
- package/dist/utils/cert-pinning.d.ts +97 -0
- package/dist/utils/cert-pinning.d.ts.map +1 -0
- package/dist/utils/cert-pinning.js +328 -0
- package/dist/utils/cert-pinning.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +133 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +673 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/cli-handler.d.ts +16 -0
- package/dist/utils/cli-handler.d.ts.map +1 -0
- package/dist/utils/cli-handler.js +102 -0
- package/dist/utils/cli-handler.js.map +1 -0
- package/dist/utils/crypto.d.ts +175 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +612 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +92 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/page-utils.d.ts +54 -0
- package/dist/utils/page-utils.d.ts.map +1 -0
- package/dist/utils/page-utils.js +405 -0
- package/dist/utils/page-utils.js.map +1 -0
- package/dist/utils/response-validator.d.ts +98 -0
- package/dist/utils/response-validator.d.ts.map +1 -0
- package/dist/utils/response-validator.js +352 -0
- package/dist/utils/response-validator.js.map +1 -0
- package/dist/utils/secrets-scanner.d.ts +126 -0
- package/dist/utils/secrets-scanner.d.ts.map +1 -0
- package/dist/utils/secrets-scanner.js +443 -0
- package/dist/utils/secrets-scanner.js.map +1 -0
- package/dist/utils/secure-memory.d.ts +130 -0
- package/dist/utils/secure-memory.d.ts.map +1 -0
- package/dist/utils/secure-memory.js +279 -0
- package/dist/utils/secure-memory.js.map +1 -0
- package/dist/utils/security.d.ts +83 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +272 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/settings-manager.d.ts +37 -0
- package/dist/utils/settings-manager.d.ts.map +1 -0
- package/dist/utils/settings-manager.js +125 -0
- package/dist/utils/settings-manager.js.map +1 -0
- package/dist/utils/stealth-utils.d.ts +135 -0
- package/dist/utils/stealth-utils.d.ts.map +1 -0
- package/dist/utils/stealth-utils.js +398 -0
- package/dist/utils/stealth-utils.js.map +1 -0
- package/dist/utils/tool-validation.d.ts +93 -0
- package/dist/utils/tool-validation.d.ts.map +1 -0
- package/dist/utils/tool-validation.js +277 -0
- package/dist/utils/tool-validation.js.map +1 -0
- package/docs/SECURITY_IMPLEMENTATION_PLAN.md +437 -0
- package/docs/configuration.md +94 -0
- package/docs/tools.md +34 -0
- package/docs/troubleshooting.md +59 -0
- package/docs/usage-guide.md +245 -0
- package/package.json +82 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages multiple parallel browser sessions for NotebookLM API
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Session lifecycle management
|
|
8
|
+
* - Auto-cleanup of inactive sessions
|
|
9
|
+
* - Resource limits (max concurrent sessions)
|
|
10
|
+
* - Shared PERSISTENT browser fingerprint (ONE context for all sessions)
|
|
11
|
+
*
|
|
12
|
+
* Based on the Python implementation from session_manager.py
|
|
13
|
+
*/
|
|
14
|
+
import { AuthManager } from "../auth/auth-manager.js";
|
|
15
|
+
import { BrowserSession } from "./browser-session.js";
|
|
16
|
+
import type { SessionInfo } from "../types.js";
|
|
17
|
+
export declare class SessionManager {
|
|
18
|
+
private authManager;
|
|
19
|
+
private sharedContextManager;
|
|
20
|
+
private sessions;
|
|
21
|
+
private maxSessions;
|
|
22
|
+
private sessionTimeout;
|
|
23
|
+
private cleanupInterval?;
|
|
24
|
+
private timeoutManager;
|
|
25
|
+
constructor(authManager: AuthManager);
|
|
26
|
+
/**
|
|
27
|
+
* Generate a unique session ID
|
|
28
|
+
*/
|
|
29
|
+
private generateSessionId;
|
|
30
|
+
/**
|
|
31
|
+
* Get existing session or create a new one
|
|
32
|
+
*
|
|
33
|
+
* @param sessionId Optional session ID to reuse existing session
|
|
34
|
+
* @param notebookUrl Notebook URL for the session
|
|
35
|
+
* @param overrideHeadless Optional override for headless mode (true = show browser)
|
|
36
|
+
*/
|
|
37
|
+
getOrCreateSession(sessionId?: string, notebookUrl?: string, overrideHeadless?: boolean): Promise<BrowserSession>;
|
|
38
|
+
/**
|
|
39
|
+
* Get an existing session by ID
|
|
40
|
+
*/
|
|
41
|
+
getSession(sessionId: string): BrowserSession | null;
|
|
42
|
+
/**
|
|
43
|
+
* Close and remove a specific session
|
|
44
|
+
*/
|
|
45
|
+
closeSession(sessionId: string): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Close all sessions that are using the provided notebook URL
|
|
48
|
+
*/
|
|
49
|
+
closeSessionsForNotebook(url: string): Promise<number>;
|
|
50
|
+
/**
|
|
51
|
+
* Clean up all inactive sessions
|
|
52
|
+
*/
|
|
53
|
+
cleanupInactiveSessions(): Promise<number>;
|
|
54
|
+
/**
|
|
55
|
+
* Clean up the oldest session to make space
|
|
56
|
+
*/
|
|
57
|
+
private cleanupOldestSession;
|
|
58
|
+
/**
|
|
59
|
+
* Close all sessions (used during shutdown)
|
|
60
|
+
*/
|
|
61
|
+
closeAllSessions(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Get all sessions info
|
|
64
|
+
*/
|
|
65
|
+
getAllSessionsInfo(): SessionInfo[];
|
|
66
|
+
/**
|
|
67
|
+
* Get aggregate stats
|
|
68
|
+
*/
|
|
69
|
+
getStats(): {
|
|
70
|
+
active_sessions: number;
|
|
71
|
+
max_sessions: number;
|
|
72
|
+
session_timeout: number;
|
|
73
|
+
oldest_session_seconds: number;
|
|
74
|
+
total_messages: number;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAItD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,cAAc,CAAwB;gBAElC,WAAW,EAAE,WAAW;IAmCpC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;;;;;OAMG;IACG,kBAAkB,CACtB,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,OAAO,GACzB,OAAO,CAAC,cAAc,CAAC;IA4G1B;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAIpD;;OAEG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAwBvD;;OAEG;IACG,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB5D;;OAEG;IACG,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC;IAsChD;;OAEG;YACW,oBAAoB;IA+BlC;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BvC;;OAEG;IACH,kBAAkB,IAAI,WAAW,EAAE;IAInC;;OAEG;IACH,QAAQ,IAAI;QACV,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,cAAc,EAAE,MAAM,CAAC;KACxB;CAoBF"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages multiple parallel browser sessions for NotebookLM API
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Session lifecycle management
|
|
8
|
+
* - Auto-cleanup of inactive sessions
|
|
9
|
+
* - Resource limits (max concurrent sessions)
|
|
10
|
+
* - Shared PERSISTENT browser fingerprint (ONE context for all sessions)
|
|
11
|
+
*
|
|
12
|
+
* Based on the Python implementation from session_manager.py
|
|
13
|
+
*/
|
|
14
|
+
import { BrowserSession } from "./browser-session.js";
|
|
15
|
+
import { SharedContextManager } from "./shared-context-manager.js";
|
|
16
|
+
import { CONFIG } from "../config.js";
|
|
17
|
+
import { log } from "../utils/logger.js";
|
|
18
|
+
import { randomBytes } from "crypto";
|
|
19
|
+
import { getSessionTimeoutManager } from "./session-timeout.js";
|
|
20
|
+
import { audit } from "../utils/audit-logger.js";
|
|
21
|
+
export class SessionManager {
|
|
22
|
+
authManager;
|
|
23
|
+
sharedContextManager;
|
|
24
|
+
sessions = new Map();
|
|
25
|
+
maxSessions;
|
|
26
|
+
sessionTimeout;
|
|
27
|
+
cleanupInterval;
|
|
28
|
+
timeoutManager;
|
|
29
|
+
constructor(authManager) {
|
|
30
|
+
this.authManager = authManager;
|
|
31
|
+
this.sharedContextManager = new SharedContextManager(authManager);
|
|
32
|
+
this.maxSessions = CONFIG.maxSessions;
|
|
33
|
+
this.sessionTimeout = CONFIG.sessionTimeout;
|
|
34
|
+
// Initialize security timeout manager
|
|
35
|
+
this.timeoutManager = getSessionTimeoutManager();
|
|
36
|
+
this.timeoutManager.setTimeoutCallback(async (sessionId, reason) => {
|
|
37
|
+
log.warning(`🔒 Security timeout: Closing session ${sessionId} due to ${reason}`);
|
|
38
|
+
await audit.security("session_security_timeout", "warning", {
|
|
39
|
+
session_id: sessionId,
|
|
40
|
+
reason,
|
|
41
|
+
});
|
|
42
|
+
await this.closeSession(sessionId);
|
|
43
|
+
});
|
|
44
|
+
log.info("🎯 SessionManager initialized");
|
|
45
|
+
log.info(` Max sessions: ${this.maxSessions}`);
|
|
46
|
+
log.info(` Timeout: ${this.sessionTimeout}s (${Math.floor(this.sessionTimeout / 60)} minutes)`);
|
|
47
|
+
const cleanupIntervalSeconds = Math.max(60, Math.min(Math.floor(this.sessionTimeout / 2), 300));
|
|
48
|
+
this.cleanupInterval = setInterval(() => {
|
|
49
|
+
this.cleanupInactiveSessions().catch((error) => {
|
|
50
|
+
log.warning(`⚠️ Error during automatic session cleanup: ${error}`);
|
|
51
|
+
});
|
|
52
|
+
}, cleanupIntervalSeconds * 1000);
|
|
53
|
+
this.cleanupInterval.unref();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generate a unique session ID
|
|
57
|
+
*/
|
|
58
|
+
generateSessionId() {
|
|
59
|
+
return randomBytes(4).toString("hex");
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get existing session or create a new one
|
|
63
|
+
*
|
|
64
|
+
* @param sessionId Optional session ID to reuse existing session
|
|
65
|
+
* @param notebookUrl Notebook URL for the session
|
|
66
|
+
* @param overrideHeadless Optional override for headless mode (true = show browser)
|
|
67
|
+
*/
|
|
68
|
+
async getOrCreateSession(sessionId, notebookUrl, overrideHeadless) {
|
|
69
|
+
// Determine target notebook URL
|
|
70
|
+
const targetUrl = (notebookUrl || CONFIG.notebookUrl || "").trim();
|
|
71
|
+
if (!targetUrl) {
|
|
72
|
+
throw new Error("Notebook URL is required to create a session");
|
|
73
|
+
}
|
|
74
|
+
if (!targetUrl.startsWith("http")) {
|
|
75
|
+
throw new Error("Notebook URL must be an absolute URL");
|
|
76
|
+
}
|
|
77
|
+
// Generate ID if not provided
|
|
78
|
+
if (!sessionId) {
|
|
79
|
+
sessionId = this.generateSessionId();
|
|
80
|
+
log.info(`🆕 Auto-generated session ID: ${sessionId}`);
|
|
81
|
+
}
|
|
82
|
+
// Check if browser visibility mode needs to change
|
|
83
|
+
if (overrideHeadless !== undefined) {
|
|
84
|
+
if (this.sharedContextManager.needsHeadlessModeChange(overrideHeadless)) {
|
|
85
|
+
log.warning(`🔄 Browser visibility changed - closing all sessions to recreate browser context...`);
|
|
86
|
+
const currentMode = this.sharedContextManager.getCurrentHeadlessMode();
|
|
87
|
+
log.info(` Switching from ${currentMode ? 'HEADLESS' : 'VISIBLE'} to ${overrideHeadless ? 'VISIBLE' : 'HEADLESS'}`);
|
|
88
|
+
// Close all sessions (they all use the same context)
|
|
89
|
+
await this.closeAllSessions();
|
|
90
|
+
log.success(` ✅ All sessions closed, browser context will be recreated with new mode`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Return existing session if found
|
|
94
|
+
if (this.sessions.has(sessionId)) {
|
|
95
|
+
const session = this.sessions.get(sessionId);
|
|
96
|
+
// Check security timeout before reusing
|
|
97
|
+
const expiry = this.timeoutManager.isExpired(sessionId);
|
|
98
|
+
if (expiry.expired) {
|
|
99
|
+
log.warning(`🔒 Session ${sessionId} has security-expired (${expiry.reason}), creating new`);
|
|
100
|
+
await audit.security("session_expired_on_reuse", "info", {
|
|
101
|
+
session_id: sessionId,
|
|
102
|
+
reason: expiry.reason,
|
|
103
|
+
});
|
|
104
|
+
await session.close();
|
|
105
|
+
this.sessions.delete(sessionId);
|
|
106
|
+
this.timeoutManager.removeSession(sessionId);
|
|
107
|
+
}
|
|
108
|
+
else if (session.notebookUrl !== targetUrl) {
|
|
109
|
+
log.warning(`♻️ Replacing session ${sessionId} with new notebook URL`);
|
|
110
|
+
await session.close();
|
|
111
|
+
this.sessions.delete(sessionId);
|
|
112
|
+
this.timeoutManager.removeSession(sessionId);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
session.updateActivity();
|
|
116
|
+
// Touch security timeout manager
|
|
117
|
+
this.timeoutManager.touchSession(sessionId);
|
|
118
|
+
log.success(`♻️ Reusing existing session ${sessionId}`);
|
|
119
|
+
return session;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Check if we need to free up space
|
|
123
|
+
if (this.sessions.size >= this.maxSessions) {
|
|
124
|
+
log.warning(`⚠️ Max sessions (${this.maxSessions}) reached, cleaning up...`);
|
|
125
|
+
const freed = await this.cleanupOldestSession();
|
|
126
|
+
if (!freed) {
|
|
127
|
+
throw new Error(`Max sessions (${this.maxSessions}) reached and no inactive sessions to clean up`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Create new session
|
|
131
|
+
log.info(`🆕 Creating new session ${sessionId}...`);
|
|
132
|
+
if (overrideHeadless !== undefined) {
|
|
133
|
+
log.info(` Show browser: ${overrideHeadless}`);
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
// Ensure the shared context exists (ONE fingerprint for all sessions!)
|
|
137
|
+
await this.sharedContextManager.getOrCreateContext(overrideHeadless);
|
|
138
|
+
// Create and initialize session
|
|
139
|
+
const session = new BrowserSession(sessionId, this.sharedContextManager, this.authManager, targetUrl);
|
|
140
|
+
await session.init();
|
|
141
|
+
this.sessions.set(sessionId, session);
|
|
142
|
+
// Register with security timeout manager
|
|
143
|
+
this.timeoutManager.startSession(sessionId);
|
|
144
|
+
// Audit: session created
|
|
145
|
+
await audit.session("session_created", sessionId, {
|
|
146
|
+
notebook_url: targetUrl,
|
|
147
|
+
active_sessions: this.sessions.size,
|
|
148
|
+
});
|
|
149
|
+
log.success(`✅ Session ${sessionId} created (${this.sessions.size}/${this.maxSessions} active)`);
|
|
150
|
+
return session;
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
log.error(`❌ Failed to create session: ${error}`);
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get an existing session by ID
|
|
159
|
+
*/
|
|
160
|
+
getSession(sessionId) {
|
|
161
|
+
return this.sessions.get(sessionId) || null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Close and remove a specific session
|
|
165
|
+
*/
|
|
166
|
+
async closeSession(sessionId) {
|
|
167
|
+
if (!this.sessions.has(sessionId)) {
|
|
168
|
+
log.warning(`⚠️ Session ${sessionId} not found`);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const session = this.sessions.get(sessionId);
|
|
172
|
+
await session.close();
|
|
173
|
+
this.sessions.delete(sessionId);
|
|
174
|
+
// Remove from security timeout manager
|
|
175
|
+
this.timeoutManager.removeSession(sessionId);
|
|
176
|
+
// Audit: session closed
|
|
177
|
+
await audit.session("session_closed", sessionId, {
|
|
178
|
+
active_sessions: this.sessions.size,
|
|
179
|
+
});
|
|
180
|
+
log.success(`✅ Session ${sessionId} closed (${this.sessions.size}/${this.maxSessions} active)`);
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Close all sessions that are using the provided notebook URL
|
|
185
|
+
*/
|
|
186
|
+
async closeSessionsForNotebook(url) {
|
|
187
|
+
let closed = 0;
|
|
188
|
+
for (const [sessionId, session] of Array.from(this.sessions.entries())) {
|
|
189
|
+
if (session.notebookUrl === url) {
|
|
190
|
+
try {
|
|
191
|
+
await session.close();
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
log.warning(` ⚠️ Error closing ${sessionId}: ${error}`);
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
this.sessions.delete(sessionId);
|
|
198
|
+
closed++;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (closed > 0) {
|
|
203
|
+
log.warning(`🧹 Closed ${closed} session(s) using removed notebook (${this.sessions.size}/${this.maxSessions} active)`);
|
|
204
|
+
}
|
|
205
|
+
return closed;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Clean up all inactive sessions
|
|
209
|
+
*/
|
|
210
|
+
async cleanupInactiveSessions() {
|
|
211
|
+
const inactiveSessions = [];
|
|
212
|
+
for (const [sessionId, session] of this.sessions.entries()) {
|
|
213
|
+
if (session.isExpired(this.sessionTimeout)) {
|
|
214
|
+
inactiveSessions.push(sessionId);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (inactiveSessions.length === 0) {
|
|
218
|
+
return 0;
|
|
219
|
+
}
|
|
220
|
+
log.warning(`🧹 Cleaning up ${inactiveSessions.length} inactive sessions...`);
|
|
221
|
+
for (const sessionId of inactiveSessions) {
|
|
222
|
+
try {
|
|
223
|
+
const session = this.sessions.get(sessionId);
|
|
224
|
+
const age = (Date.now() - session.createdAt) / 1000;
|
|
225
|
+
const inactive = (Date.now() - session.lastActivity) / 1000;
|
|
226
|
+
log.warning(` 🗑️ ${sessionId}: age=${age.toFixed(0)}s, inactive=${inactive.toFixed(0)}s, messages=${session.messageCount}`);
|
|
227
|
+
await session.close();
|
|
228
|
+
this.sessions.delete(sessionId);
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
log.warning(` ⚠️ Error cleaning up ${sessionId}: ${error}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
log.success(`✅ Cleaned up ${inactiveSessions.length} sessions (${this.sessions.size}/${this.maxSessions} active)`);
|
|
235
|
+
return inactiveSessions.length;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Clean up the oldest session to make space
|
|
239
|
+
*/
|
|
240
|
+
async cleanupOldestSession() {
|
|
241
|
+
if (this.sessions.size === 0) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
// Find oldest session
|
|
245
|
+
let oldestId = null;
|
|
246
|
+
let oldestTime = Infinity;
|
|
247
|
+
for (const [sessionId, session] of this.sessions.entries()) {
|
|
248
|
+
if (session.createdAt < oldestTime) {
|
|
249
|
+
oldestTime = session.createdAt;
|
|
250
|
+
oldestId = sessionId;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (!oldestId) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
const oldestSession = this.sessions.get(oldestId);
|
|
257
|
+
const age = (Date.now() - oldestSession.createdAt) / 1000;
|
|
258
|
+
log.warning(`🗑️ Removing oldest session ${oldestId} (age: ${age.toFixed(0)}s)`);
|
|
259
|
+
await oldestSession.close();
|
|
260
|
+
this.sessions.delete(oldestId);
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Close all sessions (used during shutdown)
|
|
265
|
+
*/
|
|
266
|
+
async closeAllSessions() {
|
|
267
|
+
if (this.cleanupInterval) {
|
|
268
|
+
clearInterval(this.cleanupInterval);
|
|
269
|
+
this.cleanupInterval = undefined;
|
|
270
|
+
}
|
|
271
|
+
if (this.sessions.size === 0) {
|
|
272
|
+
log.warning("🛑 Closing shared context (no active sessions)...");
|
|
273
|
+
await this.sharedContextManager.closeContext();
|
|
274
|
+
log.success("✅ All sessions closed");
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
log.warning(`🛑 Closing all ${this.sessions.size} sessions...`);
|
|
278
|
+
for (const sessionId of Array.from(this.sessions.keys())) {
|
|
279
|
+
try {
|
|
280
|
+
const session = this.sessions.get(sessionId);
|
|
281
|
+
await session.close();
|
|
282
|
+
this.sessions.delete(sessionId);
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
log.warning(` ⚠️ Error closing ${sessionId}: ${error}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Close the shared context
|
|
289
|
+
await this.sharedContextManager.closeContext();
|
|
290
|
+
log.success("✅ All sessions closed");
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Get all sessions info
|
|
294
|
+
*/
|
|
295
|
+
getAllSessionsInfo() {
|
|
296
|
+
return Array.from(this.sessions.values()).map((session) => session.getInfo());
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get aggregate stats
|
|
300
|
+
*/
|
|
301
|
+
getStats() {
|
|
302
|
+
const sessionsInfo = this.getAllSessionsInfo();
|
|
303
|
+
const totalMessages = sessionsInfo.reduce((sum, info) => sum + info.message_count, 0);
|
|
304
|
+
const oldestSessionSeconds = Math.max(...sessionsInfo.map((info) => info.age_seconds), 0);
|
|
305
|
+
return {
|
|
306
|
+
active_sessions: sessionsInfo.length,
|
|
307
|
+
max_sessions: this.maxSessions,
|
|
308
|
+
session_timeout: this.sessionTimeout,
|
|
309
|
+
oldest_session_seconds: oldestSessionSeconds,
|
|
310
|
+
total_messages: totalMessages,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Timeout Manager for NotebookLM MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Provides configurable session timeout enforcement:
|
|
5
|
+
* - Hard timeout: Maximum session lifetime (default: 8 hours)
|
|
6
|
+
* - Inactivity timeout: Auto-logout after idle period (default: 30 minutes)
|
|
7
|
+
* - Warning callbacks before timeout
|
|
8
|
+
* - Memory scrubbing on timeout
|
|
9
|
+
*
|
|
10
|
+
* Added by Pantheon Security for hardened fork.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Session timeout configuration
|
|
14
|
+
*/
|
|
15
|
+
export interface SessionTimeoutConfig {
|
|
16
|
+
/** Maximum session lifetime in milliseconds (default: 8 hours) */
|
|
17
|
+
maxLifetimeMs: number;
|
|
18
|
+
/** Inactivity timeout in milliseconds (default: 30 minutes) */
|
|
19
|
+
inactivityTimeoutMs: number;
|
|
20
|
+
/** Warning before timeout in milliseconds (default: 5 minutes) */
|
|
21
|
+
warningBeforeMs: number;
|
|
22
|
+
/** Enable hard timeout (default: true) */
|
|
23
|
+
enableHardTimeout: boolean;
|
|
24
|
+
/** Enable inactivity timeout (default: true) */
|
|
25
|
+
enableInactivityTimeout: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Timeout callback type
|
|
29
|
+
*/
|
|
30
|
+
export type TimeoutCallback = (sessionId: string, reason: "lifetime" | "inactivity") => Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Warning callback type
|
|
33
|
+
*/
|
|
34
|
+
export type WarningCallback = (sessionId: string, reason: "lifetime" | "inactivity", remainingMs: number) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Session Timeout Manager
|
|
37
|
+
*
|
|
38
|
+
* Manages session timeouts with configurable lifetime and inactivity limits.
|
|
39
|
+
*/
|
|
40
|
+
export declare class SessionTimeoutManager {
|
|
41
|
+
private config;
|
|
42
|
+
private sessions;
|
|
43
|
+
private checkInterval;
|
|
44
|
+
private onTimeout;
|
|
45
|
+
private onWarning;
|
|
46
|
+
constructor(config?: Partial<SessionTimeoutConfig>);
|
|
47
|
+
/**
|
|
48
|
+
* Format duration for logging
|
|
49
|
+
*/
|
|
50
|
+
private formatDuration;
|
|
51
|
+
/**
|
|
52
|
+
* Register a new session
|
|
53
|
+
*/
|
|
54
|
+
startSession(sessionId: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Update session activity (reset inactivity timer)
|
|
57
|
+
*/
|
|
58
|
+
touchSession(sessionId: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Remove a session from tracking
|
|
61
|
+
*/
|
|
62
|
+
removeSession(sessionId: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Check if a session has expired
|
|
65
|
+
*/
|
|
66
|
+
isExpired(sessionId: string): {
|
|
67
|
+
expired: boolean;
|
|
68
|
+
reason?: "lifetime" | "inactivity";
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Get time remaining for a session
|
|
72
|
+
*/
|
|
73
|
+
getTimeRemaining(sessionId: string): {
|
|
74
|
+
lifetime: number;
|
|
75
|
+
inactivity: number;
|
|
76
|
+
} | null;
|
|
77
|
+
/**
|
|
78
|
+
* Get session info for all tracked sessions
|
|
79
|
+
*/
|
|
80
|
+
getAllSessionsInfo(): Array<{
|
|
81
|
+
sessionId: string;
|
|
82
|
+
createdAt: number;
|
|
83
|
+
lastActivity: number;
|
|
84
|
+
ageMs: number;
|
|
85
|
+
inactiveMs: number;
|
|
86
|
+
lifetimeRemainingMs: number;
|
|
87
|
+
inactivityRemainingMs: number;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Set callback for when a session times out
|
|
91
|
+
*/
|
|
92
|
+
setTimeoutCallback(callback: TimeoutCallback): void;
|
|
93
|
+
/**
|
|
94
|
+
* Set callback for timeout warnings
|
|
95
|
+
*/
|
|
96
|
+
setWarningCallback(callback: WarningCallback): void;
|
|
97
|
+
/**
|
|
98
|
+
* Start periodic timeout check
|
|
99
|
+
*/
|
|
100
|
+
private startPeriodicCheck;
|
|
101
|
+
/**
|
|
102
|
+
* Check all sessions for expiry and warnings
|
|
103
|
+
*/
|
|
104
|
+
private checkAllSessions;
|
|
105
|
+
/**
|
|
106
|
+
* Stop the timeout manager
|
|
107
|
+
*/
|
|
108
|
+
stop(): void;
|
|
109
|
+
/**
|
|
110
|
+
* Get configuration
|
|
111
|
+
*/
|
|
112
|
+
getConfig(): SessionTimeoutConfig;
|
|
113
|
+
/**
|
|
114
|
+
* Update configuration
|
|
115
|
+
*/
|
|
116
|
+
updateConfig(config: Partial<SessionTimeoutConfig>): void;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get or create the global timeout manager
|
|
120
|
+
*/
|
|
121
|
+
export declare function getSessionTimeoutManager(): SessionTimeoutManager;
|
|
122
|
+
//# sourceMappingURL=session-timeout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-timeout.d.ts","sourceRoot":"","sources":["../../src/session/session-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gDAAgD;IAChD,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAaD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtG;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,YAAY,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;AAmBlH;;;;GAIG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,SAAS,CAAgC;gBAErC,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAWlD;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAkBrC;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQrC;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKtC;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,UAAU,GAAG,YAAY,CAAA;KAAE;IA2BtF;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAsBpF;;OAEG;IACH,kBAAkB,IAAI,KAAK,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,qBAAqB,EAAE,MAAM,CAAC;KAC/B,CAAC;IA4BF;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAInD;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAInD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;YACW,gBAAgB;IAuE9B;;OAEG;IACH,IAAI,IAAI,IAAI;IASZ;;OAEG;IACH,SAAS,IAAI,oBAAoB;IAIjC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI;CAI1D;AAOD;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,qBAAqB,CAKhE"}
|