@abtnode/blocklet-services 1.16.33-beta-20241024-064549-2c1ad302 → 1.16.33-beta-20241028-164124-17cf3c21

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 (306) hide show
  1. package/api/cache.js +39 -0
  2. package/api/index.js +121 -2
  3. package/api/libs/api.js +3 -3
  4. package/api/libs/connect/session.js +44 -53
  5. package/api/libs/kyc.js +9 -0
  6. package/api/libs/push-kit/index.js +17 -2
  7. package/api/middlewares/verify-sig.js +35 -3
  8. package/api/routes/blocklet.js +0 -13
  9. package/api/routes/env.js +2 -2
  10. package/api/routes/oauth.js +11 -7
  11. package/api/routes/user-session.js +38 -23
  12. package/api/routes/user.js +6 -7
  13. package/api/services/auth/index.js +43 -64
  14. package/api/services/kyc/index.js +56 -32
  15. package/api/util/attach-shared-utils.js +113 -19
  16. package/api/util/index.js +13 -12
  17. package/dist/assets/{Add-Bl82G48c.js → Add-DhnwVxhZ.js} +1 -1
  18. package/dist/assets/{Alert-B9Rlqmtk.js → Alert-C2mTW_RW.js} +1 -1
  19. package/dist/assets/{ArrowDropDown-z6CkvFic.js → ArrowDropDown-wj9U9ZE8.js} +1 -1
  20. package/dist/assets/{Autocomplete-C0mtAXbg.js → Autocomplete-CmEAN8J-.js} +1 -1
  21. package/dist/assets/{Avatar-LMc5QpZl.js → Avatar-BZ_OPd3a.js} +1 -1
  22. package/dist/assets/{ButtonGroup-Bvw5eHAy.js → ButtonGroup-CFQqy_jV.js} +1 -1
  23. package/dist/assets/CSSTransition-CJDdpnYB.js +1 -0
  24. package/dist/assets/{CheckCircle-CW1NWF0M.js → CheckCircle-DK6y1v0b.js} +1 -1
  25. package/dist/assets/{ChevronLeft-Bc2dOBpo.js → ChevronLeft-BqHB6tsg.js} +1 -1
  26. package/dist/assets/{ChevronRight-y7cPaDQ3.js → ChevronRight-DwKqpeOS.js} +1 -1
  27. package/dist/assets/{Close-DLWmZbtN.js → Close-CdDd2weK.js} +1 -1
  28. package/dist/assets/{CloseOutlined-7w3yHb7q.js → CloseOutlined-KF-hdrv3.js} +1 -1
  29. package/dist/assets/{Delete-FZyEAOwe.js → Delete-P7WqUbyQ.js} +1 -1
  30. package/dist/assets/{DeleteOutline-B-H27VeQ.js → DeleteOutline-BrrioL98.js} +1 -1
  31. package/dist/assets/{DialogContentText-CiyJlDpv.js → DialogContentText-BECZzyeS.js} +1 -1
  32. package/dist/assets/{Done-BEW0zhw2.js → Done-B8u3JQ36.js} +1 -1
  33. package/dist/assets/{Download-BfRlCRO0.js → Download-DBU6UuKg.js} +1 -1
  34. package/dist/assets/{EditIcon-CG4JGMyT.js → EditIcon-BV3Q9c3s.js} +1 -1
  35. package/dist/assets/{Error-C2cvwDlh.js → Error-CjCi6iqE.js} +1 -1
  36. package/dist/assets/{ExpandMore-CVPXcP59.js → ExpandMore-BjFaf3Fo.js} +1 -1
  37. package/dist/assets/FormControl-B9P20sHZ.js +1 -0
  38. package/dist/assets/FormControlLabel-C2tfmf09.js +1 -0
  39. package/dist/assets/{FormGroup-DoibujUR.js → FormGroup-QeEOGRIO.js} +1 -1
  40. package/dist/assets/{Google-BkswiX56.js → Google-B7LRQAsM.js} +3 -3
  41. package/dist/assets/{Grid-DmS931mb.js → Grid-BArO7d1G.js} +1 -1
  42. package/dist/assets/HelpOutline-It0-5Kn2.js +1 -0
  43. package/dist/assets/{Hidden-DFLNRBK7.js → Hidden-CpExY3Hv.js} +1 -1
  44. package/dist/assets/{InfoOutlined-BGl9NpGF.js → InfoOutlined-DEMaFK-w.js} +1 -1
  45. package/dist/assets/{InputAdornment-BfRAjWFP.js → InputAdornment-BFyVcV9g.js} +1 -1
  46. package/dist/assets/{InputLabel-snet_z2M.js → InputLabel-FW_WnrBG.js} +1 -1
  47. package/dist/assets/{LastPage-KoP1Fd4R.js → LastPage-BbNDF-1B.js} +1 -1
  48. package/dist/assets/{Launch-DaqmeZ7p.js → Launch-CM54bxPy.js} +1 -1
  49. package/dist/assets/{LaunchOutlined-D8_8q_U2.js → LaunchOutlined-DQOUx0IB.js} +1 -1
  50. package/dist/assets/{Link-ZwKMc2xW.js → Link-BLv1ybKR.js} +1 -1
  51. package/dist/assets/ListItemButton-BhIitXNK.js +1 -0
  52. package/dist/assets/{LoadingButton-DAYzECCB.js → LoadingButton-Do8QGr9D.js} +1 -1
  53. package/dist/assets/{LockIcon-CzOlJg7E.js → LockIcon-uGDnriV5.js} +1 -1
  54. package/dist/assets/{Loop-DdSi2a5X.js → Loop-DQX1T4wF.js} +1 -1
  55. package/dist/assets/MarkEmailRead-BdVitMKq.js +1 -0
  56. package/dist/assets/{Menu-cPWOWdJv.js → Menu-B60nijwd.js} +1 -1
  57. package/dist/assets/{MoreHoriz-CCaXi0-D.js → MoreHoriz-Cwgb_ZWA.js} +1 -1
  58. package/dist/assets/MoreVert-6z9sYyBh.js +1 -0
  59. package/dist/assets/{OpenInNew-DhmdNIIA.js → OpenInNew-B7MVFrbE.js} +1 -1
  60. package/dist/assets/Pagination-C8kC-7d4.js +2 -0
  61. package/dist/assets/{PlayArrow-dbaJvP3i.js → PlayArrow-CyW2vtN8.js} +1 -1
  62. package/dist/assets/{QuestionMarkCircle-ClghFyf8.js → QuestionMarkCircle-Dkgs-LrD.js} +1 -1
  63. package/dist/assets/{RadioGroup-h39eYIOw.js → RadioGroup-F9HJgTgP.js} +1 -1
  64. package/dist/assets/{Search-Deg4mgEt.js → Search-Bm4BV5ff.js} +1 -1
  65. package/dist/assets/{Select-D8wgZEYi.js → Select-DN5ZDrhq.js} +2 -2
  66. package/dist/assets/{ServerLogo-C-IdWQab.js → ServerLogo-qj6BKZhH.js} +1 -1
  67. package/dist/assets/{Skeleton-DTHod0yi.js → Skeleton-BHxGQUwb.js} +4 -4
  68. package/dist/assets/{Slider-BGdMADx-.js → Slider-DZmSOFez.js} +1 -1
  69. package/dist/assets/{Stack-Cp3hYWEn.js → Stack-CcM0sATd.js} +1 -1
  70. package/dist/assets/{Stepper-BYg7nOyi.js → Stepper-VAkPR7Rp.js} +1 -1
  71. package/dist/assets/{TextField-COEnibZX.js → TextField-CVbbJh-y.js} +1 -1
  72. package/dist/assets/{Toolbar-gvJQuyml.js → Toolbar-DMWwm961.js} +1 -1
  73. package/dist/assets/{Verified-BYBUZULO.js → Verified-CracX5_0.js} +1 -1
  74. package/dist/assets/{ViewColumn-C-7sjz0Y.js → ViewColumn-cHwmzgaQ.js} +1 -1
  75. package/dist/assets/{ViewList-JViuspE8.js → ViewList-DEr3Y-iU.js} +1 -1
  76. package/dist/assets/access-control-DEaRRq7A.js +13 -0
  77. package/dist/assets/{actions-BvIgnlgP.js → actions-BaCBwrwa.js} +1 -1
  78. package/dist/assets/{add-component-core-CF3Wvpy3.js → add-component-core-CTd25DO_.js} +38 -38
  79. package/dist/assets/add-resource-BcsfLDaF.js +1 -0
  80. package/dist/assets/{addon-BN5Sfj4m.js → addon-B5M4Vtbg.js} +1 -1
  81. package/dist/assets/{analytics-jhEGduS7.js → analytics-DKUh0ZA1.js} +8 -8
  82. package/dist/assets/api-noKs5rUY.js +1 -0
  83. package/dist/assets/ar-2TonDRvZ.js +1 -0
  84. package/dist/assets/ar-j9K5GatZ.js +1 -0
  85. package/dist/assets/audit-logs-DEv30kSD.js +58 -0
  86. package/dist/assets/{base32-RJwtUwTG.js → base32-BbBkrI_s.js} +1 -1
  87. package/dist/assets/{bundle-avatar-CYj37kYo.js → bundle-avatar-DFcMZdHK.js} +1 -1
  88. package/dist/assets/{button-Bzg3GLCP.js → button-WHxIb92N.js} +1 -1
  89. package/dist/assets/{click-to-copy-BxqXxgUi.js → click-to-copy-DSLKklSI.js} +1 -1
  90. package/dist/assets/{complete-DkKqvq-n.js → complete-CAaHcOBS.js} +1 -1
  91. package/dist/assets/{component-CBSn0ylq.js → component-_5q7tWN6.js} +81 -81
  92. package/dist/assets/{config-W5zOORTl.js → config-COlGV3BW.js} +2 -2
  93. package/dist/assets/config-_6fNEXak.js +1 -0
  94. package/dist/assets/{config-navigation-acog9zxt.js → config-navigation-DdfU54Ga.js} +5 -5
  95. package/dist/assets/{confirm-BD8lcIjf.js → confirm-CPhW4Ln4.js} +1 -1
  96. package/dist/assets/{connect-DUt6GuMA.js → connect-CJYVrjZW.js} +1 -1
  97. package/dist/assets/{connect-Cau7HJrv.js → connect-CutE2j6W.js} +1 -1
  98. package/dist/assets/connect-to-ByrmSC7Q.js +54 -0
  99. package/dist/assets/{content-layout--Pzx1mcC.js → content-layout-NMxrW85n.js} +1 -1
  100. package/dist/assets/{dashboard-CIOwnQZx.js → dashboard-yyANkyH0.js} +9 -9
  101. package/dist/assets/de-B1aG8zWS.js +1 -0
  102. package/dist/assets/de-BVh3hwT3.js +1 -0
  103. package/dist/assets/{deprecate-D_97v-_E.js → deprecate-TLU2j5Nl.js} +1 -1
  104. package/dist/assets/{did-address-DgsfKQl1.js → did-address-qp4O986k.js} +1 -1
  105. package/dist/assets/{domain-zy-h52DT.js → domain-BobgkNRn.js} +1 -1
  106. package/dist/assets/{domain-list-tyAcumiG.js → domain-list-nelUcVaZ.js} +2 -2
  107. package/dist/assets/email-BmqNkTVh.js +18 -0
  108. package/dist/assets/emotion-cache.browser.esm-CRw46sQ7.js +1 -0
  109. package/dist/assets/es-B78wkrSg.js +1 -0
  110. package/dist/assets/es-BEwxvJ2s.js +1 -0
  111. package/dist/assets/{exchange-passport-DPiMkxjA.js → exchange-passport-YyjxxQGp.js} +1 -1
  112. package/dist/assets/{fallback-DUmnMg78.js → fallback-DpZp1UKo.js} +1 -1
  113. package/dist/assets/form-text-input-Dnp-THZ5.js +11 -0
  114. package/dist/assets/{format-error-D0C8Qna1.js → format-error-BvNwPRch.js} +1 -1
  115. package/dist/assets/fr-Cvy3dZN3.js +1 -0
  116. package/dist/assets/fr-CyBvbwlz.js +1 -0
  117. package/dist/assets/{fuel-CZZpMc32.js → fuel-DwAfHv3P.js} +1 -1
  118. package/dist/assets/{fullpage-ov1kRa00.js → fullpage-BFccehDH.js} +1 -1
  119. package/dist/assets/hi-CiLl3Zi6.js +1 -0
  120. package/dist/assets/hi-nvWOxhan.js +1 -0
  121. package/dist/assets/{home-gwd5aHrM.js → home-BF01oQMN.js} +1 -1
  122. package/dist/assets/id-Cl0lvxW7.js +1 -0
  123. package/dist/assets/id-FWMMrTxm.js +1 -0
  124. package/dist/assets/{iframe-BIzC7nPA.js → iframe-CGjP6x7t.js} +1 -1
  125. package/dist/assets/index-0R3zcGhj.js +126 -0
  126. package/dist/assets/{index-BcvXX_mO.js → index-4YjFb1t8.js} +1 -1
  127. package/dist/assets/{index-DcKMlzdo.js → index-B1jXhAXk.js} +1 -1
  128. package/dist/assets/{index-rOGdJKYL.js → index-B61Zk4zc.js} +1 -1
  129. package/dist/assets/{index-AfbTuUW5.js → index-B6rU6yZ1.js} +7 -7
  130. package/dist/assets/{index-C_0JNAm2.js → index-BAsIkYmI.js} +1 -1
  131. package/dist/assets/{index-Q7ZUJ_jr.js → index-BEmU10Y0.js} +11 -11
  132. package/dist/assets/index-BFsNvHHz.js +22 -0
  133. package/dist/assets/{index-BjLsHd9C.js → index-BHRFloRH.js} +1 -1
  134. package/dist/assets/index-BZ9M67Kd.js +5 -0
  135. package/dist/assets/{index-COU4Nu6y.js → index-BZKKn0ch.js} +1 -1
  136. package/dist/assets/{index-B-DC1bkM.js → index-BnLNgi5J.js} +1 -1
  137. package/dist/assets/{index-CES_wWCV.js → index-BowU-Rc8.js} +183 -183
  138. package/dist/assets/index-Br6smtqw.js +1 -0
  139. package/dist/assets/{index-bwXQ8Wpi.js → index-BxX33nUX.js} +14 -13
  140. package/dist/assets/{index-B8-zdW7s.js → index-C4-tvqA6.js} +5 -5
  141. package/dist/assets/{index-BqpKWYMh.js → index-C6bJ8C3n.js} +1 -1
  142. package/dist/assets/{index-BJmzQOKo.js → index-CDo-yvx8.js} +1 -1
  143. package/dist/assets/index-C_izWh42.js +11 -0
  144. package/dist/assets/{index-D8OsCndp.js → index-CxykcKWh.js} +1 -1
  145. package/dist/assets/{index-QTPBiLZh.js → index-D0Foc0Tz.js} +1 -1
  146. package/dist/assets/{index-BYSwxOyW.js → index-D5jbzTmg.js} +1 -1
  147. package/dist/assets/index-DH4lKXWs.js +11 -0
  148. package/dist/assets/{index-DsWS2z9f.js → index-DaCSO68v.js} +1 -1
  149. package/dist/assets/{index-XlLZRf68.js → index-DaRP45oo.js} +1 -1
  150. package/dist/assets/{index-Bv4e_rV5.js → index-DbC1wngE.js} +1 -1
  151. package/dist/assets/index-Dnw0yymR.js +1 -0
  152. package/dist/assets/{index-Wi2p68c2.js → index-DsX4E8f1.js} +1 -1
  153. package/dist/assets/{index-C2AukIic.js → index-DtHgjXc_.js} +1 -1
  154. package/dist/assets/{index-DS-kwJv8.js → index-DusV8FU1.js} +1 -1
  155. package/dist/assets/index-FWU8WNJ8.js +1 -0
  156. package/dist/assets/{index-BA1E4qQ4.js → index-LmZHdjQZ.js} +1 -1
  157. package/dist/assets/{index-CE4JYDnG.js → index-RHJlosGb.js} +4 -4
  158. package/dist/assets/index-_uCAkv_0.js +316 -0
  159. package/dist/assets/{index-CNybmfDH.js → index-dmc3Tzez.js} +1 -1
  160. package/dist/assets/{index.es-HA92kWdG.js → index.es-DjXtuSXa.js} +3 -3
  161. package/dist/assets/{invitation-B49_oImo.js → invitation-CitdNTlE.js} +1 -1
  162. package/dist/assets/{invite-V3Nbkyr9.js → invite-8bX-82iQ.js} +1 -1
  163. package/dist/assets/isEmail-DlDmj0fr.js +1 -0
  164. package/dist/assets/{issue-passport-BK_rmsMU.js → issue-passport-DlN6RZob.js} +1 -1
  165. package/dist/assets/{item-ChdkonTR.js → item-CKNXAp6H.js} +1 -1
  166. package/dist/assets/ja-Be6ZrJ3j.js +1 -0
  167. package/dist/assets/ja-Uy7OpVJX.js +1 -0
  168. package/dist/assets/{jss-plugin-props-sort.esm-DBVL9gMW.js → jss-plugin-props-sort.esm-DoSjjNR1.js} +5 -5
  169. package/dist/assets/ko-631_NPZL.js +1 -0
  170. package/dist/assets/ko-RAcT5Den.js +1 -0
  171. package/dist/assets/{launch-result-message-BAr02bV5.js → launch-result-message-JFKmiVbN.js} +1 -1
  172. package/dist/assets/{layout-bf8MnH7p.js → layout-DEXenHhy.js} +1 -1
  173. package/dist/assets/{list-header-BdXS3bwO.js → list-header-7vVYIW_T.js} +1 -1
  174. package/dist/assets/localization-DdE_yTeV.js +1 -0
  175. package/dist/assets/{log-CEafQKJ9.js → log-ZCJiZb-D.js} +1 -1
  176. package/dist/assets/{login-CEkmeGqM.js → login-64rLho-5.js} +1 -1
  177. package/dist/assets/{login-oauth-callback-BKsN-may.js → login-oauth-callback-nOgNHNCk.js} +1 -1
  178. package/dist/assets/logo-uploader-Cz1267Av.js +133 -0
  179. package/dist/assets/{lost-passport-BKV23uoE.js → lost-passport-DjJtlNVj.js} +3 -3
  180. package/dist/assets/{lottie-Bmh0Xil_.js → lottie-DoYE5XDB.js} +1 -1
  181. package/dist/assets/notifications-Cv1XH2yb.js +65 -0
  182. package/dist/assets/{open-window-BxfESFgZ.js → open-window-CN5TQ87C.js} +1 -1
  183. package/dist/assets/overview-kalRt_uR.js +12 -0
  184. package/dist/assets/{page-header-C6Www8xa.js → page-header-BmLNlOnD.js} +1 -1
  185. package/dist/assets/{permission-C0wbV6KF.js → permission-DUsbjffq.js} +1 -1
  186. package/dist/assets/{preferences-DgOndnl4.js → preferences-ZO1kLbOx.js} +1 -1
  187. package/dist/assets/pt-BlLvTTrm.js +1 -0
  188. package/dist/assets/pt-CTpkGCgP.js +1 -0
  189. package/dist/assets/publish-resource-B2rKe7a9.js +1 -0
  190. package/dist/assets/purify.es-Bq0E5Q3l.js +2 -0
  191. package/dist/assets/react-BTu1Y-_j.js +56 -0
  192. package/dist/assets/{redux-B8mroqAb.js → redux-CJ8S87pk.js} +1 -1
  193. package/dist/assets/refType-CT_vAXIZ.js +1 -0
  194. package/dist/assets/resource-dialog-D_8tTarn.js +4 -0
  195. package/dist/assets/ru-Culp1KLs.js +1 -0
  196. package/dist/assets/ru-sSBv7F2t.js +1 -0
  197. package/dist/assets/sdk-C3SAOjUt.js +1 -0
  198. package/dist/assets/{selector-B2UrJyEC.js → selector-Rhni_cbO.js} +3 -3
  199. package/dist/assets/session-4S4FY2oN.js +1 -0
  200. package/dist/assets/setup-BQ-DnQht.js +19 -0
  201. package/dist/assets/{shorten-label-C69K-2N4.js → shorten-label-8aKNnW15.js} +1 -1
  202. package/dist/assets/simple-select-CNSx0Qbg.js +1 -0
  203. package/dist/assets/{slicedToArray-Btbq_uXo.js → slicedToArray-vg-R5s0s.js} +2 -2
  204. package/dist/assets/{spaces-CKA3haGw.js → spaces-BcZSz_wm.js} +1 -1
  205. package/dist/assets/{start-E4q8KtSK.js → start-CqQHbsvY.js} +1 -1
  206. package/dist/assets/{step-actions-Dv65pQs7.js → step-actions-DV3o9hve.js} +1 -1
  207. package/dist/assets/{studio-C9Z81BQt.js → studio-D_pIJx8G.js} +1 -1
  208. package/dist/assets/{switch-control-Cct9SW8-.js → switch-control-C-X_dl1C.js} +1 -1
  209. package/dist/assets/th-Dqms8yb0.js +1 -0
  210. package/dist/assets/th-Dv20telW.js +1 -0
  211. package/dist/assets/{toUpper-DjVC4j_j.js → toUpper-CqfCm6FQ.js} +1 -1
  212. package/dist/assets/{transfer-W8UlEJt-.js → transfer-CSfZjjyt.js} +1 -1
  213. package/dist/assets/trim-CXCEOOfq.js +1 -0
  214. package/dist/assets/{uniqBy-BzzuWGYh.js → uniqBy--m6Xe_2K.js} +1 -1
  215. package/dist/assets/{unsubscribe-BkeOgqWI.js → unsubscribe-BJWyVFrT.js} +1 -1
  216. package/dist/assets/{url-join-BLh7jCrJ.js → url-join-CAnJBM33.js} +1 -1
  217. package/dist/assets/use-blocklet-info-for-connect-did-spaces-BWR6SXSQ.js +1 -0
  218. package/dist/assets/{use-mobile-BJoJTGF0.js → use-mobile-BBtcVjXr.js} +1 -1
  219. package/dist/assets/{useAsync-CvPpFYs-.js → useAsync-DTvP9Zxi.js} +1 -1
  220. package/dist/assets/{useFormControl-BXRE7Su9.js → useFormControl-CqDUGVwx.js} +1 -1
  221. package/dist/assets/{useLocalStorage-BJH73q2r.js → useLocalStorage-BSk8yrmI.js} +1 -1
  222. package/dist/assets/{useSetState-CJBhbXdV.js → useSetState-Dvi1U0Nw.js} +1 -1
  223. package/dist/assets/useSlot-CBvar7i-.js +1 -0
  224. package/dist/assets/{useSlotProps-Bo-Lx2a7.js → useSlotProps-BO61t83_.js} +1 -1
  225. package/dist/assets/useThemeProps-BVeww5NE.js +1 -0
  226. package/dist/assets/user-center-DxinbhvA.js +1 -0
  227. package/dist/assets/{user-sessions-9jxxDLYT.js → user-sessions-BGeFoCxv.js} +1 -1
  228. package/dist/assets/{util-ZHGnEGmF.js → util-DQZs28G6.js} +1 -1
  229. package/dist/assets/vi-B-VzHaKw.js +1 -0
  230. package/dist/assets/vi-DjcU4tKh.js +1 -0
  231. package/dist/assets/wrap-locale-B-fXOOcn.js +1 -0
  232. package/dist/assets/zh-DWYwLndz.js +1 -0
  233. package/dist/assets/zh-tw-3Ki06u1b.js +1 -0
  234. package/dist/assets/zh-tw-B7lbXLVn.js +1 -0
  235. package/dist/assets/zh-u8iElwOC.js +2 -0
  236. package/dist/index.html +1 -1
  237. package/dist/service-worker.js +1 -1
  238. package/package.json +30 -27
  239. package/api/util/get-dynamic-service-config.js +0 -48
  240. package/dist/assets/Edit-Cbvlvh2w.js +0 -11
  241. package/dist/assets/FormControl-vM9EJwp4.js +0 -1
  242. package/dist/assets/FormControlLabel-CS28YgVs.js +0 -1
  243. package/dist/assets/MoreVert-D4SS6MnA.js +0 -1
  244. package/dist/assets/Pagination-BXlUtx3B.js +0 -2
  245. package/dist/assets/access-control-BDg9FQV3.js +0 -13
  246. package/dist/assets/add-resource-DLKAe3re.js +0 -1
  247. package/dist/assets/api-JbjuY7JN.js +0 -1
  248. package/dist/assets/ar-BcsWe-M7.js +0 -1
  249. package/dist/assets/ar-rur8F6ox.js +0 -1
  250. package/dist/assets/audit-logs-Vn5iZ4P_.js +0 -58
  251. package/dist/assets/config-ONP_4X_B.js +0 -1
  252. package/dist/assets/connect-to-GhSR8jRw.js +0 -54
  253. package/dist/assets/de-C-5DrcsF.js +0 -1
  254. package/dist/assets/de-f8XZAb4q.js +0 -1
  255. package/dist/assets/email-BINRPUSY.js +0 -18
  256. package/dist/assets/emotion-cache.browser.esm-ByukGais.js +0 -1
  257. package/dist/assets/es-CDmziQ2d.js +0 -1
  258. package/dist/assets/es-Dkw0SgdE.js +0 -1
  259. package/dist/assets/fr-CutjrzQz.js +0 -1
  260. package/dist/assets/fr-RdOP2uWC.js +0 -1
  261. package/dist/assets/hi-BwtTylyX.js +0 -1
  262. package/dist/assets/hi-V6iw7v5V.js +0 -1
  263. package/dist/assets/id-CeB6Ugb-.js +0 -1
  264. package/dist/assets/id-Dz8dfVhg.js +0 -1
  265. package/dist/assets/index-BHXHtIJm.js +0 -126
  266. package/dist/assets/index-CXg0jLCN.js +0 -11
  267. package/dist/assets/index-DW7dwoqE.js +0 -11
  268. package/dist/assets/index-DmdwpBJN.js +0 -261
  269. package/dist/assets/index-DqHzmyne.js +0 -68
  270. package/dist/assets/index-HqFqdQ4r.js +0 -1
  271. package/dist/assets/index-RVvYAb40.js +0 -1
  272. package/dist/assets/index-wVSweHe6.js +0 -1
  273. package/dist/assets/index.esm-S4QOHn5V.js +0 -1
  274. package/dist/assets/ja-BZrZ4ULY.js +0 -1
  275. package/dist/assets/ja-DlWywLev.js +0 -1
  276. package/dist/assets/ko-DLaz-pjP.js +0 -1
  277. package/dist/assets/ko-ESHUwy9c.js +0 -1
  278. package/dist/assets/localization-BlAk-2Dh.js +0 -1
  279. package/dist/assets/logo-uploader-DO_ePInN.js +0 -122
  280. package/dist/assets/mode-B2dWMeTO.js +0 -1
  281. package/dist/assets/notifications-CDn5GICo.js +0 -62
  282. package/dist/assets/overview-DvxryhGu.js +0 -12
  283. package/dist/assets/pt-BMSFPKAT.js +0 -1
  284. package/dist/assets/pt-CysEhQ_Z.js +0 -1
  285. package/dist/assets/publish-resource-BK8LfyYg.js +0 -1
  286. package/dist/assets/react-DWdAOKA_.js +0 -57
  287. package/dist/assets/resource-dialog-CxQ2RdqX.js +0 -57
  288. package/dist/assets/ru-2aTr2i-M.js +0 -1
  289. package/dist/assets/ru-C-IO4heq.js +0 -1
  290. package/dist/assets/sdk-BzFjs0zU.js +0 -1
  291. package/dist/assets/session-CPw6Z6tL.js +0 -1
  292. package/dist/assets/setup-C-eSKhTS.js +0 -19
  293. package/dist/assets/th-Bd6_ise5.js +0 -1
  294. package/dist/assets/th-D2W7tb3N.js +0 -1
  295. package/dist/assets/trim-pCqXvQz3.js +0 -1
  296. package/dist/assets/use-blocklet-info-for-connect-did-spaces-BfIvMuGO.js +0 -1
  297. package/dist/assets/useSlot-BnpRF9Wf.js +0 -1
  298. package/dist/assets/useThemeProps-NLTP4qET.js +0 -1
  299. package/dist/assets/user-center-DSwKYf1W.js +0 -1
  300. package/dist/assets/vi-BrQQz2Dk.js +0 -1
  301. package/dist/assets/vi-DTSqGMo-.js +0 -1
  302. package/dist/assets/wrap-locale-De5w1_ZO.js +0 -1
  303. package/dist/assets/zh-BUjxGa7K.js +0 -1
  304. package/dist/assets/zh-CT0fSzRS.js +0 -2
  305. package/dist/assets/zh-tw-GFcs7F29.js +0 -1
  306. package/dist/assets/zh-tw-i93Px0uV.js +0 -1
