@qodalis/cli-server-node 1.0.0-beta.4 → 1.0.0-beta.6

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.
Files changed (127) hide show
  1. package/README.md +315 -37
  2. package/dist/src/abstractions/index.d.ts +1 -1
  3. package/dist/src/abstractions/index.d.ts.map +1 -1
  4. package/dist/src/abstractions/index.js +4 -1
  5. package/dist/src/abstractions/index.js.map +1 -1
  6. package/dist/src/auth/cli-server-auth-gate.d.ts +31 -0
  7. package/dist/src/auth/cli-server-auth-gate.d.ts.map +1 -0
  8. package/dist/src/auth/cli-server-auth-gate.js +118 -0
  9. package/dist/src/auth/cli-server-auth-gate.js.map +1 -0
  10. package/dist/src/auth/cli-server-auth.d.ts +147 -0
  11. package/dist/src/auth/cli-server-auth.d.ts.map +1 -0
  12. package/dist/src/auth/cli-server-auth.js +143 -0
  13. package/dist/src/auth/cli-server-auth.js.map +1 -0
  14. package/dist/src/auth/index.d.ts +4 -0
  15. package/dist/src/auth/index.d.ts.map +1 -0
  16. package/dist/src/auth/index.js +19 -0
  17. package/dist/src/auth/index.js.map +1 -0
  18. package/dist/src/auth/ws-upgrade-auth.d.ts +30 -0
  19. package/dist/src/auth/ws-upgrade-auth.d.ts.map +1 -0
  20. package/dist/src/auth/ws-upgrade-auth.js +49 -0
  21. package/dist/src/auth/ws-upgrade-auth.js.map +1 -0
  22. package/dist/src/controllers/cli-controller.d.ts +8 -1
  23. package/dist/src/controllers/cli-controller.d.ts.map +1 -1
  24. package/dist/src/controllers/cli-controller.js +78 -3
  25. package/dist/src/controllers/cli-controller.js.map +1 -1
  26. package/dist/src/controllers/cli-version-controller.d.ts +16 -1
  27. package/dist/src/controllers/cli-version-controller.d.ts.map +1 -1
  28. package/dist/src/controllers/cli-version-controller.js +18 -5
  29. package/dist/src/controllers/cli-version-controller.js.map +1 -1
  30. package/dist/src/controllers/filesystem-controller.d.ts.map +1 -1
  31. package/dist/src/controllers/filesystem-controller.js +51 -7
  32. package/dist/src/controllers/filesystem-controller.js.map +1 -1
  33. package/dist/src/create-cli-server.d.ts +76 -5
  34. package/dist/src/create-cli-server.d.ts.map +1 -1
  35. package/dist/src/create-cli-server.js +88 -20
  36. package/dist/src/create-cli-server.js.map +1 -1
  37. package/dist/src/extensions/cli-builder.d.ts +19 -1
  38. package/dist/src/extensions/cli-builder.d.ts.map +1 -1
  39. package/dist/src/extensions/cli-builder.js +26 -0
  40. package/dist/src/extensions/cli-builder.js.map +1 -1
  41. package/dist/src/filesystem/filesystem-options.d.ts +1 -0
  42. package/dist/src/filesystem/filesystem-options.d.ts.map +1 -1
  43. package/dist/src/index.d.ts +5 -4
  44. package/dist/src/index.d.ts.map +1 -1
  45. package/dist/src/index.js +18 -3
  46. package/dist/src/index.js.map +1 -1
  47. package/dist/src/models/cli-server-command-descriptor.d.ts +2 -1
  48. package/dist/src/models/cli-server-command-descriptor.d.ts.map +1 -1
  49. package/dist/src/models/cli-server-output.d.ts +1 -22
  50. package/dist/src/models/cli-server-output.d.ts.map +1 -1
  51. package/dist/src/models/cli-server-response.d.ts +1 -5
  52. package/dist/src/models/cli-server-response.d.ts.map +1 -1
  53. package/dist/src/processors/cli-base64-command-processor.d.ts +1 -0
  54. package/dist/src/processors/cli-base64-command-processor.d.ts.map +1 -1
  55. package/dist/src/processors/cli-base64-command-processor.js +3 -0
  56. package/dist/src/processors/cli-base64-command-processor.js.map +1 -1
  57. package/dist/src/processors/cli-echo-command-processor.d.ts +1 -0
  58. package/dist/src/processors/cli-echo-command-processor.d.ts.map +1 -1
  59. package/dist/src/processors/cli-echo-command-processor.js +1 -0
  60. package/dist/src/processors/cli-echo-command-processor.js.map +1 -1
  61. package/dist/src/processors/cli-hash-command-processor.d.ts +1 -0
  62. package/dist/src/processors/cli-hash-command-processor.d.ts.map +1 -1
  63. package/dist/src/processors/cli-hash-command-processor.js +1 -0
  64. package/dist/src/processors/cli-hash-command-processor.js.map +1 -1
  65. package/dist/src/processors/cli-http-command-processor.d.ts +1 -0
  66. package/dist/src/processors/cli-http-command-processor.d.ts.map +1 -1
  67. package/dist/src/processors/cli-http-command-processor.js +85 -6
  68. package/dist/src/processors/cli-http-command-processor.js.map +1 -1
  69. package/dist/src/processors/cli-status-command-processor.d.ts +1 -0
  70. package/dist/src/processors/cli-status-command-processor.d.ts.map +1 -1
  71. package/dist/src/processors/cli-status-command-processor.js +1 -0
  72. package/dist/src/processors/cli-status-command-processor.js.map +1 -1
  73. package/dist/src/processors/cli-system-command-processor.d.ts +1 -0
  74. package/dist/src/processors/cli-system-command-processor.d.ts.map +1 -1
  75. package/dist/src/processors/cli-system-command-processor.js +1 -0
  76. package/dist/src/processors/cli-system-command-processor.js.map +1 -1
  77. package/dist/src/server.js +20 -6
  78. package/dist/src/server.js.map +1 -1
  79. package/dist/src/services/cli-command-executor-service.d.ts +24 -3
  80. package/dist/src/services/cli-command-executor-service.d.ts.map +1 -1
  81. package/dist/src/services/cli-command-executor-service.js +35 -3
  82. package/dist/src/services/cli-command-executor-service.js.map +1 -1
  83. package/dist/src/services/cli-command-registry.d.ts +11 -0
  84. package/dist/src/services/cli-command-registry.d.ts.map +1 -1
  85. package/dist/src/services/cli-command-registry.js +5 -0
  86. package/dist/src/services/cli-command-registry.js.map +1 -1
  87. package/dist/src/services/cli-event-socket-manager.d.ts +42 -0
  88. package/dist/src/services/cli-event-socket-manager.d.ts.map +1 -1
  89. package/dist/src/services/cli-event-socket-manager.js +139 -27
  90. package/dist/src/services/cli-event-socket-manager.js.map +1 -1
  91. package/dist/src/services/cli-log-socket-manager.d.ts +17 -1
  92. package/dist/src/services/cli-log-socket-manager.d.ts.map +1 -1
  93. package/dist/src/services/cli-log-socket-manager.js +59 -12
  94. package/dist/src/services/cli-log-socket-manager.js.map +1 -1
  95. package/dist/src/services/cli-response-builder.d.ts +9 -0
  96. package/dist/src/services/cli-response-builder.d.ts.map +1 -1
  97. package/dist/src/services/cli-response-builder.js +1 -0
  98. package/dist/src/services/cli-response-builder.js.map +1 -1
  99. package/dist/src/services/cli-shell-options.d.ts +107 -0
  100. package/dist/src/services/cli-shell-options.d.ts.map +1 -0
  101. package/dist/src/services/cli-shell-options.js +139 -0
  102. package/dist/src/services/cli-shell-options.js.map +1 -0
  103. package/dist/src/services/cli-shell-session-manager.d.ts +86 -2
  104. package/dist/src/services/cli-shell-session-manager.d.ts.map +1 -1
  105. package/dist/src/services/cli-shell-session-manager.js +493 -73
  106. package/dist/src/services/cli-shell-session-manager.js.map +1 -1
  107. package/dist/src/services/index.d.ts +2 -1
  108. package/dist/src/services/index.d.ts.map +1 -1
  109. package/dist/src/services/index.js +5 -1
  110. package/dist/src/services/index.js.map +1 -1
  111. package/dist/src/services/process-tree.d.ts +38 -0
  112. package/dist/src/services/process-tree.d.ts.map +1 -0
  113. package/dist/src/services/process-tree.js +249 -0
  114. package/dist/src/services/process-tree.js.map +1 -0
  115. package/dist/src/services/session-bound-sockets.d.ts +45 -0
  116. package/dist/src/services/session-bound-sockets.d.ts.map +1 -0
  117. package/dist/src/services/session-bound-sockets.js +129 -0
  118. package/dist/src/services/session-bound-sockets.js.map +1 -0
  119. package/dist/src/utils/logger.d.ts +11 -0
  120. package/dist/src/utils/logger.d.ts.map +1 -0
  121. package/dist/src/utils/logger.js +13 -0
  122. package/dist/src/utils/logger.js.map +1 -0
  123. package/package.json +12 -3
  124. package/dist/src/controllers/cli-controller-v2.d.ts +0 -4
  125. package/dist/src/controllers/cli-controller-v2.d.ts.map +0 -1
  126. package/dist/src/controllers/cli-controller-v2.js +0 -46
  127. package/dist/src/controllers/cli-controller-v2.js.map +0 -1
