@abtnode/blocklet-services 1.16.42-beta-20250402-131159-7647e64d → 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 (239) hide show
  1. package/api/index.js +4 -1
  2. package/api/libs/connect/session.js +4 -6
  3. package/api/libs/jwt.js +3 -3
  4. package/api/libs/push-kit/index.js +5 -2
  5. package/api/routes/federated.js +12 -2
  6. package/api/routes/user-session.js +39 -18
  7. package/api/routes/user.js +7 -12
  8. package/api/services/auth/connect/invite.js +4 -6
  9. package/api/services/auth/connect/issue-passport.js +4 -6
  10. package/api/services/auth/session.js +5 -6
  11. package/api/services/notification/index.js +20 -16
  12. package/api/socket/channel/did.js +8 -8
  13. package/api/state/message.js +59 -0
  14. package/api/util/attach-shared-utils.js +1 -0
  15. package/api/util/user-util.js +5 -7
  16. package/dist/assets/{ArrowDropDown-B6RijoMg.js → ArrowDropDown-ptWD82T6.js} +1 -1
  17. package/dist/assets/{CheckCircle-Bme_BHSe.js → CheckCircle-Btm_ouu-.js} +1 -1
  18. package/dist/assets/{ChevronLeft-CDiNoyQS.js → ChevronLeft-Dlcukg5b.js} +1 -1
  19. package/dist/assets/{ChevronRight-DyMxK2ti.js → ChevronRight-Dum8C8k7.js} +1 -1
  20. package/dist/assets/{Community-CMFBTMi_.js → Community-BuDGbplJ.js} +1 -1
  21. package/dist/assets/{DeleteOutline-C5oIt-tc.js → DeleteOutline-qIhkqz9A.js} +1 -1
  22. package/dist/assets/{Done-uAJ8-whC.js → Done-CxsGHhW2.js} +1 -1
  23. package/dist/assets/{Download-CAwoUjYq.js → Download-DtSKdPMo.js} +1 -1
  24. package/dist/assets/{EditIcon-Bgmg6UE0.js → EditIcon-BOKrjkh4.js} +1 -1
  25. package/dist/assets/{Email-BphlAPta.js → Email-D1oAzxhZ.js} +1 -1
  26. package/dist/assets/{Error-J1wFafzM.js → Error-yZoplO-q.js} +1 -1
  27. package/dist/assets/{ExpandLess-B0AhRxh8.js → ExpandLess-DN5VsSyP.js} +1 -1
  28. package/dist/assets/{Google-blbcHt2R.js → Google-Drf-_CBl.js} +1 -1
  29. package/dist/assets/{Holiday-DKefG3Bb.js → Holiday-CGw5hZXz.js} +1 -1
  30. package/dist/assets/{InfoOutlined-BjH1JBg3.js → InfoOutlined-CLOzYFOV.js} +1 -1
  31. package/dist/assets/{Launch-DJqhcPtC.js → Launch-BtdPv0ms.js} +1 -1
  32. package/dist/assets/{LaunchOutlined-CzBae9mQ.js → LaunchOutlined-Bxfn3D1k.js} +1 -1
  33. package/dist/assets/{Location-BuaxMxu4.js → Location-BNMzVuhr.js} +1 -1
  34. package/dist/assets/{LockIcon-CQ1tExIY.js → LockIcon-D-N7I3eV.js} +1 -1
  35. package/dist/assets/{Meeting-Cs60QtvP.js → Meeting-CHDEMp94.js} +1 -1
  36. package/dist/assets/{MoreHoriz-Dd-9O1iw.js → MoreHoriz-Ecf_Y2c5.js} +1 -1
  37. package/dist/assets/{OffSick-DinPaelp.js → OffSick-s49E5S0C.js} +1 -1
  38. package/dist/assets/{Phone-BmouKMyi.js → Phone-B7KVJqdR.js} +1 -1
  39. package/dist/assets/{PlayArrow-BEPk9nzV.js → PlayArrow-C5Hul3eK.js} +1 -1
  40. package/dist/assets/{QuestionMarkCircle-Dt9XJWEe.js → QuestionMarkCircle-D9Nr1DvN.js} +1 -1
  41. package/dist/assets/{ServerLogo-B33ZRE5q.js → ServerLogo-CJ7KvDlS.js} +1 -1
  42. package/dist/assets/{Timezone-CyMhRxlx.js → Timezone-fKWN5g03.js} +1 -1
  43. package/dist/assets/TuneOutlined-CIVU5KTm.js +1 -0
  44. package/dist/assets/{ViewList-CNnrIxVS.js → ViewList-DQNBBLS5.js} +1 -1
  45. package/dist/assets/{WorkingRemotely-BP_VIHeM.js → WorkingRemotely-8AJSfiNI.js} +1 -1
  46. package/dist/assets/access-control-5GyLuYd7.js +14 -0
  47. package/dist/assets/{actions-pYJdaWX5.js → actions-BK1Ssw2h.js} +1 -1
  48. package/dist/assets/{add-component-core-CgEuYlWv.js → add-component-core-Bm9enQVM.js} +1 -1
  49. package/dist/assets/{add-resource-Dw_ZKqq3.js → add-resource-Cqmj5BBD.js} +1 -1
  50. package/dist/assets/{addon-BqlSMpSy.js → addon-Dfs1zul7.js} +1 -1
  51. package/dist/assets/advanced-MSBu-f81.js +49 -0
  52. package/dist/assets/api-DeTTY4rz.js +1 -0
  53. package/dist/assets/{appearance-DyZRbR6W.js → appearance-_saX27MM.js} +1 -1
  54. package/dist/assets/ar-Bd3GUoqC.js +3 -0
  55. package/dist/assets/{ar-CVzKLI4f.js → ar-DrRqcx2b.js} +1 -1
  56. package/dist/assets/{audit-logs-BFKcADf-.js → audit-logs-C8OHcyQY.js} +3 -3
  57. package/dist/assets/{base32-C0ClYUu9.js → base32-DY8fPTYx.js} +1 -1
  58. package/dist/assets/branding-CanOP0qb.js +40 -0
  59. package/dist/assets/branding-DelDZvig.js +50 -0
  60. package/dist/assets/{bundle-avatar-BYZp7KRE.js → bundle-avatar-CxGKqpL1.js} +1 -1
  61. package/dist/assets/button-GsH-bz74.js +1 -0
  62. package/dist/assets/{click-to-copy-BfRimSvL.js → click-to-copy-BuZpdwN0.js} +1 -1
  63. package/dist/assets/{complete-1MMVAc2H.js → complete-CIxsaCVT.js} +1 -1
  64. package/dist/assets/{component-BZKPS6he.js → component-vibwLNji.js} +102 -87
  65. package/dist/assets/{config-DRS6lRly.js → config-BbT0ik5t.js} +1 -1
  66. package/dist/assets/{config-DtYY5NrA.js → config-Bl-eQAj5.js} +1 -1
  67. package/dist/assets/{config-navigation-BHoOsyWp.js → config-navigation-Dw7tct52.js} +7 -7
  68. package/dist/assets/{config-space-DxdlQBdo.js → config-space-D3pvjnQx.js} +1 -1
  69. package/dist/assets/{confirm-C57Q7ZWM.js → confirm-BzL9LNyf.js} +1 -1
  70. package/dist/assets/{connect-PChwPX8g.js → connect-CzcOswsI.js} +1 -1
  71. package/dist/assets/{connect-p9koIBBk.js → connect-Czr8O47H.js} +1 -1
  72. package/dist/assets/{connect-to-QLfyUtYC.js → connect-to-LVtY3yeI.js} +1 -1
  73. package/dist/assets/{content-layout-7vu3yv_f.js → content-layout-CcLv-R_J.js} +1 -1
  74. package/dist/assets/dashboard-BuFzcMGR.js +213 -0
  75. package/dist/assets/de-4RuZHBym.js +3 -0
  76. package/dist/assets/{de-DIJPqt1Y.js → de-BRPos3d1.js} +1 -1
  77. package/dist/assets/{delete-confirm-L9JNVh3W.js → delete-confirm-Bg3_0xz8.js} +1 -1
  78. package/dist/assets/{did-address-Bz2Y86pP.js → did-address-Dn6n8fAo.js} +1 -1
  79. package/dist/assets/doc-board-bg-DWZHV9Ng.png +0 -0
  80. package/dist/assets/domain-C_0cRyXj.js +9 -0
  81. package/dist/assets/{domain-action-card-Bovam4dU.js → domain-action-card-B6WSK3W9.js} +2 -2
  82. package/dist/assets/domains-BQtz7ONz.js +1 -0
  83. package/dist/assets/{email-SVI5bjle.js → email-qq2sglAS.js} +1 -1
  84. package/dist/assets/{es-C5RqG0zA.js → es-D2rCdMgt.js} +1 -1
  85. package/dist/assets/es-DPG1emNh.js +3 -0
  86. package/dist/assets/{exchange-passport-B3N7KRar.js → exchange-passport-CfAHAVKI.js} +1 -1
  87. package/dist/assets/{fr-BHsPT43-.js → fr-DAFx50ef.js} +1 -1
  88. package/dist/assets/fr-u7MDLCDo.js +3 -0
  89. package/dist/assets/fuel-DVzKzmYw.js +32 -0
  90. package/dist/assets/{get-safe-url-CJRwqFgD.js → get-safe-url-CA3J0_99.js} +1 -1
  91. package/dist/assets/{get-safe-url-DLBNTOpr.js → get-safe-url-DnmtzIqo.js} +1 -1
  92. package/dist/assets/{hi-Bie09Alk.js → hi-CkD7b6N9.js} +1 -1
  93. package/dist/assets/{hi-CSSYN7n8.js → hi-DS9ZR9W2.js} +1 -1
  94. package/dist/assets/home--ykFBnb1.js +1 -0
  95. package/dist/assets/{id-IlcS05qm.js → id-BMWKdVei.js} +1 -1
  96. package/dist/assets/id-C459Zhwd.js +3 -0
  97. package/dist/assets/{iframe-DPBwIvsP.js → iframe-B5D34SYo.js} +1 -1
  98. package/dist/assets/{index-CAFqxbeJ.js → index-B1UWfhev.js} +3 -3
  99. package/dist/assets/{index-RuFDBiVt.js → index-B8T_6tqA.js} +1 -1
  100. package/dist/assets/{index-D_wVtHmh.js → index-BByO9801.js} +1 -1
  101. package/dist/assets/{index-DGkTgpZy.js → index-BDliasS9.js} +1 -1
  102. package/dist/assets/index-BPS0iHSZ.js +4 -0
  103. package/dist/assets/index-BQLZ0lsX.js +1 -0
  104. package/dist/assets/{index-DZAi-K_N.js → index-BWpwjp4L.js} +32 -32
  105. package/dist/assets/index-BqIq9Uma.js +138 -0
  106. package/dist/assets/{index-Bg3m8iJ-.js → index-C6eHDaxg.js} +11 -11
  107. package/dist/assets/{index-BMSA5TdD.js → index-CBhHQMgh.js} +1 -1
  108. package/dist/assets/{index-Db6WuAj_.js → index-CClhZ8rs.js} +1 -1
  109. package/dist/assets/index-CytYWl7a.js +113 -0
  110. package/dist/assets/{index-RSW2vc0s.js → index-D8CNdALX.js} +1 -1
  111. package/dist/assets/{index-B_pl8AF-.js → index-DOdTZRA4.js} +1 -1
  112. package/dist/assets/{index-bIuZaDHS.js → index-Da6LyIoG.js} +2 -2
  113. package/dist/assets/{index-Cdm81c0H.js → index-Dy3LPNyS.js} +26 -26
  114. package/dist/assets/{index-DAE7cdom.js → index-ItdGu4Wh.js} +1 -1
  115. package/dist/assets/{index-m8CaSxXx.js → index-J5kmwEca.js} +1 -1
  116. package/dist/assets/{index-fWGZM-oP.js → index-L3MBVAcg.js} +1 -1
  117. package/dist/assets/{index-Bhnq0cVQ.js → index-VUi6PKrJ.js} +1 -1
  118. package/dist/assets/{index-CLIxjSVZ.js → index-dCzPMsw6.js} +1 -1
  119. package/dist/assets/index-ndYC_y0r.js +15 -0
  120. package/dist/assets/{index-kAPvimmq.js → index-vxB3STPb.js} +2 -2
  121. package/dist/assets/{index-8I2oAbEz.js → index-y6Dw39ly.js} +9 -9
  122. package/dist/assets/{invitation-DG6QrvdE.js → invitation-Cp6DuOW5.js} +1 -1
  123. package/dist/assets/{invite-CYIssZ1G.js → invite-DjADjbzm.js} +1 -1
  124. package/dist/assets/{issue-passport-Cft19VvI.js → issue-passport-Bu5NvC_2.js} +1 -1
  125. package/dist/assets/{item-at_gI9OW.js → item-ClBhYYKW.js} +1 -1
  126. package/dist/assets/ja-B5tIV7r-.js +3 -0
  127. package/dist/assets/{ja-C2daM668.js → ja-D2jInSAT.js} +1 -1
  128. package/dist/assets/keyboard-arrow-down-rounded-DadBVmpO.js +1 -0
  129. package/dist/assets/{ko-Lni8u0p_.js → ko-BGB5KJZq.js} +1 -1
  130. package/dist/assets/ko-CL3JJCJN.js +3 -0
  131. package/dist/assets/landing-page-BfVl47YO.js +1 -0
  132. package/dist/assets/{launch-result-message-ByEG8r_7.js → launch-result-message-BP5yMmIB.js} +1 -1
  133. package/dist/assets/{layout-ChcSB0Y2.js → layout-D5G7Z8Ws.js} +1 -1
  134. package/dist/assets/{list-DcSgz3EU.js → list-CjtRvxdF.js} +7 -7
  135. package/dist/assets/{list-header-BmTDmRY0.js → list-header-Cip98Afo.js} +1 -1
  136. package/dist/assets/localization-Tn68766t.js +1 -0
  137. package/dist/assets/{log-D7ImQrI7.js → log-_cZt5s1j.js} +1 -1
  138. package/dist/assets/{login-B9xuIjhY.js → login-Bd9eibzl.js} +1 -1
  139. package/dist/assets/{login-oauth-callback-BoFezOw0.js → login-oauth-callback-Buv0sriC.js} +1 -1
  140. package/dist/assets/{logo-uploader-Bzpld3yG.js → logo-uploader-DGn3pkYl.js} +5 -4
  141. package/dist/assets/{lost-passport-j4coS07J.js → lost-passport-BplwQoPb.js} +1 -1
  142. package/dist/assets/omit-DYK_TtPQ.js +1 -0
  143. package/dist/assets/{open-window-B8cxsAbD.js → open-window-3TWqcI62.js} +1 -1
  144. package/dist/assets/overview-CJ3muOc6.js +84 -0
  145. package/dist/assets/{page-header-YN9FqnGT.js → page-header-FKKsPnE9.js} +1 -1
  146. package/dist/assets/{permission-CTDKdktZ.js → permission-Dd3ufGD-.js} +1 -1
  147. package/dist/assets/preferences-D4OSAVTW.js +1 -0
  148. package/dist/assets/profile-embed--1Je95gw.js +1 -0
  149. package/dist/assets/pt-CYRkKZmh.js +1 -0
  150. package/dist/assets/{pt-D6N4RLzf.js → pt-DY0Ku5W5.js} +1 -1
  151. package/dist/assets/publish-resource-B4kuEUIu.js +1 -0
  152. package/dist/assets/{react-beautiful-dnd.esm-CkNk1XBJ.js → react-beautiful-dnd.esm-DxmtDCVc.js} +1 -1
  153. package/dist/assets/{relative-time-BCARyhz6.js → relative-time-Bp0EO1aU.js} +1 -1
  154. package/dist/assets/{ru-D-xvMzxI.js → ru-Cv5vRo7s.js} +1 -1
  155. package/dist/assets/ru-Dzg-gLvu.js +1 -0
  156. package/dist/assets/runtime-DCHSigWq.js +1 -0
  157. package/dist/assets/sdk-B4tneH2b.js +1 -0
  158. package/dist/assets/security-Ba0U57n2.js +95 -0
  159. package/dist/assets/{session-BaYtKD4f.js → session-BXc0WNE7.js} +1 -1
  160. package/dist/assets/setup-bc5fgvzY.js +19 -0
  161. package/dist/assets/{shorten-label-DkFTGSoy.js → shorten-label-BcXnCxH2.js} +1 -1
  162. package/dist/assets/{simple-select-CqakAZFe.js → simple-select-D7qC2duk.js} +1 -1
  163. package/dist/assets/{slicedToArray-BuQur6Mi.js → slicedToArray-CG0jVe85.js} +2 -2
  164. package/dist/assets/{start-CdXw9NWC.js → start-kkjng8Di.js} +1 -1
  165. package/dist/assets/status-Bcehte3I.js +1 -0
  166. package/dist/assets/step-actions-CAn2VbnK.js +31 -0
  167. package/dist/assets/studio-Dnzc2A5y.js +6 -0
  168. package/dist/assets/{switch-control-CpOzvDua.js → switch-control-DZceCxwF.js} +1 -1
  169. package/dist/assets/th-CevmRMq6.js +1 -0
  170. package/dist/assets/{th-CycIQ910.js → th-D6oDBVGi.js} +1 -1
  171. package/dist/assets/{traffic-CvAD-wB3.js → traffic-BbJxF2T-.js} +4 -4
  172. package/dist/assets/{transfer-BSgBIknw.js → transfer-j5hCBx8d.js} +1 -1
  173. package/dist/assets/{unsubscribe-I8S6Tbwg.js → unsubscribe-DJgSmFME.js} +1 -1
  174. package/dist/assets/{use-mobile-CUT5hy9q.js → use-mobile-DNsgYi-4.js} +1 -1
  175. package/dist/assets/use-mobile-DVecy9Ks.js +1 -0
  176. package/dist/assets/{useAsync-Cq0wbMuR.js → useAsync-Bia14KO2.js} +1 -1
  177. package/dist/assets/{useAsyncRetry-BNLrNsx3.js → useAsyncRetry-C-QH3IsB.js} +1 -1
  178. package/dist/assets/{useLocalStorage-Cligjpwl.js → useLocalStorage-BQFZ73WZ.js} +1 -1
  179. package/dist/assets/{user-center-C1k0oYvY.js → user-center-BZ0ZkNAA.js} +1 -1
  180. package/dist/assets/{util-BFBz0dr8.js → util-C9Xcu_Dq.js} +1 -1
  181. package/dist/assets/{util-COcKIr8L.js → util-WwcocPP-.js} +1 -1
  182. package/dist/assets/{vendor-arcblock-krD2mwVA.js → vendor-arcblock-B7hyNlnQ.js} +34 -34
  183. package/dist/assets/{vendor-hooks-BdjOQw7q.js → vendor-hooks-DnflU2EL.js} +1 -1
  184. package/dist/assets/{vendor-mui-core-DxqV1NVn.js → vendor-mui-core-BL-xsBvI.js} +1 -1
  185. package/dist/assets/{vendor-mui-x-BjL1xCkk.js → vendor-mui-x-BmOE-0pQ.js} +1 -1
  186. package/dist/assets/{vendor-utils-BbDUMsIF.js → vendor-utils-Cs6ARqvU.js} +1 -1
  187. package/dist/assets/{vendor-ux-did-connect-YqGDzQ2U.js → vendor-ux-did-connect-CWUKGZcn.js} +32 -32
  188. package/dist/assets/{vi-BqnfnvFP.js → vi-BKKJMbW2.js} +1 -1
  189. package/dist/assets/vi-PQuaKyKY.js +1 -0
  190. package/dist/assets/wrap-locale-DyRnlWyZ.js +1 -0
  191. package/dist/assets/zh-BBkG8qYp.js +4 -0
  192. package/dist/assets/{zh-CHmwTyCg.js → zh-D4Lak9gZ.js} +1 -1
  193. package/dist/assets/{zh-tw-D6K-qXNE.js → zh-tw-B08rjgK3.js} +1 -1
  194. package/dist/assets/zh-tw-BHJNqYL0.js +3 -0
  195. package/dist/index.html +6 -6
  196. package/dist/service-worker.js +1 -1
  197. package/package.json +36 -35
  198. package/dist/assets/access-control-PfmU_lzC.js +0 -14
  199. package/dist/assets/analytics-DLD8w-rR.js +0 -11
  200. package/dist/assets/api-0KF6Hg7c.js +0 -1
  201. package/dist/assets/ar-HpV-sy4C.js +0 -3
  202. package/dist/assets/branding-8XaHoIBD.js +0 -40
  203. package/dist/assets/button-K0-gOTcS.js +0 -1
  204. package/dist/assets/dashboard-Di0Efjh1.js +0 -216
  205. package/dist/assets/de-zgFs6Kvs.js +0 -3
  206. package/dist/assets/domain-fVU92lIu.js +0 -9
  207. package/dist/assets/domains-Cs6tdpUa.js +0 -1
  208. package/dist/assets/es-CmwByMO0.js +0 -3
  209. package/dist/assets/form-text-input-Cp0lmtAk.js +0 -11
  210. package/dist/assets/fr-CLYepc9p.js +0 -3
  211. package/dist/assets/fuel-DT6O2ymR.js +0 -32
  212. package/dist/assets/home-CQ7SI4ml.js +0 -1
  213. package/dist/assets/id-C5CwopKG.js +0 -3
  214. package/dist/assets/index-B5HkvoQC.js +0 -4
  215. package/dist/assets/index-BYkIfvmH.js +0 -109
  216. package/dist/assets/index-BzblYn_P.js +0 -138
  217. package/dist/assets/index-C9qItKIC.js +0 -138
  218. package/dist/assets/index.esm-CWepf7I_.js +0 -1
  219. package/dist/assets/ja-BPVyKlMZ.js +0 -3
  220. package/dist/assets/ko-DGmHCGCI.js +0 -3
  221. package/dist/assets/landing-page-CXo1fefz.js +0 -1
  222. package/dist/assets/localization-DXf17X8p.js +0 -1
  223. package/dist/assets/omit-BXVmqD4a.js +0 -1
  224. package/dist/assets/overview-C9x4HKRi.js +0 -12
  225. package/dist/assets/preferences-DM6b-Vr4.js +0 -1
  226. package/dist/assets/profile-embed-8sjLgVfn.js +0 -1
  227. package/dist/assets/pt-u5ojPOFS.js +0 -1
  228. package/dist/assets/publish-resource-BJIce778.js +0 -1
  229. package/dist/assets/ru-DBl90RHJ.js +0 -1
  230. package/dist/assets/sdk-DbmS8LqQ.js +0 -1
  231. package/dist/assets/setup-BtUUdr-p.js +0 -19
  232. package/dist/assets/status-B6cew_GQ.js +0 -1
  233. package/dist/assets/step-actions-D-RgRm8H.js +0 -31
  234. package/dist/assets/studio-KYZUr4tT.js +0 -6
  235. package/dist/assets/th-CbjesoRG.js +0 -1
  236. package/dist/assets/vi-xat6Zv0n.js +0 -1
  237. package/dist/assets/wrap-locale-BCL-ID0T.js +0 -1
  238. package/dist/assets/zh-BgH3IZTD.js +0 -4
  239. package/dist/assets/zh-tw-UWzs9p3g.js +0 -3