package/api/cache.js CHANGED
@@ -13,6 +13,12 @@ const sessionCacheDisabledUser = new LRU({
13
13
  maxAge: 86400 * 1000, // cache for 1 day
14
14
  });
15
15
 
16
+ const securityConfigCache = new LRU({
17
+ max: 5000, // 这里存储的是所有 blocklet 的缓存数据,需要设置的大一些
18
+ maxAge: 86400 * 1000, // 这部分数据不会频繁变动,设置为 1 天,将来可以通过页面进行性能优化设置
19
+ });
20
+
21
+ // FIXME: @zhanghan 将来需要缩短 cache key 的长度
16
22
  const keyFns = {
17
23
  node() {
18
24
  return md5('nodeState');
@@ -35,6 +41,9 @@ const keyFns = {
35
41
  sessionCacheDisabledUser(did) {
36
42
  return md5(`sessionCacheDisabledUser:${did}`);
37
43
  },
44
+ securityConfig(did, url) {
45
+ return [md5(['securityConfig', did].join(':')), url ? md5(url) : undefined].filter(Boolean).join(':');
46
+ },
38
47
  };
39
48
 
40
49
  cache.getNodeInfo = async ({ node }) => {
@@ -129,6 +138,36 @@ cache.sessionCacheDisabledUser = {
129
138
  },
130
139
  };
131
140
 
141
+ cache.getSecurityConfig = async ({ did, url, force = false, getDataFn } = {}) => {
142
+ if (!did || url === undefined) {
143
+ return null;
144
+ }
145
+ const cacheKey = cache.keyFns.securityConfig(did, url);
146
+ if (!force) {
147
+ const exist = securityConfigCache.get(cacheKey);
148
+ if (exist) {
149
+ return exist;
150
+ }
151
+ }
152
+
153
+ const result = await getDataFn();
154
+ if (result) {
155
+ securityConfigCache.set(cacheKey, result);
156
+ }
157
+ return result;
158
+ };
159
+ cache.removeSecurityConfig = ({ did } = {}) => {
160
+ if (!did) {
161
+ return;
162
+ }
163
+ const prefix = cache.keyFns.securityConfig(did);
164
+ securityConfigCache.forEach((value, key) => {
165
+ if (key.startsWith(prefix)) {
166
+ securityConfigCache.del(key);
167
+ }
168
+ });
169
+ };
170
+
132
171
  cache.keyFns = keyFns;
133
172
 
134
173
  module.exports = cache;
package/api/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  const http = require('http');
2
2
  const get = require('lodash/get');
3
+ const omitBy = require('lodash/omitBy');
4
+ const isUndefined = require('lodash/isUndefined');
3
5
  const morgan = require('morgan');
4
6
  const express = require('express');
5
7
  const dayjs = require('@abtnode/util/lib/dayjs');
@@ -11,6 +13,7 @@ const bodyParser = require('body-parser');
11
13
  const httpProxy = require('@arcblock/http-proxy');
12
14
  const { minimatch } = require('minimatch');
13
15
  const { joinURL } = require('ufo');
16
+ const helmet = require('helmet');
14
17
 
15
18
  const { WELLKNOWN_SERVICE_PATH_PREFIX, EVENTS, MAX_UPLOAD_FILE_SIZE } = require('@abtnode/constant');
16
19
  const {
@@ -23,6 +26,14 @@ const {
23
26
  const { getAppOgCacheDir } = require('@abtnode/util/lib/blocklet');
24
27
  const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
25
28
  const createInvite = require('@abtnode/auth/lib/invitation');
29
+ const {
30
+ patchResponseHeader,
31
+ DEFAULT_HELMET_CONFIG,
32
+ cleanConfigOverride,
33
+ keepConfigOverride,
34
+ patchCors,
35
+ } = require('@abtnode/util/lib/security');
36
+ const { DEFAULT_CORS_CONFIG } = require('@abtnode/util/lib/cors');
26
37
  const eventHub =
27
38
  process.env.NODE_ENV === 'test' ? require('@arcblock/event-hub/single') : require('@arcblock/event-hub');
28
39
 
@@ -122,6 +133,53 @@ module.exports = function createServer(node, serverOptions = {}) {
122
133
  proxyReq.write(req.rawBody);
123
134
  }
124
135
  });
136
+ const SECURITY_HEADER_MAP = {
137
+ contentSecurityPolicy: 'content-security-policy',
138
+ referrerPolicy: 'referrer-policy',
139
+ xFrameOptions: 'x-frame-options',
140
+ xPoweredBy: 'x-powered-by',
141
+ xXssProtection: 'x-xss-protection',
142
+ };
143
+ const CORS_HEADER_MAP = {
144
+ origin: 'access-control-allow-origin',
145
+ methods: 'access-control-allow-methods',
146
+ allowedHeaders: 'access-control-allow-headers',
147
+ exposedHeaders: 'access-control-expose-headers',
148
+ credentials: 'access-control-allow-credentials',
149
+ maxAge: 'access-control-max-age',
150
+ optionsSuccessStatus: 'access-control-allow-status',
151
+ preflightContinue: 'access-control-allow-preflight',
152
+ };
153
+
154
+ // NOTICE: !!! 注意这里最好不要有异步的函数,否则对 proxyRes 的处理可能不会被正确响应
155
+ // eslint-disable-next-line no-unused-vars
156
+ proxy.on('proxyRes', (proxyRes, req, res) => {
157
+ const securityConfig = req?.responseHeaderPolicyConfig;
158
+ if (securityConfig) {
159
+ const securityHeaderOverrideConfig = keepConfigOverride(
160
+ securityConfig?.responseHeaderPolicy?.securityHeader || {}
161
+ );
162
+ const corsOverrideConfig = keepConfigOverride(securityConfig?.responseHeaderPolicy?.cors || {});
163
+
164
+ for (const configKey of Object.keys(securityHeaderOverrideConfig)) {
165
+ if (!securityHeaderOverrideConfig[configKey]) {
166
+ const headerKey = SECURITY_HEADER_MAP[configKey];
167
+ if (isUndefined(req.get(headerKey))) {
168
+ delete proxyRes.headers[headerKey];
169
+ }
170
+ }
171
+ }
172
+
173
+ for (const configKey of Object.keys(corsOverrideConfig)) {
174
+ if (!corsOverrideConfig[configKey]) {
175
+ const headerKey = CORS_HEADER_MAP[configKey];
176
+ if (isUndefined(req.get(headerKey))) {
177
+ delete proxyRes.headers[headerKey];
178
+ }
179
+ }
180
+ }
181
+ }
182
+ });
125
183
 
126
184
  proxy.on('proxyRes', (proxyRes, req, res) => {
127
185
  const now = Date.now();
@@ -163,6 +221,11 @@ module.exports = function createServer(node, serverOptions = {}) {
163
221
  }
164
222
  });
165
223
  });