@@ -35,10 +35,20 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.CliShellSessionManager = void 0;
37
37
  const ws_1 = require("ws");
38
+ const fs = __importStar(require("fs"));
38
39
  const os = __importStar(require("os"));
39
40
  const path = __importStar(require("path"));
40
- // Lazy-load node-pty so that importing this module does not fail when the
41
- // native add-on is unavailable (e.g. in CI environments without build tools).
41
+ const logger_1 = require("../utils/logger");
42
+ const cli_server_auth_1 = require("../auth/cli-server-auth");
43
+ const cli_shell_options_1 = require("./cli-shell-options");
44
+ const process_tree_1 = require("./process-tree");
45
+ const logger = (0, logger_1.createLogger)('ShellSession');
46
+ /** Longest delay `setTimeout` supports (~24.8 days); longer ones fire immediately. */
47
+ const MAX_TIMEOUT_MS = 2 ** 31 - 1;
48
+ /**
49
+ * Lazy-loads node-pty to avoid import failures when the native add-on is unavailable.
50
+ * @throws {Error} If node-pty cannot be loaded.
51
+ */
42
52
  let _pty;
43
53
  function getPty() {
44
54
  if (!_pty) {
@@ -52,112 +62,474 @@ function getPty() {
52
62
  }
53
63
  return _pty;
54
64
  }
65
+ /**
66
+ * Manages interactive PTY shell sessions over WebSocket connections and
67
+ * enforces Appendix C: access mode, session binding, limits, timeouts,
68
+ * minimal environment and audit.
69
+ */
55
70
  class CliShellSessionManager {
56
- async handleSession(ws, cols, rows, command) {
71
+ _options;
72
+ _enabled;
73
+ _auth;
74
+ _unsubscribe;
75
+ _sessions = new Set();
76
+ _nextId = 1;
77
+ _checkTimer;
78
+ _trustProxy;
79
+ constructor(options = {}) {
80
+ this._enabled = options.enabled ?? false;
81
+ this._options = options.shell ?? {};
82
+ this._trustProxy = options.trustProxy ?? false;
83
+ }
84
+ /**
85
+ * Trusted reverse-proxy hops (`true` = 1): the remote address is the
86
+ * `X-Forwarded-For` entry at index `len - hops` (`false`/0: the socket address).
87
+ */
88
+ setTrustProxy(trust) {
89
+ this._trustProxy = trust;
90
+ }
91
+ get enabled() {
92
+ return this._enabled;
93
+ }
94
+ setEnabled(enabled) {
95
+ this._enabled = enabled;
96
+ }
97
+ get options() {
98
+ return this._options;
99
+ }
100
+ setOptions(options) {
101
+ this._options = options ?? {};
102
+ }
103
+ /** Current access mode (`undefined` while the shell is disabled). */
104
+ get authMode() {
105
+ return this._enabled ? (0, cli_shell_options_1.resolveShellAuthMode)(this._options, !!this._auth) : undefined;
106
+ }
107
+ /** Installs the auth provider (users plugin); subscribes to its session events. */
108
+ setAuth(auth) {
109
+ if (auth === this._auth)
110
+ return;
111
+ this._unsubscribe?.();
112
+ this._unsubscribe = undefined;
113
+ this._auth = auth;
114
+ if (auth?.onSessionEvent) {
115
+ this._unsubscribe = auth.onSessionEvent((event) => this.onSessionEvent(event));
116
+ }
117
+ }
118
+ /** Logs the startup state: ERROR when locked, WARNING when anonymous. */
119
+ logStartupState() {
120
+ const mode = this.authMode;
121
+ if (mode === 'locked') {
122
+ logger.error('Shell is enabled but no access mode is configured, so it is LOCKED (every connection is refused). ' +
123
+ 'Mount the users plugin (shell:execute permission), or set shell.token, shell.authorize, ' +
124
+ 'or shell.allowAnonymous (not recommended).');
125
+ }
126
+ else if (mode === 'anonymous') {
127
+ logger.warn('WARNING: shell is enabled without authentication (shell.allowAnonymous). Anyone who can reach this server gets a shell.');
128
+ }
129
+ else if (mode) {
130
+ logger.info('Shell enabled (auth=%s)', mode);
131
+ }
132
+ }
133
+ /** Open sessions. */
134
+ getSessions() {
135
+ return [...this._sessions].map((s) => ({
136
+ id: s.id,
137
+ authMode: s.authMode,
138
+ mode: s.mode,
139
+ remoteAddress: s.remoteAddress,
140
+ userId: s.ctx?.userId,
141
+ userName: s.ctx?.userName,
142
+ sessionId: s.ctx?.sessionId,
143
+ startedAt: new Date(s.startedAt).toISOString(),
144
+ }));
145
+ }
146
+ /**
147
+ * Takes over an accepted shell WebSocket: authorizes it (closing with
148
+ * 4401/4403/4404/4429 when refused), then bridges it to a PTY.
149
+ */
150
+ async accept(ws, request, url) {
151
+ if (!this._enabled) {
152
+ ws.close(cli_shell_options_1.ShellCloseCodes.Disabled, 'shell disabled');
153
+ return;
154
+ }
155
+ const cols = clampDim(url.searchParams.get('cols'), 80);
156
+ const rows = clampDim(url.searchParams.get('rows'), 24);
157
+ const command = url.searchParams.get('cmd') || undefined;
158
+ const mode = command ? 'command' : 'interactive';
159
+ const remoteAddress = this.remoteAddressOf(request);
160
+ const authMode = (0, cli_shell_options_1.resolveShellAuthMode)(this._options, !!this._auth);
161
+ let decision;
162
+ try {
163
+ decision = await this.authorize(authMode, request, url, remoteAddress, mode);
164
+ }
165
+ catch {
166
+ decision = { ok: false, code: cli_shell_options_1.ShellCloseCodes.Forbidden, reason: 'forbidden' };
167
+ }
168
+ if (!decision.ok) {
169
+ closeWs(ws, decision.code, decision.reason);
170
+ return;
171
+ }
172
+ if (ws.readyState !== ws_1.WebSocket.OPEN)
173
+ return;
174
+ const limitKey = authMode === 'users' ? `user:${decision.ctx.userId}` : `addr:${remoteAddress}`;
175
+ const perUser = this._options.maxSessionsPerUser ?? cli_shell_options_1.SHELL_DEFAULTS.maxSessionsPerUser;
176
+ const total = this._options.maxSessions ?? cli_shell_options_1.SHELL_DEFAULTS.maxSessions;
177
+ let sameKey = 0;
178
+ for (const s of this._sessions)
179
+ if (s.limitKey === limitKey)
180
+ sameKey++;
181
+ if (sameKey >= perUser || this._sessions.size >= total) {
182
+ closeWs(ws, cli_shell_options_1.ShellCloseCodes.TooMany, 'too many shell sessions');
183
+ return;
184
+ }
185
+ const now = Date.now();
186
+ const session = {
187
+ id: `sh-${this._nextId++}`,
188
+ ws,
189
+ authMode,
190
+ mode,
191
+ remoteAddress,
192
+ limitKey,
193
+ ctx: decision.ctx,
194
+ request,
195
+ startedAt: now,
196
+ lastInput: now,
197
+ inputSinceCheck: false,
198
+ lastTouch: 0,
199
+ closed: false,
200
+ };
201
+ this._sessions.add(session);
202
+ this.ensureCheckTimer();
203
+ if (session.ctx) {
204
+ // A logout/revoke/permission change between ticket consumption (or a slow
205
+ // `authorize`) and the registration above emitted its event before this
206
+ // shell could hear it: revalidate once now, before anything is spawned.
207
+ await this.revalidateSession(session);
208
+ if (session.closed)
209
+ return;
210
+ if (ws.readyState !== ws_1.WebSocket.OPEN) {
211
+ this.end(session, undefined, undefined, 'closed');
212
+ return;
213
+ }
214
+ }
215
+ this.spawn(session, cols, rows, command);
216
+ }
217
+ /** Decides access for the given mode. */
218
+ async authorize(authMode, request, url, remoteAddress, mode) {
219
+ const o = this._options;
220
+ if (authMode === 'locked') {
221
+ return { ok: false, code: cli_shell_options_1.ShellCloseCodes.LoginRequired, reason: 'shell access is not configured' };
222
+ }
223
+ let ctx;
224
+ if (authMode === 'users') {
225
+ const ticket = url.searchParams.get('ticket');
226
+ try {
227
+ ctx = ticket ? await this._auth.consumeTicket(ticket) : undefined;
228
+ }
229
+ catch (err) {
230
+ if (err?.status === 403) {
231
+ return { ok: false, code: cli_shell_options_1.ShellCloseCodes.Forbidden, reason: 'forbidden' };
232
+ }
233
+ ctx = undefined;
234
+ }
235
+ if (!ctx) {
236
+ return { ok: false, code: cli_shell_options_1.ShellCloseCodes.LoginRequired, reason: 'login required' };
237
+ }
238
+ if (!this._auth.hasPermission(ctx, cli_server_auth_1.CliServerPermissions.ShellExecute)) {
239
+ return { ok: false, code: cli_shell_options_1.ShellCloseCodes.Forbidden, reason: 'forbidden' };
240
+ }
241
+ }
242
+ // Every configured check among token/authorize must pass, whatever the mode.
243
+ if (o.token) {
244
+ const presented = (0, cli_shell_options_1.readBearerToken)(request, url);
245
+ if (!presented) {
246
+ return { ok: false, code: cli_shell_options_1.ShellCloseCodes.LoginRequired, reason: 'login required' };
247
+ }
248
+ if (!(0, cli_shell_options_1.tokensEqual)(presented, o.token)) {
249
+ return { ok: false, code: cli_shell_options_1.ShellCloseCodes.Forbidden, reason: 'forbidden' };
250
+ }
251
+ }
252
+ if (o.authorize) {
253
+ let allowed = false;
254
+ try {
255
+ allowed = (await o.authorize(request, { url, remoteAddress, mode })) === true;
256
+ }
257
+ catch (err) {
258
+ logger.warn('Shell authorize callback threw; denying (%s)', err?.message ?? 'error');
259
+ allowed = false;
260
+ }
261
+ if (!allowed) {
262
+ return { ok: false, code: cli_shell_options_1.ShellCloseCodes.Forbidden, reason: 'forbidden' };
263
+ }
264
+ }
265
+ return { ok: true, ctx };
266
+ }
267
+ spawn(session, cols, rows, command) {
268
+ const { ws } = session;
57
269
  const { shell, args } = this.getShellInfo(command);
58
- const nodePty = getPty();
59
- let ptyProcess;
270
+ let nodePty;
60
271
  try {
61
- ptyProcess = nodePty.spawn(shell, args, {
272
+ nodePty = getPty();
273
+ }
274
+ catch (err) {
275
+ logger.error('node-pty unavailable: %s', err.message ?? err);
276
+ this.send(ws, { type: 'error', message: 'shell is not available on this server' });
277
+ this.end(session, 1011, 'shell unavailable', 'error');
278
+ return;
279
+ }
280
+ // Set after the allow/set filtering: configuration can neither override nor drop it.
281
+ session.shellId = (0, process_tree_1.newShellId)();
282
+ try {
283
+ session.pty = nodePty.spawn(shell, args, {
62
284
  name: 'xterm-256color',
63
285
  cols,
64
286
  rows,
65
- cwd: os.homedir(),
66
- env: { ...process.env, TERM: 'xterm-256color' },
287
+ cwd: this._options.cwd ?? os.homedir(),
288
+ env: { ...(0, cli_shell_options_1.buildShellEnv)(this._options.env, { shell, cols, rows }), [process_tree_1.SHELL_ID_ENV]: session.shellId },
67
289
  });
68
290
  }
69
291
  catch (err) {
70
- this.send(ws, { type: 'error', message: err.message });
71
- ws.close();
292
+ logger.error('Shell spawn failed: %s', err.message ?? err);
293
+ this.send(ws, { type: 'error', message: 'failed to start shell' });
294
+ this.end(session, 1011, 'shell failed', 'error');
72
295
  return;
73
296
  }
74
- const detectedOs = os.platform() === 'win32'
75
- ? 'win32'
76
- : os.platform() === 'darwin'
77
- ? 'darwin'
78
- : 'linux';
297
+ this.onOpened(session);
79
298
  this.send(ws, {
80
299
  type: 'ready',
81
300
  shell: path.basename(shell),
82
- os: detectedOs,
301
+ os: os.platform() === 'win32' ? 'win32' : os.platform() === 'darwin' ? 'darwin' : 'linux',
83
302
  });
84
- ptyProcess.onData((data) => {
85
- this.send(ws, { type: 'stdout', data });
86
- });
87
- ptyProcess.onExit(({ exitCode }) => {
303
+ session.pty.onData((data) => this.send(ws, { type: 'stdout', data }));
304
+ session.pty.onExit(({ exitCode }) => {
305
+ if (session.closed)
306
+ return;
88
307
  this.send(ws, { type: 'exit', code: exitCode });
89
- if (ws.readyState === ws_1.WebSocket.OPEN) {
90
- ws.close();
91
- }
308
+ this.end(session, 1000, 'exit', 'exited', exitCode);
92
309
  });
93
310
  ws.on('message', (raw) => {
311
+ let msg;
94
312
  try {
95
- const msg = JSON.parse(raw.toString());
96
- switch (msg.type) {
97
- case 'stdin':
98
- ptyProcess.write(msg.data);
99
- break;
100
- case 'resize':
101
- ptyProcess.resize(msg.cols, msg.rows);
102
- break;
103
- }
313
+ msg = JSON.parse(raw.toString());
104
314
  }
105
315
  catch {
106
- // Ignore malformed messages
316
+ logger.debug('Ignoring malformed WebSocket message');
317
+ return;
107
318
  }
108
- });
109
- ws.on('close', () => {
110
319
  try {
111
- ptyProcess.kill();
320
+ if (msg.type === 'stdin' && typeof msg.data === 'string') {
321
+ session.lastInput = Date.now();
322
+ session.inputSinceCheck = true;
323
+ session.pty?.write(msg.data);
324
+ }
325
+ else if (msg.type === 'resize') {
326
+ session.pty?.resize(clampDim(String(msg.cols), cols), clampDim(String(msg.rows), rows));
327
+ }
112
328
  }
113
329
  catch {
114
- // Already exited
330
+ logger.debug('Ignoring shell message after exit');
115
331
  }
116
332
  });
117
- ws.on('error', () => {
118
- try {
119
- ptyProcess.kill();
120
- }
121
- catch {
122
- // Already exited
123
- }
333
+ ws.on('close', () => this.end(session, undefined, undefined, 'closed'));
334
+ ws.on('error', (error) => {
335
+ logger.error('Shell socket error: %s', error.message ?? error);
336
+ this.end(session, undefined, undefined, 'error');
124
337
  });
338
+ this.armTimers(session);
125
339
  }
126
- getShellInfo(command) {
127
- if (os.platform() === 'win32') {
128
- const shell = 'powershell.exe';
129
- return command
130
- ? { shell, args: ['-Command', command] }
131
- : { shell, args: [] };
132
- }
133
- const shell = this.detectShell();
134
- return command
135
- ? { shell, args: ['-c', command] }
136
- : { shell, args: [] };
137
- }
138
- detectShell() {
139
- const envShell = process.env.SHELL;
140
- if (envShell) {
141
- try {
142
- require('fs').accessSync(envShell, require('fs').constants.X_OK);
143
- return envShell;
144
- }
145
- catch {
146
- // SHELL env var points to non-existent binary, fall through
147
- }
340
+ /** Idle (no stdin) and absolute duration timers ⇒ 4408. */
341
+ armTimers(session) {
342
+ const idle = this._options.idleTimeoutMs ?? cli_shell_options_1.SHELL_DEFAULTS.idleTimeoutMs;
343
+ if (idle > 0) {
344
+ const check = () => {
345
+ if (session.closed)
346
+ return;
347
+ const remaining = session.lastInput + idle - Date.now();
348
+ if (remaining <= 0) {
349
+ this.end(session, cli_shell_options_1.ShellCloseCodes.TimedOut, 'shell timed out', 'shell timed out');
350
+ }
351
+ else {
352
+ session.idleTimer = setTimeout(check, Math.min(remaining, MAX_TIMEOUT_MS));
353
+ session.idleTimer.unref?.();
354
+ }
355
+ };
356
+ session.idleTimer = setTimeout(check, Math.min(idle, MAX_TIMEOUT_MS));
357
+ session.idleTimer.unref?.();
148
358
  }
149
- const candidates = ['/bin/bash', '/usr/bin/bash', '/bin/sh'];
150
- for (const candidate of candidates) {
151
- try {
152
- require('fs').accessSync(candidate, require('fs').constants.X_OK);
153
- return candidate;
359
+ const max = this._options.maxDurationMs;
360
+ if (max && max > 0) {
361
+ const deadline = Date.now() + max;
362
+ const expire = () => {
363
+ if (session.closed)
364
+ return;
365
+ const remaining = deadline - Date.now();
366
+ if (remaining <= 0) {
367
+ this.end(session, cli_shell_options_1.ShellCloseCodes.TimedOut, 'shell timed out', 'shell timed out');
368
+ }
369
+ else {
370
+ session.durationTimer = setTimeout(expire, Math.min(remaining, MAX_TIMEOUT_MS));
371
+ session.durationTimer.unref?.();
372
+ }
373
+ };
374
+ session.durationTimer = setTimeout(expire, Math.min(max, MAX_TIMEOUT_MS));
375
+ session.durationTimer.unref?.();
376
+ }
377
+ }
378
+ // ----------------------------------------------------- session binding
379
+ onSessionEvent(event) {
380
+ if (event.type === 'session-ended') {
381
+ for (const s of [...this._sessions]) {
382
+ if (s.ctx?.sessionId && s.ctx.sessionId === event.sessionId) {
383
+ this.end(s, cli_shell_options_1.ShellCloseCodes.LoginRequired, 'session ended', 'session ended');
384
+ }
154
385
  }
155
- catch {
386
+ }
387
+ else {
388
+ void this.recheck(event.userId);
389
+ }
390
+ }
391
+ ensureCheckTimer() {
392
+ if (this._checkTimer || !this._auth)
393
+ return;
394
+ const interval = Math.min(Math.max(this._options.sessionCheckIntervalMs ?? cli_shell_options_1.SHELL_DEFAULTS.sessionCheckIntervalMs, 10), cli_shell_options_1.SHELL_DEFAULTS.maxSessionCheckIntervalMs);
395
+ this._checkTimer = setInterval(() => void this.recheck(), interval);
396
+ this._checkTimer.unref?.();
397
+ }
398
+ stopCheckTimerIfIdle() {
399
+ if (this._checkTimer && ![...this._sessions].some((s) => s.ctx)) {
400
+ clearInterval(this._checkTimer);
401
+ this._checkTimer = undefined;
402
+ }
403
+ }
404
+ /**
405
+ * Re-validates users-mode shells: session alive, user enabled, still holding
406
+ * `shell:execute` (identities from a host auth adapter are re-authenticated
407
+ * from the original upgrade request). Otherwise the shell is closed with 4401
408
+ * `session ended` (audit reason `session ended` or `permission removed`).
409
+ * The check itself never extends the session; stdin received since the
410
+ * previous check touches it first (at most once per 30 s).
411
+ */
412
+ async recheck(userId) {
413
+ for (const s of [...this._sessions]) {
414
+ if (s.closed || !s.ctx || (userId && s.ctx.userId !== userId))
156
415
  continue;
416
+ await this.revalidateSession(s);
417
+ }
418
+ }
419
+ /** One re-check of a users-mode shell; ends it when the session ended or lost `shell:execute`. */
420
+ async revalidateSession(s) {
421
+ const auth = this._auth;
422
+ if (s.closed || !s.ctx)
423
+ return;
424
+ let fresh = s.ctx;
425
+ const now = Date.now();
426
+ const typed = s.inputSinceCheck;
427
+ s.inputSinceCheck = false;
428
+ try {
429
+ if (typed && auth?.touch && now - s.lastTouch >= cli_shell_options_1.SHELL_DEFAULTS.touchIntervalMs) {
430
+ s.lastTouch = now;
431
+ await auth.touch(s.ctx);
157
432
  }
433
+ fresh = auth?.revalidate ? await auth.revalidate(s.ctx, s.request) : s.ctx;
434
+ }
435
+ catch {
436
+ fresh = undefined;
437
+ }
438
+ if (s.closed)
439
+ return;
440
+ if (!fresh || !auth || !auth.hasPermission(fresh, cli_server_auth_1.CliServerPermissions.ShellExecute)) {
441
+ this.end(s, cli_shell_options_1.ShellCloseCodes.LoginRequired, 'session ended', fresh ? 'permission removed' : 'session ended');
442
+ }
443
+ else {
444
+ s.ctx = { ...s.ctx, permissions: fresh.permissions };
445
+ }
446
+ }
447
+ // ------------------------------------------------------------ lifecycle
448
+ onOpened(session) {
449
+ if (session.authMode === 'users' && session.ctx) {
450
+ this.audit(session, 'shell_opened', {});
158
451
  }
159
- return '/bin/sh';
452
+ else {
453
+ logger.info('Shell opened (id=%s, auth=%s, mode=%s, remote=%s)', session.id, session.authMode, session.mode, session.remoteAddress);
454
+ }
455
+ }
456
+ /**
457
+ * Ends a session once (`why` is the audit reason: exited | closed | session ended |
458
+ * permission removed | shell timed out | server shutdown | error): kills the process tree, closes the socket with the
459
+ * given code (when still open) and audits/logs the close.
460
+ */
461
+ end(session, code, reason, why, exitCode) {
462
+ if (session.closed)
463
+ return;
464
+ session.closed = true;
465
+ this._sessions.delete(session);
466
+ if (session.idleTimer)
467
+ clearTimeout(session.idleTimer);
468
+ if (session.durationTimer)
469
+ clearTimeout(session.durationTimer);
470
+ this.stopCheckTimerIfIdle();
471
+ if (session.pty) {
472
+ killTree(session.pty, session.shellId);
473
+ }
474
+ if (code !== undefined) {
475
+ closeWs(session.ws, code, reason ?? '');
476
+ }
477
+ if (!session.pty)
478
+ return; // never opened
479
+ const durationMs = Date.now() - session.startedAt;
480
+ if (session.authMode === 'users' && session.ctx) {
481
+ this.audit(session, 'shell_closed', { durationMs, reason: why, ...(why === 'exited' ? { exitCode } : {}) });
482
+ }
483
+ else {
484
+ logger.info('Shell closed (id=%s, auth=%s, mode=%s, remote=%s, reason=%s, durationMs=%d)', session.id, session.authMode, session.mode, session.remoteAddress, why, durationMs);
485
+ }
486
+ }
487
+ audit(session, event, extra) {
488
+ const ctx = session.ctx;
489
+ const audit = this._auth?.audit;
490
+ if (!audit)
491
+ return;
492
+ audit
493
+ .call(this._auth, {
494
+ event,
495
+ userId: ctx.userId,
496
+ userName: ctx.userName,
497
+ actorId: ctx.userId,
498
+ actorName: ctx.userName,
499
+ metadata: {
500
+ mode: session.mode,
501
+ sessionId: ctx.sessionId,
502
+ remoteAddress: session.remoteAddress,
503
+ ...extra,
504
+ },
505
+ })
506
+ .catch((err) => logger.error('Shell audit failed: %s', err?.message ?? err));
507
+ }
508
+ /** Closes every open shell (server shutdown). */
509
+ dispose() {
510
+ for (const s of [...this._sessions]) {
511
+ this.end(s, 1001, 'server shutdown', 'server shutdown');
512
+ }
513
+ if (this._checkTimer)
514
+ clearInterval(this._checkTimer);
515
+ this._checkTimer = undefined;
516
+ this._unsubscribe?.();
517
+ this._unsubscribe = undefined;
518
+ }
519
+ // -------------------------------------------------------------- helpers
520
+ remoteAddressOf(request) {
521
+ return (0, cli_server_auth_1.clientAddress)(request, this._trustProxy);
522
+ }
523
+ /** Determines the shell binary and arguments based on options, platform and optional command. */
524
+ getShellInfo(command) {
525
+ if (os.platform() === 'win32') {
526
+ const shell = this._options.shell ?? 'powershell.exe';
527
+ return command ? { shell, args: ['-Command', command] } : { shell, args: [] };
528
+ }
529
+ const shell = this._options.shell ?? detectShell();
530
+ return command ? { shell, args: ['-c', command] } : { shell, args: [] };
160
531
  }
532
+ /** Sends a JSON message to the WebSocket if the connection is open. */
161
533
  send(ws, msg) {
162
534
  if (ws.readyState === ws_1.WebSocket.OPEN) {
163
535
  ws.send(JSON.stringify(msg));
@@ -165,4 +537,52 @@ class CliShellSessionManager {
165
537
  }
166
538
  }
167
539
  exports.CliShellSessionManager = CliShellSessionManager;
540
+ /** Detects the best available shell on Unix systems by checking $SHELL and common paths. */
541
+ function detectShell() {
542
+ const candidates = [process.env.SHELL, '/bin/bash', '/usr/bin/bash', '/bin/sh'].filter(Boolean);
543
+ for (const candidate of candidates) {
544
+ try {
545
+ fs.accessSync(candidate, fs.constants.X_OK);
546
+ return candidate;
547
+ }
548
+ catch {
549
+ continue;
550
+ }
551
+ }
552
+ return '/bin/sh';
553
+ }
554
+ function clampDim(value, fallback) {
555
+ const n = parseInt(value ?? '', 10);
556
+ if (!Number.isFinite(n) || n <= 0)
557
+ return fallback;
558
+ return Math.min(n, 1000);
559
+ }
560
+ function closeWs(ws, code, reason) {
561
+ if (ws.readyState === ws_1.WebSocket.OPEN || ws.readyState === ws_1.WebSocket.CONNECTING) {
562
+ try {
563
+ ws.close(code, reason);
564
+ }
565
+ catch {
566
+ ws.terminate();
567
+ }
568
+ }
569
+ }
570
+ /**
571
+ * Kills the shell and everything it started. Unix: the descendant tree and every
572
+ * process carrying the shell's `QCLI_SHELL_ID` marker are collected before
573
+ * signalling (background jobs in their own process groups, `setsid`/`nohup`
574
+ * children, re-parented daemons), then HUP → TERM → (grace) → KILL.
575
+ */
576
+ function killTree(pty, shellId) {
577
+ if (os.platform() !== 'win32') {
578
+ (0, process_tree_1.terminateProcessTree)(pty.pid, undefined, shellId);
579
+ return;
580
+ }
581
+ try {
582
+ pty.kill();
583
+ }
584
+ catch {
585
+ // already exited
586
+ }
587
+ }
168
588
  //# sourceMappingURL=cli-shell-session-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-shell-session-manager.js","sourceRoot":"","sources":["../../../src/services/cli-shell-session-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-shell-session-manager.js","sourceRoot":"","sources":["../../../src/services/cli-shell-session-manager.ts"],"names":[],"mappings":"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"}