@abtnode/blocklet-services 1.16.41 → 1.16.42-beta-20250403-230303-c167c6a1

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 (332) hide show
  1. package/api/emails/_templates/verify-code-body.js +4 -4
  2. package/api/index.js +4 -1
  3. package/api/libs/connect/session.js +4 -6
  4. package/api/libs/jwt.js +3 -3
  5. package/api/libs/push-kit/index.js +5 -2
  6. package/api/routes/blocklet.js +1 -1
  7. package/api/routes/federated.js +12 -2
  8. package/api/routes/oauth.js +56 -270
  9. package/api/routes/user-session.js +40 -19
  10. package/api/routes/user.js +254 -266
  11. package/api/services/auth/connect/invite.js +4 -6
  12. package/api/services/auth/connect/issue-passport.js +4 -6
  13. package/api/services/auth/session.js +5 -6
  14. package/api/services/notification/index.js +20 -16
  15. package/api/services/notification/queue.js +9 -1
  16. package/api/socket/channel/did.js +8 -8
  17. package/api/socket/util.js +1 -4
  18. package/api/state/message.js +59 -0
  19. package/api/util/attach-shared-utils.js +1 -0
  20. package/api/util/federated.js +1 -1
  21. package/api/util/user-util.js +296 -0
  22. package/dist/assets/{ArrowDropDown-odHjNJIs.js → ArrowDropDown-ptWD82T6.js} +1 -1
  23. package/dist/assets/{CheckCircle-BqOSvJMp.js → CheckCircle-Btm_ouu-.js} +1 -1
  24. package/dist/assets/{ChevronLeft-Dv7rlUf5.js → ChevronLeft-Dlcukg5b.js} +1 -1
  25. package/dist/assets/{ChevronRight-CWeJn1iz.js → ChevronRight-Dum8C8k7.js} +1 -1
  26. package/dist/assets/{Community-CMFBTMi_.js → Community-BuDGbplJ.js} +1 -1
  27. package/dist/assets/{DeleteOutline-Cr-TyrUV.js → DeleteOutline-qIhkqz9A.js} +1 -1
  28. package/dist/assets/{Done-C1TA1wbA.js → Done-CxsGHhW2.js} +1 -1
  29. package/dist/assets/{Download-DxhnUTM_.js → Download-DtSKdPMo.js} +1 -1
  30. package/dist/assets/{EditIcon-Bgmg6UE0.js → EditIcon-BOKrjkh4.js} +1 -1
  31. package/dist/assets/{Email-BphlAPta.js → Email-D1oAzxhZ.js} +1 -1
  32. package/dist/assets/{Error-pXXvJFxN.js → Error-yZoplO-q.js} +1 -1
  33. package/dist/assets/{ExpandLess-Dc_dI20M.js → ExpandLess-DN5VsSyP.js} +1 -1
  34. package/dist/assets/{Google-DNUuYFIA.js → Google-Drf-_CBl.js} +1 -1
  35. package/dist/assets/{Holiday-DKefG3Bb.js → Holiday-CGw5hZXz.js} +1 -1
  36. package/dist/assets/{InfoOutlined-CEUhR4DY.js → InfoOutlined-CLOzYFOV.js} +1 -1
  37. package/dist/assets/{Launch-BUTOr3cR.js → Launch-BtdPv0ms.js} +1 -1
  38. package/dist/assets/{LaunchOutlined-QHq-RUJt.js → LaunchOutlined-Bxfn3D1k.js} +1 -1
  39. package/dist/assets/{Location-BuaxMxu4.js → Location-BNMzVuhr.js} +1 -1
  40. package/dist/assets/{LockIcon-CQ1tExIY.js → LockIcon-D-N7I3eV.js} +1 -1
  41. package/dist/assets/{Meeting-Cs60QtvP.js → Meeting-CHDEMp94.js} +1 -1
  42. package/dist/assets/{MoreHoriz-D1SOL47a.js → MoreHoriz-Ecf_Y2c5.js} +1 -1
  43. package/dist/assets/{OffSick-DinPaelp.js → OffSick-s49E5S0C.js} +1 -1
  44. package/dist/assets/{Phone-BmouKMyi.js → Phone-B7KVJqdR.js} +1 -1
  45. package/dist/assets/{PlayArrow-D7cGSxeN.js → PlayArrow-C5Hul3eK.js} +1 -1
  46. package/dist/assets/{QuestionMarkCircle-Dt9XJWEe.js → QuestionMarkCircle-D9Nr1DvN.js} +1 -1
  47. package/dist/assets/{ServerLogo-B33ZRE5q.js → ServerLogo-CJ7KvDlS.js} +1 -1
  48. package/dist/assets/{Timezone-CyMhRxlx.js → Timezone-fKWN5g03.js} +1 -1
  49. package/dist/assets/TuneOutlined-CIVU5KTm.js +1 -0
  50. package/dist/assets/{ViewList-vu1qOJ6P.js → ViewList-DQNBBLS5.js} +1 -1
  51. package/dist/assets/{WorkingRemotely-BP_VIHeM.js → WorkingRemotely-8AJSfiNI.js} +1 -1
  52. package/dist/assets/access-control-5GyLuYd7.js +14 -0
  53. package/dist/assets/{actions-4oGfCMlR.js → actions-BK1Ssw2h.js} +1 -1
  54. package/dist/assets/{add-component-core-CE0nArG4.js → add-component-core-Bm9enQVM.js} +31 -31
  55. package/dist/assets/{add-resource-BYM4JwzE.js → add-resource-Cqmj5BBD.js} +1 -1
  56. package/dist/assets/{addon-B9bb2bvM.js → addon-Dfs1zul7.js} +1 -1
  57. package/dist/assets/advanced-MSBu-f81.js +49 -0
  58. package/dist/assets/api-DeTTY4rz.js +1 -0
  59. package/dist/assets/appearance-_saX27MM.js +1 -0
  60. package/dist/assets/ar-Bd3GUoqC.js +3 -0
  61. package/dist/assets/{ar-CVzKLI4f.js → ar-DrRqcx2b.js} +1 -1
  62. package/dist/assets/{audit-logs-D8H5E0fC.js → audit-logs-C8OHcyQY.js} +3 -3
  63. package/dist/assets/base32-DY8fPTYx.js +1 -0
  64. package/dist/assets/branding-CanOP0qb.js +40 -0
  65. package/dist/assets/branding-DelDZvig.js +50 -0
  66. package/dist/assets/{bundle-avatar-DHwmIozH.js → bundle-avatar-CxGKqpL1.js} +1 -1
  67. package/dist/assets/button-GsH-bz74.js +1 -0
  68. package/dist/assets/{click-to-copy-B0HMuCN_.js → click-to-copy-BuZpdwN0.js} +1 -1
  69. package/dist/assets/{complete-BNf0-iqY.js → complete-CIxsaCVT.js} +1 -1
  70. package/dist/assets/{component-1r0VSsqq.js → component-vibwLNji.js} +102 -87
  71. package/dist/assets/{config-BeD5_8kr.js → config-BbT0ik5t.js} +1 -1
  72. package/dist/assets/{config-CqHmZdZv.js → config-Bl-eQAj5.js} +1 -1
  73. package/dist/assets/{config-navigation-DtN0_qFZ.js → config-navigation-Dw7tct52.js} +7 -7
  74. package/dist/assets/{config-space-DlwZewcm.js → config-space-D3pvjnQx.js} +1 -1
  75. package/dist/assets/{confirm-DmMN-34s.js → confirm-BzL9LNyf.js} +1 -1
  76. package/dist/assets/{connect-CC9dcVMV.js → connect-CzcOswsI.js} +1 -1
  77. package/dist/assets/connect-Czr8O47H.js +1 -0
  78. package/dist/assets/{connect-to-CzffwD9G.js → connect-to-LVtY3yeI.js} +1 -1
  79. package/dist/assets/{content-layout-7vu3yv_f.js → content-layout-CcLv-R_J.js} +1 -1
  80. package/dist/assets/dashboard-BuFzcMGR.js +213 -0
  81. package/dist/assets/de-4RuZHBym.js +3 -0
  82. package/dist/assets/{de-DIJPqt1Y.js → de-BRPos3d1.js} +1 -1
  83. package/dist/assets/{delete-confirm-BTaU_6Kx.js → delete-confirm-Bg3_0xz8.js} +1 -1
  84. package/dist/assets/{did-address-BC-0j4Pt.js → did-address-Dn6n8fAo.js} +1 -1
  85. package/dist/assets/doc-board-bg-DWZHV9Ng.png +0 -0
  86. package/dist/assets/domain-C_0cRyXj.js +9 -0
  87. package/dist/assets/{domain-action-card-DwQ7Q8wY.js → domain-action-card-B6WSK3W9.js} +2 -2
  88. package/dist/assets/domains-BQtz7ONz.js +1 -0
  89. package/dist/assets/{email-mj0bVFDS.js → email-qq2sglAS.js} +2 -2
  90. package/dist/assets/{es-C5RqG0zA.js → es-D2rCdMgt.js} +1 -1
  91. package/dist/assets/es-DPG1emNh.js +3 -0
  92. package/dist/assets/exchange-passport-CfAHAVKI.js +1 -0
  93. package/dist/assets/{fr-BHsPT43-.js → fr-DAFx50ef.js} +1 -1
  94. package/dist/assets/fr-u7MDLCDo.js +3 -0
  95. package/dist/assets/fuel-DVzKzmYw.js +32 -0
  96. package/dist/assets/{get-safe-url-BKl2A9x2.js → get-safe-url-CA3J0_99.js} +1 -1
  97. package/dist/assets/{get-safe-url-QFq5JNoE.js → get-safe-url-DnmtzIqo.js} +1 -1
  98. package/dist/assets/{hi-Bie09Alk.js → hi-CkD7b6N9.js} +1 -1
  99. package/dist/assets/hi-DS9ZR9W2.js +1 -0
  100. package/dist/assets/home--ykFBnb1.js +1 -0
  101. package/dist/assets/{id-IlcS05qm.js → id-BMWKdVei.js} +1 -1
  102. package/dist/assets/id-C459Zhwd.js +3 -0
  103. package/dist/assets/{iframe-B9mCpo4I.js → iframe-B5D34SYo.js} +1 -1
  104. package/dist/assets/{index-Ct7s2LPI.js → index-B1UWfhev.js} +3 -3
  105. package/dist/assets/{index-CJCg9yIK.js → index-B8T_6tqA.js} +1 -1
  106. package/dist/assets/{index-D_wVtHmh.js → index-BByO9801.js} +1 -1
  107. package/dist/assets/{index-DQ_RzIwU.js → index-BDliasS9.js} +1 -1
  108. package/dist/assets/index-BPS0iHSZ.js +4 -0
  109. package/dist/assets/index-BQLZ0lsX.js +1 -0
  110. package/dist/assets/index-BWpwjp4L.js +104 -0
  111. package/dist/assets/index-BqIq9Uma.js +138 -0
  112. package/dist/assets/{index-B4Q2DAdn.js → index-C6eHDaxg.js} +11 -11
  113. package/dist/assets/{index-BMSA5TdD.js → index-CBhHQMgh.js} +1 -1
  114. package/dist/assets/index-CClhZ8rs.js +1 -0
  115. package/dist/assets/index-CytYWl7a.js +113 -0
  116. package/dist/assets/index-D8CNdALX.js +2 -0
  117. package/dist/assets/index-DOdTZRA4.js +11 -0
  118. package/dist/assets/{index-79U1RPaq.js → index-Da6LyIoG.js} +2 -2
  119. package/dist/assets/{index-BJ2lJo7L.js → index-Dy3LPNyS.js} +42 -42
  120. package/dist/assets/index-ItdGu4Wh.js +2 -0
  121. package/dist/assets/{index-m8CaSxXx.js → index-J5kmwEca.js} +1 -1
  122. package/dist/assets/{index-fWGZM-oP.js → index-L3MBVAcg.js} +1 -1
  123. package/dist/assets/{index-BZvVDfZ4.js → index-VUi6PKrJ.js} +1 -1
  124. package/dist/assets/{index-u-lA6P_E.js → index-dCzPMsw6.js} +1 -1
  125. package/dist/assets/index-ndYC_y0r.js +15 -0
  126. package/dist/assets/{index-CGK3FEjY.js → index-vxB3STPb.js} +1 -1
  127. package/dist/assets/index-y6Dw39ly.js +290 -0
  128. package/dist/assets/{invitation-B8Qx_pFq.js → invitation-Cp6DuOW5.js} +8 -7
  129. package/dist/assets/invite-DjADjbzm.js +1 -0
  130. package/dist/assets/issue-passport-Bu5NvC_2.js +1 -0
  131. package/dist/assets/{item-BSGXym2I.js → item-ClBhYYKW.js} +1 -1
  132. package/dist/assets/ja-B5tIV7r-.js +3 -0
  133. package/dist/assets/{ja-C2daM668.js → ja-D2jInSAT.js} +1 -1
  134. package/dist/assets/keyboard-arrow-down-rounded-DadBVmpO.js +1 -0
  135. package/dist/assets/{ko-Lni8u0p_.js → ko-BGB5KJZq.js} +1 -1
  136. package/dist/assets/ko-CL3JJCJN.js +3 -0
  137. package/dist/assets/landing-page-BfVl47YO.js +1 -0
  138. package/dist/assets/{launch-result-message-ByEG8r_7.js → launch-result-message-BP5yMmIB.js} +1 -1
  139. package/dist/assets/{layout-BqhTD729.js → layout-D5G7Z8Ws.js} +1 -1
  140. package/dist/assets/list-CjtRvxdF.js +211 -0
  141. package/dist/assets/{list-header-BmTDmRY0.js → list-header-Cip98Afo.js} +1 -1
  142. package/dist/assets/localization-Tn68766t.js +1 -0
  143. package/dist/assets/{log-o_Cadt8j.js → log-_cZt5s1j.js} +1 -1
  144. package/dist/assets/{login-BQozrLDm.js → login-Bd9eibzl.js} +1 -1
  145. package/dist/assets/{login-oauth-callback-D7lIww1c.js → login-oauth-callback-Buv0sriC.js} +1 -1
  146. package/dist/assets/{logo-uploader-CUQ3aWZJ.js → logo-uploader-DGn3pkYl.js} +5 -4
  147. package/dist/assets/{lost-passport-DkETH2Lu.js → lost-passport-BplwQoPb.js} +3 -3
  148. package/dist/assets/omit-DYK_TtPQ.js +1 -0
  149. package/dist/assets/{open-window-BOl-kTC2.js → open-window-3TWqcI62.js} +1 -1
  150. package/dist/assets/overview-CJ3muOc6.js +84 -0
  151. package/dist/assets/{page-header-Dm1v9v5q.js → page-header-FKKsPnE9.js} +1 -1
  152. package/dist/assets/{permission-B5jnw9r2.js → permission-Dd3ufGD-.js} +1 -1
  153. package/dist/assets/preferences-D4OSAVTW.js +1 -0
  154. package/dist/assets/profile-embed--1Je95gw.js +1 -0
  155. package/dist/assets/pt-CYRkKZmh.js +1 -0
  156. package/dist/assets/{pt-D6N4RLzf.js → pt-DY0Ku5W5.js} +1 -1
  157. package/dist/assets/publish-resource-B4kuEUIu.js +1 -0
  158. package/dist/assets/{react-beautiful-dnd.esm-B9MfX9Xl.js → react-beautiful-dnd.esm-DxmtDCVc.js} +4 -4
  159. package/dist/assets/{relative-time-RQnsWZQc.js → relative-time-Bp0EO1aU.js} +1 -1
  160. package/dist/assets/roboto-cyrillic-400-normal-DAIM1_dR.woff2 +0 -0
  161. package/dist/assets/roboto-cyrillic-400-normal-Dry59Hjn.woff +0 -0
  162. package/dist/assets/roboto-cyrillic-500-normal-CsCirF4J.woff +0 -0
  163. package/dist/assets/roboto-cyrillic-500-normal-hCeO1jFL.woff2 +0 -0
  164. package/dist/assets/roboto-cyrillic-700-normal-CB1Rmiii.woff +0 -0
  165. package/dist/assets/roboto-cyrillic-700-normal-CzEIZVQR.woff2 +0 -0
  166. package/dist/assets/roboto-cyrillic-ext-400-normal-BxX1-eA_.woff +0 -0
  167. package/dist/assets/roboto-cyrillic-ext-400-normal-DzMWdK87.woff2 +0 -0
  168. package/dist/assets/roboto-cyrillic-ext-500-normal-B7rQpwPu.woff2 +0 -0
  169. package/dist/assets/roboto-cyrillic-ext-500-normal-ElvJfk8V.woff +0 -0
  170. package/dist/assets/roboto-cyrillic-ext-700-normal-CIu0AXX2.woff +0 -0
  171. package/dist/assets/roboto-cyrillic-ext-700-normal-D_fA0fHY.woff2 +0 -0
  172. package/dist/assets/roboto-greek-400-normal-CAI06USH.woff +0 -0
  173. package/dist/assets/roboto-greek-400-normal-jFM2czAU.woff2 +0 -0
  174. package/dist/assets/roboto-greek-500-normal-BJMS0heP.woff2 +0 -0
  175. package/dist/assets/roboto-greek-500-normal-D8eQD5zT.woff +0 -0
  176. package/dist/assets/roboto-greek-700-normal-DCrt6r9F.woff +0 -0
  177. package/dist/assets/roboto-greek-700-normal-DpKAje7q.woff2 +0 -0
  178. package/dist/assets/roboto-latin-400-normal-551zQQ7R.woff +0 -0
  179. package/dist/assets/roboto-latin-400-normal-CNwBRw8h.woff2 +0 -0
  180. package/dist/assets/roboto-latin-500-normal-CkrA1NAy.woff2 +0 -0
  181. package/dist/assets/roboto-latin-500-normal-_8jDuD7w.woff +0 -0
  182. package/dist/assets/roboto-latin-700-normal-CTLkNcF_.woff +0 -0
  183. package/dist/assets/roboto-latin-700-normal-DZr4b_KL.woff2 +0 -0
  184. package/dist/assets/roboto-latin-ext-400-normal-ZYmyxeOy.woff2 +0 -0
  185. package/dist/assets/roboto-latin-ext-400-normal-uRIBRJt5.woff +0 -0
  186. package/dist/assets/roboto-latin-ext-500-normal-C_ARlJGk.woff2 +0 -0
  187. package/dist/assets/roboto-latin-ext-500-normal-eJ10kk0m.woff +0 -0
  188. package/dist/assets/roboto-latin-ext-700-normal-BNPgmEQS.woff2 +0 -0
  189. package/dist/assets/roboto-latin-ext-700-normal-Cnx4FGpK.woff +0 -0
  190. package/dist/assets/roboto-math-400-normal-B3wgz80t.woff2 +0 -0
  191. package/dist/assets/roboto-math-400-normal-DHrwdhE6.woff +0 -0
  192. package/dist/assets/roboto-math-500-normal-CFNaIMFC.woff2 +0 -0
  193. package/dist/assets/roboto-math-500-normal-CetgDdIa.woff +0 -0
  194. package/dist/assets/roboto-math-700-normal-CpTCM92H.woff +0 -0
  195. package/dist/assets/roboto-math-700-normal-xbpggnJp.woff2 +0 -0
  196. package/dist/assets/roboto-symbols-400-normal-bG5rsNFs.woff +0 -0
  197. package/dist/assets/roboto-symbols-400-normal-fF1SLJBj.woff2 +0 -0
  198. package/dist/assets/roboto-symbols-500-normal-BXFTxrNR.woff2 +0 -0
  199. package/dist/assets/roboto-symbols-500-normal-toKUCDph.woff +0 -0
  200. package/dist/assets/roboto-symbols-700-normal-B2QKVW64.woff +0 -0
  201. package/dist/assets/roboto-symbols-700-normal-DKkQdRpM.woff2 +0 -0
  202. package/dist/assets/roboto-vietnamese-400-normal-CDDxGrUb.woff2 +0 -0
  203. package/dist/assets/roboto-vietnamese-400-normal-DgufTq8s.woff +0 -0
  204. package/dist/assets/roboto-vietnamese-500-normal-Dw5heWgq.woff +0 -0
  205. package/dist/assets/roboto-vietnamese-500-normal-HYpufUYk.woff2 +0 -0
  206. package/dist/assets/roboto-vietnamese-700-normal-BFWtvCOj.woff2 +0 -0
  207. package/dist/assets/roboto-vietnamese-700-normal-ChAl_rRV.woff +0 -0
  208. package/dist/assets/{ru-D-xvMzxI.js → ru-Cv5vRo7s.js} +1 -1
  209. package/dist/assets/ru-Dzg-gLvu.js +1 -0
  210. package/dist/assets/runtime-DCHSigWq.js +1 -0
  211. package/dist/assets/sdk-B4tneH2b.js +1 -0
  212. package/dist/assets/security-Ba0U57n2.js +95 -0
  213. package/dist/assets/session-BXc0WNE7.js +1 -0
  214. package/dist/assets/setup-bc5fgvzY.js +19 -0
  215. package/dist/assets/{shorten-label-DkFTGSoy.js → shorten-label-BcXnCxH2.js} +1 -1
  216. package/dist/assets/{simple-select-CqakAZFe.js → simple-select-D7qC2duk.js} +1 -1
  217. package/dist/assets/{slicedToArray-BuQur6Mi.js → slicedToArray-CG0jVe85.js} +2 -2
  218. package/dist/assets/{start-BSUY3DBl.js → start-kkjng8Di.js} +1 -1
  219. package/dist/assets/status-Bcehte3I.js +1 -0
  220. package/dist/assets/step-actions-CAn2VbnK.js +31 -0
  221. package/dist/assets/studio-Dnzc2A5y.js +6 -0
  222. package/dist/assets/{switch-control-BBlLGjaH.js → switch-control-DZceCxwF.js} +1 -1
  223. package/dist/assets/th-CevmRMq6.js +1 -0
  224. package/dist/assets/{th-CycIQ910.js → th-D6oDBVGi.js} +1 -1
  225. package/dist/assets/{traffic-CJDIGmp5.js → traffic-BbJxF2T-.js} +4 -4
  226. package/dist/assets/transfer-j5hCBx8d.js +16 -0
  227. package/dist/assets/{unsubscribe-afXXIHEf.js → unsubscribe-DJgSmFME.js} +1 -1
  228. package/dist/assets/{use-mobile-CUT5hy9q.js → use-mobile-DNsgYi-4.js} +1 -1
  229. package/dist/assets/use-mobile-DVecy9Ks.js +1 -0
  230. package/dist/assets/{useAsync-DM8qaMe4.js → useAsync-Bia14KO2.js} +1 -1
  231. package/dist/assets/{useAsyncRetry-B7SbzXVI.js → useAsyncRetry-C-QH3IsB.js} +1 -1
  232. package/dist/assets/{useLocalStorage-Dd4pybDP.js → useLocalStorage-BQFZ73WZ.js} +1 -1
  233. package/dist/assets/user-center-BZ0ZkNAA.js +67 -0
  234. package/dist/assets/{util-C_BCTHfw.js → util-C9Xcu_Dq.js} +1 -1
  235. package/dist/assets/{util-YyWTpLT7.js → util-WwcocPP-.js} +1 -1
  236. package/dist/assets/vendor-arcblock-B7hyNlnQ.js +1598 -0
  237. package/dist/assets/{vendor-hooks-sw5wvnca.js → vendor-hooks-DnflU2EL.js} +1 -1
  238. package/dist/assets/{vendor-mui-core-DxqV1NVn.js → vendor-mui-core-BL-xsBvI.js} +1 -1
  239. package/dist/assets/{vendor-mui-x-BjL1xCkk.js → vendor-mui-x-BmOE-0pQ.js} +1 -1
  240. package/dist/assets/vendor-utils-Cs6ARqvU.js +11 -0
  241. package/dist/assets/vendor-ux-did-connect-BDmhBveY.css +1 -0
  242. package/dist/assets/vendor-ux-did-connect-CWUKGZcn.js +1843 -0
  243. package/dist/assets/{vi-BqnfnvFP.js → vi-BKKJMbW2.js} +1 -1
  244. package/dist/assets/vi-PQuaKyKY.js +1 -0
  245. package/dist/assets/wrap-locale-DyRnlWyZ.js +1 -0
  246. package/dist/assets/zh-BBkG8qYp.js +4 -0
  247. package/dist/assets/{zh-CHmwTyCg.js → zh-D4Lak9gZ.js} +1 -1
  248. package/dist/assets/{zh-tw-D6K-qXNE.js → zh-tw-B08rjgK3.js} +1 -1
  249. package/dist/assets/zh-tw-BHJNqYL0.js +3 -0
  250. package/dist/images/all-done.png +0 -0
  251. package/dist/index.html +7 -7
  252. package/dist/service-worker.js +1 -1
  253. package/package.json +39 -40
  254. package/dist/assets/access-control-CpxcJItK.js +0 -14
  255. package/dist/assets/analytics-BXLe73MI.js +0 -11
  256. package/dist/assets/api-D9Yi7Zdr.js +0 -1
  257. package/dist/assets/appearance-DX7SoW1u.js +0 -1
  258. package/dist/assets/ar-2k9jaPIk.js +0 -3
  259. package/dist/assets/base32-BNpDT-6Q.js +0 -1
  260. package/dist/assets/branding-BW1rhy8d.js +0 -40
  261. package/dist/assets/button-CNnuiac8.js +0 -1
  262. package/dist/assets/connect-BfSOEYV-.js +0 -1
  263. package/dist/assets/dashboard-C_Q4TjPa.js +0 -216
  264. package/dist/assets/de-B9cLhykn.js +0 -3
  265. package/dist/assets/domain-CLMRXecU.js +0 -9
  266. package/dist/assets/domains-DF7TtN5q.js +0 -1
  267. package/dist/assets/es-BoQohonz.js +0 -3
  268. package/dist/assets/exchange-passport--DeUPzbW.js +0 -1
  269. package/dist/assets/form-text-input-BYF6lVnE.js +0 -11
  270. package/dist/assets/fr-doSYAOrt.js +0 -3
  271. package/dist/assets/fuel-D-kOZuF6.js +0 -32
  272. package/dist/assets/fullpage-DO8Hcbkl.js +0 -1
  273. package/dist/assets/hi-B_BwhpD8.js +0 -1
  274. package/dist/assets/home-CpnMpXiw.js +0 -1
  275. package/dist/assets/id-BgYIZCvk.js +0 -3
  276. package/dist/assets/index-BVOYP6aR.js +0 -11
  277. package/dist/assets/index-BsUr7wGb.js +0 -104
  278. package/dist/assets/index-C44fECmB.js +0 -138
  279. package/dist/assets/index-CmKAznDh.js +0 -109
  280. package/dist/assets/index-DqC2o5PB.js +0 -4
  281. package/dist/assets/index-DyTFEgKr.js +0 -1
  282. package/dist/assets/index-eCY24sH9.js +0 -137
  283. package/dist/assets/index-gTQQ3SoE.js +0 -290
  284. package/dist/assets/index-gcSQTx25.js +0 -1
  285. package/dist/assets/index.esm-CWepf7I_.js +0 -1
  286. package/dist/assets/inter-latin-300-normal-CvRFFuZy.woff2 +0 -0
  287. package/dist/assets/inter-latin-300-normal-ORCTF8i-.woff +0 -0
  288. package/dist/assets/inter-latin-400-normal-BOOGhInR.woff2 +0 -0
  289. package/dist/assets/inter-latin-400-normal-gitzw0hO.woff +0 -0
  290. package/dist/assets/inter-latin-500-normal-D2bGa7uu.woff2 +0 -0
  291. package/dist/assets/inter-latin-500-normal-deR1Tlfd.woff +0 -0
  292. package/dist/assets/inter-latin-700-normal-B8MtJ_2k.woff +0 -0
  293. package/dist/assets/inter-latin-700-normal-Sckx8rpT.woff2 +0 -0
  294. package/dist/assets/inter-latin-ext-300-normal-C2kLfG2J.woff2 +0 -0
  295. package/dist/assets/inter-latin-ext-300-normal-n8Ps4oXY.woff +0 -0
  296. package/dist/assets/inter-latin-ext-400-normal-C1t-h-pH.woff +0 -0
  297. package/dist/assets/inter-latin-ext-400-normal-hnt3BR84.woff2 +0 -0
  298. package/dist/assets/inter-latin-ext-500-normal-CIS2RHJS.woff2 +0 -0
  299. package/dist/assets/inter-latin-ext-500-normal-UMdmhHu2.woff +0 -0
  300. package/dist/assets/inter-latin-ext-700-normal-6V9MnIL5.woff +0 -0
  301. package/dist/assets/inter-latin-ext-700-normal-CzikT_rs.woff2 +0 -0
  302. package/dist/assets/invite-BBaF_vyc.js +0 -1
  303. package/dist/assets/issue-passport-DC-ly7xg.js +0 -1
  304. package/dist/assets/ja-FMMLI8YD.js +0 -3
  305. package/dist/assets/ko-C0kmRXYE.js +0 -3
  306. package/dist/assets/list-BHs8uNT5.js +0 -200
  307. package/dist/assets/localization-daPAWMzR.js +0 -1
  308. package/dist/assets/login-bg-Cbfh9Uc2.png +0 -0
  309. package/dist/assets/omit-DZNQhOf-.js +0 -1
  310. package/dist/assets/overview-Bxm05EH6.js +0 -12
  311. package/dist/assets/preferences-uri2RXdB.js +0 -1
  312. package/dist/assets/profile-embed-DnIQcD-H.js +0 -1
  313. package/dist/assets/pt-C2UJZK-O.js +0 -1
  314. package/dist/assets/publish-resource-V53U1NNv.js +0 -1
  315. package/dist/assets/ru-DDA5s4-r.js +0 -1
  316. package/dist/assets/sdk-BKSsfgrc.js +0 -1
  317. package/dist/assets/session-6ZeN-aF2.js +0 -1
  318. package/dist/assets/setup-7Gq9K_8k.js +0 -19
  319. package/dist/assets/status-C52-BFuY.js +0 -1
  320. package/dist/assets/step-actions-CA74dwgt.js +0 -31
  321. package/dist/assets/studio-CAnZfyBM.js +0 -6
  322. package/dist/assets/th-DmqOUn4C.js +0 -1
  323. package/dist/assets/transfer-cG2e24sz.js +0 -16
  324. package/dist/assets/user-center-T8Xw464s.js +0 -67
  325. package/dist/assets/vendor-arcblock-DvaaLvvM.js +0 -2361
  326. package/dist/assets/vendor-utils-DR57WNxP.js +0 -11
  327. package/dist/assets/vendor-ux-did-connect-Bciw9Ypu.js +0 -1077
  328. package/dist/assets/vendor-ux-did-connect-DhgPdlEj.css +0 -1
  329. package/dist/assets/vi-Cf__CtPD.js +0 -1
  330. package/dist/assets/wrap-locale-CX50Vz0w.js +0 -1
  331. package/dist/assets/zh-NXspK2yu.js +0 -4
  332. package/dist/assets/zh-tw-DYYDVX5I.js +0 -3
