@saluzi/saluzi-edu 0.2.20 → 0.2.21
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 +106 -83
- package/dist/rcs-web/assets/AdminPanel-B0hhIa7W.js +1 -0
- package/dist/rcs-web/assets/Claim-BTx12YJw.js +1 -0
- package/dist/rcs-web/assets/Dashboard-C_qeuXGp.js +1 -0
- package/dist/rcs-web/assets/Join-DDMaEXX-.js +1 -0
- package/dist/rcs-web/assets/Login-eCEGVdjw.js +1 -0
- package/dist/rcs-web/assets/Register-gqlt4O0J.js +1 -0
- package/dist/rcs-web/assets/{SessionDetail-B5C0o1YT.js → SessionDetail-BfrG6lOA.js} +10 -10
- package/dist/rcs-web/assets/SessionVisibilityBadge-CN3bz2gb.js +11 -0
- package/dist/rcs-web/assets/Setup-yO-c5mfy.js +1 -0
- package/dist/rcs-web/assets/{ShareLanding-DBC9gbJo.js → ShareLanding-S3XUdrDL.js} +1 -1
- package/dist/rcs-web/assets/TeamCreate-DGUK4ghi.js +1 -0
- package/dist/rcs-web/assets/TeamDetail-Ct07DirR.js +6 -0
- package/dist/rcs-web/assets/TeamList-CJTYa2Ah.js +1 -0
- package/dist/rcs-web/assets/TeamSettings-DXb0w8GG.js +1 -0
- package/dist/rcs-web/assets/UserSettings-DzreS8Mi.js +1 -0
- package/dist/rcs-web/assets/{arc-DBPKxYzS.js → arc-wiB_u0W8.js} +1 -1
- package/dist/rcs-web/assets/{architectureDiagram-3BPJPVTR-D88rj_js.js → architectureDiagram-3BPJPVTR-70tgIgZq.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-xzgUpRMn.js → dist/rcs-web/assets/blockDiagram-GPEHLZMM-Drz4LSdp.js} +1 -1
- package/dist/rcs-web/assets/{c4Diagram-AAUBKEIU-vpg_EoPb.js → c4Diagram-AAUBKEIU-BM7C7SEx.js} +1 -1
- package/dist/rcs-web/assets/channel-D-a_TNjA.js +1 -0
- package/dist/rcs-web/assets/{chunk-2J33WTMH-DXWsXvhS.js → chunk-2J33WTMH-BSqxyVTy.js} +1 -1
- package/dist/rcs-web/assets/{chunk-4BX2VUAB-BtTxwj9K.js → chunk-4BX2VUAB-HFKHN20V.js} +1 -1
- package/dist/rcs-web/assets/{chunk-55IACEB6-D2-Q95qg.js → chunk-55IACEB6-DOBdvIv4.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-Ce3e5x8u.js → dist/rcs-web/assets/chunk-727SXJPM-B2qn-WmZ.js} +1 -1
- package/dist/rcs-web/assets/{chunk-AQP2D5EJ-C0UbKVtd.js → chunk-AQP2D5EJ-DFC3ivzL.js} +1 -1
- package/dist/rcs-web/assets/{chunk-FMBD7UC4-BCwppVqh.js → chunk-FMBD7UC4-CkVr3MVW.js} +1 -1
- package/dist/rcs-web/assets/{chunk-ND2GUHAM-CnOBwWrm.js → chunk-ND2GUHAM-B2WO2xxD.js} +1 -1
- package/dist/rcs-web/assets/{chunk-QZHKN3VN-CDdzB71P.js → chunk-QZHKN3VN-YpZyVA2c.js} +1 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-Dl3V5TVw.js +1 -0
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-Dl3V5TVw.js +1 -0
- package/dist/rcs-web/assets/{code-block-IT6T5CEO-C1_H_ztH.js → code-block-IT6T5CEO-Bmds1dKk.js} +1 -1
- package/dist/rcs-web/assets/{copy-DXU1lQqc.js → copy-DdSkINCW.js} +1 -1
- package/dist/rcs-web/assets/{cose-bilkent-S5V4N54A-BC6nfjTF.js → cose-bilkent-S5V4N54A-CTtGg7Fx.js} +1 -1
- package/dist/rcs-web/assets/{dagre-BM42HDAG-CEPR_pRx.js → dagre-BM42HDAG-CFX48pZZ.js} +1 -1
- package/dist/rcs-web/assets/{diagram-2AECGRRQ-fVMGnSYa.js → diagram-2AECGRRQ-BwZE2jAF.js} +1 -1
- package/dist/rcs-web/assets/{diagram-5GNKFQAL-BPzN2rbK.js → diagram-5GNKFQAL-BuHnggju.js} +1 -1
- package/dist/rcs-web/assets/{diagram-KO2AKTUF-Boneg9n-.js → diagram-KO2AKTUF-Dmd3MO7f.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/diagram-LMA3HP47-B8AtvjO9.js → dist/rcs-web/assets/diagram-LMA3HP47-34ZNfvQd.js} +1 -1
- package/dist/rcs-web/assets/{diagram-OG6HWLK6-DjY7A8jK.js → diagram-OG6HWLK6-CjZvlFxO.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-C1BEfKxk.js → dist/rcs-web/assets/erDiagram-TEJ5UH35-BWR0WD_N.js} +1 -1
- package/dist/rcs-web/assets/{flowDiagram-I6XJVG4X-7TbI9MLV.js → flowDiagram-I6XJVG4X-DjZ7uFyw.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-CMAV0A01.js → dist/rcs-web/assets/ganttDiagram-6RSMTGT7-BuAM7awZ.js} +1 -1
- package/dist/rcs-web/assets/{gitGraphDiagram-PVQCEYII-DAlR8G81.js → gitGraphDiagram-PVQCEYII-B_6bqpod.js} +1 -1
- package/dist/rcs-web/assets/{infoDiagram-5YYISTIA-0T0DAV4W.js → infoDiagram-5YYISTIA-BbhCTAn2.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-BAw8txlx.js → dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-1VPCYnPS.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-DWvYKwz-.js → dist/rcs-web/assets/journeyDiagram-JHISSGLW-Dzl0f8Im.js} +1 -1
- package/dist/rcs-web/assets/{kanban-definition-UN3LZRKU-Qzqw1H5B.js → kanban-definition-UN3LZRKU-BGoVgBze.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/linear-D2KIJoCI.js → dist/rcs-web/assets/linear-DF7ChHtW.js} +1 -1
- package/dist/rcs-web/assets/main-B_OE0doJ.css +1 -0
- package/dist/rcs-web/assets/main-CEsvX5rj.js +253 -0
- package/dist/rcs-web/assets/{mermaid-VLURNSYL-CxWk1wHz.js → mermaid-VLURNSYL-3EqupjjN.js} +4 -4
- package/dist/rcs-web/assets/{mermaid.core-C48YvKu4.js → mermaid.core-BnVRH5R_.js} +5 -5
- package/dist/rcs-web/assets/{mindmap-definition-RKZ34NQL-BfmcTuCA.js → mindmap-definition-RKZ34NQL-R3usKqMg.js} +1 -1
- package/dist/rcs-web/assets/{pieDiagram-4H26LBE5-DVNZpnfb.js → pieDiagram-4H26LBE5-U1XXn3t9.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-COL55Z3i.js → dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-CocIpolQ.js} +1 -1
- package/dist/rcs-web/assets/{requirementDiagram-4Y6WPE33-CFczYQ0a.js → requirementDiagram-4Y6WPE33-DX7pHOr5.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-BrQEv3WQ.js → dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-TD6XCrii.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-CMxtYmQu.js → dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-EyZvfcbT.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-AJRCARHV-Dw9xJZ-A.js → stateDiagram-AJRCARHV-B_SU6QSv.js} +1 -1
- package/dist/rcs-web/assets/{stateDiagram-v2-BHNVJYJU-Br0D-weX.js → stateDiagram-v2-BHNVJYJU-C8vEqOLP.js} +1 -1
- package/{packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-DuWDwYBt.js → dist/rcs-web/assets/timeline-definition-PNZ67QCA-C2XHcj96.js} +1 -1
- package/dist/rcs-web/assets/{vennDiagram-CIIHVFJN--7IV65HQ.js → vennDiagram-CIIHVFJN-aAmhPOm3.js} +1 -1
- package/dist/rcs-web/assets/{wardleyDiagram-YWT4CUSO-CVTgWbvT.js → wardleyDiagram-YWT4CUSO-Db_mMfd6.js} +1 -1
- package/dist/rcs-web/assets/workerType-Bd-zteMi.js +1 -0
- package/{packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-B9om4xAF.js → dist/rcs-web/assets/xychartDiagram-2RQKCTM6-DPjdOqDe.js} +1 -1
- package/dist/rcs-web/index.html +2 -2
- package/package.json +1 -1
- package/packages/remote-control-server/src/__tests__/bind-replacement.test.ts +5 -5
- package/packages/remote-control-server/src/__tests__/phase4-integration.test.ts +2 -2
- package/packages/remote-control-server/src/__tests__/route-mounting.test.ts +2 -2
- package/packages/remote-control-server/src/__tests__/routes.test.ts +21 -5
- package/packages/remote-control-server/src/__tests__/shares.test.ts +21 -20
- package/packages/remote-control-server/src/__tests__/teams.test.ts +119 -0
- package/packages/remote-control-server/src/config.ts +3 -0
- package/packages/remote-control-server/src/db/schema.sql +6 -1
- package/packages/remote-control-server/src/db/sqlite.ts +46 -1
- package/packages/remote-control-server/src/registerRoutes.ts +17 -1
- package/packages/remote-control-server/src/routes/v1/environments.ts +35 -1
- package/packages/remote-control-server/src/routes/v1/sessions.ts +48 -2
- package/packages/remote-control-server/src/routes/web/auth-routes.ts +64 -0
- package/packages/remote-control-server/src/routes/web/environments.ts +7 -3
- package/packages/remote-control-server/src/routes/web/shares.ts +17 -26
- package/packages/remote-control-server/src/routes/web/teams.ts +241 -4
- package/packages/remote-control-server/src/services/environment.ts +12 -1
- package/packages/remote-control-server/src/store.ts +87 -4
- package/packages/remote-control-server/src/types/api.ts +1 -0
- package/packages/remote-control-server/web/dist/assets/AdminPanel-B0hhIa7W.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Claim-BTx12YJw.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Dashboard-C_qeuXGp.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Join-DDMaEXX-.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Login-eCEGVdjw.js +1 -0
- package/packages/remote-control-server/web/dist/assets/Register-gqlt4O0J.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{SessionDetail-B5C0o1YT.js → SessionDetail-BfrG6lOA.js} +10 -10
- package/packages/remote-control-server/web/dist/assets/SessionVisibilityBadge-CN3bz2gb.js +11 -0
- package/packages/remote-control-server/web/dist/assets/Setup-yO-c5mfy.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{ShareLanding-DBC9gbJo.js → ShareLanding-S3XUdrDL.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/TeamCreate-DGUK4ghi.js +1 -0
- package/packages/remote-control-server/web/dist/assets/TeamDetail-Ct07DirR.js +6 -0
- package/packages/remote-control-server/web/dist/assets/TeamList-CJTYa2Ah.js +1 -0
- package/packages/remote-control-server/web/dist/assets/TeamSettings-DXb0w8GG.js +1 -0
- package/packages/remote-control-server/web/dist/assets/UserSettings-DzreS8Mi.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{arc-DBPKxYzS.js → arc-wiB_u0W8.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{architectureDiagram-3BPJPVTR-D88rj_js.js → architectureDiagram-3BPJPVTR-70tgIgZq.js} +1 -1
- package/{dist/rcs-web/assets/blockDiagram-GPEHLZMM-xzgUpRMn.js → packages/remote-control-server/web/dist/assets/blockDiagram-GPEHLZMM-Drz4LSdp.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{c4Diagram-AAUBKEIU-vpg_EoPb.js → c4Diagram-AAUBKEIU-BM7C7SEx.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/channel-D-a_TNjA.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-DXWsXvhS.js → chunk-2J33WTMH-BSqxyVTy.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-BtTxwj9K.js → chunk-4BX2VUAB-HFKHN20V.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-D2-Q95qg.js → chunk-55IACEB6-DOBdvIv4.js} +1 -1
- package/{dist/rcs-web/assets/chunk-727SXJPM-Ce3e5x8u.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-B2qn-WmZ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-AQP2D5EJ-C0UbKVtd.js → chunk-AQP2D5EJ-DFC3ivzL.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-BCwppVqh.js → chunk-FMBD7UC4-CkVr3MVW.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-CnOBwWrm.js → chunk-ND2GUHAM-B2WO2xxD.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-CDdzB71P.js → chunk-QZHKN3VN-YpZyVA2c.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-Dl3V5TVw.js +1 -0
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-Dl3V5TVw.js +1 -0
- package/packages/remote-control-server/web/dist/assets/{code-block-IT6T5CEO-C1_H_ztH.js → code-block-IT6T5CEO-Bmds1dKk.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{copy-DXU1lQqc.js → copy-DdSkINCW.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{cose-bilkent-S5V4N54A-BC6nfjTF.js → cose-bilkent-S5V4N54A-CTtGg7Fx.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{dagre-BM42HDAG-CEPR_pRx.js → dagre-BM42HDAG-CFX48pZZ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-2AECGRRQ-fVMGnSYa.js → diagram-2AECGRRQ-BwZE2jAF.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-5GNKFQAL-BPzN2rbK.js → diagram-5GNKFQAL-BuHnggju.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-KO2AKTUF-Boneg9n-.js → diagram-KO2AKTUF-Dmd3MO7f.js} +1 -1
- package/{dist/rcs-web/assets/diagram-LMA3HP47-B8AtvjO9.js → packages/remote-control-server/web/dist/assets/diagram-LMA3HP47-34ZNfvQd.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{diagram-OG6HWLK6-DjY7A8jK.js → diagram-OG6HWLK6-CjZvlFxO.js} +1 -1
- package/{dist/rcs-web/assets/erDiagram-TEJ5UH35-C1BEfKxk.js → packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-BWR0WD_N.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{flowDiagram-I6XJVG4X-7TbI9MLV.js → flowDiagram-I6XJVG4X-DjZ7uFyw.js} +1 -1
- package/{dist/rcs-web/assets/ganttDiagram-6RSMTGT7-CMAV0A01.js → packages/remote-control-server/web/dist/assets/ganttDiagram-6RSMTGT7-BuAM7awZ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{gitGraphDiagram-PVQCEYII-DAlR8G81.js → gitGraphDiagram-PVQCEYII-B_6bqpod.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{infoDiagram-5YYISTIA-0T0DAV4W.js → infoDiagram-5YYISTIA-BbhCTAn2.js} +1 -1
- package/{dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-BAw8txlx.js → packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-1VPCYnPS.js} +1 -1
- package/{dist/rcs-web/assets/journeyDiagram-JHISSGLW-DWvYKwz-.js → packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-Dzl0f8Im.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{kanban-definition-UN3LZRKU-Qzqw1H5B.js → kanban-definition-UN3LZRKU-BGoVgBze.js} +1 -1
- package/{dist/rcs-web/assets/linear-D2KIJoCI.js → packages/remote-control-server/web/dist/assets/linear-DF7ChHtW.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/main-B_OE0doJ.css +1 -0
- package/packages/remote-control-server/web/dist/assets/main-CEsvX5rj.js +253 -0
- package/packages/remote-control-server/web/dist/assets/{mermaid-VLURNSYL-CxWk1wHz.js → mermaid-VLURNSYL-3EqupjjN.js} +4 -4
- package/packages/remote-control-server/web/dist/assets/{mermaid.core-C48YvKu4.js → mermaid.core-BnVRH5R_.js} +5 -5
- package/packages/remote-control-server/web/dist/assets/{mindmap-definition-RKZ34NQL-BfmcTuCA.js → mindmap-definition-RKZ34NQL-R3usKqMg.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{pieDiagram-4H26LBE5-DVNZpnfb.js → pieDiagram-4H26LBE5-U1XXn3t9.js} +1 -1
- package/{dist/rcs-web/assets/quadrantDiagram-W4KKPZXB-COL55Z3i.js → packages/remote-control-server/web/dist/assets/quadrantDiagram-W4KKPZXB-CocIpolQ.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{requirementDiagram-4Y6WPE33-CFczYQ0a.js → requirementDiagram-4Y6WPE33-DX7pHOr5.js} +1 -1
- package/{dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-BrQEv3WQ.js → packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-TD6XCrii.js} +1 -1
- package/{dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-CMxtYmQu.js → packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-EyZvfcbT.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-AJRCARHV-Dw9xJZ-A.js → stateDiagram-AJRCARHV-B_SU6QSv.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{stateDiagram-v2-BHNVJYJU-Br0D-weX.js → stateDiagram-v2-BHNVJYJU-C8vEqOLP.js} +1 -1
- package/{dist/rcs-web/assets/timeline-definition-PNZ67QCA-DuWDwYBt.js → packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-C2XHcj96.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{vennDiagram-CIIHVFJN--7IV65HQ.js → vennDiagram-CIIHVFJN-aAmhPOm3.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/{wardleyDiagram-YWT4CUSO-CVTgWbvT.js → wardleyDiagram-YWT4CUSO-Db_mMfd6.js} +1 -1
- package/packages/remote-control-server/web/dist/assets/workerType-Bd-zteMi.js +1 -0
- package/{dist/rcs-web/assets/xychartDiagram-2RQKCTM6-B9om4xAF.js → packages/remote-control-server/web/dist/assets/xychartDiagram-2RQKCTM6-DPjdOqDe.js} +1 -1
- package/packages/remote-control-server/web/dist/index.html +2 -2
- package/dist/rcs-web/assets/AdminPanel-CQU763nr.js +0 -1
- package/dist/rcs-web/assets/Dashboard-B1hQfqI9.js +0 -1
- package/dist/rcs-web/assets/Join-7hMl360t.js +0 -1
- package/dist/rcs-web/assets/Login-BE8mNc0U.js +0 -1
- package/dist/rcs-web/assets/SessionVisibilityBadge-CQN3bJW4.js +0 -11
- package/dist/rcs-web/assets/Setup-CqZ5gEBQ.js +0 -1
- package/dist/rcs-web/assets/TeamCreate-DSYdTaPe.js +0 -1
- package/dist/rcs-web/assets/TeamDetail-CmJGsgOP.js +0 -1
- package/dist/rcs-web/assets/TeamList-BMS_Qq8U.js +0 -1
- package/dist/rcs-web/assets/TeamSettings-C0sYgCFT.js +0 -1
- package/dist/rcs-web/assets/UserSettings-CqzeJ5cc.js +0 -1
- package/dist/rcs-web/assets/channel-Daz3yMSu.js +0 -1
- package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-DufdcV1P.js +0 -1
- package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-DufdcV1P.js +0 -1
- package/dist/rcs-web/assets/main-EP6Lac2m.css +0 -1
- package/dist/rcs-web/assets/main-J6cPs2y8.js +0 -253
- package/packages/remote-control-server/web/dist/assets/AdminPanel-CQU763nr.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Dashboard-B1hQfqI9.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Join-7hMl360t.js +0 -1
- package/packages/remote-control-server/web/dist/assets/Login-BE8mNc0U.js +0 -1
- package/packages/remote-control-server/web/dist/assets/SessionVisibilityBadge-CQN3bJW4.js +0 -11
- package/packages/remote-control-server/web/dist/assets/Setup-CqZ5gEBQ.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamCreate-DSYdTaPe.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamDetail-CmJGsgOP.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamList-BMS_Qq8U.js +0 -1
- package/packages/remote-control-server/web/dist/assets/TeamSettings-C0sYgCFT.js +0 -1
- package/packages/remote-control-server/web/dist/assets/UserSettings-CqzeJ5cc.js +0 -1
- package/packages/remote-control-server/web/dist/assets/channel-Daz3yMSu.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-DufdcV1P.js +0 -1
- package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-DufdcV1P.js +0 -1
- package/packages/remote-control-server/web/dist/assets/main-EP6Lac2m.css +0 -1
- package/packages/remote-control-server/web/dist/assets/main-J6cPs2y8.js +0 -253
|
@@ -3,6 +3,10 @@ import { randomUUID, createHash } from 'node:crypto'
|
|
|
3
3
|
import { getDb } from '../../db/sqlite'
|
|
4
4
|
import { sessionAuth } from '../../auth/middleware'
|
|
5
5
|
import { SYSTEM_USER_ID } from '../../auth/constants'
|
|
6
|
+
import {
|
|
7
|
+
storeClaimEnvironment,
|
|
8
|
+
storeGetEnvironmentOwnership,
|
|
9
|
+
} from '../../store'
|
|
6
10
|
|
|
7
11
|
const app = new Hono()
|
|
8
12
|
|
|
@@ -31,10 +35,20 @@ function getUserInfo(c: import('hono').Context): UserInfo {
|
|
|
31
35
|
const userId = c.get('userId') as string
|
|
32
36
|
const isAdminCtx = c.get('isAdmin') as boolean
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
// API key bypass — system admin identity (no real user row).
|
|
39
|
+
if (userId === SYSTEM_USER_ID) {
|
|
35
40
|
return { userId: SYSTEM_USER_ID, isAdmin: true, role: 'admin' }
|
|
36
41
|
}
|
|
37
42
|
|
|
43
|
+
// Cookie-authenticated admin — preserve real userId so team ownership
|
|
44
|
+
// and membership queries resolve correctly. Previously this branch
|
|
45
|
+
// overwrote userId with SYSTEM_USER_ID, causing admin-created teams
|
|
46
|
+
// to be attributed to the first admin row in the DB rather than the
|
|
47
|
+
// actual creator, and breaking GET /teams for the logged-in admin.
|
|
48
|
+
if (isAdminCtx) {
|
|
49
|
+
return { userId, isAdmin: true, role: 'admin' }
|
|
50
|
+
}
|
|
51
|
+
|
|
38
52
|
// Look up user role from DB
|
|
39
53
|
const db = getDb()
|
|
40
54
|
const row = db
|
|
@@ -228,6 +242,26 @@ app.get('/teams', withAuth, async c => {
|
|
|
228
242
|
// GET /teams/:id — Get team details
|
|
229
243
|
// ---------------------------------------------------------------------------
|
|
230
244
|
|
|
245
|
+
app.get('/teams/by-slug/:slug', withAuth, async c => {
|
|
246
|
+
const slug = c.req.param('slug')!
|
|
247
|
+
const user = getUserInfo(c)
|
|
248
|
+
|
|
249
|
+
const db = getDb()
|
|
250
|
+
const team = db
|
|
251
|
+
.query('SELECT * FROM teams WHERE slug = $slug AND deleted_at IS NULL')
|
|
252
|
+
.get({ $slug: slug }) as Record<string, unknown> | null
|
|
253
|
+
if (!team) {
|
|
254
|
+
return c.json({ error: 'Team not found' }, 404)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const teamRole = getTeamRole(team.id as string, user)
|
|
258
|
+
if (!teamRole) {
|
|
259
|
+
return c.json({ error: 'Not a team member' }, 403)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return c.json(team, 200)
|
|
263
|
+
})
|
|
264
|
+
|
|
231
265
|
app.get('/teams/:id', withAuth, async c => {
|
|
232
266
|
const teamId = c.req.param('id')!
|
|
233
267
|
const user = getUserInfo(c)
|
|
@@ -816,10 +850,10 @@ app.post('/environments/:id/transfer', withAuth, async c => {
|
|
|
816
850
|
403,
|
|
817
851
|
)
|
|
818
852
|
}
|
|
819
|
-
} else if (!user.isAdmin) {
|
|
820
|
-
// Environment not in any team — only admin can transfer
|
|
821
|
-
return c.json({ error: 'Environment not found in any team' }, 404)
|
|
822
853
|
}
|
|
854
|
+
// Personal environment (no source team): any user who is admin/owner of
|
|
855
|
+
// the target team can claim it. This lets the Web UI "link personal env
|
|
856
|
+
// to this team" flow work without requiring admin role.
|
|
823
857
|
|
|
824
858
|
// Check caller is owner/admin of the target team
|
|
825
859
|
const targetRole = getTeamRole(toTeamId, user)
|
|
@@ -862,4 +896,207 @@ app.post('/environments/:id/transfer', withAuth, async c => {
|
|
|
862
896
|
return c.json({ ok: true }, 200)
|
|
863
897
|
})
|
|
864
898
|
|
|
899
|
+
// ---------------------------------------------------------------------------
|
|
900
|
+
// DELETE /teams/:id/environments/:envId — Unlink environment from team
|
|
901
|
+
// Makes the environment personal again (no team association). Only team
|
|
902
|
+
// owner/admin (or system admin) can unlink. Sessions created under the
|
|
903
|
+
// team scope for this env lose their team ownership.
|
|
904
|
+
// ---------------------------------------------------------------------------
|
|
905
|
+
|
|
906
|
+
app.delete('/teams/:id/environments/:envId', withAuth, async c => {
|
|
907
|
+
const teamId = c.req.param('id')!
|
|
908
|
+
const envId = c.req.param('envId')!
|
|
909
|
+
const user = getUserInfo(c)
|
|
910
|
+
|
|
911
|
+
const result = getTeamOr404(c, teamId)
|
|
912
|
+
if ('error' in result) return result.error
|
|
913
|
+
|
|
914
|
+
const teamRole = getTeamRole(teamId, user)
|
|
915
|
+
if (!user.isAdmin && teamRole !== 'owner' && teamRole !== 'admin') {
|
|
916
|
+
return c.json(
|
|
917
|
+
{ error: 'Only team owner/admin can unlink environments' },
|
|
918
|
+
403,
|
|
919
|
+
)
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
const db = getDb()
|
|
923
|
+
db.query(
|
|
924
|
+
'DELETE FROM team_environments WHERE team_id = $teamId AND environment_id = $envId',
|
|
925
|
+
).run({ $teamId: teamId, $envId: envId })
|
|
926
|
+
|
|
927
|
+
// Drop team ownership for sessions in this env so they revert to personal.
|
|
928
|
+
db.query(
|
|
929
|
+
`DELETE FROM session_owners
|
|
930
|
+
WHERE owner_type = 'team' AND owner_id = $teamId
|
|
931
|
+
AND session_id IN (
|
|
932
|
+
SELECT id FROM sessions WHERE environment_id = $envId
|
|
933
|
+
)`,
|
|
934
|
+
).run({ $teamId: teamId, $envId: envId })
|
|
935
|
+
|
|
936
|
+
return c.json({ ok: true }, 200)
|
|
937
|
+
})
|
|
938
|
+
|
|
939
|
+
// ---------------------------------------------------------------------------
|
|
940
|
+
// POST /web/environments/claim — Claim an unowned environment.
|
|
941
|
+
// Worker registers env without --user-id and without --team-id → env gets a
|
|
942
|
+
// claim_token, worker prints /code/claim/<token>. First logged-in user to
|
|
943
|
+
// POST here with the matching token becomes the env's owner.
|
|
944
|
+
// ---------------------------------------------------------------------------
|
|
945
|
+
|
|
946
|
+
app.post('/environments/claim', withAuth, async c => {
|
|
947
|
+
const user = getUserInfo(c)
|
|
948
|
+
let body: Record<string, unknown>
|
|
949
|
+
try {
|
|
950
|
+
body = await c.req.json()
|
|
951
|
+
} catch {
|
|
952
|
+
return c.json({ error: 'Invalid JSON' }, 400)
|
|
953
|
+
}
|
|
954
|
+
const claimToken = body.claim_token
|
|
955
|
+
if (typeof claimToken !== 'string' || !claimToken.startsWith('clm_')) {
|
|
956
|
+
return c.json({ error: 'Invalid claim_token' }, 400)
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
const db = getDb()
|
|
960
|
+
const row = db
|
|
961
|
+
.query(
|
|
962
|
+
'SELECT id, owner_user_id, claim_expires_at FROM environments WHERE claim_token = $ct',
|
|
963
|
+
)
|
|
964
|
+
.get({ $ct: claimToken }) as {
|
|
965
|
+
id: string
|
|
966
|
+
owner_user_id: string | null
|
|
967
|
+
claim_expires_at: string | null
|
|
968
|
+
} | null
|
|
969
|
+
if (!row) {
|
|
970
|
+
return c.json({ error: 'Claim token not found' }, 404)
|
|
971
|
+
}
|
|
972
|
+
if (row.owner_user_id !== null) {
|
|
973
|
+
return c.json({ error: 'Environment already claimed' }, 409)
|
|
974
|
+
}
|
|
975
|
+
if (
|
|
976
|
+
row.claim_expires_at &&
|
|
977
|
+
new Date(row.claim_expires_at).getTime() < Date.now()
|
|
978
|
+
) {
|
|
979
|
+
return c.json({ error: 'Claim token expired' }, 410)
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
const ok = storeClaimEnvironment(row.id, user.userId)
|
|
983
|
+
if (!ok) {
|
|
984
|
+
return c.json({ error: 'Environment not found or already claimed' }, 409)
|
|
985
|
+
}
|
|
986
|
+
return c.json({ ok: true, environment_id: row.id }, 200)
|
|
987
|
+
})
|
|
988
|
+
|
|
989
|
+
// ---------------------------------------------------------------------------
|
|
990
|
+
// POST /web/sessions/:id/transfer — Transfer session between team/personal.
|
|
991
|
+
// Body: { toTeamId: string | null }. toTeamId = null strips team owner
|
|
992
|
+
// (revert to personal); toTeamId = <team> sets team owner (team members gain
|
|
993
|
+
// visibility). Caller must be the session's user owner or admin.
|
|
994
|
+
// ---------------------------------------------------------------------------
|
|
995
|
+
|
|
996
|
+
app.post('/sessions/:id/transfer', withAuth, async c => {
|
|
997
|
+
const sessionId = c.req.param('id')!
|
|
998
|
+
const user = getUserInfo(c)
|
|
999
|
+
|
|
1000
|
+
let body: Record<string, unknown>
|
|
1001
|
+
try {
|
|
1002
|
+
body = await c.req.json()
|
|
1003
|
+
} catch {
|
|
1004
|
+
return c.json({ error: 'Invalid JSON' }, 400)
|
|
1005
|
+
}
|
|
1006
|
+
const toTeamId = body.toTeamId
|
|
1007
|
+
if (toTeamId !== null && typeof toTeamId !== 'string') {
|
|
1008
|
+
return c.json({ error: 'toTeamId must be string or null' }, 400)
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
const db = getDb()
|
|
1012
|
+
// Caller must be the session's user owner, or team admin of the session's
|
|
1013
|
+
// current team owner, or system admin.
|
|
1014
|
+
const ownerRow = db
|
|
1015
|
+
.query(
|
|
1016
|
+
`SELECT owner_id FROM session_owners
|
|
1017
|
+
WHERE session_id = $sid AND owner_type = 'user'`,
|
|
1018
|
+
)
|
|
1019
|
+
.get({ $sid: sessionId }) as { owner_id: string } | null
|
|
1020
|
+
const teamOwnerRow = db
|
|
1021
|
+
.query(
|
|
1022
|
+
`SELECT owner_id FROM session_owners
|
|
1023
|
+
WHERE session_id = $sid AND owner_type = 'team'`,
|
|
1024
|
+
)
|
|
1025
|
+
.get({ $sid: sessionId }) as { owner_id: string } | null
|
|
1026
|
+
|
|
1027
|
+
const isUserOwner = ownerRow?.owner_id === user.userId
|
|
1028
|
+
let isTeamAdmin = false
|
|
1029
|
+
if (teamOwnerRow) {
|
|
1030
|
+
const role = getTeamRole(teamOwnerRow.owner_id, user)
|
|
1031
|
+
isTeamAdmin = role === 'owner' || role === 'admin'
|
|
1032
|
+
}
|
|
1033
|
+
if (!user.isAdmin && !isUserOwner && !isTeamAdmin) {
|
|
1034
|
+
return c.json({ error: 'Not authorized to transfer this session' }, 403)
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// Validate target team if set.
|
|
1038
|
+
if (toTeamId !== null) {
|
|
1039
|
+
const targetTeam = db
|
|
1040
|
+
.query('SELECT id FROM teams WHERE id = $id AND deleted_at IS NULL')
|
|
1041
|
+
.get({ $id: toTeamId })
|
|
1042
|
+
if (!targetTeam) {
|
|
1043
|
+
return c.json({ error: 'Target team not found' }, 404)
|
|
1044
|
+
}
|
|
1045
|
+
// Caller must be admin/owner of target team too (prevent dumping sessions
|
|
1046
|
+
// into teams you can't manage).
|
|
1047
|
+
const targetRole = getTeamRole(toTeamId, user)
|
|
1048
|
+
if (
|
|
1049
|
+
!user.isAdmin &&
|
|
1050
|
+
(!targetRole || (targetRole !== 'owner' && targetRole !== 'admin'))
|
|
1051
|
+
) {
|
|
1052
|
+
return c.json({ error: 'Not authorized in target team' }, 403)
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// Strip existing team owner, then set new one (if any).
|
|
1057
|
+
db.query(
|
|
1058
|
+
`DELETE FROM session_owners WHERE session_id = $sid AND owner_type = 'team'`,
|
|
1059
|
+
).run({ $sid: sessionId })
|
|
1060
|
+
if (toTeamId !== null) {
|
|
1061
|
+
db.query(
|
|
1062
|
+
`INSERT OR IGNORE INTO session_owners (session_id, owner_type, owner_id) VALUES ($sid, 'team', $tid)`,
|
|
1063
|
+
).run({ $sid: sessionId, $tid: toTeamId })
|
|
1064
|
+
}
|
|
1065
|
+
// Update sessions.visibility to match.
|
|
1066
|
+
db.query('UPDATE sessions SET visibility = $v WHERE id = $sid').run({
|
|
1067
|
+
$sid: sessionId,
|
|
1068
|
+
$v: toTeamId !== null ? 'team' : 'private',
|
|
1069
|
+
})
|
|
1070
|
+
return c.json({ ok: true }, 200)
|
|
1071
|
+
})
|
|
1072
|
+
|
|
1073
|
+
// ---------------------------------------------------------------------------
|
|
1074
|
+
// GET /users/search — Search users by username or user_id (for inviting existing users)
|
|
1075
|
+
// Returns up to 20 matches. Only authenticated users can call this.
|
|
1076
|
+
// ---------------------------------------------------------------------------
|
|
1077
|
+
|
|
1078
|
+
app.get('/users/search', withAuth, async c => {
|
|
1079
|
+
const q = (c.req.query('q') || '').trim()
|
|
1080
|
+
if (!q || q.length < 2) {
|
|
1081
|
+
return c.json([], 200)
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
const db = getDb()
|
|
1085
|
+
const pattern = `%${q}%`
|
|
1086
|
+
const rows = db
|
|
1087
|
+
.query(
|
|
1088
|
+
`SELECT id, username, role FROM users
|
|
1089
|
+
WHERE username LIKE $pattern OR id LIKE $pattern
|
|
1090
|
+
ORDER BY username ASC
|
|
1091
|
+
LIMIT 20`,
|
|
1092
|
+
)
|
|
1093
|
+
.all({ $pattern: pattern }) as Array<{
|
|
1094
|
+
id: string
|
|
1095
|
+
username: string
|
|
1096
|
+
role: string
|
|
1097
|
+
}>
|
|
1098
|
+
|
|
1099
|
+
return c.json(rows, 200)
|
|
1100
|
+
})
|
|
1101
|
+
|
|
865
1102
|
export default app
|
|
@@ -17,7 +17,11 @@ import type {
|
|
|
17
17
|
import type { EnvironmentRecord } from '../store'
|
|
18
18
|
|
|
19
19
|
function toResponse(
|
|
20
|
-
row: EnvironmentRecord & {
|
|
20
|
+
row: EnvironmentRecord & {
|
|
21
|
+
teamId?: string | null
|
|
22
|
+
teamName?: string | null
|
|
23
|
+
ownerUserId?: string | null
|
|
24
|
+
},
|
|
21
25
|
): EnvironmentResponse {
|
|
22
26
|
return {
|
|
23
27
|
id: row.id,
|
|
@@ -32,6 +36,7 @@ function toResponse(
|
|
|
32
36
|
capabilities: row.capabilities,
|
|
33
37
|
team_id: row.teamId ?? null,
|
|
34
38
|
team_name: row.teamName ?? null,
|
|
39
|
+
owner_user_id: row.ownerUserId ?? null,
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
42
|
|
|
@@ -39,6 +44,9 @@ export function registerEnvironment(
|
|
|
39
44
|
req: RegisterEnvironmentRequest & {
|
|
40
45
|
metadata?: { worker_type?: string }
|
|
41
46
|
username?: string
|
|
47
|
+
ownerUserId?: string | null
|
|
48
|
+
claimToken?: string | null
|
|
49
|
+
claimExpiresAt?: Date | null
|
|
42
50
|
},
|
|
43
51
|
) {
|
|
44
52
|
const secret = config.apiKeys[0] || ''
|
|
@@ -98,6 +106,9 @@ export function registerEnvironment(
|
|
|
98
106
|
bridgeId: req.bridge_id,
|
|
99
107
|
username: req.username,
|
|
100
108
|
capabilities: req.capabilities,
|
|
109
|
+
ownerUserId: req.ownerUserId,
|
|
110
|
+
claimToken: req.claimToken,
|
|
111
|
+
claimExpiresAt: req.claimExpiresAt,
|
|
101
112
|
})
|
|
102
113
|
|
|
103
114
|
let sessionId: string | undefined
|
|
@@ -116,6 +116,9 @@ export function storeCreateEnvironment(req: {
|
|
|
116
116
|
bridgeId?: string
|
|
117
117
|
username?: string
|
|
118
118
|
capabilities?: Record<string, unknown>
|
|
119
|
+
ownerUserId?: string | null
|
|
120
|
+
claimToken?: string | null
|
|
121
|
+
claimExpiresAt?: Date | null
|
|
119
122
|
}): EnvironmentRecord {
|
|
120
123
|
const id = `env_${randomUUID().replace(/-/g, '')}`
|
|
121
124
|
const now = new Date()
|
|
@@ -141,8 +144,8 @@ export function storeCreateEnvironment(req: {
|
|
|
141
144
|
const db = getDb()
|
|
142
145
|
const secretHash = createHash('sha256').update(record.secret).digest('hex')
|
|
143
146
|
db.query(
|
|
144
|
-
`INSERT OR REPLACE INTO environments (id, secret_hash, machine_name, worker_type, status, last_poll_at, created_at)
|
|
145
|
-
VALUES ($id, $sh, $mn, $wt, $st, $lp, $ca)`,
|
|
147
|
+
`INSERT OR REPLACE INTO environments (id, secret_hash, machine_name, worker_type, status, last_poll_at, created_at, owner_user_id, claim_token, claim_expires_at)
|
|
148
|
+
VALUES ($id, $sh, $mn, $wt, $st, $lp, $ca, $ou, $ct, $ce)`,
|
|
146
149
|
).run({
|
|
147
150
|
$id: id,
|
|
148
151
|
$sh: secretHash,
|
|
@@ -151,6 +154,9 @@ export function storeCreateEnvironment(req: {
|
|
|
151
154
|
$st: record.status,
|
|
152
155
|
$lp: record.lastPollAt?.toISOString() ?? null,
|
|
153
156
|
$ca: record.createdAt.toISOString(),
|
|
157
|
+
$ou: req.ownerUserId ?? null,
|
|
158
|
+
$ct: req.claimToken ?? null,
|
|
159
|
+
$ce: req.claimExpiresAt?.toISOString() ?? null,
|
|
154
160
|
})
|
|
155
161
|
} catch (err) {
|
|
156
162
|
console.error('[store] DB write failed in storeCreateEnvironment:', err)
|
|
@@ -223,13 +229,19 @@ export function storeListActiveEnvironments(): EnvironmentRecord[] {
|
|
|
223
229
|
* LEFT JOINs team_environments + teams (excluding soft-deleted teams).
|
|
224
230
|
*/
|
|
225
231
|
export function storeListActiveEnvironmentsWithTeam(): Array<
|
|
226
|
-
EnvironmentRecord & {
|
|
232
|
+
EnvironmentRecord & {
|
|
233
|
+
teamId: string | null
|
|
234
|
+
teamName: string | null
|
|
235
|
+
ownerUserId: string | null
|
|
236
|
+
}
|
|
227
237
|
> {
|
|
228
238
|
const active = [...environments.values()].filter(e => e.status === 'active')
|
|
229
239
|
if (active.length === 0) return []
|
|
230
240
|
|
|
231
241
|
// Build a map of env_id → { teamId, teamName } from SQLite
|
|
232
242
|
const teamMap = new Map<string, { teamId: string; teamName: string }>()
|
|
243
|
+
// Build a map of env_id → ownerUserId from SQLite
|
|
244
|
+
const ownerMap = new Map<string, string | null>()
|
|
233
245
|
try {
|
|
234
246
|
const db = getDb()
|
|
235
247
|
const rows = db
|
|
@@ -249,12 +261,20 @@ export function storeListActiveEnvironmentsWithTeam(): Array<
|
|
|
249
261
|
teamName: row.team_name,
|
|
250
262
|
})
|
|
251
263
|
}
|
|
264
|
+
const ownerRows = db
|
|
265
|
+
.query(
|
|
266
|
+
`SELECT id, owner_user_id FROM environments WHERE owner_user_id IS NOT NULL`,
|
|
267
|
+
)
|
|
268
|
+
.all() as Array<{ id: string; owner_user_id: string }>
|
|
269
|
+
for (const row of ownerRows) {
|
|
270
|
+
ownerMap.set(row.id, row.owner_user_id)
|
|
271
|
+
}
|
|
252
272
|
} catch (err) {
|
|
253
273
|
console.error(
|
|
254
274
|
'[store] DB read failed in storeListActiveEnvironmentsWithTeam:',
|
|
255
275
|
err,
|
|
256
276
|
)
|
|
257
|
-
// Fall through: return envs without team info
|
|
277
|
+
// Fall through: return envs without team/owner info
|
|
258
278
|
}
|
|
259
279
|
|
|
260
280
|
return active.map(env => {
|
|
@@ -263,10 +283,73 @@ export function storeListActiveEnvironmentsWithTeam(): Array<
|
|
|
263
283
|
...env,
|
|
264
284
|
teamId: team?.teamId ?? null,
|
|
265
285
|
teamName: team?.teamName ?? null,
|
|
286
|
+
ownerUserId: ownerMap.get(env.id) ?? null,
|
|
266
287
|
}
|
|
267
288
|
})
|
|
268
289
|
}
|
|
269
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Look up environment ownership fields from SQLite.
|
|
293
|
+
* Returns null if the environment row doesn't exist.
|
|
294
|
+
*/
|
|
295
|
+
export function storeGetEnvironmentOwnership(envId: string): {
|
|
296
|
+
ownerUserId: string | null
|
|
297
|
+
teamId: string | null
|
|
298
|
+
claimToken: string | null
|
|
299
|
+
claimExpiresAt: string | null
|
|
300
|
+
} | null {
|
|
301
|
+
try {
|
|
302
|
+
const db = getDb()
|
|
303
|
+
const row = db
|
|
304
|
+
.query(
|
|
305
|
+
`SELECT e.owner_user_id, e.claim_token, e.claim_expires_at,
|
|
306
|
+
(SELECT te.team_id FROM team_environments te WHERE te.environment_id = e.id) AS team_id
|
|
307
|
+
FROM environments e WHERE e.id = $id`,
|
|
308
|
+
)
|
|
309
|
+
.get({ $id: envId }) as {
|
|
310
|
+
owner_user_id: string | null
|
|
311
|
+
claim_token: string | null
|
|
312
|
+
claim_expires_at: string | null
|
|
313
|
+
team_id: string | null
|
|
314
|
+
} | null
|
|
315
|
+
if (!row) return null
|
|
316
|
+
return {
|
|
317
|
+
ownerUserId: row.owner_user_id,
|
|
318
|
+
teamId: row.team_id,
|
|
319
|
+
claimToken: row.claim_token,
|
|
320
|
+
claimExpiresAt: row.claim_expires_at,
|
|
321
|
+
}
|
|
322
|
+
} catch (err) {
|
|
323
|
+
console.error(
|
|
324
|
+
'[store] DB read failed in storeGetEnvironmentOwnership:',
|
|
325
|
+
err,
|
|
326
|
+
)
|
|
327
|
+
throw err
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Claim an unowned environment: write owner_user_id and clear claim_token.
|
|
333
|
+
* Returns true if the row was updated, false if env not found or already
|
|
334
|
+
* owned (idempotent — caller checks ownership state first).
|
|
335
|
+
*/
|
|
336
|
+
export function storeClaimEnvironment(envId: string, userId: string): boolean {
|
|
337
|
+
try {
|
|
338
|
+
const db = getDb()
|
|
339
|
+
const result = db
|
|
340
|
+
.query(
|
|
341
|
+
`UPDATE environments
|
|
342
|
+
SET owner_user_id = $userId, claim_token = NULL, claim_expires_at = NULL
|
|
343
|
+
WHERE id = $envId AND owner_user_id IS NULL`,
|
|
344
|
+
)
|
|
345
|
+
.run({ $envId: envId, $userId: userId })
|
|
346
|
+
return result.changes > 0
|
|
347
|
+
} catch (err) {
|
|
348
|
+
console.error('[store] DB write failed in storeClaimEnvironment:', err)
|
|
349
|
+
throw err
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
270
353
|
export function storeListActiveEnvironmentsByUsername(
|
|
271
354
|
username: string,
|
|
272
355
|
): EnvironmentRecord[] {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as d,j as e}from"./vendor-DE_-CLIE.js";import{a1 as x,a2 as o,q as m,Y as s,K as l,i as u}from"./main-CEsvX5rj.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function j(){x();const[a,i]=d.useState([]),{myTeams:r,isLoading:c}=o(),n=d.useCallback(async()=>{try{const t=await m();i(t||[])}catch(t){console.error("Admin: failed to load sessions",t)}},[]);return d.useEffect(()=>{n()},[n]),e.jsx("div",{className:"flex-1 overflow-y-auto",children:e.jsxs("div",{className:"mx-auto max-w-5xl px-4 py-8",children:[e.jsx("h1",{className:"mb-6 font-display text-2xl font-semibold text-text-primary",children:s("admin.title")}),e.jsxs("section",{className:"mb-10",children:[e.jsxs("h2",{className:"mb-4 font-display text-lg font-semibold text-text-primary",children:[s("admin.teams")," (",r.length,")"]}),c?e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-4 text-center text-text-muted",children:s("common.loading")}):r.length===0?e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-4 text-center text-text-muted",children:s("admin.noTeams")}):e.jsx("div",{className:"space-y-2",children:r.map(t=>e.jsxs("a",{href:`/teams/${t.slug}`,className:"flex items-center justify-between rounded-xl border border-border bg-surface-1 px-4 py-3 no-underline transition-colors hover:border-border-light hover:bg-surface-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("span",{className:"font-medium text-text-primary",children:t.name}),e.jsx("span",{className:"ml-2 text-xs text-text-muted",children:t.slug})]}),e.jsx("span",{className:"text-xs text-text-muted",children:l(new Date(t.created_at).getTime()/1e3)})]},t.id))})]}),e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-4 font-display text-lg font-semibold text-text-primary",children:[s("admin.sessions")," (",a.length,")"]}),a.length===0?e.jsx("div",{className:"rounded-xl border border-border bg-surface-1 p-4 text-center text-text-muted",children:s("admin.noSessions")}):e.jsx("div",{className:"space-y-2",children:a.map(t=>e.jsxs("a",{href:`/code/${t.id}`,className:"flex items-center justify-between rounded-xl border border-border bg-surface-1 px-4 py-3 no-underline transition-colors hover:border-border-light hover:bg-surface-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",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}),e.jsx("span",{className:"rounded-full bg-surface-2 px-2 py-0.5 text-xs text-text-muted",children:t.source||"unknown"})]}),e.jsx("div",{className:"truncate text-xs text-text-muted",children:t.id})]}),e.jsxs("div",{className:"ml-4 flex items-center gap-3",children:[e.jsx(u,{status:t.status}),e.jsx("span",{className:"text-xs text-text-muted",children:l(t.updated_at||t.created_at)})]})]},t.id))})]})]})})}export{j as AdminPanel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as a,j as e}from"./vendor-DE_-CLIE.js";import{m as d}from"./main-CEsvX5rj.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function f(){const r=window.location.pathname.split("/"),t=r[r.length-1]||"",[i,s]=a.useState("idle"),[o,c]=a.useState(null),[m,l]=a.useState(null);return a.useEffect(()=>{if(!t||!t.startsWith("clm_")){c("Invalid claim token"),s("error");return}s("claiming"),d(t).then(n=>{l(n.environment_id),s("success")}).catch(n=>{c(n instanceof Error?n.message:"Claim failed"),s("error")})},[t]),i==="claiming"?e.jsx("div",{className:"px-6 py-16 sm:px-10 sm:py-20",children:e.jsx("p",{className:"text-sm text-text-muted",children:"Claiming environment..."})}):i==="error"?e.jsxs("div",{className:"px-6 py-16 sm:px-10 sm:py-20",children:[e.jsx("p",{className:"text-sm text-destructive",children:o}),e.jsx("a",{href:"/code",className:"mt-4 inline-block text-accent hover:underline",children:"Back to dashboard"})]}):e.jsxs("div",{className:"px-6 py-16 sm:px-10 sm:py-20",children:[e.jsxs("header",{className:"mb-10",children:[e.jsx("h1",{className:"font-display text-2xl font-semibold tracking-tight text-text-primary",children:"Environment claimed"}),e.jsx("p",{className:"mt-2 text-sm text-text-muted",children:"You are now the owner of this environment."})]}),e.jsxs("div",{className:"space-y-4",children:[m&&e.jsx("p",{className:"font-mono text-xs text-text-muted",children:m}),e.jsx("a",{href:"/code",className:"inline-block rounded-md bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent/90 transition-colors",children:"Go to dashboard"})]})]})}export{f as Claim};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,e as i}from"./vendor-DE_-CLIE.js";import{G as S,a2 as y,i as N,K as D,a1 as w,Y as n,Q as T,n as E,q as L,r as M,p as B}from"./main-CEsvX5rj.js";import{g as v}from"./workerType-Bd-zteMi.js";import{S as I,D as F,a as O,c as A,d as P,b as $}from"./SessionVisibilityBadge-CN3bz2gb.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function W({teamName:o,className:d}){return o?e.jsx("span",{className:S("inline-flex items-center rounded-full border border-border/60 bg-surface-2 px-2 py-0.5 text-xs text-text-muted",d),children:o}):null}function q({environments:o,onSelectEnvironment:d}){const{activeTeam:u}=y(),m=i.useMemo(()=>u?o.filter(s=>s.team_id===u.id):o.filter(s=>!s.team_id),[o,u]);return!m||m.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:m.map(s=>{const p=s.worker_type==="acp",b=v(s.worker_type),c=b.fullLabel,h=b.colorClass;return e.jsxs("button",{type:"button",onClick:()=>d==null?void 0:d(s),disabled:p,className:`flex w-full items-center justify-between rounded-xl border border-border bg-surface-1 px-4 py-3 text-left transition-colors ${p?"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:s.machine_name||s.id}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${h}`,children:c}),e.jsx(W,{teamName:s.team_name??null})]}),e.jsx("div",{className:"text-sm text-text-muted",children:s.directory||""})]})}),e.jsxs("div",{className:"text-right",children:[e.jsx(N,{status:s.status}),e.jsx("div",{className:"mt-1 text-xs text-text-muted",children:s.branch||""})]})]},s.id)})})}function G({sessions:o,environments:d,onSelect:u,onDelete:m}){const{activeTeam:s,myTeams:p}=y(),b=i.useMemo(()=>{const t=new Map;for(const l of p)t.set(l.id,l.name);return t},[p]),c=i.useMemo(()=>s?o.filter(t=>t.owner_type==="team"&&t.owner_id===s.id):o.filter(t=>t.owner_type==="user"||!t.owner_type),[o,s]);if(!c||c.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 h=new Map;for(const t of d??[])t!=null&&t.id&&t.worker_type&&h.set(t.id,t.worker_type);const f=[...c].sort((t,l)=>(l.updated_at||0)-(t.updated_at||0));return e.jsx("div",{className:"space-y-2",children:f.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:()=>u(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}),t.visibility&&e.jsx(I,{visibility:t.visibility||"private"}),(()=>{var x;let l=t.source==="acp"?"acp":(x=t.environment)==null?void 0:x.worker_type;!l&&t.environment_id&&(l=h.get(t.environment_id));const a=v(l);return e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${a.colorClass}`,children:a.fullLabel})})()]}),e.jsxs("div",{className:"flex items-center gap-2 truncate text-xs text-text-muted",children:[e.jsx("span",{className:"truncate font-mono",children:t.id}),t.owner_type==="team"&&t.owner_id&&e.jsxs("span",{className:"inline-flex items-center gap-2 truncate",children:[e.jsx("span",{className:"text-text-muted/40",children:"|"}),e.jsx("span",{className:"truncate",children:b.get(t.owner_id)||t.owner_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:D(t.created_at||t.updated_at)}),m&&e.jsx("button",{type:"button",onClick:l=>{l.stopPropagation(),m(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 H({open:o,environments:d,onClose:u,onCreated:m}){w();const{activeTeam:s}=y(),[p,b]=i.useState(""),[c,h]=i.useState(""),[f,t]=i.useState("same-dir"),[l,a]=i.useState(""),[x,g]=i.useState(!1),_=i.useMemo(()=>s?d.filter(r=>r.team_id===s.id):d.filter(r=>!r.team_id),[d,s]);i.useEffect(()=>{o&&(b(""),h(""),t("same-dir"),a(""))},[o]);const k=async()=>{g(!0),a("");try{const r={};p.trim()&&(r.title=p.trim()),c&&(r.environment_id=c),r.spawn_mode=f;const j=T();j&&(r.team_id=j);const C=await E(r);m(C)}catch(r){a(r instanceof Error?r.message:n("dialog.createFailed"))}finally{g(!1)}};return e.jsx(F,{open:o,onOpenChange:r=>{r||u()},children:e.jsxs(O,{className:"max-w-md rounded-2xl border-border bg-surface-1 p-6 shadow-2xl",children:[e.jsx(A,{children:e.jsx(P,{className:"font-display text-lg font-semibold text-text-primary",children:n("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:n("dialog.titleOptional")}),e.jsx("input",{type:"text",value:p,onChange:r=>b(r.target.value),placeholder:n("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:n("dialog.environment")}),e.jsxs("select",{value:c,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:"",children:n("dialog.none")}),_.map(r=>{const j=v(r.worker_type).shortLabel;return e.jsxs("option",{value:r.id,children:[r.machine_name||r.id," (",r.branch||n("dialog.noBranch"),") · ",j]},r.id)})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-sm text-text-secondary",children:n("dialog.workspaceMode")}),e.jsxs("select",{value:f,onChange:r=>t(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:n("dialog.sameDir")}),e.jsx("option",{value:"worktree",children:n("dialog.worktree")})]})]}),l&&e.jsx("div",{className:"text-sm text-status-error",children:l})]}),e.jsxs($,{children:[e.jsx("button",{onClick:u,className:"rounded-lg border border-border px-4 py-2 text-sm text-text-secondary hover:bg-surface-2 transition-colors",children:n("common.cancel")}),e.jsx("button",{onClick:k,disabled:x,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:x?n("common.creating"):n("common.create")})]})]})})}function J({onNavigateSession:o}){w();const[d,u]=i.useState([]),[m,s]=i.useState([]),[p,b]=i.useState(!1),c=i.useCallback(async()=>{try{const[a,x]=await Promise.all([L(),M()]);u(a||[]),s(x||[])}catch(a){console.error("Dashboard render error:",a)}},[]);i.useEffect(()=>{c();const a=setInterval(c,1e4);return()=>clearInterval(a)},[c]);const h=a=>{b(!1),o(a.id)},f=i.useCallback(a=>{},[]),t=i.useCallback(a=>{o(a)},[o]),l=i.useCallback(async a=>{if(window.confirm(n("dashboard.confirmDelete").replace("{id}",a)))try{await B(a),u(x=>x.filter(g=>g.id!==a))}catch(x){alert(x instanceof Error?x.message:n("dashboard.deleteFailed"))}},[]);return e.jsx("div",{className:"px-6 py-12 sm:px-10 sm:py-16",children:e.jsxs("div",{children:[e.jsx("h1",{className:"sr-only",children:n("dashboard.title")}),e.jsxs("section",{className:"mb-16",children:[e.jsx("h2",{className:"mb-6 text-sm font-medium text-text-primary",children:n("dashboard.environments")}),e.jsx(q,{environments:m,onSelectEnvironment:f})]}),e.jsxs("section",{children:[e.jsxs("div",{className:"mb-6 flex items-center justify-between",children:[e.jsx("h2",{className:"text-sm font-medium text-text-primary",children:n("dashboard.sessions")}),e.jsx("button",{onClick:()=>b(!0),className:"rounded-md bg-accent px-3 py-1.5 text-sm font-medium text-white hover:bg-accent/90 transition-colors",children:n("dashboard.newSession")})]}),e.jsx(G,{sessions:d,environments:m,onSelect:t,onDelete:l})]}),e.jsx(H,{open:p,environments:m,onClose:()=>b(!1),onCreated:h})]})})}export{J as Dashboard};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as r,j as e}from"./vendor-DE_-CLIE.js";import{a0 as v,Y as t}from"./main-CEsvX5rj.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function E({onSuccess:b,onInvalidInvite:l}){const{join:h}=v(),[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{a0 as f,Y as t}from"./main-CEsvX5rj.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function N({onSuccess:d,onNavigateRegister:c}){const{login:m,registrationAllowed:x}=f(),[a,p]=r.useState(""),[o,b]=r.useState(""),[l,n]=r.useState(""),[i,u]=r.useState(!1),h=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:h,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=>p(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=>b(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")})]}),x&&e.jsx("button",{type:"button",onClick:c,className:"w-full text-center text-sm text-text-muted hover:text-text-primary transition-colors",children:t("auth.login.register")})]})})}export{N as Login};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as r,j as e}from"./vendor-DE_-CLIE.js";import{a0 as y,Y as t}from"./main-CEsvX5rj.js";import"./shiki-mEP5vQQu.js";import"./motion-BILbV7YQ.js";function S({onSuccess:m,onBack:x}){const{register:p}=y(),[n,b]=r.useState(""),[a,h]=r.useState(""),[l,f]=r.useState(""),[i,o]=r.useState(""),[u,d]=r.useState(!1),g=async s=>{if(s.preventDefault(),o(""),a.length<8){o(t("auth.setup.passwordTooShort"));return}if(a!==l){o(t("auth.setup.passwordMismatch"));return}d(!0);try{await p(n,a),m()}catch(c){o(c instanceof Error?c.message:t("auth.register.failed"))}finally{d(!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.register.title")}),e.jsx("p",{className:"mt-2 text-sm text-text-muted",children:t("auth.register.description")})]}),e.jsxs("form",{onSubmit:g,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:n,onChange:s=>b(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:a,onChange:s=>h(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:l,onChange:s=>f(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"})]}),i&&e.jsx("p",{className:"text-sm text-status-error",children:i}),e.jsx("button",{type:"submit",disabled: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:u?t("common.loading"):t("auth.register.submit")})]}),e.jsx("button",{type:"button",onClick:x,className:"w-full text-center text-sm text-text-muted hover:text-text-primary transition-colors",children:t("auth.register.backToLogin")})]})})}export{S as Register};
|