@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
@@ -1,12 +1,33 @@
1
- import { CliProcessCommand } from '../abstractions';
1
+ import { CliProcessCommand, ICliCommandProcessor, ICliProcessorFilter } from '../abstractions';
2
2
  import { CliServerResponse } from '../models';
3
3
  import { ICliCommandRegistry } from './cli-command-registry';
4
+ /** Service contract for executing parsed CLI commands. */
4
5
  export interface ICliCommandExecutorService {
5
- executeAsync(command: CliProcessCommand): Promise<CliServerResponse>;
6
+ /**
7
+ * Executes a parsed command by routing it to the appropriate processor.
8
+ * @param command - Parsed command to execute.
9
+ * @param signal - Optional AbortSignal to cancel the operation.
10
+ * @returns Structured response with exit code and outputs.
11
+ */
12
+ executeAsync(command: CliProcessCommand, signal?: AbortSignal): Promise<CliServerResponse>;
13
+ /**
14
+ * Adds a processor filter that can block command execution at runtime.
15
+ * @param filter - The filter to add.
16
+ */
17
+ addFilter(filter: ICliProcessorFilter): void;
18
+ /**
19
+ * Returns true if any registered filter blocks the given processor.
20
+ * @param processor - The processor to check.
21
+ */
22
+ isBlocked(processor: ICliCommandProcessor): boolean;
6
23
  }
24
+ /** Default executor that resolves processors from the registry and delegates command handling. */
7
25
  export declare class CliCommandExecutorService implements ICliCommandExecutorService {
8
26
  private readonly _registry;
27
+ private readonly _filters;
9
28
  constructor(_registry: ICliCommandRegistry);
10
- executeAsync(command: CliProcessCommand): Promise<CliServerResponse>;
29
+ addFilter(filter: ICliProcessorFilter): void;
30
+ isBlocked(processor: ICliCommandProcessor): boolean;
31
+ executeAsync(command: CliProcessCommand, signal?: AbortSignal): Promise<CliServerResponse>;
11
32
  }
12
33
  //# sourceMappingURL=cli-command-executor-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-command-executor-service.d.ts","sourceRoot":"","sources":["../../../src/services/cli-command-executor-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,WAAW,0BAA0B;IACvC,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxE;AAED,qBAAa,yBAA0B,YAAW,0BAA0B;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,mBAAmB;IAErD,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAsC7E"}
