@abtnode/blocklet-services 1.16.41-beta-20250325-054737-39c060ca → 1.16.41-beta-20250329-232306-53c45e3b

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 (258) hide show
  1. package/api/emails/_components/actions.js +9 -0
  2. package/api/emails/{components → _components}/article.js +1 -1
  3. package/api/emails/{components → _components}/asset.js +2 -2
  4. package/api/emails/{components → _components}/attachments.js +15 -13
  5. package/api/emails/{components → _components}/compose.js +2 -2
  6. package/api/emails/_components/content.js +15 -0
  7. package/api/emails/{components → _components}/footer.js +1 -1
  8. package/api/emails/{components → _components}/powered-by.js +1 -1
  9. package/api/emails/{components → _components}/token.js +2 -2
  10. package/api/emails/{components → _components}/transaction.js +1 -1
  11. package/api/emails/{pages → _templates}/notification.js +10 -10
  12. package/api/emails/_templates/verify-code-body.js +49 -0
  13. package/api/emails/_templates/verify-code.js +37 -0
  14. package/api/index.js +59 -71
  15. package/api/libs/auth/utils.js +20 -1
  16. package/api/libs/connect/session.js +55 -3
  17. package/api/libs/email.js +48 -16
  18. package/api/middlewares/body-parser.js +10 -0
  19. package/api/routes/blocklet.js +17 -4
  20. package/api/routes/federated.js +36 -13
  21. package/api/routes/mcp.js +87 -0
  22. package/api/routes/user-session.js +16 -1
  23. package/api/routes/user.js +442 -40
  24. package/api/services/auth/connect/issue-passport.js +4 -3
  25. package/api/services/auth/connect/receive-transfer-app-owner.js +17 -1
  26. package/api/services/auth/connect/verify-destroy.js +20 -0
  27. package/api/services/auth/connect/verify-elevated.js +20 -0
  28. package/api/services/auth/index.js +0 -2
  29. package/api/services/auth/session.js +1 -1
  30. package/api/services/kyc/index.js +1 -1
  31. package/api/services/mcp/server.js +37 -0
  32. package/api/services/notification/queue.js +5 -4
  33. package/api/services/studio/index.js +4 -0
  34. package/api/util/federated.js +16 -0
  35. package/dist/assets/{ArrowDropDown-BZ7nr-4O.js → ArrowDropDown-odHjNJIs.js} +1 -1
  36. package/dist/assets/{CheckCircle-V33X02sL.js → CheckCircle-BqOSvJMp.js} +1 -1
  37. package/dist/assets/{ChevronLeft-BhAwkTPM.js → ChevronLeft-Dv7rlUf5.js} +1 -1
  38. package/dist/assets/{ChevronRight-BFn5n61K.js → ChevronRight-CWeJn1iz.js} +1 -1
  39. package/dist/assets/{Community-CJcr3sxm.js → Community-CMFBTMi_.js} +1 -1
  40. package/dist/assets/{DeleteOutline-CI9d5QQr.js → DeleteOutline-Cr-TyrUV.js} +1 -1
  41. package/dist/assets/{Done-CvHaNROm.js → Done-C1TA1wbA.js} +1 -1
  42. package/dist/assets/{Download-CA6PpJRL.js → Download-DxhnUTM_.js} +1 -1
  43. package/dist/assets/{EditIcon-d_J6X2-M.js → EditIcon-Bgmg6UE0.js} +1 -1
  44. package/dist/assets/{Email-Cv_Ltuyk.js → Email-BphlAPta.js} +1 -1
  45. package/dist/assets/{Error-CkH40x6R.js → Error-pXXvJFxN.js} +1 -1
  46. package/dist/assets/{ExpandLess-DPn_CrO1.js → ExpandLess-Dc_dI20M.js} +1 -1
  47. package/dist/assets/{Google-cBME17GZ.js → Google-DNUuYFIA.js} +1 -1
  48. package/dist/assets/{Holiday-DtecZXIQ.js → Holiday-DKefG3Bb.js} +1 -1
  49. package/dist/assets/{InfoOutlined-DNOhP8aN.js → InfoOutlined-CEUhR4DY.js} +1 -1
  50. package/dist/assets/{Launch-DR5uY37Q.js → Launch-BUTOr3cR.js} +1 -1
  51. package/dist/assets/{LaunchOutlined-DzKl31aT.js → LaunchOutlined-QHq-RUJt.js} +1 -1
  52. package/dist/assets/{Location-CdiPklKa.js → Location-BuaxMxu4.js} +1 -1
  53. package/dist/assets/{LockIcon-CzTeIv2K.js → LockIcon-CQ1tExIY.js} +1 -1
  54. package/dist/assets/{Meeting-DQYhfakU.js → Meeting-Cs60QtvP.js} +1 -1
  55. package/dist/assets/{MoreHoriz-DvRtrl2X.js → MoreHoriz-D1SOL47a.js} +1 -1
  56. package/dist/assets/{OffSick-DwG4gWQF.js → OffSick-DinPaelp.js} +1 -1
  57. package/dist/assets/{Phone-CETYuRms.js → Phone-BmouKMyi.js} +1 -1
  58. package/dist/assets/{PlayArrow-B_DkcrSm.js → PlayArrow-D7cGSxeN.js} +1 -1
  59. package/dist/assets/{QuestionMarkCircle-CJiBom-M.js → QuestionMarkCircle-Dt9XJWEe.js} +1 -1
  60. package/dist/assets/{ServerLogo-Ow_B_zvr.js → ServerLogo-B33ZRE5q.js} +1 -1
  61. package/dist/assets/{Timezone-BX4VhFOS.js → Timezone-CyMhRxlx.js} +1 -1
  62. package/dist/assets/{ViewList-CVmPM3e1.js → ViewList-vu1qOJ6P.js} +1 -1
  63. package/dist/assets/{WorkingRemotely-DIBVduhu.js → WorkingRemotely-BP_VIHeM.js} +1 -1
  64. package/dist/assets/access-control-CpxcJItK.js +14 -0
  65. package/dist/assets/{actions-DqC3kJCr.js → actions-4oGfCMlR.js} +1 -1
  66. package/dist/assets/add-component-core-CE0nArG4.js +761 -0
  67. package/dist/assets/add-resource-BYM4JwzE.js +1 -0
  68. package/dist/assets/{addon-BUKk8W1Q.js → addon-B9bb2bvM.js} +1 -1
  69. package/dist/assets/analytics-BXLe73MI.js +11 -0
  70. package/dist/assets/api-D9Yi7Zdr.js +1 -0
  71. package/dist/assets/appearance-DX7SoW1u.js +1 -0
  72. package/dist/assets/ar-2k9jaPIk.js +3 -0
  73. package/dist/assets/{audit-logs-CzmQ7awq.js → audit-logs-D8H5E0fC.js} +3 -3
  74. package/dist/assets/{base32-CwsOMJzz.js → base32-BNpDT-6Q.js} +1 -1
  75. package/dist/assets/{branding-COlKYnkW.js → branding-BW1rhy8d.js} +2 -2
  76. package/dist/assets/bundle-avatar-DHwmIozH.js +1 -0
  77. package/dist/assets/button-CNnuiac8.js +1 -0
  78. package/dist/assets/{click-to-copy-BF_uUMNm.js → click-to-copy-B0HMuCN_.js} +1 -1
  79. package/dist/assets/complete-BNf0-iqY.js +45 -0
  80. package/dist/assets/{component-D_dh8l-k.js → component-1r0VSsqq.js} +2 -2
  81. package/dist/assets/{config-D7fEb50y.js → config-BeD5_8kr.js} +2 -2
  82. package/dist/assets/config-CqHmZdZv.js +1 -0
  83. package/dist/assets/{config-navigation-D8XsruhL.js → config-navigation-DtN0_qFZ.js} +3 -3
  84. package/dist/assets/{config-space-BsNunj5H.js → config-space-DlwZewcm.js} +1 -1
  85. package/dist/assets/{confirm-SUs_DctB.js → confirm-DmMN-34s.js} +2 -2
  86. package/dist/assets/connect-BfSOEYV-.js +1 -0
  87. package/dist/assets/{connect-B1JNOfKg.js → connect-CC9dcVMV.js} +1 -1
  88. package/dist/assets/{connect-to-D_r9o9e2.js → connect-to-CzffwD9G.js} +1 -1
  89. package/dist/assets/{content-layout-BQE-NWxj.js → content-layout-7vu3yv_f.js} +1 -1
  90. package/dist/assets/dashboard-C_Q4TjPa.js +216 -0
  91. package/dist/assets/de-B9cLhykn.js +3 -0
  92. package/dist/assets/{delete-confirm-CIzTutM8.js → delete-confirm-BTaU_6Kx.js} +1 -1
  93. package/dist/assets/did-address-BC-0j4Pt.js +1 -0
  94. package/dist/assets/{domain-Cs9dCGZy.js → domain-CLMRXecU.js} +1 -1
  95. package/dist/assets/{domain-action-card-CmEjTVIf.js → domain-action-card-DwQ7Q8wY.js} +2 -2
  96. package/dist/assets/domains-DF7TtN5q.js +1 -0
  97. package/dist/assets/{email-DcW8pu9K.js → email-mj0bVFDS.js} +2 -2
  98. package/dist/assets/es-BoQohonz.js +3 -0
  99. package/dist/assets/{exchange-passport-SiIAETh-.js → exchange-passport--DeUPzbW.js} +1 -1
  100. package/dist/assets/form-text-input-BYF6lVnE.js +11 -0
  101. package/dist/assets/fr-doSYAOrt.js +3 -0
  102. package/dist/assets/{fuel-BkpixTuh.js → fuel-D-kOZuF6.js} +1 -1
  103. package/dist/assets/{fullpage-BK45P92Z.js → fullpage-DO8Hcbkl.js} +1 -1
  104. package/dist/assets/{get-safe-url-BPBKhLNl.js → get-safe-url-BKl2A9x2.js} +1 -1
  105. package/dist/assets/{get-safe-url-D5pnveC6.js → get-safe-url-QFq5JNoE.js} +1 -1
  106. package/dist/assets/hi-B_BwhpD8.js +1 -0
  107. package/dist/assets/{home-qm_lBtgD.js → home-CpnMpXiw.js} +1 -1
  108. package/dist/assets/id-BgYIZCvk.js +3 -0
  109. package/dist/assets/{iframe-MARzuPzd.js → iframe-B9mCpo4I.js} +1 -1
  110. package/dist/assets/{index-ZhFE0VPc.js → index-79U1RPaq.js} +1 -1
  111. package/dist/assets/{index-RkynV8Hy.js → index-B4Q2DAdn.js} +11 -11
  112. package/dist/assets/index-BJ2lJo7L.js +346 -0
  113. package/dist/assets/{index-De6c2gZ_.js → index-BMSA5TdD.js} +1 -1
  114. package/dist/assets/{index-DkVrxjpZ.js → index-BVOYP6aR.js} +2 -2
  115. package/dist/assets/{index-MSp2Bfol.js → index-BZvVDfZ4.js} +1 -1
  116. package/dist/assets/index-BsUr7wGb.js +104 -0
  117. package/dist/assets/index-C44fECmB.js +138 -0
  118. package/dist/assets/{index-BRMrRxju.js → index-CGK3FEjY.js} +2 -2
  119. package/dist/assets/{index-DQKEK30u.js → index-CJCg9yIK.js} +1 -1
  120. package/dist/assets/index-CmKAznDh.js +109 -0
  121. package/dist/assets/{index-CjVqsxIQ.js → index-Ct7s2LPI.js} +17 -17
  122. package/dist/assets/{index-BwhP13EW.js → index-DQ_RzIwU.js} +2 -2
  123. package/dist/assets/{index-BhEkFtB1.js → index-D_wVtHmh.js} +1 -1
  124. package/dist/assets/{index-BJQAwe5r.js → index-DqC2o5PB.js} +1 -1
  125. package/dist/assets/index-DyTFEgKr.js +1 -0
  126. package/dist/assets/index-eCY24sH9.js +137 -0
  127. package/dist/assets/{index-9twdGxCF.js → index-fWGZM-oP.js} +1 -1
  128. package/dist/assets/index-gTQQ3SoE.js +290 -0
  129. package/dist/assets/index-gcSQTx25.js +1 -0
  130. package/dist/assets/{index-D9S8aCU6.js → index-m8CaSxXx.js} +1 -1
  131. package/dist/assets/{index-CcooKt06.js → index-u-lA6P_E.js} +1 -1
  132. package/dist/assets/invitation-B8Qx_pFq.js +176 -0
  133. package/dist/assets/invite-BBaF_vyc.js +1 -0
  134. package/dist/assets/{issue-passport-UNdxuvTV.js → issue-passport-DC-ly7xg.js} +1 -1
  135. package/dist/assets/{item-vIB3V7Bi.js → item-BSGXym2I.js} +1 -1
  136. package/dist/assets/ja-FMMLI8YD.js +3 -0
  137. package/dist/assets/ko-C0kmRXYE.js +3 -0
  138. package/dist/assets/{launch-result-message-irP4_5v3.js → launch-result-message-ByEG8r_7.js} +1 -1
  139. package/dist/assets/{layout-C6s5HhIK.js → layout-BqhTD729.js} +1 -1
  140. package/dist/assets/list-BHs8uNT5.js +200 -0
  141. package/dist/assets/{list-header-s-ciXcTm.js → list-header-BmTDmRY0.js} +1 -1
  142. package/dist/assets/localization-daPAWMzR.js +1 -0
  143. package/dist/assets/{log-lc82BnEg.js → log-o_Cadt8j.js} +7 -7
  144. package/dist/assets/{login-BMWayJcu.js → login-BQozrLDm.js} +1 -1
  145. package/dist/assets/{login-oauth-callback-CNErXZTB.js → login-oauth-callback-D7lIww1c.js} +1 -1
  146. package/dist/assets/{logo-uploader-CEXNuQSC.js → logo-uploader-CUQ3aWZJ.js} +3 -3
  147. package/dist/assets/{lost-passport-CvNrb0v1.js → lost-passport-DkETH2Lu.js} +3 -3
  148. package/dist/assets/{omit-DVwO9e3E.js → omit-DZNQhOf-.js} +1 -1
  149. package/dist/assets/{open-window-B6eFUa8p.js → open-window-BOl-kTC2.js} +1 -1
  150. package/dist/assets/{overview-mT5IG7r5.js → overview-Bxm05EH6.js} +1 -1
  151. package/dist/assets/{page-header-B4LQuuxg.js → page-header-Dm1v9v5q.js} +1 -1
  152. package/dist/assets/{permission-C4cBxu8K.js → permission-B5jnw9r2.js} +1 -1
  153. package/dist/assets/{preferences-tDE3WRRj.js → preferences-uri2RXdB.js} +1 -1
  154. package/dist/assets/profile-embed-DnIQcD-H.js +1 -0
  155. package/dist/assets/pt-C2UJZK-O.js +1 -0
  156. package/dist/assets/publish-resource-V53U1NNv.js +1 -0
  157. package/dist/assets/{react-beautiful-dnd.esm-BnCmTyEw.js → react-beautiful-dnd.esm-B9MfX9Xl.js} +4 -4
  158. package/dist/assets/{relative-time-W13XZ7qT.js → relative-time-RQnsWZQc.js} +1 -1
  159. package/dist/assets/ru-DDA5s4-r.js +1 -0
  160. package/dist/assets/sdk-BKSsfgrc.js +1 -0
  161. package/dist/assets/{session-D0E4yKh1.js → session-6ZeN-aF2.js} +1 -1
  162. package/dist/assets/{setup-vmtHxx8b.js → setup-7Gq9K_8k.js} +3 -3
  163. package/dist/assets/{shorten-label-CYUVOsQQ.js → shorten-label-DkFTGSoy.js} +1 -1
  164. package/dist/assets/simple-select-CqakAZFe.js +1 -0
  165. package/dist/assets/{slicedToArray-W0RilTJp.js → slicedToArray-BuQur6Mi.js} +2 -2
  166. package/dist/assets/{start-B6iWRYkb.js → start-BSUY3DBl.js} +1 -1
  167. package/dist/assets/{status-CBD3RDbA.js → status-C52-BFuY.js} +1 -1
  168. package/dist/assets/{step-actions-D1bVdqNc.js → step-actions-CA74dwgt.js} +1 -1
  169. package/dist/assets/{studio-CI-t_7sU.js → studio-CAnZfyBM.js} +1 -1
  170. package/dist/assets/{switch-control-BqINsLim.js → switch-control-BBlLGjaH.js} +1 -1
  171. package/dist/assets/th-DmqOUn4C.js +1 -0
  172. package/dist/assets/{traffic-kGqrk2bv.js → traffic-CJDIGmp5.js} +3 -3
  173. package/dist/assets/{transfer-ii7u2wA5.js → transfer-cG2e24sz.js} +1 -1
  174. package/dist/assets/{unsubscribe-DvsPQr2X.js → unsubscribe-afXXIHEf.js} +1 -1
  175. package/dist/assets/{use-mobile-CVbqh2Dx.js → use-mobile-CUT5hy9q.js} +1 -1
  176. package/dist/assets/{useAsync-D2OhgEkV.js → useAsync-DM8qaMe4.js} +1 -1
  177. package/dist/assets/{useAsyncRetry-Dju2R4r6.js → useAsyncRetry-B7SbzXVI.js} +2 -2
  178. package/dist/assets/{useLocalStorage-B4mjl5_Q.js → useLocalStorage-Dd4pybDP.js} +1 -1
  179. package/dist/assets/user-center-T8Xw464s.js +67 -0
  180. package/dist/assets/{util-CVH97CBw.js → util-C_BCTHfw.js} +1 -1
  181. package/dist/assets/{util-BT3jBHtZ.js → util-YyWTpLT7.js} +1 -1
  182. package/dist/assets/vendor-arcblock-DvaaLvvM.js +2361 -0
  183. package/dist/assets/{vendor-hooks-CYyfK9g3.js → vendor-hooks-sw5wvnca.js} +2 -2
  184. package/dist/assets/vendor-mui-core-DxqV1NVn.js +266 -0
  185. package/dist/assets/{vendor-mui-x-BTReKX4-.js → vendor-mui-x-BjL1xCkk.js} +1 -1
  186. package/dist/assets/{vendor-utils-CbeKtci8.js → vendor-utils-DR57WNxP.js} +7 -7
  187. package/dist/assets/{vendor-ux-did-connect-Dg7MsmIi.js → vendor-ux-did-connect-Bciw9Ypu.js} +57 -53
  188. package/dist/assets/vi-Cf__CtPD.js +1 -0
  189. package/dist/assets/wrap-locale-CX50Vz0w.js +1 -0
  190. package/dist/assets/zh-NXspK2yu.js +4 -0
  191. package/dist/assets/zh-tw-DYYDVX5I.js +3 -0
  192. package/dist/index.html +6 -6
  193. package/dist/service-worker.js +2 -2
  194. package/package.json +41 -36
  195. package/api/emails/components/actions.js +0 -9
  196. package/api/emails/components/content.js +0 -15
  197. package/dist/assets/ExternalIssuerIcon-BLzCUF1d.js +0 -1
  198. package/dist/assets/access-control-Dk5vBHfS.js +0 -13
  199. package/dist/assets/add-component-core-DAx5yIIg.js +0 -765
  200. package/dist/assets/add-resource-DkZqrFbC.js +0 -1
  201. package/dist/assets/analytics-BpEvUU_V.js +0 -11
  202. package/dist/assets/api-CvDkueg1.js +0 -1
  203. package/dist/assets/ar-CVfYi9he.js +0 -3
  204. package/dist/assets/bundle-avatar-mGTppfmO.js +0 -1
  205. package/dist/assets/button-Bp47Zc1i.js +0 -1
  206. package/dist/assets/complete-BGei1NKc.js +0 -45
  207. package/dist/assets/config-C4ca73g2.js +0 -1
  208. package/dist/assets/connect-CHnKwaTE.js +0 -1
  209. package/dist/assets/dashboard-CcevSjZB.js +0 -218
  210. package/dist/assets/de-B4s5NdlK.js +0 -3
  211. package/dist/assets/did-address-DnGQ03FF.js +0 -1
  212. package/dist/assets/domains-ByJLKnQ7.js +0 -1
  213. package/dist/assets/es-C48Qrhnr.js +0 -3
  214. package/dist/assets/form-text-input-B4Ezw4UV.js +0 -11
  215. package/dist/assets/fr-C_zb-sN3.js +0 -3
  216. package/dist/assets/hi-Bd1v0vAT.js +0 -1
  217. package/dist/assets/id-CAHN8LyN.js +0 -3
  218. package/dist/assets/index-2hZd332d.js +0 -138
  219. package/dist/assets/index-BMxUr1Yy.js +0 -346
  220. package/dist/assets/index-BSEtdOzl.js +0 -134
  221. package/dist/assets/index-BvH3rra0.js +0 -1
  222. package/dist/assets/index-C482NgPS.js +0 -104
  223. package/dist/assets/index-CZIXrPaX.js +0 -109
  224. package/dist/assets/index-CqnBzijY.js +0 -137
  225. package/dist/assets/index-mdmh1Xx6.js +0 -1
  226. package/dist/assets/invitation-ehDH3V7F.js +0 -176
  227. package/dist/assets/invite-BVZfCzI6.js +0 -1
  228. package/dist/assets/ja-DTJzPeZ-.js +0 -3
  229. package/dist/assets/ko--y3FSpCf.js +0 -3
  230. package/dist/assets/list-DS45KBMo.js +0 -195
  231. package/dist/assets/localization-BAzVJOkA.js +0 -1
  232. package/dist/assets/login-bg-CBktcoss.jpg +0 -0
  233. package/dist/assets/profile-embed-CNrAUity.js +0 -1
  234. package/dist/assets/pt-vs00P-F0.js +0 -1
  235. package/dist/assets/publish-resource-ApDQigSb.js +0 -1
  236. package/dist/assets/ru-CMsriCRQ.js +0 -1
  237. package/dist/assets/sdk-CdntdIAz.js +0 -1
  238. package/dist/assets/simple-select-CI23fC_x.js +0 -1
  239. package/dist/assets/th-_91ROtZM.js +0 -1
  240. package/dist/assets/user-center-Bi7zYk4z.js +0 -79
  241. package/dist/assets/vendor-arcblock-CCyyB91P.js +0 -2361
  242. package/dist/assets/vendor-mui-core-DSM7ZGuY.js +0 -266
  243. package/dist/assets/vi-BAo1CsMy.js +0 -1
  244. package/dist/assets/wrap-locale-BMEB19si.js +0 -1
  245. package/dist/assets/zh-8LRwh-dv.js +0 -4
  246. package/dist/assets/zh-tw-C8jGxySi.js +0 -3
  247. /package/api/emails/{components → _components}/copyright.js +0 -0
  248. /package/api/emails/{components → _components}/dapp.js +0 -0
  249. /package/api/emails/{components → _components}/header.js +0 -0
  250. /package/api/emails/{components → _components}/layout.js +0 -0
  251. /package/api/emails/{libs → _libs}/chain.js +0 -0
  252. /package/api/emails/{libs → _libs}/config.js +0 -0
  253. /package/api/emails/{libs → _libs}/constant.js +0 -0
  254. /package/api/emails/{libs → _libs}/explorer-url.js +0 -0
  255. /package/api/emails/{libs → _libs}/func.js +0 -0
  256. /package/api/emails/{libs → _libs}/highlight.js +0 -0
  257. /package/api/emails/{libs → _libs}/style.js +0 -0
  258. /package/api/emails/{libs → _libs}/util.js +0 -0
