@saluzi/saluzi-edu 0.2.12 → 0.2.13
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 +212 -140
- package/dist/rcs-web/assets/Dashboard-YYwDrKTN.js +1 -0
- package/dist/rcs-web/assets/Join-DKCP5X6X.js +1 -0
- package/dist/rcs-web/assets/Login-0VGZs85I.js +1 -0
- package/{packages/remote-control-server/web/dist/assets/SessionDetail-DSoMXZJb.js → dist/rcs-web/assets/SessionDetail-DmK-DfBQ.js} +11 -11
- package/dist/rcs-web/assets/Setup-C0cjxXMt.js +1 -0
- package/dist/rcs-web/assets/{ShareLanding-C06U9Nrr.js → ShareLanding-DUZrreJ7.js} +1 -1
- package/dist/rcs-web/assets/TeamCreate-B8ZV6EdY.js +1 -0
- package/dist/rcs-web/assets/{TeamDetail-d_GwIRHd.js → TeamDetail-DBAsJ__i.js} +2 -2
- package/dist/rcs-web/assets/{TeamList-BlNGdKci.js → TeamList-C-Hte4nV.js} +1 -1
- package/dist/rcs-web/assets/{TeamSettings-CPraC9uS.js → TeamSettings-CNVwYwcp.js} +1 -1
- package/dist/rcs-web/assets/UserSettings-DRdz9kYE.js +1 -0
- package/dist/rcs-web/assets/{arc-BmYza-0n.js → arc-CJxirXEQ.js} +1 -1
- package/dist/rcs-web/assets/{architectureDiagram-3BPJPVTR-CYBtlgdO.js → architectureDiagram-3BPJPVTR-BZvIHrLA.js} +1 -1
- package/dist/rcs-web/assets/{blockDiagram-GPEHLZMM-RJAfHk_a.js → blockDiagram-GPEHLZMM-3p0y3Ija.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/c4Diagram-AAUBKEIU-CJ-qJA6w.js → dist/rcs-web/assets/c4Diagram-AAUBKEIU-Bmz9A1wn.js} +1 -1
- package/dist/rcs-web/assets/channel-DaI_n8dp.js +1 -0
- package/dist/rcs-web/assets/{chunk-2J33WTMH-n5I6Q1zJ.js → chunk-2J33WTMH-B8gQz22j.js} +1 -1
- package/dist/rcs-web/assets/{chunk-4BX2VUAB-CSOBh7qY.js → chunk-4BX2VUAB-CgLEZsTU.js} +1 -1
- package/dist/rcs-web/assets/{chunk-55IACEB6-C0euQVm_.js → chunk-55IACEB6-0mdE_-IS.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-Ch7yD8cR.js → dist/rcs-web/assets/chunk-727SXJPM-DdtjnIHR.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-Ms2Q7r6u.js → dist/rcs-web/assets/chunk-AQP2D5EJ-BtwFPk50.js} +1 -1
- package/dist/rcs-web/assets/{chunk-FMBD7UC4-bszHUkpx.js → chunk-FMBD7UC4-BcO9mQ0P.js} +1 -1
- package/dist/rcs-web/assets/{chunk-ND2GUHAM-BVQIhq6J.js → chunk-ND2GUHAM-BvRq13S_.js} +1 -1
- package/dist/rcs-web/assets/{chunk-QZHKN3VN-BVEDe5qc.js → chunk-QZHKN3VN-D7GHkPpq.js} +1 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-pYllpkOq.js +1 -0
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-pYllpkOq.js +1 -0
- package/dist/rcs-web/assets/{code-block-IT6T5CEO-B26n-rFC.js → code-block-IT6T5CEO-B1p-vO-3.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-DXc7GE8W.js → dist/rcs-web/assets/cose-bilkent-S5V4N54A-L0rUZuH5.js} +1 -1
- package/dist/rcs-web/assets/{dagre-BM42HDAG-DAXofHt_.js → dagre-BM42HDAG-CHGuio22.js} +1 -1
- package/dist/rcs-web/assets/{diagram-2AECGRRQ-DK0TBUQA.js → diagram-2AECGRRQ-DIDRyQk8.js} +1 -1
- package/dist/rcs-web/assets/{diagram-5GNKFQAL-DMsq-Grp.js → diagram-5GNKFQAL-CNubKb6P.js} +1 -1
- package/dist/rcs-web/assets/{diagram-KO2AKTUF-B3FMhmUc.js → diagram-KO2AKTUF-CzQh664-.js} +1 -1
- package/dist/rcs-web/assets/{diagram-LMA3HP47-BjO3BHFl.js → diagram-LMA3HP47-CWBR7-VG.js} +1 -1
- package/dist/rcs-web/assets/{diagram-OG6HWLK6-CNg4B2L3.js → diagram-OG6HWLK6-BMHdlbcZ.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-BDxz8NRK.js → dist/rcs-web/assets/erDiagram-TEJ5UH35-OgT8dC-K.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/flowDiagram-I6XJVG4X-VIgM13sK.js → dist/rcs-web/assets/flowDiagram-I6XJVG4X-DRrCY2oB.js} +1 -1
- package/dist/rcs-web/assets/{ganttDiagram-6RSMTGT7-Ba2QuJU0.js → ganttDiagram-6RSMTGT7-DctpzEKN.js} +1 -1
- package/dist/rcs-web/assets/{gitGraphDiagram-PVQCEYII-B-gV-lAg.js → gitGraphDiagram-PVQCEYII-5KpLszm9.js} +1 -1
- package/dist/rcs-web/assets/{infoDiagram-5YYISTIA-DothwgD4.js → infoDiagram-5YYISTIA-BAKD_Tt7.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-DhpjM1Vc.js → dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-VHOPG4Nc.js} +1 -1
- package/dist/rcs-web/assets/{journeyDiagram-JHISSGLW-PbQTouMJ.js → journeyDiagram-JHISSGLW-BtGih-ik.js} +1 -1
- package/dist/rcs-web/assets/{kanban-definition-UN3LZRKU-63WdwG-X.js → kanban-definition-UN3LZRKU-BsEGZsD1.js} +1 -1
- package/dist/rcs-web/assets/{linear-CeRljV9s.js → linear-Dj636PNG.js} +1 -1
- package/dist/rcs-web/assets/main-CkqtCllF.js +238 -0
- package/dist/rcs-web/assets/{mermaid-VLURNSYL-CG6yNR7g.js → mermaid-VLURNSYL-DutpHHm9.js} +4 -4
- package/dist/rcs-web/assets/{mermaid.core-CAuNNATY.js → mermaid.core-XHHf0pen.js} +5 -5
- package/dist/rcs-web/assets/{mindmap-definition-RKZ34NQL-9hDL1CUV.js → mindmap-definition-RKZ34NQL-BBa8V_3g.js} +1 -1
- package/dist/rcs-web/assets/{pieDiagram-4H26LBE5-BS_P2t04.js → pieDiagram-4H26LBE5-BuNEdo9H.js} +1 -1
- package/dist/rcs-web/assets/{quadrantDiagram-W4KKPZXB-Cp9QQkHV.js → quadrantDiagram-W4KKPZXB-CsJgyQIN.js} +1 -1
- package/dist/rcs-web/assets/{requirementDiagram-4Y6WPE33-C_XSzOKE.js → requirementDiagram-4Y6WPE33-DqMJZ914.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-BhuVqzZd.js → dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-CVsz09q2.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-C3IPZrcW.js → dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-BRp4Wddn.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-AJRCARHV-CN4iNPRl.js → stateDiagram-AJRCARHV-S-QqQr-D.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-v2-BHNVJYJU-CICBlDSJ.js → stateDiagram-v2-BHNVJYJU-D77KfDr-.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-Be7t_3rC.js → dist/rcs-web/assets/timeline-definition-PNZ67QCA-De8bFWnE.js} +1 -1
- package/dist/rcs-web/assets/{useTeams-DPHGnBHL.js → useTeams-CqJOqEy1.js} +1 -1
- package/dist/rcs-web/assets/{vennDiagram-CIIHVFJN-CSaUc2Xv.js → vennDiagram-CIIHVFJN-Dikwrn1L.js} +1 -1
- package/dist/rcs-web/assets/{wardleyDiagram-YWT4CUSO-DTuJrl9P.js → wardleyDiagram-YWT4CUSO-DUzpiV6H.js} +1 -1
- package/dist/rcs-web/assets/{workerType-CSqeySYe.js → workerType-DOQ0AHrq.js} +1 -1
- package/dist/rcs-web/assets/{xychartDiagram-2RQKCTM6-BQ0oU3Qi.js → xychartDiagram-2RQKCTM6-OZNbB32D.js} +1 -1
- package/dist/rcs-web/index.html +1 -1
- package/package.json +2 -2
- package/packages/remote-control-server/src/__tests__/cookie.test.ts +0 -71
- package/packages/remote-control-server/src/__tests__/data-layer-round2.test.ts +556 -0
- package/packages/remote-control-server/src/__tests__/route-mounting.test.ts +212 -0
- package/packages/remote-control-server/src/__tests__/routes.test.ts +5 -44
- package/packages/remote-control-server/src/__tests__/security-fixes.test.ts +526 -0
- package/packages/remote-control-server/src/__tests__/security-round3.test.ts +780 -0
- package/packages/remote-control-server/src/__tests__/shares.test.ts +5 -2
- package/packages/remote-control-server/src/auth/constants.ts +0 -6
- package/packages/remote-control-server/src/auth/cookie.ts +0 -43
- package/packages/remote-control-server/src/auth/csrf.ts +58 -0
- package/packages/remote-control-server/src/auth/middleware.ts +7 -4
- package/packages/remote-control-server/src/index.ts +26 -0
- package/packages/remote-control-server/src/registerRoutes.ts +17 -1
- package/packages/remote-control-server/src/routes/web/auth-routes.ts +93 -54
- package/packages/remote-control-server/src/routes/web/auth.ts +16 -23
- package/packages/remote-control-server/src/routes/web/sessions.ts +30 -5
- package/packages/remote-control-server/src/routes/web/shares.ts +38 -1
- package/packages/remote-control-server/src/routes/web/teams.ts +22 -4
- package/packages/remote-control-server/src/services/session.ts +143 -9
- package/packages/remote-control-server/src/store.ts +34 -1
- package/packages/remote-control-server/src/types/api.ts +0 -1
- package/packages/remote-control-server/web/dist/assets/Dashboard-YYwDrKTN.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Join-DKCP5X6X.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Login-0VGZs85I.js +1 -0
- package/{dist/rcs-web/assets/SessionDetail-DSoMXZJb.js → packages/remote-control-server/web/dist/assets/SessionDetail-DmK-DfBQ.js} +11 -11
- package/packages/remote-control-server/web/dist/assets/Setup-C0cjxXMt.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{ShareLanding-C06U9Nrr.js → ShareLanding-DUZrreJ7.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/TeamCreate-B8ZV6EdY.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{TeamDetail-d_GwIRHd.js → TeamDetail-DBAsJ__i.js} +2 -2
- package/packages/remote-control-server/web/dist/assets/{TeamList-BlNGdKci.js → TeamList-C-Hte4nV.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{TeamSettings-CPraC9uS.js → TeamSettings-CNVwYwcp.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/UserSettings-DRdz9kYE.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{arc-BmYza-0n.js → arc-CJxirXEQ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{architectureDiagram-3BPJPVTR-CYBtlgdO.js → architectureDiagram-3BPJPVTR-BZvIHrLA.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{blockDiagram-GPEHLZMM-RJAfHk_a.js → blockDiagram-GPEHLZMM-3p0y3Ija.js} +1 -1
- package/{dist/rcs-web/assets/c4Diagram-AAUBKEIU-CJ-qJA6w.js → packages/remote-control-server/web/dist/assets/c4Diagram-AAUBKEIU-Bmz9A1wn.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/channel-DaI_n8dp.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-n5I6Q1zJ.js → chunk-2J33WTMH-B8gQz22j.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-CSOBh7qY.js → chunk-4BX2VUAB-CgLEZsTU.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-C0euQVm_.js → chunk-55IACEB6-0mdE_-IS.js} +1 -1
- package/{dist/rcs-web/assets/chunk-727SXJPM-Ch7yD8cR.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-DdtjnIHR.js} +1 -1
- package/{dist/rcs-web/assets/chunk-AQP2D5EJ-Ms2Q7r6u.js → packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-BtwFPk50.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-bszHUkpx.js → chunk-FMBD7UC4-BcO9mQ0P.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-BVQIhq6J.js → chunk-ND2GUHAM-BvRq13S_.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-BVEDe5qc.js → chunk-QZHKN3VN-D7GHkPpq.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-pYllpkOq.js +1 -0
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-pYllpkOq.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{code-block-IT6T5CEO-B26n-rFC.js → code-block-IT6T5CEO-B1p-vO-3.js} +1 -1
- package/{dist/rcs-web/assets/cose-bilkent-S5V4N54A-DXc7GE8W.js → packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-L0rUZuH5.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{dagre-BM42HDAG-DAXofHt_.js → dagre-BM42HDAG-CHGuio22.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-2AECGRRQ-DK0TBUQA.js → diagram-2AECGRRQ-DIDRyQk8.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-5GNKFQAL-DMsq-Grp.js → diagram-5GNKFQAL-CNubKb6P.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-KO2AKTUF-B3FMhmUc.js → diagram-KO2AKTUF-CzQh664-.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-LMA3HP47-BjO3BHFl.js → diagram-LMA3HP47-CWBR7-VG.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-OG6HWLK6-CNg4B2L3.js → diagram-OG6HWLK6-BMHdlbcZ.js} +1 -1
- package/{dist/rcs-web/assets/erDiagram-TEJ5UH35-BDxz8NRK.js → packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-OgT8dC-K.js} +1 -1
- package/{dist/rcs-web/assets/flowDiagram-I6XJVG4X-VIgM13sK.js → packages/remote-control-server/web/dist/assets/flowDiagram-I6XJVG4X-DRrCY2oB.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{ganttDiagram-6RSMTGT7-Ba2QuJU0.js → ganttDiagram-6RSMTGT7-DctpzEKN.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{gitGraphDiagram-PVQCEYII-B-gV-lAg.js → gitGraphDiagram-PVQCEYII-5KpLszm9.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{infoDiagram-5YYISTIA-DothwgD4.js → infoDiagram-5YYISTIA-BAKD_Tt7.js} +1 -1
- package/{dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-DhpjM1Vc.js → packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-VHOPG4Nc.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{journeyDiagram-JHISSGLW-PbQTouMJ.js → journeyDiagram-JHISSGLW-BtGih-ik.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{kanban-definition-UN3LZRKU-63WdwG-X.js → kanban-definition-UN3LZRKU-BsEGZsD1.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{linear-CeRljV9s.js → linear-Dj636PNG.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/main-CkqtCllF.js +238 -0
- package/packages/remote-control-server/web/dist/assets/{mermaid-VLURNSYL-CG6yNR7g.js → mermaid-VLURNSYL-DutpHHm9.js} +4 -4
- package/packages/remote-control-server/web/dist/assets/{mermaid.core-CAuNNATY.js → mermaid.core-XHHf0pen.js} +5 -5
- package/packages/remote-control-server/web/dist/assets/{mindmap-definition-RKZ34NQL-9hDL1CUV.js → mindmap-definition-RKZ34NQL-BBa8V_3g.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{pieDiagram-4H26LBE5-BS_P2t04.js → pieDiagram-4H26LBE5-BuNEdo9H.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{quadrantDiagram-W4KKPZXB-Cp9QQkHV.js → quadrantDiagram-W4KKPZXB-CsJgyQIN.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{requirementDiagram-4Y6WPE33-C_XSzOKE.js → requirementDiagram-4Y6WPE33-DqMJZ914.js} +1 -1
- package/{dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-BhuVqzZd.js → packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-CVsz09q2.js} +1 -1
- package/{dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-C3IPZrcW.js → packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-BRp4Wddn.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-AJRCARHV-CN4iNPRl.js → stateDiagram-AJRCARHV-S-QqQr-D.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-v2-BHNVJYJU-CICBlDSJ.js → stateDiagram-v2-BHNVJYJU-D77KfDr-.js} +1 -1
- package/{dist/rcs-web/assets/timeline-definition-PNZ67QCA-Be7t_3rC.js → packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-De8bFWnE.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{useTeams-DPHGnBHL.js → useTeams-CqJOqEy1.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{vennDiagram-CIIHVFJN-CSaUc2Xv.js → vennDiagram-CIIHVFJN-Dikwrn1L.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{wardleyDiagram-YWT4CUSO-DTuJrl9P.js → wardleyDiagram-YWT4CUSO-DUzpiV6H.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{workerType-CSqeySYe.js → workerType-DOQ0AHrq.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{xychartDiagram-2RQKCTM6-BQ0oU3Qi.js → xychartDiagram-2RQKCTM6-OZNbB32D.js} +1 -1
- package/packages/remote-control-server/web/dist/index.html +1 -1
- package/dist/rcs-web/assets/Dashboard-D_Im4UId.js +0 -1
- package/dist/rcs-web/assets/Join-BTnvMsB9.js +0 -1
- package/dist/rcs-web/assets/Login-ClT7RckC.js +0 -1
- package/dist/rcs-web/assets/Setup-PaDA6Et-.js +0 -1
- package/dist/rcs-web/assets/TeamCreate-249rK3U3.js +0 -1
- package/dist/rcs-web/assets/UserSettings-X627Fdni.js +0 -1
- package/dist/rcs-web/assets/channel-BUwWbT6U.js +0 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-DYtx22zv.js +0 -1
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-DYtx22zv.js +0 -1
- package/dist/rcs-web/assets/i18n-Dbt-vEQ3.js +0 -1
- package/dist/rcs-web/assets/main-DvfxciBy.js +0 -238
- package/packages/remote-control-server/web/dist/assets/Dashboard-D_Im4UId.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Join-BTnvMsB9.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Login-ClT7RckC.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Setup-PaDA6Et-.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamCreate-249rK3U3.js +0 -1
- package/packages/remote-control-server/web/dist/assets/UserSettings-X627Fdni.js +0 -1
- package/packages/remote-control-server/web/dist/assets/channel-BUwWbT6U.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-DYtx22zv.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-DYtx22zv.js +0 -1
- package/packages/remote-control-server/web/dist/assets/i18n-Dbt-vEQ3.js +0 -1
- package/packages/remote-control-server/web/dist/assets/main-DvfxciBy.js +0 -238
|
@@ -11,6 +11,18 @@ interface SessionOwnerRow {
|
|
|
11
11
|
owner_id: string
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Check if a user is a member of a given team.
|
|
16
|
+
*/
|
|
17
|
+
function isTeamMember(userId: string, teamId: string, db: ReturnType<typeof getDb>): boolean {
|
|
18
|
+
const row = db
|
|
19
|
+
.query(
|
|
20
|
+
'SELECT user_id FROM team_members WHERE team_id = $teamId AND user_id = $userId',
|
|
21
|
+
)
|
|
22
|
+
.get({ $teamId: teamId, $userId: userId })
|
|
23
|
+
return !!row
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
interface ShareRow {
|
|
15
27
|
id: string
|
|
16
28
|
session_id: string
|
|
@@ -323,12 +335,14 @@ app.get(
|
|
|
323
335
|
// Look up the share
|
|
324
336
|
const share = db
|
|
325
337
|
.query(
|
|
326
|
-
`SELECT id, session_id, expires_at
|
|
338
|
+
`SELECT id, session_id, granted_to_user, granted_to_team, expires_at
|
|
327
339
|
FROM session_shares WHERE id = $id`,
|
|
328
340
|
)
|
|
329
341
|
.get({ $id: shareToken }) as {
|
|
330
342
|
id: string
|
|
331
343
|
session_id: string
|
|
344
|
+
granted_to_user: string | null
|
|
345
|
+
granted_to_team: string | null
|
|
332
346
|
expires_at: string | null
|
|
333
347
|
} | null
|
|
334
348
|
|
|
@@ -347,6 +361,29 @@ app.get(
|
|
|
347
361
|
)
|
|
348
362
|
}
|
|
349
363
|
|
|
364
|
+
// Grantee check: caller must be the granted_to_user or a member of granted_to_team
|
|
365
|
+
const callerUserId = c.get('userId') as string | undefined
|
|
366
|
+
if (!callerUserId) {
|
|
367
|
+
return c.json(
|
|
368
|
+
{ error: { type: 'unauthorized', message: 'Not authenticated' } },
|
|
369
|
+
401,
|
|
370
|
+
)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const isAdmin = c.get('isAdmin') as boolean | undefined
|
|
374
|
+
const isGrantee =
|
|
375
|
+
isAdmin ||
|
|
376
|
+
share.granted_to_user === callerUserId ||
|
|
377
|
+
(share.granted_to_team !== null &&
|
|
378
|
+
isTeamMember(callerUserId, share.granted_to_team, db))
|
|
379
|
+
|
|
380
|
+
if (!isGrantee) {
|
|
381
|
+
return c.json(
|
|
382
|
+
{ error: { type: 'forbidden', message: 'Not authorized for this share' } },
|
|
383
|
+
403,
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
|
|
350
387
|
// Check session still exists — return only public-safe fields
|
|
351
388
|
const session = db
|
|
352
389
|
.query(
|
|
@@ -144,13 +144,22 @@ app.post('/teams', withAuth, async c => {
|
|
|
144
144
|
const teamId = `team_${randomUUID().replace(/-/g, '')}`
|
|
145
145
|
const now = new Date().toISOString()
|
|
146
146
|
|
|
147
|
-
// For system admin, use the first admin user as created_by
|
|
147
|
+
// For system admin (API key), use the first admin user as created_by.
|
|
148
|
+
// For a logged-in admin user, use their own userId.
|
|
148
149
|
let createdBy = user.userId
|
|
149
|
-
if (user.
|
|
150
|
+
if (user.userId === SYSTEM_USER_ID) {
|
|
150
151
|
const adminUser = db
|
|
151
|
-
.query(
|
|
152
|
+
.query(
|
|
153
|
+
"SELECT id FROM users WHERE role = 'admin' ORDER BY created_at ASC LIMIT 1",
|
|
154
|
+
)
|
|
152
155
|
.get() as { id: string } | null
|
|
153
|
-
|
|
156
|
+
if (!adminUser) {
|
|
157
|
+
return c.json(
|
|
158
|
+
{ error: 'No admin user available to create team' },
|
|
159
|
+
400,
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
createdBy = adminUser.id
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
db.query(
|
|
@@ -815,6 +824,15 @@ app.post('/environments/:id/transfer', withAuth, async c => {
|
|
|
815
824
|
return c.json({ error: 'Environment not found in any team' }, 404)
|
|
816
825
|
}
|
|
817
826
|
|
|
827
|
+
// Check caller is owner/admin of the target team
|
|
828
|
+
const targetRole = getTeamRole(toTeamId, user)
|
|
829
|
+
if (!user.isAdmin && (!targetRole || (targetRole !== 'owner' && targetRole !== 'admin'))) {
|
|
830
|
+
return c.json(
|
|
831
|
+
{ error: 'Not authorized in target team' },
|
|
832
|
+
403,
|
|
833
|
+
)
|
|
834
|
+
}
|
|
835
|
+
|
|
818
836
|
// Remove from source team
|
|
819
837
|
db.query('DELETE FROM team_environments WHERE environment_id = $envId').run({
|
|
820
838
|
$envId: envId,
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
storeListSessionsByOwnerUuid,
|
|
11
11
|
} from '../store'
|
|
12
12
|
import { randomUUID } from 'node:crypto'
|
|
13
|
+
import { getDb } from '../db/sqlite'
|
|
14
|
+
import type { Database } from 'bun:sqlite'
|
|
13
15
|
import { getAllEventBuses, removeEventBus } from '../transport/event-bus'
|
|
14
16
|
import type {
|
|
15
17
|
CreateSessionRequest,
|
|
@@ -123,20 +125,152 @@ export function resolveExistingWebSessionId(sessionId: string): string | null {
|
|
|
123
125
|
return resolveExistingSessionId(sessionId)
|
|
124
126
|
}
|
|
125
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Determine the access level a user has to a session.
|
|
130
|
+
*
|
|
131
|
+
* Returns:
|
|
132
|
+
* - `'owner'` — user owns the session directly or via team ownership
|
|
133
|
+
* - `'write'` — user has a non-expired write share
|
|
134
|
+
* - `'read'` — user has a non-expired read share (direct or via team)
|
|
135
|
+
* - `null` — no access
|
|
136
|
+
*/
|
|
137
|
+
export function isSessionVisibleToUser(
|
|
138
|
+
sessionId: string,
|
|
139
|
+
userId: string,
|
|
140
|
+
db: Database,
|
|
141
|
+
): 'owner' | 'write' | 'read' | null {
|
|
142
|
+
// Rule 1: direct user ownership
|
|
143
|
+
const directOwner = db
|
|
144
|
+
.query(
|
|
145
|
+
`SELECT 1 FROM session_owners
|
|
146
|
+
WHERE session_id = $sessionId AND owner_type = 'user' AND owner_id = $userId
|
|
147
|
+
LIMIT 1`,
|
|
148
|
+
)
|
|
149
|
+
.get({ $sessionId: sessionId, $userId: userId })
|
|
150
|
+
if (directOwner) return 'owner'
|
|
151
|
+
|
|
152
|
+
// Rule 2: team ownership — session owned by a team the user belongs to
|
|
153
|
+
const teamOwner = db
|
|
154
|
+
.query(
|
|
155
|
+
`SELECT 1 FROM session_owners so
|
|
156
|
+
JOIN team_members tm ON tm.team_id = so.owner_id
|
|
157
|
+
WHERE so.session_id = $sessionId
|
|
158
|
+
AND so.owner_type = 'team'
|
|
159
|
+
AND tm.user_id = $userId
|
|
160
|
+
LIMIT 1`,
|
|
161
|
+
)
|
|
162
|
+
.get({ $sessionId: sessionId, $userId: userId })
|
|
163
|
+
if (teamOwner) return 'owner'
|
|
164
|
+
|
|
165
|
+
// Rule 3: direct write share (non-expired)
|
|
166
|
+
const writeShare = db
|
|
167
|
+
.query(
|
|
168
|
+
`SELECT 1 FROM session_shares
|
|
169
|
+
WHERE session_id = $sessionId
|
|
170
|
+
AND granted_to_user = $userId
|
|
171
|
+
AND permission = 'write'
|
|
172
|
+
AND (expires_at IS NULL OR expires_at > strftime('%Y-%m-%dT%H:%M:%S.000Z', 'now'))
|
|
173
|
+
LIMIT 1`,
|
|
174
|
+
)
|
|
175
|
+
.get({ $sessionId: sessionId, $userId: userId })
|
|
176
|
+
if (writeShare) return 'write'
|
|
177
|
+
|
|
178
|
+
// Rule 4: direct read share (non-expired)
|
|
179
|
+
const readShare = db
|
|
180
|
+
.query(
|
|
181
|
+
`SELECT 1 FROM session_shares
|
|
182
|
+
WHERE session_id = $sessionId
|
|
183
|
+
AND granted_to_user = $userId
|
|
184
|
+
AND permission = 'read'
|
|
185
|
+
AND (expires_at IS NULL OR expires_at > strftime('%Y-%m-%dT%H:%M:%S.000Z', 'now'))
|
|
186
|
+
LIMIT 1`,
|
|
187
|
+
)
|
|
188
|
+
.get({ $sessionId: sessionId, $userId: userId })
|
|
189
|
+
if (readShare) return 'read'
|
|
190
|
+
|
|
191
|
+
// Rule 5: team write share (non-expired)
|
|
192
|
+
const teamWriteShare = db
|
|
193
|
+
.query(
|
|
194
|
+
`SELECT 1 FROM session_shares ss
|
|
195
|
+
JOIN team_members tm ON tm.team_id = ss.granted_to_team
|
|
196
|
+
WHERE ss.session_id = $sessionId
|
|
197
|
+
AND tm.user_id = $userId
|
|
198
|
+
AND ss.permission = 'write'
|
|
199
|
+
AND (ss.expires_at IS NULL OR ss.expires_at > strftime('%Y-%m-%dT%H:%M:%S.000Z', 'now'))
|
|
200
|
+
LIMIT 1`,
|
|
201
|
+
)
|
|
202
|
+
.get({ $sessionId: sessionId, $userId: userId })
|
|
203
|
+
if (teamWriteShare) return 'write'
|
|
204
|
+
|
|
205
|
+
// Rule 6: team read share (non-expired)
|
|
206
|
+
const teamReadShare = db
|
|
207
|
+
.query(
|
|
208
|
+
`SELECT 1 FROM session_shares ss
|
|
209
|
+
JOIN team_members tm ON tm.team_id = ss.granted_to_team
|
|
210
|
+
WHERE ss.session_id = $sessionId
|
|
211
|
+
AND tm.user_id = $userId
|
|
212
|
+
AND ss.permission = 'read'
|
|
213
|
+
AND (ss.expires_at IS NULL OR ss.expires_at > strftime('%Y-%m-%dT%H:%M:%S.000Z', 'now'))
|
|
214
|
+
LIMIT 1`,
|
|
215
|
+
)
|
|
216
|
+
.get({ $sessionId: sessionId, $userId: userId })
|
|
217
|
+
if (teamReadShare) return 'read'
|
|
218
|
+
|
|
219
|
+
return null
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Resolve a session ID for a user, checking ownership, shares, and team access.
|
|
224
|
+
*
|
|
225
|
+
* @param sessionId — the session ID to resolve (web or code prefix)
|
|
226
|
+
* @param uuid — the user ID
|
|
227
|
+
* @param requireWrite — if true, only return the ID when the user has write access
|
|
228
|
+
* (owner or write share); if false, read access suffices
|
|
229
|
+
*/
|
|
126
230
|
export function resolveOwnedWebSessionId(
|
|
127
231
|
sessionId: string,
|
|
128
232
|
uuid: string,
|
|
233
|
+
requireWrite = false,
|
|
129
234
|
): string | null {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
235
|
+
try {
|
|
236
|
+
const db = getDb()
|
|
237
|
+
const visibility = isSessionVisibleToUser(sessionId, uuid, db)
|
|
238
|
+
if (visibility) {
|
|
239
|
+
if (!requireWrite || visibility === 'owner' || visibility === 'write') {
|
|
240
|
+
return sessionId
|
|
241
|
+
}
|
|
242
|
+
}
|
|
133
243
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
compatibleCodeSessionId
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
244
|
+
// Try compatible code session ID
|
|
245
|
+
const compatibleCodeSessionId = toCompatibleCodeSessionId(sessionId)
|
|
246
|
+
if (compatibleCodeSessionId) {
|
|
247
|
+
const compatVisibility = isSessionVisibleToUser(
|
|
248
|
+
compatibleCodeSessionId,
|
|
249
|
+
uuid,
|
|
250
|
+
db,
|
|
251
|
+
)
|
|
252
|
+
if (compatVisibility) {
|
|
253
|
+
if (
|
|
254
|
+
!requireWrite ||
|
|
255
|
+
compatVisibility === 'owner' ||
|
|
256
|
+
compatVisibility === 'write'
|
|
257
|
+
) {
|
|
258
|
+
return compatibleCodeSessionId
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
} catch {
|
|
263
|
+
// Fallback to legacy ownership check if DB is unavailable
|
|
264
|
+
if (storeIsSessionOwner(sessionId, uuid)) {
|
|
265
|
+
return sessionId
|
|
266
|
+
}
|
|
267
|
+
const compatibleCodeSessionId = toCompatibleCodeSessionId(sessionId)
|
|
268
|
+
if (
|
|
269
|
+
compatibleCodeSessionId &&
|
|
270
|
+
storeIsSessionOwner(compatibleCodeSessionId, uuid)
|
|
271
|
+
) {
|
|
272
|
+
return compatibleCodeSessionId
|
|
273
|
+
}
|
|
140
274
|
}
|
|
141
275
|
|
|
142
276
|
return null
|
|
@@ -180,6 +180,36 @@ export function storeUpdateEnvironment(
|
|
|
180
180
|
const rec = environments.get(id)
|
|
181
181
|
if (!rec) return false
|
|
182
182
|
Object.assign(rec, patch, { updatedAt: new Date() })
|
|
183
|
+
try {
|
|
184
|
+
const db = getDb()
|
|
185
|
+
const sets: string[] = []
|
|
186
|
+
const params: Record<string, string | number | null> = { $id: id }
|
|
187
|
+
|
|
188
|
+
if (patch.status !== undefined) {
|
|
189
|
+
sets.push('status = $status')
|
|
190
|
+
params.$status = patch.status
|
|
191
|
+
}
|
|
192
|
+
if (patch.lastPollAt !== undefined) {
|
|
193
|
+
sets.push('last_poll_at = $lastPollAt')
|
|
194
|
+
params.$lastPollAt = patch.lastPollAt?.toISOString() ?? null
|
|
195
|
+
}
|
|
196
|
+
if (patch.machineName !== undefined) {
|
|
197
|
+
sets.push('machine_name = $machineName')
|
|
198
|
+
params.$machineName = patch.machineName
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// bridgeId, maxSessions, capabilities, updatedAt are in-memory only —
|
|
202
|
+
// the environments table has no corresponding columns.
|
|
203
|
+
|
|
204
|
+
if (sets.length > 0) {
|
|
205
|
+
db.query(
|
|
206
|
+
`UPDATE environments SET ${sets.join(', ')} WHERE id = $id`,
|
|
207
|
+
).run(params)
|
|
208
|
+
}
|
|
209
|
+
} catch (err) {
|
|
210
|
+
console.error('[store] DB write failed in storeUpdateEnvironment:', err)
|
|
211
|
+
throw err
|
|
212
|
+
}
|
|
183
213
|
return true
|
|
184
214
|
}
|
|
185
215
|
|
|
@@ -204,6 +234,7 @@ export function storeCreateSession(req: {
|
|
|
204
234
|
permissionMode?: string | null
|
|
205
235
|
idPrefix?: string
|
|
206
236
|
username?: string | null
|
|
237
|
+
visibility?: string
|
|
207
238
|
}): SessionRecord {
|
|
208
239
|
const id = `${req.idPrefix || 'session_'}${randomUUID().replace(/-/g, '')}`
|
|
209
240
|
const now = new Date()
|
|
@@ -231,7 +262,7 @@ export function storeCreateSession(req: {
|
|
|
231
262
|
$title: record.title,
|
|
232
263
|
$status: record.status,
|
|
233
264
|
$source: record.source,
|
|
234
|
-
$vis: 'private',
|
|
265
|
+
$vis: req.visibility ?? 'private',
|
|
235
266
|
$pm: record.permissionMode,
|
|
236
267
|
$ca: record.createdAt.toISOString(),
|
|
237
268
|
$ua: record.updatedAt.toISOString(),
|
|
@@ -268,6 +299,7 @@ export function storeUpdateSession(
|
|
|
268
299
|
})
|
|
269
300
|
} catch (err) {
|
|
270
301
|
console.error('[store] DB write failed in storeUpdateSession:', err)
|
|
302
|
+
throw err
|
|
271
303
|
}
|
|
272
304
|
return true
|
|
273
305
|
}
|
|
@@ -292,6 +324,7 @@ export function storeDeleteSession(id: string): boolean {
|
|
|
292
324
|
db.query('DELETE FROM sessions WHERE id = $id').run({ $id: id })
|
|
293
325
|
} catch (err) {
|
|
294
326
|
console.error('[store] DB write failed in storeDeleteSession:', err)
|
|
327
|
+
throw err
|
|
295
328
|
}
|
|
296
329
|
return deleted
|
|
297
330
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,e as d}from"./vendor-DE_-CLIE.js";import{h as N,B as w,Q as v,I as s,l as k,n as C,o as S,m as _}from"./main-CkqtCllF.js";import{g as y,D,a as L,c as E,d as B,b as M}from"./workerType-DOQ0AHrq.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function T({environments:l,onSelectEnvironment:x}){return!l||l.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:l.map(a=>{const i=a.worker_type==="acp",c=y(a.worker_type),u=c.fullLabel,t=c.colorClass;return e.jsxs("button",{type:"button",onClick:()=>x==null?void 0:x(a),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:a.machine_name||a.id}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${t}`,children:u})]}),e.jsx("div",{className:"text-sm text-text-muted",children:a.directory||""})]})}),e.jsxs("div",{className:"text-right",children:[e.jsx(N,{status:a.status}),e.jsx("div",{className:"mt-1 text-xs text-text-muted",children:a.branch||""})]})]},a.id)})})}function F({sessions:l,environments:x,onSelect:a,onDelete:i}){if(!l||l.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 c=new Map;for(const t of x??[])t!=null&&t.id&&t.worker_type&&c.set(t.id,t.worker_type);const u=[...l].sort((t,n)=>(n.updated_at||0)-(t.updated_at||0));return e.jsx("div",{className:"space-y-2",children:u.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:()=>a(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 h;let n=t.source==="acp"?"acp":(h=t.environment)==null?void 0:h.worker_type;!n&&t.environment_id&&(n=c.get(t.environment_id));const p=y(n);return e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${p.colorClass}`,children:p.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(N,{status:t.status}),e.jsx("span",{className:"text-xs text-text-muted",children:w(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 I({open:l,environments:x,onClose:a,onCreated:i}){v();const[c,u]=d.useState(""),[t,n]=d.useState(""),[p,h]=d.useState("same-dir"),[f,b]=d.useState(""),[o,m]=d.useState(!1);d.useEffect(()=>{l&&(u(""),n(""),h("same-dir"),b(""))},[l]);const g=async()=>{m(!0),b("");try{const r={};c.trim()&&(r.title=c.trim()),t&&(r.environment_id=t),r.spawn_mode=p;const j=await k(r);i(j)}catch(r){b(r instanceof Error?r.message:s("dialog.createFailed"))}finally{m(!1)}};return e.jsx(D,{open:l,onOpenChange:r=>{r||a()},children:e.jsxs(L,{className:"max-w-md rounded-2xl border-border bg-surface-1 p-6 shadow-2xl",children:[e.jsx(E,{children:e.jsx(B,{className:"font-display text-lg font-semibold text-text-primary",children:s("dialog.newSession")})}),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:s("dialog.titleOptional")}),e.jsx("input",{type:"text",value:c,onChange:r=>u(r.target.value),placeholder:s("dialog.titlePlaceholder"),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:s("dialog.environment")}),e.jsxs("select",{value:t,onChange:r=>n(r.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:s("dialog.none")}),x.map(r=>{const j=y(r.worker_type).shortLabel;return e.jsxs("option",{value:r.id,children:[r.machine_name||r.id," (",r.branch||s("dialog.noBranch"),") · ",j]},r.id)})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm text-text-secondary",children:s("dialog.workspaceMode")}),e.jsxs("select",{value:p,onChange:r=>h(r.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:s("dialog.sameDir")}),e.jsx("option",{value:"worktree",children:s("dialog.worktree")})]})]}),f&&e.jsx("div",{className:"text-sm text-status-error",children:f})]}),e.jsxs(M,{children:[e.jsx("button",{onClick:a,className:"rounded-lg border border-border px-4 py-2 text-sm text-text-secondary hover:bg-surface-2 transition-colors",children:s("common.cancel")}),e.jsx("button",{onClick:g,disabled:o,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:o?s("common.creating"):s("common.create")})]})]})})}function H({onNavigateSession:l}){v();const[x,a]=d.useState([]),[i,c]=d.useState([]),[u,t]=d.useState(!1),n=d.useCallback(async()=>{try{const[o,m]=await Promise.all([C(),S()]);a(o||[]),c(m||[])}catch(o){console.error("Dashboard render error:",o)}},[]);d.useEffect(()=>{n();const o=setInterval(n,1e4);return()=>clearInterval(o)},[n]);const p=o=>{t(!1),l(o.id)},h=d.useCallback(o=>{},[]),f=d.useCallback(o=>{l(o)},[l]),b=d.useCallback(async o=>{if(window.confirm(s("dashboard.confirmDelete").replace("{id}",o)))try{await _(o),a(m=>m.filter(g=>g.id!==o))}catch(m){alert(m instanceof Error?m.message:s("dashboard.deleteFailed"))}},[]);return e.jsxs("div",{className:"mx-auto max-w-5xl px-4 py-8",children:[e.jsx("h1",{className:"sr-only",children:s("dashboard.title")}),e.jsxs("section",{className:"mb-10",children:[e.jsx("h2",{className:"mb-4 font-display text-lg font-semibold text-text-primary",children:s("dashboard.environments")}),e.jsx(T,{environments:i,onSelectEnvironment:h})]}),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:s("dashboard.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:s("dashboard.newSession")})]}),e.jsx(F,{sessions:x,environments:i,onSelect:f,onDelete:b})]}),e.jsx(I,{open:u,environments:i,onClose:()=>t(!1),onCreated:p})]})}export{H as Dashboard};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as r,j as e}from"./vendor-DE_-CLIE.js";import{N,I as t}from"./main-CkqtCllF.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function E({onSuccess:b,onInvalidInvite:l}){const{join:h}=N(),[u,f]=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?f(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 h(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{E as Join};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as r,j as e}from"./vendor-DE_-CLIE.js";import{N as b,I as t}from"./main-CkqtCllF.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function j({onSuccess:d}){const{login:c}=b(),[a,m]=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 c(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=>m(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{j as Login};
|