@saluzi/saluzi-edu 0.2.13 → 0.2.15

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.
Files changed (179) hide show
  1. package/dist/cli.js +79 -72
  2. package/dist/rcs-web/assets/AdminPanel-CQU763nr.js +1 -0
  3. package/dist/rcs-web/assets/Dashboard-B1hQfqI9.js +1 -0
  4. package/dist/rcs-web/assets/Join-7hMl360t.js +1 -0
  5. package/{packages/remote-control-server/web/dist/assets/Login-0VGZs85I.js → dist/rcs-web/assets/Login-BE8mNc0U.js} +1 -1
  6. package/dist/rcs-web/assets/SessionDetail-B5C0o1YT.js +55 -0
  7. package/dist/rcs-web/assets/SessionVisibilityBadge-CQN3bJW4.js +11 -0
  8. package/dist/rcs-web/assets/{Setup-C0cjxXMt.js → Setup-CqZ5gEBQ.js} +1 -1
  9. package/dist/rcs-web/assets/{ShareLanding-DUZrreJ7.js → ShareLanding-DBC9gbJo.js} +1 -1
  10. package/dist/rcs-web/assets/TeamCreate-DSYdTaPe.js +1 -0
  11. package/dist/rcs-web/assets/TeamDetail-CmJGsgOP.js +1 -0
  12. package/dist/rcs-web/assets/TeamList-BMS_Qq8U.js +1 -0
  13. package/dist/rcs-web/assets/{TeamSettings-CNVwYwcp.js → TeamSettings-C0sYgCFT.js} +1 -1
  14. package/dist/rcs-web/assets/UserSettings-CqzeJ5cc.js +1 -0
  15. package/{packages/remote-control-server/web/dist/assets/arc-CJxirXEQ.js → dist/rcs-web/assets/arc-DBPKxYzS.js} +1 -1
  16. package/dist/rcs-web/assets/{architectureDiagram-3BPJPVTR-BZvIHrLA.js → architectureDiagram-3BPJPVTR-D88rj_js.js} +1 -1
  17. package/dist/rcs-web/assets/{blockDiagram-GPEHLZMM-3p0y3Ija.js → blockDiagram-GPEHLZMM-xzgUpRMn.js} +1 -1
  18. package/dist/rcs-web/assets/{c4Diagram-AAUBKEIU-Bmz9A1wn.js → c4Diagram-AAUBKEIU-vpg_EoPb.js} +1 -1
  19. package/dist/rcs-web/assets/channel-Daz3yMSu.js +1 -0
  20. package/dist/rcs-web/assets/{chunk-2J33WTMH-B8gQz22j.js → chunk-2J33WTMH-DXWsXvhS.js} +1 -1
  21. package/dist/rcs-web/assets/{chunk-4BX2VUAB-CgLEZsTU.js → chunk-4BX2VUAB-BtTxwj9K.js} +1 -1
  22. package/dist/rcs-web/assets/{chunk-55IACEB6-0mdE_-IS.js → chunk-55IACEB6-D2-Q95qg.js} +1 -1
  23. package/{packages/remote-control-server/web/dist/assets/chunk-727SXJPM-DdtjnIHR.js → dist/rcs-web/assets/chunk-727SXJPM-Ce3e5x8u.js} +1 -1
  24. package/{packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-BtwFPk50.js → dist/rcs-web/assets/chunk-AQP2D5EJ-C0UbKVtd.js} +1 -1
  25. package/dist/rcs-web/assets/{chunk-FMBD7UC4-BcO9mQ0P.js → chunk-FMBD7UC4-BCwppVqh.js} +1 -1
  26. package/dist/rcs-web/assets/{chunk-ND2GUHAM-BvRq13S_.js → chunk-ND2GUHAM-CnOBwWrm.js} +1 -1
  27. package/dist/rcs-web/assets/{chunk-QZHKN3VN-D7GHkPpq.js → chunk-QZHKN3VN-CDdzB71P.js} +1 -1
  28. package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-DufdcV1P.js +1 -0
  29. package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-DufdcV1P.js +1 -0
  30. package/dist/rcs-web/assets/{code-block-IT6T5CEO-B1p-vO-3.js → code-block-IT6T5CEO-C1_H_ztH.js} +1 -1
  31. package/dist/rcs-web/assets/copy-DXU1lQqc.js +6 -0
  32. package/{packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-L0rUZuH5.js → dist/rcs-web/assets/cose-bilkent-S5V4N54A-BC6nfjTF.js} +1 -1
  33. package/dist/rcs-web/assets/{dagre-BM42HDAG-CHGuio22.js → dagre-BM42HDAG-CEPR_pRx.js} +1 -1
  34. package/dist/rcs-web/assets/{diagram-2AECGRRQ-DIDRyQk8.js → diagram-2AECGRRQ-fVMGnSYa.js} +1 -1
  35. package/dist/rcs-web/assets/{diagram-5GNKFQAL-CNubKb6P.js → diagram-5GNKFQAL-BPzN2rbK.js} +1 -1
  36. package/dist/rcs-web/assets/{diagram-KO2AKTUF-CzQh664-.js → diagram-KO2AKTUF-Boneg9n-.js} +1 -1
  37. package/dist/rcs-web/assets/{diagram-LMA3HP47-CWBR7-VG.js → diagram-LMA3HP47-B8AtvjO9.js} +1 -1
  38. package/dist/rcs-web/assets/{diagram-OG6HWLK6-BMHdlbcZ.js → diagram-OG6HWLK6-DjY7A8jK.js} +1 -1
  39. package/{packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-OgT8dC-K.js → dist/rcs-web/assets/erDiagram-TEJ5UH35-C1BEfKxk.js} +1 -1
  40. package/{packages/remote-control-server/web/dist/assets/flowDiagram-I6XJVG4X-DRrCY2oB.js → dist/rcs-web/assets/flowDiagram-I6XJVG4X-7TbI9MLV.js} +1 -1
  41. package/dist/rcs-web/assets/{ganttDiagram-6RSMTGT7-DctpzEKN.js → ganttDiagram-6RSMTGT7-CMAV0A01.js} +1 -1
  42. package/dist/rcs-web/assets/{gitGraphDiagram-PVQCEYII-5KpLszm9.js → gitGraphDiagram-PVQCEYII-DAlR8G81.js} +1 -1
  43. package/dist/rcs-web/assets/{infoDiagram-5YYISTIA-BAKD_Tt7.js → infoDiagram-5YYISTIA-0T0DAV4W.js} +1 -1
  44. package/{packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-VHOPG4Nc.js → dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-BAw8txlx.js} +1 -1
  45. package/{packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-BtGih-ik.js → dist/rcs-web/assets/journeyDiagram-JHISSGLW-DWvYKwz-.js} +1 -1
  46. package/dist/rcs-web/assets/{kanban-definition-UN3LZRKU-BsEGZsD1.js → kanban-definition-UN3LZRKU-Qzqw1H5B.js} +1 -1
  47. package/{packages/remote-control-server/web/dist/assets/linear-Dj636PNG.js → dist/rcs-web/assets/linear-D2KIJoCI.js} +1 -1
  48. package/dist/rcs-web/assets/main-J6cPs2y8.js +253 -0
  49. package/dist/rcs-web/assets/{mermaid-VLURNSYL-DutpHHm9.js → mermaid-VLURNSYL-CxWk1wHz.js} +4 -4
  50. package/dist/rcs-web/assets/{mermaid.core-XHHf0pen.js → mermaid.core-C48YvKu4.js} +5 -5
  51. package/dist/rcs-web/assets/{mindmap-definition-RKZ34NQL-BBa8V_3g.js → mindmap-definition-RKZ34NQL-BfmcTuCA.js} +1 -1
  52. package/dist/rcs-web/assets/{pieDiagram-4H26LBE5-BuNEdo9H.js → pieDiagram-4H26LBE5-DVNZpnfb.js} +1 -1
  53. package/dist/rcs-web/assets/{quadrantDiagram-W4KKPZXB-CsJgyQIN.js → quadrantDiagram-W4KKPZXB-COL55Z3i.js} +1 -1
  54. package/dist/rcs-web/assets/{requirementDiagram-4Y6WPE33-DqMJZ914.js → requirementDiagram-4Y6WPE33-CFczYQ0a.js} +1 -1
  55. package/{packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-CVsz09q2.js → dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-BrQEv3WQ.js} +1 -1
  56. package/{packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-BRp4Wddn.js → dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-CMxtYmQu.js} +1 -1
  57. package/{packages/remote-control-server/web/dist/assets/stateDiagram-AJRCARHV-S-QqQr-D.js → dist/rcs-web/assets/stateDiagram-AJRCARHV-Dw9xJZ-A.js} +1 -1
  58. package/dist/rcs-web/assets/{stateDiagram-v2-BHNVJYJU-D77KfDr-.js → stateDiagram-v2-BHNVJYJU-Br0D-weX.js} +1 -1
  59. package/{packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-De8bFWnE.js → dist/rcs-web/assets/timeline-definition-PNZ67QCA-DuWDwYBt.js} +1 -1
  60. package/dist/rcs-web/assets/{vennDiagram-CIIHVFJN-Dikwrn1L.js → vennDiagram-CIIHVFJN--7IV65HQ.js} +1 -1
  61. package/dist/rcs-web/assets/{wardleyDiagram-YWT4CUSO-DUzpiV6H.js → wardleyDiagram-YWT4CUSO-CVTgWbvT.js} +1 -1
  62. package/dist/rcs-web/assets/{xychartDiagram-2RQKCTM6-OZNbB32D.js → xychartDiagram-2RQKCTM6-B9om4xAF.js} +1 -1
  63. package/dist/rcs-web/index.html +1 -1
  64. package/package.json +1 -1
  65. package/packages/remote-control-server/src/__tests__/auth-login.test.ts +21 -4
  66. package/packages/remote-control-server/src/__tests__/auth-security.test.ts +12 -6
  67. package/packages/remote-control-server/src/__tests__/data-layer-round2.test.ts +12 -11
  68. package/packages/remote-control-server/src/__tests__/db-isolation.test.ts +61 -0
  69. package/packages/remote-control-server/src/__tests__/low-priority-fixes.test.ts +178 -0
  70. package/packages/remote-control-server/src/__tests__/middleware.test.ts +4 -4
  71. package/packages/remote-control-server/src/__tests__/route-mounting.test.ts +26 -8
  72. package/packages/remote-control-server/src/__tests__/security-fixes.test.ts +32 -27
  73. package/packages/remote-control-server/src/__tests__/security-round3.test.ts +5 -1
  74. package/packages/remote-control-server/src/__tests__/team-filter-api.test.ts +280 -0
  75. package/packages/remote-control-server/src/__tests__/team-session-env.test.ts +169 -0
  76. package/packages/remote-control-server/src/__tests__/teams.test.ts +7 -0
  77. package/packages/remote-control-server/src/auth/csrf.ts +1 -3
  78. package/packages/remote-control-server/src/auth/middleware.ts +13 -4
  79. package/packages/remote-control-server/src/index.ts +11 -8
  80. package/packages/remote-control-server/src/routes/v1/environments.ts +12 -9
  81. package/packages/remote-control-server/src/routes/v1/sessions.ts +1 -1
  82. package/packages/remote-control-server/src/routes/web/auth-routes.ts +3 -1
  83. package/packages/remote-control-server/src/routes/web/auth.ts +2 -1
  84. package/packages/remote-control-server/src/routes/web/environments.ts +22 -4
  85. package/packages/remote-control-server/src/routes/web/sessions.ts +24 -12
  86. package/packages/remote-control-server/src/routes/web/shares.ts +11 -2
  87. package/packages/remote-control-server/src/routes/web/teams.ts +6 -9
  88. package/packages/remote-control-server/src/services/environment.ts +8 -3
  89. package/packages/remote-control-server/src/services/session.ts +56 -45
  90. package/packages/remote-control-server/src/store.ts +128 -7
  91. package/packages/remote-control-server/src/types/api.ts +8 -1
  92. package/packages/remote-control-server/web/dist/assets/AdminPanel-CQU763nr.js +1 -0
  93. package/packages/remote-control-server/web/dist/assets/Dashboard-B1hQfqI9.js +1 -0
  94. package/packages/remote-control-server/web/dist/assets/Join-7hMl360t.js +1 -0
  95. package/{dist/rcs-web/assets/Login-0VGZs85I.js → packages/remote-control-server/web/dist/assets/Login-BE8mNc0U.js} +1 -1
  96. package/packages/remote-control-server/web/dist/assets/SessionDetail-B5C0o1YT.js +55 -0
  97. package/packages/remote-control-server/web/dist/assets/SessionVisibilityBadge-CQN3bJW4.js +11 -0
  98. package/packages/remote-control-server/web/dist/assets/{Setup-C0cjxXMt.js → Setup-CqZ5gEBQ.js} +1 -1
  99. package/packages/remote-control-server/web/dist/assets/{ShareLanding-DUZrreJ7.js → ShareLanding-DBC9gbJo.js} +1 -1
  100. package/packages/remote-control-server/web/dist/assets/TeamCreate-DSYdTaPe.js +1 -0
  101. package/packages/remote-control-server/web/dist/assets/TeamDetail-CmJGsgOP.js +1 -0
  102. package/packages/remote-control-server/web/dist/assets/TeamList-BMS_Qq8U.js +1 -0
  103. package/packages/remote-control-server/web/dist/assets/{TeamSettings-CNVwYwcp.js → TeamSettings-C0sYgCFT.js} +1 -1
  104. package/packages/remote-control-server/web/dist/assets/UserSettings-CqzeJ5cc.js +1 -0
  105. package/{dist/rcs-web/assets/arc-CJxirXEQ.js → packages/remote-control-server/web/dist/assets/arc-DBPKxYzS.js} +1 -1
  106. package/packages/remote-control-server/web/dist/assets/{architectureDiagram-3BPJPVTR-BZvIHrLA.js → architectureDiagram-3BPJPVTR-D88rj_js.js} +1 -1
  107. package/packages/remote-control-server/web/dist/assets/{blockDiagram-GPEHLZMM-3p0y3Ija.js → blockDiagram-GPEHLZMM-xzgUpRMn.js} +1 -1
  108. package/packages/remote-control-server/web/dist/assets/{c4Diagram-AAUBKEIU-Bmz9A1wn.js → c4Diagram-AAUBKEIU-vpg_EoPb.js} +1 -1
  109. package/packages/remote-control-server/web/dist/assets/channel-Daz3yMSu.js +1 -0
  110. package/packages/remote-control-server/web/dist/assets/{chunk-2J33WTMH-B8gQz22j.js → chunk-2J33WTMH-DXWsXvhS.js} +1 -1
  111. package/packages/remote-control-server/web/dist/assets/{chunk-4BX2VUAB-CgLEZsTU.js → chunk-4BX2VUAB-BtTxwj9K.js} +1 -1
  112. package/packages/remote-control-server/web/dist/assets/{chunk-55IACEB6-0mdE_-IS.js → chunk-55IACEB6-D2-Q95qg.js} +1 -1
  113. package/{dist/rcs-web/assets/chunk-727SXJPM-DdtjnIHR.js → packages/remote-control-server/web/dist/assets/chunk-727SXJPM-Ce3e5x8u.js} +1 -1
  114. package/{dist/rcs-web/assets/chunk-AQP2D5EJ-BtwFPk50.js → packages/remote-control-server/web/dist/assets/chunk-AQP2D5EJ-C0UbKVtd.js} +1 -1
  115. package/packages/remote-control-server/web/dist/assets/{chunk-FMBD7UC4-BcO9mQ0P.js → chunk-FMBD7UC4-BCwppVqh.js} +1 -1
  116. package/packages/remote-control-server/web/dist/assets/{chunk-ND2GUHAM-BvRq13S_.js → chunk-ND2GUHAM-CnOBwWrm.js} +1 -1
  117. package/packages/remote-control-server/web/dist/assets/{chunk-QZHKN3VN-D7GHkPpq.js → chunk-QZHKN3VN-CDdzB71P.js} +1 -1
  118. package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-DufdcV1P.js +1 -0
  119. package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-DufdcV1P.js +1 -0
  120. package/packages/remote-control-server/web/dist/assets/{code-block-IT6T5CEO-B1p-vO-3.js → code-block-IT6T5CEO-C1_H_ztH.js} +1 -1
  121. package/packages/remote-control-server/web/dist/assets/copy-DXU1lQqc.js +6 -0
  122. package/{dist/rcs-web/assets/cose-bilkent-S5V4N54A-L0rUZuH5.js → packages/remote-control-server/web/dist/assets/cose-bilkent-S5V4N54A-BC6nfjTF.js} +1 -1
  123. package/packages/remote-control-server/web/dist/assets/{dagre-BM42HDAG-CHGuio22.js → dagre-BM42HDAG-CEPR_pRx.js} +1 -1
  124. package/packages/remote-control-server/web/dist/assets/{diagram-2AECGRRQ-DIDRyQk8.js → diagram-2AECGRRQ-fVMGnSYa.js} +1 -1
  125. package/packages/remote-control-server/web/dist/assets/{diagram-5GNKFQAL-CNubKb6P.js → diagram-5GNKFQAL-BPzN2rbK.js} +1 -1
  126. package/packages/remote-control-server/web/dist/assets/{diagram-KO2AKTUF-CzQh664-.js → diagram-KO2AKTUF-Boneg9n-.js} +1 -1
  127. package/packages/remote-control-server/web/dist/assets/{diagram-LMA3HP47-CWBR7-VG.js → diagram-LMA3HP47-B8AtvjO9.js} +1 -1
  128. package/packages/remote-control-server/web/dist/assets/{diagram-OG6HWLK6-BMHdlbcZ.js → diagram-OG6HWLK6-DjY7A8jK.js} +1 -1
  129. package/{dist/rcs-web/assets/erDiagram-TEJ5UH35-OgT8dC-K.js → packages/remote-control-server/web/dist/assets/erDiagram-TEJ5UH35-C1BEfKxk.js} +1 -1
  130. package/{dist/rcs-web/assets/flowDiagram-I6XJVG4X-DRrCY2oB.js → packages/remote-control-server/web/dist/assets/flowDiagram-I6XJVG4X-7TbI9MLV.js} +1 -1
  131. package/packages/remote-control-server/web/dist/assets/{ganttDiagram-6RSMTGT7-DctpzEKN.js → ganttDiagram-6RSMTGT7-CMAV0A01.js} +1 -1
  132. package/packages/remote-control-server/web/dist/assets/{gitGraphDiagram-PVQCEYII-5KpLszm9.js → gitGraphDiagram-PVQCEYII-DAlR8G81.js} +1 -1
  133. package/packages/remote-control-server/web/dist/assets/{infoDiagram-5YYISTIA-BAKD_Tt7.js → infoDiagram-5YYISTIA-0T0DAV4W.js} +1 -1
  134. package/{dist/rcs-web/assets/ishikawaDiagram-YF4QCWOH-VHOPG4Nc.js → packages/remote-control-server/web/dist/assets/ishikawaDiagram-YF4QCWOH-BAw8txlx.js} +1 -1
  135. package/{dist/rcs-web/assets/journeyDiagram-JHISSGLW-BtGih-ik.js → packages/remote-control-server/web/dist/assets/journeyDiagram-JHISSGLW-DWvYKwz-.js} +1 -1
  136. package/packages/remote-control-server/web/dist/assets/{kanban-definition-UN3LZRKU-BsEGZsD1.js → kanban-definition-UN3LZRKU-Qzqw1H5B.js} +1 -1
  137. package/{dist/rcs-web/assets/linear-Dj636PNG.js → packages/remote-control-server/web/dist/assets/linear-D2KIJoCI.js} +1 -1
  138. package/packages/remote-control-server/web/dist/assets/main-J6cPs2y8.js +253 -0
  139. package/packages/remote-control-server/web/dist/assets/{mermaid-VLURNSYL-DutpHHm9.js → mermaid-VLURNSYL-CxWk1wHz.js} +4 -4
  140. package/packages/remote-control-server/web/dist/assets/{mermaid.core-XHHf0pen.js → mermaid.core-C48YvKu4.js} +5 -5
  141. package/packages/remote-control-server/web/dist/assets/{mindmap-definition-RKZ34NQL-BBa8V_3g.js → mindmap-definition-RKZ34NQL-BfmcTuCA.js} +1 -1
  142. package/packages/remote-control-server/web/dist/assets/{pieDiagram-4H26LBE5-BuNEdo9H.js → pieDiagram-4H26LBE5-DVNZpnfb.js} +1 -1
  143. package/packages/remote-control-server/web/dist/assets/{quadrantDiagram-W4KKPZXB-CsJgyQIN.js → quadrantDiagram-W4KKPZXB-COL55Z3i.js} +1 -1
  144. package/packages/remote-control-server/web/dist/assets/{requirementDiagram-4Y6WPE33-DqMJZ914.js → requirementDiagram-4Y6WPE33-CFczYQ0a.js} +1 -1
  145. package/{dist/rcs-web/assets/sankeyDiagram-5OEKKPKP-CVsz09q2.js → packages/remote-control-server/web/dist/assets/sankeyDiagram-5OEKKPKP-BrQEv3WQ.js} +1 -1
  146. package/{dist/rcs-web/assets/sequenceDiagram-3UESZ5HK-BRp4Wddn.js → packages/remote-control-server/web/dist/assets/sequenceDiagram-3UESZ5HK-CMxtYmQu.js} +1 -1
  147. package/{dist/rcs-web/assets/stateDiagram-AJRCARHV-S-QqQr-D.js → packages/remote-control-server/web/dist/assets/stateDiagram-AJRCARHV-Dw9xJZ-A.js} +1 -1
  148. package/packages/remote-control-server/web/dist/assets/{stateDiagram-v2-BHNVJYJU-D77KfDr-.js → stateDiagram-v2-BHNVJYJU-Br0D-weX.js} +1 -1
  149. package/{dist/rcs-web/assets/timeline-definition-PNZ67QCA-De8bFWnE.js → packages/remote-control-server/web/dist/assets/timeline-definition-PNZ67QCA-DuWDwYBt.js} +1 -1
  150. package/packages/remote-control-server/web/dist/assets/{vennDiagram-CIIHVFJN-Dikwrn1L.js → vennDiagram-CIIHVFJN--7IV65HQ.js} +1 -1
  151. package/packages/remote-control-server/web/dist/assets/{wardleyDiagram-YWT4CUSO-DUzpiV6H.js → wardleyDiagram-YWT4CUSO-CVTgWbvT.js} +1 -1
  152. package/packages/remote-control-server/web/dist/assets/{xychartDiagram-2RQKCTM6-OZNbB32D.js → xychartDiagram-2RQKCTM6-B9om4xAF.js} +1 -1
  153. package/packages/remote-control-server/web/dist/index.html +1 -1
  154. package/dist/rcs-web/assets/Dashboard-YYwDrKTN.js +0 -1
  155. package/dist/rcs-web/assets/Join-DKCP5X6X.js +0 -1
  156. package/dist/rcs-web/assets/SessionDetail-DmK-DfBQ.js +0 -50
  157. package/dist/rcs-web/assets/TeamCreate-B8ZV6EdY.js +0 -1
  158. package/dist/rcs-web/assets/TeamDetail-DBAsJ__i.js +0 -11
  159. package/dist/rcs-web/assets/TeamList-C-Hte4nV.js +0 -1
  160. package/dist/rcs-web/assets/UserSettings-DRdz9kYE.js +0 -1
  161. package/dist/rcs-web/assets/channel-DaI_n8dp.js +0 -1
  162. package/dist/rcs-web/assets/classDiagram-4FO5ZUOK-pYllpkOq.js +0 -1
  163. package/dist/rcs-web/assets/classDiagram-v2-Q7XG4LA2-pYllpkOq.js +0 -1
  164. package/dist/rcs-web/assets/main-CkqtCllF.js +0 -238
  165. package/dist/rcs-web/assets/useTeams-CqJOqEy1.js +0 -1
  166. package/dist/rcs-web/assets/workerType-DOQ0AHrq.js +0 -1
  167. package/packages/remote-control-server/web/dist/assets/Dashboard-YYwDrKTN.js +0 -1
  168. package/packages/remote-control-server/web/dist/assets/Join-DKCP5X6X.js +0 -1
  169. package/packages/remote-control-server/web/dist/assets/SessionDetail-DmK-DfBQ.js +0 -50
  170. package/packages/remote-control-server/web/dist/assets/TeamCreate-B8ZV6EdY.js +0 -1
  171. package/packages/remote-control-server/web/dist/assets/TeamDetail-DBAsJ__i.js +0 -11
  172. package/packages/remote-control-server/web/dist/assets/TeamList-C-Hte4nV.js +0 -1
  173. package/packages/remote-control-server/web/dist/assets/UserSettings-DRdz9kYE.js +0 -1
  174. package/packages/remote-control-server/web/dist/assets/channel-DaI_n8dp.js +0 -1
  175. package/packages/remote-control-server/web/dist/assets/classDiagram-4FO5ZUOK-pYllpkOq.js +0 -1
  176. package/packages/remote-control-server/web/dist/assets/classDiagram-v2-Q7XG4LA2-pYllpkOq.js +0 -1
  177. package/packages/remote-control-server/web/dist/assets/main-CkqtCllF.js +0 -238
  178. package/packages/remote-control-server/web/dist/assets/useTeams-CqJOqEy1.js +0 -1
  179. package/packages/remote-control-server/web/dist/assets/workerType-DOQ0AHrq.js +0 -1