package/api/index.js CHANGED
@@ -22,6 +22,7 @@ const {
22
22
  RESOURCE_PATTERN,
23
23
  } = require('@blocklet/constant');
24
24
  const { getAppOgCacheDir } = require('@abtnode/util/lib/blocklet');
25
+ const { ensureLocale } = require('@abtnode/util/lib/middlewares/ensure-locale');
25
26
  const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
26
27
  const createInvite = require('@abtnode/auth/lib/invitation');
27
28
  const { getStatusFromError } = require('@abtnode/util/lib/custom-error');
@@ -448,6 +449,8 @@ module.exports = function createServer(node, serverOptions = {}) {
448
449
  server.set('trust proxy', 'loopback');
449
450
 
450
451
  server.use(cookieParser());
452
+ // 此时没有执行 bodyParser,所以不使用 body 进行判断
453
+ server.use(ensureLocale({ methods: ['query', 'cookies'] }));
451
454
 
452
455
  // Shared util functions on current request
453
456
  server.use((req, res, next) => {
@@ -649,7 +652,7 @@ self.blocklet = {
649
652
  });
650
653
 
651
654
  // This must come after all proxied requests that begins with WELLKNOWN_SERVICE_PATH_PREFIX
652
- server.use(WELLKNOWN_SERVICE_PATH_PREFIX, bodyParser);
655
+ server.use(WELLKNOWN_SERVICE_PATH_PREFIX, bodyParser, ensureLocale({ force: true }));
653
656
 
654
657
  // Studio service
655
658
  StudioService.init(server, node);
@@ -47,6 +47,7 @@ const { getSourceAppPid, getLoginProvider } = require('@blocklet/sdk/lib/util/lo
47
47
  const { getDidSpacesInfoByClaims, silentAuthorizationInConnect } = require('@abtnode/auth/lib/util/spaces');
48
48
  const getRequestIP = require('@abtnode/util/lib/get-request-ip');
49
49
  const { PASSPORT_LOG_ACTION, PASSPORT_SOURCE, PASSPORT_STATUS } = require('@abtnode/constant');
50
+ const { getDeviceData } = require('@abtnode/util/lib/device');
50
51
 
51
52
  const logger = require('../logger')('connect');
52
53
  const { createTokenFn, getDidConnectVersion } = require('../../util');
@@ -595,11 +596,10 @@ module.exports = {
595
596
  );
596
597
  }
597
598
  const lastLoginIp = getRequestIP(request);
598
- const walletDeviceMessageToken = request.get('wallet-device-message-token');
599
- const walletDeviceId = request.get('wallet-device-id');
600
599
  const ua = request.get('user-agent');
601
600
  // request.context.store.connectedWallet
602
601
  const walletOS = request.context.didwallet.os;
602
+ const deviceData = getDeviceData({ req: request });
603
603
 
604
604
  const userSessionDoc = await node.upsertUserSession({
605
605
  teamDid,
@@ -612,8 +612,7 @@ module.exports = {
612
612
  lastLoginIp,
613
613
  extra: {
614
614
  walletOS,
615
- walletDeviceMessageToken,
616
- walletDeviceId,
615
+ device: deviceData,
617
616
  },
618
617
  });
619
618
 
@@ -651,8 +650,7 @@ module.exports = {
651
650
  lastLoginIp,
652
651
  extra: {
653
652
  walletOS,
654
- walletDeviceMessageToken,
655
- walletDeviceId,
653
+ device: deviceData,
656
654
  },
657
655
  });
658
656
  });