1
+ {"version":3,"file":"cli-command-executor-service.d.ts","sourceRoot":"","sources":["../../../src/services/cli-command-executor-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAK7D,0DAA0D;AAC1D,MAAM,WAAW,0BAA0B;IACvC;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE3F;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAE7C;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAAC;CACvD;AAED,kGAAkG;AAClG,qBAAa,yBAA0B,YAAW,0BAA0B;IAG5D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;gBAEzB,SAAS,EAAE,mBAAmB;IAE3D,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAI5C,SAAS,CAAC,SAAS,EAAE,oBAAoB,GAAG,OAAO;IAI7C,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA8DnG"}
@@ -1,12 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CliCommandExecutorService = void 0;
4
+ const logger_1 = require("../utils/logger");
5
+ const logger = (0, logger_1.createLogger)('CommandExecutor');
6
+ /** Default executor that resolves processors from the registry and delegates command handling. */
4
7
  class CliCommandExecutorService {
5
8
  _registry;
9
+ _filters = [];
6
10
  constructor(_registry) {
7
11
  this._registry = _registry;
8
12
  }
9
- async executeAsync(command) {
13
+ addFilter(filter) {
14
+ this._filters.push(filter);
15
+ }
16
+ isBlocked(processor) {
17
+ return this._filters.some(f => !f.isAllowed(processor));
18
+ }
19
+ async executeAsync(command, signal) {
20
+ logger.debug('Executing command: %s', command.command);
10
21
  const processor = this._registry.findProcessor(command.command, command.chainCommands?.length ? command.chainCommands : undefined);
11
22
  if (!processor) {
12
23
  return {
@@ -20,14 +31,35 @@ class CliCommandExecutorService {
20
31
  ],
21
32
  };
22
33
  }
23
- try {
24
- const result = await processor.handleAsync(command);
34
+ if (this.isBlocked(processor)) {
35
+ logger.warn('Command blocked by filter (plugin disabled): %s', command.command);
25
36
  return {
37
+ exitCode: 1,
38
+ outputs: [
39
+ {
40
+ type: 'text',
41
+ value: `Command '${command.command}' is currently disabled.`,
42
+ style: 'error',
43
+ },
44
+ ],
45
+ };
46
+ }
47
+ try {
48
+ if (processor.handleStructuredAsync) {
49
+ const response = await processor.handleStructuredAsync(command, signal);
50
+ logger.debug('Command completed: %s (exitCode=%d)', command.command, response.exitCode);
51
+ return response;
52
+ }
53
+ const result = await processor.handleAsync(command, signal);
54
+ const response = {
26
55
  exitCode: 0,
27
56
  outputs: [{ type: 'text', value: result }],
28
57
  };
58
+ logger.debug('Command completed: %s (exitCode=%d)', command.command, response.exitCode);
59
+ return response;
29
60
  }
30
61
  catch (err) {
62
+ logger.error('Command execution failed: %s - %s', command.command, err.message ?? err);
31
63
  return {
32
64
  exitCode: 1,
33
65
  outputs: [
@@ -1 +1 @@
1
- {"version":3,"file":"cli-command-executor-service.js","sourceRoot":"","sources":["../../../src/services/cli-command-executor-service.ts"],"names":[],"mappings":";;;AAQA,MAAa,yBAAyB;IACL;IAA7B,YAA6B,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAE/D,KAAK,CAAC,YAAY,CAAC,OAA0B;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAC1C,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CACpE,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO;gBACH,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,oBAAoB,OAAO,CAAC,OAAO,EAAE;wBAC5C,KAAK,EAAE,OAAO;qBACjB;iBACJ;aACJ,CAAC;QACN,CAAC;QAED,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACpD,OAAO;gBACH,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;aAC7C,CAAC;QACN,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,OAAO;gBACH,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,4BAA4B,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE;wBACvD,KAAK,EAAE,OAAO;qBACjB;iBACJ;aACJ,CAAC;QACN,CAAC;IACL,CAAC;CACJ;AAzCD,8DAyCC"}
1
+ {"version":3,"file":"cli-command-executor-service.js","sourceRoot":"","sources":["../../../src/services/cli-command-executor-service.ts"],"names":[],"mappings":";;;AAGA,4CAA+C;AAE/C,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,iBAAiB,CAAC,CAAC;AAyB/C,kGAAkG;AAClG,MAAa,yBAAyB;IAGL;IAFZ,QAAQ,GAA0B,EAAE,CAAC;IAEtD,YAA6B,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAE/D,SAAS,CAAC,MAA2B;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,SAAS,CAAC,SAA+B;QACrC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAA0B,EAAE,MAAoB;QAC/D,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAC1C,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CACpE,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO;gBACH,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,oBAAoB,OAAO,CAAC,OAAO,EAAE;wBAC5C,KAAK,EAAE,OAAO;qBACjB;iBACJ;aACJ,CAAC;QACN,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,iDAAiD,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAChF,OAAO;gBACH,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,YAAY,OAAO,CAAC,OAAO,0BAA0B;wBAC5D,KAAK,EAAE,OAAO;qBACjB;iBACJ;aACJ,CAAC;QACN,CAAC;QAED,IAAI,CAAC;YACD,IAAI,SAAS,CAAC,qBAAqB,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBACxE,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACxF,OAAO,QAAQ,CAAC;YACpB,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAsB;gBAChC,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;aAC7C,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxF,OAAO,QAAQ,CAAC;QACpB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;YACvF,OAAO;gBACH,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,MAAM;wBACZ,KAAK,EAAE,4BAA4B,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE;wBACvD,KAAK,EAAE,OAAO;qBACjB;iBACJ;aACJ,CAAC;QACN,CAAC;IACL,CAAC;CACJ;AA3ED,8DA2EC"}
@@ -1,14 +1,25 @@
1
1
  import { ICliCommandProcessor } from '../abstractions';
2
+ /** Registry that stores and looks up CLI command processors by command name. */
2
3
  export interface ICliCommandRegistry {
4
+ /** All registered top-level processors. */
3
5
  readonly processors: ReadonlyArray<ICliCommandProcessor>;
6
+ /** Registers a command processor. */
4
7
  register(processor: ICliCommandProcessor): void;
8
+ /**
9
+ * Finds a processor by command name, optionally resolving a sub-command chain.
10
+ * @param command - Top-level command name.
11
+ * @param chainCommands - Optional sub-command chain to resolve.
12
+ * @returns Matching processor, or undefined if not found.
13
+ */
5
14
  findProcessor(command: string, chainCommands?: string[]): ICliCommandProcessor | undefined;
6
15
  }
16
+ /** Default in-memory implementation of {@link ICliCommandRegistry}. */
7
17
  export declare class CliCommandRegistry implements ICliCommandRegistry {
8
18
  private _processors;
9
19
  get processors(): ReadonlyArray<ICliCommandProcessor>;
10
20
  register(processor: ICliCommandProcessor): void;
11
21
  findProcessor(command: string, chainCommands?: string[]): ICliCommandProcessor | undefined;
22
+ /** Walks the sub-processor tree to resolve a chain of sub-commands. */
12
23
  private resolveChain;
13
24
  }
14
25
  //# sourceMappingURL=cli-command-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-command-registry.d.ts","sourceRoot":"","sources":["../../../src/services/cli-command-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACzD,QAAQ,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAChD,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,oBAAoB,GAAG,SAAS,CAAC;CAC9F;AAED,qBAAa,kBAAmB,YAAW,mBAAmB;IAC1D,OAAO,CAAC,WAAW,CAAgD;IAEnE,IAAI,UAAU,IAAI,aAAa,CAAC,oBAAoB,CAAC,CAEpD;IAED,QAAQ,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI;IAI/C,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,oBAAoB,GAAG,SAAS;IAS1F,OAAO,CAAC,YAAY;CAkBvB"}
1
+ {"version":3,"file":"cli-command-registry.d.ts","sourceRoot":"","sources":["../../../src/services/cli-command-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAKvD,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACzD,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAChD;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,oBAAoB,GAAG,SAAS,CAAC;CAC9F;AAED,uEAAuE;AACvE,qBAAa,kBAAmB,YAAW,mBAAmB;IAC1D,OAAO,CAAC,WAAW,CAAgD;IAEnE,IAAI,UAAU,IAAI,aAAa,CAAC,oBAAoB,CAAC,CAEpD;IAED,QAAQ,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI;IAK/C,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,oBAAoB,GAAG,SAAS;IAS1F,uEAAuE;IACvE,OAAO,CAAC,YAAY;CAkBvB"}
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CliCommandRegistry = void 0;
4
+ const logger_1 = require("../utils/logger");
5
+ const logger = (0, logger_1.createLogger)('CommandRegistry');
6
+ /** Default in-memory implementation of {@link ICliCommandRegistry}. */
4
7
  class CliCommandRegistry {
5
8
  _processors = new Map();
6
9
  get processors() {
@@ -8,6 +11,7 @@ class CliCommandRegistry {
8
11
  }
9
12
  register(processor) {
10
13
  this._processors.set(processor.command.toLowerCase(), processor);
14
+ logger.debug('Registered processor: %s', processor.command);
11
15
  }
12
16
  findProcessor(command, chainCommands) {
13
17
  const processor = this._processors.get(command.toLowerCase());
@@ -16,6 +20,7 @@ class CliCommandRegistry {
16
20
  }
17
21
  return this.resolveChain(processor, chainCommands);
18
22
  }
23
+ /** Walks the sub-processor tree to resolve a chain of sub-commands. */
19
24
  resolveChain(processor, chainCommands) {
20
25
  let current = processor;
21
26
  for (const sub of chainCommands) {
@@ -1 +1 @@
1
- {"version":3,"file":"cli-command-registry.js","sourceRoot":"","sources":["../../../src/services/cli-command-registry.ts"],"names":[],"mappings":";;;AAQA,MAAa,kBAAkB;IACnB,WAAW,GAAsC,IAAI,GAAG,EAAE,CAAC;IAEnE,IAAI,UAAU;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,QAAQ,CAAC,SAA+B;QACpC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,SAAS,CAAC,CAAC;IACrE,CAAC;IAED,aAAa,CAAC,OAAe,EAAE,aAAwB;QACnD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;YACvC,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACvD,CAAC;IAEO,YAAY,CAChB,SAA+B,EAC/B,aAAuB;QAEvB,IAAI,OAAO,GAAG,SAAS,CAAC;QAExB,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE,CACvD,CAAC;YACF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;YAC/D,CAAC;YACD,OAAO,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ;AAtCD,gDAsCC"}
1
+ {"version":3,"file":"cli-command-registry.js","sourceRoot":"","sources":["../../../src/services/cli-command-registry.ts"],"names":[],"mappings":";;;AACA,4CAA+C;AAE/C,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,iBAAiB,CAAC,CAAC;AAiB/C,uEAAuE;AACvE,MAAa,kBAAkB;IACnB,WAAW,GAAsC,IAAI,GAAG,EAAE,CAAC;IAEnE,IAAI,UAAU;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,QAAQ,CAAC,SAA+B;QACpC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,SAAS,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC;IAED,aAAa,CAAC,OAAe,EAAE,aAAwB;QACnD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;YACvC,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACvD,CAAC;IAED,uEAAuE;IAC/D,YAAY,CAChB,SAA+B,EAC/B,aAAuB;QAEvB,IAAI,OAAO,GAAG,SAAS,CAAC;QAExB,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE,CACvD,CAAC;YACF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;YAC/D,CAAC;YACD,OAAO,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ;AAxCD,gDAwCC"}
@@ -1,16 +1,57 @@
1
1
  import type { Server } from 'http';
2
+ import { CliShellSessionManager } from './cli-shell-session-manager';
3
+ import { CliShellAuthMode, CliShellOptions } from './cli-shell-options';
4
+ import { ICliServerAuth } from '../auth/cli-server-auth';
5
+ /** Information about a connected WebSocket event client. */
2
6
  export interface CliWebSocketClientInfo {
3
7
  id: string;
4
8
  connectedAt: string;
5
9
  remoteAddress: string;
6
10
  type: 'events';
7
11
  }
12
+ export interface CliEventSocketManagerOptions {
13
+ /** Accept interactive shell sessions on `/ws/v1/qcli/shell` (default false). */
14
+ enableShell?: boolean;
15
+ /** Shell security options (access mode, limits, timeouts, environment). */
16
+ shell?: CliShellOptions;
17
+ /**
18
+ * Trusted reverse-proxy hops (`true` = 1, `false`/0 = none) for `X-Forwarded-*`
19
+ * headers (shell per-address limits/logs, same-origin checks).
20
+ */
21
+ trustProxy?: boolean | number;
22
+ /** When set, every upgrade with an `Origin` header must come from one of these. */
23
+ allowedOrigins?: string[];
24
+ }
25
+ /**
26
+ * Manages WebSocket connections for server-push events and interactive shell sessions.
27
+ * Handles upgrades on `/ws/v1/qcli/events` and (when `enableShell` is set)
28
+ * `/ws/v1/qcli/shell`. With an auth provider that protects the server, event
29
+ * upgrades need a single-use `?ticket=`; `session-kicked` is delivered only to
30
+ * the affected user. Sockets authenticated with a stored session are bound to
31
+ * it: once it ends they are closed with 4401 `session ended` (after
32
+ * `session-kicked` for revocations; see {@link SessionBoundSockets}). Shell
33
+ * access (modes, limits, session binding) is decided by {@link CliShellSessionManager}.
34
+ */
8
35
  export declare class CliEventSocketManager {
9
36
  private _wss;
10
37
  private readonly _clients;
11
38
  private readonly _clientMeta;
12
39
  private readonly _shellManager;
13
40
  private _nextClientId;
41
+ private _auth?;
42
+ private _allowedOrigins?;
43
+ private readonly _trustProxy;
44
+ private readonly _sessionBound;
45
+ constructor(options?: CliEventSocketManagerOptions);
46
+ /** Installs the auth provider (users plugin) used to authenticate upgrades with tickets. */
47
+ setAuth(auth: ICliServerAuth | undefined): void;
48
+ setAllowedOrigins(origins: string[] | undefined): void;
49
+ setShellEnabled(enabled: boolean): void;
50
+ get shellEnabled(): boolean;
51
+ /** Shell access mode (`undefined` while the shell is disabled). */
52
+ get shellAuthMode(): CliShellAuthMode | undefined;
53
+ /** The shell session manager (open sessions, limits, binding). */
54
+ get shellManager(): CliShellSessionManager;
14
55
  private static readonly EVENT_PATHS;
15
56
  private static readonly SHELL_PATHS;
16
57
  /**
@@ -30,6 +71,7 @@ export declare class CliEventSocketManager {
30
71
  * Return information about all currently connected event clients.
31
72
  */
32
73
  getClients(): CliWebSocketClientInfo[];
74
+ /** Terminates all connections and closes the WebSocket server. */
33
75
  dispose(): void;
34
76
  }
35
77
  //# sourceMappingURL=cli-event-socket-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-event-socket-manager.d.ts","sourceRoot":"","sources":["../../../src/services/cli-event-socket-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,MAAM,CAAC;AAIpD,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,QAAQ,CAAC;CAClB;AAQD,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IACjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,aAAa,CAAK;IAE1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAGhC;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAGhC;IAEH;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAwD5B;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IASxD;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB1C;;OAEG;IACH,UAAU,IAAI,sBAAsB,EAAE;IAkBtC,OAAO,IAAI,IAAI;CAQlB"}
1
+ {"version":3,"file":"cli-event-socket-manager.d.ts","sourceRoot":"","sources":["../../../src/services/cli-event-socket-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,MAAM,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAExE,OAAO,EAA8C,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAMrG,4DAA4D;AAC5D,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,QAAQ,CAAC;CAClB;AAUD,MAAM,WAAW,4BAA4B;IACzC,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAKD;;;;;;;;;GASG;AACH,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IACjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgD;gBAElE,OAAO,GAAE,4BAAiC;IAUtD,4FAA4F;IAC5F,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI;IAM/C,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI;IAItD,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIvC,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,mEAAmE;IACnE,IAAI,aAAa,IAAI,gBAAgB,GAAG,SAAS,CAEhD;IAED,kEAAkE;IAClE,IAAI,YAAY,IAAI,sBAAsB,CAEzC;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAGhC;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAGhC;IAEH;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IA+E5B;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAyCxD;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1C;;OAEG;IACH,UAAU,IAAI,sBAAsB,EAAE;IAkBtC,kEAAkE;IAClE,OAAO,IAAI,IAAI;CAUlB"}
@@ -4,12 +4,65 @@ exports.CliEventSocketManager = void 0;
4
4
  const ws_1 = require("ws");
5
5
  const url_1 = require("url");
6
6
  const cli_shell_session_manager_1 = require("./cli-shell-session-manager");
7
+ const logger_1 = require("../utils/logger");
8
+ const cli_server_auth_1 = require("../auth/cli-server-auth");
9
+ const ws_upgrade_auth_1 = require("../auth/ws-upgrade-auth");
10
+ const session_bound_sockets_1 = require("./session-bound-sockets");
11
+ const logger = (0, logger_1.createLogger)('EventSocket');
12
+ /** Events delivered only to sockets authenticated as the event's user. */
13
+ const USER_SCOPED_EVENTS = new Set(['session-kicked']);
14
+ /**
15
+ * Manages WebSocket connections for server-push events and interactive shell sessions.
16
+ * Handles upgrades on `/ws/v1/qcli/events` and (when `enableShell` is set)
17
+ * `/ws/v1/qcli/shell`. With an auth provider that protects the server, event
18
+ * upgrades need a single-use `?ticket=`; `session-kicked` is delivered only to
19
+ * the affected user. Sockets authenticated with a stored session are bound to
20
+ * it: once it ends they are closed with 4401 `session ended` (after
21
+ * `session-kicked` for revocations; see {@link SessionBoundSockets}). Shell
22
+ * access (modes, limits, session binding) is decided by {@link CliShellSessionManager}.
23
+ */
7
24
  class CliEventSocketManager {
8
25
  _wss = null;
9
26
  _clients = new Set();
10
27
  _clientMeta = new Map();
11
- _shellManager = new cli_shell_session_manager_1.CliShellSessionManager();
28
+ _shellManager;
12
29
  _nextClientId = 1;
30
+ _auth;
31
+ _allowedOrigins;
32
+ _trustProxy;
33
+ _sessionBound = new session_bound_sockets_1.SessionBoundSockets({ awaitKick: true });
34
+ constructor(options = {}) {
35
+ this._shellManager = new cli_shell_session_manager_1.CliShellSessionManager({
36
+ enabled: options.enableShell ?? false,
37
+ shell: options.shell,
38
+ trustProxy: options.trustProxy,
39
+ });
40
+ this._allowedOrigins = options.allowedOrigins;
41
+ this._trustProxy = options.trustProxy ?? false;
42
+ }
43
+ /** Installs the auth provider (users plugin) used to authenticate upgrades with tickets. */
44
+ setAuth(auth) {
45
+ this._auth = auth;
46
+ this._shellManager.setAuth(auth);
47
+ this._sessionBound.setAuth(auth);
48
+ }
49
+ setAllowedOrigins(origins) {
50
+ this._allowedOrigins = origins;
51
+ }
52
+ setShellEnabled(enabled) {
53
+ this._shellManager.setEnabled(enabled);
54
+ }
55
+ get shellEnabled() {
56
+ return this._shellManager.enabled;
57
+ }
58
+ /** Shell access mode (`undefined` while the shell is disabled). */
59
+ get shellAuthMode() {
60
+ return this._shellManager.authMode;
61
+ }
62
+ /** The shell session manager (open sessions, limits, binding). */
63
+ get shellManager() {
64
+ return this._shellManager;
65
+ }
13
66
  static EVENT_PATHS = new Set([
14
67
  '/ws/v1/qcli/events',
15
68
  '/ws/qcli/events',
@@ -24,50 +77,73 @@ class CliEventSocketManager {
24
77
  */
25
78
  attach(server) {
26
79
  this._wss = new ws_1.WebSocketServer({ noServer: true });
80
+ this._shellManager.logStartupState();
27
81
  server.on('upgrade', (request, socket, head) => {
28
- const parsed = new url_1.URL(request.url ?? '', 'http://localhost');
82
+ let parsed;
83
+ try {
84
+ parsed = new url_1.URL(request.url ?? '', 'http://localhost');
85
+ }
86
+ catch {
87
+ return; // malformed request target: not one of our paths
88
+ }
29
89
  const pathname = parsed.pathname;
30
90
  if (CliEventSocketManager.EVENT_PATHS.has(pathname)) {
31
- this._wss.handleUpgrade(request, socket, head, (ws) => {
32
- this._wss.emit('connection', ws, request);
33
- });
91
+ (0, ws_upgrade_auth_1.authorizeWsUpgrade)(request, parsed, { auth: this._auth, allowedOrigins: this._allowedOrigins, trustProxy: this._trustProxy }).then((result) => {
92
+ if (!result.ok) {
93
+ (0, ws_upgrade_auth_1.rejectUpgrade)(socket, result.status);
94
+ return;
95
+ }
96
+ this._wss.handleUpgrade(request, socket, head, (ws) => {
97
+ this._wss.emit('connection', ws, request, result.ctx);
98
+ });
99
+ }, () => (0, ws_upgrade_auth_1.rejectUpgrade)(socket, 401));
34
100
  return;
35
101
  }
36
102
  if (CliEventSocketManager.SHELL_PATHS.has(pathname)) {
37
- this._wss.handleUpgrade(request, socket, head, (ws) => {
38
- const cols = parseInt(parsed.searchParams.get('cols') ?? '80', 10) || 80;
39
- const rows = parseInt(parsed.searchParams.get('rows') ?? '24', 10) || 24;
40
- const cmd = parsed.searchParams.get('cmd') || undefined;
41
- this._shellManager.handleSession(ws, cols, rows, cmd).catch((err) => {
42
- try {
43
- ws.send(JSON.stringify({ type: 'error', message: err.message }));
44
- ws.close();
45
- }
46
- catch {
47
- // ignore
48
- }
103
+ // Origin rejection stays an HTTP 403; every other refusal is
104
+ // "accept, then close" with a code the browser can read (C5).
105
+ (0, ws_upgrade_auth_1.authorizeWsUpgrade)(request, parsed, { allowedOrigins: this._allowedOrigins, trustProxy: this._trustProxy }).then((result) => {
106
+ if (!result.ok) {
107
+ (0, ws_upgrade_auth_1.rejectUpgrade)(socket, result.status);
108
+ return;
109
+ }
110
+ this._wss.handleUpgrade(request, socket, head, (ws) => {
111
+ this._shellManager.accept(ws, request, parsed).catch((err) => {
112
+ logger.error('Shell session error: %s', err?.message ?? err);
113
+ try {
114
+ ws.close(1011, 'shell error');
115
+ }
116
+ catch {
117
+ // ignore
118
+ }
119
+ });
49
120
  });
50
121
  });
51
122
  return;
52
123
  }
53
- // Not our path — let other handlers deal with it
124
+ // Unrecognized path; leave for other upgrade handlers
54
125
  });
55
- this._wss.on('connection', (ws, request) => {
126
+ this._wss.on('connection', (ws, request, auth) => {
56
127
  this._clients.add(ws);
128
+ const id = `evt-${this._nextClientId++}`;
57
129
  this._clientMeta.set(ws, {
58
- id: `evt-${this._nextClientId++}`,
130
+ id,
59
131
  connectedAt: new Date(),
60
132
  remoteAddress: request.socket.remoteAddress ?? 'unknown',
133
+ auth,
61
134
  });
135
+ this._sessionBound.bind(ws, auth);
136
+ logger.info('Client connected (id=%s)', id);
62
137
  ws.send(JSON.stringify({ type: 'connected' }));
63
- ws.on('close', () => {
64
- this._clients.delete(ws);
65
- this._clientMeta.delete(ws);
66
- });
67
- ws.on('error', () => {
138
+ const disconnected = () => {
139
+ const meta = this._clientMeta.get(ws);
140
+ logger.info('Client disconnected (id=%s)', meta?.id ?? 'unknown');
141
+ this._sessionBound.unbind(ws);
68
142
  this._clients.delete(ws);
69
143
  this._clientMeta.delete(ws);
70
- });
144
+ };
145
+ ws.on('close', disconnected);
146
+ ws.on('error', disconnected);
71
147
  });
72
148
  }
73
149
  /**
@@ -75,16 +151,47 @@ class CliEventSocketManager {
75
151
  */
76
152
  broadcastMessage(message) {
77
153
  const data = JSON.stringify(message);
154
+ const type = typeof message.type === 'string' ? message.type : '';
155
+ const payload = (message.data ?? {});
156
+ const toClose = [];
78
157
  for (const ws of this._clients) {
79
- if (ws.readyState === ws_1.WebSocket.OPEN) {
158
+ if (ws.readyState !== ws_1.WebSocket.OPEN)
159
+ continue;
160
+ const auth = this._clientMeta.get(ws)?.auth;
161
+ if (USER_SCOPED_EVENTS.has(type)) {
162
+ // Only the affected user's sockets learn about it
163
+ if (!auth || auth.userId !== payload.userId)
164
+ continue;
80
165
  ws.send(data);
166
+ if (type === 'session-kicked' && auth.sessionId && auth.sessionId === payload.sessionId) {
167
+ toClose.push(ws);
168
+ }
169
+ continue;
81
170
  }
171
+ // A socket whose session ended only waits for its session-kicked
172
+ if (this._sessionBound.isEnding(ws))
173
+ continue;
174
+ if (this._auth?.protectServer) {
175
+ // Server-wide events need the matching read permission
176
+ const needed = type === 'log' || type.startsWith('log:')
177
+ ? cli_server_auth_1.CliServerPermissions.LogsRead
178
+ : type.startsWith('job:')
179
+ ? cli_server_auth_1.CliServerPermissions.JobsRead
180
+ : undefined;
181
+ if (needed && (!auth || !this._auth.hasPermission(auth, needed)))
182
+ continue;
183
+ }
184
+ ws.send(data);
185
+ }
186
+ for (const ws of toClose) {
187
+ this._sessionBound.kicked(ws);
82
188
  }
83
189
  }
84
190
  /**
85
191
  * Broadcast a disconnect event to all connected clients and close sockets.
86
192
  */
87
193
  async broadcastDisconnect() {
194
+ logger.info('Broadcasting disconnect to %d clients', this._clients.size);
88
195
  const message = JSON.stringify({ type: 'disconnect' });
89
196
  const promises = [];
90
197
  for (const ws of this._clients) {
@@ -98,6 +205,8 @@ class CliEventSocketManager {
98
205
  }
99
206
  }
100
207
  await Promise.all(promises);
208
+ this._shellManager.dispose();
209
+ this._sessionBound.dispose();
101
210
  this._clients.clear();
102
211
  this._clientMeta.clear();
103
212
  }
@@ -121,7 +230,10 @@ class CliEventSocketManager {
121
230
  }
122
231
  return result;
123
232
  }
233
+ /** Terminates all connections and closes the WebSocket server. */
124
234
  dispose() {
235
+ this._shellManager.dispose();
236
+ this._sessionBound.dispose();
125
237
  for (const ws of this._clients) {
126
238
  ws.terminate();
127
239
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cli-event-socket-manager.js","sourceRoot":"","sources":["../../../src/services/cli-event-socket-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-event-socket-manager.js","sourceRoot":"","sources":["../../../src/services/cli-event-socket-manager.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import type { Server } from 'http';
2
+ import { ICliServerAuth } from '../auth/cli-server-auth';
3
+ /** Information about a connected WebSocket log-streaming client. */
2
4
  export interface CliLogWebSocketClientInfo {
3
5
  id: string;
4
6
  connectedAt: string;
@@ -10,12 +12,25 @@ export interface CliLogWebSocketClientInfo {
10
12
  * Manages WebSocket connections for streaming log messages to clients.
11
13
  *
12
14
  * Parity with CliLogSocketManager in the .NET and Python servers.
13
- * Handles `/ws/v1/qcli/logs` and `/ws/qcli/logs` upgrade paths.
15
+ * Handles `/ws/v1/qcli/logs` and `/ws/qcli/logs` upgrade paths. Sockets
16
+ * authenticated with a stored session are bound to it: once it ends they are
17
+ * closed with 4401 `session ended` (see {@link SessionBoundSockets}).
14
18
  */
15
19
  export declare class CliLogSocketManager {
16
20
  private _wss;
17
21
  private readonly _clients;
18
22
  private _nextClientId;
23
+ private _auth?;
24
+ private _allowedOrigins?;
25
+ private readonly _trustProxy;
26
+ private readonly _sessionBound;
27
+ constructor(options?: {
28
+ allowedOrigins?: string[];
29
+ trustProxy?: boolean | number;
30
+ });
31
+ /** Installs the auth provider; when it protects the server, upgrades need a ticket and `logs:read`. */
32
+ setAuth(auth: ICliServerAuth | undefined): void;
33
+ setAllowedOrigins(origins: string[] | undefined): void;
19
34
  private static readonly LOG_PATHS;
20
35
  /**
21
36
  * Check whether a log at `logLevel` passes the `filterLevel` gate.
@@ -45,6 +60,7 @@ export declare class CliLogSocketManager {
45
60
  * Return information about all currently connected log clients.
46
61
  */
47
62
  getClients(): CliLogWebSocketClientInfo[];
63
+ /** Terminates all connections and closes the WebSocket server. */
48
64
  dispose(): void;
49
65
  private _handleConnection;
50
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cli-log-socket-manager.d.ts","sourceRoot":"","sources":["../../../src/services/cli-log-socket-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,MAAM,CAAC;AAGpD,MAAM,WAAW,yBAAyB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CAChB;AAsCD;;;;;GAKG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,aAAa,CAAK;IAE1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAG9B;IAEH;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAY3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAUzF;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAgB5B;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAsB5E;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB1C;;OAEG;IACH,UAAU,IAAI,yBAAyB,EAAE;IAgBzC,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,iBAAiB;CAsB5B"}
1
+ {"version":3,"file":"cli-log-socket-manager.d.ts","sourceRoot":"","sources":["../../../src/services/cli-log-socket-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAmB,MAAM,MAAM,CAAC;AAGpD,OAAO,EAA8C,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAMrG,oEAAoE;AACpE,MAAM,WAAW,yBAAyB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CAChB;AAsCD;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;gBAE/C,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAO;IAKtF,uGAAuG;IACvG,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI;IAK/C,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI;IAItD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAG9B;IAEH;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAY3E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAUzF;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAmC5B;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAsB5E;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB1C;;OAEG;IACH,UAAU,IAAI,yBAAyB,EAAE;IAgBzC,kEAAkE;IAClE,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,iBAAiB;CAwB5B"}