@@ -0,0 +1,169 @@
1
+ import { describe, test, expect, beforeEach, mock } from 'bun:test'
2
+ import { mockConfigModule } from './helpers/mock-config'
3
+
4
+ mock.module('../config', () => mockConfigModule())
5
+
6
+ import { Hono } from 'hono'
7
+ import { Database } from 'bun:sqlite'
8
+ import { randomUUID } from 'node:crypto'
9
+ import { tmpdir } from 'node:os'
10
+ import { resolve } from 'node:path'
11
+ import { unlinkSync, existsSync } from 'node:fs'
12
+ import webSessions from '../routes/web/sessions'
13
+ import webEnvironments from '../routes/web/environments'
14
+ import { storeReset, storeCreateEnvironment, storeBindSession } from '../store'
15
+ import { initDatabase, resetDbSingleton, getDb } from '../db/sqlite'
16
+ import { issueSessionToken } from '../auth/session'
17
+
18
+ function freshDb(): Database {
19
+ try { resetDbSingleton() } catch {}
20
+ const path = resolve(tmpdir(), `rcs-team-${randomUUID().replace(/-/g, '').slice(0, 8)}.db`)
21
+ return initDatabase(path)
22
+ }
23
+
24
+ function createUser(db: Database, role = 'member'): { id: string; username: string } {
25
+ const id = `usr_${randomUUID().replace(/-/g, '')}`
26
+ const now = new Date().toISOString()
27
+ db.query(
28
+ `INSERT INTO users (id, username, password_hash, role, created_at) VALUES ($id, $u, 'h', $r, $now)`,
29
+ ).run({ $id: id, $u: `user_${id.slice(0, 6)}`, $r: role, $now: now })
30
+ return { id, username: `user_${id.slice(0, 6)}` }
31
+ }
32
+
33
+ function createTeam(db: Database, createdBy: string): string {
34
+ const id = `team_${randomUUID().replace(/-/g, '')}`
35
+ const now = new Date().toISOString()
36
+ db.query(
37
+ `INSERT INTO teams (id, name, slug, created_by, created_at, updated_at) VALUES ($id, $n, $s, $by, $now, $now)`,
38
+ ).run({ $id: id, $n: 'Eng', $s: `eng-${id.slice(0, 6)}`, $by: createdBy, $now: now })
39
+ db.query(
40
+ `INSERT INTO team_members (team_id, user_id, role, added_at, added_by) VALUES ($t, $u, 'member', $now, $by)`,
41
+ ).run({ $t: id, $u: createdBy, $now: now, $by: createdBy })
42
+ return id
43
+ }
44
+
45
+ function linkEnvToTeam(db: Database, envId: string, teamId: string): void {
46
+ db.query(
47
+ `INSERT OR IGNORE INTO team_environments (team_id, environment_id) VALUES ($t, $e)`,
48
+ ).run({ $t: teamId, $e: envId })
49
+ }
50
+
51
+ function authHeader(token: string): Record<string, string> {
52
+ return { Authorization: `Bearer ${token}` }
53
+ }
54
+
55
+ function createApp(): Hono {
56
+ const app = new Hono()
57
+ app.route('/web', webSessions)
58
+ app.route('/web', webEnvironments)
59
+ return app
60
+ }
61
+
62
+ describe('团队域 session 创建与 environment 可见性', () => {
63
+ let db: Database
64
+ let app: Hono
65
+ let user: { id: string; username: string }
66
+ let accessToken: string
67
+ let teamId: string
68
+ let envId: string
69
+
70
+ beforeEach(() => {
71
+ db = freshDb()
72
+ app = createApp()
73
+ user = createUser(db)
74
+ teamId = createTeam(db, user.id)
75
+
76
+ // Register an environment and link it to the team
77
+ const env = storeCreateEnvironment({ secret: 'secret', machineName: 'dev', username: user.id })
78
+ envId = env.id
79
+ linkEnvToTeam(db, envId, teamId)
80
+
81
+ // Issue a session token for the user
82
+ const { accessToken: at } = issueSessionToken(user.id, db)
83
+ accessToken = at
84
+ })
85
+
86
+ test('团队域新建 session 应设 visibility=team 并绑 team owner', async () => {
87
+ const res = await app.request('/web/sessions', {
88
+ method: 'POST',
89
+ headers: { 'Content-Type': 'application/json', ...authHeader(accessToken) },
90
+ body: JSON.stringify({
91
+ title: 'Team Session',
92
+ environment_id: envId,
93
+ team_id: teamId,
94
+ }),
95
+ })
96
+ expect(res.status).toBe(200)
97
+ const session = await res.json()
98
+
99
+ // Bug A: visibility 应为 'team',不是 'private'
100
+ expect(session.visibility).toBe('team')
101
+
102
+ // session_owners 应有 owner_type='team', owner_id=teamId
103
+ const owners = db
104
+ .query('SELECT owner_type, owner_id FROM session_owners WHERE session_id = $sid')
105
+ .all({ $sid: session.id }) as Array<{ owner_type: string; owner_id: string }>
106
+ const teamOwner = owners.find(o => o.owner_type === 'team')
107
+ expect(teamOwner).toBeDefined()
108
+ expect(teamOwner!.owner_id).toBe(teamId)
109
+ })
110
+
111
+ test('团队域 session 应被 team 成员可见', async () => {
112
+ // Create a session in team context
113
+ const createRes = await app.request('/web/sessions', {
114
+ method: 'POST',
115
+ headers: { 'Content-Type': 'application/json', ...authHeader(accessToken) },
116
+ body: JSON.stringify({
117
+ title: 'Team Session',
118
+ environment_id: envId,
119
+ team_id: teamId,
120
+ }),
121
+ })
122
+ const session = await createRes.json()
123
+
124
+ // Add another team member
125
+ const member2 = createUser(db)
126
+ db.query(
127
+ `INSERT INTO team_members (team_id, user_id, role, added_at, added_by) VALUES ($t, $u, 'member', $now, $by)`,
128
+ ).run({ $t: teamId, $u: member2.id, $now: new Date().toISOString(), $by: user.id })
129
+
130
+ // Member2 should be able to resolve the session (not 403)
131
+ const { accessToken: at2 } = issueSessionToken(member2.id, db)
132
+ const getRes = await app.request(`/web/sessions/${session.id}`, {
133
+ headers: authHeader(at2),
134
+ })
135
+ expect(getRes.status).not.toBe(403)
136
+ // Should be 200 (session visible to team member)
137
+ expect(getRes.status).toBe(200)
138
+ })
139
+
140
+ test('团队域应能看到属于该 team 的 environment', async () => {
141
+ const res = await app.request('/web/environments', {
142
+ headers: authHeader(accessToken),
143
+ })
144
+ expect(res.status).toBe(200)
145
+ const envs = await res.json()
146
+ expect(Array.isArray(envs)).toBe(true)
147
+ expect(envs.length).toBeGreaterThanOrEqual(1)
148
+
149
+ // The team-linked env should have team_id and team_name
150
+ const teamEnv = envs.find((e: { team_id?: string }) => e.team_id === teamId)
151
+ expect(teamEnv).toBeDefined()
152
+ expect(teamEnv.team_name).toBe('Eng')
153
+ })
154
+
155
+ test('个人域不应看到 team 的 environment', async () => {
156
+ // Create a user with no team membership
157
+ const solo = createUser(db)
158
+ const { accessToken: at } = issueSessionToken(solo.id, db)
159
+
160
+ const res = await app.request('/web/environments', {
161
+ headers: authHeader(at),
162
+ })
163
+ expect(res.status).toBe(200)
164
+ const envs = await res.json()
165
+ // Solo user should NOT see the team's environment (only admin sees all)
166
+ const teamEnv = envs.find((e: { team_id?: string }) => e.team_id === teamId)
167
+ expect(teamEnv).toBeUndefined()
168
+ })
169
+ })
@@ -1479,6 +1479,13 @@ describe('POST /web/environments/:id/transfer', () => {
1479
1479
  })