@@ -1,17 +1,10 @@
1
- const {
2
- WELLKNOWN_SERVICE_PATH_PREFIX,
3
- SECURITY_RULE_DEFAULT_ID,
4
- ROLES,
5
- VERIFY_CODE_TTL,
6
- PASSPORT_STATUS,
7
- } = require('@abtnode/constant');
1
+ const { WELLKNOWN_SERVICE_PATH_PREFIX, VERIFY_CODE_TTL } = require('@abtnode/constant');
8
2
  const JWT = require('@arcblock/jwt');
9
3
  const { render } = require('@react-email/components');
10
- const { messages, getApplicationInfo } = require('@abtnode/auth/lib/auth');
4
+ const { getApplicationInfo, handleInvitationReceive } = require('@abtnode/auth/lib/auth');
11
5
  const { fromAppDid } = require('@arcblock/did-ext');
12
6
  const { extractUserAvatar, getUserAvatarUrl } = require('@abtnode/util/lib/user');
13
7
  const formatContext = require('@abtnode/util/lib/format-context');
14
- const createTranslator = require('@abtnode/util/lib/translate');
15
8
  const { fromBase64 } = require('@ocap/util');
16
9
  const { isFromPublicKey } = require('@arcblock/did');
17
10
  const { LOGIN_PROVIDER } = require('@blocklet/constant');
