@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
|
@@ -27,19 +27,17 @@ function toResponse(row: EnvironmentRecord): EnvironmentResponse {
|
|
|
27
27
|
worker_type: row.workerType,
|
|
28
28
|
channel_group_id: row.bridgeId,
|
|
29
29
|
capabilities: row.capabilities,
|
|
30
|
-
has_worker_token: row.workerTokenHash !== null,
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
export function registerEnvironment(
|
|
35
34
|
req: RegisterEnvironmentRequest & {
|
|
36
|
-
metadata?: { worker_type?: string
|
|
35
|
+
metadata?: { worker_type?: string }
|
|
37
36
|
username?: string
|
|
38
37
|
},
|
|
39
38
|
) {
|
|
40
39
|
const secret = config.apiKeys[0] || ''
|
|
41
40
|
const workerType = req.worker_type || req.metadata?.worker_type
|
|
42
|
-
const workerTokenHash = req.metadata?.worker_token_hash ?? null
|
|
43
41
|
|
|
44
42
|
// ACP agents with a bridge_id (channel group): reuse the most recent
|
|
45
43
|
// offline env in the same group instead of creating a new one on every
|
|
@@ -92,7 +90,6 @@ export function registerEnvironment(
|
|
|
92
90
|
gitRepoUrl: req.git_repo_url,
|
|
93
91
|
maxSessions: req.max_sessions,
|
|
94
92
|
workerType,
|
|
95
|
-
workerTokenHash,
|
|
96
93
|
bridgeId: req.bridge_id,
|
|
97
94
|
username: req.username,
|
|
98
95
|
capabilities: req.capabilities,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Database } from 'bun:sqlite'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* List all sessions visible to a given user.
|
|
5
|
+
*
|
|
6
|
+
* Visibility rules:
|
|
7
|
+
* 1. System admin (users.role = 'admin') → sees everything including orphans
|
|
8
|
+
* 2. Sessions owned by the user (owner_type='user', owner_id=userId)
|
|
9
|
+
* 3. Sessions owned by a team the user belongs to, with visibility='team' or 'public'
|
|
10
|
+
* 4. Sessions explicitly shared with the user via session_shares
|
|
11
|
+
* 5. Sessions explicitly shared with a team the user belongs to via session_shares
|
|
12
|
+
* 6. Sessions with visibility='public' (anyone can see)
|
|
13
|
+
* 7. Orphan sessions (no owner) → only admin visible
|
|
14
|
+
*/
|
|
15
|
+
export function storeListSessionsVisibleToUser(
|
|
16
|
+
userId: string,
|
|
17
|
+
db: Database,
|
|
18
|
+
): Array<Record<string, unknown>> {
|
|
19
|
+
// Check if user is a system admin
|
|
20
|
+
const userRow = db
|
|
21
|
+
.query('SELECT role FROM users WHERE id = $userId')
|
|
22
|
+
.get({ $userId: userId }) as { role: string } | null
|
|
23
|
+
|
|
24
|
+
const isSystemAdmin = userRow?.role === 'admin'
|
|
25
|
+
|
|
26
|
+
if (isSystemAdmin) {
|
|
27
|
+
// Admin sees all sessions
|
|
28
|
+
return db.query('SELECT * FROM sessions').all() as Array<
|
|
29
|
+
Record<string, unknown>
|
|
30
|
+
>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Build a query that unions all visibility rules
|
|
34
|
+
// Note: expires_at is stored as ISO 8601 (e.g. "2026-07-21T12:00:00.000Z"),
|
|
35
|
+
// so we use strftime to produce a comparable ISO string for "now".
|
|
36
|
+
const sql = `
|
|
37
|
+
SELECT DISTINCT s.* FROM sessions s
|
|
38
|
+
WHERE
|
|
39
|
+
-- Rule 2: owned by user
|
|
40
|
+
EXISTS (
|
|
41
|
+
SELECT 1 FROM session_owners so
|
|
42
|
+
WHERE so.session_id = s.id
|
|
43
|
+
AND so.owner_type = 'user'
|
|
44
|
+
AND so.owner_id = $userId
|
|
45
|
+
)
|
|
46
|
+
-- Rule 3: owned by user's team + visibility team/public
|
|
47
|
+
OR (
|
|
48
|
+
s.visibility IN ('team', 'public')
|
|
49
|
+
AND EXISTS (
|
|
50
|
+
SELECT 1 FROM session_owners so
|
|
51
|
+
JOIN team_members tm ON tm.team_id = so.owner_id
|
|
52
|
+
WHERE so.session_id = s.id
|
|
53
|
+
AND so.owner_type = 'team'
|
|
54
|
+
AND tm.user_id = $userId
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
-- Rule 4: explicitly shared with user (non-expired)
|
|
58
|
+
OR EXISTS (
|
|
59
|
+
SELECT 1 FROM session_shares ss
|
|
60
|
+
WHERE ss.session_id = s.id
|
|
61
|
+
AND ss.granted_to_user = $userId
|
|
62
|
+
AND (ss.expires_at IS NULL OR ss.expires_at > strftime('%Y-%m-%dT%H:%M:%S.000Z', 'now'))
|
|
63
|
+
)
|
|
64
|
+
-- Rule 5: shared with a team the user belongs to (non-expired)
|
|
65
|
+
OR EXISTS (
|
|
66
|
+
SELECT 1 FROM session_shares ss
|
|
67
|
+
JOIN team_members tm ON tm.team_id = ss.granted_to_team
|
|
68
|
+
WHERE ss.session_id = s.id
|
|
69
|
+
AND tm.user_id = $userId
|
|
70
|
+
AND (ss.expires_at IS NULL OR ss.expires_at > strftime('%Y-%m-%dT%H:%M:%S.000Z', 'now'))
|
|
71
|
+
)
|
|
72
|
+
-- Rule 6: public visibility
|
|
73
|
+
OR s.visibility = 'public'
|
|
74
|
+
`
|
|
75
|
+
|
|
76
|
+
return db.query(sql).all({ $userId: userId }) as Array<
|
|
77
|
+
Record<string, unknown>
|
|
78
|
+
>
|
|
79
|
+
}
|
|
@@ -3,8 +3,6 @@ import {
|
|
|
3
3
|
storeGetSession,
|
|
4
4
|
storeGetEnvironment,
|
|
5
5
|
storeIsSessionOwner,
|
|
6
|
-
storeGetSessionOwners,
|
|
7
|
-
storeBindSession,
|
|
8
6
|
storeUpdateSession,
|
|
9
7
|
storeListSessions,
|
|
10
8
|
storeListSessionsByUsername,
|
|
@@ -141,16 +139,6 @@ export function resolveOwnedWebSessionId(
|
|
|
141
139
|
return compatibleCodeSessionId
|
|
142
140
|
}
|
|
143
141
|
|
|
144
|
-
// Auto-bind: if the session exists but has no owner, claim it for the requesting user
|
|
145
|
-
const existingId = resolveExistingSessionId(sessionId)
|
|
146
|
-
if (existingId) {
|
|
147
|
-
const owners = storeGetSessionOwners(existingId)
|
|
148
|
-
if (!owners || owners.size === 0) {
|
|
149
|
-
storeBindSession(existingId, uuid)
|
|
150
|
-
return existingId
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
142
|
return null
|
|
155
143
|
}
|
|
156
144
|
|
|
@@ -245,7 +233,6 @@ function toSummaryResponse(row: {
|
|
|
245
233
|
environment = {
|
|
246
234
|
id: env.id,
|
|
247
235
|
machine_name: env.machineName,
|
|
248
|
-
has_worker_token: env.workerTokenHash !== null,
|
|
249
236
|
worker_type: env.workerType,
|
|
250
237
|
}
|
|
251
238
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto'
|
|
1
|
+
import { randomUUID, createHash } from 'node:crypto'
|
|
2
|
+
import { getDb } from './db/sqlite'
|
|
2
3
|
|
|
3
4
|
// ---------- Types ----------
|
|
4
5
|
|
|
@@ -16,11 +17,6 @@ export interface EnvironmentRecord {
|
|
|
16
17
|
gitRepoUrl: string | null
|
|
17
18
|
maxSessions: number
|
|
18
19
|
workerType: string
|
|
19
|
-
// SHA256 hash of the per-environment worker access token (RCS_WORKER_TOKENS).
|
|
20
|
-
// Web UI users must enter the matching plaintext token to connect to this
|
|
21
|
-
// environment's sessions. Null when the worker didn't register a token
|
|
22
|
-
// (legacy/claude.ai path) — in that case sessions are open access.
|
|
23
|
-
workerTokenHash: string | null
|
|
24
20
|
bridgeId: string | null
|
|
25
21
|
capabilities: Record<string, unknown> | null
|
|
26
22
|
status: string
|
|
@@ -76,8 +72,7 @@ const sessions = new Map<string, SessionRecord>()
|
|
|
76
72
|
const workItems = new Map<string, WorkItemRecord>()
|
|
77
73
|
const sessionWorkers = new Map<string, SessionWorkerRecord>()
|
|
78
74
|
|
|
79
|
-
//
|
|
80
|
-
const sessionOwners = new Map<string, Set<string>>()
|
|
75
|
+
// Session ownership tracked in SQLite session_owners table
|
|
81
76
|
|
|
82
77
|
// ---------- User ----------
|
|
83
78
|
|
|
@@ -117,7 +112,6 @@ export function storeCreateEnvironment(req: {
|
|
|
117
112
|
gitRepoUrl?: string
|
|
118
113
|
maxSessions?: number
|
|
119
114
|
workerType?: string
|
|
120
|
-
workerTokenHash?: string | null
|
|
121
115
|
bridgeId?: string
|
|
122
116
|
username?: string
|
|
123
117
|
capabilities?: Record<string, unknown>
|
|
@@ -133,7 +127,6 @@ export function storeCreateEnvironment(req: {
|
|
|
133
127
|
gitRepoUrl: req.gitRepoUrl ?? null,
|
|
134
128
|
maxSessions: req.maxSessions ?? 1,
|
|
135
129
|
workerType: req.workerType ?? 'claude_code',
|
|
136
|
-
workerTokenHash: req.workerTokenHash ?? null,
|
|
137
130
|
bridgeId: req.bridgeId ?? null,
|
|
138
131
|
capabilities: req.capabilities ?? null,
|
|
139
132
|
status: 'active',
|
|
@@ -143,6 +136,25 @@ export function storeCreateEnvironment(req: {
|
|
|
143
136
|
updatedAt: now,
|
|
144
137
|
}
|
|
145
138
|
environments.set(id, record)
|
|
139
|
+
try {
|
|
140
|
+
const db = getDb()
|
|
141
|
+
const secretHash = createHash('sha256').update(record.secret).digest('hex')
|
|
142
|
+
db.query(
|
|
143
|
+
`INSERT OR REPLACE INTO environments (id, secret_hash, machine_name, worker_type, status, last_poll_at, created_at)
|
|
144
|
+
VALUES ($id, $sh, $mn, $wt, $st, $lp, $ca)`,
|
|
145
|
+
).run({
|
|
146
|
+
$id: id,
|
|
147
|
+
$sh: secretHash,
|
|
148
|
+
$mn: record.machineName,
|
|
149
|
+
$wt: record.workerType,
|
|
150
|
+
$st: record.status,
|
|
151
|
+
$lp: record.lastPollAt?.toISOString() ?? null,
|
|
152
|
+
$ca: record.createdAt.toISOString(),
|
|
153
|
+
})
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.error('[store] DB write failed in storeCreateEnvironment:', err)
|
|
156
|
+
throw err
|
|
157
|
+
}
|
|
146
158
|
return record
|
|
147
159
|
}
|
|
148
160
|
|
|
@@ -208,6 +220,26 @@ export function storeCreateSession(req: {
|
|
|
208
220
|
updatedAt: now,
|
|
209
221
|
}
|
|
210
222
|
sessions.set(id, record)
|
|
223
|
+
try {
|
|
224
|
+
const db = getDb()
|
|
225
|
+
db.query(
|
|
226
|
+
`INSERT OR REPLACE INTO sessions (id, environment_id, title, status, source, visibility, permission_mode, created_at, updated_at)
|
|
227
|
+
VALUES ($id, $eid, $title, $status, $source, $vis, $pm, $ca, $ua)`,
|
|
228
|
+
).run({
|
|
229
|
+
$id: id,
|
|
230
|
+
$eid: record.environmentId,
|
|
231
|
+
$title: record.title,
|
|
232
|
+
$status: record.status,
|
|
233
|
+
$source: record.source,
|
|
234
|
+
$vis: 'private',
|
|
235
|
+
$pm: record.permissionMode,
|
|
236
|
+
$ca: record.createdAt.toISOString(),
|
|
237
|
+
$ua: record.updatedAt.toISOString(),
|
|
238
|
+
})
|
|
239
|
+
} catch (err) {
|
|
240
|
+
console.error('[store] DB write failed in storeCreateSession:', err)
|
|
241
|
+
throw err
|
|
242
|
+
}
|
|
211
243
|
return record
|
|
212
244
|
}
|
|
213
245
|
|
|
@@ -224,6 +256,19 @@ export function storeUpdateSession(
|
|
|
224
256
|
const rec = sessions.get(id)
|
|
225
257
|
if (!rec) return false
|
|
226
258
|
Object.assign(rec, patch, { updatedAt: new Date() })
|
|
259
|
+
try {
|
|
260
|
+
const db = getDb()
|
|
261
|
+
db.query(
|
|
262
|
+
`UPDATE sessions SET title = COALESCE($title, title), status = COALESCE($status, status), updated_at = $ua WHERE id = $id`,
|
|
263
|
+
).run({
|
|
264
|
+
$id: id,
|
|
265
|
+
$title: patch.title ?? null,
|
|
266
|
+
$status: patch.status ?? null,
|
|
267
|
+
$ua: rec.updatedAt.toISOString(),
|
|
268
|
+
})
|
|
269
|
+
} catch (err) {
|
|
270
|
+
console.error('[store] DB write failed in storeUpdateSession:', err)
|
|
271
|
+
}
|
|
227
272
|
return true
|
|
228
273
|
}
|
|
229
274
|
|
|
@@ -241,7 +286,14 @@ export function storeListSessionsByEnvironment(envId: string): SessionRecord[] {
|
|
|
241
286
|
|
|
242
287
|
export function storeDeleteSession(id: string): boolean {
|
|
243
288
|
sessionWorkers.delete(id)
|
|
244
|
-
|
|
289
|
+
const deleted = sessions.delete(id)
|
|
290
|
+
try {
|
|
291
|
+
const db = getDb()
|
|
292
|
+
db.query('DELETE FROM sessions WHERE id = $id').run({ $id: id })
|
|
293
|
+
} catch (err) {
|
|
294
|
+
console.error('[store] DB write failed in storeDeleteSession:', err)
|
|
295
|
+
}
|
|
296
|
+
return deleted
|
|
245
297
|
}
|
|
246
298
|
|
|
247
299
|
// ---------- Session Worker ----------
|
|
@@ -300,72 +352,99 @@ export function storeUpsertSessionWorker(
|
|
|
300
352
|
|
|
301
353
|
// ---------- Work Items ----------
|
|
302
354
|
|
|
303
|
-
// ---------- Session Ownership (
|
|
355
|
+
// ---------- Session Ownership (SQLite-backed) ----------
|
|
304
356
|
|
|
305
|
-
export function storeBindSession(
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
357
|
+
export function storeBindSession(
|
|
358
|
+
sessionId: string,
|
|
359
|
+
ownerId: string,
|
|
360
|
+
ownerType: 'user' | 'team' = 'user',
|
|
361
|
+
): void {
|
|
362
|
+
try {
|
|
363
|
+
const db = getDb()
|
|
364
|
+
db.query(
|
|
365
|
+
`INSERT OR IGNORE INTO session_owners (session_id, owner_type, owner_id)
|
|
366
|
+
VALUES ($sessionId, $ownerType, $ownerId)`,
|
|
367
|
+
).run({
|
|
368
|
+
$sessionId: sessionId,
|
|
369
|
+
$ownerType: ownerType,
|
|
370
|
+
$ownerId: ownerId,
|
|
371
|
+
})
|
|
372
|
+
} catch (err) {
|
|
373
|
+
console.error('[store] DB write failed in storeBindSession:', err)
|
|
374
|
+
throw err
|
|
310
375
|
}
|
|
311
|
-
owners.add(uuid)
|
|
312
376
|
}
|
|
313
377
|
|
|
314
378
|
export function storeIsSessionOwner(sessionId: string, uuid: string): boolean {
|
|
315
|
-
|
|
316
|
-
|
|
379
|
+
try {
|
|
380
|
+
const db = getDb()
|
|
381
|
+
const row = db
|
|
382
|
+
.query(
|
|
383
|
+
`SELECT 1 FROM session_owners
|
|
384
|
+
WHERE session_id = $sessionId AND owner_id = $ownerId
|
|
385
|
+
LIMIT 1`,
|
|
386
|
+
)
|
|
387
|
+
.get({ $sessionId: sessionId, $ownerId: uuid })
|
|
388
|
+
return !!row
|
|
389
|
+
} catch (err) {
|
|
390
|
+
console.error('[store] DB read failed in storeIsSessionOwner:', err)
|
|
391
|
+
return false
|
|
392
|
+
}
|
|
317
393
|
}
|
|
318
394
|
|
|
319
395
|
export function storeGetSessionOwners(
|
|
320
396
|
sessionId: string,
|
|
321
397
|
): Set<string> | undefined {
|
|
322
|
-
|
|
398
|
+
try {
|
|
399
|
+
const db = getDb()
|
|
400
|
+
const rows = db
|
|
401
|
+
.query(
|
|
402
|
+
`SELECT owner_id FROM session_owners WHERE session_id = $sessionId`,
|
|
403
|
+
)
|
|
404
|
+
.all({ $sessionId: sessionId }) as Array<{ owner_id: string }>
|
|
405
|
+
if (rows.length === 0) return undefined
|
|
406
|
+
return new Set(rows.map(r => r.owner_id))
|
|
407
|
+
} catch (err) {
|
|
408
|
+
console.error('[store] DB read failed in storeGetSessionOwners:', err)
|
|
409
|
+
return undefined
|
|
410
|
+
}
|
|
323
411
|
}
|
|
324
412
|
|
|
325
413
|
export function storeListSessionsByOwnerUuid(uuid: string): SessionRecord[] {
|
|
326
414
|
const result: SessionRecord[] = []
|
|
327
415
|
const resultIds = new Set<string>()
|
|
328
416
|
|
|
329
|
-
// Collect sessions
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
417
|
+
// Collect sessions owned by this user from SQLite
|
|
418
|
+
try {
|
|
419
|
+
const db = getDb()
|
|
420
|
+
const ownedRows = db
|
|
421
|
+
.query(`SELECT session_id FROM session_owners WHERE owner_id = $ownerId`)
|
|
422
|
+
.all({ $ownerId: uuid }) as Array<{ session_id: string }>
|
|
423
|
+
for (const row of ownedRows) {
|
|
424
|
+
const session = sessions.get(row.session_id)
|
|
333
425
|
if (session) {
|
|
334
426
|
result.push(session)
|
|
335
|
-
resultIds.add(
|
|
427
|
+
resultIds.add(row.session_id)
|
|
336
428
|
}
|
|
337
429
|
}
|
|
338
|
-
}
|
|
339
430
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
result.push(session)
|
|
352
|
-
resultIds.add(sessionId)
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Auto-bind orphaned non-ACP sessions (no owner — typically native RCS
|
|
357
|
-
// worker sessions created via REST without a user context)
|
|
358
|
-
for (const [sessionId, session] of sessions) {
|
|
359
|
-
if (resultIds.has(sessionId)) continue
|
|
360
|
-
if (session.source === 'acp') continue // already handled above
|
|
361
|
-
const owners = sessionOwners.get(sessionId)
|
|
362
|
-
// No owners map entry at all, or empty owners set
|
|
363
|
-
const isOrphaned = !owners || owners.size === 0
|
|
364
|
-
if (isOrphaned) {
|
|
365
|
-
storeBindSession(sessionId, uuid)
|
|
366
|
-
result.push(session)
|
|
367
|
-
resultIds.add(sessionId)
|
|
431
|
+
// Include public sessions
|
|
432
|
+
const publicRows = db
|
|
433
|
+
.query(`SELECT id FROM sessions WHERE visibility = 'public'`)
|
|
434
|
+
.all() as Array<{ id: string }>
|
|
435
|
+
for (const row of publicRows) {
|
|
436
|
+
if (resultIds.has(row.id)) continue
|
|
437
|
+
const session = sessions.get(row.id)
|
|
438
|
+
if (session) {
|
|
439
|
+
result.push(session)
|
|
440
|
+
resultIds.add(row.id)
|
|
441
|
+
}
|
|
368
442
|
}
|
|
443
|
+
} catch (err) {
|
|
444
|
+
console.error(
|
|
445
|
+
'[store] DB read failed in storeListSessionsByOwnerUuid:',
|
|
446
|
+
err,
|
|
447
|
+
)
|
|
369
448
|
}
|
|
370
449
|
|
|
371
450
|
return result
|
|
@@ -488,5 +567,20 @@ export function storeReset() {
|
|
|
488
567
|
sessions.clear()
|
|
489
568
|
workItems.clear()
|
|
490
569
|
sessionWorkers.clear()
|
|
491
|
-
|
|
570
|
+
try {
|
|
571
|
+
const db = getDb()
|
|
572
|
+
// Delete in FK-safe order: child tables before parent tables
|
|
573
|
+
db.query('DELETE FROM session_tokens').run()
|
|
574
|
+
db.query('DELETE FROM session_owners').run()
|
|
575
|
+
db.query('DELETE FROM session_shares').run()
|
|
576
|
+
db.query('DELETE FROM team_members').run()
|
|
577
|
+
db.query('DELETE FROM team_environments').run()
|
|
578
|
+
db.query('DELETE FROM invitations').run()
|
|
579
|
+
db.query('DELETE FROM sessions').run()
|
|
580
|
+
db.query('DELETE FROM environments').run()
|
|
581
|
+
db.query('DELETE FROM teams').run()
|
|
582
|
+
db.query('DELETE FROM users').run()
|
|
583
|
+
} catch (err) {
|
|
584
|
+
console.error('[store] DB cleanup failed in storeReset:', err)
|
|
585
|
+
}
|
|
492
586
|
}
|
|
@@ -5,6 +5,8 @@ declare module 'hono' {
|
|
|
5
5
|
interface ContextVariableMap {
|
|
6
6
|
username?: string
|
|
7
7
|
uuid?: string
|
|
8
|
+
userId?: string
|
|
9
|
+
isAdmin?: boolean
|
|
8
10
|
jwtPayload?: { session_id: string; role: string; iat: number; exp: number }
|
|
9
11
|
}
|
|
10
12
|
}
|
|
@@ -95,7 +97,6 @@ export interface SessionWorkItemInfo {
|
|
|
95
97
|
export interface SessionEnvironmentInfo {
|
|
96
98
|
id: string
|
|
97
99
|
machine_name: string | null
|
|
98
|
-
has_worker_token: boolean
|
|
99
100
|
worker_type: string
|
|
100
101
|
}
|
|
101
102
|
|
|
@@ -134,7 +135,6 @@ export interface EnvironmentResponse {
|
|
|
134
135
|
worker_type?: string
|
|
135
136
|
channel_group_id?: string | null
|
|
136
137
|
capabilities?: Record<string, unknown> | null
|
|
137
|
-
has_worker_token?: boolean
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
export interface ServerInfoResponse {
|
|
@@ -146,11 +146,6 @@ export interface ServerInfoResponse {
|
|
|
146
146
|
sessions_active: number
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
export interface TestWorkerTokenResponse {
|
|
150
|
-
valid: boolean
|
|
151
|
-
env_id: string
|
|
152
|
-
}
|
|
153
|
-
|
|
154
149
|
export interface SessionSummaryResponse {
|
|
155
150
|
id: string
|
|
156
151
|
title: string | null
|
|
@@ -161,7 +156,6 @@ export interface SessionSummaryResponse {
|
|
|
161
156
|
environment: {
|
|
162
157
|
id: string
|
|
163
158
|
machine_name: string | null
|
|
164
|
-
has_worker_token: boolean
|
|
165
159
|
worker_type: string
|
|
166
160
|
} | null
|
|
167
161
|
updated_at: number
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,e as l}from"./vendor-DE_-CLIE.js";import{h as y,E as N,m as v,o as w,p as k,n as C}from"./main-30YqUvTd.js";import{g as j,D as S,a as _,c as D,d as E,b as L}from"./workerType-OM09y7Lk.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function M({environments:o,onSelectEnvironment:c}){return!o||o.length===0?e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-8 text-center text-text-muted",children:"No active environments"}):e.jsx("div",{className:"space-y-2",children:o.map(r=>{const i=r.worker_type==="acp",d=j(r.worker_type),m=d.fullLabel,t=d.colorClass;return e.jsxs("button",{type:"button",onClick:()=>c==null?void 0:c(r),disabled:i,className:`flex w-full items-center justify-between rounded-xl border border-border bg-surface-1 px-4 py-3 text-left transition-colors ${i?"cursor-default opacity-80":"hover:border-border-light cursor-pointer"}`,children:[e.jsx("div",{className:"flex items-center gap-3",children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text-primary",children:r.machine_name||r.id}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${t}`,children:m})]}),e.jsx("div",{className:"text-sm text-text-muted",children:r.directory||""})]})}),e.jsxs("div",{className:"text-right",children:[e.jsx(y,{status:r.status}),e.jsx("div",{className:"mt-1 text-xs text-text-muted",children:r.branch||""})]})]},r.id)})})}function T({sessions:o,environments:c,onSelect:r,onDelete:i}){if(!o||o.length===0)return e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-8 text-center text-text-muted",children:"No sessions"});const d=new Map;for(const t of c??[])t!=null&&t.id&&t.worker_type&&d.set(t.id,t.worker_type);const m=[...o].sort((t,n)=>(n.updated_at||0)-(t.updated_at||0));return e.jsx("div",{className:"space-y-2",children:m.map(t=>e.jsxs("div",{className:"group flex w-full items-center justify-between rounded-xl border border-border bg-surface-1 px-4 py-3 text-left transition-colors hover:border-border-light hover:bg-surface-2",children:[e.jsxs("button",{type:"button",onClick:()=>r(t.id),className:"min-w-0 flex-1 text-left",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium text-text-primary",children:t.title||t.id}),(()=>{var p;let n=t.source==="acp"?"acp":(p=t.environment)==null?void 0:p.worker_type;!n&&t.environment_id&&(n=d.get(t.environment_id));const u=j(n);return e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${u.colorClass}`,children:u.fullLabel})})()]}),e.jsx("div",{className:"truncate text-xs text-text-muted",children:t.id})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(y,{status:t.status}),e.jsx("span",{className:"text-xs text-text-muted",children:N(t.created_at||t.updated_at)}),i&&e.jsx("button",{type:"button",onClick:n=>{n.stopPropagation(),i(t.id)},className:"rounded p-1 text-text-muted opacity-0 transition-all hover:text-status-error group-hover:opacity-100",title:"Delete session",children:e.jsx("svg",{className:"h-4 w-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})]},t.id))})}function F({open:o,environments:c,onClose:r,onCreated:i}){const[d,m]=l.useState(""),[t,n]=l.useState(""),[u,p]=l.useState("same-dir"),[b,h]=l.useState(""),[a,x]=l.useState(!1);l.useEffect(()=>{o&&(m(""),n(""),p("same-dir"),h(""))},[o]);const f=async()=>{x(!0),h("");try{const s={};d.trim()&&(s.title=d.trim()),t&&(s.environment_id=t),s.spawn_mode=u;const g=await v(s);i(g)}catch(s){h(s instanceof Error?s.message:"Failed to create session")}finally{x(!1)}};return e.jsx(S,{open:o,onOpenChange:s=>{s||r()},children:e.jsxs(_,{className:"max-w-md rounded-2xl border-border bg-surface-1 p-6 shadow-2xl",children:[e.jsx(D,{children:e.jsx(E,{className:"font-display text-lg font-semibold text-text-primary",children:"New Session"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm text-text-secondary",children:"Title (optional)"}),e.jsx("input",{type:"text",value:d,onChange:s=>m(s.target.value),placeholder:"My session",className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:border-brand focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm text-text-secondary",children:"Environment"}),e.jsxs("select",{value:t,onChange:s=>n(s.target.value),className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-brand focus:outline-none",children:[e.jsx("option",{value:"",children:"-- None --"}),c.map(s=>{const g=j(s.worker_type).shortLabel;return e.jsxs("option",{value:s.id,children:[s.machine_name||s.id," (",s.branch||"no branch",") · ",g]},s.id)})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm text-text-secondary",children:"Workspace Mode"}),e.jsxs("select",{value:u,onChange:s=>p(s.target.value),className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-brand focus:outline-none",children:[e.jsx("option",{value:"same-dir",children:"工作区 (same-dir) — sessions share the directory"}),e.jsx("option",{value:"worktree",children:"工作树 (worktree) — each session gets an isolated git worktree"})]})]}),b&&e.jsx("div",{className:"text-sm text-status-error",children:b})]}),e.jsxs(L,{children:[e.jsx("button",{onClick:r,className:"rounded-lg border border-border px-4 py-2 text-sm text-text-secondary hover:bg-surface-2 transition-colors",children:"Cancel"}),e.jsx("button",{onClick:f,disabled:a,className:"rounded-lg bg-brand px-4 py-2 text-sm font-medium text-white hover:bg-brand-light disabled:opacity-50 transition-colors",children:a?"Creating...":"Create"})]})]})})}function A({onNavigateSession:o}){const[c,r]=l.useState([]),[i,d]=l.useState([]),[m,t]=l.useState(!1),n=l.useCallback(async()=>{try{const[a,x]=await Promise.all([w(),k()]);r(a||[]),d(x||[])}catch(a){console.error("Dashboard render error:",a)}},[]);l.useEffect(()=>{n();const a=setInterval(n,1e4);return()=>clearInterval(a)},[n]);const u=a=>{t(!1),o(a.id)},p=l.useCallback(a=>{},[]),b=l.useCallback(a=>{o(a)},[o]),h=l.useCallback(async a=>{if(window.confirm(`删除会话 ${a}?此操作不可恢复。`))try{await C(a),r(x=>x.filter(f=>f.id!==a))}catch(x){alert(x instanceof Error?x.message:"Failed to delete session")}},[]);return e.jsxs("div",{className:"mx-auto max-w-5xl px-4 py-8",children:[e.jsx("h1",{className:"sr-only",children:"Dashboard"}),e.jsxs("section",{className:"mb-10",children:[e.jsx("h2",{className:"mb-4 font-display text-lg font-semibold text-text-primary",children:"Environments"}),e.jsx(M,{environments:i,onSelectEnvironment:p})]}),e.jsxs("section",{children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between",children:[e.jsx("h2",{className:"font-display text-lg font-semibold text-text-primary",children:"Sessions"}),e.jsx("button",{onClick:()=>t(!0),className:"rounded-lg bg-brand px-3 py-1.5 text-sm font-medium text-white hover:bg-brand-light transition-colors",children:"+ New Session"})]}),e.jsx(T,{sessions:c,environments:i,onSelect:b,onDelete:h})]}),e.jsx(F,{open:m,environments:i,onClose:()=>t(!1),onCreated:u})]})}export{A as Dashboard};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as r,j as e}from"./vendor-DE_-CLIE.js";import{M as v}from"./main-30YqUvTd.js";import{t}from"./i18n-Dbt-vEQ3.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function P({onSuccess:b,onInvalidInvite:l}){const{join:f}=v(),[u,h]=r.useState(""),[d,j]=r.useState(""),[o,w]=r.useState(""),[c,g]=r.useState(""),[m,n]=r.useState(""),[x,p]=r.useState(!1);r.useEffect(()=>{const a=new URLSearchParams(window.location.search).get("invite");a?h(a):l()},[l]);const y=async s=>{if(s.preventDefault(),n(""),o.length<8){n(t("auth.setup.passwordTooShort"));return}if(o!==c){n(t("auth.setup.passwordMismatch"));return}p(!0);try{await f(u,d,o),b()}catch(a){const i=a instanceof Error?a.message:"Join failed";if(i.includes("Invalid invitation")||i.includes("expired")||i.includes("already used")){l();return}n(i)}finally{p(!1)}};return e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-surface-0 px-4",children:e.jsxs("div",{className:"w-full max-w-sm space-y-6",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("h1",{className:"font-display text-2xl font-semibold text-text-primary",children:t("auth.join.title")}),e.jsx("p",{className:"mt-2 text-sm text-text-muted",children:t("auth.join.welcome")}),e.jsx("p",{className:"mt-1 text-sm text-text-muted",children:t("auth.join.description")})]}),e.jsxs("form",{onSubmit:y,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-text-secondary",children:t("auth.join.username")}),e.jsx("input",{type:"text",value:d,onChange:s=>j(s.target.value),required:!0,autoComplete:"username",autoFocus:!0,className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:border-brand focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-text-secondary",children:t("auth.join.password")}),e.jsx("input",{type:"password",value:o,onChange:s=>w(s.target.value),required:!0,autoComplete:"new-password",className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:border-brand focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-text-secondary",children:t("auth.join.confirmPassword")}),e.jsx("input",{type:"password",value:c,onChange:s=>g(s.target.value),required:!0,autoComplete:"new-password",className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:border-brand focus:outline-none"})]}),m&&e.jsx("p",{className:"text-sm text-status-error",children:m}),e.jsx("button",{type:"submit",disabled:x||!u,className:"w-full rounded-lg bg-brand px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-brand-light disabled:cursor-not-allowed disabled:opacity-50",children:x?t("common.loading"):t("auth.join.submit")})]})]})})}export{P as Join};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as r,j as e}from"./vendor-DE_-CLIE.js";import{M as b}from"./main-30YqUvTd.js";import{t}from"./i18n-Dbt-vEQ3.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function w({onSuccess:d}){const{login:m}=b(),[a,c]=r.useState(""),[o,x]=r.useState(""),[l,n]=r.useState(""),[i,u]=r.useState(!1),p=async s=>{s.preventDefault(),n(""),u(!0);try{await m(a,o),d()}catch{n(t("auth.login.failed"))}finally{u(!1)}};return e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-surface-0 px-4",children:e.jsxs("div",{className:"w-full max-w-sm space-y-6",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("h1",{className:"font-display text-2xl font-semibold text-text-primary",children:t("auth.login.title")}),e.jsx("p",{className:"mt-2 text-sm text-text-muted",children:t("auth.login.description")})]}),e.jsxs("form",{onSubmit:p,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-text-secondary",children:t("auth.login.username")}),e.jsx("input",{type:"text",value:a,onChange:s=>c(s.target.value),required:!0,autoComplete:"username",autoFocus:!0,className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:border-brand focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm font-medium text-text-secondary",children:t("auth.login.password")}),e.jsx("input",{type:"password",value:o,onChange:s=>x(s.target.value),required:!0,autoComplete:"current-password",className:"w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:border-brand focus:outline-none"})]}),l&&e.jsx("p",{className:"text-sm text-status-error",children:l}),e.jsx("button",{type:"submit",disabled:i,className:"w-full rounded-lg bg-brand px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-brand-light disabled:cursor-not-allowed disabled:opacity-50",children:i?t("common.loading"):t("auth.login.submit")})]})]})})}export{w as Login};
|