1480
1480
 
1481
1481
  test('team admin → 200', async () => {
1482
+ // teamAdmin must also be admin/owner in the target team (security fix)
1483
+ addTeamMember(db, {
1484
+ teamId: targetTeam.id,
1485
+ userId: teamAdmin.id,
1486
+ role: 'admin',
1487
+ addedBy: owner.id,
1488
+ })
1482
1489
  const res = await app.request(`/web/environments/${envId}/transfer`, {
1483
1490
  method: 'POST',
1484
1491
  headers: {
@@ -40,9 +40,7 @@ export async function csrfCheck(c: Context, next: Next) {
40
40
  // Support ALLOWED_ORIGINS env variable (comma-separated)
41
41
  const envOrigins =
42
42
  (c.env?.ALLOWED_ORIGINS as string | undefined) ??
43
- (typeof process !== 'undefined'
44
- ? process.env.ALLOWED_ORIGINS
45
- : undefined)
43
+ (typeof process !== 'undefined' ? process.env.ALLOWED_ORIGINS : undefined)
46
44
  if (envOrigins) {
47
45
  for (const o of envOrigins.split(',')) {
48
46
  const trimmed = o.trim()
@@ -62,8 +62,8 @@ export function extractWebSocketAuthToken(c: Context): string | undefined {
62
62
  /**
63
63
  * Unified authentication middleware — supports two modes:
64
64
  *
65
- * 1. **Token mode** (Web UI): Bearer token resolved via server-side lookup → username injected
66
- * 2. **API Key mode** (CLI bridge): Valid API key + X-Username header → username injected
65
+ * 1. **Token mode** (Web UI): Bearer token resolved via server-side lookup → userId injected
66
+ * 2. **API Key mode** (CLI bridge): Valid API key + X-Username header → userId injected
67
67
  */
68
68
  export async function apiKeyAuth(c: Context, next: Next) {
69
69
  const token = extractBearerToken(c)
@@ -71,7 +71,7 @@ export async function apiKeyAuth(c: Context, next: Next) {
71
71
  // Try token authentication (Web UI)
72
72
  const tokenUsername = resolveToken(token)
73
73
  if (tokenUsername) {
74
- c.set('username', tokenUsername)
74
+ c.set('userId', tokenUsername)
75
75
  await next()
76
76
  return
77
77
  }
@@ -81,7 +81,7 @@ export async function apiKeyAuth(c: Context, next: Next) {
81
81
  // Extract username from X-Username header or ?username= query param
82
82
  const username = c.req.header('X-Username') || c.req.query('username')
83
83
  if (username) {
84
- c.set('username', username)
84
+ c.set('userId', username)
85
85
  }
86
86
  await next()
87
87
  return
@@ -223,6 +223,15 @@ export async function sessionAuth(c: Context, next: Next) {
223
223
  }
224
224
  } catch (err) {
225
225
  console.warn('[sessionAuth] DB resolution failed:', err)
226
+ return c.json(
227
+ {
228
+ error: {
229
+ type: 'service_unavailable',
230
+ message: 'Database unavailable — cannot resolve session token',
231
+ },
232
+ },
233
+ 503,
234
+ )
226
235
  }
227
236
  }
228
237
 
@@ -66,14 +66,17 @@ try {
66
66
  console.warn('[RCS] Failed to reap expired sessions:', err)
67
67
  }
68
68
 
69
- const reapInterval = setInterval(() => {
70
- try {
71
- const db = getDb()
72
- reapExpiredSessions(db)
73
- } catch {
74
- // ignore — DB may not be available
75
- }
76
- }, 60 * 60 * 1000) // every hour
69
+ const reapInterval = setInterval(
70
+ () => {
71
+ try {
72
+ const db = getDb()
73
+ reapExpiredSessions(db)
74
+ } catch {
75
+ // ignore — DB may not be available
76
+ }
77
+ },
78
+ 60 * 60 * 1000,
79
+ ) // every hour
77
80
 
78
81
  if (reapInterval.unref) {
79
82
  reapInterval.unref()
@@ -27,14 +27,14 @@ async function bridgeAuth(c: Context, next: Next) {
27
27
  if (bearer) {
28
28
  // Admin API key
29
29
  if (validateApiKey(bearer)) {
30
- c.set('username', c.req.header('X-Username') || c.req.query('username'))
30
+ c.set('userId', c.req.header('X-Username') || c.req.query('username'))
31
31
  await next()
32
32
  return
33
33
  }
34
34
  // In-memory token
35
35
  const username = resolveToken(bearer)
36
36
  if (username) {
37
- c.set('username', username)
37
+ c.set('userId', username)
38
38
  await next()
39
39
  return
40
40
  }
@@ -47,8 +47,9 @@ async function bridgeAuth(c: Context, next: Next) {
47
47
  await next()
48
48
  return
49
49
  }
50
- } catch {
51
- // DB not available
50
+ } catch (err) {
51
+ console.error('[bridge] DB error during session token resolution:', err)
52
+ return c.json({ error: 'Database unavailable' }, 503)
52
53
  }
53
54
  }
54
55
  // Fall back to apiKeyAuth (handles X-Username + API key from body/header)
@@ -59,7 +60,7 @@ async function bridgeAuth(c: Context, next: Next) {
59
60
  app.post('/bridge', acceptCliHeaders, bridgeAuth, async c => {
60
61
  const body = await c.req.json()
61
62
  const userId = c.get('userId') as string | undefined
62
- const username = (c.get('username') as string | undefined) || userId
63
+ const username = userId
63
64
  const teamId = c.req.header('X-Team-Id')
64
65
 
65
66
  // Validate team if X-Team-Id is provided
@@ -102,8 +103,9 @@ app.post('/bridge', acceptCliHeaders, bridgeAuth, async c => {
102
103
  )
103
104
  }
104
105
  }
105
- } catch {
106
- // DB not available — skip team validation
106
+ } catch (err) {
107
+ console.error('[bridge] DB error during team validation:', err)
108
+ return c.json({ error: 'Database unavailable' }, 503)
107
109
  }
108
110
  }
109
111
 
@@ -116,8 +118,9 @@ app.post('/bridge', acceptCliHeaders, bridgeAuth, async c => {
116
118
  db.query(
117
119
  'INSERT OR IGNORE INTO team_environments (team_id, environment_id) VALUES ($teamId, $envId)',
118
120
  ).run({ $teamId: teamId, $envId: result.environment_id })
119
- } catch {
120
- // DB not available
121
+ } catch (err) {
122
+ console.error('[bridge] DB error during team-environment link:', err)
123
+ return c.json({ error: 'Database unavailable' }, 503)
121
124
  }
122
125
  }
123
126
 
@@ -16,7 +16,7 @@ const app = new Hono()
16
16
  /** POST /v1/sessions — Create session */
17
17
  app.post('/', acceptCliHeaders, apiKeyAuth, async c => {
18
18
  const body = await c.req.json()
19
- const username = c.get('username')
19
+ const username = c.get('userId')
20
20
  const session = createSession({ ...body, username })
21
21
 
22
22
  // Create work item if environment is specified
@@ -452,7 +452,9 @@ app.post('/join', async c => {
452
452
  // Re-check invitation state inside the transaction (may have changed).
453
453
  // Only check uses >= max_uses — consumed_at is set conditionally below.
454
454
  const currentInv = db
455
- .query('SELECT uses, max_uses FROM invitations WHERE token_hash = $hash')
455
+ .query(
456
+ 'SELECT uses, max_uses FROM invitations WHERE token_hash = $hash',
457
+ )
456
458
  .get({ $hash: tokenHash }) as { uses: number; max_uses: number } | null
457
459
 
458
460
  if (!currentInv || currentInv.uses >= currentInv.max_uses) {
@@ -13,7 +13,8 @@ app.all('/bind', c => {
13
13
  {
14
14
  error: {
15
15
  type: 'gone',
16
- message: '/web/bind has been removed. Use authenticated session creation instead.',
16
+ message:
17
+ '/web/bind has been removed. Use authenticated session creation instead.',
17
18
  },
18
19
  },
19
20
  410,
@@ -4,14 +4,32 @@ import { config } from '../../config'
4
4
  import { listActiveEnvironmentsResponse } from '../../services/environment'
5
5
  import { listWebSessionsByOwnerUuid } from '../../services/session'
6
6
  import { storeListActiveEnvironments } from '../../store'
7
+ import { getDb } from '../../db/sqlite'
7
8
 
8
9
  const app = new Hono()
9
10
 
10
- /** GET /web/environments — List active environments (UUID-based, no user filtering) */
11
+ /** GET /web/environments — List active environments.
12
+ * Admin sees all. Non-admin sees only environments linked to teams they
13
+ * belong to, plus environments with no team association (personal space). */
11
14
  app.get('/environments', sessionAuth, async c => {
12
- // Environments are shared across all UUIDs for now
13
- const envs = listActiveEnvironmentsResponse()
14
- return c.json(envs, 200)
15
+ const userId = c.get('userId') as string
16
+ const isAdmin = c.get('isAdmin') as boolean
17
+
18
+ const allEnvs = listActiveEnvironmentsResponse()
19
+
20
+ if (isAdmin) {
21
+ return c.json(allEnvs, 200)
22
+ }
23
+
24
+ // Resolve the user's team memberships so we can filter environments.
25
+ const db = getDb()
26
+ const teamRows = db
27
+ .query('SELECT team_id FROM team_members WHERE user_id = $userId')
28
+ .all({ $userId: userId }) as Array<{ team_id: string }>
29
+ const teamIds = new Set(teamRows.map(r => r.team_id))
30
+
31
+ const filtered = allEnvs.filter(env => !env.team_id || teamIds.has(env.team_id))
32
+ return c.json(filtered, 200)
15
33
  })
16
34
 
17
35
  /** GET /web/server-info — Aggregate server status for Web UI identity panel */
@@ -32,18 +32,22 @@ const app = new Hono()
32
32
  * X-User-Id header for a real user identity. If no valid identity is
33
33
  * found, returns null — the session will be orphaned (admin-visible).
34
34
  */
35
- function resolveBindUserId(
36
- c: import('hono').Context,
37
- ): string | null {
38
- const uuid = c.get('userId')!
39
- if (uuid !== SYSTEM_USER_ID) return uuid
40
-
41
- // API key auth — check X-User-Id header for real user identity
42
- const headerUserId = c.req.header('X-User-Id')
43
- if (headerUserId && headerUserId !== SYSTEM_USER_ID) {
44
- return headerUserId
35
+ function resolveBindUserId(c: import('hono').Context): string | null {
36
+ const userId = c.get('userId')
37
+ if (!userId || userId === SYSTEM_USER_ID) {
38
+ // API key auth — only admin can use X-User-Id to bind on behalf of a user
39
+ const isAdmin = c.get('isAdmin')
40
+ if (!isAdmin) {
41
+ return null // non-admin API key cannot create sessions as another user
42
+ }
43
+ const headerUserId = c.req.header('X-User-Id')
44
+ if (headerUserId && headerUserId !== SYSTEM_USER_ID) {
45
+ console.log(`[audit] API key created session as user ${headerUserId}`)
46
+ return headerUserId
47
+ }
48
+ return null // API key without X-User-Id → orphan session (admin-visible)
45
49
  }
46
- return null
50
+ return userId
47
51
  }
48
52
 
49
53
  /** POST /web/sessions — Create a session from web UI */
@@ -81,14 +85,22 @@ app.post('/sessions', sessionAuth, async c => {
81
85
  }
82
86
  }
83
87
 
88
+ const teamId = typeof body.team_id === 'string' ? body.team_id : null
89
+
84
90
  const session = createSession({
85
91
  environment_id: body.environment_id || null,
86
92
  title: body.title || 'New Session',
87
93
  source: 'web',
88
94
  permission_mode: body.permission_mode || 'default',
95
+ visibility: teamId ? 'team' : 'private',
89
96
  })
90
97
 
91
- // Auto-bind to creator's UUID (skip for system/API key without real user)
98
+ // Bind team owner first (if creating in team context), then user owner.
99
+ // Team ownership makes the session visible to all team members; user
100
+ // ownership gives the creator explicit access.
101
+ if (teamId) {
102
+ storeBindSession(session.id, teamId, 'team')
103
+ }
92
104
  if (bindUserId) {
93
105
  storeBindSession(session.id, bindUserId)
94
106
  }
@@ -14,7 +14,11 @@ interface SessionOwnerRow {
14
14
  /**
15
15
  * Check if a user is a member of a given team.
16
16
  */
17
- function isTeamMember(userId: string, teamId: string, db: ReturnType<typeof getDb>): boolean {
17
+ function isTeamMember(
18
+ userId: string,
19
+ teamId: string,
20
+ db: ReturnType<typeof getDb>,
21
+ ): boolean {
18
22
  const row = db
19
23
  .query(
20
24
  'SELECT user_id FROM team_members WHERE team_id = $teamId AND user_id = $userId',
@@ -379,7 +383,12 @@ app.get(
379
383
 
380
384
  if (!isGrantee) {
381
385
  return c.json(
382
- { error: { type: 'forbidden', message: 'Not authorized for this share' } },
386
+ {
387
+ error: {
388
+ type: 'forbidden',
389
+ message: 'Not authorized for this share',
390
+ },
391
+ },
383
392
  403,
384
393
  )
385
394
  }
@@ -154,10 +154,7 @@ app.post('/teams', withAuth, async c => {
154
154
  )
155
155
  .get() as { id: string } | null
156
156
  if (!adminUser) {
157
- return c.json(
158
- { error: 'No admin user available to create team' },
159
- 400,
160
- )
157
+ return c.json({ error: 'No admin user available to create team' }, 400)
161
158
  }
162
159
  createdBy = adminUser.id
163
160
  }
@@ -826,11 +823,11 @@ app.post('/environments/:id/transfer', withAuth, async c => {
826
823
 
827
824
  // Check caller is owner/admin of the target team
828
825
  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
- )
826
+ if (
827
+ !user.isAdmin &&
828
+ (!targetRole || (targetRole !== 'owner' && targetRole !== 'admin'))
829
+ ) {
830
+ return c.json({ error: 'Not authorized in target team' }, 403)
834
831
  }
835
832
 
836
833
  // Remove from source team
@@ -5,6 +5,7 @@ import {
5
5
  storeGetEnvironment,
6
6
  storeUpdateEnvironment,
7
7
  storeListActiveEnvironments,
8
+ storeListActiveEnvironmentsWithTeam,
8
9
  storeListActiveEnvironmentsByUsername,
9
10
  storeListAcpAgentsByChannelGroup,
10
11
  storeListSessionsByEnvironment,
@@ -15,7 +16,9 @@ import type {
15
16
  } from '../types/api'
16
17
  import type { EnvironmentRecord } from '../store'
17
18
 
18
- function toResponse(row: EnvironmentRecord): EnvironmentResponse {
19
+ function toResponse(
20
+ row: EnvironmentRecord & { teamId?: string | null; teamName?: string | null },
21
+ ): EnvironmentResponse {
19
22
  return {
20
23
  id: row.id,
21
24
  machine_name: row.machineName,
@@ -27,6 +30,8 @@ function toResponse(row: EnvironmentRecord): EnvironmentResponse {
27
30
  worker_type: row.workerType,
28
31
  channel_group_id: row.bridgeId,
29
32
  capabilities: row.capabilities,
33
+ team_id: row.teamId ?? null,
34
+ team_name: row.teamName ?? null,
30
35
  }
31
36
  }
32
37
 
@@ -136,13 +141,13 @@ export function listActiveEnvironments() {
136
141
  }
137
142
 
138
143
  export function listActiveEnvironmentsResponse(): EnvironmentResponse[] {
139
- return storeListActiveEnvironments().map(toResponse)
144
+ return storeListActiveEnvironmentsWithTeam().map(r => toResponse(r))
140
145
  }
141
146
 
142
147
  export function listActiveEnvironmentsByUsername(
143
148
  username: string,
144
149
  ): EnvironmentResponse[] {
145
- return storeListActiveEnvironmentsByUsername(username).map(toResponse)
150
+ return storeListActiveEnvironmentsByUsername(username).map(r => toResponse(r))
146
151
  }
147
152
 
148
153
  export function reconnectEnvironment(envId: string) {