@qodalis/cli-server-node 1.0.0-beta.5 → 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.
- package/README.md +175 -19
- package/dist/src/auth/cli-server-auth-gate.d.ts +31 -0
- package/dist/src/auth/cli-server-auth-gate.d.ts.map +1 -0
- package/dist/src/auth/cli-server-auth-gate.js +118 -0
- package/dist/src/auth/cli-server-auth-gate.js.map +1 -0
- package/dist/src/auth/cli-server-auth.d.ts +147 -0
- package/dist/src/auth/cli-server-auth.d.ts.map +1 -0
- package/dist/src/auth/cli-server-auth.js +143 -0
- package/dist/src/auth/cli-server-auth.js.map +1 -0
- package/dist/src/auth/index.d.ts +4 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/index.js +19 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/ws-upgrade-auth.d.ts +30 -0
- package/dist/src/auth/ws-upgrade-auth.d.ts.map +1 -0
- package/dist/src/auth/ws-upgrade-auth.js +49 -0
- package/dist/src/auth/ws-upgrade-auth.js.map +1 -0
- package/dist/src/controllers/cli-controller.d.ts +2 -1
- package/dist/src/controllers/cli-controller.d.ts.map +1 -1
- package/dist/src/controllers/cli-controller.js +7 -2
- package/dist/src/controllers/cli-controller.js.map +1 -1
- package/dist/src/controllers/cli-version-controller.d.ts +12 -1
- package/dist/src/controllers/cli-version-controller.d.ts.map +1 -1
- package/dist/src/controllers/cli-version-controller.js +7 -2
- package/dist/src/controllers/cli-version-controller.js.map +1 -1
- package/dist/src/create-cli-server.d.ts +45 -1
- package/dist/src/create-cli-server.d.ts.map +1 -1
- package/dist/src/create-cli-server.js +71 -10
- package/dist/src/create-cli-server.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +15 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/server.js +12 -0
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/cli-event-socket-manager.d.ts +37 -1
- package/dist/src/services/cli-event-socket-manager.d.ts.map +1 -1
- package/dist/src/services/cli-event-socket-manager.js +126 -28
- package/dist/src/services/cli-event-socket-manager.js.map +1 -1
- package/dist/src/services/cli-log-socket-manager.d.ts +15 -1
- package/dist/src/services/cli-log-socket-manager.d.ts.map +1 -1
- package/dist/src/services/cli-log-socket-manager.js +53 -13
- package/dist/src/services/cli-log-socket-manager.js.map +1 -1
- package/dist/src/services/cli-shell-options.d.ts +107 -0
- package/dist/src/services/cli-shell-options.d.ts.map +1 -0
- package/dist/src/services/cli-shell-options.js +139 -0
- package/dist/src/services/cli-shell-options.js.map +1 -0
- package/dist/src/services/cli-shell-session-manager.d.ts +83 -10
- package/dist/src/services/cli-shell-session-manager.d.ts.map +1 -1
- package/dist/src/services/cli-shell-session-manager.js +474 -85
- package/dist/src/services/cli-shell-session-manager.js.map +1 -1
- package/dist/src/services/index.d.ts +2 -1
- package/dist/src/services/index.d.ts.map +1 -1
- package/dist/src/services/index.js +5 -1
- package/dist/src/services/index.js.map +1 -1
- package/dist/src/services/process-tree.d.ts +38 -0
- package/dist/src/services/process-tree.d.ts.map +1 -0
- package/dist/src/services/process-tree.js +249 -0
- package/dist/src/services/process-tree.js.map +1 -0
- package/dist/src/services/session-bound-sockets.d.ts +45 -0
- package/dist/src/services/session-bound-sockets.d.ts.map +1 -0
- package/dist/src/services/session-bound-sockets.js +129 -0
- package/dist/src/services/session-bound-sockets.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-cli-server.js","sourceRoot":"","sources":["../../src/create-cli-server.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"create-cli-server.js","sourceRoot":"","sources":["../../src/create-cli-server.ts"],"names":[],"mappings":";;;;;AA6GA,0CA6HC;AA1OD,sDAAmD;AACnD,gDAAwB;AACxB,yCAAuH;AACvH,6CAA0C;AAC1C,iEAAmE;AACnE,iFAAkF;AAClF,+EAA6E;AAC7E,wFAA8E;AAC9E,8FAA8G;AAC9G,2CAA8C;AAC9C,4DAAyG;AACzG,sEAAkF;AAwBlF,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,QAAQ,CAAC,CAAC;AA0EtC,SAAgB,eAAe,CAAC,UAA4B,EAAE;IAC1D,MAAM,EAAE,QAAQ,GAAG,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,GAAG,KAAK,EAAE,KAAK,EAAE,UAAU,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACxI,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IACtB,MAAM,SAAS,GAAG,IAAA,kCAAgB,EAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAChB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,GAAE,CAAC,CAAC;IACpB,CAAC;SAAM,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACtD,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,EAAC,UAAU,CAAC,CAAC,CAAC;IAC9B,CAAC;SAAM,IAAI,UAAU,KAAK,SAAS,IAAI,cAAc,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjF,8EAA8E;QAC9E,GAAG,CAAC,GAAG,CACH,IAAA,cAAI,EAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;YACnB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;YAClC,QAAQ,CAAC,IAAI,EAAE;gBACX,MAAM,EAAE,IAAA,iCAAe,EAAC,MAAM,EAAE,cAAc,CAAC,IAAI,IAAA,8BAAY,EAAC,MAAM,EAAE,GAAsB,CAAC;aAClG,CAAC,CAAC;QACP,CAAC,CAAC,CACL,CAAC;IACN,CAAC;IAED,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACxC,8EAA8E;IAC9E,GAAG,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,IAAqB,EAAE,GAAqB,EAAE,IAA0B,EAAE,EAAE;QAC3F,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,qBAAqB,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,CAAC,EAAE,CAAC;YACjF,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC3D,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC;YACpG,OAAO;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,6BAAkB,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,uBAAU,CAAC,QAAQ,CAAC,CAAC;IAEzC,oEAAoE;IACpE,IAAI,UAAsC,CAAC;IAC3C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,GAAG,CAAC,GAAG,CACH,IAAA,2CAAoB,EAAC,GAAG,EAAE,CAAC,UAAU,EAAE;QACnC,QAAQ;QACR,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,IAAA,oCAAa,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC3E,YAAY;KACf,CAAC,CACL,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACZ,SAAS,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,oCAAyB,CAAC,QAAQ,CAAC,CAAC;IAEzD,MAAM,kBAAkB,GAAG,IAAI,gCAAqB,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;IACzG,MAAM,gBAAgB,GAAG,IAAI,8BAAmB,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;IACjF,MAAM,iBAAiB,GAAG,GAAsB,EAAE;QAC9C,MAAM,IAAI,GAAG,kBAAkB,CAAC,aAAa,CAAC;QAC9C,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACtE,CAAC,CAAC;IAEF,6BAA6B;IAC7B,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,IAAA,mDAA0B,EAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;IAExE,gBAAgB;IAChB,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,IAAA,oCAAmB,EAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;IAExF,6DAA6D;IAC7D,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAC9B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAA,oCAAmB,EAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,kCAAkC;IAClC,IAAI,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC7C,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC3C,8EAA8E;QAC9E,UAAU,GAAG,IAAI,oDAAqB,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACb,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,IAAA,8CAAsB,EAAC,UAAU,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,oBAAoB;IACpB,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC9C,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,UAAU,GAAG,IAAI,sDAAoB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAChE,GAAG,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAA,8DAA4B,EAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IACrG,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAEjF,MAAM,OAAO,GAAG,CAAC,IAAgC,EAAE,EAAE;QACjD,UAAU,GAAG,IAAI,CAAC;QAClB,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,EAAE,cAAc,EAAE,CAAC;YACnB,cAAc;YACd,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,GAAG,CAAC;SAC/D,CAAC,CAAC;IACP,CAAC,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,WAAW,GAAG,CAAC,MAAuB,EAAE,EAAE;QAC5C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACpD,YAAY,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAA,oCAAa,EAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;YACxD,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YACnD,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAC5G,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { ICliCommandAuthor, CliCommandAuthor, DefaultLibraryAuthor, CliProcessCommand, ICliCommandParameterDescriptor, CliCommandParameterDescriptor, ICliCommandProcessor, CliCommandProcessor, ICliModule, CliModule, ICliProcessorFilter, } from './abstractions';
|
|
2
2
|
export { CliServerOutput, CliServerResponse, CliServerCommandDescriptor, CliServerCommandParameterDescriptorDto, } from './models';
|
|
3
|
-
export { ICliCommandRegistry, CliCommandRegistry, ICliResponseBuilder, CliResponseBuilder, ICliCommandExecutorService, CliCommandExecutorService, CliEventSocketManager, CliShellSessionManager, CliLogSocketManager, } from './services';
|
|
3
|
+
export { ICliCommandRegistry, CliCommandRegistry, ICliResponseBuilder, CliResponseBuilder, ICliCommandExecutorService, CliCommandExecutorService, CliEventSocketManager, CliShellSessionManager, CliShellSessionInfo, CliLogSocketManager, CliShellOptions, CliShellEnvOptions, CliShellAuthMode, CliShellAuthorizeContext, ShellCloseCodes, } from './services';
|
|
4
|
+
export { CliServerAuthContext, CliServerAuthError, CliServerAuditEntry, CliServerSessionEvent, ICliServerAuth, CliServerPermissions, isOriginAllowed, isSameOrigin, requestOrigin, clientAddress, trustedProxyHops, createServerAuthGate, ServerAuthGateOptions, requiredServerPermissions, authorizeWsUpgrade, rejectUpgrade, } from './auth';
|
|
4
5
|
export { createCliController } from './controllers/cli-controller';
|
|
5
6
|
export { createCliVersionController } from './controllers/cli-version-controller';
|
|
6
7
|
export { createFilesystemRouter } from './controllers/filesystem-controller';
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,8BAA8B,EAC9B,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,mBAAmB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACH,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,sCAAsC,GACzC,MAAM,UAAU,CAAC;AAGlB,OAAO,EACH,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,8BAA8B,EAC9B,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,mBAAmB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACH,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,sCAAsC,GACzC,MAAM,UAAU,CAAC;AAGlB,OAAO,EACH,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,EAClB,aAAa,GAChB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAG7E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EACH,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,0BAA0B,EAC1B,MAAM,EACN,QAAQ,EACR,aAAa,EACb,uBAAuB,GAC1B,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAG1E,OAAO,EACH,oBAAoB,EACpB,SAAS,EACT,QAAQ,EACR,2BAA2B,EAC3B,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GACpB,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAG9G,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAGhH,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAGpG,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAGtF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.CliHttpCommandProcessor = exports.CliSystemCommandProcessor = exports.CliStatusCommandProcessor = exports.CliEchoCommandProcessor = exports.S3FileStorageProvider = exports.SqliteFileStorageProvider = exports.JsonFileStorageProvider = exports.IsADirectoryError = exports.NotADirectoryError = exports.FileExistsError = exports.PermissionDeniedError = exports.FileNotFoundError = exports.FileSystemModule = exports.OsFileStorageProvider = exports.InMemoryFileStorageProvider = exports.FileSystemPathValidator = exports.createCliJobsController = exports.parseInterval = exports.JobError = exports.InMemoryJobStorageProvider = exports.CliJobLogger = exports.CliJobExecutionContext = exports.CliJobScheduler = exports.CliJobsBuilder = exports.CliBuilder = exports.createFilesystemRouter = exports.createCliVersionController = exports.createCliController = exports.rejectUpgrade = exports.authorizeWsUpgrade = exports.requiredServerPermissions = exports.createServerAuthGate = exports.trustedProxyHops = exports.clientAddress = exports.requestOrigin = exports.isSameOrigin = exports.isOriginAllowed = exports.CliServerPermissions = exports.ShellCloseCodes = exports.CliLogSocketManager = exports.CliShellSessionManager = exports.CliEventSocketManager = exports.CliCommandExecutorService = exports.CliResponseBuilder = exports.CliCommandRegistry = exports.CliModule = exports.CliCommandProcessor = exports.CliCommandParameterDescriptor = exports.DefaultLibraryAuthor = exports.CliCommandAuthor = void 0;
|
|
4
|
+
exports.createCliServer = exports.createLogger = exports.CliBase64CommandProcessor = exports.CliHashCommandProcessor = void 0;
|
|
4
5
|
// Abstractions
|
|
5
6
|
var abstractions_1 = require("./abstractions");
|
|
6
7
|
Object.defineProperty(exports, "CliCommandAuthor", { enumerable: true, get: function () { return abstractions_1.CliCommandAuthor; } });
|
|
@@ -16,6 +17,19 @@ Object.defineProperty(exports, "CliCommandExecutorService", { enumerable: true,
|
|
|
16
17
|
Object.defineProperty(exports, "CliEventSocketManager", { enumerable: true, get: function () { return services_1.CliEventSocketManager; } });
|
|
17
18
|
Object.defineProperty(exports, "CliShellSessionManager", { enumerable: true, get: function () { return services_1.CliShellSessionManager; } });
|
|
18
19
|
Object.defineProperty(exports, "CliLogSocketManager", { enumerable: true, get: function () { return services_1.CliLogSocketManager; } });
|
|
20
|
+
Object.defineProperty(exports, "ShellCloseCodes", { enumerable: true, get: function () { return services_1.ShellCloseCodes; } });
|
|
21
|
+
// Server auth (implemented by the users plugin)
|
|
22
|
+
var auth_1 = require("./auth");
|
|
23
|
+
Object.defineProperty(exports, "CliServerPermissions", { enumerable: true, get: function () { return auth_1.CliServerPermissions; } });
|
|
24
|
+
Object.defineProperty(exports, "isOriginAllowed", { enumerable: true, get: function () { return auth_1.isOriginAllowed; } });
|
|
25
|
+
Object.defineProperty(exports, "isSameOrigin", { enumerable: true, get: function () { return auth_1.isSameOrigin; } });
|
|
26
|
+
Object.defineProperty(exports, "requestOrigin", { enumerable: true, get: function () { return auth_1.requestOrigin; } });
|
|
27
|
+
Object.defineProperty(exports, "clientAddress", { enumerable: true, get: function () { return auth_1.clientAddress; } });
|
|
28
|
+
Object.defineProperty(exports, "trustedProxyHops", { enumerable: true, get: function () { return auth_1.trustedProxyHops; } });
|
|
29
|
+
Object.defineProperty(exports, "createServerAuthGate", { enumerable: true, get: function () { return auth_1.createServerAuthGate; } });
|
|
30
|
+
Object.defineProperty(exports, "requiredServerPermissions", { enumerable: true, get: function () { return auth_1.requiredServerPermissions; } });
|
|
31
|
+
Object.defineProperty(exports, "authorizeWsUpgrade", { enumerable: true, get: function () { return auth_1.authorizeWsUpgrade; } });
|
|
32
|
+
Object.defineProperty(exports, "rejectUpgrade", { enumerable: true, get: function () { return auth_1.rejectUpgrade; } });
|
|
19
33
|
// Controllers
|
|
20
34
|
var cli_controller_1 = require("./controllers/cli-controller");
|
|
21
35
|
Object.defineProperty(exports, "createCliController", { enumerable: true, get: function () { return cli_controller_1.createCliController; } });
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAAA,eAAe;AACf,+CAYwB;AAVpB,gHAAA,gBAAgB,OAAA;AAChB,oHAAA,oBAAoB,OAAA;AAGpB,6HAAA,6BAA6B,OAAA;AAE7B,mHAAA,mBAAmB,OAAA;AAEnB,yGAAA,SAAS,OAAA;AAYb,WAAW;AACX,uCAgBoB;AAdhB,8GAAA,kBAAkB,OAAA;AAElB,8GAAA,kBAAkB,OAAA;AAElB,qHAAA,yBAAyB,OAAA;AACzB,iHAAA,qBAAqB,OAAA;AACrB,kHAAA,sBAAsB,OAAA;AAEtB,+GAAA,mBAAmB,OAAA;AAKnB,2GAAA,eAAe,OAAA;AAGnB,gDAAgD;AAChD,+BAiBgB;AAXZ,4GAAA,oBAAoB,OAAA;AACpB,uGAAA,eAAe,OAAA;AACf,oGAAA,YAAY,OAAA;AACZ,qGAAA,aAAa,OAAA;AACb,qGAAA,aAAa,OAAA;AACb,wGAAA,gBAAgB,OAAA;AAChB,4GAAA,oBAAoB,OAAA;AAEpB,iHAAA,yBAAyB,OAAA;AACzB,0GAAA,kBAAkB,OAAA;AAClB,qGAAA,aAAa,OAAA;AAGjB,cAAc;AACd,+DAAmE;AAA1D,qHAAA,mBAAmB,OAAA;AAC5B,+EAAkF;AAAzE,oIAAA,0BAA0B,OAAA;AACnC,6EAA6E;AAApE,+HAAA,sBAAsB,OAAA;AAE/B,aAAa;AACb,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AAEnB,qDAAqD;AACrD,0EAUyC;AATrC,wHAAA,cAAc,OAAA;AACd,yHAAA,eAAe,OAAA;AACf,gIAAA,sBAAsB,OAAA;AACtB,sHAAA,YAAY,OAAA;AACZ,oIAAA,0BAA0B,OAAA;AAE1B,kHAAA,QAAQ,OAAA;AACR,uHAAA,aAAa,OAAA;AACb,iIAAA,uBAAuB,OAAA;AAG3B,sBAAsB;AACtB,2CAA0E;AAA9C,qHAAA,uBAAuB,OAAA;AAEnD,oBAAoB;AACpB,sFAa+C;AAT3C,2IAAA,2BAA2B,OAAA;AAC3B,qIAAA,qBAAqB,OAAA;AAErB,gIAAA,gBAAgB,OAAA;AAChB,iIAAA,iBAAiB,OAAA;AACjB,qIAAA,qBAAqB,OAAA;AACrB,+HAAA,eAAe,OAAA;AACf,kIAAA,kBAAkB,OAAA;AAClB,iIAAA,iBAAiB,OAAA;AAGrB,2BAA2B;AAC3B,gGAA8G;AAArG,4IAAA,uBAAuB,OAAA;AAEhC,6BAA6B;AAC7B,oGAAgH;AAAvG,gJAAA,yBAAyB,OAAA;AAElC,yBAAyB;AACzB,4FAAoG;AAA3F,wIAAA,qBAAqB,OAAA;AAE9B,aAAa;AACb,sFAAkF;AAAzE,qIAAA,uBAAuB,OAAA;AAChC,0FAAsF;AAA7E,yIAAA,yBAAyB,OAAA;AAClC,0FAAsF;AAA7E,yIAAA,yBAAyB,OAAA;AAClC,sFAAkF;AAAzE,qIAAA,uBAAuB,OAAA;AAChC,sFAAkF;AAAzE,qIAAA,uBAAuB,OAAA;AAChC,0FAAsF;AAA7E,yIAAA,yBAAyB,OAAA;AAElC,YAAY;AACZ,yCAAsD;AAArC,sGAAA,YAAY,OAAA;AAE7B,iBAAiB;AACjB,yDAA0G;AAAjG,oHAAA,eAAe,OAAA"}
|
package/dist/src/server.js
CHANGED
|
@@ -12,7 +12,16 @@ const cli_hash_command_processor_1 = require("./processors/cli-hash-command-proc
|
|
|
12
12
|
const cli_base64_command_processor_1 = require("./processors/cli-base64-command-processor");
|
|
13
13
|
const cli_server_plugin_weather_1 = require("@qodalis/cli-server-plugin-weather");
|
|
14
14
|
const port = process.env.PORT ?? 8047;
|
|
15
|
+
// CORS / WebSocket origins, e.g. QCLI_ALLOWED_ORIGINS=http://localhost:4200,http://localhost:4300
|
|
16
|
+
const allowedOrigins = process.env.QCLI_ALLOWED_ORIGINS?.split(',').map((o) => o.trim()).filter(Boolean);
|
|
17
|
+
// Remote shell (no users plugin here): set QCLI_SHELL_TOKEN to enable it in
|
|
18
|
+
// token mode. Clients send `Authorization: Bearer <token>` (browser clients:
|
|
19
|
+
// the server's configured `headers`, forwarded as `_header_Authorization`).
|
|
20
|
+
const shellToken = process.env.QCLI_SHELL_TOKEN?.trim() || undefined;
|
|
15
21
|
const { app, eventSocketManager } = (0, create_cli_server_1.createCliServer)({
|
|
22
|
+
allowedOrigins,
|
|
23
|
+
enableShell: !!shellToken,
|
|
24
|
+
shell: shellToken ? { token: shellToken } : undefined,
|
|
16
25
|
configure: (builder) => {
|
|
17
26
|
builder
|
|
18
27
|
.addProcessor(new cli_echo_command_processor_1.CliEchoCommandProcessor())
|
|
@@ -30,6 +39,9 @@ const server = app.listen(port, () => {
|
|
|
30
39
|
logger.info(` Execute: http://localhost:${port}/api/v1/qcli/execute`);
|
|
31
40
|
logger.info(` Capabilities: http://localhost:${port}/api/v1/qcli/capabilities`);
|
|
32
41
|
logger.info(` Events: ws://localhost:${port}/ws/v1/qcli/events`);
|
|
42
|
+
if (shellToken) {
|
|
43
|
+
logger.info(` Shell: ws://localhost:${port}/ws/v1/qcli/shell (token mode)`);
|
|
44
|
+
}
|
|
33
45
|
});
|
|
34
46
|
eventSocketManager.attach(server);
|
|
35
47
|
process.on('SIGINT', async () => {
|
package/dist/src/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";;;AAEA,2DAAsD;AACtD,2CAA8C;AAE9C,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,QAAQ,CAAC,CAAC;AACtC,wFAAkF;AAClF,4FAAsF;AACtF,4FAAsF;AACtF,wFAAkF;AAClF,wFAAkF;AAClF,4FAAsF;AACtF,kFAAmE;AAEnE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;AAEtC,MAAM,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,IAAA,mCAAe,EAAC;IAChD,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;QACnB,OAAO;aACF,YAAY,CAAC,IAAI,oDAAuB,EAAE,CAAC;aAC3C,YAAY,CAAC,IAAI,wDAAyB,EAAE,CAAC;aAC7C,YAAY,CAAC,IAAI,wDAAyB,EAAE,CAAC;aAC7C,YAAY,CAAC,IAAI,oDAAuB,EAAE,CAAC;aAC3C,YAAY,CAAC,IAAI,oDAAuB,EAAE,CAAC;aAC3C,YAAY,CAAC,IAAI,wDAAyB,EAAE,CAAC;aAC7C,SAAS,CAAC,IAAI,yCAAa,EAAE,CAAC,CAAC;IACxC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACjC,MAAM,CAAC,IAAI,CAAC,sDAAsD,IAAI,EAAE,CAAC,CAAC;IAC1E,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,uBAAuB,CAAC,CAAC;IAC7E,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,sBAAsB,CAAC,CAAC;IAC5E,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,2BAA2B,CAAC,CAAC;IACjF,MAAM,CAAC,IAAI,CAAC,kCAAkC,IAAI,oBAAoB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";;;AAEA,2DAAsD;AACtD,2CAA8C;AAE9C,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,QAAQ,CAAC,CAAC;AACtC,wFAAkF;AAClF,4FAAsF;AACtF,4FAAsF;AACtF,wFAAkF;AAClF,wFAAkF;AAClF,4FAAsF;AACtF,kFAAmE;AAEnE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;AAEtC,kGAAkG;AAClG,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAEzG,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AAErE,MAAM,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,IAAA,mCAAe,EAAC;IAChD,cAAc;IACd,WAAW,EAAE,CAAC,CAAC,UAAU;IACzB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS;IACrD,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;QACnB,OAAO;aACF,YAAY,CAAC,IAAI,oDAAuB,EAAE,CAAC;aAC3C,YAAY,CAAC,IAAI,wDAAyB,EAAE,CAAC;aAC7C,YAAY,CAAC,IAAI,wDAAyB,EAAE,CAAC;aAC7C,YAAY,CAAC,IAAI,oDAAuB,EAAE,CAAC;aAC3C,YAAY,CAAC,IAAI,oDAAuB,EAAE,CAAC;aAC3C,YAAY,CAAC,IAAI,wDAAyB,EAAE,CAAC;aAC7C,SAAS,CAAC,IAAI,yCAAa,EAAE,CAAC,CAAC;IACxC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACjC,MAAM,CAAC,IAAI,CAAC,sDAAsD,IAAI,EAAE,CAAC,CAAC;IAC1E,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,uBAAuB,CAAC,CAAC;IAC7E,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,sBAAsB,CAAC,CAAC;IAC5E,MAAM,CAAC,IAAI,CAAC,oCAAoC,IAAI,2BAA2B,CAAC,CAAC;IACjF,MAAM,CAAC,IAAI,CAAC,kCAAkC,IAAI,oBAAoB,CAAC,CAAC;IACxE,IAAI,UAAU,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,kCAAkC,IAAI,gCAAgC,CAAC,CAAC;IACxF,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAElC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC5B,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAChC,MAAM,kBAAkB,CAAC,mBAAmB,EAAE,CAAC;IAC/C,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC7B,MAAM,kBAAkB,CAAC,mBAAmB,EAAE,CAAC;IAC/C,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
|
|
@@ -1,4 +1,7 @@
|
|
|
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';
|
|
2
5
|
/** Information about a connected WebSocket event client. */
|
|
3
6
|
export interface CliWebSocketClientInfo {
|
|
4
7
|
id: string;
|
|
@@ -6,9 +9,28 @@ export interface CliWebSocketClientInfo {
|
|
|
6
9
|
remoteAddress: string;
|
|
7
10
|
type: 'events';
|
|
8
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
|
+
}
|
|
9
25
|
/**
|
|
10
26
|
* Manages WebSocket connections for server-push events and interactive shell sessions.
|
|
11
|
-
* Handles upgrades on `/ws/v1/qcli/events` and
|
|
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}.
|
|
12
34
|
*/
|
|
13
35
|
export declare class CliEventSocketManager {
|
|
14
36
|
private _wss;
|
|
@@ -16,6 +38,20 @@ export declare class CliEventSocketManager {
|
|
|
16
38
|
private readonly _clientMeta;
|
|
17
39
|
private readonly _shellManager;
|
|
18
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;
|
|
19
55
|
private static readonly EVENT_PATHS;
|
|
20
56
|
private static readonly SHELL_PATHS;
|
|
21
57
|
/**
|
|
@@ -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;
|
|
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"}
|
|
@@ -5,17 +5,64 @@ 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
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");
|
|
8
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']);
|
|
9
14
|
/**
|
|
10
15
|
* Manages WebSocket connections for server-push events and interactive shell sessions.
|
|
11
|
-
* Handles upgrades on `/ws/v1/qcli/events` and
|
|
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}.
|
|
12
23
|
*/
|
|
13
24
|
class CliEventSocketManager {
|
|
14
25
|
_wss = null;
|
|
15
26
|
_clients = new Set();
|
|
16
27
|
_clientMeta = new Map();
|
|
17
|
-
_shellManager
|
|
28
|
+
_shellManager;
|
|
18
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
|
+
}
|
|
19
66
|
static EVENT_PATHS = new Set([
|
|
20
67
|
'/ws/v1/qcli/events',
|
|
21
68
|
'/ws/qcli/events',
|
|
@@ -30,56 +77,73 @@ class CliEventSocketManager {
|
|
|
30
77
|
*/
|
|
31
78
|
attach(server) {
|
|
32
79
|
this._wss = new ws_1.WebSocketServer({ noServer: true });
|
|
80
|
+
this._shellManager.logStartupState();
|
|
33
81
|
server.on('upgrade', (request, socket, head) => {
|
|
34
|
-
|
|
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
|
+
}
|
|
35
89
|
const pathname = parsed.pathname;
|
|
36
90
|
if (CliEventSocketManager.EVENT_PATHS.has(pathname)) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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));
|
|
40
100
|
return;
|
|
41
101
|
}
|
|
42
102
|
if (CliEventSocketManager.SHELL_PATHS.has(pathname)) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
+
});
|
|
55
120
|
});
|
|
56
121
|
});
|
|
57
122
|
return;
|
|
58
123
|
}
|
|
59
124
|
// Unrecognized path; leave for other upgrade handlers
|
|
60
125
|
});
|
|
61
|
-
this._wss.on('connection', (ws, request) => {
|
|
126
|
+
this._wss.on('connection', (ws, request, auth) => {
|
|
62
127
|
this._clients.add(ws);
|
|
63
128
|
const id = `evt-${this._nextClientId++}`;
|
|
64
129
|
this._clientMeta.set(ws, {
|
|
65
130
|
id,
|
|
66
131
|
connectedAt: new Date(),
|
|
67
132
|
remoteAddress: request.socket.remoteAddress ?? 'unknown',
|
|
133
|
+
auth,
|
|
68
134
|
});
|
|
135
|
+
this._sessionBound.bind(ws, auth);
|
|
69
136
|
logger.info('Client connected (id=%s)', id);
|
|
70
137
|
ws.send(JSON.stringify({ type: 'connected' }));
|
|
71
|
-
|
|
72
|
-
const meta = this._clientMeta.get(ws);
|
|
73
|
-
logger.info('Client disconnected (id=%s)', meta?.id ?? 'unknown');
|
|
74
|
-
this._clients.delete(ws);
|
|
75
|
-
this._clientMeta.delete(ws);
|
|
76
|
-
});
|
|
77
|
-
ws.on('error', () => {
|
|
138
|
+
const disconnected = () => {
|
|
78
139
|
const meta = this._clientMeta.get(ws);
|
|
79
140
|
logger.info('Client disconnected (id=%s)', meta?.id ?? 'unknown');
|
|
141
|
+
this._sessionBound.unbind(ws);
|
|
80
142
|
this._clients.delete(ws);
|
|
81
143
|
this._clientMeta.delete(ws);
|
|
82
|
-
}
|
|
144
|
+
};
|
|
145
|
+
ws.on('close', disconnected);
|
|
146
|
+
ws.on('error', disconnected);
|
|
83
147
|
});
|
|
84
148
|
}
|
|
85
149
|
/**
|
|
@@ -87,10 +151,40 @@ class CliEventSocketManager {
|
|
|
87
151
|
*/
|
|
88
152
|
broadcastMessage(message) {
|
|
89
153
|
const data = JSON.stringify(message);
|
|
154
|
+
const type = typeof message.type === 'string' ? message.type : '';
|
|
155
|
+
const payload = (message.data ?? {});
|
|
156
|
+
const toClose = [];
|
|
90
157
|
for (const ws of this._clients) {
|
|
91
|
-
if (ws.readyState
|
|
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;
|
|
92
165
|
ws.send(data);
|
|
166
|
+
if (type === 'session-kicked' && auth.sessionId && auth.sessionId === payload.sessionId) {
|
|
167
|
+
toClose.push(ws);
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
93
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);
|
|
94
188
|
}
|
|
95
189
|
}
|
|
96
190
|
/**
|
|
@@ -111,6 +205,8 @@ class CliEventSocketManager {
|
|
|
111
205
|
}
|
|
112
206
|
}
|
|
113
207
|
await Promise.all(promises);
|
|
208
|
+
this._shellManager.dispose();
|
|
209
|
+
this._sessionBound.dispose();
|
|
114
210
|
this._clients.clear();
|
|
115
211
|
this._clientMeta.clear();
|
|
116
212
|
}
|
|
@@ -136,6 +232,8 @@ class CliEventSocketManager {
|
|
|
136
232
|
}
|
|
137
233
|
/** Terminates all connections and closes the WebSocket server. */
|
|
138
234
|
dispose() {
|
|
235
|
+
this._shellManager.dispose();
|
|
236
|
+
this._sessionBound.dispose();
|
|
139
237
|
for (const ws of this._clients) {
|
|
140
238
|
ws.terminate();
|
|
141
239
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-event-socket-manager.js","sourceRoot":"","sources":["../../../src/services/cli-event-socket-manager.ts"],"names":[],"mappings":";;;AAAA,2BAAgD;AAEhD,6BAA0B;AAC1B,2EAAqE;
|
|
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,5 @@
|
|
|
1
1
|
import type { Server } from 'http';
|
|
2
|
+
import { ICliServerAuth } from '../auth/cli-server-auth';
|
|
2
3
|
/** Information about a connected WebSocket log-streaming client. */
|
|
3
4
|
export interface CliLogWebSocketClientInfo {
|
|
4
5
|
id: string;
|
|
@@ -11,12 +12,25 @@ export interface CliLogWebSocketClientInfo {
|
|
|
11
12
|
* Manages WebSocket connections for streaming log messages to clients.
|
|
12
13
|
*
|
|
13
14
|
* Parity with CliLogSocketManager in the .NET and Python servers.
|
|
14
|
-
* 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}).
|
|
15
18
|
*/
|
|
16
19
|
export declare class CliLogSocketManager {
|
|
17
20
|
private _wss;
|
|
18
21
|
private readonly _clients;
|
|
19
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;
|
|
20
34
|
private static readonly LOG_PATHS;
|
|
21
35
|
/**
|
|
22
36
|
* Check whether a log at `logLevel` passes the `filterLevel` gate.
|
|
@@ -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;
|
|
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"}
|
|
@@ -4,6 +4,9 @@ exports.CliLogSocketManager = void 0;
|
|
|
4
4
|
const ws_1 = require("ws");
|
|
5
5
|
const url_1 = require("url");
|
|
6
6
|
const logger_1 = require("../utils/logger");
|
|
7
|
+
const cli_server_auth_1 = require("../auth/cli-server-auth");
|
|
8
|
+
const ws_upgrade_auth_1 = require("../auth/ws-upgrade-auth");
|
|
9
|
+
const session_bound_sockets_1 = require("./session-bound-sockets");
|
|
7
10
|
const logger = (0, logger_1.createLogger)('LogSocket');
|
|
8
11
|
/**
|
|
9
12
|
* Level ordering from lowest to highest severity.
|
|
@@ -34,12 +37,30 @@ function normalizeLevel(level) {
|
|
|
34
37
|
* Manages WebSocket connections for streaming log messages to clients.
|
|
35
38
|
*
|
|
36
39
|
* Parity with CliLogSocketManager in the .NET and Python servers.
|
|
37
|
-
* Handles `/ws/v1/qcli/logs` and `/ws/qcli/logs` upgrade paths.
|
|
40
|
+
* Handles `/ws/v1/qcli/logs` and `/ws/qcli/logs` upgrade paths. Sockets
|
|
41
|
+
* authenticated with a stored session are bound to it: once it ends they are
|
|
42
|
+
* closed with 4401 `session ended` (see {@link SessionBoundSockets}).
|
|
38
43
|
*/
|
|
39
44
|
class CliLogSocketManager {
|
|
40
45
|
_wss = null;
|
|
41
46
|
_clients = new Map();
|
|
42
47
|
_nextClientId = 1;
|
|
48
|
+
_auth;
|
|
49
|
+
_allowedOrigins;
|
|
50
|
+
_trustProxy;
|
|
51
|
+
_sessionBound = new session_bound_sockets_1.SessionBoundSockets();
|
|
52
|
+
constructor(options = {}) {
|
|
53
|
+
this._allowedOrigins = options.allowedOrigins;
|
|
54
|
+
this._trustProxy = options.trustProxy ?? false;
|
|
55
|
+
}
|
|
56
|
+
/** Installs the auth provider; when it protects the server, upgrades need a ticket and `logs:read`. */
|
|
57
|
+
setAuth(auth) {
|
|
58
|
+
this._auth = auth;
|
|
59
|
+
this._sessionBound.setAuth(auth);
|
|
60
|
+
}
|
|
61
|
+
setAllowedOrigins(origins) {
|
|
62
|
+
this._allowedOrigins = origins;
|
|
63
|
+
}
|
|
43
64
|
static LOG_PATHS = new Set([
|
|
44
65
|
'/ws/v1/qcli/logs',
|
|
45
66
|
'/ws/qcli/logs',
|
|
@@ -79,14 +100,31 @@ class CliLogSocketManager {
|
|
|
79
100
|
attach(server) {
|
|
80
101
|
this._wss = new ws_1.WebSocketServer({ noServer: true });
|
|
81
102
|
server.on('upgrade', (request, socket, head) => {
|
|
82
|
-
|
|
103
|
+
let parsed;
|
|
104
|
+
try {
|
|
105
|
+
parsed = new url_1.URL(request.url ?? '', 'http://localhost');
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return; // malformed request target: not one of our paths
|
|
109
|
+
}
|
|
83
110
|
const pathname = parsed.pathname;
|
|
84
111
|
if (!CliLogSocketManager.LOG_PATHS.has(pathname))
|
|
85
112
|
return;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.
|
|
89
|
-
|
|
113
|
+
(0, ws_upgrade_auth_1.authorizeWsUpgrade)(request, parsed, {
|
|
114
|
+
auth: this._auth,
|
|
115
|
+
allowedOrigins: this._allowedOrigins,
|
|
116
|
+
trustProxy: this._trustProxy,
|
|
117
|
+
permission: cli_server_auth_1.CliServerPermissions.LogsRead,
|
|
118
|
+
}).then((result) => {
|
|
119
|
+
if (!result.ok) {
|
|
120
|
+
(0, ws_upgrade_auth_1.rejectUpgrade)(socket, result.status);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this._wss.handleUpgrade(request, socket, head, (ws) => {
|
|
124
|
+
const levelFilter = parsed.searchParams.get('level') || null;
|
|
125
|
+
this._handleConnection(ws, request, levelFilter, result.ctx);
|
|
126
|
+
});
|
|
127
|
+
}, () => (0, ws_upgrade_auth_1.rejectUpgrade)(socket, 401));
|
|
90
128
|
});
|
|
91
129
|
}
|
|
92
130
|
/**
|
|
@@ -131,6 +169,7 @@ class CliLogSocketManager {
|
|
|
131
169
|
}
|
|
132
170
|
}
|
|
133
171
|
await Promise.all(promises);
|
|
172
|
+
this._sessionBound.dispose();
|
|
134
173
|
this._clients.clear();
|
|
135
174
|
}
|
|
136
175
|
/**
|
|
@@ -153,13 +192,14 @@ class CliLogSocketManager {
|
|
|
153
192
|
}
|
|
154
193
|
/** Terminates all connections and closes the WebSocket server. */
|
|
155
194
|
dispose() {
|
|
195
|
+
this._sessionBound.dispose();
|
|
156
196
|
for (const entry of this._clients.values()) {
|
|
157
197
|
entry.ws.terminate();
|
|
158
198
|
}
|
|
159
199
|
this._clients.clear();
|
|
160
200
|
this._wss?.close();
|
|
161
201
|
}
|
|
162
|
-
_handleConnection(ws, request, levelFilter) {
|
|
202
|
+
_handleConnection(ws, request, levelFilter, auth) {
|
|
163
203
|
const id = `log-${this._nextClientId++}`;
|
|
164
204
|
const entry = {
|
|
165
205
|
id,
|
|
@@ -169,16 +209,16 @@ class CliLogSocketManager {
|
|
|
169
209
|
levelFilter,
|
|
170
210
|
};
|
|
171
211
|
this._clients.set(id, entry);
|
|
212
|
+
this._sessionBound.bind(ws, auth);
|
|
172
213
|
ws.send(JSON.stringify({ type: 'connected' }));
|
|
173
214
|
logger.info('Log client connected (id=%s, level=%s)', id, levelFilter ?? 'all');
|
|
174
|
-
|
|
175
|
-
logger.info('Log client disconnected (id=%s)', id);
|
|
176
|
-
this._clients.delete(id);
|
|
177
|
-
});
|
|
178
|
-
ws.on('error', () => {
|
|
215
|
+
const disconnected = () => {
|
|
179
216
|
logger.info('Log client disconnected (id=%s)', id);
|
|
217
|
+
this._sessionBound.unbind(ws);
|
|
180
218
|
this._clients.delete(id);
|
|
181
|
-
}
|
|
219
|
+
};
|
|
220
|
+
ws.on('close', disconnected);
|
|
221
|
+
ws.on('error', disconnected);
|
|
182
222
|
}
|
|
183
223
|
}
|
|
184
224
|
exports.CliLogSocketManager = CliLogSocketManager;
|