@@ -46,6 +46,7 @@ const {
46
46
  const { getSourceAppPid, getLoginProvider } = require('@blocklet/sdk/lib/util/login');
47
47
  const { getDidSpacesInfoByClaims, silentAuthorizationInConnect } = require('@abtnode/auth/lib/util/spaces');
48
48
  const getRequestIP = require('@abtnode/util/lib/get-request-ip');
49
+ const { PASSPORT_LOG_ACTION, PASSPORT_SOURCE, PASSPORT_STATUS } = require('@abtnode/constant');
49
50
 
50
51
  const logger = require('../logger')('connect');
51
52
  const { createTokenFn, getDidConnectVersion } = require('../../util');
@@ -75,6 +76,20 @@ const validateLocalPassport = async ({ vc, node, locale, blocklet, teamDid, user
75
76
  if (vc.credentialSubject.id !== userDid) {
76
77
  throw new CustomError(403, messages.actionForbidden[locale]);
77
78
  }
79
+
80
+ const passport = await node.getPassportById({ teamDid, passportId: vc.id });
81
+ if (!passport) {
82
+ throw new CustomError(403, messages.passportNotFound[locale]);
83
+ }
84
+
85
+ if (passport.status === PASSPORT_STATUS.REVOKED) {
86
+ throw new CustomError(403, messages.passportRevoked[locale](passport.title));
87
+ }
88
+
89
+ if (passport.status === PASSPORT_STATUS.EXPIRED) {
90
+ throw new CustomError(403, messages.passportExpired[locale]);
91
+ }
92
+
78
93
  if (!(await node.isPassportValid({ teamDid, passportId: vc.id }))) {
79
94
  throw new CustomError(403, messages.passportNotFound[locale]);
80
95
  }
@@ -204,7 +219,8 @@ module.exports = {
204
219
  */
205
220
  const blocklet = await request.getBlocklet();
206
221
  const { accessPolicyConfig } = await request.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
207
- const { did: teamDid, wallet: blockletWallet } = await request.getBlockletInfo();
222
+ const blockletInfo = await request.getBlockletInfo();
223
+ const { did: teamDid, wallet: blockletWallet } = blockletInfo;
208
224
  const sourceAppPid = getSourceAppPid(request);
209
225
 
210
226
  const profileItems = getProfileItems(blocklet.settings?.session, request.context.didwallet);
@@ -481,7 +497,13 @@ module.exports = {
481
497
  }
482
498
 
483
499
  // Recreate passport with correct role
484
- passport = vc ? createUserPassport(vc, { role }) : null;
500
+ passport = vc ? createUserPassport(vc, { role, source: PASSPORT_SOURCE.ISSUE }) : null;
501
+ if (passport?.id) {
502
+ const isTrustedPassport = (blocklet.trustedPassports || []).some((x) => x.issuerDid === passport?.issuer?.id);
503
+ if (isTrustedPassport) {
504
+ passport.source = PASSPORT_SOURCE.TRUSTED;
505
+ }
506
+ }
485
507
 
486
508
  const now = new Date().toISOString();
487
509
  const connectedNft = nftState
@@ -636,6 +658,21 @@ module.exports = {
636
658
  });
637
659
  }
638
660
 
661
+ if (passport) {
662
+ await node.createPassportLog(
663
+ teamDid,
664
+ {
665
+ passportId: passport.id,
666
+ action: PASSPORT_LOG_ACTION.USED,
667
+ operatorDid: userDid,
668
+ metadata: {
669
+ action,
670
+ },
671
+ },
672
+ request
673
+ );
674
+ }
675
+
639
676
  // Generate new session token that client can save to localStorage
640
677
  const createToken = createTokenFn(createSessionToken);
641
678
  const sessionConfig = blocklet.settings?.session || {};
@@ -989,7 +1026,7 @@ module.exports = {
989
1026
  await checkAppOwner({ node, role, blocklet, userDid, locale });
990
1027
 
991
1028
  // Recreate passport with correct role
992
- passport = vc ? createUserPassport(vc, { role }) : null;
1029
+ passport = vc ? createUserPassport(vc, { role, source: PASSPORT_SOURCE.ISSUE }) : null;
993
1030
 
994
1031
  await node.updateUser({
995
1032
  teamDid,
@@ -1015,6 +1052,21 @@ module.exports = {
1015
1052
  node
1016
1053
  );
1017
1054
 
1055
+ if (passport) {
1056
+ await node.createPassportLog(
1057
+ teamDid,
1058
+ {
1059
+ passportId: passport.id,
1060
+ action: PASSPORT_LOG_ACTION.USED,
1061
+ operatorDid: '',
1062
+ metadata: {
1063
+ action: 'switch-passport-approve',
1064
+ },
1065
+ },
1066
+ request
1067
+ );
1068
+ }
1069
+
1018
1070
  // Generate new session token that client can save to localStorage
1019
1071
  const createToken = createTokenFn(createSessionToken);
1020
1072
  const sessionConfig = blocklet.settings?.session || {};
package/api/libs/email.js CHANGED
@@ -5,7 +5,8 @@ const { getEmailServiceProvider } = require('@abtnode/auth/lib/email');
5
5
  const { sendEmailWithLauncher } = require('@abtnode/auth/lib/launcher');
6
6
 
7
7
  const logger = require('./logger')('blocklet-services:notification');
8
- const { NotificationEmail } = require('../emails/pages/notification');
8
+ const { NotificationEmail } = require('../emails/_templates/notification');
9
+ const { VerifyCodeEmail } = require('../emails/_templates/verify-code');
9
10
  const cache = require('../cache');
10
11
 
11
12
  const schemaEmail = Joi.string().email().required();
@@ -15,7 +16,16 @@ const validateEmail = schemaEmail.validateAsync.bind(schemaEmail);
15
16
  async function sendEmail(
16
17
  receiver,
17
18
  notification,
18
- { teamDid, node, locale, unsubscribeToken = '', userInfo = {}, raw = false, launcher = false }
19
+ {
20
+ teamDid,
21
+ node,
22
+ locale,
23
+ unsubscribeToken = '',
24
+ userInfo = {},
25
+ raw = false,
26
+ launcher = false,
27
+ template = 'notification',
28
+ }
19
29
  ) {
20
30
  if (!receiver) {
21
31
  throw new Error('receiver is required');
@@ -56,20 +66,42 @@ async function sendEmail(
56
66
  'You have received a notification'
57
67
  }`;
58
68
 
59
- const html = render(
60
- NotificationEmail({
61
- subject,
62
- appInfo,
63
- ...notification,
64
- locale,
65
- raw,
66
- unsubscribeToken,
67
- userInfo: {
68
- ...userInfo,
69
- email: receiver,
70
- },
71
- })
72
- );
69
+ let html = '';
70
+ try {
71
+ if (template === 'notification') {
72
+ html = await render(
73
+ NotificationEmail({
74
+ subject,
75
+ appInfo,
76
+ ...notification,
77
+ locale,
78
+ raw,
79
+ unsubscribeToken,
80
+ userInfo: {
81
+ ...userInfo,
82
+ email: receiver,
83
+ },
84
+ })
85
+ );
86
+ } else if (template === 'verify-code') {
87
+ html = await render(
88
+ VerifyCodeEmail({
89
+ subject,
90
+ appInfo,
91
+ ...notification,
92
+ locale,
93
+ raw,
94
+ userInfo: {
95
+ ...userInfo,
96
+ email: receiver,
97
+ },
98
+ })
99
+ );
100
+ }
101
+ } catch (err) {
102
+ logger.error('Failed to render email template:', err);
103
+ throw new Error(`Failed to render ${template} template: ${err.message}`);
104
+ }
73
105
 
74
106
  const emailData = {
75
107
  from: `"${appInfo.title}" <${config.from}>`,
@@ -0,0 +1,10 @@
1
+ const bodyParser = require('body-parser');
2
+ const { MAX_UPLOAD_FILE_SIZE } = require('@abtnode/constant');
3
+
4
+ // body parser only for blocklet service related request
5
+ const maxUploadSize = Number(process.env.MAX_UPLOAD_FILE_SIZE) || MAX_UPLOAD_FILE_SIZE;
6
+
7
+ module.exports = [
8
+ bodyParser.json({ limit: `${maxUploadSize}mb` }),
9
+ bodyParser.urlencoded({ extended: true, limit: `${maxUploadSize}mb` }),
10
+ ];
@@ -10,7 +10,6 @@ const { joinURL } = require('ufo');
10
10
  const cors = require('cors');
11
11
  const { getPassportStatusEndpoint } = require('@abtnode/auth/lib/auth');
12
12
  const { createPassportVC, createPassport, createUserPassport } = require('@abtnode/auth/lib/passport');
13
-
14
13
  const formatContext = require('@abtnode/util/lib/format-context');
15
14
  const { getStatusFromError } = require('@abtnode/util/lib/custom-error');
16
15
  const { getUserAvatarUrl, getAvatarFile, getAppAvatarUrl, extractUserAvatar } = require('@abtnode/util/lib/user');
@@ -41,6 +40,7 @@ const {
41
40
  USER_AVATAR_URL_PREFIX,
42
41
  WELLKNOWN_BLOCKLET_HEALTH_PATH,
43
42
  } = require('@abtnode/constant');
43
+ const { PASSPORT_SOURCE, PASSPORT_LOG_ACTION, PASSPORT_ISSUE_ACTION } = require('@abtnode/constant');
44
44
 
45
45
  const { createDownloadLogStream } = require('@abtnode/core/lib/util/log');
46
46
 
@@ -189,7 +189,7 @@ module.exports = {
189
189
  // 不能使用 useCache 可能会拿不到最新的 blocklet 信息
190
190
  const blocklet = await req.getBlocklet({ useCache: false });
191
191
 
192
- const { fromSetup } = req.body;
192
+ const { fromSetup } = req.query;
193
193
  const { did: userDid } = req.user;
194
194
 
195
195
  // eslint-disable-next-line no-unreachable
@@ -223,7 +223,7 @@ module.exports = {
223
223
  }
224
224
  }
225
225
 
226
- if (fromSetup) {
226
+ if (fromSetup === '1') {
227
227
  const teamDid = blocklet.meta.did;
228
228
  const { wallet, name, passportColor } = await req.getBlockletInfo();
229
229
  // NOTICE: 这里的 did 是从 session 中取到的永久 did,不需要查询 connectedAccount
@@ -267,7 +267,8 @@ module.exports = {
267
267
  });
268
268
 
269
269
  // write passport to db
270
- const passport = createUserPassport(vc, { role });
270
+ const passport = createUserPassport(vc, { role, source: PASSPORT_SOURCE.ISSUE });
271
+
271
272
  const result = await node.updateUser({
272
273
  teamDid,
273
274
  user: {
@@ -285,6 +286,18 @@ module.exports = {
285
286
  node
286
287
  );
287
288
 
289
+ if (passport) {
290
+ await node.createPassportLog(teamDid, {
291
+ passportId: passport.id,
292
+ action: PASSPORT_LOG_ACTION.ISSUE,
293
+ operatorDid: userDid,
294
+ metadata: {
295
+ action: PASSPORT_ISSUE_ACTION.ISSUE_ON_BLOCKLET_START,
296
+ context: formatContext(req),
297
+ },
298
+ });
299
+ }
300
+
288
301
  // send owner vc
289
302
  const notificationText = {
290
303
  title: {
@@ -41,19 +41,21 @@ function getAuditLogActorByFederatedSite(blocklet) {
41
41
  };
42
42
  }
43
43
 
44
- async function syncSwitchProfile(user, { node, teamDid, dataDir }) {
45
- const tempUser = pick(user, [
46
- 'did',
47
- 'pk',
48
- 'avatar',
49
- 'fullName',
50
- 'email',
51
- 'phone',
52
- 'url',
53
- 'inviter',
54
- 'emailVerified',
55
- 'phoneVerified',
56
- ]);
44
+ const SYNC_FIELDS = [
45
+ 'did',
46
+ 'pk',
47
+ 'avatar',
48
+ 'fullName',
49
+ 'email',
50
+ 'phone',
51
+ 'url',
52
+ 'inviter',
53
+ 'emailVerified',
54
+ 'phoneVerified',
55
+ ];
56
+
57
+ async function syncSwitchProfile(user, { node, teamDid, dataDir, fields = SYNC_FIELDS }) {
58
+ const tempUser = pick(user, fields);
57
59
 
58
60
  // 处理 avatar
59
61
  if (tempUser.avatar) {
@@ -142,6 +144,10 @@ async function syncDisconnectAccount(user, { node, teamDid, blocklet }) {
142
144
  });
143
145
  }
144
146
 
147
+ function syncUserProfile(user, { node, teamDid, dataDir }) {
148
+ return syncSwitchProfile(user, { node, teamDid, dataDir, fields: [...SYNC_FIELDS, 'metadata', 'address'] });
149
+ }
150
+
145
151
  /**
146
152
  * member 站点向 master 站点请求拉取一个用户信息
147
153
  */
@@ -153,6 +159,8 @@ const syncUserFnMaps = {
153
159
  connectAccount: syncConnectAccount,
154
160
  // 用户解绑第三方登录
155
161
  disconnectAccount: syncDisconnectAccount,
162
+ // 用户同步 profile
163
+ syncProfile: syncUserProfile,
156
164
  };
157
165
 
158
166
  module.exports = {
@@ -804,5 +812,20 @@ module.exports = {
804
812
  const siteInfo = await generateSiteInfo({ nodeInfo, blocklet, domainAliases });
805
813
  res.json(siteInfo);
806
814
  });
815
+
816
+ // 用于 member 向 master 获取指定 sub 用户的共公开钱包信息
817
+ server.post(`${prefixApi}/getUser`, ensureBlocklet(), checkFederatedCall(), async (req, res) => {
818
+ const { verifyData } = req;
819
+ const { userSub } = verifyData;
820
+ if (!userSub) {
821
+ res.status(400).json({ error: 'missing userSub' });
822
+ return;
823
+ }
824
+ const { wallet: blockletWallet } = await req.getBlockletInfo();
825
+ const userWallet = fromAppDid(userSub, blockletWallet.secretKey);
826
+ res.json({
827
+ wallet: pick(userWallet, ['type', 'publicKey', 'address']),
828
+ });
829
+ });
807
830
  },
808
831
  };
@@ -0,0 +1,87 @@
1
+ /* eslint-disable no-console */
2
+ const { WELLKNOWN_SERVICE_PATH_PREFIX, SECURITY_RULE_DEFAULT_ID } = require('@abtnode/constant');
3
+ const { joinURL } = require('ufo');
4
+ const get = require('lodash/get');
5
+ const getBlockletInfo = require('@blocklet/meta/lib/info');
6
+ const { checkPublicAccess } = require('@blocklet/meta/lib/util');
7
+ // eslint-disable-next-line import/no-unresolved
8
+ const { SSEServerTransport } = require('@modelcontextprotocol/sdk/server/sse.js');
9
+
10
+ const { mcpServer } = require('../services/mcp/server');
11
+
12
+ const isMCPSupported = (b) => get(b.meta, 'capabilities.mcp', false);
13
+
14
+ module.exports = {
15
+ init(server, node) {
16
+ // Return all MCP servers
17
+ server.get(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/mcp/servers'), async (req, res) => {
18
+ const blocklet = await req.getBlocklet();
19
+ const { securityRules } = await node.getBlockletSecurityRules({ did: blocklet.appDid });
20
+ let securityConfig = securityRules.find((x) => x.id === SECURITY_RULE_DEFAULT_ID);
21
+
22
+ const mcpServers = [];
23
+
24
+ // Blocklet Service MCP Server
25
+ const info = getBlockletInfo(blocklet);
26
+ const baseUrl = joinURL(info.appUrl, WELLKNOWN_SERVICE_PATH_PREFIX, '/blocklet');
27
+ mcpServers.push({
28
+ did: blocklet.appDid,
29
+ name: info.name,
30
+ description: info.description,
31
+ endpoint: joinURL(info.appUrl, WELLKNOWN_SERVICE_PATH_PREFIX, '/mcp/sse'),
32
+ protected: !checkPublicAccess(securityConfig),
33
+ version: info.version,
34
+ logo: joinURL(baseUrl, '/logo'),
35
+ });
36
+
37
+ // Components MCP Server
38
+ blocklet.children.forEach((x) => {
39
+ securityConfig = securityRules.find((r) => r.componentDid === x.meta.did && r.pathPattern === '*');
40
+ if (isMCPSupported(x)) {
41
+ mcpServers.push({
42
+ did: `${blocklet.appDid}/${x.meta.did}`,
43
+ name: x.meta.title,
44
+ description: x.meta.description,
45
+ endpoint: joinURL(info.appUrl, x.mountPoint, '/mcp/sse'),
46
+ protected: !checkPublicAccess(securityConfig),
47
+ version: x.meta.version,
48
+ logo: joinURL(baseUrl, `/logo-bundle/${x.meta.did}?v=${info.version}`),
49
+ });
50
+ }
51
+ });
52
+
53
+ // TODO: should we include official services? such as chain, did-spaces, name-service, etc.
54
+ res.json({
55
+ version: info.version,
56
+ servers: mcpServers,
57
+ });
58
+ });
59
+
60
+ // Serve Service MCP server
61
+
62
+ // to support multiple simultaneous connections we have a lookup object from sessionId to transport
63
+ const transports = {};
64
+ server.get(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/mcp/sse'), async (_, res) => {
65
+ // Set required headers for SSE
66
+ res.header('X-Accel-Buffering', 'no');
67
+
68
+ const transport = new SSEServerTransport(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/mcp/messages'), res);
69
+ transports[transport.sessionId] = transport;
70
+ res.on('close', () => {
71
+ delete transports[transport.sessionId];
72
+ });
73
+ await mcpServer.connect(transport);
74
+ });
75
+
76
+ server.post(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/mcp/messages'), async (req, res) => {
77
+ const { sessionId } = req.query;
78
+ const transport = transports[sessionId];
79
+ if (transport) {
80
+ // Send the body to the transport since we have already parsed it
81
+ await transport.handlePostMessage(req, res, req.body);
82
+ } else {
83
+ res.status(400).send('No transport found for sessionId');
84
+ }
85
+ });
86
+ },
87
+ };
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-await-in-loop */
2
- const { WELLKNOWN_SERVICE_PATH_PREFIX, SESSION_TTL } = require('@abtnode/constant');
2
+ const { WELLKNOWN_SERVICE_PATH_PREFIX, SESSION_TTL, PASSPORT_LOG_ACTION } = require('@abtnode/constant');
3
3
  const { LOGIN_PROVIDER } = require('@blocklet/constant');
4
4
  const pick = require('lodash/pick');
5
5
  const defaults = require('lodash/defaults');
@@ -223,6 +223,21 @@ module.exports = {
223
223
  },
224
224
  });
225
225
 
226
+ if (targetPassport) {
227
+ await node.createPassportLog(
228
+ teamDid,
229
+ {
230
+ passportId: targetPassport.id,
231
+ action: PASSPORT_LOG_ACTION.LOGIN,
232
+ operatorDid: loggedInUser.did,
233
+ metadata: {
234
+ action: 'login',
235
+ },
236
+ },
237
+ req
238
+ );
239
+ }
240
+
226
241
  result = createToken(
227
242
  user.did,
228
243
  {