@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.
- package/api/cache.js +39 -0
- package/api/index.js +121 -2
- package/api/libs/api.js +3 -3
- package/api/libs/connect/session.js +44 -53
- package/api/libs/kyc.js +9 -0
- package/api/libs/push-kit/index.js +17 -2
- package/api/middlewares/verify-sig.js +35 -3
- package/api/routes/blocklet.js +0 -13
- package/api/routes/env.js +2 -2
- package/api/routes/oauth.js +11 -7
- package/api/routes/user-session.js +38 -23
- package/api/routes/user.js +6 -7
- package/api/services/auth/index.js +43 -64
- package/api/services/kyc/index.js +56 -32
- package/api/util/attach-shared-utils.js +113 -19
- package/api/util/index.js +13 -12
- package/dist/assets/{Add-Bl82G48c.js → Add-DhnwVxhZ.js} +1 -1
- package/dist/assets/{Alert-B9Rlqmtk.js → Alert-C2mTW_RW.js} +1 -1
- package/dist/assets/{ArrowDropDown-z6CkvFic.js → ArrowDropDown-wj9U9ZE8.js} +1 -1
- package/dist/assets/{Autocomplete-C0mtAXbg.js → Autocomplete-CmEAN8J-.js} +1 -1
- package/dist/assets/{Avatar-LMc5QpZl.js → Avatar-BZ_OPd3a.js} +1 -1
- package/dist/assets/{ButtonGroup-Bvw5eHAy.js → ButtonGroup-CFQqy_jV.js} +1 -1
- package/dist/assets/CSSTransition-CJDdpnYB.js +1 -0
- package/dist/assets/{CheckCircle-CW1NWF0M.js → CheckCircle-DK6y1v0b.js} +1 -1
- package/dist/assets/{ChevronLeft-Bc2dOBpo.js → ChevronLeft-BqHB6tsg.js} +1 -1
- package/dist/assets/{ChevronRight-y7cPaDQ3.js → ChevronRight-DwKqpeOS.js} +1 -1
- package/dist/assets/{Close-DLWmZbtN.js → Close-CdDd2weK.js} +1 -1
- package/dist/assets/{CloseOutlined-7w3yHb7q.js → CloseOutlined-KF-hdrv3.js} +1 -1
- package/dist/assets/{Delete-FZyEAOwe.js → Delete-P7WqUbyQ.js} +1 -1
- package/dist/assets/{DeleteOutline-B-H27VeQ.js → DeleteOutline-BrrioL98.js} +1 -1
- package/dist/assets/{DialogContentText-CiyJlDpv.js → DialogContentText-BECZzyeS.js} +1 -1
- package/dist/assets/{Done-BEW0zhw2.js → Done-B8u3JQ36.js} +1 -1
- package/dist/assets/{Download-BfRlCRO0.js → Download-DBU6UuKg.js} +1 -1
- package/dist/assets/{EditIcon-CG4JGMyT.js → EditIcon-BV3Q9c3s.js} +1 -1
- package/dist/assets/{Error-C2cvwDlh.js → Error-CjCi6iqE.js} +1 -1
- package/dist/assets/{ExpandMore-CVPXcP59.js → ExpandMore-BjFaf3Fo.js} +1 -1
- package/dist/assets/FormControl-B9P20sHZ.js +1 -0
- package/dist/assets/FormControlLabel-C2tfmf09.js +1 -0
- package/dist/assets/{FormGroup-DoibujUR.js → FormGroup-QeEOGRIO.js} +1 -1
- package/dist/assets/{Google-BkswiX56.js → Google-B7LRQAsM.js} +3 -3
- package/dist/assets/{Grid-DmS931mb.js → Grid-BArO7d1G.js} +1 -1
- package/dist/assets/HelpOutline-It0-5Kn2.js +1 -0
- package/dist/assets/{Hidden-DFLNRBK7.js → Hidden-CpExY3Hv.js} +1 -1
- package/dist/assets/{InfoOutlined-BGl9NpGF.js → InfoOutlined-DEMaFK-w.js} +1 -1
- package/dist/assets/{InputAdornment-BfRAjWFP.js → InputAdornment-BFyVcV9g.js} +1 -1
- package/dist/assets/{InputLabel-snet_z2M.js → InputLabel-FW_WnrBG.js} +1 -1
- package/dist/assets/{LastPage-KoP1Fd4R.js → LastPage-BbNDF-1B.js} +1 -1
- package/dist/assets/{Launch-DaqmeZ7p.js → Launch-CM54bxPy.js} +1 -1
- package/dist/assets/{LaunchOutlined-D8_8q_U2.js → LaunchOutlined-DQOUx0IB.js} +1 -1
- package/dist/assets/{Link-ZwKMc2xW.js → Link-BLv1ybKR.js} +1 -1
- package/dist/assets/ListItemButton-BhIitXNK.js +1 -0
- package/dist/assets/{LoadingButton-DAYzECCB.js → LoadingButton-Do8QGr9D.js} +1 -1
- package/dist/assets/{LockIcon-CzOlJg7E.js → LockIcon-uGDnriV5.js} +1 -1
- package/dist/assets/{Loop-DdSi2a5X.js → Loop-DQX1T4wF.js} +1 -1
- package/dist/assets/MarkEmailRead-BdVitMKq.js +1 -0
- package/dist/assets/{Menu-cPWOWdJv.js → Menu-B60nijwd.js} +1 -1
- package/dist/assets/{MoreHoriz-CCaXi0-D.js → MoreHoriz-Cwgb_ZWA.js} +1 -1
- package/dist/assets/MoreVert-6z9sYyBh.js +1 -0
- package/dist/assets/{OpenInNew-DhmdNIIA.js → OpenInNew-B7MVFrbE.js} +1 -1
- package/dist/assets/Pagination-C8kC-7d4.js +2 -0
- package/dist/assets/{PlayArrow-dbaJvP3i.js → PlayArrow-CyW2vtN8.js} +1 -1
- package/dist/assets/{QuestionMarkCircle-ClghFyf8.js → QuestionMarkCircle-Dkgs-LrD.js} +1 -1
- package/dist/assets/{RadioGroup-h39eYIOw.js → RadioGroup-F9HJgTgP.js} +1 -1
- package/dist/assets/{Search-Deg4mgEt.js → Search-Bm4BV5ff.js} +1 -1
- package/dist/assets/{Select-D8wgZEYi.js → Select-DN5ZDrhq.js} +2 -2
- package/dist/assets/{ServerLogo-C-IdWQab.js → ServerLogo-qj6BKZhH.js} +1 -1
- package/dist/assets/{Skeleton-DTHod0yi.js → Skeleton-BHxGQUwb.js} +4 -4
- package/dist/assets/{Slider-BGdMADx-.js → Slider-DZmSOFez.js} +1 -1
- package/dist/assets/{Stack-Cp3hYWEn.js → Stack-CcM0sATd.js} +1 -1
- package/dist/assets/{Stepper-BYg7nOyi.js → Stepper-VAkPR7Rp.js} +1 -1
- package/dist/assets/{TextField-COEnibZX.js → TextField-CVbbJh-y.js} +1 -1
- package/dist/assets/{Toolbar-gvJQuyml.js → Toolbar-DMWwm961.js} +1 -1
- package/dist/assets/{Verified-BYBUZULO.js → Verified-CracX5_0.js} +1 -1
- package/dist/assets/{ViewColumn-C-7sjz0Y.js → ViewColumn-cHwmzgaQ.js} +1 -1
- package/dist/assets/{ViewList-JViuspE8.js → ViewList-DEr3Y-iU.js} +1 -1
- package/dist/assets/access-control-DEaRRq7A.js +13 -0
- package/dist/assets/{actions-BvIgnlgP.js → actions-BaCBwrwa.js} +1 -1
- package/dist/assets/{add-component-core-CF3Wvpy3.js → add-component-core-CTd25DO_.js} +38 -38
- package/dist/assets/add-resource-BcsfLDaF.js +1 -0
- package/dist/assets/{addon-BN5Sfj4m.js → addon-B5M4Vtbg.js} +1 -1
- package/dist/assets/{analytics-jhEGduS7.js → analytics-DKUh0ZA1.js} +8 -8
- package/dist/assets/api-noKs5rUY.js +1 -0
- package/dist/assets/ar-2TonDRvZ.js +1 -0
- package/dist/assets/ar-j9K5GatZ.js +1 -0
- package/dist/assets/audit-logs-DEv30kSD.js +58 -0
- package/dist/assets/{base32-RJwtUwTG.js → base32-BbBkrI_s.js} +1 -1
- package/dist/assets/{bundle-avatar-CYj37kYo.js → bundle-avatar-DFcMZdHK.js} +1 -1
- package/dist/assets/{button-Bzg3GLCP.js → button-WHxIb92N.js} +1 -1
- package/dist/assets/{click-to-copy-BxqXxgUi.js → click-to-copy-DSLKklSI.js} +1 -1
- package/dist/assets/{complete-DkKqvq-n.js → complete-CAaHcOBS.js} +1 -1
- package/dist/assets/{component-CBSn0ylq.js → component-_5q7tWN6.js} +81 -81
- package/dist/assets/{config-W5zOORTl.js → config-COlGV3BW.js} +2 -2
- package/dist/assets/config-_6fNEXak.js +1 -0
- package/dist/assets/{config-navigation-acog9zxt.js → config-navigation-DdfU54Ga.js} +5 -5
- package/dist/assets/{confirm-BD8lcIjf.js → confirm-CPhW4Ln4.js} +1 -1
- package/dist/assets/{connect-DUt6GuMA.js → connect-CJYVrjZW.js} +1 -1
- package/dist/assets/{connect-Cau7HJrv.js → connect-CutE2j6W.js} +1 -1
- package/dist/assets/connect-to-ByrmSC7Q.js +54 -0
- package/dist/assets/{content-layout--Pzx1mcC.js → content-layout-NMxrW85n.js} +1 -1
- package/dist/assets/{dashboard-CIOwnQZx.js → dashboard-yyANkyH0.js} +9 -9
- package/dist/assets/de-B1aG8zWS.js +1 -0
- package/dist/assets/de-BVh3hwT3.js +1 -0
- package/dist/assets/{deprecate-D_97v-_E.js → deprecate-TLU2j5Nl.js} +1 -1
- package/dist/assets/{did-address-DgsfKQl1.js → did-address-qp4O986k.js} +1 -1
- package/dist/assets/{domain-zy-h52DT.js → domain-BobgkNRn.js} +1 -1
- package/dist/assets/{domain-list-tyAcumiG.js → domain-list-nelUcVaZ.js} +2 -2
- package/dist/assets/email-BmqNkTVh.js +18 -0
- package/dist/assets/emotion-cache.browser.esm-CRw46sQ7.js +1 -0
- package/dist/assets/es-B78wkrSg.js +1 -0
- package/dist/assets/es-BEwxvJ2s.js +1 -0
- package/dist/assets/{exchange-passport-DPiMkxjA.js → exchange-passport-YyjxxQGp.js} +1 -1
- package/dist/assets/{fallback-DUmnMg78.js → fallback-DpZp1UKo.js} +1 -1
- package/dist/assets/form-text-input-Dnp-THZ5.js +11 -0
- package/dist/assets/{format-error-D0C8Qna1.js → format-error-BvNwPRch.js} +1 -1
- package/dist/assets/fr-Cvy3dZN3.js +1 -0
- package/dist/assets/fr-CyBvbwlz.js +1 -0
- package/dist/assets/{fuel-CZZpMc32.js → fuel-DwAfHv3P.js} +1 -1
- package/dist/assets/{fullpage-ov1kRa00.js → fullpage-BFccehDH.js} +1 -1
- package/dist/assets/hi-CiLl3Zi6.js +1 -0
- package/dist/assets/hi-nvWOxhan.js +1 -0
- package/dist/assets/{home-gwd5aHrM.js → home-BF01oQMN.js} +1 -1
- package/dist/assets/id-Cl0lvxW7.js +1 -0
- package/dist/assets/id-FWMMrTxm.js +1 -0
- package/dist/assets/{iframe-BIzC7nPA.js → iframe-CGjP6x7t.js} +1 -1
- package/dist/assets/index-0R3zcGhj.js +126 -0
- package/dist/assets/{index-BcvXX_mO.js → index-4YjFb1t8.js} +1 -1
- package/dist/assets/{index-DcKMlzdo.js → index-B1jXhAXk.js} +1 -1
- package/dist/assets/{index-rOGdJKYL.js → index-B61Zk4zc.js} +1 -1
- package/dist/assets/{index-AfbTuUW5.js → index-B6rU6yZ1.js} +7 -7
- package/dist/assets/{index-C_0JNAm2.js → index-BAsIkYmI.js} +1 -1
- package/dist/assets/{index-Q7ZUJ_jr.js → index-BEmU10Y0.js} +11 -11
- package/dist/assets/index-BFsNvHHz.js +22 -0
- package/dist/assets/{index-BjLsHd9C.js → index-BHRFloRH.js} +1 -1
- package/dist/assets/index-BZ9M67Kd.js +5 -0
- package/dist/assets/{index-COU4Nu6y.js → index-BZKKn0ch.js} +1 -1
- package/dist/assets/{index-B-DC1bkM.js → index-BnLNgi5J.js} +1 -1
- package/dist/assets/{index-CES_wWCV.js → index-BowU-Rc8.js} +183 -183
- package/dist/assets/index-Br6smtqw.js +1 -0
- package/dist/assets/{index-bwXQ8Wpi.js → index-BxX33nUX.js} +14 -13
- package/dist/assets/{index-B8-zdW7s.js → index-C4-tvqA6.js} +5 -5
- package/dist/assets/{index-BqpKWYMh.js → index-C6bJ8C3n.js} +1 -1
- package/dist/assets/{index-BJmzQOKo.js → index-CDo-yvx8.js} +1 -1
- package/dist/assets/index-C_izWh42.js +11 -0
- package/dist/assets/{index-D8OsCndp.js → index-CxykcKWh.js} +1 -1
- package/dist/assets/{index-QTPBiLZh.js → index-D0Foc0Tz.js} +1 -1
- package/dist/assets/{index-BYSwxOyW.js → index-D5jbzTmg.js} +1 -1
- package/dist/assets/index-DH4lKXWs.js +11 -0
- package/dist/assets/{index-DsWS2z9f.js → index-DaCSO68v.js} +1 -1
- package/dist/assets/{index-XlLZRf68.js → index-DaRP45oo.js} +1 -1
- package/dist/assets/{index-Bv4e_rV5.js → index-DbC1wngE.js} +1 -1
- package/dist/assets/index-Dnw0yymR.js +1 -0
- package/dist/assets/{index-Wi2p68c2.js → index-DsX4E8f1.js} +1 -1
- package/dist/assets/{index-C2AukIic.js → index-DtHgjXc_.js} +1 -1
- package/dist/assets/{index-DS-kwJv8.js → index-DusV8FU1.js} +1 -1
- package/dist/assets/index-FWU8WNJ8.js +1 -0
- package/dist/assets/{index-BA1E4qQ4.js → index-LmZHdjQZ.js} +1 -1
- package/dist/assets/{index-CE4JYDnG.js → index-RHJlosGb.js} +4 -4
- package/dist/assets/index-_uCAkv_0.js +316 -0
- package/dist/assets/{index-CNybmfDH.js → index-dmc3Tzez.js} +1 -1
- package/dist/assets/{index.es-HA92kWdG.js → index.es-DjXtuSXa.js} +3 -3
- package/dist/assets/{invitation-B49_oImo.js → invitation-CitdNTlE.js} +1 -1
- package/dist/assets/{invite-V3Nbkyr9.js → invite-8bX-82iQ.js} +1 -1
- package/dist/assets/isEmail-DlDmj0fr.js +1 -0
- package/dist/assets/{issue-passport-BK_rmsMU.js → issue-passport-DlN6RZob.js} +1 -1
- package/dist/assets/{item-ChdkonTR.js → item-CKNXAp6H.js} +1 -1
- package/dist/assets/ja-Be6ZrJ3j.js +1 -0
- package/dist/assets/ja-Uy7OpVJX.js +1 -0
- package/dist/assets/{jss-plugin-props-sort.esm-DBVL9gMW.js → jss-plugin-props-sort.esm-DoSjjNR1.js} +5 -5
- package/dist/assets/ko-631_NPZL.js +1 -0
- package/dist/assets/ko-RAcT5Den.js +1 -0
- package/dist/assets/{launch-result-message-BAr02bV5.js → launch-result-message-JFKmiVbN.js} +1 -1
- package/dist/assets/{layout-bf8MnH7p.js → layout-DEXenHhy.js} +1 -1
- package/dist/assets/{list-header-BdXS3bwO.js → list-header-7vVYIW_T.js} +1 -1
- package/dist/assets/localization-DdE_yTeV.js +1 -0
- package/dist/assets/{log-CEafQKJ9.js → log-ZCJiZb-D.js} +1 -1
- package/dist/assets/{login-CEkmeGqM.js → login-64rLho-5.js} +1 -1
- package/dist/assets/{login-oauth-callback-BKsN-may.js → login-oauth-callback-nOgNHNCk.js} +1 -1
- package/dist/assets/logo-uploader-Cz1267Av.js +133 -0
- package/dist/assets/{lost-passport-BKV23uoE.js → lost-passport-DjJtlNVj.js} +3 -3
- package/dist/assets/{lottie-Bmh0Xil_.js → lottie-DoYE5XDB.js} +1 -1
- package/dist/assets/notifications-Cv1XH2yb.js +65 -0
- package/dist/assets/{open-window-BxfESFgZ.js → open-window-CN5TQ87C.js} +1 -1
- package/dist/assets/overview-kalRt_uR.js +12 -0
- package/dist/assets/{page-header-C6Www8xa.js → page-header-BmLNlOnD.js} +1 -1
- package/dist/assets/{permission-C0wbV6KF.js → permission-DUsbjffq.js} +1 -1
- package/dist/assets/{preferences-DgOndnl4.js → preferences-ZO1kLbOx.js} +1 -1
- package/dist/assets/pt-BlLvTTrm.js +1 -0
- package/dist/assets/pt-CTpkGCgP.js +1 -0
- package/dist/assets/publish-resource-B2rKe7a9.js +1 -0
- package/dist/assets/purify.es-Bq0E5Q3l.js +2 -0
- package/dist/assets/react-BTu1Y-_j.js +56 -0
- package/dist/assets/{redux-B8mroqAb.js → redux-CJ8S87pk.js} +1 -1
- package/dist/assets/refType-CT_vAXIZ.js +1 -0
- package/dist/assets/resource-dialog-D_8tTarn.js +4 -0
- package/dist/assets/ru-Culp1KLs.js +1 -0
- package/dist/assets/ru-sSBv7F2t.js +1 -0
- package/dist/assets/sdk-C3SAOjUt.js +1 -0
- package/dist/assets/{selector-B2UrJyEC.js → selector-Rhni_cbO.js} +3 -3
- package/dist/assets/session-4S4FY2oN.js +1 -0
- package/dist/assets/setup-BQ-DnQht.js +19 -0
- package/dist/assets/{shorten-label-C69K-2N4.js → shorten-label-8aKNnW15.js} +1 -1
- package/dist/assets/simple-select-CNSx0Qbg.js +1 -0
- package/dist/assets/{slicedToArray-Btbq_uXo.js → slicedToArray-vg-R5s0s.js} +2 -2
- package/dist/assets/{spaces-CKA3haGw.js → spaces-BcZSz_wm.js} +1 -1
- package/dist/assets/{start-E4q8KtSK.js → start-CqQHbsvY.js} +1 -1
- package/dist/assets/{step-actions-Dv65pQs7.js → step-actions-DV3o9hve.js} +1 -1
- package/dist/assets/{studio-C9Z81BQt.js → studio-D_pIJx8G.js} +1 -1
- package/dist/assets/{switch-control-Cct9SW8-.js → switch-control-C-X_dl1C.js} +1 -1
- package/dist/assets/th-Dqms8yb0.js +1 -0
- package/dist/assets/th-Dv20telW.js +1 -0
- package/dist/assets/{toUpper-DjVC4j_j.js → toUpper-CqfCm6FQ.js} +1 -1
- package/dist/assets/{transfer-W8UlEJt-.js → transfer-CSfZjjyt.js} +1 -1
- package/dist/assets/trim-CXCEOOfq.js +1 -0
- package/dist/assets/{uniqBy-BzzuWGYh.js → uniqBy--m6Xe_2K.js} +1 -1
- package/dist/assets/{unsubscribe-BkeOgqWI.js → unsubscribe-BJWyVFrT.js} +1 -1
- package/dist/assets/{url-join-BLh7jCrJ.js → url-join-CAnJBM33.js} +1 -1
- package/dist/assets/use-blocklet-info-for-connect-did-spaces-BWR6SXSQ.js +1 -0
- package/dist/assets/{use-mobile-BJoJTGF0.js → use-mobile-BBtcVjXr.js} +1 -1
- package/dist/assets/{useAsync-CvPpFYs-.js → useAsync-DTvP9Zxi.js} +1 -1
- package/dist/assets/{useFormControl-BXRE7Su9.js → useFormControl-CqDUGVwx.js} +1 -1
- package/dist/assets/{useLocalStorage-BJH73q2r.js → useLocalStorage-BSk8yrmI.js} +1 -1
- package/dist/assets/{useSetState-CJBhbXdV.js → useSetState-Dvi1U0Nw.js} +1 -1
- package/dist/assets/useSlot-CBvar7i-.js +1 -0
- package/dist/assets/{useSlotProps-Bo-Lx2a7.js → useSlotProps-BO61t83_.js} +1 -1
- package/dist/assets/useThemeProps-BVeww5NE.js +1 -0
- package/dist/assets/user-center-DxinbhvA.js +1 -0
- package/dist/assets/{user-sessions-9jxxDLYT.js → user-sessions-BGeFoCxv.js} +1 -1
- package/dist/assets/{util-ZHGnEGmF.js → util-DQZs28G6.js} +1 -1
- package/dist/assets/vi-B-VzHaKw.js +1 -0
- package/dist/assets/vi-DjcU4tKh.js +1 -0
- package/dist/assets/wrap-locale-B-fXOOcn.js +1 -0
- package/dist/assets/zh-DWYwLndz.js +1 -0
- package/dist/assets/zh-tw-3Ki06u1b.js +1 -0
- package/dist/assets/zh-tw-B7lbXLVn.js +1 -0
- package/dist/assets/zh-u8iElwOC.js +2 -0
- package/dist/index.html +1 -1
- package/dist/service-worker.js +1 -1
- package/package.json +30 -27
- package/api/util/get-dynamic-service-config.js +0 -48
- package/dist/assets/Edit-Cbvlvh2w.js +0 -11
- package/dist/assets/FormControl-vM9EJwp4.js +0 -1
- package/dist/assets/FormControlLabel-CS28YgVs.js +0 -1
- package/dist/assets/MoreVert-D4SS6MnA.js +0 -1
- package/dist/assets/Pagination-BXlUtx3B.js +0 -2
- package/dist/assets/access-control-BDg9FQV3.js +0 -13
- package/dist/assets/add-resource-DLKAe3re.js +0 -1
- package/dist/assets/api-JbjuY7JN.js +0 -1
- package/dist/assets/ar-BcsWe-M7.js +0 -1
- package/dist/assets/ar-rur8F6ox.js +0 -1
- package/dist/assets/audit-logs-Vn5iZ4P_.js +0 -58
- package/dist/assets/config-ONP_4X_B.js +0 -1
- package/dist/assets/connect-to-GhSR8jRw.js +0 -54
- package/dist/assets/de-C-5DrcsF.js +0 -1
- package/dist/assets/de-f8XZAb4q.js +0 -1
- package/dist/assets/email-BINRPUSY.js +0 -18
- package/dist/assets/emotion-cache.browser.esm-ByukGais.js +0 -1
- package/dist/assets/es-CDmziQ2d.js +0 -1
- package/dist/assets/es-Dkw0SgdE.js +0 -1
- package/dist/assets/fr-CutjrzQz.js +0 -1
- package/dist/assets/fr-RdOP2uWC.js +0 -1
- package/dist/assets/hi-BwtTylyX.js +0 -1
- package/dist/assets/hi-V6iw7v5V.js +0 -1
- package/dist/assets/id-CeB6Ugb-.js +0 -1
- package/dist/assets/id-Dz8dfVhg.js +0 -1
- package/dist/assets/index-BHXHtIJm.js +0 -126
- package/dist/assets/index-CXg0jLCN.js +0 -11
- package/dist/assets/index-DW7dwoqE.js +0 -11
- package/dist/assets/index-DmdwpBJN.js +0 -261
- package/dist/assets/index-DqHzmyne.js +0 -68
- package/dist/assets/index-HqFqdQ4r.js +0 -1
- package/dist/assets/index-RVvYAb40.js +0 -1
- package/dist/assets/index-wVSweHe6.js +0 -1
- package/dist/assets/index.esm-S4QOHn5V.js +0 -1
- package/dist/assets/ja-BZrZ4ULY.js +0 -1
- package/dist/assets/ja-DlWywLev.js +0 -1
- package/dist/assets/ko-DLaz-pjP.js +0 -1
- package/dist/assets/ko-ESHUwy9c.js +0 -1
- package/dist/assets/localization-BlAk-2Dh.js +0 -1
- package/dist/assets/logo-uploader-DO_ePInN.js +0 -122
- package/dist/assets/mode-B2dWMeTO.js +0 -1
- package/dist/assets/notifications-CDn5GICo.js +0 -62
- package/dist/assets/overview-DvxryhGu.js +0 -12
- package/dist/assets/pt-BMSFPKAT.js +0 -1
- package/dist/assets/pt-CysEhQ_Z.js +0 -1
- package/dist/assets/publish-resource-BK8LfyYg.js +0 -1
- package/dist/assets/react-DWdAOKA_.js +0 -57
- package/dist/assets/resource-dialog-CxQ2RdqX.js +0 -57
- package/dist/assets/ru-2aTr2i-M.js +0 -1
- package/dist/assets/ru-C-IO4heq.js +0 -1
- package/dist/assets/sdk-BzFjs0zU.js +0 -1
- package/dist/assets/session-CPw6Z6tL.js +0 -1
- package/dist/assets/setup-C-eSKhTS.js +0 -19
- package/dist/assets/th-Bd6_ise5.js +0 -1
- package/dist/assets/th-D2W7tb3N.js +0 -1
- package/dist/assets/trim-pCqXvQz3.js +0 -1
- package/dist/assets/use-blocklet-info-for-connect-did-spaces-BfIvMuGO.js +0 -1
- package/dist/assets/useSlot-BnpRF9Wf.js +0 -1
- package/dist/assets/useThemeProps-NLTP4qET.js +0 -1
- package/dist/assets/user-center-DSwKYf1W.js +0 -1
- package/dist/assets/vi-BrQQz2Dk.js +0 -1
- package/dist/assets/vi-DTSqGMo-.js +0 -1
- package/dist/assets/wrap-locale-De5w1_ZO.js +0 -1
- package/dist/assets/zh-BUjxGa7K.js +0 -1
- package/dist/assets/zh-CT0fSzRS.js +0 -2
- package/dist/assets/zh-tw-GFcs7F29.js +0 -1
- 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
|
@@ -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 {
|
|
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,
|
|
98
|
-
|
|
99
|
-
|
|
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 (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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 = '',
|
|
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
|
|
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
|
|
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: !
|
|
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
|
|
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
|
-
|
|
340
|
-
|
|
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,
|
|
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
|
|
715
|
-
if (get(
|
|
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,
|
|
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
|
|
851
|
-
|
|
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: !
|
|
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
|
|
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
|
-
|
|
917
|
-
if (
|
|
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,
|
|
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
|
-
|
|
84
|
-
|
|
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
|
|
8
|
-
|
|
9
|
-
const
|
|
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,
|
package/api/routes/blocklet.js
CHANGED
|
@@ -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,
|
|
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 ||
|
|
40
|
+
webWalletUrl: "${info.webWalletUrl || serviceConfig.webWalletUrl || opts.webWalletUrl}",
|
|
41
41
|
nftDomainUrl: "${info.nftDomainUrl || ''}",
|
|
42
42
|
passportColor: "${passportColor}",
|
|
43
43
|
serverDid: "${info.did}",
|