@abtnode/blocklet-services 1.16.34-beta-20241204-140321-4d75ca21 → 1.16.34-beta-20241206-124652-493dbc39

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 (303) hide show
  1. package/api/libs/connect/session.js +4 -4
  2. package/api/libs/open-graph/index.js +1 -1
  3. package/api/middlewares/check-federated.js +157 -0
  4. package/api/routes/blocklet.js +19 -13
  5. package/api/routes/federated.js +529 -573
  6. package/api/routes/oauth.js +38 -55
  7. package/api/routes/user-session.js +239 -214
  8. package/api/routes/user.js +52 -45
  9. package/api/services/auth/connect/invite.js +1 -1
  10. package/api/services/auth/connect/issue-passport.js +1 -1
  11. package/api/services/auth/session.js +31 -9
  12. package/api/util/attach-shared-utils.js +6 -6
  13. package/api/util/federated.js +28 -72
  14. package/dist/assets/Add-Dr8htRSM.js +1 -0
  15. package/dist/assets/{Alert-XwCbbCdw.js → Alert-gRD_jJCj.js} +1 -1
  16. package/dist/assets/ArrowDropDown-DI04xnPr.js +1 -0
  17. package/dist/assets/{Autocomplete-CtKfl8OV.js → Autocomplete-DPolRnqk.js} +1 -1
  18. package/dist/assets/{Avatar-BuTYVz6S.js → Avatar-D6TPuXUP.js} +1 -1
  19. package/dist/assets/{ButtonGroup-9mTO_MUt.js → ButtonGroup-BcLw8gsE.js} +1 -1
  20. package/dist/assets/{CSSTransition-VPmtoKE7.js → CSSTransition-DdlHGsuR.js} +1 -1
  21. package/dist/assets/CheckCircle-BPxn_ieu.js +1 -0
  22. package/dist/assets/ChevronLeft-5FOp5_pf.js +1 -0
  23. package/dist/assets/ChevronRight-PVflalU6.js +1 -0
  24. package/dist/assets/Delete-CaO8fR6N.js +1 -0
  25. package/dist/assets/DeleteOutline-PIJBVOmm.js +1 -0
  26. package/dist/assets/{DialogContentText-BSTFqlB8.js → DialogContentText-BvYfkPC9.js} +1 -1
  27. package/dist/assets/Done-Cqnr64ll.js +1 -0
  28. package/dist/assets/Download-Bv95-VOA.js +1 -0
  29. package/dist/assets/{EditIcon-D5uy6dXe.js → EditIcon-B2INxzak.js} +1 -1
  30. package/dist/assets/Error-vrb7fyQU.js +1 -0
  31. package/dist/assets/ExpandMore-B3TZX84r.js +1 -0
  32. package/dist/assets/{FormControl-D9UzJGr3.js → FormControl-BlJhfvE4.js} +1 -1
  33. package/dist/assets/{FormControlLabel-Ka9Y3VW4.js → FormControlLabel-DUahNTJi.js} +1 -1
  34. package/dist/assets/FormGroup-BhKveWGx.js +1 -0
  35. package/dist/assets/{Google-fmIzZ4SE.js → Google-2VzbESXy.js} +1 -1
  36. package/dist/assets/{Grid-CLg9BKgo.js → Grid-HlOuSRmU.js} +1 -1
  37. package/dist/assets/HelpOutline-pRqeT6i_.js +1 -0
  38. package/dist/assets/{Hidden-B_FCIv2F.js → Hidden-BIaa-blE.js} +1 -1
  39. package/dist/assets/InfoOutlined-CvA_NzdD.js +1 -0
  40. package/dist/assets/InputAdornment-mbNfreso.js +1 -0
  41. package/dist/assets/{LastPage-BNIPjfIv.js → LastPage-BI2XzpBc.js} +1 -1
  42. package/dist/assets/Launch-DIHn67BI.js +1 -0
  43. package/dist/assets/LaunchOutlined-DBAHz0tb.js +1 -0
  44. package/dist/assets/{Link-Dgz_hg-A.js → Link-SvE6tGEV.js} +1 -1
  45. package/dist/assets/{ListItemButton-COVroopz.js → ListItemButton-DRswm1pu.js} +1 -1
  46. package/dist/assets/{ListSubheader-DoFPqSxT.js → ListSubheader-Cedlz0t5.js} +1 -1
  47. package/dist/assets/{LoadingButton-Cpsng3ic.js → LoadingButton-1nXdJV1_.js} +1 -1
  48. package/dist/assets/{LockIcon-xMd6TgDT.js → LockIcon-BlUU7Km8.js} +1 -1
  49. package/dist/assets/Loop-Do-1bTcZ.js +1 -0
  50. package/dist/assets/MarkEmailRead-DJzwbP2x.js +1 -0
  51. package/dist/assets/Menu-4JehMzAB.js +1 -0
  52. package/dist/assets/MoreHoriz-BiDBSm9w.js +1 -0
  53. package/dist/assets/MoreVert-BHPy5yQk.js +1 -0
  54. package/dist/assets/OpenInNew-Ox-Wg6B7.js +1 -0
  55. package/dist/assets/{Pagination-BdODbVsE.js → Pagination-DtmO1FEC.js} +1 -1
  56. package/dist/assets/PlayArrow-D8oFKkOl.js +1 -0
  57. package/dist/assets/{QuestionMarkCircle-CeLvEIhA.js → QuestionMarkCircle-CRCb7vLB.js} +1 -1
  58. package/dist/assets/RadioGroup-CAeo2G7k.js +1 -0
  59. package/dist/assets/Search-B4FkzoeR.js +1 -0
  60. package/dist/assets/{Select-BM5xijW7.js → Select-pOhG5uV8.js} +2 -2
  61. package/dist/assets/{ServerLogo-CocwN-L6.js → ServerLogo-C3qS1K9u.js} +1 -1
  62. package/dist/assets/{Skeleton-BQ4gLbdR.js → Skeleton-XhcFgkuH.js} +3 -3
  63. package/dist/assets/Stack-BGVSv0bm.js +1 -0
  64. package/dist/assets/{Stepper-DPFFvB9h.js → Stepper-1oUkII92.js} +1 -1
  65. package/dist/assets/{TextField-CFRK87D0.js → TextField-BYIMGo2O.js} +1 -1
  66. package/dist/assets/{Toolbar-Ba22YRhW.js → Toolbar-MXTUjpSN.js} +1 -1
  67. package/dist/assets/ViewColumn-Dl8WBRoz.js +1 -0
  68. package/dist/assets/ViewList-Dw7InfFl.js +1 -0
  69. package/dist/assets/_createAggregator-CF3Ywu_Z.js +1 -0
  70. package/dist/assets/access-control-CPDqmVDW.js +13 -0
  71. package/dist/assets/{actions-R7d7-bh3.js → actions-DB6zFAt9.js} +1 -1
  72. package/dist/assets/{add-component-core-qARkFBQB.js → add-component-core-DpqYAR-R.js} +11 -11
  73. package/dist/assets/add-resource-BY7yN1M7.js +1 -0
  74. package/dist/assets/{addon-BJli1WRW.js → addon-cSEDcT4t.js} +1 -1
  75. package/dist/assets/{analytics-B3iUwhYK.js → analytics-CObVf_QD.js} +8 -8
  76. package/dist/assets/api-SlMwqh4b.js +1 -0
  77. package/dist/assets/{ar-7AvHBDLJ.js → ar-BENken66.js} +1 -1
  78. package/dist/assets/audit-logs-BMMQleD-.js +58 -0
  79. package/dist/assets/{base32-Mo2B3fHT.js → base32-Cky7ZH4x.js} +1 -1
  80. package/dist/assets/{branding-BThKyvoW.js → branding-DD9lnLdg.js} +2 -2
  81. package/dist/assets/bundle-avatar-D1CsKnAr.js +1 -0
  82. package/dist/assets/{button-eTEsJSJ0.js → button-C2skqS2y.js} +1 -1
  83. package/dist/assets/{click-to-copy-CkFI8a1W.js → click-to-copy-B_U6uers.js} +1 -1
  84. package/dist/assets/complete-Cm1aTSRB.js +45 -0
  85. package/dist/assets/{component-kGv-hUvT.js → component-CU-7h3yK.js} +2 -2
  86. package/dist/assets/{config-BVYueZpV.js → config-CKVwTxh4.js} +2 -2
  87. package/dist/assets/config-GyMHYuIo.js +1 -0
  88. package/dist/assets/{config-navigation-NUbYVs4N.js → config-navigation-DqtZRu1x.js} +1 -1
  89. package/dist/assets/config-space-xHVn7Zw_.js +1 -0
  90. package/dist/assets/{confirm-CIF7Vu-X.js → confirm-BYGcMOdN.js} +1 -1
  91. package/dist/assets/{connect-Dj-BrpmM.js → connect-7KX0ip82.js} +1 -1
  92. package/dist/assets/connect-Cjg3Lm4D.js +1 -0
  93. package/dist/assets/connect-to-BWP8Cqu6.js +1 -0
  94. package/dist/assets/{content-layout-DSpN7kL2.js → content-layout-8jsNhe-5.js} +1 -1
  95. package/dist/assets/dashboard-BZreJCiA.js +165 -0
  96. package/dist/assets/{de-S6ufmRx0.js → de-C8d8saMJ.js} +1 -1
  97. package/dist/assets/{deprecate-W6wP2f1U.js → deprecate-Bj3Q5Wi_.js} +1 -1
  98. package/dist/assets/{did-address-DpP51eII.js → did-address-7Sb16VSB.js} +1 -1
  99. package/dist/assets/domain-D-DYyZbR.js +9 -0
  100. package/dist/assets/domain-list-p_9GKY-M.js +15 -0
  101. package/dist/assets/email-Canxuwlg.js +18 -0
  102. package/dist/assets/emotion-cache.browser.esm-DRs-CTgF.js +1 -0
  103. package/dist/assets/{es-Sth9cv6C.js → es-8ZzWXB3U.js} +1 -1
  104. package/dist/assets/exchange-passport-Dv2bo20G.js +1 -0
  105. package/dist/assets/{fallback-CTOpqcoo.js → fallback-BlcEp1VL.js} +1 -1
  106. package/dist/assets/form-text-input-D26GlKxQ.js +11 -0
  107. package/dist/assets/{format-error-jTY-wvGv.js → format-error-Dk89U0uh.js} +2 -2
  108. package/dist/assets/{fr-BX6bo8e1.js → fr-CDmTLuDM.js} +1 -1
  109. package/dist/assets/{fuel-Dx06V-YR.js → fuel-DeEVMoW6.js} +1 -1
  110. package/dist/assets/{fullpage-Dz8PPWdq.js → fullpage-CFHcuwWr.js} +1 -1
  111. package/dist/assets/{hi-pYobKga6.js → hi-DfYUKMCb.js} +1 -1
  112. package/dist/assets/{home-BCoo1Guo.js → home-D7XPwTjK.js} +1 -1
  113. package/dist/assets/{id-Xei40tOm.js → id-BeY7iur-.js} +1 -1
  114. package/dist/assets/{iframe-GN8AUKA4.js → iframe-tSt_So8C.js} +1 -1
  115. package/dist/assets/{index-delqLXRr.js → index-3lBO8ivG.js} +8 -8
  116. package/dist/assets/{index-BXHMtAUn.js → index-6dmWRa5a.js} +2 -2
  117. package/dist/assets/{index-rA_BKM5G.js → index-B6vN1Pjj.js} +3 -3
  118. package/dist/assets/{index-W2CQmt_X.js → index-BaYuwQfE.js} +1 -1
  119. package/dist/assets/index-BilCISvf.js +1 -0
  120. package/dist/assets/{index-B_EeAcSB.js → index-Bk-KtZtw.js} +1 -1
  121. package/dist/assets/index-C-OENO3T.js +16 -0
  122. package/dist/assets/{index-Db_Y81_-.js → index-C56N3wab.js} +2 -2
  123. package/dist/assets/{index-CG1XIXZC.js → index-C89kYDNU.js} +1 -1
  124. package/dist/assets/{index-B3Z8DzsY.js → index-CNE2uXX8.js} +6 -6
  125. package/dist/assets/index-CPFKRWiW.js +316 -0
  126. package/dist/assets/{index-COdSzYad.js → index-CQuGc78Y.js} +2 -2
  127. package/dist/assets/{index-cIe0Ged1.js → index-CswkYvFG.js} +1 -1
  128. package/dist/assets/index-CuJzImxJ.js +1 -0
  129. package/dist/assets/index-CwEyBOgW.js +4 -0
  130. package/dist/assets/{index-CjkNshyI.js → index-D-G-CrJO.js} +1 -1
  131. package/dist/assets/{index-8OiEpVkg.js → index-D0CXo93j.js} +1 -1
  132. package/dist/assets/{index-UEoZJA9L.js → index-D2m633vu.js} +1 -1
  133. package/dist/assets/index-DQjLOWie.js +5 -0
  134. package/dist/assets/{index-CYQV6023.js → index-DbUU7z6J.js} +11 -11
  135. package/dist/assets/{index-B019qXp1.js → index-DcWx2h61.js} +1 -1
  136. package/dist/assets/{index-B3pPqycI.js → index-DfQHFN6t.js} +1 -1
  137. package/dist/assets/{index-ZPFypmuO.js → index-DsLePqKc.js} +1 -1
  138. package/dist/assets/{index-DgonWrzm.js → index-DsZCBFlr.js} +9 -9
  139. package/dist/assets/{index-BxKrUgd9.js → index-DtdETaBU.js} +70 -70
  140. package/dist/assets/{index-yi-655mj.js → index-EWrqmue5.js} +1 -1
  141. package/dist/assets/{index-BjfhU-QW.js → index-Ed6XamYf.js} +1 -1
  142. package/dist/assets/{index-BzVm0XuZ.js → index-I4Wjjc9p.js} +1 -1
  143. package/dist/assets/index-K-RQRB6f.js +1 -0
  144. package/dist/assets/{index-q1m8Euwz.js → index-Qbrukcer.js} +1 -1
  145. package/dist/assets/index-fU8Snm90.js +102 -0
  146. package/dist/assets/{index-Bs9TLgSC.js → index-hcyZSWah.js} +2 -2
  147. package/dist/assets/index-tap0PKb5.js +29 -0
  148. package/dist/assets/{index-BP0LEaeg.js → index-vQSgatpS.js} +8 -8
  149. package/dist/assets/{index-BidszMO2.js → index-vRY4Eqk5.js} +39 -39
  150. package/dist/assets/{invitation-BPrK4inJ.js → invitation-BTS9OmKY.js} +5 -5
  151. package/dist/assets/invite-DdlZu1iK.js +5 -0
  152. package/dist/assets/{isEmail-BnC4loew.js → isEmail-CmNEnnPO.js} +1 -1
  153. package/dist/assets/issue-passport-BOYK0sdW.js +1 -0
  154. package/dist/assets/item-DiOlNyoQ.js +1 -0
  155. package/dist/assets/{ja-DG0a06x8.js → ja-DvJTZg_Q.js} +1 -1
  156. package/dist/assets/{jss-plugin-props-sort.esm-Bp0MqRVc.js → jss-plugin-props-sort.esm-B0GYUqad.js} +6 -6
  157. package/dist/assets/{ko-BBC-RcU5.js → ko-C1lnK-Gx.js} +1 -1
  158. package/dist/assets/{launch-result-message-4m30f0Ag.js → launch-result-message-CU6VqlMp.js} +1 -1
  159. package/dist/assets/{layout-Btp-_hcD.js → layout-BLLz87sa.js} +2 -2
  160. package/dist/assets/{list-header-DQEePd_T.js → list-header-XuCMCGCV.js} +1 -1
  161. package/dist/assets/localization-ClU7HEEr.js +1 -0
  162. package/dist/assets/{log-DGIf8qzM.js → log-CzdQsoGM.js} +6 -6
  163. package/dist/assets/login-DxPcP1jX.js +1 -0
  164. package/dist/assets/login-oauth-callback-6aacB0AP.js +1 -0
  165. package/dist/assets/{logo-uploader-CC8WqbW-.js → logo-uploader-FwiUnYYD.js} +4 -4
  166. package/dist/assets/lost-passport-CP1WD-6W.js +168 -0
  167. package/dist/assets/{lottie-react.esm-CtltdV0t.js → lottie-react.esm-D7IQJqb8.js} +1 -1
  168. package/dist/assets/notifications-BuECL_6T.js +65 -0
  169. package/dist/assets/open-window-Bg3rwEW-.js +1 -0
  170. package/dist/assets/overview-CjXvkE0B.js +12 -0
  171. package/dist/assets/{page-header-B5a7RE0E.js → page-header-ByFkqYoX.js} +1 -1
  172. package/dist/assets/{permission-CBfa-qlX.js → permission-DbhB5Z1v.js} +1 -1
  173. package/dist/assets/{preferences-CuRLxM0K.js → preferences-BYmMPHkz.js} +1 -1
  174. package/dist/assets/{pt-CNmFfxJU.js → pt-C86mXB8Z.js} +1 -1
  175. package/dist/assets/publish-resource-CRym3QNG.js +1 -0
  176. package/dist/assets/{raf-schd.esm-KaxPdV64.js → raf-schd.esm-B7lVwb88.js} +1 -1
  177. package/dist/assets/{react-beautiful-dnd.esm-BlBywA4z.js → react-beautiful-dnd.esm-DzxofBcj.js} +1 -1
  178. package/dist/assets/refType-C0MWXRP4.js +1 -0
  179. package/dist/assets/{resource-dialog-DpLtB_Fw.js → resource-dialog-DvLQ35FQ.js} +1 -1
  180. package/dist/assets/{ru-BVNv9w91.js → ru-Dxm-iAqn.js} +1 -1
  181. package/dist/assets/sdk-C9VDRIUH.js +1 -0
  182. package/dist/assets/{selector-Drr6pXp9.js → selector-CVbTF87I.js} +4 -4
  183. package/dist/assets/session-CfGQq4aA.js +1 -0
  184. package/dist/assets/setup-Cn5VZSrf.js +19 -0
  185. package/dist/assets/{shorten-label-DK0L2sJV.js → shorten-label-DkBNZBHq.js} +1 -1
  186. package/dist/assets/simple-select-Dar19mu0.js +1 -0
  187. package/dist/assets/{slicedToArray-n9LJBwV4.js → slicedToArray-Bh7YTn9v.js} +2 -2
  188. package/dist/assets/start-BeQmK9fc.js +187 -0
  189. package/dist/assets/{step-actions-D_1mpc4C.js → step-actions-DauWsHJ8.js} +2 -2
  190. package/dist/assets/studio-DsQEpBvk.js +6 -0
  191. package/dist/assets/{switch-control-2C3bwebR.js → switch-control-Dsh5_EeP.js} +1 -1
  192. package/dist/assets/{th-CObnQ6OH.js → th-BamIf1b8.js} +1 -1
  193. package/dist/assets/{toUpper-DtTJYJCz.js → toUpper-BzsouAll.js} +1 -1
  194. package/dist/assets/transfer-DaiNG55d.js +16 -0
  195. package/dist/assets/trim-BSxRkodT.js +1 -0
  196. package/dist/assets/uniqBy-DdK7WB2a.js +1 -0
  197. package/dist/assets/unsubscribe-QZHXePvC.js +1 -0
  198. package/dist/assets/{url-join-aL0dlRwK.js → url-join-Bz42DLTX.js} +1 -1
  199. package/dist/assets/{use-mobile-TJQ6s1hH.js → use-mobile-BORWdgFu.js} +1 -1
  200. package/dist/assets/{use-mobile-D7IK9xm6.js → use-mobile-BnLttn6s.js} +1 -1
  201. package/dist/assets/{useAsync-B5aCa8BU.js → useAsync-XGhszTqi.js} +1 -1
  202. package/dist/assets/{useFormControl-De83T2k8.js → useFormControl-CUbdx--c.js} +1 -1
  203. package/dist/assets/{useLocalStorage-Cg4UWbtJ.js → useLocalStorage-CQGh5cLr.js} +1 -1
  204. package/dist/assets/{useSetState-C5EefhmT.js → useSetState-DJ05e857.js} +1 -1
  205. package/dist/assets/useSlot-DcPzSHnC.js +1 -0
  206. package/dist/assets/{useSlotProps-9EZsnKiK.js → useSlotProps-D6DLjewQ.js} +1 -1
  207. package/dist/assets/{useThemeProps-DFbMvLjq.js → useThemeProps-D4tucCRV.js} +1 -1
  208. package/dist/assets/user-center-BA6Kltkg.js +1 -0
  209. package/dist/assets/user-sessions-DvMYo49k.js +1 -0
  210. package/dist/assets/util-CEeqN3nG.js +1 -0
  211. package/dist/assets/{vi-DPE1cpvE.js → vi-CTEgHnG8.js} +1 -1
  212. package/dist/assets/wrap-locale-Ce8iB_Ha.js +1 -0
  213. package/dist/assets/{zh-ZJh718gR.js → zh-C9pcKSvk.js} +1 -1
  214. package/dist/assets/{zh-tw-q3KEUdcz.js → zh-tw-CuhSzmQN.js} +1 -1
  215. package/dist/images/splash-landscape.png +0 -0
  216. package/dist/images/splash-portrait.png +0 -0
  217. package/dist/index.html +1 -1
  218. package/dist/service-worker.js +1 -1
  219. package/package.json +38 -37
  220. package/api/middlewares/verify-federated-call.js +0 -36
  221. package/dist/assets/Add-DtejxYv7.js +0 -1
  222. package/dist/assets/ArrowDropDown-DLu5ghJ6.js +0 -1
  223. package/dist/assets/CheckCircle-BvTAg_Vb.js +0 -1
  224. package/dist/assets/ChevronLeft-CogeEPev.js +0 -1
  225. package/dist/assets/ChevronRight-BATWClLP.js +0 -1
  226. package/dist/assets/Delete-BvK_hDyw.js +0 -1
  227. package/dist/assets/DeleteOutline-CFkN2u6G.js +0 -1
  228. package/dist/assets/Done-BCayGyaP.js +0 -1
  229. package/dist/assets/Download-3v1IPpRg.js +0 -1
  230. package/dist/assets/Error-KMHXOqQS.js +0 -1
  231. package/dist/assets/ExpandMore-XeiYcXA0.js +0 -1
  232. package/dist/assets/FormGroup-BqZ71koG.js +0 -1
  233. package/dist/assets/HelpOutline-D-mVzldg.js +0 -1
  234. package/dist/assets/InfoOutlined-fhivWooJ.js +0 -1
  235. package/dist/assets/InputAdornment-7bcT-OxU.js +0 -1
  236. package/dist/assets/Launch-B6-uAhbQ.js +0 -1
  237. package/dist/assets/LaunchOutlined-BEenLVbN.js +0 -1
  238. package/dist/assets/Loop-tJ6uJkRI.js +0 -1
  239. package/dist/assets/MarkEmailRead-BNHtpgz2.js +0 -1
  240. package/dist/assets/Menu-CkD81HZ5.js +0 -1
  241. package/dist/assets/MoreHoriz-qqmi4YRC.js +0 -1
  242. package/dist/assets/MoreVert-BZZ4IBOf.js +0 -1
  243. package/dist/assets/OpenInNew-C5XvRsRC.js +0 -1
  244. package/dist/assets/PlayArrow-Cn0cfGNW.js +0 -1
  245. package/dist/assets/RadioGroup-CkuUb_-r.js +0 -1
  246. package/dist/assets/Search-DXRr3XZy.js +0 -1
  247. package/dist/assets/Stack-690-8aHU.js +0 -1
  248. package/dist/assets/ViewColumn-GTnSFOFd.js +0 -1
  249. package/dist/assets/ViewList-BtVWmZJ0.js +0 -1
  250. package/dist/assets/_createAggregator-Ct5VkIH5.js +0 -1
  251. package/dist/assets/access-control-BmMbklSe.js +0 -13
  252. package/dist/assets/add-resource-lnxpvPO7.js +0 -1
  253. package/dist/assets/api-lbSHYKYc.js +0 -1
  254. package/dist/assets/audit-logs-0TJ_0Mvw.js +0 -58
  255. package/dist/assets/bundle-avatar-CcIs5XOV.js +0 -1
  256. package/dist/assets/complete-Bb-6z_26.js +0 -45
  257. package/dist/assets/config-kysZ8p5u.js +0 -1
  258. package/dist/assets/config-space-BPpdFWKx.js +0 -1
  259. package/dist/assets/connect-DPIWGg69.js +0 -1
  260. package/dist/assets/connect-to-ZJr8_Nq9.js +0 -1
  261. package/dist/assets/dashboard-BUsMb2Wm.js +0 -165
  262. package/dist/assets/domain-CcBPnmmR.js +0 -9
  263. package/dist/assets/domain-list-CVn1TPCl.js +0 -15
  264. package/dist/assets/email-DETfN-BC.js +0 -18
  265. package/dist/assets/emotion-cache.browser.esm-DkJEKl9I.js +0 -1
  266. package/dist/assets/exchange-passport-BetHiKY_.js +0 -1
  267. package/dist/assets/form-text-input-BUB_rL9o.js +0 -11
  268. package/dist/assets/index-4RJk4AiM.js +0 -1
  269. package/dist/assets/index-B2fUK0Jg.js +0 -16
  270. package/dist/assets/index-BArNVkrG.js +0 -1
  271. package/dist/assets/index-BDxuBkP1.js +0 -29
  272. package/dist/assets/index-CQSz6hXt.js +0 -316
  273. package/dist/assets/index-CRK13xk6.js +0 -102
  274. package/dist/assets/index-D_g2YpF8.js +0 -1
  275. package/dist/assets/index-De1VedzO.js +0 -5
  276. package/dist/assets/index-PD8enw5a.js +0 -4
  277. package/dist/assets/invite-VzUmhGJg.js +0 -5
  278. package/dist/assets/issue-passport-573OuQnm.js +0 -1
  279. package/dist/assets/item-BoFU04RW.js +0 -1
  280. package/dist/assets/localization-BJhiRnk-.js +0 -1
  281. package/dist/assets/login-Cu5oiCaE.js +0 -1
  282. package/dist/assets/login-oauth-callback-Dim9h4c3.js +0 -1
  283. package/dist/assets/lost-passport-D_HnDqKr.js +0 -168
  284. package/dist/assets/notifications-tGIsoEd6.js +0 -65
  285. package/dist/assets/open-window-CmBy5HkH.js +0 -1
  286. package/dist/assets/overview-CmwcUtDq.js +0 -12
  287. package/dist/assets/publish-resource-aoq2ZIeT.js +0 -1
  288. package/dist/assets/refType-CNi4gHMp.js +0 -1
  289. package/dist/assets/sdk-CrAhZvgC.js +0 -1
  290. package/dist/assets/session-BGDxwrDP.js +0 -1
  291. package/dist/assets/setup-cPNeqLVK.js +0 -19
  292. package/dist/assets/simple-select-CHsQAOYZ.js +0 -1
  293. package/dist/assets/start-CcvndivR.js +0 -187
  294. package/dist/assets/studio-BdIpZDRv.js +0 -6
  295. package/dist/assets/transfer-BNPHc5-e.js +0 -16
  296. package/dist/assets/trim-Boaje3e9.js +0 -1
  297. package/dist/assets/uniqBy-B2B_OSuq.js +0 -1
  298. package/dist/assets/unsubscribe-eud8OqTh.js +0 -1
  299. package/dist/assets/useSlot-DebDFCUQ.js +0 -1
  300. package/dist/assets/user-center-BWtnQHWR.js +0 -1
  301. package/dist/assets/user-sessions-DTvyZm5S.js +0 -1
  302. package/dist/assets/util-BBKZBp8H.js +0 -1
  303. package/dist/assets/wrap-locale-Ci8gmRb6.js +0 -1
