@saluzi/saluzi-edu 0.2.9 → 0.2.11
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/dist/cli.js +336 -333
- package/dist/rcs-web/assets/Dashboard-BwotBWlJ.js +1 -0
- package/dist/rcs-web/assets/Join-4yrksbdX.js +1 -0
- package/dist/rcs-web/assets/Login-Cxm_yEeE.js +1 -0
- package/dist/rcs-web/assets/SessionDetail-DNdfPOYy.js +50 -0
- package/dist/rcs-web/assets/Setup-BiAAxugt.js +1 -0
- package/dist/rcs-web/assets/ShareLanding-CP3Z6ckr.js +1 -0
- package/dist/rcs-web/assets/TeamCreate-DgdCwRSb.js +1 -0
- package/dist/rcs-web/assets/TeamDetail-CkNTFoMB.js +11 -0
- package/dist/rcs-web/assets/TeamList-Bf0sQ5RQ.js +1 -0
- package/dist/rcs-web/assets/TeamSettings-BaNAfXU3.js +1 -0
- package/dist/rcs-web/assets/UserSettings-CsutQjxG.js +1 -0
- package/{packages/remote-control-server/web/dist/assets/arc-D90597o-.js → dist/rcs-web/assets/arc-BxxmNQO6.js} +1 -1
- package/dist/rcs-web/assets/architectureDiagram-3BPJPVTR-DBjkRdbd.js +36 -0
- package/dist/rcs-web/assets/{blockDiagram-GPEHLZMM-DHd8IbOs.js → blockDiagram-GPEHLZMM-BF6COWlM.js} +2 -2
- package/dist/rcs-web/assets/{c4Diagram-AAUBKEIU-CjFkQJ9h.js → c4Diagram-AAUBKEIU-DHOf390v.js} +2 -2
- package/dist/rcs-web/assets/channel-JsvbMQjW.js +1 -0
- package/dist/rcs-web/assets/{chunk-2J33WTMH-C21XWnGZ.js → chunk-2J33WTMH-CeJN8yjM.js} +1 -1
- package/dist/rcs-web/assets/{chunk-4BX2VUAB-B3SXiJlt.js → chunk-4BX2VUAB-jP76_P2A.js} +1 -1
- package/dist/rcs-web/assets/{chunk-55IACEB6-DjImv45F.js → chunk-55IACEB6-BsFA6emB.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-DtnaqsyD.js → dist/rcs-web/assets/chunk-727SXJPM-BF4HrQjZ.js} +1 -1
- package/dist/rcs-web/assets/{chunk-AQP2D5EJ-BVFgH5mS.js → chunk-AQP2D5EJ-DToJ74Kc.js} +1 -1
- package/dist/rcs-web/assets/{chunk-FMBD7UC4-Bl8jgb57.js → chunk-FMBD7UC4-DVTARgsa.js} +1 -1
- package/dist/rcs-web/assets/{chunk-ND2GUHAM-BpK111zh.js → chunk-ND2GUHAM-C50Gqv9c.js} +1 -1
- package/dist/rcs-web/assets/{chunk-QZHKN3VN-ruhIHBim.js → chunk-QZHKN3VN-EsIIh6zV.js} +1 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-BXn8Uc4c.js +1 -0
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-BXn8Uc4c.js +1 -0
- package/dist/rcs-web/assets/code-block-IT6T5CEO-BnufHNTT.js +2 -0
- package/dist/rcs-web/assets/cose-bilkent-S5V4N54A-M6tNt14I.js +1 -0
- package/dist/rcs-web/assets/dagre-BM42HDAG-DaTm29qG.js +4 -0
- package/dist/rcs-web/assets/diagram-2AECGRRQ-fqoeOvq2.js +43 -0
- package/dist/rcs-web/assets/diagram-5GNKFQAL-6s2CiaGG.js +10 -0
- package/dist/rcs-web/assets/{diagram-KO2AKTUF-Uy3PDP5S.js → diagram-KO2AKTUF-C0aw_N95.js} +2 -2
- package/dist/rcs-web/assets/diagram-LMA3HP47-C8_Rv3rB.js +24 -0
- package/dist/rcs-web/assets/diagram-OG6HWLK6-Dae4u8Uc.js +24 -0
- package/{packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-sre_MTeK.js → dist/rcs-web/assets/erDiagram-TEJ5UH35-CosS5VWr.js} +13 -13
- package/dist/rcs-web/assets/{flowDiagram-I6XJVG4X-DwrWaLoe.js → flowDiagram-I6XJVG4X-D_Mxs46-.js} +2 -2
- package/dist/rcs-web/assets/ganttDiagram-6RSMTGT7-B0jy8Am_.js +292 -0
- package/dist/rcs-web/assets/gitGraphDiagram-PVQCEYII-CSdu2HVI.js +106 -0
- package/dist/rcs-web/assets/i18n-Dbt-vEQ3.js +1 -0
- package/dist/rcs-web/assets/infoDiagram-5YYISTIA-Dcbc9L1S.js +2 -0
- package/{packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-SO0nn3--.js → dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-BLMjFE4t.js} +2 -2
- package/dist/rcs-web/assets/{journeyDiagram-JHISSGLW-D4igFUd4.js → journeyDiagram-JHISSGLW-Dw4nh1xI.js} +2 -2
- package/dist/rcs-web/assets/{kanban-definition-UN3LZRKU-Cm_yKsZC.js → kanban-definition-UN3LZRKU-DkU3j_ly.js} +2 -2
- package/dist/rcs-web/assets/{linear-4IMGll_E.js → linear-N5Cify7M.js} +1 -1
- package/dist/rcs-web/assets/main-30YqUvTd.js +238 -0
- package/dist/rcs-web/assets/main-EP6Lac2m.css +1 -0
- package/{packages/remote-control-server/web/dist/assets/mermaid-VLURNSYL-D_yQ7nAd.js → dist/rcs-web/assets/mermaid-VLURNSYL-gfiJUpl_.js} +5 -5
- package/dist/rcs-web/assets/{mermaid.core-B1qOUdiU.js → mermaid.core-B_Xc65Bf.js} +5 -5
- package/dist/rcs-web/assets/{mindmap-definition-RKZ34NQL-yETom5qt.js → mindmap-definition-RKZ34NQL-DUavHfNu.js} +2 -2
- package/{packages/remote-control-server/web/dist/assets/pieDiagram-4H26LBE5-KIhqXGT6.js → dist/rcs-web/assets/pieDiagram-4H26LBE5-DSJaToTU.js} +2 -2
- package/{packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-DISqmoA6.js → dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-BFp6TnHj.js} +2 -2
- package/dist/rcs-web/assets/{requirementDiagram-4Y6WPE33-DsgT4ptk.js → requirementDiagram-4Y6WPE33-eil6F3-O.js} +2 -2
- package/{packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-Dn67kbn0.js → dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-DbGhoepK.js} +2 -2
- package/{packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-CtWaXZHl.js → dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-B0YrN1ud.js} +14 -14
- package/dist/rcs-web/assets/stateDiagram-AJRCARHV-CofFPj3N.js +1 -0
- package/dist/rcs-web/assets/stateDiagram-v2-BHNVJYJU-DPlcvPn1.js +1 -0
- package/{packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-Dk5WUenC.js → dist/rcs-web/assets/timeline-definition-PNZ67QCA-Bx4dusy8.js} +2 -2
- package/dist/rcs-web/assets/useTeams-MDI4djXg.js +1 -0
- package/{packages/remote-control-server/web/dist/assets/vennDiagram-CIIHVFJN-TY8EiRrC.js → dist/rcs-web/assets/vennDiagram-CIIHVFJN-B_-3l-MF.js} +2 -2
- package/dist/rcs-web/assets/{wardleyDiagram-YWT4CUSO-BK3oi47X.js → wardleyDiagram-YWT4CUSO-DNSn-pGp.js} +2 -2
- package/dist/rcs-web/assets/workerType-OM09y7Lk.js +1 -0
- package/{packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-DhsxqX67.js → dist/rcs-web/assets/xychartDiagram-2RQKCTM6-TqUbNp0j.js} +2 -2
- package/dist/rcs-web/index.html +2 -3
- package/package.json +2 -1
- package/packages/remote-control-server/src/__tests__/acp-ws-handler.test.ts +7 -19
- package/packages/remote-control-server/src/__tests__/auth-login.test.ts +561 -0
- package/packages/remote-control-server/src/__tests__/auth-security.test.ts +547 -0
- package/packages/remote-control-server/src/__tests__/auth.test.ts +7 -18
- package/packages/remote-control-server/src/__tests__/bind-replacement.test.ts +251 -0
- package/packages/remote-control-server/src/__tests__/cookie.test.ts +155 -0
- package/packages/remote-control-server/src/__tests__/data-layer-fixes.test.ts +147 -0
- package/packages/remote-control-server/src/__tests__/db.test.ts +582 -0
- package/packages/remote-control-server/src/__tests__/design-gaps.test.ts +440 -0
- package/packages/remote-control-server/src/__tests__/disconnect-monitor.test.ts +2 -18
- package/packages/remote-control-server/src/__tests__/helpers/db.ts +43 -0
- package/packages/remote-control-server/src/__tests__/helpers/fixtures.ts +94 -0
- package/packages/remote-control-server/src/__tests__/helpers/mock-config.ts +31 -0
- package/packages/remote-control-server/src/__tests__/middleware.test.ts +4 -112
- package/packages/remote-control-server/src/__tests__/password.test.ts +76 -0
- package/packages/remote-control-server/src/__tests__/phase4-cleanup.test.ts +290 -0
- package/packages/remote-control-server/src/__tests__/phase4-integration.test.ts +224 -0
- package/packages/remote-control-server/src/__tests__/routes.test.ts +292 -207
- package/packages/remote-control-server/src/__tests__/services.test.ts +2 -18
- package/packages/remote-control-server/src/__tests__/session-visibility.test.ts +452 -0
- package/packages/remote-control-server/src/__tests__/session.test.ts +216 -0
- package/packages/remote-control-server/src/__tests__/shares.test.ts +1419 -0
- package/packages/remote-control-server/src/__tests__/sse-writer.test.ts +2 -18
- package/packages/remote-control-server/src/__tests__/teams.test.ts +2089 -0
- package/packages/remote-control-server/src/__tests__/work-dispatch.test.ts +2 -18
- package/packages/remote-control-server/src/__tests__/worker-token-removal.test.ts +487 -0
- package/packages/remote-control-server/src/__tests__/ws-handler.test.ts +2 -18
- package/packages/remote-control-server/src/auth/constants.ts +13 -0
- package/packages/remote-control-server/src/auth/cookie.ts +75 -0
- package/packages/remote-control-server/src/auth/middleware.ts +75 -165
- package/packages/remote-control-server/src/auth/password.ts +116 -0
- package/packages/remote-control-server/src/auth/session.ts +130 -0
- package/packages/remote-control-server/src/db/schema.sql +116 -0
- package/packages/remote-control-server/src/db/sqlite.ts +99 -0
- package/packages/remote-control-server/src/routes/acp/index.ts +6 -11
- package/packages/remote-control-server/src/routes/v1/environments.ts +111 -8
- package/packages/remote-control-server/src/routes/web/auth-routes.ts +634 -0
- package/packages/remote-control-server/src/routes/web/control.ts +5 -5
- package/packages/remote-control-server/src/routes/web/environments.ts +5 -27
- package/packages/remote-control-server/src/routes/web/sessions.ts +19 -41
- package/packages/remote-control-server/src/routes/web/shares.ts +371 -0
- package/packages/remote-control-server/src/routes/web/teams.ts +850 -0
- package/packages/remote-control-server/src/services/environment.ts +1 -4
- package/packages/remote-control-server/src/services/session-visibility.ts +79 -0
- package/packages/remote-control-server/src/services/session.ts +0 -13
- package/packages/remote-control-server/src/store.ts +150 -56
- package/packages/remote-control-server/src/types/api.ts +2 -8
- package/packages/remote-control-server/web/dist/assets/Dashboard-BwotBWlJ.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Join-4yrksbdX.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Login-Cxm_yEeE.js +1 -0
- package/packages/remote-control-server/web/dist/assets/SessionDetail-DNdfPOYy.js +50 -0
- package/packages/remote-control-server/web/dist/assets/Setup-BiAAxugt.js +1 -0
- package/packages/remote-control-server/web/dist/assets/ShareLanding-CP3Z6ckr.js +1 -0
- package/packages/remote-control-server/web/dist/assets/TeamCreate-DgdCwRSb.js +1 -0
- package/packages/remote-control-server/web/dist/assets/TeamDetail-CkNTFoMB.js +11 -0
- package/packages/remote-control-server/web/dist/assets/TeamList-Bf0sQ5RQ.js +1 -0
- package/packages/remote-control-server/web/dist/assets/TeamSettings-BaNAfXU3.js +1 -0
- package/packages/remote-control-server/web/dist/assets/UserSettings-CsutQjxG.js +1 -0
- package/{dist/rcs-web/assets/arc-D90597o-.js → packages/remote-control-server/web/dist/assets/arc-BxxmNQO6.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/architectureDiagram-3BPJPVTR-DBjkRdbd.js +36 -0
- package/packages/remote-control-server/web/dist/assets/{blockDiagram-GPEHLZMM-DHd8IbOs.js → blockDiagram-GPEHLZMM-BF6COWlM.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{c4Diagram-AAUBKEIU-CjFkQJ9h.js → c4Diagram-AAUBKEIU-DHOf390v.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/channel-JsvbMQjW.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-C21XWnGZ.js → chunk-2J33WTMH-CeJN8yjM.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-B3SXiJlt.js → chunk-4BX2VUAB-jP76_P2A.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-DjImv45F.js → chunk-55IACEB6-BsFA6emB.js} +1 -1
- package/{dist/rcs-web/assets/chunk-727SXJPM-DtnaqsyD.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-BF4HrQjZ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-AQP2D5EJ-BVFgH5mS.js → chunk-AQP2D5EJ-DToJ74Kc.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-Bl8jgb57.js → chunk-FMBD7UC4-DVTARgsa.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-BpK111zh.js → chunk-ND2GUHAM-C50Gqv9c.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-ruhIHBim.js → chunk-QZHKN3VN-EsIIh6zV.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-BXn8Uc4c.js +1 -0
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-BXn8Uc4c.js +1 -0
- package/packages/remote-control-server/web/dist/assets/code-block-IT6T5CEO-BnufHNTT.js +2 -0
- package/packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-M6tNt14I.js +1 -0
- package/packages/remote-control-server/web/dist/assets/dagre-BM42HDAG-DaTm29qG.js +4 -0
- package/packages/remote-control-server/web/dist/assets/diagram-2AECGRRQ-fqoeOvq2.js +43 -0
- package/packages/remote-control-server/web/dist/assets/diagram-5GNKFQAL-6s2CiaGG.js +10 -0
- package/packages/remote-control-server/web/dist/assets/{diagram-KO2AKTUF-Uy3PDP5S.js → diagram-KO2AKTUF-C0aw_N95.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/diagram-LMA3HP47-C8_Rv3rB.js +24 -0
- package/packages/remote-control-server/web/dist/assets/diagram-OG6HWLK6-Dae4u8Uc.js +24 -0
- package/{dist/rcs-web/assets/erDiagram-TEJ5UH35-sre_MTeK.js → packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-CosS5VWr.js} +13 -13
- package/packages/remote-control-server/web/dist/assets/{flowDiagram-I6XJVG4X-DwrWaLoe.js → flowDiagram-I6XJVG4X-D_Mxs46-.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-B0jy8Am_.js +292 -0
- package/packages/remote-control-server/web/dist/assets/gitGraphDiagram-PVQCEYII-CSdu2HVI.js +106 -0
- package/packages/remote-control-server/web/dist/assets/i18n-Dbt-vEQ3.js +1 -0
- package/packages/remote-control-server/web/dist/assets/infoDiagram-5YYISTIA-Dcbc9L1S.js +2 -0
- package/{dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-SO0nn3--.js → packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-BLMjFE4t.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{journeyDiagram-JHISSGLW-D4igFUd4.js → journeyDiagram-JHISSGLW-Dw4nh1xI.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{kanban-definition-UN3LZRKU-Cm_yKsZC.js → kanban-definition-UN3LZRKU-DkU3j_ly.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{linear-4IMGll_E.js → linear-N5Cify7M.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/main-30YqUvTd.js +238 -0
- package/packages/remote-control-server/web/dist/assets/main-EP6Lac2m.css +1 -0
- package/{dist/rcs-web/assets/mermaid-VLURNSYL-D_yQ7nAd.js → packages/remote-control-server/web/dist/assets/mermaid-VLURNSYL-gfiJUpl_.js} +5 -5
- package/packages/remote-control-server/web/dist/assets/{mermaid.core-B1qOUdiU.js → mermaid.core-B_Xc65Bf.js} +5 -5
- package/packages/remote-control-server/web/dist/assets/{mindmap-definition-RKZ34NQL-yETom5qt.js → mindmap-definition-RKZ34NQL-DUavHfNu.js} +2 -2
- package/{dist/rcs-web/assets/pieDiagram-4H26LBE5-KIhqXGT6.js → packages/remote-control-server/web/dist/assets/pieDiagram-4H26LBE5-DSJaToTU.js} +2 -2
- package/{dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-DISqmoA6.js → packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-BFp6TnHj.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{requirementDiagram-4Y6WPE33-DsgT4ptk.js → requirementDiagram-4Y6WPE33-eil6F3-O.js} +2 -2
- package/{dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-Dn67kbn0.js → packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-DbGhoepK.js} +2 -2
- package/{dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-CtWaXZHl.js → packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-B0YrN1ud.js} +14 -14
- package/packages/remote-control-server/web/dist/assets/stateDiagram-AJRCARHV-CofFPj3N.js +1 -0
- package/packages/remote-control-server/web/dist/assets/stateDiagram-v2-BHNVJYJU-DPlcvPn1.js +1 -0
- package/{dist/rcs-web/assets/timeline-definition-PNZ67QCA-Dk5WUenC.js → packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-Bx4dusy8.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/useTeams-MDI4djXg.js +1 -0
- package/{dist/rcs-web/assets/vennDiagram-CIIHVFJN-TY8EiRrC.js → packages/remote-control-server/web/dist/assets/vennDiagram-CIIHVFJN-B_-3l-MF.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{wardleyDiagram-YWT4CUSO-BK3oi47X.js → wardleyDiagram-YWT4CUSO-DNSn-pGp.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/workerType-OM09y7Lk.js +1 -0
- package/{dist/rcs-web/assets/xychartDiagram-2RQKCTM6-DhsxqX67.js → packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-TqUbNp0j.js} +2 -2
- package/packages/remote-control-server/web/dist/index.html +2 -3
- package/dist/rcs-web/assets/Dashboard-Cyj-Bb86.js +0 -2
- package/dist/rcs-web/assets/SessionDetail-SA9QBkyj.js +0 -51
- package/dist/rcs-web/assets/architectureDiagram-3BPJPVTR-CG9q9_bk.js +0 -36
- package/dist/rcs-web/assets/channel-CQFGglg-.js +0 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-C5rBdShD.js +0 -1
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-C5rBdShD.js +0 -1
- package/dist/rcs-web/assets/code-block-IT6T5CEO-BLGFrBw3.js +0 -2
- package/dist/rcs-web/assets/cose-bilkent-S5V4N54A-DBKEXjqM.js +0 -1
- package/dist/rcs-web/assets/dagre-BM42HDAG-DB_SWlAe.js +0 -4
- package/dist/rcs-web/assets/diagram-2AECGRRQ-Gbm8G3Xz.js +0 -43
- package/dist/rcs-web/assets/diagram-5GNKFQAL-BBuWqfDc.js +0 -10
- package/dist/rcs-web/assets/diagram-LMA3HP47-DyUwNrlg.js +0 -24
- package/dist/rcs-web/assets/diagram-OG6HWLK6-BXpvRwkJ.js +0 -24
- package/dist/rcs-web/assets/ganttDiagram-6RSMTGT7-ByDYviDl.js +0 -292
- package/dist/rcs-web/assets/gitGraphDiagram-PVQCEYII-BUnOPw74.js +0 -106
- package/dist/rcs-web/assets/infoDiagram-5YYISTIA-B1RpwJHG.js +0 -2
- package/dist/rcs-web/assets/main-0A4a3FDU.css +0 -1
- package/dist/rcs-web/assets/main-Dom16YJk.js +0 -283
- package/dist/rcs-web/assets/qr-C0jP9HcD.js +0 -8
- package/dist/rcs-web/assets/qr-scanner-worker.min-D85Z9gVD.js +0 -98
- package/dist/rcs-web/assets/stateDiagram-AJRCARHV-D6xp64f3.js +0 -1
- package/dist/rcs-web/assets/stateDiagram-v2-BHNVJYJU-D76vZCyQ.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Dashboard-Cyj-Bb86.js +0 -2
- package/packages/remote-control-server/web/dist/assets/SessionDetail-SA9QBkyj.js +0 -51
- package/packages/remote-control-server/web/dist/assets/architectureDiagram-3BPJPVTR-CG9q9_bk.js +0 -36
- package/packages/remote-control-server/web/dist/assets/channel-CQFGglg-.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-C5rBdShD.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-C5rBdShD.js +0 -1
- package/packages/remote-control-server/web/dist/assets/code-block-IT6T5CEO-BLGFrBw3.js +0 -2
- package/packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-DBKEXjqM.js +0 -1
- package/packages/remote-control-server/web/dist/assets/dagre-BM42HDAG-DB_SWlAe.js +0 -4
- package/packages/remote-control-server/web/dist/assets/diagram-2AECGRRQ-Gbm8G3Xz.js +0 -43
- package/packages/remote-control-server/web/dist/assets/diagram-5GNKFQAL-BBuWqfDc.js +0 -10
- package/packages/remote-control-server/web/dist/assets/diagram-LMA3HP47-DyUwNrlg.js +0 -24
- package/packages/remote-control-server/web/dist/assets/diagram-OG6HWLK6-BXpvRwkJ.js +0 -24
- package/packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-ByDYviDl.js +0 -292
- package/packages/remote-control-server/web/dist/assets/gitGraphDiagram-PVQCEYII-BUnOPw74.js +0 -106
- package/packages/remote-control-server/web/dist/assets/infoDiagram-5YYISTIA-B1RpwJHG.js +0 -2
- package/packages/remote-control-server/web/dist/assets/main-0A4a3FDU.css +0 -1
- package/packages/remote-control-server/web/dist/assets/main-Dom16YJk.js +0 -283
- package/packages/remote-control-server/web/dist/assets/qr-C0jP9HcD.js +0 -8
- package/packages/remote-control-server/web/dist/assets/qr-scanner-worker.min-D85Z9gVD.js +0 -98
- package/packages/remote-control-server/web/dist/assets/stateDiagram-AJRCARHV-D6xp64f3.js +0 -1
- package/packages/remote-control-server/web/dist/assets/stateDiagram-v2-BHNVJYJU-D76vZCyQ.js +0 -1
|
@@ -1,24 +1,8 @@
|
|
|
1
1
|
import { describe, test, expect, beforeEach, mock } from 'bun:test'
|
|
2
|
+
import { mockConfigModule } from './helpers/mock-config'
|
|
2
3
|
|
|
3
4
|
// Mock config
|
|
4
|
-
|
|
5
|
-
port: 3000,
|
|
6
|
-
host: '0.0.0.0',
|
|
7
|
-
apiKeys: ['test-api-key'],
|
|
8
|
-
baseUrl: 'http://localhost:3000',
|
|
9
|
-
pollTimeout: 1,
|
|
10
|
-
heartbeatInterval: 20,
|
|
11
|
-
jwtExpiresIn: 3600,
|
|
12
|
-
disconnectTimeout: 300,
|
|
13
|
-
webCorsOrigins: [],
|
|
14
|
-
wsIdleTimeout: 30,
|
|
15
|
-
wsKeepaliveInterval: 20,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
mock.module('../config', () => ({
|
|
19
|
-
config: mockConfig,
|
|
20
|
-
getBaseUrl: () => 'http://localhost:3000',
|
|
21
|
-
}))
|
|
5
|
+
mock.module('../config', () => mockConfigModule({ pollTimeout: 1 }))
|
|
22
6
|
|
|
23
7
|
import { Hono } from 'hono'
|
|
24
8
|
import {
|
|
@@ -88,6 +72,12 @@ function toWebSessionId(sessionId: string): string {
|
|
|
88
72
|
return `session_${sessionId.slice('cse_'.length)}`
|
|
89
73
|
}
|
|
90
74
|
|
|
75
|
+
// Auth helper for web route tests: issues a session token and returns Bearer header.
|
|
76
|
+
// Tokens are issued fresh per call so they survive storeReset() in beforeEach.
|
|
77
|
+
function _auth(user: string): string {
|
|
78
|
+
return `Bearer ${issueToken(user).token}`
|
|
79
|
+
}
|
|
80
|
+
|
|
91
81
|
describe('V1 Session Routes', () => {
|
|
92
82
|
let app: Hono
|
|
93
83
|
|
|
@@ -619,9 +609,12 @@ describe('Web Session Routes', () => {
|
|
|
619
609
|
})
|
|
620
610
|
|
|
621
611
|
test('POST /web/sessions — creates and auto-binds session', async () => {
|
|
622
|
-
const res = await app.request('/web/sessions
|
|
612
|
+
const res = await app.request('/web/sessions', {
|
|
623
613
|
method: 'POST',
|
|
624
|
-
headers: {
|
|
614
|
+
headers: {
|
|
615
|
+
Authorization: _auth('user-1'),
|
|
616
|
+
'Content-Type': 'application/json',
|
|
617
|
+
},
|
|
625
618
|
body: JSON.stringify({ title: 'Web Session' }),
|
|
626
619
|
})
|
|
627
620
|
expect(res.status).toBe(200)
|
|
@@ -632,14 +625,19 @@ describe('Web Session Routes', () => {
|
|
|
632
625
|
|
|
633
626
|
test('GET /web/sessions — returns sessions owned by UUID', async () => {
|
|
634
627
|
// Create and bind
|
|
635
|
-
const createRes = await app.request('/web/sessions
|
|
628
|
+
const createRes = await app.request('/web/sessions', {
|
|
636
629
|
method: 'POST',
|
|
637
|
-
headers: {
|
|
630
|
+
headers: {
|
|
631
|
+
Authorization: _auth('user-1'),
|
|
632
|
+
'Content-Type': 'application/json',
|
|
633
|
+
},
|
|
638
634
|
body: JSON.stringify({}),
|
|
639
635
|
})
|
|
640
636
|
const { id } = await createRes.json()
|
|
641
637
|
|
|
642
|
-
const listRes = await app.request('/web/sessions
|
|
638
|
+
const listRes = await app.request('/web/sessions', {
|
|
639
|
+
headers: { Authorization: _auth('user-1') },
|
|
640
|
+
})
|
|
643
641
|
expect(listRes.status).toBe(200)
|
|
644
642
|
const sessions = await listRes.json()
|
|
645
643
|
expect(sessions).toHaveLength(1)
|
|
@@ -651,13 +649,17 @@ describe('Web Session Routes', () => {
|
|
|
651
649
|
storeBindSession(codeSession.id, 'user-1')
|
|
652
650
|
const compatId = toWebSessionId(codeSession.id)
|
|
653
651
|
|
|
654
|
-
const listRes = await app.request('/web/sessions
|
|
652
|
+
const listRes = await app.request('/web/sessions', {
|
|
653
|
+
headers: { Authorization: _auth('user-1') },
|
|
654
|
+
})
|
|
655
655
|
expect(listRes.status).toBe(200)
|
|
656
656
|
const sessions = await listRes.json()
|
|
657
657
|
expect(sessions).toHaveLength(1)
|
|
658
658
|
expect(sessions[0].id).toBe(compatId)
|
|
659
659
|
|
|
660
|
-
const allRes = await app.request('/web/sessions/all
|
|
660
|
+
const allRes = await app.request('/web/sessions/all', {
|
|
661
|
+
headers: { Authorization: _auth('user-1') },
|
|
662
|
+
})
|
|
661
663
|
expect(allRes.status).toBe(200)
|
|
662
664
|
const summaries = await allRes.json()
|
|
663
665
|
expect(summaries).toHaveLength(1)
|
|
@@ -671,18 +673,26 @@ describe('Web Session Routes', () => {
|
|
|
671
673
|
|
|
672
674
|
test('GET /web/sessions/all — lists only sessions owned by requesting UUID', async () => {
|
|
673
675
|
// Create 2 sessions via different users
|
|
674
|
-
await app.request('/web/sessions
|
|
676
|
+
await app.request('/web/sessions', {
|
|
675
677
|
method: 'POST',
|
|
676
|
-
headers: {
|
|
678
|
+
headers: {
|
|
679
|
+
Authorization: _auth('user-1'),
|
|
680
|
+
'Content-Type': 'application/json',
|
|
681
|
+
},
|
|
677
682
|
body: JSON.stringify({}),
|
|
678
683
|
})
|
|
679
|
-
await app.request('/web/sessions
|
|
684
|
+
await app.request('/web/sessions', {
|
|
680
685
|
method: 'POST',
|
|
681
|
-
headers: {
|
|
686
|
+
headers: {
|
|
687
|
+
Authorization: _auth('user-2'),
|
|
688
|
+
'Content-Type': 'application/json',
|
|
689
|
+
},
|
|
682
690
|
body: JSON.stringify({}),
|
|
683
691
|
})
|
|
684
692
|
|
|
685
|
-
const allRes = await app.request('/web/sessions/all
|
|
693
|
+
const allRes = await app.request('/web/sessions/all', {
|
|
694
|
+
headers: { Authorization: _auth('user-1') },
|
|
695
|
+
})
|
|
686
696
|
expect(allRes.status).toBe(200)
|
|
687
697
|
const sessions = await allRes.json()
|
|
688
698
|
expect(sessions).toHaveLength(1) // only user-1's session, not user-2's
|
|
@@ -704,7 +714,9 @@ describe('Web Session Routes', () => {
|
|
|
704
714
|
const { storeUpdateSession } = await import('../store')
|
|
705
715
|
storeUpdateSession(inactive.id, { status: 'inactive' })
|
|
706
716
|
|
|
707
|
-
const listRes = await app.request('/web/sessions
|
|
717
|
+
const listRes = await app.request('/web/sessions', {
|
|
718
|
+
headers: { Authorization: _auth('user-1') },
|
|
719
|
+
})
|
|
708
720
|
expect(listRes.status).toBe(200)
|
|
709
721
|
const sessions = await listRes.json()
|
|
710
722
|
const sessionIds = sessions.map((session: { id: string }) => session.id)
|
|
@@ -712,7 +724,9 @@ describe('Web Session Routes', () => {
|
|
|
712
724
|
expect(sessionIds).toContain(inactive.id)
|
|
713
725
|
expect(sessionIds).toContain(open.id)
|
|
714
726
|
|
|
715
|
-
const allRes = await app.request('/web/sessions/all
|
|
727
|
+
const allRes = await app.request('/web/sessions/all', {
|
|
728
|
+
headers: { Authorization: _auth('user-1') },
|
|
729
|
+
})
|
|
716
730
|
expect(allRes.status).toBe(200)
|
|
717
731
|
const summaries = await allRes.json()
|
|
718
732
|
const summaryIds = summaries.map((session: { id: string }) => session.id)
|
|
@@ -722,14 +736,19 @@ describe('Web Session Routes', () => {
|
|
|
722
736
|
})
|
|
723
737
|
|
|
724
738
|
test('GET /web/sessions/:id — returns owned session', async () => {
|
|
725
|
-
const createRes = await app.request('/web/sessions
|
|
739
|
+
const createRes = await app.request('/web/sessions', {
|
|
726
740
|
method: 'POST',
|
|
727
|
-
headers: {
|
|
741
|
+
headers: {
|
|
742
|
+
Authorization: _auth('user-1'),
|
|
743
|
+
'Content-Type': 'application/json',
|
|
744
|
+
},
|
|
728
745
|
body: JSON.stringify({}),
|
|
729
746
|
})
|
|
730
747
|
const { id } = await createRes.json()
|
|
731
748
|
|
|
732
|
-
const getRes = await app.request(`/web/sessions/${id}
|
|
749
|
+
const getRes = await app.request(`/web/sessions/${id}`, {
|
|
750
|
+
headers: { Authorization: _auth('user-1') },
|
|
751
|
+
})
|
|
733
752
|
expect(getRes.status).toBe(200)
|
|
734
753
|
})
|
|
735
754
|
|
|
@@ -760,9 +779,9 @@ describe('Web Session Routes', () => {
|
|
|
760
779
|
}),
|
|
761
780
|
})
|
|
762
781
|
|
|
763
|
-
const getRes = await app.request(
|
|
764
|
-
|
|
765
|
-
)
|
|
782
|
+
const getRes = await app.request(`/web/sessions/${toWebSessionId(id)}`, {
|
|
783
|
+
headers: { Authorization: _auth('user-1') },
|
|
784
|
+
})
|
|
766
785
|
expect(getRes.status).toBe(200)
|
|
767
786
|
const body = await getRes.json()
|
|
768
787
|
expect(body.automation_state).toEqual({
|
|
@@ -774,35 +793,48 @@ describe('Web Session Routes', () => {
|
|
|
774
793
|
})
|
|
775
794
|
|
|
776
795
|
test('GET /web/sessions/:id — 403 for non-owner', async () => {
|
|
777
|
-
const createRes = await app.request('/web/sessions
|
|
796
|
+
const createRes = await app.request('/web/sessions', {
|
|
778
797
|
method: 'POST',
|
|
779
|
-
headers: {
|
|
798
|
+
headers: {
|
|
799
|
+
Authorization: _auth('user-1'),
|
|
800
|
+
'Content-Type': 'application/json',
|
|
801
|
+
},
|
|
780
802
|
body: JSON.stringify({}),
|
|
781
803
|
})
|
|
782
804
|
const { id } = await createRes.json()
|
|
783
805
|
|
|
784
|
-
const getRes = await app.request(`/web/sessions/${id}
|
|
806
|
+
const getRes = await app.request(`/web/sessions/${id}`, {
|
|
807
|
+
headers: { Authorization: _auth('user-2') },
|
|
808
|
+
})
|
|
785
809
|
expect(getRes.status).toBe(403)
|
|
786
810
|
})
|
|
787
811
|
|
|
788
812
|
test('GET /web/sessions/:id/history — returns events', async () => {
|
|
789
|
-
const createRes = await app.request('/web/sessions
|
|
813
|
+
const createRes = await app.request('/web/sessions', {
|
|
790
814
|
method: 'POST',
|
|
791
|
-
headers: {
|
|
815
|
+
headers: {
|
|
816
|
+
Authorization: _auth('user-1'),
|
|
817
|
+
'Content-Type': 'application/json',
|
|
818
|
+
},
|
|
792
819
|
body: JSON.stringify({}),
|
|
793
820
|
})
|
|
794
821
|
const { id } = await createRes.json()
|
|
795
822
|
|
|
796
|
-
const histRes = await app.request(`/web/sessions/${id}/history
|
|
823
|
+
const histRes = await app.request(`/web/sessions/${id}/history`, {
|
|
824
|
+
headers: { Authorization: _auth('user-1') },
|
|
825
|
+
})
|
|
797
826
|
expect(histRes.status).toBe(200)
|
|
798
827
|
const body = await histRes.json()
|
|
799
828
|
expect(body.events).toEqual([])
|
|
800
829
|
})
|
|
801
830
|
|
|
802
831
|
test('GET /web/sessions/:id/history — returns task_state snapshots', async () => {
|
|
803
|
-
const createRes = await app.request('/web/sessions
|
|
832
|
+
const createRes = await app.request('/web/sessions', {
|
|
804
833
|
method: 'POST',
|
|
805
|
-
headers: {
|
|
834
|
+
headers: {
|
|
835
|
+
Authorization: _auth('user-1'),
|
|
836
|
+
'Content-Type': 'application/json',
|
|
837
|
+
},
|
|
806
838
|
body: JSON.stringify({}),
|
|
807
839
|
})
|
|
808
840
|
const { id } = await createRes.json()
|
|
@@ -817,7 +849,9 @@ describe('Web Session Routes', () => {
|
|
|
817
849
|
'inbound',
|
|
818
850
|
)
|
|
819
851
|
|
|
820
|
-
const histRes = await app.request(`/web/sessions/${id}/history
|
|
852
|
+
const histRes = await app.request(`/web/sessions/${id}/history`, {
|
|
853
|
+
headers: { Authorization: _auth('user-1') },
|
|
854
|
+
})
|
|
821
855
|
expect(histRes.status).toBe(200)
|
|
822
856
|
const body = await histRes.json()
|
|
823
857
|
expect(body.events).toHaveLength(1)
|
|
@@ -833,35 +867,45 @@ describe('Web Session Routes', () => {
|
|
|
833
867
|
storeBindSession(codeSession.id, 'user-1')
|
|
834
868
|
const compatId = toWebSessionId(codeSession.id)
|
|
835
869
|
|
|
836
|
-
const getRes = await app.request(`/web/sessions/${compatId}
|
|
870
|
+
const getRes = await app.request(`/web/sessions/${compatId}`, {
|
|
871
|
+
headers: { Authorization: _auth('user-1') },
|
|
872
|
+
})
|
|
837
873
|
expect(getRes.status).toBe(200)
|
|
838
874
|
const session = await getRes.json()
|
|
839
875
|
expect(session.id).toBe(compatId)
|
|
840
876
|
|
|
841
|
-
const histRes = await app.request(
|
|
842
|
-
|
|
843
|
-
)
|
|
877
|
+
const histRes = await app.request(`/web/sessions/${compatId}/history`, {
|
|
878
|
+
headers: { Authorization: _auth('user-1') },
|
|
879
|
+
})
|
|
844
880
|
expect(histRes.status).toBe(200)
|
|
845
881
|
const history = await histRes.json()
|
|
846
882
|
expect(history.events).toEqual([])
|
|
847
883
|
})
|
|
848
884
|
|
|
849
885
|
test('GET /web/sessions/:id/history — 403 for non-owner', async () => {
|
|
850
|
-
const createRes = await app.request('/web/sessions
|
|
886
|
+
const createRes = await app.request('/web/sessions', {
|
|
851
887
|
method: 'POST',
|
|
852
|
-
headers: {
|
|
888
|
+
headers: {
|
|
889
|
+
Authorization: _auth('user-1'),
|
|
890
|
+
'Content-Type': 'application/json',
|
|
891
|
+
},
|
|
853
892
|
body: JSON.stringify({}),
|
|
854
893
|
})
|
|
855
894
|
const { id } = await createRes.json()
|
|
856
895
|
|
|
857
|
-
const histRes = await app.request(`/web/sessions/${id}/history
|
|
896
|
+
const histRes = await app.request(`/web/sessions/${id}/history`, {
|
|
897
|
+
headers: { Authorization: _auth('user-2') },
|
|
898
|
+
})
|
|
858
899
|
expect(histRes.status).toBe(403)
|
|
859
900
|
})
|
|
860
901
|
|
|
861
902
|
test('GET /web/sessions/:id — 404 after session deleted', async () => {
|
|
862
|
-
const createRes = await app.request('/web/sessions
|
|
903
|
+
const createRes = await app.request('/web/sessions', {
|
|
863
904
|
method: 'POST',
|
|
864
|
-
headers: {
|
|
905
|
+
headers: {
|
|
906
|
+
Authorization: _auth('user-1'),
|
|
907
|
+
'Content-Type': 'application/json',
|
|
908
|
+
},
|
|
865
909
|
body: JSON.stringify({}),
|
|
866
910
|
})
|
|
867
911
|
const { id } = await createRes.json()
|
|
@@ -873,7 +917,9 @@ describe('Web Session Routes', () => {
|
|
|
873
917
|
})
|
|
874
918
|
|
|
875
919
|
// Session still exists (archived), so we can still get it
|
|
876
|
-
const getRes = await app.request(`/web/sessions/${id}
|
|
920
|
+
const getRes = await app.request(`/web/sessions/${id}`, {
|
|
921
|
+
headers: { Authorization: _auth('user-1') },
|
|
922
|
+
})
|
|
877
923
|
// After archive, session status is "archived" but still exists
|
|
878
924
|
expect(getRes.status).toBe(200)
|
|
879
925
|
})
|
|
@@ -881,9 +927,12 @@ describe('Web Session Routes', () => {
|
|
|
881
927
|
test('GET /web/sessions/:id/history — 404 for non-existent session', async () => {
|
|
882
928
|
// Bind to a non-existent session won't work, but if ownership was set
|
|
883
929
|
// and session deleted, we need to test the 404 path
|
|
884
|
-
const createRes = await app.request('/web/sessions
|
|
930
|
+
const createRes = await app.request('/web/sessions', {
|
|
885
931
|
method: 'POST',
|
|
886
|
-
headers: {
|
|
932
|
+
headers: {
|
|
933
|
+
Authorization: _auth('user-1'),
|
|
934
|
+
'Content-Type': 'application/json',
|
|
935
|
+
},
|
|
887
936
|
body: JSON.stringify({}),
|
|
888
937
|
})
|
|
889
938
|
const { id } = await createRes.json()
|
|
@@ -892,14 +941,19 @@ describe('Web Session Routes', () => {
|
|
|
892
941
|
const { storeDeleteSession } = await import('../store')
|
|
893
942
|
storeDeleteSession(id)
|
|
894
943
|
|
|
895
|
-
const histRes = await app.request(`/web/sessions/${id}/history
|
|
944
|
+
const histRes = await app.request(`/web/sessions/${id}/history`, {
|
|
945
|
+
headers: { Authorization: _auth('user-1') },
|
|
946
|
+
})
|
|
896
947
|
expect(histRes.status).toBe(404)
|
|
897
948
|
})
|
|
898
949
|
|
|
899
950
|
test('POST /web/sessions with invalid environment_id — handles work item error', async () => {
|
|
900
|
-
const res = await app.request('/web/sessions
|
|
951
|
+
const res = await app.request('/web/sessions', {
|
|
901
952
|
method: 'POST',
|
|
902
|
-
headers: {
|
|
953
|
+
headers: {
|
|
954
|
+
Authorization: _auth('user-1'),
|
|
955
|
+
'Content-Type': 'application/json',
|
|
956
|
+
},
|
|
903
957
|
body: JSON.stringify({ environment_id: 'env_nonexistent' }),
|
|
904
958
|
})
|
|
905
959
|
// Session is still created even if work item fails
|
|
@@ -909,16 +963,19 @@ describe('Web Session Routes', () => {
|
|
|
909
963
|
})
|
|
910
964
|
|
|
911
965
|
test('GET /web/sessions/:id/events — returns SSE stream', async () => {
|
|
912
|
-
const createRes = await app.request('/web/sessions
|
|
966
|
+
const createRes = await app.request('/web/sessions', {
|
|
913
967
|
method: 'POST',
|
|
914
|
-
headers: {
|
|
968
|
+
headers: {
|
|
969
|
+
Authorization: _auth('user-1'),
|
|
970
|
+
'Content-Type': 'application/json',
|
|
971
|
+
},
|
|
915
972
|
body: JSON.stringify({}),
|
|
916
973
|
})
|
|
917
974
|
const { id } = await createRes.json()
|
|
918
975
|
|
|
919
|
-
const eventsRes = await app.request(
|
|
920
|
-
|
|
921
|
-
)
|
|
976
|
+
const eventsRes = await app.request(`/web/sessions/${id}/events`, {
|
|
977
|
+
headers: { Authorization: _auth('user-1') },
|
|
978
|
+
})
|
|
922
979
|
expect(eventsRes.status).toBe(200)
|
|
923
980
|
expect(eventsRes.headers.get('Content-Type')).toBe('text/event-stream')
|
|
924
981
|
|
|
@@ -937,9 +994,9 @@ describe('Web Session Routes', () => {
|
|
|
937
994
|
storeBindSession(codeSession.id, 'user-1')
|
|
938
995
|
const compatId = toWebSessionId(codeSession.id)
|
|
939
996
|
|
|
940
|
-
const eventsRes = await app.request(
|
|
941
|
-
|
|
942
|
-
)
|
|
997
|
+
const eventsRes = await app.request(`/web/sessions/${compatId}/events`, {
|
|
998
|
+
headers: { Authorization: _auth('user-1') },
|
|
999
|
+
})
|
|
943
1000
|
expect(eventsRes.status).toBe(200)
|
|
944
1001
|
expect(eventsRes.headers.get('Content-Type')).toBe('text/event-stream')
|
|
945
1002
|
|
|
@@ -953,23 +1010,29 @@ describe('Web Session Routes', () => {
|
|
|
953
1010
|
})
|
|
954
1011
|
|
|
955
1012
|
test('GET /web/sessions/:id/events — 403 for non-owner', async () => {
|
|
956
|
-
const createRes = await app.request('/web/sessions
|
|
1013
|
+
const createRes = await app.request('/web/sessions', {
|
|
957
1014
|
method: 'POST',
|
|
958
|
-
headers: {
|
|
1015
|
+
headers: {
|
|
1016
|
+
Authorization: _auth('user-1'),
|
|
1017
|
+
'Content-Type': 'application/json',
|
|
1018
|
+
},
|
|
959
1019
|
body: JSON.stringify({}),
|
|
960
1020
|
})
|
|
961
1021
|
const { id } = await createRes.json()
|
|
962
1022
|
|
|
963
|
-
const eventsRes = await app.request(
|
|
964
|
-
|
|
965
|
-
)
|
|
1023
|
+
const eventsRes = await app.request(`/web/sessions/${id}/events`, {
|
|
1024
|
+
headers: { Authorization: _auth('user-2') },
|
|
1025
|
+
})
|
|
966
1026
|
expect(eventsRes.status).toBe(403)
|
|
967
1027
|
})
|
|
968
1028
|
|
|
969
1029
|
test('GET /web/sessions/:id/events — 409 for archived session', async () => {
|
|
970
|
-
const createRes = await app.request('/web/sessions
|
|
1030
|
+
const createRes = await app.request('/web/sessions', {
|
|
971
1031
|
method: 'POST',
|
|
972
|
-
headers: {
|
|
1032
|
+
headers: {
|
|
1033
|
+
Authorization: _auth('user-1'),
|
|
1034
|
+
'Content-Type': 'application/json',
|
|
1035
|
+
},
|
|
973
1036
|
body: JSON.stringify({}),
|
|
974
1037
|
})
|
|
975
1038
|
const { id } = await createRes.json()
|
|
@@ -979,7 +1042,9 @@ describe('Web Session Routes', () => {
|
|
|
979
1042
|
headers: AUTH_HEADERS,
|
|
980
1043
|
})
|
|
981
1044
|
|
|
982
|
-
const res = await app.request(`/web/sessions/${id}/events
|
|
1045
|
+
const res = await app.request(`/web/sessions/${id}/events`, {
|
|
1046
|
+
headers: { Authorization: _auth('user-1') },
|
|
1047
|
+
})
|
|
983
1048
|
expect(res.status).toBe(409)
|
|
984
1049
|
const body = await res.json()
|
|
985
1050
|
expect(body.error.type).toBe('session_closed')
|
|
@@ -998,23 +1063,26 @@ describe('Web Control Routes', () => {
|
|
|
998
1063
|
app = createApp()
|
|
999
1064
|
|
|
1000
1065
|
// Create and bind session
|
|
1001
|
-
const createRes = await app.request('/web/sessions
|
|
1066
|
+
const createRes = await app.request('/web/sessions', {
|
|
1002
1067
|
method: 'POST',
|
|
1003
|
-
headers: {
|
|
1068
|
+
headers: {
|
|
1069
|
+
Authorization: _auth('user-1'),
|
|
1070
|
+
'Content-Type': 'application/json',
|
|
1071
|
+
},
|
|
1004
1072
|
body: JSON.stringify({}),
|
|
1005
1073
|
})
|
|
1006
1074
|
sessionId = (await createRes.json()).id
|
|
1007
1075
|
})
|
|
1008
1076
|
|
|
1009
1077
|
test('POST /web/sessions/:id/events — sends user message', async () => {
|
|
1010
|
-
const res = await app.request(
|
|
1011
|
-
|
|
1012
|
-
{
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1078
|
+
const res = await app.request(`/web/sessions/${sessionId}/events`, {
|
|
1079
|
+
method: 'POST',
|
|
1080
|
+
headers: {
|
|
1081
|
+
Authorization: _auth('user-1'),
|
|
1082
|
+
'Content-Type': 'application/json',
|
|
1016
1083
|
},
|
|
1017
|
-
|
|
1084
|
+
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1085
|
+
})
|
|
1018
1086
|
expect(res.status).toBe(200)
|
|
1019
1087
|
const body = await res.json()
|
|
1020
1088
|
expect(body.status).toBe('ok')
|
|
@@ -1026,111 +1094,114 @@ describe('Web Control Routes', () => {
|
|
|
1026
1094
|
storeBindSession(rawSessionId, 'user-1')
|
|
1027
1095
|
const compatId = toWebSessionId(rawSessionId)
|
|
1028
1096
|
|
|
1029
|
-
const eventsRes = await app.request(
|
|
1030
|
-
|
|
1031
|
-
{
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1097
|
+
const eventsRes = await app.request(`/web/sessions/${compatId}/events`, {
|
|
1098
|
+
method: 'POST',
|
|
1099
|
+
headers: {
|
|
1100
|
+
Authorization: _auth('user-1'),
|
|
1101
|
+
'Content-Type': 'application/json',
|
|
1035
1102
|
},
|
|
1036
|
-
|
|
1103
|
+
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1104
|
+
})
|
|
1037
1105
|
expect(eventsRes.status).toBe(200)
|
|
1038
1106
|
|
|
1039
|
-
const controlRes = await app.request(
|
|
1040
|
-
|
|
1041
|
-
{
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
body: JSON.stringify({
|
|
1045
|
-
type: 'permission_response',
|
|
1046
|
-
approved: true,
|
|
1047
|
-
request_id: 'r1',
|
|
1048
|
-
}),
|
|
1107
|
+
const controlRes = await app.request(`/web/sessions/${compatId}/control`, {
|
|
1108
|
+
method: 'POST',
|
|
1109
|
+
headers: {
|
|
1110
|
+
Authorization: _auth('user-1'),
|
|
1111
|
+
'Content-Type': 'application/json',
|
|
1049
1112
|
},
|
|
1050
|
-
|
|
1113
|
+
body: JSON.stringify({
|
|
1114
|
+
type: 'permission_response',
|
|
1115
|
+
approved: true,
|
|
1116
|
+
request_id: 'r1',
|
|
1117
|
+
}),
|
|
1118
|
+
})
|
|
1051
1119
|
expect(controlRes.status).toBe(200)
|
|
1052
1120
|
|
|
1053
1121
|
const interruptRes = await app.request(
|
|
1054
|
-
`/web/sessions/${compatId}/interrupt
|
|
1122
|
+
`/web/sessions/${compatId}/interrupt`,
|
|
1055
1123
|
{
|
|
1056
1124
|
method: 'POST',
|
|
1057
|
-
headers: {
|
|
1125
|
+
headers: {
|
|
1126
|
+
Authorization: _auth('user-1'),
|
|
1127
|
+
'Content-Type': 'application/json',
|
|
1128
|
+
},
|
|
1058
1129
|
},
|
|
1059
1130
|
)
|
|
1060
1131
|
expect(interruptRes.status).toBe(200)
|
|
1061
1132
|
})
|
|
1062
1133
|
|
|
1063
1134
|
test('POST /web/sessions/:id/events — 403 for non-owner', async () => {
|
|
1064
|
-
const res = await app.request(
|
|
1065
|
-
|
|
1066
|
-
{
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1135
|
+
const res = await app.request(`/web/sessions/${sessionId}/events`, {
|
|
1136
|
+
method: 'POST',
|
|
1137
|
+
headers: {
|
|
1138
|
+
Authorization: _auth('user-2'),
|
|
1139
|
+
'Content-Type': 'application/json',
|
|
1070
1140
|
},
|
|
1071
|
-
|
|
1141
|
+
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1142
|
+
})
|
|
1072
1143
|
expect(res.status).toBe(403)
|
|
1073
1144
|
})
|
|
1074
1145
|
|
|
1075
1146
|
test('POST /web/sessions/:id/control — sends control request', async () => {
|
|
1076
|
-
const res = await app.request(
|
|
1077
|
-
|
|
1078
|
-
{
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
body: JSON.stringify({
|
|
1082
|
-
type: 'permission_response',
|
|
1083
|
-
approved: true,
|
|
1084
|
-
request_id: 'r1',
|
|
1085
|
-
}),
|
|
1147
|
+
const res = await app.request(`/web/sessions/${sessionId}/control`, {
|
|
1148
|
+
method: 'POST',
|
|
1149
|
+
headers: {
|
|
1150
|
+
Authorization: _auth('user-1'),
|
|
1151
|
+
'Content-Type': 'application/json',
|
|
1086
1152
|
},
|
|
1087
|
-
|
|
1153
|
+
body: JSON.stringify({
|
|
1154
|
+
type: 'permission_response',
|
|
1155
|
+
approved: true,
|
|
1156
|
+
request_id: 'r1',
|
|
1157
|
+
}),
|
|
1158
|
+
})
|
|
1088
1159
|
expect(res.status).toBe(200)
|
|
1089
1160
|
})
|
|
1090
1161
|
|
|
1091
1162
|
test('POST /web/sessions/:id/interrupt — interrupts session', async () => {
|
|
1092
|
-
const res = await app.request(
|
|
1093
|
-
|
|
1094
|
-
{
|
|
1095
|
-
|
|
1096
|
-
|
|
1163
|
+
const res = await app.request(`/web/sessions/${sessionId}/interrupt`, {
|
|
1164
|
+
method: 'POST',
|
|
1165
|
+
headers: {
|
|
1166
|
+
Authorization: _auth('user-1'),
|
|
1167
|
+
'Content-Type': 'application/json',
|
|
1097
1168
|
},
|
|
1098
|
-
)
|
|
1169
|
+
})
|
|
1099
1170
|
expect(res.status).toBe(200)
|
|
1100
1171
|
})
|
|
1101
1172
|
|
|
1102
1173
|
test('POST /web/sessions/:id/interrupt — 403 for non-owner', async () => {
|
|
1103
|
-
const res = await app.request(
|
|
1104
|
-
|
|
1105
|
-
{
|
|
1106
|
-
|
|
1107
|
-
|
|
1174
|
+
const res = await app.request(`/web/sessions/${sessionId}/interrupt`, {
|
|
1175
|
+
method: 'POST',
|
|
1176
|
+
headers: {
|
|
1177
|
+
Authorization: _auth('user-2'),
|
|
1178
|
+
'Content-Type': 'application/json',
|
|
1108
1179
|
},
|
|
1109
|
-
)
|
|
1180
|
+
})
|
|
1110
1181
|
expect(res.status).toBe(403)
|
|
1111
1182
|
})
|
|
1112
1183
|
|
|
1113
1184
|
test('POST /web/sessions/:id/control — 403 for non-owner', async () => {
|
|
1114
|
-
const res = await app.request(
|
|
1115
|
-
|
|
1116
|
-
{
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
body: JSON.stringify({ type: 'permission_response', approved: true }),
|
|
1185
|
+
const res = await app.request(`/web/sessions/${sessionId}/control`, {
|
|
1186
|
+
method: 'POST',
|
|
1187
|
+
headers: {
|
|
1188
|
+
Authorization: _auth('user-2'),
|
|
1189
|
+
'Content-Type': 'application/json',
|
|
1120
1190
|
},
|
|
1121
|
-
|
|
1191
|
+
body: JSON.stringify({ type: 'permission_response', approved: true }),
|
|
1192
|
+
})
|
|
1122
1193
|
expect(res.status).toBe(403)
|
|
1123
1194
|
})
|
|
1124
1195
|
|
|
1125
1196
|
test('POST /web/sessions/:id/events — 403 for non-existent session with no ownership', async () => {
|
|
1126
|
-
const res = await app.request(
|
|
1127
|
-
'
|
|
1128
|
-
{
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1197
|
+
const res = await app.request('/web/sessions/nonexistent/events', {
|
|
1198
|
+
method: 'POST',
|
|
1199
|
+
headers: {
|
|
1200
|
+
Authorization: _auth('user-1'),
|
|
1201
|
+
'Content-Type': 'application/json',
|
|
1132
1202
|
},
|
|
1133
|
-
|
|
1203
|
+
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1204
|
+
})
|
|
1134
1205
|
expect(res.status).toBe(403)
|
|
1135
1206
|
})
|
|
1136
1207
|
|
|
@@ -1140,35 +1211,38 @@ describe('Web Control Routes', () => {
|
|
|
1140
1211
|
headers: AUTH_HEADERS,
|
|
1141
1212
|
})
|
|
1142
1213
|
|
|
1143
|
-
const eventsRes = await app.request(
|
|
1144
|
-
|
|
1145
|
-
{
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1214
|
+
const eventsRes = await app.request(`/web/sessions/${sessionId}/events`, {
|
|
1215
|
+
method: 'POST',
|
|
1216
|
+
headers: {
|
|
1217
|
+
Authorization: _auth('user-1'),
|
|
1218
|
+
'Content-Type': 'application/json',
|
|
1149
1219
|
},
|
|
1150
|
-
|
|
1220
|
+
body: JSON.stringify({ type: 'user', content: 'hello' }),
|
|
1221
|
+
})
|
|
1151
1222
|
expect(eventsRes.status).toBe(409)
|
|
1152
1223
|
|
|
1153
|
-
const controlRes = await app.request(
|
|
1154
|
-
|
|
1155
|
-
{
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
body: JSON.stringify({
|
|
1159
|
-
type: 'permission_response',
|
|
1160
|
-
approved: true,
|
|
1161
|
-
request_id: 'r1',
|
|
1162
|
-
}),
|
|
1224
|
+
const controlRes = await app.request(`/web/sessions/${sessionId}/control`, {
|
|
1225
|
+
method: 'POST',
|
|
1226
|
+
headers: {
|
|
1227
|
+
Authorization: _auth('user-1'),
|
|
1228
|
+
'Content-Type': 'application/json',
|
|
1163
1229
|
},
|
|
1164
|
-
|
|
1230
|
+
body: JSON.stringify({
|
|
1231
|
+
type: 'permission_response',
|
|
1232
|
+
approved: true,
|
|
1233
|
+
request_id: 'r1',
|
|
1234
|
+
}),
|
|
1235
|
+
})
|
|
1165
1236
|
expect(controlRes.status).toBe(409)
|
|
1166
1237
|
|
|
1167
1238
|
const interruptRes = await app.request(
|
|
1168
|
-
`/web/sessions/${sessionId}/interrupt
|
|
1239
|
+
`/web/sessions/${sessionId}/interrupt`,
|
|
1169
1240
|
{
|
|
1170
1241
|
method: 'POST',
|
|
1171
|
-
headers: {
|
|
1242
|
+
headers: {
|
|
1243
|
+
Authorization: _auth('user-1'),
|
|
1244
|
+
'Content-Type': 'application/json',
|
|
1245
|
+
},
|
|
1172
1246
|
},
|
|
1173
1247
|
)
|
|
1174
1248
|
expect(interruptRes.status).toBe(409)
|
|
@@ -1191,7 +1265,9 @@ describe('Web Environment Routes', () => {
|
|
|
1191
1265
|
body: JSON.stringify({ machine_name: 'mac1' }),
|
|
1192
1266
|
})
|
|
1193
1267
|
|
|
1194
|
-
const res = await app.request('/web/environments
|
|
1268
|
+
const res = await app.request('/web/environments', {
|
|
1269
|
+
headers: { Authorization: _auth('user-1') },
|
|
1270
|
+
})
|
|
1195
1271
|
expect(res.status).toBe(200)
|
|
1196
1272
|
const envs = await res.json()
|
|
1197
1273
|
expect(envs).toHaveLength(1)
|
|
@@ -2016,9 +2092,12 @@ describe('V2 Worker Events Routes', () => {
|
|
|
2016
2092
|
})
|
|
2017
2093
|
|
|
2018
2094
|
test('GET /v1/code/sessions/:id/worker/events/stream — normalizes web permission approvals to control_response', async () => {
|
|
2019
|
-
const createRes = await app.request('/web/sessions
|
|
2095
|
+
const createRes = await app.request('/web/sessions', {
|
|
2020
2096
|
method: 'POST',
|
|
2021
|
-
headers: {
|
|
2097
|
+
headers: {
|
|
2098
|
+
Authorization: _auth('user-1'),
|
|
2099
|
+
'Content-Type': 'application/json',
|
|
2100
|
+
},
|
|
2022
2101
|
body: JSON.stringify({}),
|
|
2023
2102
|
})
|
|
2024
2103
|
const { id } = await createRes.json()
|
|
@@ -2037,18 +2116,18 @@ describe('V2 Worker Events Routes', () => {
|
|
|
2037
2116
|
|
|
2038
2117
|
await reader.read() // initial keepalive
|
|
2039
2118
|
|
|
2040
|
-
const controlRes = await app.request(
|
|
2041
|
-
|
|
2042
|
-
{
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
body: JSON.stringify({
|
|
2046
|
-
type: 'permission_response',
|
|
2047
|
-
approved: true,
|
|
2048
|
-
request_id: 'req-1',
|
|
2049
|
-
}),
|
|
2119
|
+
const controlRes = await app.request(`/web/sessions/${id}/control`, {
|
|
2120
|
+
method: 'POST',
|
|
2121
|
+
headers: {
|
|
2122
|
+
Authorization: _auth('user-1'),
|
|
2123
|
+
'Content-Type': 'application/json',
|
|
2050
2124
|
},
|
|
2051
|
-
|
|
2125
|
+
body: JSON.stringify({
|
|
2126
|
+
type: 'permission_response',
|
|
2127
|
+
approved: true,
|
|
2128
|
+
request_id: 'req-1',
|
|
2129
|
+
}),
|
|
2130
|
+
})
|
|
2052
2131
|
expect(controlRes.status).toBe(200)
|
|
2053
2132
|
|
|
2054
2133
|
const chunk = await reader.read()
|
|
@@ -2062,9 +2141,12 @@ describe('V2 Worker Events Routes', () => {
|
|
|
2062
2141
|
})
|
|
2063
2142
|
|
|
2064
2143
|
test('GET /v1/code/sessions/:id/worker/events/stream — normalizes web plan rejection feedback to deny control_response', async () => {
|
|
2065
|
-
const createRes = await app.request('/web/sessions
|
|
2144
|
+
const createRes = await app.request('/web/sessions', {
|
|
2066
2145
|
method: 'POST',
|
|
2067
|
-
headers: {
|
|
2146
|
+
headers: {
|
|
2147
|
+
Authorization: _auth('user-1'),
|
|
2148
|
+
'Content-Type': 'application/json',
|
|
2149
|
+
},
|
|
2068
2150
|
body: JSON.stringify({}),
|
|
2069
2151
|
})
|
|
2070
2152
|
const { id } = await createRes.json()
|
|
@@ -2083,19 +2165,19 @@ describe('V2 Worker Events Routes', () => {
|
|
|
2083
2165
|
|
|
2084
2166
|
await reader.read() // initial keepalive
|
|
2085
2167
|
|
|
2086
|
-
const controlRes = await app.request(
|
|
2087
|
-
|
|
2088
|
-
{
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
body: JSON.stringify({
|
|
2092
|
-
type: 'permission_response',
|
|
2093
|
-
approved: false,
|
|
2094
|
-
request_id: 'req-2',
|
|
2095
|
-
message: 'Need more detail',
|
|
2096
|
-
}),
|
|
2168
|
+
const controlRes = await app.request(`/web/sessions/${id}/control`, {
|
|
2169
|
+
method: 'POST',
|
|
2170
|
+
headers: {
|
|
2171
|
+
Authorization: _auth('user-1'),
|
|
2172
|
+
'Content-Type': 'application/json',
|
|
2097
2173
|
},
|
|
2098
|
-
|
|
2174
|
+
body: JSON.stringify({
|
|
2175
|
+
type: 'permission_response',
|
|
2176
|
+
approved: false,
|
|
2177
|
+
request_id: 'req-2',
|
|
2178
|
+
message: 'Need more detail',
|
|
2179
|
+
}),
|
|
2180
|
+
})
|
|
2099
2181
|
expect(controlRes.status).toBe(200)
|
|
2100
2182
|
|
|
2101
2183
|
const chunk = await reader.read()
|
|
@@ -2111,9 +2193,12 @@ describe('V2 Worker Events Routes', () => {
|
|
|
2111
2193
|
})
|
|
2112
2194
|
|
|
2113
2195
|
test('GET /v1/code/sessions/:id/worker/events/stream — normalizes web interrupts to control_request', async () => {
|
|
2114
|
-
const createRes = await app.request('/web/sessions
|
|
2196
|
+
const createRes = await app.request('/web/sessions', {
|
|
2115
2197
|
method: 'POST',
|
|
2116
|
-
headers: {
|
|
2198
|
+
headers: {
|
|
2199
|
+
Authorization: _auth('user-1'),
|
|
2200
|
+
'Content-Type': 'application/json',
|
|
2201
|
+
},
|
|
2117
2202
|
body: JSON.stringify({}),
|
|
2118
2203
|
})
|
|
2119
2204
|
const { id } = await createRes.json()
|
|
@@ -2132,13 +2217,13 @@ describe('V2 Worker Events Routes', () => {
|
|
|
2132
2217
|
|
|
2133
2218
|
await reader.read() // initial keepalive
|
|
2134
2219
|
|
|
2135
|
-
const interruptRes = await app.request(
|
|
2136
|
-
|
|
2137
|
-
{
|
|
2138
|
-
|
|
2139
|
-
|
|
2220
|
+
const interruptRes = await app.request(`/web/sessions/${id}/interrupt`, {
|
|
2221
|
+
method: 'POST',
|
|
2222
|
+
headers: {
|
|
2223
|
+
Authorization: _auth('user-1'),
|
|
2224
|
+
'Content-Type': 'application/json',
|
|
2140
2225
|
},
|
|
2141
|
-
)
|
|
2226
|
+
})
|
|
2142
2227
|
expect(interruptRes.status).toBe(200)
|
|
2143
2228
|
|
|
2144
2229
|
const chunk = await reader.read()
|