package/api/libs/jwt.js CHANGED
@@ -47,7 +47,7 @@ const initJwt = (node, options) => {
47
47
  elevated,
48
48
  });
49
49
 
50
- const verifySessionToken = (token, secret, { checkFromDb, teamDid, checkToken } = {}) =>
50
+ const verifySessionToken = (token, secret, { checkFromDb, teamDid, checkToken, locale = 'en' } = {}) =>
51
51
  // eslint-disable-next-line implicit-arrow-linebreak
52
52
  new Promise((resolve, reject) => {
53
53
  jwt.verify(token, secret, async (err, decoded) => {
@@ -91,13 +91,13 @@ const initJwt = (node, options) => {
91
91
  }
92
92
 
93
93
  if (!user.approved) {
94
- return reject(new Error(`Invalid jwt token: ${messages.notAllowedAppUser.en}`));
94
+ return reject(new Error(`Invalid jwt token: ${messages.notAllowedAppUser[locale]}`));
95
95
  }
96
96
 
97
97
  if (passport && passport.id) {
98
98
  const valid = await node.isPassportValid({ teamDid, passportId: passport.id });
99
99
  if (valid === false) {
100
- return reject(new Error(`Passport ${passport.name} has been revoked`));
100
+ return reject(new Error(messages.passportRevoked[locale](passport.name, passport.issuer?.name)));
101
101
  }
102
102
  }
103
103
 
@@ -56,10 +56,13 @@ async function sendPush(receiver, notification, { node, teamDid }) {
56
56
  user.userSessions.forEach((x) => {
57
57
  // NOTICE: 这里需要转为小写来判断
58
58
  const platform = x?.extra?.walletOS?.toLowerCase();
59
- const deviceToken = x?.extra?.walletDeviceMessageToken;
59
+ // 兼容处理,支持读取 walletDeviceMessageToken
60
+ const deviceToken = x?.extra?.device?.messageToken || x?.extra?.walletDeviceMessageToken;
61
+ const deviceClientName = x?.extra?.device?.clientName;
60
62
  if (platform && ['ios', 'android', 'ios-sandbox'].includes(platform) && deviceToken) {
61
63
  acc.push({
62
64
  platform,
65
+ deviceClientName,
63
66
  deviceToken,
64
67
  userDid: x.userDid,
65
68
  });
@@ -70,7 +73,7 @@ async function sendPush(receiver, notification, { node, teamDid }) {
70
73
  }, []);
71
74
 
72
75
  const filterTargets = uniqWith(targets, (a, b) => {
73
- return a.deviceToken === b.deviceToken && a.platform === b.platform;
76
+ return a.deviceToken === b.deviceToken && a.platform === b.platform && a.deviceClientName === b.deviceClientName;
74
77
  });
75
78
 
76
79
  if (filterTargets.length === 0) {
@@ -1,4 +1,4 @@
1
- const { WELLKNOWN_SERVICE_PATH_PREFIX, FEDERATED } = require('@abtnode/constant');
1
+ const { WELLKNOWN_SERVICE_PATH_PREFIX, FEDERATED, PASSPORT_STATUS } = require('@abtnode/constant');
2
2
  const { signV2 } = require('@arcblock/jwt');
3
3
  const isNil = require('lodash/isNil');
4
4
  const pick = require('lodash/pick');
@@ -573,13 +573,23 @@ module.exports = {
573
573
  }
574
574
  );
575
575
  if (prevUser?.approved === false) {
576
- res.status(401).json({ error: messages.notAllowedAppUser.en });
576
+ res.status(401).json({ error: messages.notAllowedAppUser[req.blockletLocale] });
577
577
  return;
578
578
  }
579
579
  // HACK: member 调用 master 时,将 passport 的 role 还原为 master 中原有的 role
580
580
  const targetPassport = passport?.id
581
581
  ? (prevUser?.passports || []).find((item) => item.id === passport.id)
582
582
  : null;
583
+ if (targetPassport?.status === PASSPORT_STATUS.EXPIRED) {
584
+ res.status(401).json({ error: messages.passportExpired[req.blockletLocale] });
585
+ return;
586
+ }
587
+ if (targetPassport?.status === PASSPORT_STATUS.REVOKED) {
588
+ res.status(401).json({
589
+ error: messages.passportRevoked[req.blockletLocale](targetPassport.title, targetPassport.issuer?.name),
590
+ });
591
+ return;
592
+ }
583
593
 
584
594
  // HACK: 用户在 master 中存在时,不更新任何用户信息;不存在时,将新增一个用户
585
595
  const filterUserInfo = prevUser ? {} : user;
@@ -1,5 +1,10 @@
1
1
  /* eslint-disable no-await-in-loop */
2
- const { WELLKNOWN_SERVICE_PATH_PREFIX, SESSION_TTL, PASSPORT_LOG_ACTION } = require('@abtnode/constant');
2
+ const {
3
+ WELLKNOWN_SERVICE_PATH_PREFIX,
4
+ SESSION_TTL,
5
+ PASSPORT_LOG_ACTION,
6
+ PASSPORT_STATUS,
7
+ } = require('@abtnode/constant');
3
8
  const { LOGIN_PROVIDER } = require('@blocklet/constant');
4
9
  const pick = require('lodash/pick');
5
10
  const defaults = require('lodash/defaults');
@@ -11,6 +16,7 @@ const getRequestIP = require('@abtnode/util/lib/get-request-ip');
11
16
  const { getFederatedMembers, getFederatedMaster } = require('@abtnode/auth/lib/util/federated');
12
17
  const { messages } = require('@abtnode/auth/lib/auth');
13
18
  const { Joi } = require('@arcblock/validator');
19
+ const { getDeviceData } = require('@abtnode/util/lib/device');
14
20
  const cors = require('cors');
15
21
 
16
22
  const logger = require('../libs/logger')('blocklet-services:user-session');
@@ -23,6 +29,8 @@ const checkUser = require('../middlewares/check-user');
23
29
  const prefix = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/user-session`;
24
30
  const limit = pLimit(5);
25
31
 
32
+ const userInfoBlackList = ['extra.walletDeviceId', 'extra.walletDeviceMessageToken', 'extra.device'];
33
+
26
34
  async function getPassport(passportId, { node, teamDid }) {
27
35
  const passport = await node.getPassportById({ teamDid, passportId });
28
36
  return passport;
@@ -155,7 +163,7 @@ module.exports = {
155
163
  if (validSession) {
156
164
  const user = await node.getUser({ teamDid, user: { did: validUserSession.userDid } });
157
165
  if (!user.approved) {
158
- res.status(401).json(messages.notAllowedAppUser.en);
166
+ res.status(401).json(messages.notAllowedAppUser[req.blockletLocale]);
159
167
  return;
160
168
  }
161
169
  const sourceProvider = getSourceProvider(user);
@@ -209,6 +217,16 @@ module.exports = {
209
217
  const targetPassport = validUserSession.passportId
210
218
  ? (user?.passports || []).find((item) => item.id === validUserSession.passportId)
211
219
  : null;
220
+ if (targetPassport?.status === PASSPORT_STATUS.EXPIRED) {
221
+ res.status(401).json({ error: messages.passportExpired[req.blockletLocale] });
222
+ return;
223
+ }
224
+ if (targetPassport?.status === PASSPORT_STATUS.REVOKED) {
225
+ res.status(401).json({
226
+ error: messages.passportRevoked[req.blockletLocale](targetPassport.title, targetPassport.issuer.name),
227
+ });
228
+ return;
229
+ }
212
230
  const loggedInUser = await node.loginUser({
213
231
  teamDid,
214
232
  user: {
@@ -259,8 +277,7 @@ module.exports = {
259
277
 
260
278
  const lastLoginIp = getRequestIP(req);
261
279
  const ua = req.get('user-agent');
262
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
263
- const walletDeviceId = req.get('wallet-device-id');
280
+ const deviceData = getDeviceData({ req });
264
281
 
265
282
  const userSessionDoc = await node.upsertUserSession({
266
283
  id: validUserSession.id,
@@ -274,8 +291,7 @@ module.exports = {
274
291
  lastLoginIp,
275
292
  extra: {
276
293
  walletOS,
277
- walletDeviceMessageToken,
278
- walletDeviceId,
294
+ device: deviceData,
279
295
  },
280
296
  });
281
297
 
@@ -290,8 +306,7 @@ module.exports = {
290
306
  lastLoginIp,
291
307
  extra: {
292
308
  walletOS,
293
- walletDeviceMessageToken,
294
- walletDeviceId,
309
+ device: deviceData,
295
310
  },
296
311
  });
297
312
  }
@@ -349,10 +364,7 @@ module.exports = {
349
364
  .filter((x) => {
350
365
  return x?.user?.approved;
351
366
  })
352
- .map((x) => {
353
- // NOTICE: 移除 walletDeviceId 和 walletDeviceMessageToken,避免泄露
354
- return omit(x, ['extra.walletDeviceId', 'extra.walletDeviceMessageToken']);
355
- });
367
+ .map((x) => omit(x, userInfoBlackList));
356
368
 
357
369
  res.json(result);
358
370
  });
@@ -369,6 +381,8 @@ module.exports = {
369
381
  const { appPid } = blocklet;
370
382
  const teamDid = appPid;
371
383
 
384
+ const federatedSites = blocklet?.settings?.federated?.sites || [];
385
+
372
386
  const visitorId = req.get('x-blocklet-visitor-id');
373
387
 
374
388
  if (!visitorId) {
@@ -381,7 +395,17 @@ module.exports = {
381
395
  visitorId,
382
396
  });
383
397
 
384
- const pendingList = userSessions.map((item) =>
398
+ const validUserSessions = userSessions.filter((x) => {
399
+ const federatedSite = federatedSites.find((y) => y.appPid === x.appPid);
400
+ if (federatedSite?.appPid === teamDid) {
401
+ return true;
402
+ }
403
+ if (federatedSite?.status === 'approved') {
404
+ return true;
405
+ }
406
+ return false;
407
+ });
408
+ const pendingList = validUserSessions.map((item) =>
385
409
  limit(() =>
386
410
  patchUserSessionData(item, {
387
411
  blocklet,
@@ -393,7 +417,7 @@ module.exports = {
393
417
  );
394
418
  await Promise.all(pendingList);
395
419
 
396
- const result = userSessions
420
+ const result = validUserSessions
397
421
  .filter((x) => {
398
422
  if (x.status === 'expired') {
399
423
  return false;
@@ -404,10 +428,7 @@ module.exports = {
404
428
 
405
429
  return checkLoginUserSession(x, { req });
406
430
  })
407
- .map((x) => {
408
- // NOTICE: 移除 walletDeviceId 和 walletDeviceMessageToken,避免泄露
409
- return omit(x, ['extra.walletDeviceId', 'extra.walletDeviceMessageToken']);
410
- });
431
+ .map((x) => omit(x, userInfoBlackList));
411
432
 
412
433
  res.json(result);
413
434
  });
@@ -24,6 +24,7 @@ const { xss } = require('@blocklet/xss');
24
24
  const { withQuery, joinURL } = require('ufo');
25
25
  const cors = require('cors');
26
26
  const createTranslator = require('@abtnode/util/lib/translate');
27
+ const { getDeviceData } = require('@abtnode/util/lib/device');
27
28
 
28
29
  const { createTokenFn, getDidConnectVersion } = require('../util');
29
30
  const initJwt = require('../libs/jwt');
@@ -340,8 +341,7 @@ async function loginSDK(req, node, options) {
340
341
  );
341
342
  const lastLoginIp = getRequestIP(req);
342
343
  const ua = req.get('user-agent');
343
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
344
- const walletDeviceId = req.get('wallet-device-id');
344
+ const deviceData = getDeviceData({ req });
345
345
  const userSession = await node.upsertUserSession({
346
346
  visitorId,
347
347
  teamDid,
@@ -352,8 +352,7 @@ async function loginSDK(req, node, options) {
352
352
  lastLoginIp,
353
353
  extra: {
354
354
  walletOS: 'api',
355
- walletDeviceMessageToken,
356
- walletDeviceId,
355
+ device: deviceData,
357
356
  },
358
357
  });
359
358
  node.syncUserSession({
@@ -366,8 +365,7 @@ async function loginSDK(req, node, options) {
366
365
  lastLoginIp,
367
366
  extra: {
368
367
  walletOS: 'api',
369
- walletDeviceMessageToken,
370
- walletDeviceId,
368
+ device: deviceData,
371
369
  },
372
370
  });
373
371
  return {
@@ -844,8 +842,7 @@ module.exports = {
844
842
  { ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
845
843
  );
846
844
  const ua = req.get('user-agent');
847
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
848
- const walletDeviceId = req.get('wallet-device-id');
845
+ const deviceData = getDeviceData({ req });
849
846
  const userSession = await node.upsertUserSession({
850
847
  visitorId,
851
848
  teamDid,
@@ -856,8 +853,7 @@ module.exports = {
856
853
  lastLoginIp,
857
854
  extra: {
858
855
  walletOS,
859
- walletDeviceMessageToken,
860
- walletDeviceId,
856
+ device: deviceData,
861
857
  },
862
858
  });
863
859
  node.syncUserSession({
@@ -870,8 +866,7 @@ module.exports = {
870
866
  lastLoginIp,
871
867
  extra: {
872
868
  walletOS,
873
- walletDeviceMessageToken,
874
- walletDeviceId,
869
+ device: deviceData,
875
870
  },
876
871
  });
877
872
 
@@ -11,6 +11,7 @@ const { getSourceAppPid } = require('@blocklet/sdk/lib/util/login');
11
11
  const { WELLKNOWN_SERVICE_PATH_PREFIX } = require('@abtnode/constant');
12
12
  const { LOGIN_PROVIDER } = require('@blocklet/constant');
13
13
  const getRequestIP = require('@abtnode/util/lib/get-request-ip');
14
+ const { getDeviceData } = require('@abtnode/util/lib/device');
14
15
 
15
16
  const { createTokenFn, getDidConnectVersion } = require('../../../util');
16
17
  const { getUserWithinFederated } = require('../../../util/federated');
@@ -122,8 +123,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
122
123
 
123
124
  const lastLoginIp = getRequestIP(req);
124
125
  const ua = req.get('user-agent');
125
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
126
- const walletDeviceId = req.get('wallet-device-id');
126
+ const deviceData = getDeviceData({ req });
127
127
  const userSessionDoc = await node.upsertUserSession({
128
128
  teamDid,
129
129
  visitorId,
@@ -135,8 +135,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
135
135
  lastLoginIp,
136
136
  extra: {
137
137
  walletOS,
138
- walletDeviceMessageToken,
139
- walletDeviceId,
138
+ device: deviceData,
140
139
  },
141
140
  });
142
141
  node.syncUserSession({
@@ -149,8 +148,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
149
148
  lastLoginIp,
150
149
  extra: {
151
150
  walletOS,
152
- walletDeviceMessageToken,
153
- walletDeviceId,
151
+ device: deviceData,
154
152
  },
155
153
  });
156
154
  await updateSession(
@@ -10,6 +10,7 @@ const { getSourceAppPid } = require('@blocklet/sdk/lib/util/login');
10
10
  const { WELLKNOWN_SERVICE_PATH_PREFIX } = require('@abtnode/constant');
11
11
  const { LOGIN_PROVIDER } = require('@blocklet/constant');
12
12
  const getRequestIP = require('@abtnode/util/lib/get-request-ip');
13
+ const { getDeviceData } = require('@abtnode/util/lib/device');
13
14
 
14
15
  const { createTokenFn, getDidConnectVersion } = require('../../../util');
15
16
 
@@ -48,8 +49,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
48
49
  const walletOS = req.context?.didwallet?.os;
49
50
  const lastLoginIp = getRequestIP(req);
50
51
  const ua = req.get('user-agent');
51
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
52
- const walletDeviceId = req.get('wallet-device-id');
52
+ const deviceData = getDeviceData({ req });
53
53
 
54
54
  const { response, passport, role } = await handleIssuePassportResponse({
55
55
  req,
@@ -96,8 +96,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
96
96
  lastLoginIp,
97
97
  extra: {
98
98
  walletOS,
99
- walletDeviceMessageToken,
100
- walletDeviceId,
99
+ device: deviceData,
101
100
  },
102
101
  });
103
102
  node.syncUserSession({
@@ -110,8 +109,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
110
109
  lastLoginIp,
111
110
  extra: {
112
111
  walletOS,
113
- walletDeviceMessageToken,
114
- walletDeviceId,
112
+ device: deviceData,
115
113
  },
116
114
  });
117
115
 
@@ -14,6 +14,7 @@ const {
14
14
  const { LOGIN_PROVIDER } = require('@blocklet/constant');
15
15
  const { signResponse } = require('@blocklet/meta/lib/security');
16
16
  const getRequestIP = require('@abtnode/util/lib/get-request-ip');
17
+ const { getDeviceData } = require('@abtnode/util/lib/device');
17
18
  const isUrl = require('is-url');
18
19
 
19
20
  const { createTokenFn, getDidConnectVersion } = require('../../util');
@@ -230,6 +231,7 @@ module.exports = {
230
231
  throw new Error(`invalid token type ${t.tokenType}`);
231
232
  }
232
233
  },
234
+ locale: req.blockletLocale,
233
235
  });
234
236
 
235
237
  const user = await node.getUser({ teamDid, user: { did: userPid } });
@@ -268,8 +270,7 @@ module.exports = {
268
270
  );
269
271
  const ua = req.get('user-agent');
270
272
  const lastLoginIp = getRequestIP(req);
271
- const walletDeviceMessageToken = req.get('wallet-device-message-token');
272
- const walletDeviceId = req.get('wallet-device-id');
273
+ const deviceData = getDeviceData({ req });
273
274
  const userSession = await node.upsertUserSession({
274
275
  visitorId,
275
276
  teamDid,
@@ -280,8 +281,7 @@ module.exports = {
280
281
  lastLoginIp,
281
282
  extra: {
282
283
  walletOS,
283
- walletDeviceMessageToken,
284
- walletDeviceId,
284
+ device: deviceData,
285
285
  },
286
286
  });
287
287
  if (user?.sourceAppPid) {
@@ -294,8 +294,7 @@ module.exports = {
294
294
  lastLoginIp,
295
295
  extra: {
296
296
  walletOS,
297
- walletDeviceMessageToken,
298
- walletDeviceId,
297
+ device: deviceData,
299
298
  },
300
299
  });
301
300
  }
@@ -94,23 +94,27 @@ const init = ({ node }) => {
94
94
  heartbeatTimeout: 60 * 1000 * 10,
95
95
  });
96
96
 
97
- // Let first worker process do something as master
98
- if (process.env.NODE_APP_INSTANCE === '0') {
99
- // cron
100
- Cron.init({
101
- jobs: [
102
- // @ts-ignore
103
- {
104
- name: 'prune messages',
105
- time: '0 0 0 * * 1', // every Monday per week
106
- fn: () => states.message.prune(),
107
- },
108
- ],
109
- onError: (error, name) => {
110
- logger.error('Run job failed', { name, error });
97
+ // 清除离线的消息
98
+ Cron.init({
99
+ jobs: [
100
+ {
101
+ name: 'prune messages',
102
+ time: '0 0 0 * * 1', // every Monday per week
103
+ fn: () => states.message.prune(),
111
104
  },
112
- });
113
- }
105
+ {
106
+ name: 'message-data-cleanup',
107
+ // time: '0 0 8 * * *', // check every day
108
+ time: '0 0 * * * *', // check every hour
109
+ // time: '*/5 * * * * *', // check every 5 seconds
110
+ fn: () => states.message.pruneExpiredData(),
111
+ options: { runOnInit: false },
112
+ },
113
+ ],
114
+ onError: (error, name) => {
115
+ logger.error('Run job failed', { name, error });
116
+ },
117
+ });
114
118
 
115
119
  const wrapSendHandler = (fn, channel) => {
116
120
  return async (req, res) => {
@@ -199,7 +199,7 @@ const sendToAppDid = async ({
199
199
  wsServer,
200
200
  }) => {
201
201
  if (notification && sender) {
202
- const { keepForOfflineUser = true } = options || {};
202
+ const { keepForOfflineUser = true, ttl } = options || {};
203
203
  const teamDid = sender.appDid;
204
204
  const { id } = notification;
205
205
  if (Array.isArray(receiver)) {
@@ -227,14 +227,14 @@ const sendToAppDid = async ({
227
227
  });
228
228
  }
229
229
 
230
- // 这里仅 feed 类型不需要保存离线消息
231
- // connect|passthrough 类型都需要保存离线消息,目的是为了快速流转到下一步
232
- const isKeepForOfflineUser =
233
- keepForOfflineUser && (!notification.type || notification.type?.toLowerCase() !== 'feed');
234
-
235
- if (count <= 0 && isKeepForOfflineUser) {
230
+ if (count <= 0 && keepForOfflineUser) {
236
231
  logger.error('Online client was not found', { userDid: receiver });
237
- await states.message.insert({ did: receiver, event: EVENTS.MESSAGE, data: payload });
232
+ await states.message.insert({
233
+ did: receiver,
234
+ event: EVENTS.MESSAGE,
235
+ data: payload,
236
+ ttl: typeof ttl === 'number' && ttl > 0 ? ttl : null,
237
+ });
238
238
  }
239
239
  });
240
240
  return;
@@ -1,12 +1,29 @@
1
1
  const BaseState = require('@abtnode/core/lib/states/base');
2
+ const { Op, Sequelize } = require('sequelize');
3
+ const logger = require('@abtnode/logger')('@abtnode/core:states');
4
+
5
+ const DEFAULT_TTL = 30; // 30 minutes
6
+ const MAX_TTL = 7200; // 7200 minutes (5 days)
7
+ const MINUTE_IN_MS = 1000 * 60;
2
8
 
3
9
  class MessageState extends BaseState {
4
10
  insert(doc, ...args) {
11
+ const extra = {};
12
+ if (doc.ttl && typeof doc.ttl === 'number' && doc.ttl > 0) {
13
+ const ttl = Math.min(doc.ttl, MAX_TTL);
14
+ extra.expiredAt = new Date(Date.now() + MINUTE_IN_MS * ttl);
15
+ } else if (!doc.ttl && doc.event === 'message' && doc.data?.type) {
16
+ if (['feed', 'connect', 'passthrough'].includes(doc.data.type)) {
17
+ extra.expiredAt = new Date(Date.now() + MINUTE_IN_MS * DEFAULT_TTL); // 30分钟后过期
18
+ }
19
+ }
20
+
5
21
  return super.insert(
6
22
  {
7
23
  ...doc,
8
24
  createdAt: Date.now(),
9
25
  updatedAt: Date.now(),
26
+ ...extra,
10
27
  },
11
28
  ...args
12
29
  );
@@ -16,6 +33,48 @@ class MessageState extends BaseState {
16
33
  const t = time || 5 * 24 * 60 * 60 * 1000; // 5 day
17
34
  return this.remove({ createdAt: { $lt: Date.now() - t } });
18
35
  }
36
+
37
+ /**
38
+ * 如果有设置过期时间,则删除过期的数据,
39
+ * 如果没有设置过期时间,则清除数据的条件如下
40
+ * 1. 创建时间早于五分钟
41
+ * 2. event 类型为 'message'
42
+ * 3. data.type 为 'feed', 'connect' 或 'passthrough'
43
+ */
44
+ async pruneExpiredData() {
45
+ try {
46
+ // 获取指定时间前的时间戳
47
+ const expiryThreshold = new Date();
48
+
49
+ // 1. 删除有 expiredAt 的记录
50
+ const deletedExpiredData = await this.remove({
51
+ where: {
52
+ expiredAt: { [Op.lt]: expiryThreshold },
53
+ },
54
+ });
55
+
56
+ logger.info(`message data cleanup completed: deleted ${deletedExpiredData} expired records`);
57
+
58
+ // 2. 兼容代码,删除之前没有设置 expiredAt 的记录
59
+ const timeAgo = new Date();
60
+ timeAgo.setMinutes(timeAgo.getMinutes() - DEFAULT_TTL); // 设置过期时间
61
+
62
+ const where = {
63
+ createdAt: { [Op.lt]: timeAgo },
64
+ expiredAt: { [Op.is]: null },
65
+ event: 'message',
66
+ [Op.and]: [Sequelize.literal("json_extract(data, '$.type') IN ('feed', 'connect', 'passthrough')")],
67
+ };
68
+
69
+ const deletedCount = await this.remove({
70
+ where,
71
+ });
72
+
73
+ logger.info(`message data cleanup completed: deleted ${deletedCount} records`);
74
+ } catch (error) {
75
+ logger.error('Error during message data cleanup:', error);
76
+ }
77
+ }
19
78
  }
20
79
 
21
80
  module.exports = MessageState;
@@ -165,6 +165,7 @@ module.exports = ({ node, req, options }) => {
165
165
  const opt = {
166
166
  checkFromDb: (decoded) => cache.sessionCacheDisabledUser.get(decoded?.did),
167
167
  teamDid,
168
+ locale: req.blockletLocale,
168
169
  };
169
170
 
170
171
  const user = await verifySessionToken(token, secret, opt);