@@ -20,20 +13,18 @@ const merge = require('lodash/merge');
20
13
  const omitBy = require('lodash/omitBy');
21
14
  const omit = require('lodash/omit');
22
15
  const uniq = require('lodash/uniq');
23
- const last = require('lodash/last');
24
- const sortBy = require('lodash/sortBy');
25
16
  const { getLastUsedPassport } = require('@abtnode/auth/lib/passport');
26
- const { getWallet } = require('@blocklet/meta/lib/did-utils');
17
+ const { getWallet, getWalletDid } = require('@blocklet/meta/lib/did-utils');
27
18
  const { Joi } = require('@arcblock/validator');
28
19
  const { parse } = require('@abtnode/core/lib/util/ua');
29
- const { checkInvitedUserOnly } = require('@abtnode/auth/lib/oauth');
30
20
  const getRequestIP = require('@abtnode/util/lib/get-request-ip');
31
21
  const formatError = require('@abtnode/util/lib/format-error');
32
22
  const CustomError = require('@abtnode/util/lib/custom-error');
33
- const { callFederated } = require('@abtnode/auth/lib/util/federated');
34
23
  const { xss } = require('@blocklet/xss');
35
- const { withQuery } = require('ufo');
24
+ const { withQuery, joinURL } = require('ufo');
36
25
  const cors = require('cors');
