onbuzz 4.9.13 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/glob/README.md +31 -5
- package/node_modules/glob/dist/commonjs/glob.d.ts +8 -0
- package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/glob.js +2 -1
- package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
- package/node_modules/glob/dist/commonjs/index.min.js +3 -3
- package/node_modules/glob/dist/commonjs/index.min.js.map +4 -4
- package/node_modules/glob/dist/commonjs/pattern.d.ts +3 -0
- package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/pattern.js +4 -0
- package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
- package/node_modules/glob/dist/esm/glob.d.ts +8 -0
- package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/glob.js +2 -1
- package/node_modules/glob/dist/esm/glob.js.map +1 -1
- package/node_modules/glob/dist/esm/index.min.js +3 -3
- package/node_modules/glob/dist/esm/index.min.js.map +4 -4
- package/node_modules/glob/dist/esm/pattern.d.ts +3 -0
- package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/pattern.js +4 -0
- package/node_modules/glob/dist/esm/pattern.js.map +1 -1
- package/node_modules/{@isaacs → glob/node_modules}/balanced-match/README.md +7 -10
- package/node_modules/{@isaacs → glob/node_modules}/balanced-match/package.json +7 -18
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/README.md +3 -6
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.js +6 -4
- package/node_modules/glob/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -0
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.js +6 -4
- package/node_modules/glob/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/package.json +11 -7
- package/node_modules/glob/node_modules/minimatch/README.md +76 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts +4 -2
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js +309 -55
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js +2 -4
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js +4 -4
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts +81 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js +232 -134
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js +8 -8
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts +4 -2
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js +309 -55
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js +2 -4
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js +4 -4
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts +81 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.js +232 -134
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js +8 -8
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/package.json +17 -11
- package/node_modules/glob/package.json +10 -13
- package/node_modules/minipass/LICENSE.md +55 -0
- package/node_modules/minipass/dist/commonjs/index.d.ts +12 -16
- package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/minipass/dist/commonjs/index.js +13 -3
- package/node_modules/minipass/dist/commonjs/index.js.map +1 -1
- package/node_modules/minipass/dist/esm/index.d.ts +12 -16
- package/node_modules/minipass/dist/esm/index.d.ts.map +1 -1
- package/node_modules/minipass/dist/esm/index.js +3 -1
- package/node_modules/minipass/dist/esm/index.js.map +1 -1
- package/node_modules/minipass/package.json +9 -14
- package/node_modules/path-scurry/node_modules/lru-cache/README.md +96 -10
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts +109 -32
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +334 -197
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js.map +4 -4
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts +109 -32
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +333 -196
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js.map +4 -4
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/package.json +71 -18
- package/node_modules/path-scurry/package.json +8 -24
- package/package.json +1 -1
- package/scripts/debug-balance-probe.mjs +35 -35
- package/scripts/push-image.sh +43 -43
- package/scripts/setup-acr.sh +65 -65
- package/scripts/verify-optional-deps.js +96 -1
- package/src/__tests__/composioCliFlags.test.js +239 -239
- package/src/analyzers/CSSAnalyzer.js +298 -297
- package/src/analyzers/ConfigValidator.js +691 -690
- package/src/analyzers/ESLintAnalyzer.js +320 -320
- package/src/analyzers/JavaScriptAnalyzer.js +260 -261
- package/src/analyzers/PrettierFormatter.js +246 -247
- package/src/analyzers/PythonAnalyzer.js +283 -283
- package/src/analyzers/SecurityAnalyzer.js +729 -729
- package/src/analyzers/SparrowAnalyzer.js +341 -341
- package/src/analyzers/TypeScriptAnalyzer.js +247 -247
- package/src/analyzers/__tests__/CSSAnalyzer.test.js +41 -41
- package/src/analyzers/__tests__/ConfigValidator.test.js +362 -362
- package/src/analyzers/__tests__/JavaScriptAnalyzer.test.js +40 -40
- package/src/analyzers/__tests__/PythonAnalyzer.test.js +205 -208
- package/src/analyzers/__tests__/SecurityAnalyzer.test.js +303 -303
- package/src/analyzers/__tests__/TypeScriptAnalyzer.test.js +187 -187
- package/src/analyzers/codeCloneDetector/analyzer.js +344 -344
- package/src/analyzers/codeCloneDetector/detector.js +250 -250
- package/src/analyzers/codeCloneDetector/index.js +194 -192
- package/src/analyzers/codeCloneDetector/parser.js +199 -199
- package/src/core/__tests__/agentPool.test.js +866 -866
- package/src/core/__tests__/agentPoolAutoResume.test.js +209 -209
- package/src/core/__tests__/agentPoolWakeOnMessage.test.js +315 -315
- package/src/core/__tests__/agentScheduler.emptyResponseChatStall.test.js +213 -213
- package/src/core/__tests__/agentScheduler.errorCategorisation.test.js +246 -246
- package/src/core/__tests__/agentScheduler.firstChunkTimeout.test.js +138 -138
- package/src/core/__tests__/agentScheduler.modeTransitions.test.js +233 -233
- package/src/core/__tests__/agentScheduler.nativePromptPick.test.js +319 -319
- package/src/core/__tests__/agentScheduler.taskLifecycleInstruction.test.js +78 -78
- package/src/core/__tests__/agentScheduler.visualizer.test.js +258 -258
- package/src/core/__tests__/flowCheckpointStore.test.js +140 -140
- package/src/core/__tests__/flowEndToEnd.test.js +565 -565
- package/src/core/__tests__/flowFieldMapping.test.js +188 -189
- package/src/core/__tests__/flowLintClientMirror.test.js +96 -98
- package/src/core/__tests__/flowSavePayload.test.js +170 -169
- package/src/core/__tests__/flowTemplates.test.js +311 -311
- package/src/core/__tests__/flowVersionStore.test.js +123 -123
- package/src/core/__tests__/messageProcessor.test.js +669 -669
- package/src/core/__tests__/stateManager.test.js +0 -1
- package/src/core/agentPool.js +2474 -2475
- package/src/core/agentScheduler.js +1 -4
- package/src/core/contextManager.js +708 -708
- package/src/core/flowExecutor.js +1510 -1510
- package/src/core/flowFieldMapping.js +136 -138
- package/src/core/messageProcessor.js +953 -954
- package/src/core/orchestrator.js +593 -595
- package/src/core/stateManager.js +1765 -1752
- package/src/index.js +1221 -1221
- package/src/interfaces/__tests__/archivedAgentDelete.test.js +207 -207
- package/src/interfaces/__tests__/bulkAgentRoute.test.js +361 -361
- package/src/interfaces/__tests__/imageServing.test.js +228 -228
- package/src/interfaces/__tests__/remoteSessionAuth.test.js +308 -308
- package/src/interfaces/__tests__/videoJobsRoutes.test.js +178 -179
- package/src/interfaces/__tests__/webServer.marketplace.test.js +629 -629
- package/src/interfaces/schedulerRoutes.js +50 -50
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +341 -350
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +156 -156
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +325 -330
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +385 -388
- package/src/interfaces/terminal/api/session.js +265 -266
- package/src/interfaces/terminal/api/websocket.js +496 -497
- package/src/interfaces/terminal/components/AgentCreator.js +691 -705
- package/src/interfaces/terminal/components/AgentEditor.js +676 -678
- package/src/interfaces/terminal/components/AgentSwitcher.js +331 -330
- package/src/interfaces/terminal/components/ErrorPanel.js +263 -264
- package/src/interfaces/terminal/components/Header.js +28 -28
- package/src/interfaces/terminal/components/Layout.js +598 -603
- package/src/interfaces/terminal/components/MessageList.js +280 -281
- package/src/interfaces/terminal/components/SettingsPanel.js +410 -415
- package/src/interfaces/terminal/components/StatusBar.js +2 -0
- package/src/interfaces/terminal/index.js +168 -168
- package/src/interfaces/terminal/state/useAgentControl.js +496 -496
- package/src/interfaces/terminal/state/useAgents.js +537 -537
- package/src/interfaces/terminal/state/useMessages.js +629 -630
- package/src/interfaces/terminal/state/useTools.js +554 -554
- package/src/interfaces/terminal/utils/debugLogger.js +44 -44
- package/src/interfaces/terminal/utils/settingsStorage.js +232 -232
- package/src/interfaces/webServer.js +7578 -7579
- package/src/interfaces/webServer.js.bak +7046 -7046
- package/src/modules/fileExplorer/__tests__/zipDownload.test.js +237 -237
- package/src/modules/fileExplorer/controller.js +470 -469
- package/src/modules/fileExplorer/routes.js +285 -286
- package/src/modules/widget/__tests__/isDisabled.test.js +41 -41
- package/src/modules/widget/__tests__/routes.test.js +677 -678
- package/src/modules/widget/__tests__/runtime.test.js +401 -401
- package/src/modules/widget/__tests__/versioning.test.js +309 -309
- package/src/modules/widget/__tests__/webComponentRuntime.test.js +565 -565
- package/src/modules/widget/__tests__/widgetTool.test.js +316 -316
- package/src/modules/widget/routes.js +435 -435
- package/src/modules/widget/runtime/bundle.js +640 -640
- package/src/modules/widget/runtime/webComponentBundle.js +470 -470
- package/src/modules/widget/schema.js +182 -181
- package/src/modules/widget/widgetTool.js +1389 -1389
- package/src/services/__tests__/agentActivityService.test.js +401 -402
- package/src/services/__tests__/benchmarkService.test.js +184 -184
- package/src/services/__tests__/contextInjectionService.test.js +246 -246
- package/src/services/__tests__/conversationQuery.test.js +721 -723
- package/src/services/__tests__/credentialVault.test.js +469 -469
- package/src/services/__tests__/discordService.integration.test.js +638 -639
- package/src/services/__tests__/flowContextService.test.js +590 -590
- package/src/services/__tests__/memoryService.test.js +1 -1
- package/src/services/__tests__/messageSource.test.js +380 -380
- package/src/services/__tests__/modelRouterNaming.test.js +111 -111
- package/src/services/__tests__/projectDetector.test.js +34 -34
- package/src/services/__tests__/promptService.test.js +242 -242
- package/src/services/__tests__/telegramService.test.js +941 -941
- package/src/services/__tests__/tokenCountingService.test.js +48 -48
- package/src/services/agentActivityService.js +419 -420
- package/src/services/aiService.js +2997 -3001
- package/src/services/apiKeyManager.js +359 -359
- package/src/services/benchmarkService.js +196 -196
- package/src/services/codebaseKnowledgeService.js +2 -2
- package/src/services/composioService.js +738 -738
- package/src/services/conversationCompactionService.js +1258 -1257
- package/src/services/credentialVault.js +685 -685
- package/src/services/discordService.js +792 -793
- package/src/services/embeddings/__tests__/azureCustomProvider.test.js +232 -232
- package/src/services/embeddings/__tests__/embeddingService.test.js +417 -417
- package/src/services/embeddings/__tests__/localProvider.test.js +263 -263
- package/src/services/embeddings/autoRecall.js +218 -219
- package/src/services/embeddings/indexers/__tests__/agentIndexer.test.js +232 -232
- package/src/services/embeddings/indexers/__tests__/memoryIndexer.test.js +418 -418
- package/src/services/embeddings/indexers/__tests__/reminisceIndexer.test.js +356 -357
- package/src/services/embeddings/indexers/__tests__/skillsIndexer.test.js +145 -145
- package/src/services/embeddings/indexers/__tests__/taskIndexer.test.js +146 -146
- package/src/services/embeddings/indexers/composioIndexer.js +279 -279
- package/src/services/embeddings/providerInterface.js +206 -206
- package/src/services/embeddings/providers/localProvider.js +11 -7
- package/src/services/embeddings/providers/openaiProvider.js +101 -101
- package/src/services/embeddings/vectorStore/inMemoryJsonStore.js +356 -356
- package/src/services/errorHandler.js +809 -809
- package/src/services/flowContextService.js +586 -586
- package/src/services/grounding/MockAdapter.js +125 -125
- package/src/services/modelRouterService.js +26 -31
- package/src/services/modelsService.js +322 -322
- package/src/services/ollamaService.js +452 -452
- package/src/services/projectDetector.js +403 -404
- package/src/services/promptService.js +418 -418
- package/src/services/qualityInspector.js +795 -795
- package/src/services/scheduleService.js +726 -726
- package/src/services/serviceRegistry.js +386 -386
- package/src/services/telegrafBot.js +174 -174
- package/src/services/telegramService.js +1972 -1972
- package/src/services/visualEditorBridge.js +1033 -1033
- package/src/services/visualEditorServer.js +1769 -1774
- package/src/services/whatsappService.js +667 -668
- package/src/tools/__tests__/agentCommunicationTool.findAgent.test.js +226 -226
- package/src/tools/__tests__/agentCommunicationTool.test.js +3 -3
- package/src/tools/__tests__/agentDelayTool.test.js +342 -342
- package/src/tools/__tests__/baseTool.test.js +3 -3
- package/src/tools/__tests__/codeMapTool.test.js +915 -915
- package/src/tools/__tests__/fileContentReplaceTool.test.js +309 -309
- package/src/tools/__tests__/fileTreeTool.test.js +274 -274
- package/src/tools/__tests__/filesystemTool.test.js +815 -815
- package/src/tools/__tests__/foundryWebSearchTool.test.js +252 -252
- package/src/tools/__tests__/imageTool.validator.test.js +194 -194
- package/src/tools/__tests__/jobDoneTool.test.js +580 -581
- package/src/tools/__tests__/memoryTool.forgetStale.test.js +272 -272
- package/src/tools/__tests__/memoryTool.reminisce.test.js +2 -2
- package/src/tools/__tests__/memoryTool.reminisceSemanticSearch.test.js +301 -301
- package/src/tools/__tests__/memoryTool.semanticSearch.test.js +405 -405
- package/src/tools/__tests__/memoryTool.teamPool.test.js +293 -293
- package/src/tools/__tests__/memoryTool.test.js +1 -1
- package/src/tools/__tests__/seekTool.test.js +282 -282
- package/src/tools/__tests__/skillsTool.search.test.js +164 -164
- package/src/tools/__tests__/skillsTool.test.js +226 -226
- package/src/tools/__tests__/staticAnalysisTool.test.js +509 -509
- package/src/tools/__tests__/taskManagerTool.discipline.test.js +137 -137
- package/src/tools/__tests__/taskManagerTool.search.test.js +143 -143
- package/src/tools/__tests__/taskManagerTool.test.js +866 -866
- package/src/tools/__tests__/terminalTool.test.js +448 -448
- package/src/tools/__tests__/toolShapeForgiveness.test.js +259 -260
- package/src/tools/__tests__/userPromptTool.test.js +297 -297
- package/src/tools/__tests__/videoTool.jobs.test.js +147 -147
- package/src/tools/__tests__/webTool.e2e.test.js +609 -603
- package/src/tools/__tests__/webTool.unit.test.js +195 -195
- package/src/tools/__tests__/webTool.visionModel.test.js +75 -75
- package/src/tools/agentCommunicationTool.js +8 -10
- package/src/tools/agentDelayTool.js +496 -497
- package/src/tools/asyncToolManager.js +602 -603
- package/src/tools/baseTool.js +12 -11
- package/src/tools/cloneDetectionTool.js +576 -581
- package/src/tools/codeMapTool.js +0 -6
- package/src/tools/composioTool.js +617 -617
- package/src/tools/dependencyResolverTool.js +1211 -1212
- package/src/tools/desktop/DesktopTool.js +629 -638
- package/src/tools/desktop/__tests__/DesktopTool.e2e.test.js +306 -306
- package/src/tools/desktop/__tests__/DesktopTool.test.js +507 -507
- package/src/tools/desktop/__tests__/osController.test.js +364 -364
- package/src/tools/desktop/osController.js +491 -491
- package/src/tools/docxTool.js +623 -623
- package/src/tools/excelTool.js +636 -636
- package/src/tools/fileContentReplaceTool.js +5 -7
- package/src/tools/fileSystemTool.js +12 -19
- package/src/tools/fileTreeTool.js +840 -840
- package/src/tools/foundryWebSearchTool.js +273 -273
- package/src/tools/helpTool.js +198 -198
- package/src/tools/imageTool.js +1397 -1397
- package/src/tools/importAnalyzerTool.js +1056 -1056
- package/src/tools/jobDoneTool.js +495 -495
- package/src/tools/memoryTool.js +1 -1
- package/src/tools/office/pres/__tests__/presSystem.test.js +365 -365
- package/src/tools/office/pres/archetypes/agenda.js +61 -61
- package/src/tools/office/pres/archetypes/bentoGrid.js +218 -219
- package/src/tools/office/pres/archetypes/bigStat.js +140 -142
- package/src/tools/office/pres/archetypes/closing.js +70 -70
- package/src/tools/office/pres/archetypes/hero.js +70 -70
- package/src/tools/office/pres/archetypes/productHero.js +93 -94
- package/src/tools/office/pres/archetypes/table.js +73 -74
- package/src/tools/office/pres/backgrounds/orb.js +66 -66
- package/src/tools/office/pres/components.js +422 -423
- package/src/tools/officeTool.js +441 -441
- package/src/tools/pdfTool.js +625 -627
- package/src/tools/platformControlTool.js +1081 -1081
- package/src/tools/seekTool.js +917 -918
- package/src/tools/skillsTool.js +1 -1
- package/src/tools/staticAnalysisTool.js +2143 -2146
- package/src/tools/taskManagerTool.js +3324 -3324
- package/src/tools/terminalTool.js +2615 -2618
- package/src/tools/videoTool.js +1303 -1303
- package/src/tools/visionTool.js +508 -508
- package/src/tools/visualEditorTool.js +1289 -1290
- package/src/tools/webTool.js +3368 -3368
- package/src/tools/whatsappTool.js +464 -464
- package/src/types/__tests__/agent.test.js +499 -499
- package/src/types/__tests__/contextReference.test.js +606 -606
- package/src/types/__tests__/conversation.test.js +555 -555
- package/src/types/__tests__/toolCommand.test.js +584 -584
- package/src/types/contextReference.js +974 -971
- package/src/types/conversation.js +729 -729
- package/src/types/toolCommand.js +746 -746
- package/src/utilities/__tests__/attachmentValidator.test.js +80 -80
- package/src/utilities/__tests__/auditReport.test.js +328 -328
- package/src/utilities/__tests__/directoryAccessManager.test.js +388 -388
- package/src/utilities/__tests__/jsonRepair.test.js +103 -104
- package/src/utilities/__tests__/modeTransitionReasons.test.js +105 -105
- package/src/utilities/__tests__/platformUtils.test.js +80 -87
- package/src/utilities/__tests__/structuredFileValidator.test.js +261 -263
- package/src/utilities/__tests__/toolConstants.test.js +92 -94
- package/src/utilities/__tests__/useIsTouchDevice.detect.test.js +114 -114
- package/src/utilities/__tests__/webUiUtilSync.test.js +117 -117
- package/src/utilities/attachmentValidator.js +284 -288
- package/src/utilities/authCache.js.backup-1779570472481 +121 -121
- package/src/utilities/browserStealth.js +631 -630
- package/src/utilities/configManager.js +616 -617
- package/src/utilities/directoryAccessManager.js +564 -565
- package/src/utilities/fileProcessor.js +308 -307
- package/src/utilities/humanBehavior.js +454 -453
- package/src/utilities/logger.js +479 -479
- package/src/utilities/structuredFileValidator.js +696 -699
- package/src/utilities/tagParser.js +5 -10
- package/src/utilities/userDataDir.js +308 -308
- package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js.map +0 -1
- package/node_modules/@isaacs/brace-expansion/dist/esm/index.js.map +0 -1
- package/node_modules/minipass/LICENSE +0 -15
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/LICENSE.md +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/LICENSE +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/package.json +0 -0
|
@@ -1,308 +1,308 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for the Remote Session Auth Gate middleware in webServer.js.
|
|
3
|
-
*
|
|
4
|
-
* When LOXIA_REMOTE_SESSION=true, every request (except /api/health and /health)
|
|
5
|
-
* must carry a valid session token — either as a cookie or as a ?session_token= query param.
|
|
6
|
-
*
|
|
7
|
-
* Covers:
|
|
8
|
-
* - /api/health is always public (bypasses auth gate)
|
|
9
|
-
* - ?session_token= in URL sets cookie and redirects (strips token from URL)
|
|
10
|
-
* - Valid loxia_session cookie allows access
|
|
11
|
-
* - Missing/invalid token returns 401 JSON for /api/ paths
|
|
12
|
-
* - Missing/invalid token returns 401 HTML for non-API paths
|
|
13
|
-
* - Wrong token is rejected
|
|
14
|
-
* - API key auto-configuration from LOXIA_API_KEY env var
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { describe, it, expect,
|
|
18
|
-
import express from 'express';
|
|
19
|
-
import { createServer } from 'http';
|
|
20
|
-
|
|
21
|
-
const VALID_TOKEN = 'test-session-token-abc123';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Build a minimal Express app that replicates the remote session auth gate
|
|
25
|
-
* from webServer.js, plus a few test routes behind it.
|
|
26
|
-
*/
|
|
27
|
-
function buildRemoteSessionApp(sessionToken) {
|
|
28
|
-
const app = express();
|
|
29
|
-
app.use(express.json());
|
|
30
|
-
|
|
31
|
-
// ── Replicate the auth gate from webServer.js ──────────────────
|
|
32
|
-
app.use((req, res, next) => {
|
|
33
|
-
// Health endpoint is public
|
|
34
|
-
if (req.path === '/api/health' || req.path === '/health') return next();
|
|
35
|
-
|
|
36
|
-
// Static assets are public (CSS, JS, images, fonts)
|
|
37
|
-
if (req.path.startsWith('/static/') || req.path.endsWith('.svg') || req.path.endsWith('.png') || req.path.endsWith('.ico') || req.path.endsWith('.woff2')) return next();
|
|
38
|
-
|
|
39
|
-
// Parse cookies manually
|
|
40
|
-
const cookies = {};
|
|
41
|
-
(req.headers.cookie || '').split(';').forEach(c => {
|
|
42
|
-
const [k, ...v] = c.trim().split('=');
|
|
43
|
-
if (k) cookies[k] = v.join('=');
|
|
44
|
-
});
|
|
45
|
-
const tokenFromCookie = cookies.loxia_session;
|
|
46
|
-
const tokenFromQuery = req.query?.session_token;
|
|
47
|
-
|
|
48
|
-
if (tokenFromQuery === sessionToken) {
|
|
49
|
-
// Set cookie and redirect without token in URL
|
|
50
|
-
res.cookie('loxia_session', sessionToken, {
|
|
51
|
-
httpOnly: true,
|
|
52
|
-
sameSite: 'lax',
|
|
53
|
-
maxAge: 7200 * 1000,
|
|
54
|
-
path: '/'
|
|
55
|
-
});
|
|
56
|
-
const url = new URL(req.originalUrl, `http://${req.headers.host}`);
|
|
57
|
-
url.searchParams.delete('session_token');
|
|
58
|
-
return res.redirect(url.pathname + url.search);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (tokenFromCookie === sessionToken) {
|
|
62
|
-
return next();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Unauthorized
|
|
66
|
-
if (req.path.startsWith('/api/')) {
|
|
67
|
-
return res.status(401).json({ error: 'Session authentication required' });
|
|
68
|
-
}
|
|
69
|
-
return res.status(401).send('<html><body><h2>Session Expired</h2></body></html>');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// ── Test routes behind the gate ────────────────────────────────
|
|
73
|
-
app.get('/api/health', (req, res) => res.json({ status: 'healthy' }));
|
|
74
|
-
app.get('/health', (req, res) => res.json({ status: 'healthy' }));
|
|
75
|
-
app.get('/static/index-abc123.js', (req, res) => res.type('js').send('console.log("app")'));
|
|
76
|
-
app.get('/static/index-abc123.css', (req, res) => res.type('css').send('body{}'));
|
|
77
|
-
app.get('/loxia-icon.svg', (req, res) => res.type('svg').send('<svg></svg>'));
|
|
78
|
-
app.get('/favicon.ico', (req, res) => res.type('ico').send(''));
|
|
79
|
-
app.get('/api/test', (req, res) => res.json({ success: true, data: 'protected' }));
|
|
80
|
-
app.get('/', (req, res) => res.send('<html><body>Web UI</body></html>'));
|
|
81
|
-
app.get('/dashboard', (req, res) => res.send('<html><body>Dashboard</body></html>'));
|
|
82
|
-
|
|
83
|
-
return app;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async function startServer(app) {
|
|
87
|
-
const server = createServer(app);
|
|
88
|
-
await new Promise(resolve => server.listen(0, resolve));
|
|
89
|
-
return { server, baseUrl: `http://127.0.0.1:${server.address().port}` };
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
describe('Remote Session Auth Gate', () => {
|
|
93
|
-
let server;
|
|
94
|
-
|
|
95
|
-
afterEach(() => {
|
|
96
|
-
if (server) server.close();
|
|
97
|
-
server = null;
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// ── Health endpoints bypass ──────────────────────────────────────
|
|
101
|
-
describe('health endpoints (public)', () => {
|
|
102
|
-
it('/api/health is accessible without any token', async () => {
|
|
103
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
104
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
105
|
-
server = s;
|
|
106
|
-
|
|
107
|
-
const res = await fetch(`${baseUrl}/api/health`);
|
|
108
|
-
expect(res.status).toBe(200);
|
|
109
|
-
const body = await res.json();
|
|
110
|
-
expect(body.status).toBe('healthy');
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('/health is accessible without any token', async () => {
|
|
114
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
115
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
116
|
-
server = s;
|
|
117
|
-
|
|
118
|
-
const res = await fetch(`${baseUrl}/health`);
|
|
119
|
-
expect(res.status).toBe(200);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// ── Static assets bypass (public) ──────────────────────────────────
|
|
124
|
-
describe('static assets (public, no auth needed)', () => {
|
|
125
|
-
it('/static/*.js is accessible without any token', async () => {
|
|
126
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
127
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
128
|
-
server = s;
|
|
129
|
-
|
|
130
|
-
const res = await fetch(`${baseUrl}/static/index-abc123.js`);
|
|
131
|
-
expect(res.status).toBe(200);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('/static/*.css is accessible without any token', async () => {
|
|
135
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
136
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
137
|
-
server = s;
|
|
138
|
-
|
|
139
|
-
const res = await fetch(`${baseUrl}/static/index-abc123.css`);
|
|
140
|
-
expect(res.status).toBe(200);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('.svg files are accessible without any token', async () => {
|
|
144
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
145
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
146
|
-
server = s;
|
|
147
|
-
|
|
148
|
-
const res = await fetch(`${baseUrl}/loxia-icon.svg`);
|
|
149
|
-
expect(res.status).toBe(200);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('.ico files are accessible without any token', async () => {
|
|
153
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
154
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
155
|
-
server = s;
|
|
156
|
-
|
|
157
|
-
const res = await fetch(`${baseUrl}/favicon.ico`);
|
|
158
|
-
expect(res.status).toBe(200);
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// ── Token via query param (first access) ─────────────────────────
|
|
163
|
-
describe('?session_token= query param (first access)', () => {
|
|
164
|
-
it('valid token sets cookie and redirects (strips token from URL)', async () => {
|
|
165
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
166
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
167
|
-
server = s;
|
|
168
|
-
|
|
169
|
-
const res = await fetch(`${baseUrl}/?session_token=${VALID_TOKEN}`, { redirect: 'manual' });
|
|
170
|
-
expect(res.status).toBe(302);
|
|
171
|
-
|
|
172
|
-
// Check redirect strips the session_token param
|
|
173
|
-
const location = res.headers.get('location');
|
|
174
|
-
expect(location).toBe('/');
|
|
175
|
-
expect(location).not.toContain('session_token');
|
|
176
|
-
|
|
177
|
-
// Check Set-Cookie header
|
|
178
|
-
const setCookie = res.headers.get('set-cookie');
|
|
179
|
-
expect(setCookie).toContain('loxia_session=');
|
|
180
|
-
expect(setCookie).toContain(VALID_TOKEN);
|
|
181
|
-
expect(setCookie).toContain('HttpOnly');
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it('preserves other query params when stripping session_token', async () => {
|
|
185
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
186
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
187
|
-
server = s;
|
|
188
|
-
|
|
189
|
-
const res = await fetch(`${baseUrl}/dashboard?session_token=${VALID_TOKEN}&theme=dark`, { redirect: 'manual' });
|
|
190
|
-
expect(res.status).toBe(302);
|
|
191
|
-
const location = res.headers.get('location');
|
|
192
|
-
expect(location).toContain('theme=dark');
|
|
193
|
-
expect(location).not.toContain('session_token');
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it('wrong token in query param is rejected (not redirected)', async () => {
|
|
197
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
198
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
199
|
-
server = s;
|
|
200
|
-
|
|
201
|
-
const res = await fetch(`${baseUrl}/?session_token=wrong-token`, { redirect: 'manual' });
|
|
202
|
-
// Should NOT redirect — falls through to 401
|
|
203
|
-
expect(res.status).toBe(401);
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// ── Token via cookie (subsequent requests) ───────────────────────
|
|
208
|
-
describe('loxia_session cookie (subsequent requests)', () => {
|
|
209
|
-
it('valid cookie allows access to API endpoints', async () => {
|
|
210
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
211
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
212
|
-
server = s;
|
|
213
|
-
|
|
214
|
-
const res = await fetch(`${baseUrl}/api/test`, {
|
|
215
|
-
headers: { 'Cookie': `loxia_session=${VALID_TOKEN}` }
|
|
216
|
-
});
|
|
217
|
-
expect(res.status).toBe(200);
|
|
218
|
-
const body = await res.json();
|
|
219
|
-
expect(body.success).toBe(true);
|
|
220
|
-
expect(body.data).toBe('protected');
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
it('valid cookie allows access to HTML pages', async () => {
|
|
224
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
225
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
226
|
-
server = s;
|
|
227
|
-
|
|
228
|
-
const res = await fetch(`${baseUrl}/`, {
|
|
229
|
-
headers: { 'Cookie': `loxia_session=${VALID_TOKEN}` }
|
|
230
|
-
});
|
|
231
|
-
expect(res.status).toBe(200);
|
|
232
|
-
const text = await res.text();
|
|
233
|
-
expect(text).toContain('Web UI');
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it('wrong cookie value is rejected', async () => {
|
|
237
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
238
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
239
|
-
server = s;
|
|
240
|
-
|
|
241
|
-
const res = await fetch(`${baseUrl}/api/test`, {
|
|
242
|
-
headers: { 'Cookie': `loxia_session=wrong-value` }
|
|
243
|
-
});
|
|
244
|
-
expect(res.status).toBe(401);
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// ── No token at all ──────────────────────────────────────────────
|
|
249
|
-
describe('no token (unauthenticated)', () => {
|
|
250
|
-
it('API endpoints return 401 JSON', async () => {
|
|
251
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
252
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
253
|
-
server = s;
|
|
254
|
-
|
|
255
|
-
const res = await fetch(`${baseUrl}/api/test`);
|
|
256
|
-
expect(res.status).toBe(401);
|
|
257
|
-
const body = await res.json();
|
|
258
|
-
expect(body.error).toBe('Session authentication required');
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
it('HTML pages return 401 with Session Expired message', async () => {
|
|
262
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
263
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
264
|
-
server = s;
|
|
265
|
-
|
|
266
|
-
const res = await fetch(`${baseUrl}/dashboard`);
|
|
267
|
-
expect(res.status).toBe(401);
|
|
268
|
-
const text = await res.text();
|
|
269
|
-
expect(text).toContain('Session Expired');
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it('root path without token returns 401', async () => {
|
|
273
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
274
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
275
|
-
server = s;
|
|
276
|
-
|
|
277
|
-
const res = await fetch(`${baseUrl}/`);
|
|
278
|
-
expect(res.status).toBe(401);
|
|
279
|
-
});
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
// ── Cookie with multiple values ──────────────────────────────────
|
|
283
|
-
describe('cookie parsing edge cases', () => {
|
|
284
|
-
it('handles multiple cookies correctly (picks loxia_session)', async () => {
|
|
285
|
-
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
286
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
287
|
-
server = s;
|
|
288
|
-
|
|
289
|
-
const res = await fetch(`${baseUrl}/api/test`, {
|
|
290
|
-
headers: { 'Cookie': `other=foo; loxia_session=${VALID_TOKEN}; another=bar` }
|
|
291
|
-
});
|
|
292
|
-
expect(res.status).toBe(200);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
it('handles cookie with = in value', async () => {
|
|
296
|
-
// Token won't normally have = but test the parser handles it
|
|
297
|
-
const tokenWithEquals = 'abc=def=ghi';
|
|
298
|
-
const app = buildRemoteSessionApp(tokenWithEquals);
|
|
299
|
-
const { server: s, baseUrl } = await startServer(app);
|
|
300
|
-
server = s;
|
|
301
|
-
|
|
302
|
-
const res = await fetch(`${baseUrl}/api/test`, {
|
|
303
|
-
headers: { 'Cookie': `loxia_session=${tokenWithEquals}` }
|
|
304
|
-
});
|
|
305
|
-
expect(res.status).toBe(200);
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the Remote Session Auth Gate middleware in webServer.js.
|
|
3
|
+
*
|
|
4
|
+
* When LOXIA_REMOTE_SESSION=true, every request (except /api/health and /health)
|
|
5
|
+
* must carry a valid session token — either as a cookie or as a ?session_token= query param.
|
|
6
|
+
*
|
|
7
|
+
* Covers:
|
|
8
|
+
* - /api/health is always public (bypasses auth gate)
|
|
9
|
+
* - ?session_token= in URL sets cookie and redirects (strips token from URL)
|
|
10
|
+
* - Valid loxia_session cookie allows access
|
|
11
|
+
* - Missing/invalid token returns 401 JSON for /api/ paths
|
|
12
|
+
* - Missing/invalid token returns 401 HTML for non-API paths
|
|
13
|
+
* - Wrong token is rejected
|
|
14
|
+
* - API key auto-configuration from LOXIA_API_KEY env var
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { describe, it, expect, afterEach } from '@jest/globals';
|
|
18
|
+
import express from 'express';
|
|
19
|
+
import { createServer } from 'http';
|
|
20
|
+
|
|
21
|
+
const VALID_TOKEN = 'test-session-token-abc123';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Build a minimal Express app that replicates the remote session auth gate
|
|
25
|
+
* from webServer.js, plus a few test routes behind it.
|
|
26
|
+
*/
|
|
27
|
+
function buildRemoteSessionApp(sessionToken) {
|
|
28
|
+
const app = express();
|
|
29
|
+
app.use(express.json());
|
|
30
|
+
|
|
31
|
+
// ── Replicate the auth gate from webServer.js ──────────────────
|
|
32
|
+
app.use((req, res, next) => {
|
|
33
|
+
// Health endpoint is public
|
|
34
|
+
if (req.path === '/api/health' || req.path === '/health') return next();
|
|
35
|
+
|
|
36
|
+
// Static assets are public (CSS, JS, images, fonts)
|
|
37
|
+
if (req.path.startsWith('/static/') || req.path.endsWith('.svg') || req.path.endsWith('.png') || req.path.endsWith('.ico') || req.path.endsWith('.woff2')) return next();
|
|
38
|
+
|
|
39
|
+
// Parse cookies manually
|
|
40
|
+
const cookies = {};
|
|
41
|
+
(req.headers.cookie || '').split(';').forEach(c => {
|
|
42
|
+
const [k, ...v] = c.trim().split('=');
|
|
43
|
+
if (k) cookies[k] = v.join('=');
|
|
44
|
+
});
|
|
45
|
+
const tokenFromCookie = cookies.loxia_session;
|
|
46
|
+
const tokenFromQuery = req.query?.session_token;
|
|
47
|
+
|
|
48
|
+
if (tokenFromQuery === sessionToken) {
|
|
49
|
+
// Set cookie and redirect without token in URL
|
|
50
|
+
res.cookie('loxia_session', sessionToken, {
|
|
51
|
+
httpOnly: true,
|
|
52
|
+
sameSite: 'lax',
|
|
53
|
+
maxAge: 7200 * 1000,
|
|
54
|
+
path: '/'
|
|
55
|
+
});
|
|
56
|
+
const url = new URL(req.originalUrl, `http://${req.headers.host}`);
|
|
57
|
+
url.searchParams.delete('session_token');
|
|
58
|
+
return res.redirect(url.pathname + url.search);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (tokenFromCookie === sessionToken) {
|
|
62
|
+
return next();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Unauthorized
|
|
66
|
+
if (req.path.startsWith('/api/')) {
|
|
67
|
+
return res.status(401).json({ error: 'Session authentication required' });
|
|
68
|
+
}
|
|
69
|
+
return res.status(401).send('<html><body><h2>Session Expired</h2></body></html>');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// ── Test routes behind the gate ────────────────────────────────
|
|
73
|
+
app.get('/api/health', (req, res) => res.json({ status: 'healthy' }));
|
|
74
|
+
app.get('/health', (req, res) => res.json({ status: 'healthy' }));
|
|
75
|
+
app.get('/static/index-abc123.js', (req, res) => res.type('js').send('console.log("app")'));
|
|
76
|
+
app.get('/static/index-abc123.css', (req, res) => res.type('css').send('body{}'));
|
|
77
|
+
app.get('/loxia-icon.svg', (req, res) => res.type('svg').send('<svg></svg>'));
|
|
78
|
+
app.get('/favicon.ico', (req, res) => res.type('ico').send(''));
|
|
79
|
+
app.get('/api/test', (req, res) => res.json({ success: true, data: 'protected' }));
|
|
80
|
+
app.get('/', (req, res) => res.send('<html><body>Web UI</body></html>'));
|
|
81
|
+
app.get('/dashboard', (req, res) => res.send('<html><body>Dashboard</body></html>'));
|
|
82
|
+
|
|
83
|
+
return app;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function startServer(app) {
|
|
87
|
+
const server = createServer(app);
|
|
88
|
+
await new Promise(resolve => server.listen(0, resolve));
|
|
89
|
+
return { server, baseUrl: `http://127.0.0.1:${server.address().port}` };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
describe('Remote Session Auth Gate', () => {
|
|
93
|
+
let server;
|
|
94
|
+
|
|
95
|
+
afterEach(() => {
|
|
96
|
+
if (server) server.close();
|
|
97
|
+
server = null;
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// ── Health endpoints bypass ──────────────────────────────────────
|
|
101
|
+
describe('health endpoints (public)', () => {
|
|
102
|
+
it('/api/health is accessible without any token', async () => {
|
|
103
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
104
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
105
|
+
server = s;
|
|
106
|
+
|
|
107
|
+
const res = await fetch(`${baseUrl}/api/health`);
|
|
108
|
+
expect(res.status).toBe(200);
|
|
109
|
+
const body = await res.json();
|
|
110
|
+
expect(body.status).toBe('healthy');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('/health is accessible without any token', async () => {
|
|
114
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
115
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
116
|
+
server = s;
|
|
117
|
+
|
|
118
|
+
const res = await fetch(`${baseUrl}/health`);
|
|
119
|
+
expect(res.status).toBe(200);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// ── Static assets bypass (public) ──────────────────────────────────
|
|
124
|
+
describe('static assets (public, no auth needed)', () => {
|
|
125
|
+
it('/static/*.js is accessible without any token', async () => {
|
|
126
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
127
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
128
|
+
server = s;
|
|
129
|
+
|
|
130
|
+
const res = await fetch(`${baseUrl}/static/index-abc123.js`);
|
|
131
|
+
expect(res.status).toBe(200);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('/static/*.css is accessible without any token', async () => {
|
|
135
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
136
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
137
|
+
server = s;
|
|
138
|
+
|
|
139
|
+
const res = await fetch(`${baseUrl}/static/index-abc123.css`);
|
|
140
|
+
expect(res.status).toBe(200);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('.svg files are accessible without any token', async () => {
|
|
144
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
145
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
146
|
+
server = s;
|
|
147
|
+
|
|
148
|
+
const res = await fetch(`${baseUrl}/loxia-icon.svg`);
|
|
149
|
+
expect(res.status).toBe(200);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('.ico files are accessible without any token', async () => {
|
|
153
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
154
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
155
|
+
server = s;
|
|
156
|
+
|
|
157
|
+
const res = await fetch(`${baseUrl}/favicon.ico`);
|
|
158
|
+
expect(res.status).toBe(200);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// ── Token via query param (first access) ─────────────────────────
|
|
163
|
+
describe('?session_token= query param (first access)', () => {
|
|
164
|
+
it('valid token sets cookie and redirects (strips token from URL)', async () => {
|
|
165
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
166
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
167
|
+
server = s;
|
|
168
|
+
|
|
169
|
+
const res = await fetch(`${baseUrl}/?session_token=${VALID_TOKEN}`, { redirect: 'manual' });
|
|
170
|
+
expect(res.status).toBe(302);
|
|
171
|
+
|
|
172
|
+
// Check redirect strips the session_token param
|
|
173
|
+
const location = res.headers.get('location');
|
|
174
|
+
expect(location).toBe('/');
|
|
175
|
+
expect(location).not.toContain('session_token');
|
|
176
|
+
|
|
177
|
+
// Check Set-Cookie header
|
|
178
|
+
const setCookie = res.headers.get('set-cookie');
|
|
179
|
+
expect(setCookie).toContain('loxia_session=');
|
|
180
|
+
expect(setCookie).toContain(VALID_TOKEN);
|
|
181
|
+
expect(setCookie).toContain('HttpOnly');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('preserves other query params when stripping session_token', async () => {
|
|
185
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
186
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
187
|
+
server = s;
|
|
188
|
+
|
|
189
|
+
const res = await fetch(`${baseUrl}/dashboard?session_token=${VALID_TOKEN}&theme=dark`, { redirect: 'manual' });
|
|
190
|
+
expect(res.status).toBe(302);
|
|
191
|
+
const location = res.headers.get('location');
|
|
192
|
+
expect(location).toContain('theme=dark');
|
|
193
|
+
expect(location).not.toContain('session_token');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('wrong token in query param is rejected (not redirected)', async () => {
|
|
197
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
198
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
199
|
+
server = s;
|
|
200
|
+
|
|
201
|
+
const res = await fetch(`${baseUrl}/?session_token=wrong-token`, { redirect: 'manual' });
|
|
202
|
+
// Should NOT redirect — falls through to 401
|
|
203
|
+
expect(res.status).toBe(401);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// ── Token via cookie (subsequent requests) ───────────────────────
|
|
208
|
+
describe('loxia_session cookie (subsequent requests)', () => {
|
|
209
|
+
it('valid cookie allows access to API endpoints', async () => {
|
|
210
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
211
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
212
|
+
server = s;
|
|
213
|
+
|
|
214
|
+
const res = await fetch(`${baseUrl}/api/test`, {
|
|
215
|
+
headers: { 'Cookie': `loxia_session=${VALID_TOKEN}` }
|
|
216
|
+
});
|
|
217
|
+
expect(res.status).toBe(200);
|
|
218
|
+
const body = await res.json();
|
|
219
|
+
expect(body.success).toBe(true);
|
|
220
|
+
expect(body.data).toBe('protected');
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('valid cookie allows access to HTML pages', async () => {
|
|
224
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
225
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
226
|
+
server = s;
|
|
227
|
+
|
|
228
|
+
const res = await fetch(`${baseUrl}/`, {
|
|
229
|
+
headers: { 'Cookie': `loxia_session=${VALID_TOKEN}` }
|
|
230
|
+
});
|
|
231
|
+
expect(res.status).toBe(200);
|
|
232
|
+
const text = await res.text();
|
|
233
|
+
expect(text).toContain('Web UI');
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('wrong cookie value is rejected', async () => {
|
|
237
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
238
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
239
|
+
server = s;
|
|
240
|
+
|
|
241
|
+
const res = await fetch(`${baseUrl}/api/test`, {
|
|
242
|
+
headers: { 'Cookie': `loxia_session=wrong-value` }
|
|
243
|
+
});
|
|
244
|
+
expect(res.status).toBe(401);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// ── No token at all ──────────────────────────────────────────────
|
|
249
|
+
describe('no token (unauthenticated)', () => {
|
|
250
|
+
it('API endpoints return 401 JSON', async () => {
|
|
251
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
252
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
253
|
+
server = s;
|
|
254
|
+
|
|
255
|
+
const res = await fetch(`${baseUrl}/api/test`);
|
|
256
|
+
expect(res.status).toBe(401);
|
|
257
|
+
const body = await res.json();
|
|
258
|
+
expect(body.error).toBe('Session authentication required');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('HTML pages return 401 with Session Expired message', async () => {
|
|
262
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
263
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
264
|
+
server = s;
|
|
265
|
+
|
|
266
|
+
const res = await fetch(`${baseUrl}/dashboard`);
|
|
267
|
+
expect(res.status).toBe(401);
|
|
268
|
+
const text = await res.text();
|
|
269
|
+
expect(text).toContain('Session Expired');
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('root path without token returns 401', async () => {
|
|
273
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
274
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
275
|
+
server = s;
|
|
276
|
+
|
|
277
|
+
const res = await fetch(`${baseUrl}/`);
|
|
278
|
+
expect(res.status).toBe(401);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// ── Cookie with multiple values ──────────────────────────────────
|
|
283
|
+
describe('cookie parsing edge cases', () => {
|
|
284
|
+
it('handles multiple cookies correctly (picks loxia_session)', async () => {
|
|
285
|
+
const app = buildRemoteSessionApp(VALID_TOKEN);
|
|
286
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
287
|
+
server = s;
|
|
288
|
+
|
|
289
|
+
const res = await fetch(`${baseUrl}/api/test`, {
|
|
290
|
+
headers: { 'Cookie': `other=foo; loxia_session=${VALID_TOKEN}; another=bar` }
|
|
291
|
+
});
|
|
292
|
+
expect(res.status).toBe(200);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('handles cookie with = in value', async () => {
|
|
296
|
+
// Token won't normally have = but test the parser handles it
|
|
297
|
+
const tokenWithEquals = 'abc=def=ghi';
|
|
298
|
+
const app = buildRemoteSessionApp(tokenWithEquals);
|
|
299
|
+
const { server: s, baseUrl } = await startServer(app);
|
|
300
|
+
server = s;
|
|
301
|
+
|
|
302
|
+
const res = await fetch(`${baseUrl}/api/test`, {
|
|
303
|
+
headers: { 'Cookie': `loxia_session=${tokenWithEquals}` }
|
|
304
|
+
});
|
|
305
|
+
expect(res.status).toBe(200);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
});
|