224
+ eventHub.on(BlockletEvents.securityConfigUpdated, ({ did }) => {
225
+ // 检测到安全配置更新后,需要批量删除指定前缀的 cache(会包含整个 blocklet 所有的 security cache)
226
+ logger.info('blocklet securityConfig update', { did, pid: process.pid });
227
+ cache.removeSecurityConfig({ did });
228
+ });
166
229
  eventHub.on(EVENTS.NODE_UPDATED, () => {
167
230
  logger.info('node update', { pid: process.pid });
168
231
  cache.del(cache.keyFns.node());
@@ -193,6 +256,42 @@ module.exports = function createServer(node, serverOptions = {}) {
193
256
  });
194
257
  });
195
258
 
259
+ async function wrapHelmet({ req, res, securityConfig, blocklet }, next) {
260
+ let config = securityConfig?.responseHeaderPolicy?.securityHeader || {};
261
+ config = cleanConfigOverride(config, req);
262
+
263
+ config = await patchResponseHeader(config, { node, blocklet });
264
+
265
+ helmet({
266
+ ...DEFAULT_HELMET_CONFIG,
267
+ ...omitBy(config, isUndefined),
268
+ })(req, res, next);
269
+ }
270
+
271
+ function wrapCors({ req, res, securityConfig, blocklet }, next) {
272
+ cors(async (_req, callback) => {
273
+ let config = securityConfig?.responseHeaderPolicy?.cors || {};
274
+ config = await patchCors(config, { node, blocklet });
275
+ config = cleanConfigOverride(config, req);
276
+
277
+ // HACK: 如果是 * ,需要转换为字符串来使用
278
+ if (config.origin?.join('') === '*') {
279
+ config.origin = '*';
280
+ }
281
+ if (config.allowedHeaders?.join('') === '*') {
282
+ config.allowedHeaders = '*';
283
+ }
284
+ if (config.exposedHeaders?.join('') === '*') {
285
+ config.exposedHeaders = '*';
286
+ }
287
+
288
+ callback(null, {
289
+ ...DEFAULT_CORS_CONFIG,
290
+ ...omitBy(config, isUndefined),
291
+ });
292
+ })(req, res, next);
293
+ }
294
+
196
295
  // Http server