@@ -1,26 +1,26 @@
1
1
  const { WELLKNOWN_SERVICE_PATH_PREFIX, FEDERATED } = require('@abtnode/constant');
2
2
  const { signV2 } = require('@arcblock/jwt');
3
- const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
4
- const cloneDeep = require('lodash/cloneDeep');
5
3
  const isNil = require('lodash/isNil');
4
+ const pick = require('lodash/pick');
5
+ const remove = require('lodash/remove');
6
6
  const pLimit = require('p-limit');
7
- const pRetry = require('p-retry');
8
- const { joinURL } = require('ufo');
7
+ const pMap = require('p-map');
9
8
 
10
- const { LOGIN_PROVIDER } = require('@blocklet/constant');
9
+ const { LOGIN_PROVIDER, SIG_VERSION } = require('@blocklet/constant');
11
10
  const { getAvatarByUrl, extractUserAvatar } = require('@abtnode/util/lib/user');
12
11
  const { getApplicationInfo, messages } = require('@abtnode/auth/lib/auth');
13
- const pick = require('lodash/pick');
14
- const defaults = require('lodash/defaults');
15
- const remove = require('lodash/remove');
12
+ const {
13
+ callFederated,
14
+ generateSiteInfo,
15
+ getFederatedSiteEnv,
16
+ safeGetFederated,
17
+ } = require('@abtnode/auth/lib/util/federated');
16
18
  const { fromAppDid } = require('@arcblock/did-ext');