26
+ const createTranslator = require('@abtnode/util/lib/translate');
27
+ const { getDeviceData } = require('@abtnode/util/lib/device');
37
28
 
38
29
  const { createTokenFn, getDidConnectVersion } = require('../util');
39
30
  const initJwt = require('../libs/jwt');
@@ -44,13 +35,14 @@ const { getAvatarByEmail } = require('../libs/auth/utils');
44
35
  const logger = require('../libs/logger')('user');
45
36
  const ensureBlocklet = require('../middlewares/ensure-blocklet');
46
37
  const checkUser = require('../middlewares/check-user');
47
- const { getUserWithinFederated, getUserAvatarUrl: getRawUserAvatarUrl } = require('../util/federated');
48
38
  const { Profile } = require('../state/profile');
49
39
  const { emailSchema } = require('../socket/channel/did');
50
40
  const { sendEmail } = require('../libs/email');
51
41
  const federatedUtil = require('../util/federated');
42
+ const userUtil = require('../util/user-util');
52
43
  const { VerifyCodeBody } = require('../emails/_templates/verify-code-body');
53
44
  const { checkFederatedCall } = require('../middlewares/check-federated');
45
+ const { sendToUser } = require('../libs/notification');
54
46
 
55
47
  const validateUser = (user) => {
56
48
  try {
@@ -69,6 +61,7 @@ const PREFIX = WELLKNOWN_SERVICE_PATH_PREFIX;
69
61
 
70
62
  const prefix = `${PREFIX}/user`;
71
63
  const prefixApi = `${PREFIX}/api/user`;
64
+
72
65
  const translations = {
73
66
  zh: {
74
67
  notAllowed: '你已经被禁止访问该应用',
@@ -81,6 +74,8 @@ const translations = {
81
74
  emailAlreadySent: '我们已发送验证电子邮件。请检查您的收件箱或垃圾邮件文件夹。如果您没有看到它,您可以稍后再试。',
82
75
  emailVerifySuccess: '邮箱验证成功',
83
76
  emailTitle: '登录 {appName}',
77
+ invalidVerifyCode: '验证码不正确',
78
+ missingInviteId: '缺少邀请 ID',
84
79
  },
85
80
  en: {
86
81
  notAllowed: 'Your have been revoked access to this blocklet',
@@ -94,19 +89,13 @@ const translations = {
94
89
  "We've sent a verification email. Please check your inbox and spam folder. If you don't see it, you can try again in a few minutes.",
95
90
  emailVerifySuccess: 'Email verified successfully',
96
91
  emailTitle: 'Login to {appName}',
92
+ invalidVerifyCode: 'Invalid verify code',
93
+ missingInviteId: 'Missing invite ID',
97
94
  },
98
95
  };
99
96
 
100
97
  const t = createTranslator({ translations });
101
98
 
102
- async function checkNeedInvite({ req, node, teamDid, locale }) {
103
- const { accessPolicyConfig } = await req.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
104
- const isInvitedUserOnly = await checkInvitedUserOnly(accessPolicyConfig, node, teamDid);
105
- if (isInvitedUserOnly) {
106
- throw new CustomError(403, messages.notInvited[locale]);
107
- }
108
- }
109
-
110
99
  function ensureUserExist(user, { locale } = {}) {
111
100
  if (!user) {
112
101
  throw new CustomError(404, t('notExist', locale));
@@ -136,7 +125,7 @@ async function composeProfileData({ avatar, fullName, email }, { node, req, team
136
125
  avatarLocal = await getAvatarByEmail(email);
137
126
  }
138
127
  if (!fullName) {
139
- profile.fullName = email;
128
+ profile.fullName = userUtil.getUserNameByEmail(email);
140
129
  }
141
130
  }
142
131
  }
@@ -191,7 +180,7 @@ async function loginWallet(
191
180
  profile = await composeProfileData({ avatar, email, fullName }, { node, req, teamDid });
192
181
  }
193
182
  } else {
194
- await checkNeedInvite({ req, node, teamDid, locale });
183
+ await userUtil.checkNeedInvite({ req, node, teamDid, locale });
195
184
  profile = await composeProfileData({ avatar, email, fullName }, { node, req, teamDid, isCreate: true });
196
185
  }
197
186
 
@@ -255,7 +244,7 @@ async function loginOAuth(
255
244
  profile = await composeProfileData({ avatar, email, fullName }, { node, req, teamDid });
256
245
  }
257
246
  } else {
258
- await checkNeedInvite({ req, node, teamDid, locale });
247
+ await userUtil.checkNeedInvite({ req, node, teamDid, locale });
259
248
  profile = await composeProfileData({ avatar, email, fullName }, { node, req, teamDid, isCreate: true });
260
249
  }
261
250
 
@@ -281,7 +270,7 @@ async function loginOAuth(
281
270
  return doc;
282
271
  }
283
272
 
284
- async function login(req, node, options) {
273
+ async function loginSDK(req, node, options) {
285
274
  const {
286
275
  provider = LOGIN_PROVIDER.WALLET,
287
276
  did,
@@ -352,8 +341,7 @@ async function login(req, node, options) {
352
341
  );
353
342
  const lastLoginIp = getRequestIP(req);
354
343
  const ua = req.get('user-agent');
355
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
356
- const walletDeviceId = req.get('wallet-device-id');
344
+ const deviceData = getDeviceData({ req });
357
345
  const userSession = await node.upsertUserSession({
358
346
  visitorId,
359
347
  teamDid,
@@ -364,8 +352,7 @@ async function login(req, node, options) {
364
352
  lastLoginIp,
365
353
  extra: {
366
354
  walletOS: 'api',
367
- walletDeviceMessageToken,
368
- walletDeviceId,
355
+ device: deviceData,
369
356
  },
370
357
  });
371
358
  node.syncUserSession({
@@ -378,8 +365,7 @@ async function login(req, node, options) {
378
365
  lastLoginIp,
379
366
  extra: {
380
367
  walletOS: 'api',
381
- walletDeviceMessageToken,
382
- walletDeviceId,
368
+ device: deviceData,
383
369
  },
384
370
  });
385
371
  return {
@@ -391,7 +377,10 @@ async function login(req, node, options) {
391
377
  }
392
378
 
393
379
  async function verifyUserSig({ userDid, signature, teamDid, sourceAppPid, userPk }, { node, locale, blocklet }) {
394
- const currentUser = await getUserWithinFederated({ sourceAppPid, teamDid, userDid, userPk }, { node, blocklet });
380
+ const currentUser = await federatedUtil.getUserWithinFederated(
381
+ { sourceAppPid, teamDid, userDid, userPk },
382
+ { node, blocklet }
383
+ );
395
384
  ensureUserExist(currentUser, { locale });
396
385
  ensureUserEnable(currentUser, { locale });
397
386
 
@@ -451,6 +440,212 @@ function checkUserSig({ node }) {
451
440
  };
452
441
  }
453
442
 
443
+ async function loginEmail(req, node, options) {
444
+ const { locale = 'en' } = req.query;
445
+ const { sourceAppPid = null, inviter = null } = req.body;
446
+
447
+ const blocklet = await req.getBlocklet();
448
+ const teamDid = blocklet.appPid;
449
+ const verifyCode = await userUtil.getVerifyCodeFromReq({ logger, req });
450
+ const verifyCodeResult = await node.consumeVerifyCode({ teamDid, code: verifyCode });
451
+
452
+ if (!verifyCodeResult) {
453
+ throw new CustomError(400, t('invalidVerifyCode', locale));
454
+ }
455
+ logger.info('Email login: consume verify code', { teamDid, code: verifyCode, result: verifyCodeResult });
456
+
457
+ // 保持跟 oauth 账户的格式一致
458
+ const sub = `email|${verifyCodeResult.subject}`;
459
+ const { wallet: userWallet } = await userUtil.getUserFromSub(sub, { req });
460
+ const userInfo = {
461
+ email: verifyCodeResult.subject,
462
+ provider: LOGIN_PROVIDER.EMAIL,
463
+ };
464
+
465
+ const userDid = userWallet.address;
466
+ const userPk = userWallet.publicKey;
467
+
468
+ let profile;
469
+ let currentUser = await federatedUtil.getUserWithinFederated(
470
+ { sourceAppPid, teamDid, userDid, userPk },
471
+ { node, blocklet }
472
+ );
473
+ const connectedAccount = {
474
+ provider: LOGIN_PROVIDER.EMAIL,
475
+ did: userDid,
476
+ pk: userPk,
477
+ id: sub,
478
+ userInfo,
479
+ };
480
+ const lastUsedPassport = userUtil.getLastUsedPassport({ passports: currentUser?.passports });
481
+
482
+ if (!currentUser) {
483
+ await userUtil.checkNeedInvite({ req, node, teamDid, locale });
484
+ currentUser = {
485
+ did: userDid,
486
+ pk: userPk,
487
+ };
488
+ const avatar = await userUtil.getAvatarBnByEmail(verifyCodeResult.subject, { req, node });
489
+ profile = {
490
+ fullName: userUtil.getUserNameByEmail(verifyCodeResult.subject),
491
+ avatar,
492
+ inviter,
493
+ email: verifyCodeResult.subject,
494
+ // email 登录默认认为邮箱已验证
495
+ emailVerified: true,
496
+ };
497
+ }
498
+
499
+ const { sessionToken, refreshToken, visitorId } = await userUtil.loginUserSession(
500
+ {
501
+ did: currentUser.did || userDid,
502
+ pk: currentUser.pk,
503
+ profile,
504
+ passport: lastUsedPassport,
505
+ sourceAppPid,
506
+ connectedAccount,
507
+ provider: LOGIN_PROVIDER.EMAIL,
508
+ },
509
+ { req, node, options }
510
+ );
511
+
512
+ return {
513
+ sessionToken,
514
+ refreshToken,
515
+ visitorId,
516
+ };
517
+ }
518
+
519
+ async function inviteEmail(req, node, options) {
520
+ const { locale = 'en' } = req.query;
521
+ const { sourceAppPid = null, inviteId, baseUrl } = req.body;
522
+
523
+ if (!inviteId) {
524
+ throw new CustomError(400, t('missingInviteId', locale));
525
+ }
526
+
527
+ const blocklet = await req.getBlocklet();
528
+ const teamDid = blocklet.appPid;
529
+ const verifyCode = await userUtil.getVerifyCodeFromReq({ logger, req });
530
+ const verifyCodeResult = await node.consumeVerifyCode({ teamDid, code: verifyCode });
531
+
532
+ if (!verifyCodeResult) {
533
+ throw new CustomError(400, t('invalidVerifyCode', locale));
534
+ }
535
+ logger.info('Email invite: consume verify code', { teamDid, code: verifyCode, result: verifyCodeResult });
536
+
537
+ // 保持跟 oauth 账户的格式一致
538
+ const sub = `email|${verifyCodeResult.subject}`;
539
+ const { wallet: userWallet } = await userUtil.getUserFromSub(sub, { req });
540
+ const userInfo = {
541
+ email: verifyCodeResult.subject,
542
+ provider: LOGIN_PROVIDER.EMAIL,
543
+ };
544
+
545
+ const userDid = userWallet.address;
546
+ const userPk = userWallet.publicKey;
547
+
548
+ let profile;
549
+ let currentUser = await federatedUtil.getUserWithinFederated(
550
+ { sourceAppPid, teamDid, userDid, userPk },
551
+ { node, blocklet }
552
+ );
553
+ logger.info('Email invite: get user info', { teamDid, currentUser });
554
+ const nodeInfo = await req.getNodeInfo();
555
+ const { name: applicationName } = await getApplicationInfo({ node, nodeInfo, teamDid });
556
+
557
+ if (!currentUser) {
558
+ currentUser = {
559
+ did: userDid,
560
+ pk: userPk,
561
+ };
562
+
563
+ const avatar = await userUtil.getAvatarBnByEmail(verifyCodeResult.subject, { req, node });
564
+ profile = {
565
+ fullName: userUtil.getUserNameByEmail(verifyCodeResult.subject),
566
+ avatar,
567
+ email: verifyCodeResult.subject,
568
+ // email 登录默认认为邮箱已验证
569
+ emailVerified: true,
570
+ };
571
+ }
572
+
573
+ const statusEndpointBaseUrl = joinURL(baseUrl, WELLKNOWN_SERVICE_PATH_PREFIX);
574
+ const endpoint = baseUrl;
575
+
576
+ const { passport, response, role, inviteInfo, user } = await handleInvitationReceive({
577
+ req,
578
+ node,
579
+ endpoint,
580
+ inviteId,
581
+ nodeInfo,
582
+ profile: profile || {
583
+ email: currentUser.email,
584
+ fullName: currentUser.fullName,
585
+ avatar: getUserAvatarUrl(baseUrl, currentUser.avatar),
586
+ },
587
+ statusEndpointBaseUrl,
588
+ teamDid,
589
+ userDid: userWallet.address,
590
+ userPk: userWallet.publicKey,
591
+ locale,
592
+ provider: LOGIN_PROVIDER.EMAIL,
593
+ });
594
+
595
+ if (currentUser) {
596
+ const walletDid = getWalletDid(currentUser);
597
+ if (walletDid) {
598
+ // 如果已经绑定了 wallet 账户,则将 passport 发送给 wallet 账户
599
+ await sendToUser(
600
+ walletDid,
601
+ {
602
+ title: 'Invitation accepted',
603
+ body: `You accept an invitation to be a ${role} of ${applicationName}`,
604
+ attachments: [
605
+ {
606
+ type: 'vc',
607
+ data: {
608
+ credential: response.data,
609
+ tag: role,
610
+ },
611
+ },
612
+ ],
613
+ },
614
+ { req }
615
+ );
616
+ }
617
+ }
618
+ const connectedAccount = {
619
+ provider: LOGIN_PROVIDER.EMAIL,
620
+ id: sub,
621
+ did: userWallet.address,
622
+ pk: userWallet.publicKey,
623
+ userInfo,
624
+ };
625
+
626
+ if (profile) {
627
+ profile.inviter = inviteInfo.inviter?.did;
628
+ }
629
+
630
+ const { sessionToken, refreshToken, visitorId } = await userUtil.loginUserSession(
631
+ {
632
+ did: currentUser.did,
633
+ pk: currentUser.pk,
634
+ profile,
635
+ passport,
636
+ sourceAppPid,
637
+ connectedAccount,
638
+ },
639
+ { req, node, options, loggedUser: user }
640
+ );
641
+
642
+ return {
643
+ sessionToken,
644
+ refreshToken,
645
+ visitorId,
646
+ };
647
+ }
648
+
454
649
  const privacyConfigInputSchema = Joi.object({
455
650
  userDid: Joi.DID().required(),
456
651
  });
@@ -545,7 +740,7 @@ module.exports = {
545
740
  // 应用后端自行登录逻辑(SDK 中调用)
546
741
  server.post([`${prefix}/login`, `${prefixApi}/login`], verifySig, async (req, res) => {
547
742
  try {
548
- const data = await login(req, node, options);
743
+ const data = await loginSDK(req, node, options);
549
744
  res.status(200).json(data);
550
745
  } catch (err) {
551
746
  logger.error('Failed login', { error: err });
@@ -647,8 +842,7 @@ module.exports = {
647
842
  { ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
648
843
  );
649
844
  const ua = req.get('user-agent');
650
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
651
- const walletDeviceId = req.get('wallet-device-id');
845
+ const deviceData = getDeviceData({ req });
652
846
  const userSession = await node.upsertUserSession({
653
847
  visitorId,
654
848
  teamDid,
@@ -659,8 +853,7 @@ module.exports = {
659
853
  lastLoginIp,
660
854
  extra: {
661
855
  walletOS,
662
- walletDeviceMessageToken,
663
- walletDeviceId,
856
+ device: deviceData,
664
857
  },
665
858
  });
666
859
  node.syncUserSession({
@@ -673,8 +866,7 @@ module.exports = {
673
866
  lastLoginIp,
674
867
  extra: {
675
868
  walletOS,
676
- walletDeviceMessageToken,
677
- walletDeviceId,
869
+ device: deviceData,
678
870
  },
679
871
  });
680
872
 
@@ -700,7 +892,7 @@ module.exports = {
700
892
  const { did: teamDid } = await req.getBlockletInfo();
701
893
  const pendingList = users.map(async (item) => {
702
894
  if (item?.did && item?.pk) {
703
- const findUser = await getUserWithinFederated(
895
+ const findUser = await federatedUtil.getUserWithinFederated(
704
896
  { sourceAppPid, teamDid, userDid: item.did, userPk: item.pk },
705
897
  { node, blocklet }
706
898
  );
@@ -971,230 +1163,26 @@ module.exports = {
971
1163
  }
972
1164
  });
973
1165
  server.post(`${prefixApi}/email/login`, ensureBlocklet(), ensureCors, async (req, res) => {
974
- try {
975
- const { locale = 'en' } = req.query;
976
- const { blocklet } = req;
977
- const teamDid = blocklet.appPid;
978
- let passport = { name: 'Guest', role: 'guest' };
979
-
980
- const { code, magicToken, sourceAppPid = null } = req.body;
981
- const blockletInfo = await req.getBlockletInfo();
982
- let finalCode = code;
983
- if (!code && magicToken) {
984
- const valid = await JWT.verify(magicToken, blockletInfo.wallet.publicKey);
985
- if (!valid) {
986
- logger.error('Email login: Invalid magic token', { teamDid, magicToken });
987
- throw new CustomError(401, 'Invalid magic link');
988
- }
989
- const decodeData = JWT.decode(magicToken, true);
990
- if (!decodeData?.data?.code) {
991
- logger.error('Email login: failed to parse magicToken data', { teamDid, magicToken, decodeData });
992
- throw new CustomError(400, 'Invalid magic token format');
993
- }
994
- finalCode = decodeData?.data?.code;
995
- }
996
- const verifyCodeResult = await node.consumeVerifyCode({ teamDid, code: finalCode });
997
- if (!verifyCodeResult) {
998
- throw new CustomError(400, 'Invalid verify code');
999
- }
1000
- logger.info('Email login: consume verify code', { teamDid, code, result: verifyCodeResult });
1001
-
1002
- // 保持跟 oauth 账户的格式一致
1003
- const sub = `email|${verifyCodeResult.subject}`;
1004
- let userWallet;
1005
- if (sourceAppPid) {
1006
- const masterSite = federatedUtil.getFederatedMaster(blocklet);
1007
- const { permanentWallet } = blockletInfo;
1008
- const result = await callFederated({
1009
- action: 'getUser',
1010
- site: masterSite,
1011
- permanentWallet,
1012
- data: {
1013
- userSub: sub,
1014
- },
1015
- });
1016
- userWallet = result?.wallet;
1017
- } else {
1018
- userWallet = fromAppDid(sub, blockletInfo.wallet.secretKey);
1019
- }
1020
-
1021
- const lastLoginIp = getRequestIP(req);
1022
-
1023
- const userDid = userWallet.address;
1024
- const userPk = userWallet.publicKey;
1025
-
1026
- let doc;
1027
- let passportForLog;
1028
- let profile;
1029
- let currentUser = await node.getUser({ teamDid, user: { did: userWallet.address } });
1030
- const connectedAccount = {
1031
- provider: LOGIN_PROVIDER.EMAIL,
1032
- did: userDid,
1033
- pk: userPk,
1034
- id: sub,
1035
- };
1036
-
1037
- if (currentUser) {
1038
- profile = {
1039
- fullName: currentUser.fullName,
1040
- email: currentUser.email,
1041
- avatar: currentUser.avatar,
1042
- };
1043
- const allPassports = currentUser.passports || [];
1044
- const validPassports = allPassports.filter((item) => item.status === PASSPORT_STATUS.VALID);
1045
- const lastUsedPassport = last(sortBy(validPassports, 'lastLoginAt'));
1046
- passportForLog = lastUsedPassport;
1047
- if (lastUsedPassport) {
1048
- passport = pick(lastUsedPassport, ['id', 'name', 'role', 'scope']);
1049
- }
1050
- doc = await node.loginUser({
1051
- teamDid,
1052
- user: {
1053
- did: currentUser.did,
1054
- pk: currentUser.pk,
1055
- locale,
1056
- lastLoginIp,
1057
- sourceAppPid,
1058
- passport: lastUsedPassport,
1059
- connectedAccount,
1060
- },
1061
- });
1062
- } else {
1063
- await checkNeedInvite({ req, node, teamDid, locale });
1064
- currentUser = {
1065
- did: userWallet.address,
1066
- pk: userWallet.publicKey,
1067
- };
1068
- const nodeInfo = await req.getNodeInfo();
1069
- const { dataDir } = await getApplicationInfo({ node, nodeInfo, teamDid });
1070
- let avatar = await getAvatarByEmail(verifyCodeResult.subject);
1071
- avatar = await extractUserAvatar(avatar, { dataDir });
1072
- profile = {
1073
- fullName: verifyCodeResult.subject.split('@')[0],
1074
- email: verifyCodeResult.subject,
1075
- avatar,
1076
- // email 登录默认认为邮箱已验证
1077
- emailVerified: true,
1078
- };
1079
- // 实际创建用户
1080
- doc = await node.loginUser({
1081
- teamDid,
1082
- user: {
1083
- did: currentUser.did,
1084
- pk: currentUser.pk,
1085
- ...profile,
1086
- locale,
1087
- lastLoginIp,
1088
- sourceAppPid,
1089
- connectedAccount,
1090
- },
1091
- });
1092
- }
1093
-
1094
- await node.createAuditLog(
1095
- {
1096
- action: 'login',
1097
- args: {
1098
- teamDid,
1099
- userDid: currentUser.did || userDid,
1100
- passport: passportForLog,
1101
- provider: LOGIN_PROVIDER.EMAIL,
1102
- sourceAppPid,
1103
- },
1104
- context: formatContext(Object.assign(req, { user: doc })),
1105
- result: doc,
1106
- },
1107
- node
1108
- );
1109
-
1110
- const ua = req.get('user-agent');
1111
- const visitorId = req.get('x-blocklet-visitor-id');
1112
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
1113
- const walletDeviceId = req.get('wallet-device-id');
1114
- const userSessionDoc = await node.upsertUserSession({
1115
- teamDid,
1116
- userDid: currentUser.did,
1117
- visitorId,
1118
- appPid: teamDid,
1119
- passportId: passport?.id,
1120
- status: 'online',
1121
- ua: null,
1122
- lastLoginIp,
1123
- extra: {
1124
- walletOS: 'web',
1125
- walletDeviceMessageToken,
1126
- walletDeviceId,
1127
- },
1128
- });
1129
-
1130
- if (federatedUtil.shouldSyncFederated(sourceAppPid, blocklet)) {
1131
- const syncUserData = {
1132
- did: currentUser.did,
1133
- pk: currentUser.pk,
1134
- ...profile,
1135
- avatar: getUserAvatarUrl(blockletInfo.appUrl, profile.avatar),
1136
- connectedAccount: [connectedAccount],
1137
- inviter: doc.inviter,
1138
- };
1139
- const masterSite = federatedUtil.getFederatedMaster(blocklet);
1166
+ const { action = 'login' } = req.body;
1167
+ const actionMap = {
1168
+ login: loginEmail,
1169
+ invite: inviteEmail,
1170
+ };
1171
+ if (!actionMap[action]) {
1172
+ logger.error('Failed to login by email', { error: 'action not exist', action });
1173
+ throw new Error(`action not exist: ${action}`);
1174
+ }
1140
1175
 
1141
- node
1142
- .syncFederated({
1143
- did: teamDid,
1144
- data: {
1145
- users: [
1146
- {
1147
- ...syncUserData,
1148
- action: 'connectAccount',
1149
- sourceAppPid: sourceAppPid || masterSite?.appPid,
1150
- },
1151
- ],
1152
- },
1153
- })
1154
- .then(() => {
1155
- node.syncUserSession({
1156
- teamDid,
1157
- userDid: userSessionDoc.userDid,
1158
- visitorId: userSessionDoc.visitorId,
1159
- passportId: passport?.id,
1160
- targetAppPid: sourceAppPid,
1161
- ua,
1162
- lastLoginIp,
1163
- extra: {
1164
- walletOS: 'web',
1165
- walletDeviceMessageToken,
1166
- walletDeviceId,
1167
- },
1168
- });
1169
- });
1176
+ try {
1177
+ const result = await actionMap[action](req, node, options);
1178
+ res.json(result);
1179
+ } catch (err) {
1180
+ logger.error('Failed login email', { error: err, action });
1181
+ if (err instanceof CustomError) {
1182
+ res.status(err.code).send(err.message);
1183
+ return;
1170
1184
  }
1171
-
1172
- const { createSessionToken } = initJwt(node, options);
1173
- const createToken = createTokenFn(createSessionToken);
1174
- const sessionConfig = blocklet.settings?.session || {};
1175
- const { sessionToken, refreshToken } = createToken(
1176
- currentUser.did,
1177
- {
1178
- secret: blockletInfo.secret,
1179
- passport,
1180
- role: passport.scope === 'passport' ? passport.role : ROLES.GUEST,
1181
- fullName: doc.fullName,
1182
- provider: LOGIN_PROVIDER.EMAIL,
1183
- walletOS: 'web',
1184
- emailVerified: !!doc?.emailVerified,
1185
- phoneVerified: !!doc?.phoneVerified,
1186
- },
1187
- { ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
1188
- );
1189
-
1190
- return res.status(200).json({
1191
- sessionToken,
1192
- refreshToken,
1193
- visitorId: userSessionDoc.visitorId,
1194
- });
1195
- } catch (error) {
1196
- logger.error('Email login failed', { error });
1197
- return res.status(400).send(error.message);
1185
+ throw err;
1198
1186
  }
1199
1187
  });
1200
1188
 
@@ -1434,7 +1422,7 @@ module.exports = {
1434
1422
  return;
1435
1423
  }
1436
1424
  if (user.avatar) {
1437
- user.avatar = getRawUserAvatarUrl(user.avatar, blocklet);
1425
+ user.avatar = federatedUtil.getUserAvatarUrl(user.avatar, blocklet);
1438
1426
  }
1439
1427
  let returnFields = ['avatar', 'did', 'fullName', 'sourceAppPid', 'createdAt', 'email', 'phone', 'metadata'];
1440
1428