197
296
  const server = express();
198
297
  const maxUploadSize = Number(process.env.MAX_UPLOAD_FILE_SIZE) || MAX_UPLOAD_FILE_SIZE;
@@ -205,8 +304,8 @@ module.exports = function createServer(node, serverOptions = {}) {
205
304
  },
206
305
  };
207
306
 
307
+ // NOTICE: we need to trust proxy to get real ip address
208
308
  server.set('trust proxy', 'loopback');
209
- server.disable('x-powered-by');
210
309
 
211
310
  server.use(cookieParser());
212
311
 
@@ -220,15 +319,34 @@ module.exports = function createServer(node, serverOptions = {}) {
220
319
  server.use(bodyParser.urlencoded({ extended: true, limit: `${maxUploadSize}mb`, verify }));
221
320
 
222
321
  // NOTE: will be overwrite by Blocklet Server in production
223
- server.use(cors());
224
322
 
225
323
  // Shared util functions on current request
226
324
  server.use((req, res, next) => {
325
+ // NOTICE: 增加了 req 上的公用函数,比如 req.getBlocklet
227
326
  attachSharedUtils({ node, req, options });
228
327
  StaticService.attachUtils({ req, res, proxy });
229
328
  next();
230
329
  });
231
330
 
331
+ // 此处逻辑会为 service 和 blocklet 都增加安全相关的 header 配置
332
+ server.use(async (req, res, next) => {
333
+ const did = req.getBlockletDid();
334
+ // NOTICE: 非 blocklet 的请求也会经过这里,需要直接放行
335
+ if (!did) {
336
+ next();
337
+ return;
338
+ }
339
+ const blocklet = await req.getBlocklet({ attachRuntimeInfo: true });
340
+ const { accessPolicyConfig, responseHeaderPolicyConfig } = await req.getSecurityConfig();
341
+
342
+ req.accessPolicyConfig = accessPolicyConfig;
343
+ req.responseHeaderPolicyConfig = responseHeaderPolicyConfig;
344
+
345
+ wrapHelmet({ req, res, securityConfig: responseHeaderPolicyConfig, blocklet }, () => {
346
+ wrapCors({ req, res, securityConfig: responseHeaderPolicyConfig, blocklet }, next);
347
+ });
348
+ });
349
+
232
350
  /* istanbul ignore if */
233
351
  if (isProduction) {
234
352
  morgan.token('x-request-id', (req) => req.headers['x-request-id'] || '-');
@@ -413,6 +531,7 @@ module.exports = function createServer(node, serverOptions = {}) {
413
531
  req.target = target; // for internal use
414
532
  imageService.processImage(req, res);
415
533
  } else {
534
+ // NOTICE: 此处已经不需要再添加一次 header 了,在上面的中间件中会一起处理
416
535
  proxy.safeWeb(req, res, { target, headers });
417
536
  }
418
537
  } else {
package/api/libs/api.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { default: axios } = require('axios');
2
2
 
3
- axios.defaults.timeout = 10 * 1000; // 超时时间设为10s
4
-
5
- const api = axios.create();
3
+ const api = axios.create({
4
+ timeout: 10 * 1000,
5
+ });
6
6
 
7
7
  module.exports = { api };
@@ -15,9 +15,8 @@ const {
15
15
  NODE_SERVICES,
16
16
  ROLES,
17
17
  WELLKNOWN_SERVICE_PATH_PREFIX,
18
- WHO_CAN_ACCESS,
19
- WHO_CAN_ACCESS_PREFIX_ROLES,
20
18
  MAIN_CHAIN_ENDPOINT,
19
+ SECURITY_RULE_DEFAULT_ID,
21
20
  } = require('@abtnode/constant');
22
21
  const {
23
22
  validatePassport,
@@ -35,7 +34,6 @@ const { fromAppDid } = require('@arcblock/did-ext');
35
34
  const { LOGIN_PROVIDER, BLOCKLET_APP_SPACE_REQUIREMENT, DID_SPACES } = require('@blocklet/constant');
36
35
  const createTranslator = require('@abtnode/util/lib/translate');
37
36
  const {
38
- getRolesFromAuthConfig,
39
37
  getBlockletAppIdList,
40
38
  forEachBlockletSync,
41
39
  getAppName,
@@ -47,7 +45,7 @@ const { getDidSpacesInfoByClaims, silentAuthorizationInConnect } = require('@abt
47
45
  const getRequestIP = require('@abtnode/util/lib/get-request-ip');
48
46
 
49
47
  const logger = require('../logger')('connect');
50
- const { isInvitedUserOnly, createTokenFn, getDidConnectVersion } = require('../../util');
48
+ const { checkInvitedUserOnly, createTokenFn, getDidConnectVersion } = require('../../util');
51
49
  const { transferPassport, PASSPORT_VC_TYPES } = require('../auth/utils');
52
50
  const { migrateAccount, declareAccount } = require('../../services/oauth');
53
51
  const { getKycClaims, verifyKycClaims, getPassportVc, isProfileUrlSupported, getProfileItems } = require('../kyc');
@@ -94,18 +92,13 @@ const getRoleFromVC = async ({ vc, node, locale, blocklet, teamDid, sourceAppPid
94
92
  return role;
95
93
  };
96
94
 
97
- const validateRole = async ({ role, authConfig, locale, node, teamDid }) => {
98
- if (authConfig.whoCanAccess === WHO_CAN_ACCESS.OWNER && role !== ROLES.OWNER) {
99
- throw new Error(
100
- {
101
- zh: '你不是该应用的所有者',
102
- en: 'You are not the owner of this application',
103
- }[locale]
104
- );
105
- }
95
+ const validateRole = async ({ role, securityConfig, locale, node, teamDid }) => {
96
+ const accessRoles = securityConfig?.accessPolicy?.roles ?? null;
97
+ const accessRevert = securityConfig?.accessPolicy?.revert ?? false;
106
98
 
107
99
  const roleList = await node.getRoles({ teamDid });
108
100
  if (!roleList.some((x) => x.name === role)) {
101
+ // 事实上,这里表示的是通行证已经被删除了,也就是这个 role 不存在了
109
102
  throw new Error(
110
103
  {
111
104
  zh: '通行证已被应用撤销',
@@ -114,17 +107,19 @@ const validateRole = async ({ role, authConfig, locale, node, teamDid }) => {
114
107
  );
115
108
  }
116
109
 
117
- if (authConfig.whoCanAccess && authConfig.whoCanAccess.startsWith(WHO_CAN_ACCESS_PREFIX_ROLES)) {
118
- const roles = getRolesFromAuthConfig(authConfig);
119
- if (!roles.includes(role)) {
120
- const list = roleList.filter((x) => roles.some((y) => y === x.name)).map((x) => x.title);
121
- throw new Error(
122
- {
123
- zh: `请使用 ${list.join(' ')} 通行证登录`,
124
- en: `Please use ${list.join(' or ')} passport to login`,
125
- }[locale]
126
- );
127
- }
110
+ if (accessRoles === null && accessRevert === false) {
111
+ return;
112
+ }
113
+
114
+ const validRoles = accessRevert ? (roleList || []).filter((x) => !accessRoles.includes(x.name)) : accessRoles;
115
+ if (!validRoles.includes(role)) {
116
+ const roleTitleList = (roleList || []).filter((x) => validRoles.some((y) => y === x.name)).map((x) => x.title);
117
+ throw new Error(
118
+ {
119
+ zh: `请使用 ${roleTitleList.join(' 或 ')} 通行证登录`,
120
+ en: `Please use ${roleTitleList.join(' or ')} passport to login`,
121
+ }[locale]
122
+ );
128
123
  }
129
124
  };
130
125
 
@@ -164,12 +159,12 @@ module.exports = {
164
159
  * }} param0
165
160
  * @returns
166
161
  */
167
- onConnect: async ({ node, request, userDid, locale = 'en', passportId = '', componentId, action, baseUrl }) => {
162
+ onConnect: async ({ node, request, userDid, locale = 'en', passportId = '', action, baseUrl }) => {
168
163
  /**
169
164
  * @type {import('@abtnode/client').BlockletState}
170
165
  */
171
166
  const blocklet = await request.getBlocklet();
172
- const config = await request.getServiceConfig(NODE_SERVICES.AUTH, { componentId });
167
+ const { accessPolicyConfig } = await request.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
173
168
  const { did: teamDid, wallet: blockletWallet } = await request.getBlockletInfo();
174
169
  const sourceAppPid = getSourceAppPid(request);
175
170
 
@@ -195,13 +190,15 @@ module.exports = {
195
190
 
196
191
  if (action === 'login') {
197
192
  // passport claim
198
- const [invitedUserOnly] = config ? await isInvitedUserOnly(config, node, teamDid) : [false];
193
+ const isInvitedUserOnly = accessPolicyConfig
194
+ ? await checkInvitedUserOnly(accessPolicyConfig, node, teamDid)
195
+ : [false];
199
196
  const passportClaim = {
200
197
  type: 'verifiableCredential',
201
198
  description: messages.requestPassport[locale],
202
199
  item: PASSPORT_VC_TYPES,
203
200
  trustedIssuers: await getTrustedIssuers(blocklet, { sourceAppPid }),
204
- optional: !invitedUserOnly,
201
+ optional: !isInvitedUserOnly,
205
202
  claimUrl: getPassportClaimUrl(baseUrl),
206
203
  };
207
204
  if (passportId) {
@@ -291,7 +288,6 @@ module.exports = {
291
288
  claims,
292
289
  baseUrl,
293
290
  createSessionToken,
294
- componentId,
295
291
  action,
296
292
  visitorId,
297
293
  inviter,
@@ -312,11 +308,10 @@ module.exports = {
312
308
  const realPk = currentUser?.pk || userPk;
313
309
 
314
310
  // Get auth config
315
- const authConfig = (await request.getServiceConfig(NODE_SERVICES.AUTH, { componentId })) || {};
311
+ const { accessPolicyConfig } = await request.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
316
312
 
317
313
  let vc;
318
314
  let nftState;
319
- let invitedUserOnly = false;
320
315
  let defaultRole = ROLES.GUEST;
321
316
  let defaultTtl = 0;
322
317
  let defaultTtlPolicy = 'never';
@@ -336,8 +331,13 @@ module.exports = {
336
331
  locale,
337
332
  trustedIssuers: await getTrustedIssuers(blocklet, { sourceAppPid }),
338
333
  });
339
- [invitedUserOnly, defaultRole, issuePassport] = await isInvitedUserOnly(authConfig, node, teamDid);
340
- if (invitedUserOnly && !vc) {
334
+ const isInvitedUserOnly = await checkInvitedUserOnly(accessPolicyConfig, node, teamDid);
335
+ const userCount = await node.getUsersCount({ teamDid });
336
+ if (userCount === 0) {
337
+ defaultRole = ROLES.OWNER;
338
+ issuePassport = true;
339
+ }
340
+ if (isInvitedUserOnly && !vc) {
341
341
  throw new Error(messages.missingPassport[locale]);
342
342
  }
343
343
 
@@ -421,7 +421,7 @@ module.exports = {
421
421
 
422
422
  // Get role
423
423
  const role = await getRoleFromVC({ vc, node, locale, blocklet, teamDid, sourceAppPid });
424
- await validateRole({ role, authConfig, locale, node, teamDid });
424
+ await validateRole({ role, securityConfig: accessPolicyConfig, locale, node, teamDid });
425
425
 
426
426
  checkAppOwner({ role, blocklet, userDid, locale });
427
427
 
@@ -711,8 +711,8 @@ module.exports = {
711
711
  throw new Error(messages.userMismatch[locale]);
712
712
  }
713
713
 
714
- const config = await request.getServiceConfig(NODE_SERVICES.AUTH);
715
- if (get(config, 'allowSwitchProfile', true) === false) {
714
+ const serviceConfig = await request.getServiceConfig(NODE_SERVICES.AUTH);
715
+ if (get(serviceConfig, 'allowSwitchProfile', true) === false) {
716
716
  throw new Error(messages.actionForbidden[locale]);
717
717
  }
718
718
 
@@ -823,7 +823,7 @@ module.exports = {
823
823
  },
824
824
 
825
825
  switchPassport: {
826
- onConnect: async ({ node, request, locale, userDid, previousUserDid, componentId, baseUrl }) => {
826
+ onConnect: async ({ node, request, locale, userDid, previousUserDid, baseUrl }) => {
827
827
  if (userDid && previousUserDid && userDid !== previousUserDid) {
828
828
  throw new Error(messages.userMismatch[locale]);
829
829
  }
@@ -847,12 +847,8 @@ module.exports = {
847
847
  throw new Error(messages.notAuthorized[locale]);
848
848
  }
849
849
 
850
- const config = await request.getServiceConfig(NODE_SERVICES.AUTH, { componentId });
851
- // FIXME: @zhanghan blocklet-service 的页面中,无法提供 componentId,暂时只能默认不允许切换到 no-passport
852
- let invitedUserOnly = true;
853
- if (config) {
854
- [invitedUserOnly] = await isInvitedUserOnly(config, node, teamDid);
855
- }
850
+ const { accessPolicyConfig } = await request.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
851
+ const isInvitedUserOnly = await checkInvitedUserOnly(accessPolicyConfig, node, teamDid);
856
852
 
857
853
  const blocklet = await request.getBlocklet();
858
854
  const sourceAppPid = getSourceAppPid(request);
@@ -863,7 +859,7 @@ module.exports = {
863
859
  description: messages.requestPassport[locale],
864
860
  item: PASSPORT_VC_TYPES,
865
861
  trustedIssuers: await getTrustedIssuers(blocklet, { sourceAppPid }),
866
- optional: !invitedUserOnly,
862
+ optional: !isInvitedUserOnly,
867
863
  claimUrl: getPassportClaimUrl(baseUrl),
868
864
  },
869
865
  };
@@ -876,7 +872,6 @@ module.exports = {
876
872
  verifiableCredential,
877
873
  userDid,
878
874
  createSessionToken,
879
- componentId,
880
875
  sourceAppPid,
881
876
  provider,
882
877
  }) => {
@@ -901,7 +896,7 @@ module.exports = {
901
896
  }
902
897
 
903
898
  // Get auth config
904
- const authConfig = (await request.getServiceConfig(NODE_SERVICES.AUTH, { componentId })) || {};
899
+ const { accessPolicyConfig } = await request.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
905
900
 
906
901
  // Get passport vc
907
902
  const vc = await getPassportVc({
@@ -911,13 +906,9 @@ module.exports = {
911
906
  trustedIssuers: await getTrustedIssuers(blocklet, { sourceAppPid }),
912
907
  });
913
908
 
914
- // FIXME: @zhanghan 在 blocklet-service 的页面中,无法提供 componentId,暂时只能默认不允许切换到 no-passport
915
909
  // Validate passport required
916
- let invitedUserOnly = true;
917
- if (authConfig) {
918
- [invitedUserOnly] = await isInvitedUserOnly(authConfig, node, teamDid);
919
- }
920
- if (invitedUserOnly && !vc) {
910
+ const isInvitedUserOnly = await checkInvitedUserOnly(accessPolicyConfig, node, teamDid);
911
+ if (isInvitedUserOnly && !vc) {
921
912
  throw new Error(messages.missingPassport[locale]);
922
913
  }
923
914
 
@@ -929,7 +920,7 @@ module.exports = {
929
920
 
930
921
  // Get role
931
922
  const role = await getRoleFromVC({ vc, node, locale, blocklet, teamDid, sourceAppPid });
932
- await validateRole({ role, authConfig, locale, node, teamDid });
923
+ await validateRole({ role, securityConfig: accessPolicyConfig, locale, node, teamDid });
933
924
 
934
925
  checkAppOwner({ role, blocklet, userDid, locale });
935
926
 
package/api/libs/kyc.js CHANGED
@@ -4,6 +4,7 @@ const pick = require('lodash/pick');
4
4
  const trim = require('lodash/trim');
5
5
  const lowerCase = require('lodash/lowerCase');
6
6
  const semver = require('semver');
7
+ const { Hasher } = require('@ocap/mcrypto');
7
8
  const { LOGIN_PROVIDER } = require('@blocklet/constant');
8
9
  const { messages, getVCFromClaims } = require('@abtnode/auth/lib/auth');
9
10
  const { getPassportClaimUrl, getKycAcquireUrl } = require('@abtnode/auth/lib/passport');
@@ -144,6 +145,10 @@ async function getKycClaims(blocklet, user, locale, baseUrl, sourceAppPid) {
144
145
  acquireUrl: getKycAcquireUrl(baseUrl, '', 'email'),
145
146
  claimUrl: getPassportClaimUrl(baseUrl, '', 'email'),
146
147
  };
148
+ if (user?.email) {
149
+ emailKycClaim.tag = Hasher.SHA3.hash256(user.email);
150
+ emailKycClaim.description += `: ${user.email}`;
151
+ }
147
152
  claims.emailKyc = ['verifiableCredential', emailKycClaim];
148
153
  }
149
154
 
@@ -158,6 +163,10 @@ async function getKycClaims(blocklet, user, locale, baseUrl, sourceAppPid) {
158
163
  acquireUrl: getKycAcquireUrl(baseUrl, '', 'phone'),
159
164
  claimUrl: getPassportClaimUrl(baseUrl, '', 'phone'),
160
165
  };
166
+ if (user?.phone) {
167
+ phoneKycClaim.tag = Hasher.SHA3.hash256(user.phone);
168
+ phoneKycClaim.description += `: ${user.phone}`;
169
+ }
161
170
  claims.phoneKyc = ['verifiableCredential', phoneKycClaim];
162
171
  }
163
172
 
@@ -3,6 +3,7 @@ const { sign } = require('@blocklet/sdk/lib/util/verify-sign');
3
3
  const getBlockletInfo = require('@blocklet/meta/lib/info');
4
4
  const { joinURL } = require('ufo');
5
5
  const pRetry = require('p-retry');
6
+ const { SIG_VERSION } = require('@blocklet/constant');
6
7
 
7
8
  const { api } = require('../api');
8
9
  const logger = require('../logger')('blocklet-services:notification');
@@ -22,6 +23,7 @@ async function sendPush(receiver, notification, { node, teamDid }) {
22
23
  }
23
24
 
24
25
  const pushKitConfig = {
26
+ // @see https://test.store.blocklet.dev/blocklets/z2qa6xfPH6zHq5AQjb2Qm5CfmpndyQsvZrTKH
25
27
  did: config.did || 'z2qa6xfPH6zHq5AQjb2Qm5CfmpndyQsvZrTKH',
26
28
  pushPath: config.pushPath || '/api/push',
27
29
  };
@@ -77,11 +79,21 @@ async function sendPush(receiver, notification, { node, teamDid }) {
77
79
  }
78
80
 
79
81
  const blockletInfo = getBlockletInfo(blocklet);
82
+ const iat = Math.floor(Date.now() / 1000);
83
+ const exp = iat + 60 * 5;
80
84
 
81
85
  const sig = sign(
82
86
  {
83
- targets: filterTargets,
84
- data: notification,
87
+ body: {
88
+ targets: filterTargets,
89
+ data: notification,
90
+ },
91
+ query: {},
92
+ method: 'post',
93
+ // NOTICE: 这里只能使用 push-kit 中接收到的 req.originalUrl 值,不能使用完整路径,否则会校验失败
94
+ url: pushKitConfig.pushPath,
95
+ iat,
96
+ exp,
85
97
  },
86
98
  { appSk: blockletInfo.wallet.secretKey }
87
99
  );
@@ -99,6 +111,9 @@ async function sendPush(receiver, notification, { node, teamDid }) {
99
111
  headers: {
100
112
  'x-blocklet-sig': sig,
101
113
  'x-blocklet-sig-pk': blockletInfo.wallet.publicKey,
114
+ 'x-blocklet-sig-iat': iat,
115
+ 'x-blocklet-sig-exp': exp,
116
+ 'x-blocklet-sig-version': SIG_VERSION.DEFAULT,
102
117
  },
103
118
  }
104
119
  ),
@@ -1,12 +1,44 @@
1
+ const { SIG_VERSION } = require('@blocklet/constant');
1
2
  const { verify } = require('@blocklet/sdk/lib/util/verify-sign');
3
+ const semver = require('semver');
4
+ const { parseURL } = require('ufo');
5
+
6
+ const legacyFn = (req) => {
7
+ const data = req?.body ?? {};
8
+ const params = req?.query ?? {};
9
+ return { data, params };
10
+ };
11
+
12
+ const latestFn = (req) => {
13
+ const data = {};
14
+ data.body = req.body ?? {};
15
+ data.query = req.params ?? {};
16
+ data.method = req.method.toLowerCase();
17
+ data.url = parseURL(req.originalUrl).pathname;
18
+ const now = Math.floor(Date.now() / 1000);
19
+ const iat = Number(req.get('x-component-sig-iat'));
20
+ const exp = Number(req.get('x-component-sig-exp'));
21
+ if (Number.isNaN(iat) || Number.isNaN(exp)) {
22
+ throw new Error('invalid sig');
23
+ }
24
+ if (exp < now) {
25
+ throw new Error('expired sig');
26
+ }
27
+ data.iat = iat;
28
+ data.exp = exp;
29
+ return data;
30
+ };
2
31
 
3
32
  const verifySig = async (req, res, next) => {
4
33
  try {
5
34
  const blocklet = await req.getBlocklet();
6
35
  const sig = req.get('x-blocklet-sig');
7
- const data = typeof req.body === 'undefined' ? {} : req.body;
8
- const params = typeof req.query === 'undefined' ? {} : req.query;
9
- const verified = verify({ data, params }, sig, {
36
+ const sigVersion = req.get('x-blocklet-sig-version');
37
+ // FIXME: @zhanghan 2024-11-30 需要移除这个旧的兼容(提升总体的安全性)
38
+ const getData = semver.gt(semver.coerce(sigVersion), semver.coerce(SIG_VERSION.V0)) ? latestFn : legacyFn;
39
+ const data = await getData(req);
40
+
41
+ const verified = verify(data, sig, {
10
42
  // NOTICE: blocklet-service 的运行环境中不包含以下环境变量,必须从 blocklet 信息中去获取并传递
11
43
  type: blocklet.environmentObj.BLOCKLET_APP_CHAIN_TYPE,
12
44
  appSk: blocklet.environmentObj.BLOCKLET_APP_SK,
@@ -7,7 +7,6 @@ const JWT = require('@arcblock/jwt');
7
7
  const { isValid } = require('@arcblock/did');
8
8
  const { joinURL } = require('ufo');
9
9
  const cors = require('cors');
10
- const handleInstanceInStore = require('@abtnode/core/lib/util/public-to-store');
11
10
  const { getPassportStatusEndpoint } = require('@abtnode/auth/lib/auth');
12
11
  const { createPassportVC, createPassport, createUserPassport } = require('@abtnode/auth/lib/passport');
13
12
 
@@ -227,18 +226,6 @@ module.exports = {
227
226
 
228
227
  await node.setBlockletInitialized({ did: blocklet.meta.did, owner: { did: userDid, pk } });
229
228
 
230
- // 调用 store 管理公开实例
231
- // 如果一个 blocklet 没有设置 公开实例,启动成功后不应给 store 发请求
232
- const { publicToStore } = blocklet.settings;
233
- if (publicToStore && !startError) {
234
- try {
235
- await handleInstanceInStore(blocklet, { userDid, publicToStore });
236
- } catch (error) {
237
- // 即使实例公开不成功,不能影响正常启动流程
238
- logger.error('failed to send blocklet logo', { did: blocklet.meta.did, error });
239
- }
240
- }
241
-
242
229
  // send notification to wallet
243
230
  const receiver = userDid;
244
231
  const token = JWT.sign(wallet.address, wallet.secretKey);
package/api/routes/env.js CHANGED
@@ -9,7 +9,7 @@ module.exports = {
9
9
  server.get(`**${WELLKNOWN_SERVICE_PATH_PREFIX}/api/env`, async (req, res) => {
10
10
  res.type('js');
11
11
 
12
- const [blockletInfo, blocklet, config, info] = await Promise.all([
12
+ const [blockletInfo, blocklet, serviceConfig, info] = await Promise.all([
13
13
  req.getBlockletInfo(),
14
14
  req.getBlocklet(),
15
15
  req.getServiceConfig(NODE_SERVICES.AUTH),
@@ -37,7 +37,7 @@ module.exports = {
37
37
  pathPrefix: "${pathPrefix}",
38
38
  apiPrefix: "${pathPrefix.replace(/\/+$/, '')}${WELLKNOWN_SERVICE_PATH_PREFIX}",
39
39
  ${groupPathPrefix ? `groupPathPrefix: "${groupPathPrefix}",` : ''}
40
- webWalletUrl: "${info.webWalletUrl || config.webWalletUrl || opts.webWalletUrl}",
40
+ webWalletUrl: "${info.webWalletUrl || serviceConfig.webWalletUrl || opts.webWalletUrl}",
41
41
  nftDomainUrl: "${info.nftDomainUrl || ''}",
42
42
  passportColor: "${passportColor}",
43
43
  serverDid: "${info.did}",