17
19
 
18
20
  const logger = require('../libs/logger')('blocklet-services:federated');
19
- const { api } = require('../libs/api');
20
21
  const initJwt = require('../libs/jwt');
21
22
  const { createTokenFn, getDidConnectVersion } = require('../util');
22
23
  const ensureBlocklet = require('../middlewares/ensure-blocklet');
23
- const verifyFederatedCall = require('../middlewares/verify-federated-call');
24
24
  const {
25
25
  getUserAvatarUrl,
26
26
  getFederatedMaster,
@@ -28,10 +28,10 @@ const {
28
28
  getTrustedDomains,
29
29
  } = require('../util/federated');
30
30
  const { declareAccount, migrateAccount } = require('../services/oauth');
31
+ const { checkFederatedCall } = require('../middlewares/check-federated');
31
32
 
32
33
  const PREFIX = WELLKNOWN_SERVICE_PATH_PREFIX;
33
-
34
- const prefix = `${PREFIX}/api/federated`;
34
+ const prefixApi = `${PREFIX}/api/federated`;
35
35
 
36
36
  function getAuditLogActorByFederatedSite(blocklet) {
37
37
  return {
@@ -145,96 +145,76 @@ async function syncDisconnectAccount(user, { node, teamDid, blocklet }) {
145
145
  /**
146
146
  * member 站点向 master 站点请求拉取一个用户信息
147
147
  */
148
- async function pullUserAccount(user, { node, teamDid, blocklet }) {
149
- const { did } = user;
150
- const currentUser = await node.getUser({
151
- teamDid,
152
- user: {
153
- did,
154
- },
155
- options: {
156
- enableConnectedAccount: true,
157
- },
158
- });
159
-
160
- if (!currentUser) return null;
161
148
 
162
- const syncUser = pick(currentUser, [
163
- 'did',
164
- 'pk',
165
- 'fullName',
166
- 'email',
167
- 'phone',
168
- 'url',
169
- 'remark',
170
- 'sourceProvider',
171
- 'locale',
172
- 'approved',
173
- 'extra',
174
- 'sourceAppPid',
175
- 'inviter',
176
- 'emailVerified',
177
- 'phoneVerified',
178
- ]);
179
- syncUser.avatar = getUserAvatarUrl(currentUser.avatar, blocklet);
180
- syncUser.email = syncUser.email || '';
181
- syncUser.connectedAccounts = currentUser.connectedAccounts.map((x) => {
182
- const connectAccount = pick(x, ['did', 'pk', 'provider', 'id', 'userInfo']);
183
- if (!connectAccount.id) {
184
- delete connectAccount.id;
185
- }
186
- return connectAccount;
187
- });
188
-
189
- return syncUser;
190
- }
191
-
192
- const syncFnMaps = {
149
+ const syncUserFnMaps = {
150
+ // 用户更换 profile 通知
193
151
  switchProfile: syncSwitchProfile,
152
+ // 用户绑定第三方登录
194
153
  connectAccount: syncConnectAccount,
154
+ // 用户解绑第三方登录
195
155
  disconnectAccount: syncDisconnectAccount,
196
- pullAccount: pullUserAccount,
197
156
  };
198
157
 
199
158
  module.exports = {
200
159
  init(server, node, options) {
160
+ // =============================== 以下为公开的接口 ===============================
161
+
162
+ // 获取当前站点所有可信的域名
163
+ server.get(`${prefixApi}/getTrustedDomains`, ensureBlocklet(), async (req, res) => {
164
+ const { blocklet } = req;
165
+ const result = await getTrustedDomains({ node, req, blocklet });
166
+ res.json(result);
167
+ });
168
+
169
+ server.get(`${prefixApi}/env`, ensureBlocklet(), (req, res) => {
170
+ const { blocklet } = req;
171
+ const masterSite = getFederatedMaster(blocklet);
172
+ const result = {
173
+ sigVersion: SIG_VERSION.DEFAULT,
174
+ masterAppUrl: masterSite?.appUrl,
175
+ };
176
+ res.json(result);
177
+ });
178
+
201
179
  // step 1 申请加入(member 向 master 申请)
202
- server.post(`${prefix}/join`, ensureBlocklet(), async (req, res) => {
203
- // master blocklet
180
+ // member 发起(master 不能发起),master 处理该路由
181
+ server.post(`${prefixApi}/join`, ensureBlocklet(), async (req, res) => {
204
182
  const { blocklet } = req;
205
183
  const { site } = req.body;
206
184
  const teamDid = blocklet.appPid;
207
185
 
208
- const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
209
- config: {
210
- appId: blocklet.appDid,
211
- appPid: teamDid,
186
+ const federated = safeGetFederated(blocklet, { isMaster: true });
187
+ const exists = federated.sites.find((x) => x.appPid === site.appPid);
188
+ // 1. 检查当前站点群的数据中是否有目标站点
189
+ if (exists) {
190
+ logger.error("already in a federated site group, don't need join again", {
191
+ teamDid,
192
+ site,
193
+ });
194
+ res.status(401).send("already in a federated site group, don't need join again");
195
+ return;
196
+ }
197
+
198
+ // 1. 检查目标站点自身是否已加入其他的站点群
199
+ const siteEnv = await getFederatedSiteEnv({
200
+ site: {
201
+ appUrl: site.appUrl,
212
202
  },
213
- sites: [],
214
203
  });
204
+ if (siteEnv.masterAppUrl) {
205
+ logger.error('already in a federated site group, please quit federated site group first', {
206
+ siteEnv,
207
+ site,
208
+ });
209
+ res.status(401).send('already in a federated site group, please quit federated site group first');
210
+ return;
211
+ }
212
+
213
+ // 当前站点未形成站点群,需要先生成 master 的相关信息
215
214
  if (federated.sites.length === 0) {
216
215
  const nodeInfo = await req.getNodeInfo();
217
- const blockletInfo = await req.getBlockletInfo();
218
216
  const domainAliases = await node.getBlockletDomainAliases({ blocklet, nodeInfo });
219
- const masterSite = {
220
- appId: blocklet.appDid,
221
- appPid: teamDid,
222
- aliasDid: (blocklet.migratedFrom || []).map((item) => item.appDid),
223
- appName: blockletInfo.name,
224
- appDescription: blockletInfo.description,
225
- appUrl: blockletInfo.appUrl,
226
- aliasDomain: domainAliases.map((item) => item.value),
227
- appLogo:
228
- blocklet.environmentObj.BLOCKLET_APP_LOGO ||
229
- normalizePathPrefix(`${WELLKNOWN_SERVICE_PATH_PREFIX}/blocklet/logo`) ||
230
- '/',
231
- appLogoRect: blocklet.environmentObj.BLOCKLET_APP_LOGO_RECT,
232
- did: blockletInfo.permanentWallet.address,
233
- pk: blockletInfo.permanentWallet.publicKey,
234
- serverId: nodeInfo.did,
235
- serverVersion: nodeInfo.version,
236
- version: blocklet.meta.version,
237
- };
217
+ const masterSite = await generateSiteInfo({ blocklet, domainAliases, nodeInfo });
238
218
  federated.sites = [masterSite];
239
219
  }
240
220
 
@@ -247,8 +227,8 @@ module.exports = {
247
227
  });
248
228
  }
249
229
  // member 申请后,将 member 展示在列表中
250
- // 更新的是自己
251
- const newState = await node.setFederated({
230
+ // 更新的是自己,此时还不用通知其他的子成员站点
231
+ const newBlockletState = await node.setFederated({
252
232
  did: teamDid,
253
233
  config: federated,
254
234
  });
@@ -260,195 +240,469 @@ module.exports = {
260
240
  context: {
261
241
  user: getAuditLogActorByFederatedSite(site),
262
242
  },
263
- result: newState,
243
+ result: newBlockletState,
264
244
  },
265
245
  node
266
246
  );
267
247
 
268
- // 将新增的数据返回给 member
248
+ // 将新增的数据返回给 member,只返回 master 和申请成员,待审核通过后,才能获取所有的成员站点信息
249
+ const result = federated.sites.filter((x) => [teamDid, site.appPid].includes(x.appPid));
269
250
  res.json({
270
- sites: federated.sites,
251
+ sites: result,
271
252
  });
272
253
  });
273
254
 
274
- // member master 请求退出统一登录
275
- server.post(`${prefix}/quit`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
276
- const { blocklet } = req;
277
- const { memberPid } = req.body.verifyData;
278
- const teamDid = blocklet.appPid;
255
+ // =============================== 以下为需要鉴权的接口 ===============================
279
256
 
280
- const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
281
- config: {
282
- appId: blocklet.appDid,
283
- appPid: teamDid,
284
- },
285
- sites: [],
286
- });
257
+ // ------------------------------- 以下为仅 member 可以发起的请求 -------------------------------
287
258
 
288
- const removedSites = remove(federated.sites, (item) => item.appPid === memberPid);
259
+ // member master 请求退出统一登录,然后 master 把情况同步给所有成员站点
260
+ // member 发起(master 不能发起),master 处理该路由 (member -> master)
261
+ server.post(
262
+ `${prefixApi}/quit`,
263
+ ensureBlocklet(),
264
+ checkFederatedCall({ mode: 'memberToMaster', allowStatus: ['approved', 'rejected', 'pending'] }),
265
+ async (req, res) => {
266
+ const { blocklet, verifySite } = req;
267
+ const teamDid = blocklet.appPid;
289
268
 
290
- const { permanentWallet } = await req.getBlockletInfo();
291
- const postData = {
292
- signer: permanentWallet.address,
293
- data: signV2(permanentWallet.address, permanentWallet.secretKey, { sites: federated.sites }),
294
- };
295
- const limitSync = pLimit(FEDERATED.SYNC_LIMIT);
296
-
297
- const waitingList = federated.sites
298
- .filter((item) => item.appId !== federated.config.appId)
299
- .map((item) => {
300
- return limitSync(async () => {
301
- const url = joinURL(item.appUrl, WELLKNOWN_SERVICE_PATH_PREFIX, '/api/federated/sync');
302
- // NOTICE: 即使通知其他 member 失败了,也不影响来源 member 退出统一登录
303
- try {
304
- await pRetry(() => api.post(url, postData), {
305
- retries: 3,
306
- });
307
- } catch (error) {
308
- logger.error('Failed to sync federated member', {
309
- error,
310
- url,
311
- did: blocklet.appDid,
312
- action: 'quit',
313
- });
314
- }
269
+ const federated = safeGetFederated(blocklet, { isMaster: true });
270
+ const [removedSite] = remove(federated.sites, (item) => item.appPid === verifySite.appPid);
271
+
272
+ const { permanentWallet } = await req.getBlockletInfo();
273
+ const limitSync = pLimit(FEDERATED.SYNC_LIMIT);
274
+
275
+ const waitingList = federated.sites
276
+ // 排除 master 和请求退出的 member
277
+ .filter((item) => ![teamDid, verifySite.appPid].includes(item.appPid))
278
+ .map((item) => {
279
+ return limitSync(async () => {
280
+ // NOTICE: 即使通知其他 member 失败了,也不影响来源 member 退出统一登录
281
+ try {
282
+ await callFederated({
283
+ action: 'sync',
284
+ site: item,
285
+ data: { sites: [{ action: 'delete', appPid: verifySite.appPid }] },
286
+ permanentWallet,
287
+ });
288
+ } catch (error) {
289
+ logger.error('Failed to sync federated member', {
290
+ error,
291
+ did: blocklet.appDid,
292
+ action: 'quit',
293
+ siteItem: item,
294
+ });
295
+ }
296
+ });
315
297
  });
298
+ await Promise.all(waitingList);
299
+
300
+ const newState = await node.setFederated({
301
+ did: teamDid,
302
+ config: federated,
316
303
  });
317
- await Promise.all(waitingList);
318
304
 
319
- const newState = await node.setFederated({
320
- did: teamDid,
321
- config: federated,
322
- });
305
+ await node.createAuditLog(
306
+ {
307
+ action: 'quitFederated',
308
+ args: { memberSite: removedSite, teamDid },
309
+ context: {
310
+ user: getAuditLogActorByFederatedSite(removedSite),
311
+ },
312
+ result: newState,
313
+ },
314
+ node
315
+ );
323
316
 
324
- await node.createAuditLog(
325
- {
326
- action: 'quitFederated',
327
- args: { memberSite: removedSites[0], teamDid },
328
- context: {
329
- user: getAuditLogActorByFederatedSite(removedSites[0]),
317
+ res.status(204).send();
318
+ }
319
+ );
320
+
321
+ // member 向 master 申请第三方账号的 migrate
322
+ // member 发起(master 不能发起),master 处理该路由 (member -> master)
323
+ server.post(
324
+ `${prefixApi}/migrateAccount`,
325
+ ensureBlocklet(),
326
+ checkFederatedCall({ mode: 'memberToMaster' }),
327
+ async (req, res) => {
328
+ const { blocklet, verifySite, verifyData } = req;
329
+ const { did: teamDid, wallet: blockletWallet } = await req.getBlockletInfo();
330
+ const { fromUserDid, toUserDid, toUserPk } = verifyData;
331
+ const oauthUser = await node.getUser({ teamDid, user: { did: fromUserDid } });
332
+ const connectedAccounts = oauthUser?.connectedAccounts || [];
333
+ const sourceProvider = oauthUser?.sourceProvider;
334
+ const oauthAccount = connectedAccounts.find((item) => item.provider === sourceProvider);
335
+ const userWallet = fromAppDid(oauthAccount.id, blockletWallet.secretKey);
336
+
337
+ const bindUser = {
338
+ did: toUserDid,
339
+ pk: toUserPk,
340
+ };
341
+ await declareAccount({ wallet: userWallet, blocklet });
342
+ await migrateAccount({ wallet: userWallet, blocklet, user: bindUser });
343
+ await node.createAuditLog(
344
+ {
345
+ action: 'migrateFederatedAccount',
346
+ args: { fromUserDid, toUserDid, callerSite: verifySite, teamDid },
347
+ context: {
348
+ user: getAuditLogActorByFederatedSite(verifySite),
349
+ },
330
350
  },
331
- result: newState,
332
- },
333
- node
334
- );
351
+ node
352
+ );
353
+ res.status(204).send();
354
+ }
355
+ );
335
356
 
336
- res.json({});
337
- });
357
+ // member 向 master 索取 delegation 和 roles 列表
358
+ // member 发起(master 不能发起),master 处理该路由 (member -> master)
359
+ server.post(
360
+ `${prefixApi}/getMasterAuthorization`,
361
+ ensureBlocklet(),
362
+ checkFederatedCall({ mode: 'memberToMaster' }),
363
+ async (req, res) => {
364
+ const { blocklet, verifySite } = req;
365
+ const teamDid = blocklet.appPid;
366
+ const { permanentWallet } = await req.getBlockletInfo();
367
+ const delegation = signV2(permanentWallet.address, permanentWallet.secretKey, {
368
+ // HACK: 钱包签名使用的始终是最新的,这里的 dalegation 也保持 agentDid 就是当前应用最新的 did(appId)
369
+ agentDid: `did:abt:${verifySite.appId}`,
370
+ permissions: [
371
+ {
372
+ role: 'DIDConnectAgent',
373
+ claims: [
374
+ 'authPrincipal',
375
+ 'profile',
376
+ 'signature',
377
+ 'prepareTx',
378
+ 'agreement',
379
+ 'verifiableCredential',
380
+ 'asset',
381
+ 'assetOrVC',
382
+ 'keyPair',
383
+ // 'encryptionKey', // 备份还原应用时使用
384
+ ],
385
+ },
386
+ ],
387
+ exp: Math.floor(new Date().getTime() / 1000) + 86400 * 365 * 100, // valid for 100 year
388
+ });
389
+ const roleList = await node.getRoles({ teamDid });
390
+ const roles = roleList.map((item) => pick(item, ['name', 'title', 'description']));
391
+ res.json({ delegation, roles });
392
+ }
393
+ );
338
394
 
339
- // master 通知 member 当前统一登录要解散
340
- server.post(`${prefix}/disband`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
341
- const { blocklet } = req;
342
- const { verifySite } = req.body;
343
- const teamDid = blocklet.appPid;
395
+ server.post(
396
+ `${prefixApi}/pullFederatedSites`,
397
+ ensureBlocklet(),
398
+ checkFederatedCall({ mode: 'memberToMaster' }),
399
+ (req, res) => {
400
+ const { blocklet } = req;
401
+ const federated = safeGetFederated(blocklet, { isMaster: true });
402
+ const result = federated.sites.filter((x) => !['pending'].includes(x.status));
403
+ res.json(result);
404
+ }
405
+ );
344
406
 
345
- const newState = await node.setFederated({
346
- did: teamDid,
347
- config: null,
348
- });
349
- await node.createAuditLog(
350
- {
351
- action: 'disbandFederated',
352
- args: { blocklet, masterSite: verifySite, teamDid },
353
- context: {
354
- user: getAuditLogActorByFederatedSite(verifySite),
407
+ server.post(
408
+ `${prefixApi}/pullAccount`,
409
+ ensureBlocklet(),
410
+ checkFederatedCall({ mode: 'memberToMaster' }),
411
+ async (req, res) => {
412
+ const { blocklet, verifyData } = req;
413
+ const { users } = verifyData;
414
+ const result = await pMap(
415
+ users,
416
+ async (user) => {
417
+ const teamDid = blocklet.appPid;
418
+ const currentUser = await node.getUser({
419
+ teamDid,
420
+ user: {
421
+ did: user.did,
422
+ },
423
+ options: {
424
+ enableConnectedAccount: true,
425
+ },
426
+ });
427
+
428
+ if (!currentUser) return null;
429
+
430
+ const syncUser = pick(currentUser, [
431
+ 'did',
432
+ 'pk',
433
+ 'fullName',
434
+ 'email',
435
+ 'phone',
436
+ 'url',
437
+ 'remark',
438
+ 'sourceProvider',
439
+ 'locale',
440
+ 'approved',
441
+ 'extra',
442
+ 'sourceAppPid',
443
+ 'inviter',
444
+ 'emailVerified',
445
+ 'phoneVerified',
446
+ ]);
447
+ syncUser.avatar = getUserAvatarUrl(currentUser.avatar, blocklet);
448
+ syncUser.email = syncUser.email || '';
449
+ syncUser.connectedAccounts = currentUser.connectedAccounts.map((x) => {
450
+ const connectAccount = pick(x, ['did', 'pk', 'provider', 'id', 'userInfo']);
451
+ if (!connectAccount.id) {
452
+ delete connectAccount.id;
453
+ }
454
+ return connectAccount;
455
+ });
456
+ return syncUser;
355
457
  },
356
- result: newState,
357
- },
358
- node
359
- );
360
- res.json({});
361
- });
458
+ { concurrency: FEDERATED.SYNC_LIMIT }
459
+ );
460
+
461
+ res.json(result);
462
+ }
463
+ );
464
+
465
+ // ------------------------------- 以下为仅 master 可以发起的请求 -------------------------------
466
+
467
+ // master 通知 member 当前统一登录要解散
468
+ // master 发起(member 不能发起),member 处理该路由 (master -> member)
469
+ server.post(
470
+ `${prefixApi}/disband`,
471
+ ensureBlocklet(),
472
+ checkFederatedCall({ mode: 'masterToMember' }),
473
+ async (req, res) => {
474
+ const { blocklet, verifySite } = req;
475
+ const teamDid = blocklet.appPid;
476
+
477
+ const newState = await node.setFederated({
478
+ did: teamDid,
479
+ config: null,
480
+ });
481
+ await node.createAuditLog(
482
+ {
483
+ action: 'disbandFederated',
484
+ args: { blocklet, masterSite: verifySite, teamDid },
485
+ context: {
486
+ user: getAuditLogActorByFederatedSite(verifySite),
487
+ },
488
+ result: newState,
489
+ },
490
+ node
491
+ );
492
+ res.status(204).send();
493
+ }
494
+ );
362
495
 
363
496
  // step 2 审批(master 申批 member)
364
497
  // core/state/lib/blocklet/manager/disk.js -> auditFederatedLogin
365
- // audit-res 接受 master 的处理结果同步,保存 delegation
366
- server.post(`${prefix}/audit-res`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
367
- const { blocklet } = req;
368
- const { delegation, roles, masterPid, status } = req.body.verifyData;
369
- const { verifySite } = req.body;
370
- const teamDid = blocklet.appPid;
371
- const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
372
- config: {
373
- appId: blocklet.appDid,
374
- appPid: teamDid,
375
- isMaster: false,
376
- },
377
- sites: [],
378
- });
379
- federated.config.delegation = delegation;
380
- if (status === 'approved') {
381
- const trustedPassports = blocklet.trustedPassports || [];
382
- const hasTrustedPassport = trustedPassports.find((item) => item.issuerDid === masterPid);
383
- if (!hasTrustedPassport) {
384
- await node.configTrustedPassports({
385
- teamDid,
386
- trustedPassports: [
387
- ...trustedPassports,
388
- {
389
- issuerDid: masterPid,
390
- remark: 'Generated on join federated login',
391
- mappings: roles.map((item) => {
392
- return {
393
- from: { passport: item.name },
394
- to: { role: 'guest' },
395
- };
396
- }),
397
- },
398
- ],
399
- });
498
+ // audit-res 接受 master 的处理结果同步
499
+ // master 发起(member 不能发起),member 处理该路由 (master -> member)
500
+ server.post(
501
+ `${prefixApi}/audit-res`,
502
+ ensureBlocklet(),
503
+ checkFederatedCall({
504
+ mode: 'masterToMember',
505
+ }),
506
+ async (req, res) => {
507
+ const { blocklet, verifySite, verifyData } = req;
508
+ const { status } = verifyData;
509
+ const teamDid = blocklet.appPid;
510
+ if (status === 'approved') {
511
+ await node.syncMasterAuthorization({ did: teamDid });
512
+ await node.syncFederatedConfig({ did: teamDid });
513
+ } else if (status === 'rejected') {
514
+ const federated = safeGetFederated(blocklet);
515
+ const selfSite = federated.sites?.find((x) => x.appPid === teamDid);
516
+ if (selfSite) {
517
+ selfSite.status = 'rejected';
518
+ await node.setFederated({
519
+ did: teamDid,
520
+ config: federated,
521
+ });
522
+ }
400
523
  }
524
+
525
+ await node.createAuditLog(
526
+ {
527
+ action: 'auditFederated',
528
+ args: { masterSite: verifySite, status, teamDid },
529
+ context: {
530
+ user: getAuditLogActorByFederatedSite(verifySite),
531
+ },
532
+ result: blocklet,
533
+ },
534
+ node
535
+ );
536
+ res.status(204).send();
401
537
  }
538
+ );
402
539
 
403
- const newState = await node.setFederated({
404
- did: teamDid,
405
- config: federated,
406
- });
407
- await node.createAuditLog(
408
- {
409
- action: 'auditFederated',
410
- args: { masterSite: verifySite, status, teamDid },
411
- context: {
412
- user: getAuditLogActorByFederatedSite(verifySite),
540
+ // 用于在 master 站点登录页面获取 member 登录的 token
541
+ // master 发起(member 不能发起),member 处理该路由 (master -> member)
542
+ server.post(
543
+ `${prefixApi}/loginByMaster`,
544
+ ensureBlocklet(),
545
+ checkFederatedCall({ mode: 'masterToMember' }),
546
+ async (req, res) => {
547
+ const { blocklet, verifySite, verifyData } = req;
548
+ const { passport, user, walletOS, provider } = verifyData;
549
+ const { createSessionToken } = initJwt(node, options);
550
+ const createToken = createTokenFn(createSessionToken);
551
+ const { secret } = await req.getBlockletInfo();
552
+ const teamDid = blocklet.appPid;
553
+
554
+ const sessionConfig = blocklet.settings?.session || {};
555
+ const prevUser = await getUserWithinFederated(
556
+ {
557
+ teamDid,
558
+ sourceAppPid: verifySite.appPid,
559
+ userDid: user.did,
560
+ userPk: user.pk,
413
561
  },
414
- result: newState,
415
- },
416
- node
417
- );
418
- res.json(federated);
419
- });
562
+ {
563
+ node,
564
+ blocklet,
565
+ }
566
+ );
567
+ if (prevUser?.approved === false) {
568
+ res.status(401).json({ error: messages.notAllowedAppUser.en });
569
+ return;
570
+ }
571
+ // HACK: member 调用 master 时,将 passport 的 role 还原为 master 中原有的 role
572
+ const targetPassport = passport?.id
573
+ ? (prevUser?.passports || []).find((item) => item.id === passport.id)
574
+ : null;
575
+
576
+ // HACK: 用户在 master 中存在时,不更新任何用户信息;不存在时,将新增一个用户
577
+ const filterUserInfo = prevUser ? {} : user;
578
+ if (filterUserInfo.avatar) {
579
+ let avatar = await getAvatarByUrl(filterUserInfo.avatar);
580
+ const nodeInfo = await req.getNodeInfo();
581
+
582
+ const { dataDir } = await getApplicationInfo({ node, nodeInfo, teamDid });
583
+ avatar = await extractUserAvatar(avatar, { dataDir });
584
+ filterUserInfo.avatar = avatar;
585
+ }
586
+ const realDid = prevUser?.did || user.did;
587
+ const realPk = prevUser?.pk || user.pk;
588
+ const newUser = await node.loginUser({
589
+ teamDid,
590
+ user: {
591
+ ...filterUserInfo,
592
+ did: realDid,
593
+ pk: realPk,
594
+ passport: targetPassport,
595
+ sourceAppPid: verifySite.appPid,
596
+ connectedAccount: {
597
+ provider: provider || LOGIN_PROVIDER.WALLET,
598
+ did: user.did,
599
+ pk: user.pk,
600
+ },
601
+ },
602
+ });
603
+
604
+ const { sessionToken, refreshToken } = createToken(
605
+ user.did,
606
+ {
607
+ secret,
608
+ passport: targetPassport,
609
+ role: targetPassport?.role || 'guest',
610
+ fullName: newUser.fullName,
611
+ provider: provider || LOGIN_PROVIDER.WALLET,
612
+ walletOS,
613
+ sourceAppPid: verifySite.appPid,
614
+ emailVerified: newUser.emailVerified,
615
+ phoneVerified: newUser.phoneVerified,
616
+ },
617
+ {
618
+ ...sessionConfig,
619
+ didConnectVersion: getDidConnectVersion(req),
620
+ }
621
+ );
622
+
623
+ await node.createAuditLog(
624
+ {
625
+ action: 'loginByMaster',
626
+ args: { masterSite: verifySite, teamDid },
627
+ context: {
628
+ user: newUser,
629
+ },
630
+ result: blocklet,
631
+ },
632
+ node
633
+ );
634
+
635
+ res.json({ sessionToken, refreshToken });
636
+ }
637
+ );
638
+
639
+ // ------------------------------- 以下为站点群内可以互相发起的请求 -------------------------------
420
640
 
421
641
  // step 3 同步站点群信息(master 向 member 广播站点群信息,广播请求在 manager/disk.js 文件中 class FederatedBlockletManager 发起 )
422
- // 该路由为 member 接受响应的 api(只允许 master 调用)
423
- server.post(`${prefix}/sync`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
424
- const { blocklet } = req;
425
- const { verifySite } = req.body;
642
+ // 站点群互相可以任意获取
643
+ server.post(`${prefixApi}/sync`, ensureBlocklet(), checkFederatedCall(), async (req, res) => {
644
+ const { blocklet, verifySite, verifyData } = req;
426
645
  const teamDid = blocklet.appPid;
427
- const { users = null, sites = null, userSessions = null } = req.body.verifyData;
646
+ const { users = null, sites = null, userSessions = null } = verifyData;
428
647
  const resultData = {
429
648
  users: [],
430
649
  sites: [],
431
650
  userSessions: [],
432
651
  };
433
652
 
434
- // FIXME: @zhanghan 校验 users 和 sites 数据合法性
653
+ // sites 支持增量更新
435
654
  if (!isNil(sites)) {
436
655
  const limitSync = pLimit(FEDERATED.SYNC_LIMIT);
437
656
  const pendingSiteList = [];
438
- const federated = cloneDeep(blocklet.settings.federated || {});
439
- federated.sites = sites;
657
+ const federated = safeGetFederated(blocklet);
658
+ for (const site of sites) {
659
+ const { action, ...siteItem } = site;
660
+ const findIndex = federated.sites.findIndex((x) => x.appPid === siteItem.appPid);
661
+ const isMyself = siteItem.appPid === teamDid;
662
+ if (action === 'update') {
663
+ if (findIndex > -1) {
664
+ Object.assign(federated.sites[findIndex], siteItem);
665
+ }
666
+ } else if (action === 'upsert') {
667
+ if (findIndex > -1) {
668
+ Object.assign(federated.sites[findIndex], siteItem);
669
+ } else {
670
+ federated.sites.push(siteItem);
671
+ }
672
+ // 不允许增加自己,也不允许删除自己
673
+ } else if (!isMyself) {
674
+ if (action === 'add') {
675
+ if (findIndex === -1) {
676
+ federated.sites.push(siteItem);
677
+ }
678
+ } else if (action === 'delete') {
679
+ if (findIndex > -1) {
680
+ federated.sites.splice(findIndex, 1);
681
+ }
682
+ }
683
+ }
684
+ }
440
685
  pendingSiteList.push(
441
686
  limitSync(async () => {
442
- await node.setFederated({
443
- did: teamDid,
444
- config: federated,
445
- });
687
+ try {
688
+ await node.setFederated({
689
+ did: teamDid,
690
+ config: federated,
691
+ });
692
+ } catch (error) {
693
+ logger.error('failed to update federated sites', {
694
+ error,
695
+ teamDid,
696
+ sites,
697
+ });
698
+ }
446
699
  })
447
700
  );
448
701
  const resList = await Promise.all(pendingSiteList);
449
702
  resultData.sites = resList;
450
703
  }
451
704
 
705
+ // users 支持增量更新
452
706
  if (!isNil(users)) {
453
707
  if (Array.isArray(users)) {
454
708
  const limitSync = pLimit(FEDERATED.SYNC_LIMIT);
@@ -458,14 +712,23 @@ module.exports = {
458
712
  for (const user of users) {
459
713
  pendingUserList.push(
460
714
  limitSync(async () => {
461
- const result = await syncFnMaps[user.action]?.(
462
- {
463
- ...user,
464
- sourceAppPid: user.sourceAppPid === teamDid ? null : user.sourceAppPid,
465
- },
466
- { node, teamDid, dataDir, blocklet }
467
- );
468
- return result;
715
+ try {
716
+ const result = await syncUserFnMaps[user.action]?.(
717
+ {
718
+ ...user,
719
+ sourceAppPid: user.sourceAppPid === teamDid ? null : user.sourceAppPid,
720
+ },
721
+ { node, teamDid, dataDir, blocklet }
722
+ );
723
+ return result;
724
+ } catch (error) {
725
+ logger.error('failed to update federated users', {
726
+ error,
727
+ user,
728
+ });
729
+ }
730
+
731
+ return null;
469
732
  })
470
733
  );
471
734
  }
@@ -474,6 +737,7 @@ module.exports = {
474
737
  }
475
738
  }
476
739
 
740
+ // userSessions 支持增量更新
477
741
  if (!isNil(userSessions)) {
478
742
  if (Array.isArray(userSessions)) {
479
743
  const pendingUserSessionList = [];
@@ -482,14 +746,27 @@ module.exports = {
482
746
  const { action, ...userSessionItem } = userSession;
483
747
  pendingUserSessionList.push(
484
748
  limitSync(async () => {
485
- if (action === 'login') {
486
- await node.upsertUserSession({ ...userSessionItem, teamDid, status: 'online' });
487
- } else if (action === 'logout') {
488
- await node.logoutUser({
489
- ...userSessionItem,
749
+ try {
750
+ if (action === 'login') {
751
+ const result = await node.upsertUserSession({ ...userSessionItem, teamDid, status: 'online' });
752
+ return result;
753
+ }
754
+ if (action === 'logout') {
755
+ const result = await node.logoutUser({
756
+ ...userSessionItem,
757
+ teamDid,
758
+ });
759
+ return result;
760
+ }
761
+ } catch (error) {
762
+ logger.error('failed to update federated userSession', {
763
+ error,
764
+ action,
765
+ userSessionItem,
490
766
  teamDid,
491
767
  });
492
768
  }
769
+ return null;
493
770
  })
494
771
  );
495
772
  }
@@ -509,344 +786,23 @@ module.exports = {
509
786
  res.json(resultData);
510
787
  });
511
788
 
512
- // step 6 发放自动登录 token(master 向 member 发起生成 token 请求)
513
- server.post(`${prefix}/token`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
514
- const { user, masterPid, role, passport, walletOS, provider } = req.body.verifyData;
515
- const { verifySite } = req.body;
516
- const { createSessionToken } = initJwt(node, options);
517
- const createToken = createTokenFn(createSessionToken);
518
- const { secret } = await req.getBlockletInfo();
519
- const { blocklet } = req;
520
- const teamDid = blocklet.appPid;
521
-
522
- const sessionConfig = blocklet.settings?.session || {};
523
- const trustedPassports = blocklet.trustedPassports || [];
524
- // HACK: 这里只对比 pid,因为自动生成的数据只有 master-site 的 pid
525
- const masterPassport = trustedPassports.find((item) => item.issuerDid === masterPid);
526
- const findMapping = masterPassport ? masterPassport.mappings.find((item) => item.from.passport === role) : null;
527
- const targetPassport = findMapping
528
- ? {
529
- role: findMapping.to?.role || 'guest',
530
- name: findMapping.to?.role || 'Guest',
531
- id: passport?.id || '',
532
- }
533
- : { role: 'guest', name: 'Guest' };
534
- let { avatar } = user || {};
535
- if (avatar) {
536
- try {
537
- avatar = await getAvatarByUrl(user.avatar);
538
- const nodeInfo = await req.getNodeInfo();
539
-
540
- const { dataDir } = await getApplicationInfo({ node, nodeInfo, teamDid });
541
- avatar = await extractUserAvatar(avatar, { dataDir });
542
- } catch (err) {
543
- logger.error('Failed to convert user avatar', { error: err });
544
- }
545
- }
546
- const doc = await node.loginUser({
547
- teamDid,
548
- user: {
549
- ...user,
550
- avatar,
551
- // HACK: @zhanghan 这里会将 passport 插入到当前用户的 passport 列表中,federated 登录不应该插入 passport
552
- // passport: findMapping ? targetPassport : null,
553
- sourceAppPid: masterPid,
554
- connectedAccount: {
555
- provider: provider || LOGIN_PROVIDER.WALLET,
556
- id: masterPid,
557
- did: user.did,
558
- pk: user.pk,
559
- },
560
- },
561
- });
562
- const { sessionToken, refreshToken } = createToken(
563
- doc.did,
564
- {
565
- secret,
566
- role: targetPassport.role,
567
- passport: targetPassport,
568
- fullName: doc.fullName,
569
- provider: provider || LOGIN_PROVIDER.WALLET,
570
- walletOS,
571
- emailVerified: doc.emailVerified,
572
- phoneVerified: doc.phoneVerified,
573
- },
574
- {
575
- ...sessionConfig,
576
- didConnectVersion: getDidConnectVersion(req),
577
- }
578
- );
579
- await node.createAuditLog(
580
- {
581
- action: 'loginByMaster',
582
- args: { masterSite: verifySite, teamDid },
583
- context: {
584
- user: doc,
585
- },
586
- result: blocklet,
587
- },
588
- node
589
- );
590
-
591
- res.json({ sessionToken, refreshToken });
592
- });
593
-
594
- // member 主动调起 master 登录(实现登录 member 时,自动登录 master)
595
- // member 传递过来的 user.did 和 user.pk 均为 master-site 与钱包生成的
596
- server.post(`${prefix}/loginByMember`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
597
- const { verifySite } = req.body;
598
- const { user, passport, walletOS, provider } = req.body.verifyData;
599
- const { createSessionToken } = initJwt(node, options);
600
- const createToken = createTokenFn(createSessionToken);
601
- const { secret } = await req.getBlockletInfo();
602
- const { blocklet } = req;
603
- const teamDid = blocklet.appPid;
604
-
605
- const sessionConfig = blocklet.settings?.session || {};
606
- const prevUser = await node.getUser({
607
- teamDid,
608
- user: { did: user.did },
609
- options: { enableConnectedAccount: true },
610
- });
611
- // HACK: member 调用 master 时,将 passport 的 role 还原为 master 中原有的 role
612
- const targetPassport = passport?.id ? (prevUser?.passports || []).find((item) => item.id === passport.id) : null;
613
-
614
- // HACK: 用户在 master 中存在时,不更新任何用户信息;不存在时,将新增一个用户
615
- const filterUserInfo = prevUser ? {} : user;
616
- if (filterUserInfo.avatar) {
617
- let avatar = await getAvatarByUrl(filterUserInfo.avatar);
618
- const nodeInfo = await req.getNodeInfo();
619
-
620
- const { dataDir } = await getApplicationInfo({ node, nodeInfo, teamDid });
621
- avatar = await extractUserAvatar(avatar, { dataDir });
622
- filterUserInfo.avatar = avatar;
623
- }
624
- const realDid = prevUser?.did || user.did;
625
- const realPk = prevUser?.pk || user.pk;
626
- // NOTICE: 这里是 Master 登录,不需要 sourceAppPid 字段
627
- const newUser = await node.loginUser({
628
- teamDid,
629
- user: {
630
- ...filterUserInfo,
631
- did: realDid,
632
- pk: realPk,
633
- passport: targetPassport,
634
- connectedAccount: {
635
- provider: provider || LOGIN_PROVIDER.WALLET,
636
- did: user.did,
637
- pk: user.pk,
638
- },
639
- },
640
- });
641
-
642
- const { sessionToken, refreshToken } = createToken(
643
- user.did,
644
- {
645
- secret,
646
- passport: targetPassport,
647
- role: targetPassport?.role || 'guest',
648
- fullName: newUser.fullName,
649
- // 这里是 member 登录了 master 的账号,对于 master 来说,其实还是使用 wallet 来登录的
650
- provider: LOGIN_PROVIDER.WALLET,
651
- walletOS,
652
- emailVerified: newUser.emailVerified,
653
- phoneVerified: newUser.phoneVerified,
654
- },
655
- {
656
- ...sessionConfig,
657
- didConnectVersion: getDidConnectVersion(req),
658
- }
659
- );
660
-
661
- await node.createAuditLog(
662
- {
663
- action: 'loginByMember',
664
- args: { memberSite: verifySite, teamDid },
665
- context: {
666
- user: newUser,
667
- },
668
- result: blocklet,
669
- },
670
- node
671
- );
672
-
673
- res.json({ sessionToken, refreshToken });
674
- });
675
-
676
- // 用于在 master 站点登录页面获取 member 登录的 token
677
- server.post(`${prefix}/loginByMaster`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
678
- const { verifySite } = req.body;
679
- const { passport, user, walletOS, provider } = req.body.verifyData;
680
- const { createSessionToken } = initJwt(node, options);
681
- const createToken = createTokenFn(createSessionToken);
682
- const { secret } = await req.getBlockletInfo();
683
- const { blocklet } = req;
789
+ // 获取指定 passportId 的内容
790
+ // 站点群互相可以任意获取
791
+ server.post(`${prefixApi}/getPassport`, ensureBlocklet(), checkFederatedCall(), async (req, res) => {
792
+ const { blocklet, verifyData } = req;
684
793
  const teamDid = blocklet.appPid;
685
-
686
- const sessionConfig = blocklet.settings?.session || {};
687
- const prevUser = await getUserWithinFederated(
688
- {
689
- teamDid,
690
- sourceAppPid: verifySite.appPid,
691
- userDid: user.did,
692
- userPk: user.pk,
693
- },
694
- {
695
- node,
696
- blocklet,
697
- }
698
- );
699
- if (prevUser?.approved === false) {
700
- res.status(401).json({ error: messages.notAllowedAppUser.en });
701
- return;
702
- }
703
- // HACK: member 调用 master 时,将 passport 的 role 还原为 master 中原有的 role
704
- const targetPassport = passport?.id ? (prevUser?.passports || []).find((item) => item.id === passport.id) : null;
705
-
706
- // HACK: 用户在 master 中存在时,不更新任何用户信息;不存在时,将新增一个用户
707
- const filterUserInfo = prevUser ? {} : user;
708
- if (filterUserInfo.avatar) {
709
- let avatar = await getAvatarByUrl(filterUserInfo.avatar);
710
- const nodeInfo = await req.getNodeInfo();
711
-
712
- const { dataDir } = await getApplicationInfo({ node, nodeInfo, teamDid });
713
- avatar = await extractUserAvatar(avatar, { dataDir });
714
- filterUserInfo.avatar = avatar;
715
- }
716
- const realDid = prevUser?.did || user.did;
717
- const realPk = prevUser?.pk || user.pk;
718
- const newUser = await node.loginUser({
719
- teamDid,
720
- user: {
721
- ...filterUserInfo,
722
- did: realDid,
723
- pk: realPk,
724
- passport: targetPassport,
725
- sourceAppPid: verifySite.appPid,
726
- connectedAccount: {
727
- provider: provider || LOGIN_PROVIDER.WALLET,
728
- did: user.did,
729
- pk: user.pk,
730
- },
731
- },
732
- });
733
-
734
- const { sessionToken, refreshToken } = createToken(
735
- user.did,
736
- {
737
- secret,
738
- passport: targetPassport,
739
- role: targetPassport?.role || 'guest',
740
- fullName: newUser.fullName,
741
- provider: provider || LOGIN_PROVIDER.WALLET,
742
- walletOS,
743
- sourceAppPid: verifySite.appPid,
744
- emailVerified: newUser.emailVerified,
745
- phoneVerified: newUser.phoneVerified,
746
- },
747
- {
748
- ...sessionConfig,
749
- didConnectVersion: getDidConnectVersion(req),
750
- }
751
- );
752
-
753
- await node.createAuditLog(
754
- {
755
- action: 'loginByMaster',
756
- args: { masterSite: verifySite, teamDid },
757
- context: {
758
- user: newUser,
759
- },
760
- result: blocklet,
761
- },
762
- node
763
- );
764
-
765
- res.json({ sessionToken, refreshToken });
766
- });
767
-
768
- // member 向 master 申请 auth0 账号的 migrate
769
- server.post(`${prefix}/migrateAuth0`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
770
- const { blocklet } = req;
771
- const { verifySite } = req.body;
772
- const { did: teamDid, wallet: blockletWallet } = await req.getBlockletInfo();
773
- const { fromUserDid, toUserDid, toUserPk } = req.body.verifyData;
774
- const oauthUser = await node.getUser({ teamDid, user: { did: fromUserDid } });
775
- const connectedAccounts = oauthUser?.connectedAccounts || [];
776
- const sourceProvider = oauthUser?.sourceProvider;
777
- const oauthAccount = connectedAccounts.find((item) => item.provider === sourceProvider);
778
- const userWallet = fromAppDid(oauthAccount.id, blockletWallet.secretKey);
779
-
780
- const bindUser = {
781
- did: toUserDid,
782
- pk: toUserPk,
783
- };
784
- await declareAccount({ wallet: userWallet, blocklet });
785
- await migrateAccount({ wallet: userWallet, blocklet, user: bindUser });
786
- await node.createAuditLog(
787
- {
788
- action: 'migrateFederatedAuth0',
789
- args: { fromUserDid, toUserDid, callerSite: verifySite, teamDid },
790
- context: {
791
- user: getAuditLogActorByFederatedSite(verifySite),
792
- },
793
- },
794
- node
795
- );
796
- res.json({});
797
- });
798
-
799
- // member 去登录 master
800
- // 该监听是由 member 站点来做的,member 向自己的后端来申请要登录 master,member 的后端组装加密数据,由 Master 来接收并执行相应操作
801
- server.post(`${prefix}/loginMaster`, ensureBlocklet(), async (req, res) => {
802
- if (!req.user) {
803
- res.status(401).send('Unauthorized');
804
- return;
805
- }
806
- const { blocklet } = req;
807
- const masterSite = getFederatedMaster(blocklet);
808
- if (!masterSite) {
809
- res.status(400).send('No federated context found');
810
- return;
811
- }
812
-
813
- const { did: teamDid, permanentWallet } = await req.getBlockletInfo();
814
- const user = await node.getUser({ teamDid, user: { did: req.user.did } });
815
- const { passport, walletOS, provider } = req.user;
816
- const url = joinURL(masterSite.appUrl, prefix, 'loginByMember');
817
- const postData = {
818
- signer: permanentWallet.address,
819
- data: signV2(permanentWallet.address, permanentWallet.secretKey, { user, passport, walletOS, provider }),
820
- };
821
-
822
- const { data } = await api.post(url, postData);
823
- await node.createAuditLog(
824
- {
825
- action: 'loginFederatedMaster',
826
- args: { masterSite, teamDid },
827
- context: {
828
- user,
829
- },
830
- result: blocklet,
831
- },
832
- node
833
- );
834
- res.json(data);
835
- });
836
-
837
- server.post(`${prefix}/getPassport`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
838
- const { blocklet } = req;
839
- const teamDid = blocklet.appPid;
840
- const { passportId } = req.body.verifyData;
794
+ const { passportId } = verifyData;
841
795
  const result = await node.getPassportById({ teamDid, passportId });
842
796
  res.json(result);
843
797
  });
844
798
 
845
- // 获取当前站点所有可信的域名
846
- server.get(`${prefix}/getTrustedDomains`, ensureBlocklet(), async (req, res) => {
799
+ server.post(`${prefixApi}/getConfig`, ensureBlocklet(), checkFederatedCall(), async (req, res) => {
847
800
  const { blocklet } = req;
848
- const result = await getTrustedDomains({ node, req, blocklet });
849
- res.json(result);
801
+ const nodeInfo = await node.getNodeInfo();
802
+ const domainAliases = await node.getBlockletDomainAliases({ blocklet, nodeInfo });
803
+
804
+ const siteInfo = await generateSiteInfo({ nodeInfo, blocklet, domainAliases });
805
+ res.json(siteInfo);
850
806
  });
851
807
  },
852
808
  };