@abtnode/blocklet-services 1.16.33-beta-20241024-064549-2c1ad302 → 1.16.33-beta-20241028-005826-60afb7c4
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/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 +32 -62
- package/api/util/attach-shared-utils.js +109 -19
- package/api/util/index.js +13 -12
- package/dist/assets/{Add-Bl82G48c.js → Add-BQRw67Fa.js} +1 -1
- package/dist/assets/{Alert-B9Rlqmtk.js → Alert-Cb8GUvFi.js} +1 -1
- package/dist/assets/{ArrowDropDown-z6CkvFic.js → ArrowDropDown-BRkkVMO8.js} +1 -1
- package/dist/assets/{Autocomplete-C0mtAXbg.js → Autocomplete-CiMJCI6q.js} +1 -1
- package/dist/assets/{Avatar-LMc5QpZl.js → Avatar-JUqpVuoZ.js} +1 -1
- package/dist/assets/{ButtonGroup-Bvw5eHAy.js → ButtonGroup-Dkr30o-y.js} +1 -1
- package/dist/assets/CSSTransition-CaK7nxWs.js +1 -0
- package/dist/assets/{CheckCircle-CW1NWF0M.js → CheckCircle-dQlnEikR.js} +1 -1
- package/dist/assets/{ChevronLeft-Bc2dOBpo.js → ChevronLeft-D1jj_OCE.js} +1 -1
- package/dist/assets/{ChevronRight-y7cPaDQ3.js → ChevronRight-4B8L2FvK.js} +1 -1
- package/dist/assets/{Close-DLWmZbtN.js → Close-D9t1V0bN.js} +1 -1
- package/dist/assets/{CloseOutlined-7w3yHb7q.js → CloseOutlined-_dO3T_PC.js} +1 -1
- package/dist/assets/{Delete-FZyEAOwe.js → Delete-C1RI7dqa.js} +1 -1
- package/dist/assets/{DeleteOutline-B-H27VeQ.js → DeleteOutline-B7DWD_Pd.js} +1 -1
- package/dist/assets/{DialogContentText-CiyJlDpv.js → DialogContentText-BGwSGY20.js} +1 -1
- package/dist/assets/{Done-BEW0zhw2.js → Done-B9inxpK9.js} +1 -1
- package/dist/assets/{Download-BfRlCRO0.js → Download-Chn_mucC.js} +1 -1
- package/dist/assets/{EditIcon-CG4JGMyT.js → EditIcon-Bxcvoews.js} +1 -1
- package/dist/assets/{Error-C2cvwDlh.js → Error-CD7hXBjK.js} +1 -1
- package/dist/assets/{ExpandMore-CVPXcP59.js → ExpandMore-CZbzCTKg.js} +1 -1
- package/dist/assets/{FormControl-vM9EJwp4.js → FormControl-CVE9WL7K.js} +1 -1
- package/dist/assets/FormControlLabel-DYWd7TcF.js +1 -0
- package/dist/assets/{FormGroup-DoibujUR.js → FormGroup-DdQz-TwB.js} +1 -1
- package/dist/assets/{Google-BkswiX56.js → Google-DcVWJY2S.js} +1 -1
- package/dist/assets/{Grid-DmS931mb.js → Grid-BZnpkTQP.js} +1 -1
- package/dist/assets/{Hidden-DFLNRBK7.js → Hidden-CbAVlEDm.js} +1 -1
- package/dist/assets/{InfoOutlined-BGl9NpGF.js → InfoOutlined-NM9liF3s.js} +1 -1
- package/dist/assets/{InputAdornment-BfRAjWFP.js → InputAdornment-Bpn9HTW3.js} +1 -1
- package/dist/assets/{InputLabel-snet_z2M.js → InputLabel-RH2D4KPR.js} +1 -1
- package/dist/assets/{LastPage-KoP1Fd4R.js → LastPage-DWF6cED3.js} +1 -1
- package/dist/assets/{Launch-DaqmeZ7p.js → Launch-B6giRvog.js} +1 -1
- package/dist/assets/{LaunchOutlined-D8_8q_U2.js → LaunchOutlined-BbztgzUz.js} +1 -1
- package/dist/assets/{Link-ZwKMc2xW.js → Link-mzUHhPTN.js} +1 -1
- package/dist/assets/{LoadingButton-DAYzECCB.js → LoadingButton-BgKjZXkL.js} +1 -1
- package/dist/assets/{LockIcon-CzOlJg7E.js → LockIcon-4PWP1bDL.js} +1 -1
- package/dist/assets/{Loop-DdSi2a5X.js → Loop-P56l68QD.js} +1 -1
- package/dist/assets/MarkEmailRead-DOjMeCFe.js +1 -0
- package/dist/assets/{Menu-cPWOWdJv.js → Menu-I0j8Ts_k.js} +1 -1
- package/dist/assets/{MoreHoriz-CCaXi0-D.js → MoreHoriz-BihREYOu.js} +1 -1
- package/dist/assets/MoreVert-DDBU9EgD.js +1 -0
- package/dist/assets/{OpenInNew-DhmdNIIA.js → OpenInNew-DNUMd1Ki.js} +1 -1
- package/dist/assets/{Pagination-BXlUtx3B.js → Pagination-DFhSxhpu.js} +1 -1
- package/dist/assets/{PlayArrow-dbaJvP3i.js → PlayArrow-m_SU1GSc.js} +1 -1
- package/dist/assets/{QuestionMarkCircle-ClghFyf8.js → QuestionMarkCircle-L9oBHKLh.js} +1 -1
- package/dist/assets/{RadioGroup-h39eYIOw.js → RadioGroup-BZc2gQ3J.js} +1 -1
- package/dist/assets/{Search-Deg4mgEt.js → Search-DcpIU2VO.js} +1 -1
- package/dist/assets/{Select-D8wgZEYi.js → Select-BjqrbqwY.js} +2 -2
- package/dist/assets/{ServerLogo-C-IdWQab.js → ServerLogo-D3rrSDtL.js} +1 -1
- package/dist/assets/{Skeleton-DTHod0yi.js → Skeleton-cOZ7paOF.js} +1 -1
- package/dist/assets/{Slider-BGdMADx-.js → Slider-BPnwflNL.js} +1 -1
- package/dist/assets/{Stack-Cp3hYWEn.js → Stack-BpqXnyM6.js} +1 -1
- package/dist/assets/{Stepper-BYg7nOyi.js → Stepper-cjIW0fgZ.js} +1 -1
- package/dist/assets/{TextField-COEnibZX.js → TextField-PnwHOv_7.js} +1 -1
- package/dist/assets/{Toolbar-gvJQuyml.js → Toolbar-C46QlHj5.js} +1 -1
- package/dist/assets/{Verified-BYBUZULO.js → Verified-kWQRhAzA.js} +1 -1
- package/dist/assets/{ViewColumn-C-7sjz0Y.js → ViewColumn-di8RRjuH.js} +1 -1
- package/dist/assets/{ViewList-JViuspE8.js → ViewList-B-z7Gj50.js} +1 -1
- package/dist/assets/access-control-HU86cVDN.js +13 -0
- package/dist/assets/{actions-BvIgnlgP.js → actions-DpdmI0vS.js} +1 -1
- package/dist/assets/{add-component-core-CF3Wvpy3.js → add-component-core-C12Yk8Zd.js} +28 -28
- package/dist/assets/add-resource-B5PS9Yw0.js +1 -0
- package/dist/assets/{addon-BN5Sfj4m.js → addon-CigkkKH3.js} +1 -1
- package/dist/assets/{analytics-jhEGduS7.js → analytics-B6_E7bBR.js} +7 -7
- package/dist/assets/api-BTWN6BD3.js +1 -0
- package/dist/assets/ar-DPKr6aJE.js +1 -0
- package/dist/assets/{audit-logs-Vn5iZ4P_.js → audit-logs-BCK2xbFz.js} +1 -1
- package/dist/assets/{base32-RJwtUwTG.js → base32-CEA8NAOs.js} +1 -1
- package/dist/assets/{bundle-avatar-CYj37kYo.js → bundle-avatar-BEi2sYgQ.js} +1 -1
- package/dist/assets/{button-Bzg3GLCP.js → button-qSDF0MHZ.js} +1 -1
- package/dist/assets/{click-to-copy-BxqXxgUi.js → click-to-copy-DNMw_CsM.js} +1 -1
- package/dist/assets/{complete-DkKqvq-n.js → complete-ktDziJkp.js} +1 -1
- package/dist/assets/{component-CBSn0ylq.js → component-cpm50z3M.js} +92 -92
- package/dist/assets/{config-W5zOORTl.js → config-C98DoG5F.js} +2 -2
- package/dist/assets/config-Cpoq5q2q.js +1 -0
- package/dist/assets/{config-navigation-acog9zxt.js → config-navigation-DHqRxI1-.js} +5 -5
- package/dist/assets/{confirm-BD8lcIjf.js → confirm-CHPPgJ5w.js} +1 -1
- package/dist/assets/{connect-Cau7HJrv.js → connect-CVt7hhhZ.js} +1 -1
- package/dist/assets/{connect-DUt6GuMA.js → connect-_wsn53RM.js} +1 -1
- package/dist/assets/connect-to-BhVu4jHm.js +54 -0
- package/dist/assets/{content-layout--Pzx1mcC.js → content-layout-4m3OHN99.js} +1 -1
- package/dist/assets/{dashboard-CIOwnQZx.js → dashboard-BuNhMwdN.js} +4 -4
- package/dist/assets/de-Cl5__jPN.js +1 -0
- package/dist/assets/{deprecate-D_97v-_E.js → deprecate-DovOjub0.js} +1 -1
- package/dist/assets/{did-address-DgsfKQl1.js → did-address-CdScrBCT.js} +1 -1
- package/dist/assets/{domain-zy-h52DT.js → domain-DnltSVJm.js} +1 -1
- package/dist/assets/{domain-list-tyAcumiG.js → domain-list-CAkva7x_.js} +2 -2
- package/dist/assets/email-ByYt-V3O.js +18 -0
- package/dist/assets/emotion-cache.browser.esm-Bl95gpZS.js +1 -0
- package/dist/assets/es-BhoY4pub.js +1 -0
- package/dist/assets/{exchange-passport-DPiMkxjA.js → exchange-passport-yUOmsAsG.js} +1 -1
- package/dist/assets/{fallback-DUmnMg78.js → fallback-Ck0I8St3.js} +1 -1
- package/dist/assets/form-text-input-psgwvKm-.js +11 -0
- package/dist/assets/{format-error-D0C8Qna1.js → format-error-IawEMzuv.js} +1 -1
- package/dist/assets/fr-T--qF3dZ.js +1 -0
- package/dist/assets/{fuel-CZZpMc32.js → fuel-DYf7OlG7.js} +1 -1
- package/dist/assets/{fullpage-ov1kRa00.js → fullpage-L8eyCcID.js} +1 -1
- package/dist/assets/hi-Bkr9nxwZ.js +1 -0
- package/dist/assets/{home-gwd5aHrM.js → home-BaeqwiMV.js} +1 -1
- package/dist/assets/id-BbxiX6aD.js +1 -0
- package/dist/assets/{iframe-BIzC7nPA.js → iframe-D-vgaTgv.js} +1 -1
- package/dist/assets/index-B714sBVK.js +11 -0
- package/dist/assets/{index-BjLsHd9C.js → index-BAQvuUj1.js} +1 -1
- package/dist/assets/{index-BJmzQOKo.js → index-BNbx1KY2.js} +1 -1
- package/dist/assets/{index-Wi2p68c2.js → index-BSfUxS10.js} +1 -1
- package/dist/assets/{index-BYSwxOyW.js → index-BYtyuTe_.js} +1 -1
- package/dist/assets/index-BhWojJ48.js +316 -0
- package/dist/assets/{index-DsWS2z9f.js → index-C46QsmAx.js} +1 -1
- package/dist/assets/{index-B-DC1bkM.js → index-C4OUjclt.js} +1 -1
- package/dist/assets/index-CB7LGtSy.js +22 -0
- package/dist/assets/{index-COU4Nu6y.js → index-CKJ-4t1N.js} +1 -1
- package/dist/assets/index-CPjnF38z.js +1 -0
- package/dist/assets/{index-XlLZRf68.js → index-CUuwfStF.js} +1 -1
- package/dist/assets/{index-CES_wWCV.js → index-Cicr8_v0.js} +183 -183
- package/dist/assets/{index-BA1E4qQ4.js → index-ClPetRXB.js} +1 -1
- package/dist/assets/{index-C_0JNAm2.js → index-CmMULrYg.js} +1 -1
- package/dist/assets/{index-BcvXX_mO.js → index-CvuYuNrC.js} +1 -1
- package/dist/assets/{index-CE4JYDnG.js → index-Czj3ph5d.js} +4 -4
- package/dist/assets/{index-C2AukIic.js → index-D5IcO7Vq.js} +1 -1
- package/dist/assets/{index-D8OsCndp.js → index-D8UHLaZo.js} +1 -1
- package/dist/assets/{index-CNybmfDH.js → index-DFI3ASVb.js} +1 -1
- package/dist/assets/{index-bwXQ8Wpi.js → index-DH0OTY_E.js} +1 -1
- package/dist/assets/{index-DcKMlzdo.js → index-DLuD4Ybl.js} +1 -1
- package/dist/assets/{index-Bv4e_rV5.js → index-DTIMKD2Z.js} +1 -1
- package/dist/assets/{index-QTPBiLZh.js → index-DZJ5Xczt.js} +1 -1
- package/dist/assets/{index-AfbTuUW5.js → index-DZvaAYzJ.js} +7 -7
- package/dist/assets/{index-B8-zdW7s.js → index-DpBCF5xl.js} +1 -1
- package/dist/assets/{index-DS-kwJv8.js → index-DpYNQxep.js} +1 -1
- package/dist/assets/index-DtlYOQGh.js +5 -0
- package/dist/assets/index-DzjvRcZX.js +126 -0
- package/dist/assets/{index-Q7ZUJ_jr.js → index-MuwP8CmB.js} +11 -11
- package/dist/assets/{index-BqpKWYMh.js → index-VWtFyzkK.js} +1 -1
- package/dist/assets/{index-DW7dwoqE.js → index-b3txmGPa.js} +1 -1
- package/dist/assets/index-e3kJGRQs.js +1 -0
- package/dist/assets/{index-rOGdJKYL.js → index-eMi3myGI.js} +1 -1
- package/dist/assets/index-lIQZq2T1.js +1 -0
- package/dist/assets/{index.es-HA92kWdG.js → index.es-omOswc9R.js} +3 -3
- package/dist/assets/{invitation-B49_oImo.js → invitation-tEQ5ZLGQ.js} +1 -1
- package/dist/assets/{invite-V3Nbkyr9.js → invite-BL9JwrO-.js} +1 -1
- package/dist/assets/{issue-passport-BK_rmsMU.js → issue-passport-B4cIxbeW.js} +1 -1
- package/dist/assets/{item-ChdkonTR.js → item--EFKzxT4.js} +1 -1
- package/dist/assets/ja-B5UxYW93.js +1 -0
- package/dist/assets/{jss-plugin-props-sort.esm-DBVL9gMW.js → jss-plugin-props-sort.esm-CwzPC0-q.js} +5 -5
- package/dist/assets/ko-CpyVmdoA.js +1 -0
- package/dist/assets/{launch-result-message-BAr02bV5.js → launch-result-message-D3lgLPek.js} +1 -1
- package/dist/assets/{layout-bf8MnH7p.js → layout-CeB8tvZm.js} +1 -1
- package/dist/assets/{list-header-BdXS3bwO.js → list-header-BEHCrfI7.js} +1 -1
- package/dist/assets/localization-DMO6m7q5.js +1 -0
- package/dist/assets/{log-CEafQKJ9.js → log-BA8otNYe.js} +1 -1
- package/dist/assets/{login-CEkmeGqM.js → login-MJNn4jX3.js} +1 -1
- package/dist/assets/{login-oauth-callback-BKsN-may.js → login-oauth-callback-a4ix1w_Y.js} +1 -1
- package/dist/assets/logo-uploader-D3WhF6vw.js +133 -0
- package/dist/assets/{lost-passport-BKV23uoE.js → lost-passport-BqI_ADgq.js} +3 -3
- package/dist/assets/{lottie-Bmh0Xil_.js → lottie-CKskIEos.js} +1 -1
- package/dist/assets/notifications-BuezJhNN.js +65 -0
- package/dist/assets/{open-window-BxfESFgZ.js → open-window-vG7gxIZq.js} +1 -1
- package/dist/assets/overview-pVXjVv4f.js +12 -0
- package/dist/assets/{page-header-C6Www8xa.js → page-header-CDbgUvxH.js} +1 -1
- package/dist/assets/{permission-C0wbV6KF.js → permission-CC_4NjQs.js} +1 -1
- package/dist/assets/{preferences-DgOndnl4.js → preferences-AiiMUULa.js} +1 -1
- package/dist/assets/pt-DNYyqLg4.js +1 -0
- package/dist/assets/publish-resource-C2uzL0M9.js +1 -0
- package/dist/assets/purify.es-Bq0E5Q3l.js +2 -0
- package/dist/assets/react-BeNwKB5d.js +56 -0
- package/dist/assets/{redux-B8mroqAb.js → redux-CSFGRixa.js} +1 -1
- package/dist/assets/refType-D_QSkOey.js +1 -0
- package/dist/assets/resource-dialog-CE8xTvOH.js +4 -0
- package/dist/assets/ru-iLN_KAH_.js +1 -0
- package/dist/assets/sdk-DxG_dISZ.js +1 -0
- package/dist/assets/{selector-B2UrJyEC.js → selector-D17_2gf0.js} +1 -1
- package/dist/assets/session-D-foQV_d.js +1 -0
- package/dist/assets/setup-Ctq13rGM.js +19 -0
- package/dist/assets/{shorten-label-C69K-2N4.js → shorten-label-DH9SHtdj.js} +1 -1
- package/dist/assets/simple-select-BxJC7ug8.js +1 -0
- package/dist/assets/{slicedToArray-Btbq_uXo.js → slicedToArray-iU9d1Nzl.js} +2 -2
- package/dist/assets/{spaces-CKA3haGw.js → spaces-zoAgXjLC.js} +1 -1
- package/dist/assets/{start-E4q8KtSK.js → start-DMZbLY0L.js} +1 -1
- package/dist/assets/{step-actions-Dv65pQs7.js → step-actions-oojkqr2w.js} +1 -1
- package/dist/assets/{studio-C9Z81BQt.js → studio-Dcd2i5DA.js} +1 -1
- package/dist/assets/{switch-control-Cct9SW8-.js → switch-control-DA8reBy9.js} +1 -1
- package/dist/assets/th-pEKbhX2z.js +1 -0
- package/dist/assets/{toUpper-DjVC4j_j.js → toUpper-SILegrQ3.js} +1 -1
- package/dist/assets/{transfer-W8UlEJt-.js → transfer-B7uXnaTg.js} +1 -1
- package/dist/assets/trim-DtY2mn6M.js +1 -0
- package/dist/assets/{uniqBy-BzzuWGYh.js → uniqBy-CqrMZpMi.js} +1 -1
- package/dist/assets/{unsubscribe-BkeOgqWI.js → unsubscribe-Dckvx5GC.js} +1 -1
- package/dist/assets/{url-join-BLh7jCrJ.js → url-join-MhXUJvvH.js} +1 -1
- package/dist/assets/use-blocklet-info-for-connect-did-spaces-wq894EOf.js +1 -0
- package/dist/assets/{use-mobile-BJoJTGF0.js → use-mobile-B1qMoH4W.js} +1 -1
- package/dist/assets/{useAsync-CvPpFYs-.js → useAsync-DwqCgR5n.js} +1 -1
- package/dist/assets/{useFormControl-BXRE7Su9.js → useFormControl-581SE09O.js} +1 -1
- package/dist/assets/{useLocalStorage-BJH73q2r.js → useLocalStorage-2QP2xSVk.js} +1 -1
- package/dist/assets/{useSetState-CJBhbXdV.js → useSetState-xUMH0B_e.js} +1 -1
- package/dist/assets/{useSlot-BnpRF9Wf.js → useSlot-1YlTOkWf.js} +1 -1
- package/dist/assets/{useSlotProps-Bo-Lx2a7.js → useSlotProps-CH7A38KN.js} +1 -1
- package/dist/assets/{useThemeProps-NLTP4qET.js → useThemeProps-2Eh-Pntu.js} +1 -1
- package/dist/assets/user-center-DLGGLlGO.js +1 -0
- package/dist/assets/{user-sessions-9jxxDLYT.js → user-sessions-BYM0F6ns.js} +1 -1
- package/dist/assets/{util-ZHGnEGmF.js → util-CTLIHCQ7.js} +1 -1
- package/dist/assets/vi-CNA5ZRDz.js +1 -0
- package/dist/assets/wrap-locale-kin7AMXS.js +1 -0
- package/dist/assets/zh-C91ux8Ex.js +2 -0
- package/dist/assets/zh-tw-wIRljAO1.js +1 -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/FormControlLabel-CS28YgVs.js +0 -1
- package/dist/assets/MoreVert-D4SS6MnA.js +0 -1
- 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-rur8F6ox.js +0 -1
- 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/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/fr-RdOP2uWC.js +0 -1
- package/dist/assets/hi-V6iw7v5V.js +0 -1
- package/dist/assets/id-CeB6Ugb-.js +0 -1
- package/dist/assets/index-BHXHtIJm.js +0 -126
- package/dist/assets/index-CXg0jLCN.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-DlWywLev.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/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/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-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/user-center-DSwKYf1W.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-CT0fSzRS.js +0 -2
- package/dist/assets/zh-tw-i93Px0uV.js +0 -1
package/api/routes/oauth.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
const { handleInvitationReceive, getApplicationInfo } = require('@abtnode/auth/lib/auth');
|
|
2
2
|
const { upsertToPassports, createPassportSvg } = require('@abtnode/auth/lib/passport');
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
WELLKNOWN_SERVICE_PATH_PREFIX,
|
|
5
|
+
PASSPORT_STATUS,
|
|
6
|
+
ROLES,
|
|
7
|
+
SECURITY_RULE_DEFAULT_ID,
|
|
8
|
+
} = require('@abtnode/constant');
|
|
4
9
|
const { extractUserAvatar, getUserAvatarUrl, getAppAvatarUrl } = require('@abtnode/util/lib/user');
|
|
5
10
|
const { fromAppDid } = require('@arcblock/did-ext');
|
|
6
11
|
const { getBlockletAppIdList } = require('@blocklet/meta/lib/util');
|
|
@@ -28,7 +33,7 @@ const OAuthApple = require('../libs/auth/adapters/apple');
|
|
|
28
33
|
const { getAvatarByEmail, transferPassport, getAvatarByUrl } = require('../libs/auth/utils');
|
|
29
34
|
const initJwt = require('../libs/jwt');
|
|
30
35
|
const { sendToUser } = require('../libs/notification');
|
|
31
|
-
const {
|
|
36
|
+
const { checkInvitedUserOnly, createTokenFn, getDidConnectVersion, redirectWithoutCache } = require('../util');
|
|
32
37
|
const { ApiError } = require('../util/error');
|
|
33
38
|
const federatedUtil = require('../util/federated');
|
|
34
39
|
const { isOAuthEmailVerified, isEmailUniqueRequired, isEmailKycRequired, isSameEmail } = require('../libs/kyc');
|
|
@@ -172,7 +177,7 @@ function getAuthClient(blocklet, provider, { legacy = false, appPid } = {}) {
|
|
|
172
177
|
|
|
173
178
|
async function login(req, node, options) {
|
|
174
179
|
const blocklet = await req.getBlocklet();
|
|
175
|
-
const { locale = 'en', provider,
|
|
180
|
+
const { locale = 'en', provider, inviter = null, sourceAppPid = null } = req.body;
|
|
176
181
|
let visitorId = req.body?.visitorId;
|
|
177
182
|
if (!visitorId) {
|
|
178
183
|
visitorId = req.get('x-blocklet-visitor-id');
|
|
@@ -189,11 +194,10 @@ async function login(req, node, options) {
|
|
|
189
194
|
const userDid = userWallet.address;
|
|
190
195
|
const userPk = userWallet.publicKey;
|
|
191
196
|
|
|
192
|
-
|
|
193
|
-
const config = await req.getServiceConfig(NODE_SERVICES.AUTH, { componentId });
|
|
197
|
+
const { accessPolicyConfig } = await req.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
|
|
194
198
|
const nodeInfo = await req.getNodeInfo();
|
|
195
199
|
const { dataDir } = await getApplicationInfo({ node, nodeInfo, teamDid });
|
|
196
|
-
const
|
|
200
|
+
const isInvitedUserOnly = await checkInvitedUserOnly(accessPolicyConfig, node, teamDid);
|
|
197
201
|
|
|
198
202
|
const lastLoginIp = getRequestIP(req);
|
|
199
203
|
let passport = { name: 'Guest', role: 'guest' };
|
|
@@ -248,7 +252,7 @@ async function login(req, node, options) {
|
|
|
248
252
|
let avatar = oauthInfo.picture ? await getAvatarByUrl(oauthInfo.picture) : await getAvatarByEmail(oauthInfo.email);
|
|
249
253
|
avatar = await extractUserAvatar(avatar, { dataDir });
|
|
250
254
|
// 当前 oauth 账户不存在,自动添加一个新用户
|
|
251
|
-
if (
|
|
255
|
+
if (isInvitedUserOnly) {
|
|
252
256
|
throw new ApiError(403, t('needInviteToLogin', locale));
|
|
253
257
|
}
|
|
254
258
|
|
|
@@ -93,27 +93,27 @@ module.exports = {
|
|
|
93
93
|
// NOTE: 保留 /login 路由,该功能不是针对于某一个实体来操作的,需要更明确表达意图
|
|
94
94
|
app.post(`${prefix}/login`, ensureBlocklet(), async (req, res) => {
|
|
95
95
|
const { blocklet } = req;
|
|
96
|
-
const
|
|
96
|
+
const loginUserSession = req.body;
|
|
97
97
|
let visitorId = req.body?.visitorId;
|
|
98
98
|
if (!visitorId) {
|
|
99
99
|
visitorId = req.get('x-blocklet-visitor-id');
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
if (!userDid) {
|
|
102
|
+
if (!loginUserSession.userDid) {
|
|
103
103
|
res.status(400).json({ error: 'userDid is required' });
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
|
-
if (!appPid) {
|
|
106
|
+
if (!loginUserSession.appPid) {
|
|
107
107
|
res.status(400).json({ error: 'appPid is required' });
|
|
108
108
|
return;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
const teamDid = blocklet.appPid;
|
|
112
|
-
|
|
113
112
|
const userSessions = await node.getUserSession({
|
|
114
113
|
teamDid,
|
|
115
|
-
userDid,
|
|
114
|
+
userDid: loginUserSession.userDid,
|
|
116
115
|
visitorId,
|
|
116
|
+
id: loginUserSession.id,
|
|
117
117
|
});
|
|
118
118
|
const now = Date.now();
|
|
119
119
|
const sessionTtl = blocklet.settings?.session?.ttl || SESSION_TTL;
|
|
@@ -122,7 +122,7 @@ module.exports = {
|
|
|
122
122
|
const validSession = sortedUserSessions.some((x) => now - new Date(x.updatedAt).getTime() < sessionTtl * 1000);
|
|
123
123
|
|
|
124
124
|
if (validSession) {
|
|
125
|
-
const user = await node.getUser({ teamDid, user: { did: userDid } });
|
|
125
|
+
const user = await node.getUser({ teamDid, user: { did: loginUserSession.userDid } });
|
|
126
126
|
if (!user.approved) {
|
|
127
127
|
res.status(401).json(messages.notAllowedAppUser.en);
|
|
128
128
|
return;
|
|
@@ -138,7 +138,9 @@ module.exports = {
|
|
|
138
138
|
|
|
139
139
|
const provider = sourceProvider || LOGIN_PROVIDER.WALLET;
|
|
140
140
|
|
|
141
|
-
const memberSite = federated.sites.find(
|
|
141
|
+
const memberSite = federated.sites.find(
|
|
142
|
+
(item) => item.appPid === loginUserSession.appPid && item.isMaster === false
|
|
143
|
+
);
|
|
142
144
|
const postUser = pick(user, ['did', 'pk', 'fullName', 'locale', 'inviter', 'generation']);
|
|
143
145
|
postUser.lastLoginAt = getRequestIP(req);
|
|
144
146
|
|
|
@@ -160,7 +162,7 @@ module.exports = {
|
|
|
160
162
|
did: teamDid,
|
|
161
163
|
data: {
|
|
162
164
|
user: postUser,
|
|
163
|
-
passport: passportId ? { id: passportId } : undefined,
|
|
165
|
+
passport: loginUserSession.passportId ? { id: loginUserSession.passportId } : undefined,
|
|
164
166
|
walletOS,
|
|
165
167
|
provider,
|
|
166
168
|
},
|
|
@@ -179,7 +181,9 @@ module.exports = {
|
|
|
179
181
|
const createToken = createTokenFn(createSessionToken);
|
|
180
182
|
const { secret } = await req.getBlockletInfo();
|
|
181
183
|
const sessionConfig = blocklet.settings?.session || {};
|
|
182
|
-
const targetPassport =
|
|
184
|
+
const targetPassport = loginUserSession.passportId
|
|
185
|
+
? (user?.passports || []).find((item) => item.id === loginUserSession.passportId)
|
|
186
|
+
: null;
|
|
183
187
|
const loggedInUser = await node.loginUser({
|
|
184
188
|
teamDid,
|
|
185
189
|
user: {
|
|
@@ -219,11 +223,12 @@ module.exports = {
|
|
|
219
223
|
const walletDeviceId = req.get('wallet-device-id');
|
|
220
224
|
|
|
221
225
|
const userSessionDoc = await node.upsertUserSession({
|
|
226
|
+
id: loginUserSession.id,
|
|
222
227
|
teamDid,
|
|
223
|
-
userDid,
|
|
228
|
+
userDid: loginUserSession.userDid,
|
|
224
229
|
visitorId,
|
|
225
|
-
appPid,
|
|
226
|
-
passportId,
|
|
230
|
+
appPid: loginUserSession.appPid,
|
|
231
|
+
passportId: loginUserSession.passportId,
|
|
227
232
|
status: 'online',
|
|
228
233
|
ua,
|
|
229
234
|
lastLoginIp,
|
|
@@ -237,10 +242,10 @@ module.exports = {
|
|
|
237
242
|
if (isFederatedLogin) {
|
|
238
243
|
node.syncUserSession({
|
|
239
244
|
teamDid,
|
|
240
|
-
userDid,
|
|
245
|
+
userDid: loginUserSession.userDid,
|
|
241
246
|
visitorId: userSessionDoc.visitorId,
|
|
242
|
-
passportId,
|
|
243
|
-
targetAppPid: appPid,
|
|
247
|
+
passportId: loginUserSession.passportId,
|
|
248
|
+
targetAppPid: loginUserSession.appPid,
|
|
244
249
|
ua,
|
|
245
250
|
lastLoginIp,
|
|
246
251
|
extra: {
|
|
@@ -254,9 +259,9 @@ module.exports = {
|
|
|
254
259
|
logger.info('quick-login with', {
|
|
255
260
|
teamDid,
|
|
256
261
|
visitorId,
|
|
257
|
-
userDid,
|
|
258
|
-
appPid,
|
|
259
|
-
passportId,
|
|
262
|
+
userDid: loginUserSession.userDid,
|
|
263
|
+
appPid: loginUserSession.appPid,
|
|
264
|
+
passportId: loginUserSession.passportId,
|
|
260
265
|
extra: {
|
|
261
266
|
walletOS,
|
|
262
267
|
},
|
|
@@ -267,17 +272,22 @@ module.exports = {
|
|
|
267
272
|
logger.warn('failed to quick-login with', {
|
|
268
273
|
teamDid,
|
|
269
274
|
visitorId,
|
|
270
|
-
userDid,
|
|
271
|
-
appPid,
|
|
272
|
-
passportId,
|
|
275
|
+
userDid: loginUserSession.userDid,
|
|
276
|
+
appPid: loginUserSession.appPid,
|
|
277
|
+
passportId: loginUserSession.passportId,
|
|
273
278
|
});
|
|
274
|
-
res.status(
|
|
279
|
+
res.status(401).json({ error: 'session expired' });
|
|
275
280
|
}
|
|
276
281
|
});
|
|
277
282
|
|
|
283
|
+
/**
|
|
284
|
+
* 获取指定用户的所有登录会话
|
|
285
|
+
*/
|
|
278
286
|
app.get(`${prefix}`, ensureBlocklet(), async (req, res) => {
|
|
279
287
|
const { blocklet } = req;
|
|
280
288
|
const teamDid = blocklet.appPid;
|
|
289
|
+
const requestIp = getRequestIP(req);
|
|
290
|
+
const userAgent = req.get('user-agent');
|
|
281
291
|
|
|
282
292
|
// NOTICE: 此处的 visitorId 必须显式传入,否则用户将无法正常查询自己的所有 sessions
|
|
283
293
|
const { userDid, appPid, visitorId } = req.query;
|
|
@@ -308,7 +318,12 @@ module.exports = {
|
|
|
308
318
|
|
|
309
319
|
// NOTICE: 移除 walletDeviceId 和 walletDeviceMessageToken,避免泄露
|
|
310
320
|
const result = userSessions
|
|
311
|
-
.filter((x) =>
|
|
321
|
+
.filter((x) => {
|
|
322
|
+
if (x.lastLoginIp !== requestIp || x.ua !== userAgent || x.status === 'expired') {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
return x?.user?.approved;
|
|
326
|
+
})
|
|
312
327
|
.map((x) => {
|
|
313
328
|
return omit(x, ['extra.walletDeviceId', 'extra.walletDeviceMessageToken']);
|
|
314
329
|
});
|
package/api/routes/user.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { WELLKNOWN_SERVICE_PATH_PREFIX, SECURITY_RULE_DEFAULT_ID } = require('@abtnode/constant');
|
|
2
2
|
const { getApplicationInfo } = require('@abtnode/auth/lib/auth');
|
|
3
3
|
const { fromAppDid } = require('@arcblock/did-ext');
|
|
4
4
|
const { extractUserAvatar } = require('@abtnode/util/lib/user');
|
|
@@ -17,7 +17,7 @@ const { Joi } = require('@arcblock/validator');
|
|
|
17
17
|
const { parse } = require('@abtnode/core/lib/util/ua');
|
|
18
18
|
const getRequestIP = require('@abtnode/util/lib/get-request-ip');
|
|
19
19
|
|
|
20
|
-
const {
|
|
20
|
+
const { checkInvitedUserOnly, createTokenFn, getDidConnectVersion } = require('../util');
|
|
21
21
|
const initJwt = require('../libs/jwt');
|
|
22
22
|
const { getAvatarByUrl } = require('../libs/auth/utils');
|
|
23
23
|
const { ApiError } = require('../util/error');
|
|
@@ -61,10 +61,10 @@ const translations = {
|
|
|
61
61
|
|
|
62
62
|
const t = createTranslator({ translations });
|
|
63
63
|
|
|
64
|
-
async function checkNeedInvite({ req, node, teamDid,
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
64
|
+
async function checkNeedInvite({ req, node, teamDid, locale }) {
|
|
65
|
+
const { accessPolicyConfig } = await req.getSecurityConfig({ id: SECURITY_RULE_DEFAULT_ID });
|
|
66
|
+
const isInvitedUserOnly = await checkInvitedUserOnly(accessPolicyConfig, node, teamDid);
|
|
67
|
+
if (isInvitedUserOnly) {
|
|
68
68
|
throw new ApiError(403, t('needInviteToLogin', locale));
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -467,7 +467,6 @@ module.exports = {
|
|
|
467
467
|
if (error) {
|
|
468
468
|
throw new ApiError(400, error.message);
|
|
469
469
|
}
|
|
470
|
-
// FIXME: @zhanghan 需要根据 componentId 来判断当前 component 设置的访问权限,来看当前要登录的用户是否有登录的权限
|
|
471
470
|
const blocklet = await req.getBlocklet();
|
|
472
471
|
const { did: teamDid, secret } = await req.getBlockletInfo();
|
|
473
472
|
const currentUser = await verifyUserSig(
|
|
@@ -4,17 +4,9 @@ const cookie = require('cookie');
|
|
|
4
4
|
const bearerToken = require('@abtnode/util/lib/express-bearer-token');
|
|
5
5
|
|
|
6
6
|
const validators = require('@blocklet/sdk/lib/validators');
|
|
7
|
-
const {
|
|
8
|
-
genPermissionName,
|
|
9
|
-
NODE_SERVICES,
|
|
10
|
-
WHO_CAN_ACCESS,
|
|
11
|
-
WHO_CAN_ACCESS_PREFIX_ROLES,
|
|
12
|
-
ROLES,
|
|
13
|
-
WELLKNOWN_SERVICE_PATH_PREFIX,
|
|
14
|
-
} = require('@abtnode/constant');
|
|
7
|
+
const { NODE_SERVICES, ROLES, WELLKNOWN_SERVICE_PATH_PREFIX } = require('@abtnode/constant');
|
|
15
8
|
const { BLOCKLET_MODES } = require('@blocklet/constant');
|
|
16
9
|
const { setUserInfoHeaders } = require('@abtnode/auth/lib/auth');
|
|
17
|
-
const { getRolesFromAuthConfig } = require('@blocklet/meta/lib/util');
|
|
18
10
|
|
|
19
11
|
const { createConnectToDidSpacesRoute } = require('@abtnode/auth/lib/connect-to-did-spaces');
|
|
20
12
|
const logger = require('../../libs/logger')('auth');
|
|
@@ -90,9 +82,9 @@ const init = ({ node, options }) => {
|
|
|
90
82
|
* @returns {CheckAuthRes} res
|
|
91
83
|
*/
|
|
92
84
|
const checkAuth = async ({ req } = {}) => {
|
|
93
|
-
const
|
|
85
|
+
const serviceConfig = (await req.getServiceConfig(NODE_SERVICES.AUTH)) || {};
|
|
94
86
|
|
|
95
|
-
const ignoreUrls = (get(
|
|
87
|
+
const ignoreUrls = (get(serviceConfig, 'ignoreUrls') || []).filter(Boolean);
|
|
96
88
|
|
|
97
89
|
// default public url
|
|
98
90
|
// developers need not config the following urls in blocklet.yml
|
|
@@ -105,47 +97,35 @@ const init = ({ node, options }) => {
|
|
|
105
97
|
|
|
106
98
|
const teamDid = req.getBlockletDid();
|
|
107
99
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
100
|
+
const rbac = await node.getRBAC(teamDid);
|
|
101
|
+
const [allRoles, { accessPolicyConfig }] = await Promise.all([rbac.getRoles(teamDid), req.getSecurityConfig()]);
|
|
102
|
+
|
|
103
|
+
const accessRoles = accessPolicyConfig?.accessPolicy?.roles || null;
|
|
104
|
+
const accessReverse = accessPolicyConfig?.accessPolicy?.reverse || false;
|
|
105
|
+
|
|
106
|
+
// public 公开权限,不做任何拦截
|
|
107
|
+
if (accessRoles === null && accessReverse === false) {
|
|
108
|
+
return { ignored: true };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// invite only, 需要被邀请才能访问的情况
|
|
112
|
+
// HACK: 不是公开的情况下,就是需要有通行证才能访问,此时只需要判断 req.user 是否存在即可
|
|
113
|
+
// if (accessRoles.length === 0 && accessReverse === true) {}
|
|
114
|
+
if (!req.user) {
|
|
120
115
|
const payableRole = allRoles.find((x) => x.extra?.acquire?.pay);
|
|
121
116
|
return {
|
|
122
117
|
blocked: true,
|
|
123
118
|
authenticated: false,
|
|
124
119
|
payable: payableRole?.extra?.acquire?.pay,
|
|
125
120
|
};
|
|
126
|
-
}
|
|
127
|
-
// 需要 owner 才能访问
|
|
128
|
-
return {
|
|
129
|
-
blocked: true,
|
|
130
|
-
authenticated: true,
|
|
131
|
-
authorized: false,
|
|
132
|
-
requiredRoles: [
|
|
133
|
-
{
|
|
134
|
-
name: ROLES.OWNER,
|
|
135
|
-
title: 'Owner',
|
|
136
|
-
description: 'Owner',
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
};
|
|
140
|
-
} else if (config.whoCanAccess.startsWith(WHO_CAN_ACCESS_PREFIX_ROLES)) {
|
|
141
|
-
// 指定 passport 才能访问
|
|
142
|
-
// 需要用户拥有的权限
|
|
143
|
-
const roles = getRolesFromAuthConfig(config);
|
|
144
|
-
if (!roles.includes(req.user.role)) {
|
|
145
|
-
const rbac = await node.getRBAC(teamDid);
|
|
146
|
-
// 系统中的所有权限
|
|
147
|
-
const allRoles = await rbac.getRoles(teamDid);
|
|
121
|
+
}
|
|
148
122
|
|
|
123
|
+
// 指定 role 访问权限
|
|
124
|
+
if (accessRoles.length > 0) {
|
|
125
|
+
const roles = accessReverse
|
|
126
|
+
? allRoles.filter((role) => !accessRoles.includes(role.name)).map((role) => role.name)
|
|
127
|
+
: accessRoles;
|
|
128
|
+
if (!roles.includes(req.user.role)) {
|
|
149
129
|
return {
|
|
150
130
|
blocked: true,
|
|
151
131
|
authenticated: true,
|
|
@@ -176,22 +156,6 @@ const init = ({ node, options }) => {
|
|
|
176
156
|
}
|
|
177
157
|
}
|
|
178
158
|
|
|
179
|
-
if (!config.blockUnauthorized) {
|
|
180
|
-
return { ignored: true, ignoreReason: 'blockUnauthorized' };
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const rule = await req.getRoutingRule();
|
|
184
|
-
if (rule.to && rule.to.interfaceName) {
|
|
185
|
-
const permissionName = genPermissionName(rule.to.interfaceName);
|
|
186
|
-
const rbac = await node.getRBAC(teamDid);
|
|
187
|
-
|
|
188
|
-
if (await rbac.can(req.user.role, ...permissionName.split('_'))) {
|
|
189
|
-
return {};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return { blocked: true, authenticated: true, authorized: false };
|
|
193
|
-
}
|
|
194
|
-
|
|
195
159
|
return {};
|
|
196
160
|
};
|
|
197
161
|
|
|
@@ -312,6 +276,7 @@ const init = ({ node, options }) => {
|
|
|
312
276
|
setUserInfoHeaders(req);
|
|
313
277
|
|
|
314
278
|
const { blocked } = await checkAuth({ req });
|
|
279
|
+
|
|
315
280
|
if (blocked) {
|
|
316
281
|
const component = await req.getComponent();
|
|
317
282
|
if (component?.mode === 'development') {
|
|
@@ -353,6 +318,7 @@ const init = ({ node, options }) => {
|
|
|
353
318
|
return next();
|
|
354
319
|
};
|
|
355
320
|
|
|
321
|
+
// 检查是否符合访问权限控制,不符合的就进行重定向
|
|
356
322
|
middlewares.checkAuth = async (req, res, next) => {
|
|
357
323
|
res.locals.auth = await checkAuth({ req });
|
|
358
324
|
const { blocked, authenticated, authorized, payable, requiredRoles } = res.locals.auth;
|
|
@@ -380,7 +346,11 @@ const init = ({ node, options }) => {
|
|
|
380
346
|
getRedirectUrl({
|
|
381
347
|
req,
|
|
382
348
|
pagePath: '/login',
|
|
383
|
-
params: {
|
|
349
|
+
params: {
|
|
350
|
+
authenticated: 1,
|
|
351
|
+
payable,
|
|
352
|
+
requiredRoles: JSON.stringify(requiredRoles),
|
|
353
|
+
},
|
|
384
354
|
})
|
|
385
355
|
);
|
|
386
356
|
} else {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
const get = require('lodash/get');
|
|
2
|
+
const { joinURL, parseURL } = require('ufo');
|
|
3
|
+
const pathToRegExp = require('path-to-regexp');
|
|
2
4
|
|
|
3
|
-
const {
|
|
5
|
+
const { findComponentByIdV2, getMountPoints } = require('@blocklet/meta/lib/util');
|
|
4
6
|
const { getDefaultServiceConfig } = require('@blocklet/meta/lib/service');
|
|
5
|
-
const
|
|
6
|
-
const cache = require('../cache');
|
|
7
|
+
const logger = require('@abtnode/logger')('@abtnode/blocklet-services:security');
|
|
7
8
|
|
|
9
|
+
const cache = require('../cache');
|
|
8
10
|
const formatContext = require('./format-context');
|
|
9
|
-
const getDynamicServiceConfig = require('./get-dynamic-service-config');
|
|
10
11
|
const getStaticServiceConfig = require('./get-static-service-config');
|
|
11
12
|
const initJwt = require('../libs/jwt');
|
|
13
|
+
const { isFeDev } = require('../libs/env');
|
|
12
14
|
|
|
13
15
|
module.exports = ({ node, req, options }) => {
|
|
14
16
|
req.getBlockletDid = () => req.headers['x-blocklet-did'] || get(options, 'blockletDid', '');
|
|
@@ -62,26 +64,14 @@ module.exports = ({ node, req, options }) => {
|
|
|
62
64
|
return defaultConfig;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
let appDynamicConfig = getDynamicServiceConfig(serviceName, app);
|
|
66
|
-
if (appDynamicConfig?.whoCanAccess === WHO_CAN_ACCESS.ALL) {
|
|
67
|
-
appDynamicConfig = null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
67
|
const _componentId = componentId || req.getBlockletComponentId();
|
|
71
68
|
|
|
72
69
|
const componentStaticConfig = getStaticServiceConfig(serviceName, app, _componentId);
|
|
73
70
|
|
|
74
|
-
const config = { ...defaultConfig, ...componentStaticConfig
|
|
75
|
-
|
|
76
|
-
const component = findComponentById(app, _componentId);
|
|
77
|
-
|
|
78
|
-
if (!component) {
|
|
79
|
-
return config;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const componentDynamicConfig = getDynamicServiceConfig(serviceName, component, { type: 'component' });
|
|
71
|
+
const config = { ...defaultConfig, ...componentStaticConfig };
|
|
72
|
+
delete config.whoCanAccess;
|
|
83
73
|
|
|
84
|
-
return
|
|
74
|
+
return config;
|
|
85
75
|
};
|
|
86
76
|
|
|
87
77
|
req.getBlocklet = ({ useCache = true, attachRuntimeInfo = false } = {}) => {
|
|
@@ -149,6 +139,106 @@ module.exports = ({ node, req, options }) => {
|
|
|
149
139
|
}
|
|
150
140
|
};
|
|
151
141
|
|
|
142
|
+
/**
|
|
143
|
+
* @description 获取指定请求的安全配置(默认获取当前请求的安全配置,可以指定 url,也可以指定 ID)
|
|
144
|
+
* @param {object} [options]
|
|
145
|
+
* @param {object} [options.req] - 请求对象,默认为当前请求对象
|
|
146
|
+
* @param {string} [options.url] - 指定的 URL
|
|
147
|
+
* @param {string} [options.id] - 指定的 security-rule ID
|
|
148
|
+
* @param {string} [options.componentDid] - 指定的 component DID
|
|
149
|
+
* @returns {Promise<object | null>}
|
|
150
|
+
*/
|
|
151
|
+
req.getSecurityConfig = async ({ req: inputReq = req, url: inputUrl, id, componentDid: inputComponentDid } = {}) => {
|
|
152
|
+
const defaultConfig = {
|
|
153
|
+
accessPolicyConfig: null,
|
|
154
|
+
responseHeaderPolicyConfig: null,
|
|
155
|
+
};
|
|
156
|
+
const rawUrl = inputUrl || inputReq.originalUrl;
|
|
157
|
+
const currentUrl = parseURL(rawUrl).pathname;
|
|
158
|
+
// NOTICE: 排除 node_modules, .yalc 等目录下的请求,这部分没有必要做安全处理
|
|
159
|
+
if (currentUrl.startsWith('/node_modules') || currentUrl.startsWith('/.yalc') || currentUrl.includes('/@fs/')) {
|
|
160
|
+
return defaultConfig;
|
|
161
|
+
}
|
|
162
|
+
// NOTICE: 如果 service 处于开发环境中,则会有很多 vite 相关的请求,这部分不需要做安全处理
|
|
163
|
+
if (
|
|
164
|
+
isFeDev &&
|
|
165
|
+
(currentUrl.startsWith('/.well-known/service/node_modules/') ||
|
|
166
|
+
currentUrl.startsWith('/.well-known/service/src/') ||
|
|
167
|
+
currentUrl.startsWith('/.well-known/service/@react-refresh') ||
|
|
168
|
+
currentUrl.startsWith('/.well-known/service/@vite/client'))
|
|
169
|
+
) {
|
|
170
|
+
return defaultConfig;
|
|
171
|
+
}
|
|
172
|
+
// NOTICE: 如果当前连接是 websocket,则 inputReq 上不包含 get 方法,需要读取 header 只能通过 inputReq.headers 来获取
|
|
173
|
+
// HACK: ws 链接默认不拦截,ws 不会携带 cookie,无法进行 access 的权限判断,目前只能默认放行
|
|
174
|
+
if (inputReq.headers.upgrade && inputReq.headers.upgrade.toLowerCase() === 'websocket') {
|
|
175
|
+
return defaultConfig;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const blockletDid = inputReq.getBlockletDid();
|
|
179
|
+
|
|
180
|
+
const getDataFn = async () => {
|
|
181
|
+
try {
|
|
182
|
+
let componentPrefix = inputReq.get('x-path-prefix') || '/';
|
|
183
|
+
const blocklet = await inputReq.getBlocklet();
|
|
184
|
+
const componentMountPoints = getMountPoints(blocklet);
|
|
185
|
+
|
|
186
|
+
if (inputComponentDid) {
|
|
187
|
+
const customComponent = componentMountPoints.find((x) => x.did === inputComponentDid);
|
|
188
|
+
if (customComponent) {
|
|
189
|
+
componentPrefix = customComponent.mountPoint;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// NOTICE: 上面拿到的 originalUrl 是被移除了 componentPrefix 的 URL,所以需要重新拼接;如果指定了要匹配的 URL,就不需要拼接 componentPrefix 了
|
|
194
|
+
const realUrl = inputUrl || joinURL(componentPrefix, currentUrl);
|
|
195
|
+
|
|
196
|
+
const { securityRules } = await node.getBlockletSecurityRules({ did: blockletDid, formated: true });
|
|
197
|
+
if (id) {
|
|
198
|
+
// NOTICE: 在指定 ID 的情况下,可能会查不到,这时候需要返回默认配置
|
|
199
|
+
return securityRules.find((rule) => rule.id === id) ?? defaultConfig;
|
|
200
|
+
}
|
|
201
|
+
const matchedAccessPolicyRules = [];
|
|
202
|
+
const matchedResponseHeaderPolicyRules = [];
|
|
203
|
+
|
|
204
|
+
for (const securityRuleItem of securityRules) {
|
|
205
|
+
const keys = [];
|
|
206
|
+
const matchComponent = componentMountPoints.find(
|
|
207
|
+
(componentItem) => componentItem.did === securityRuleItem.componentDid
|
|
208
|
+
);
|
|
209
|
+
const mergePathPattern = joinURL(matchComponent?.mountPoint || '/', securityRuleItem.pathPattern);
|
|
210
|
+
const regexp = pathToRegExp(mergePathPattern, keys);
|
|
211
|
+
const match = regexp.exec(realUrl);
|
|
212
|
+
if (match) {
|
|
213
|
+
if (securityRuleItem.accessPolicy) {
|
|
214
|
+
matchedAccessPolicyRules.push(securityRuleItem);
|
|
215
|
+
}
|
|
216
|
+
if (securityRuleItem.responseHeaderPolicy) {
|
|
217
|
+
matchedResponseHeaderPolicyRules.push(securityRuleItem);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const matchedRule = {
|
|
223
|
+
accessPolicyConfig: matchedAccessPolicyRules.length > 0 ? matchedAccessPolicyRules[0] : null,
|
|
224
|
+
responseHeaderPolicyConfig:
|
|
225
|
+
matchedResponseHeaderPolicyRules.length > 0 ? matchedResponseHeaderPolicyRules[0] : null,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
return matchedRule;
|
|
229
|
+
} catch (error) {
|
|
230
|
+
logger.error('Failed to getsecurityConfig', { error, rawUrl, blockletDid });
|
|
231
|
+
return defaultConfig;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
const result = await cache.getSecurityConfig({
|
|
235
|
+
did: blockletDid,
|
|
236
|
+
url: currentUrl,
|
|
237
|
+
getDataFn,
|
|
238
|
+
});
|
|
239
|
+
return result;
|
|
240
|
+
};
|
|
241
|
+
|
|
152
242
|
req.cache = cache;
|
|
153
243
|
};
|
|
154
244
|
|
package/api/util/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { joinURL } = require('ufo');
|
|
2
2
|
const { minimatch } = require('minimatch');
|
|
3
|
-
const { ROLES
|
|
3
|
+
const { ROLES } = require('@abtnode/constant');
|
|
4
4
|
const { BLOCKLET_MODES } = require('@blocklet/constant');
|
|
5
5
|
const { findWebInterfacePort, findComponentByIdV2 } = require('@blocklet/meta/lib/util');
|
|
6
6
|
const { WELLKNOWN_SERVICE_PATH_PREFIX } = require('@abtnode/constant');
|
|
@@ -144,27 +144,27 @@ const getRedirectUrl = ({ req, pagePath, params = {} }) => {
|
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
/**
|
|
147
|
-
* @
|
|
148
|
-
* @typedef {string} defaultRole
|
|
149
|
-
* @typedef {boolean} isIssuePassport
|
|
150
|
-
* @param {import('@abtnode/client').BlockletSettings} config
|
|
147
|
+
* @param {object} config
|
|
151
148
|
* @param {any} node
|
|
152
149
|
* @param {string} teamDid
|
|
153
|
-
* @returns {Promise<
|
|
150
|
+
* @returns {Promise<boolean>}
|
|
154
151
|
*/
|
|
155
|
-
const
|
|
152
|
+
const checkInvitedUserOnly = async (config, node, teamDid) => {
|
|
156
153
|
const count = await node.getUsersCount({ teamDid });
|
|
157
154
|
|
|
158
155
|
// issue owner passport for first login user
|
|
159
156
|
if (count === 0) {
|
|
160
|
-
return
|
|
157
|
+
return false;
|
|
161
158
|
}
|
|
162
159
|
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
const accessRoles = config?.accessPolicy?.roles ?? null;
|
|
161
|
+
const accessRevert = config?.accessPolicy?.revert ?? false;
|
|
162
|
+
if (accessRoles === null && accessRevert === false) {
|
|
163
|
+
return false;
|
|
165
164
|
}
|
|
166
165
|
|
|
167
|
-
|
|
166
|
+
// NOTICE: 其他情况都是需要保护的(默认情况应该也是需要保护)
|
|
167
|
+
return true;
|
|
168
168
|
};
|
|
169
169
|
|
|
170
170
|
/**
|
|
@@ -212,6 +212,7 @@ const shouldIgnoreUrl = (url, urls) => {
|
|
|
212
212
|
}
|
|
213
213
|
const _url = url.slice(0, length);
|
|
214
214
|
for (let i = 0; i < urls.length; i++) {
|
|
215
|
+
// FIXME: @zhanghan 这里不应该使用 minimatch 来匹配 url,应该改为使用 path-to-regexp
|
|
215
216
|
if (minimatch(_url, urls[i])) {
|
|
216
217
|
return true;
|
|
217
218
|
}
|
|
@@ -231,7 +232,7 @@ module.exports = {
|
|
|
231
232
|
shouldGotoStartPage,
|
|
232
233
|
ensureProxyUrl,
|
|
233
234
|
getRedirectUrl,
|
|
234
|
-
|
|
235
|
+
checkInvitedUserOnly,
|
|
235
236
|
createTokenFn,
|
|
236
237
|
getDidConnectVersion,
|
|
237
238
|
nanoid,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{X as r,Y as t,j as a}from"./index-
|
|
1
|
+
import{X as r,Y as t,j as a}from"./index-Cicr8_v0.js";var e={},u=t;Object.defineProperty(e,"__esModule",{value:!0});var d=e.default=void 0,v=u(r()),o=a;d=e.default=(0,v.default)((0,o.jsx)("path",{d:"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z"}),"Add");export{d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aE as w,aF as H,at as c,j as e,aG as d,ai as T,aH as g,cd as y,ce as I,aK as n,r as _,aI as F,aJ as U,aC as V,aM as Z,aN as D}from"./index-
|
|
1
|
+
import{aE as w,aF as H,at as c,j as e,aG as d,ai as T,aH as g,cd as y,ce as I,aK as n,r as _,aI as F,aJ as U,aC as V,aM as Z,aN as D}from"./index-Cicr8_v0.js";import{u as M}from"./useSlot-1YlTOkWf.js";function G(t){return H("MuiAlert",t)}const S=w("MuiAlert",["root","action","icon","message","filled","colorSuccess","colorInfo","colorWarning","colorError","filledSuccess","filledInfo","filledWarning","filledError","outlined","outlinedSuccess","outlinedInfo","outlinedWarning","outlinedError","standard","standardSuccess","standardInfo","standardWarning","standardError"]),J=c(e.jsx("path",{d:"M20,12A8,8 0 0,1 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4C12.76,4 13.5,4.11 14.2, 4.31L15.77,2.74C14.61,2.26 13.34,2 12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0, 0 22,12M7.91,10.08L6.5,11.5L11,16L21,6L19.59,4.58L11,13.17L7.91,10.08Z"}),"SuccessOutlined"),K=c(e.jsx("path",{d:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z"}),"ReportProblemOutlined"),q=c(e.jsx("path",{d:"M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"}),"ErrorOutline"),Q=c(e.jsx("path",{d:"M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20, 12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10, 10 0 0,0 12,2M11,17H13V11H11V17Z"}),"InfoOutlined"),X=c(e.jsx("path",{d:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"}),"Close"),Y=["action","children","className","closeText","color","components","componentsProps","icon","iconMapping","onClose","role","severity","slotProps","slots","variant"],tt=t=>{const{variant:s,color:r,severity:o,classes:l}=t,u={root:["root",`color${g(r||o)}`,`${s}${g(r||o)}`,`${s}`],icon:["icon"],message:["message"],action:["action"]};return D(u,G,l)},ot=d(T,{name:"MuiAlert",slot:"Root",overridesResolver:(t,s)=>{const{ownerState:r}=t;return[s.root,s[r.variant],s[`${r.variant}${g(r.color||r.severity)}`]]}})(({theme:t})=>{const s=t.palette.mode==="light"?y:I,r=t.palette.mode==="light"?I:y;return n({},t.typography.body2,{backgroundColor:"transparent",display:"flex",padding:"6px 16px",variants:[...Object.entries(t.palette).filter(([,o])=>o.main&&o.light).map(([o])=>({props:{colorSeverity:o,variant:"standard"},style:{color:t.vars?t.vars.palette.Alert[`${o}Color`]:s(t.palette[o].light,.6),backgroundColor:t.vars?t.vars.palette.Alert[`${o}StandardBg`]:r(t.palette[o].light,.9),[`& .${S.icon}`]:t.vars?{color:t.vars.palette.Alert[`${o}IconColor`]}:{color:t.palette[o].main}}})),...Object.entries(t.palette).filter(([,o])=>o.main&&o.light).map(([o])=>({props:{colorSeverity:o,variant:"outlined"},style:{color:t.vars?t.vars.palette.Alert[`${o}Color`]:s(t.palette[o].light,.6),border:`1px solid ${(t.vars||t).palette[o].light}`,[`& .${S.icon}`]:t.vars?{color:t.vars.palette.Alert[`${o}IconColor`]}:{color:t.palette[o].main}}})),...Object.entries(t.palette).filter(([,o])=>o.main&&o.dark).map(([o])=>({props:{colorSeverity:o,variant:"filled"},style:n({fontWeight:t.typography.fontWeightMedium},t.vars?{color:t.vars.palette.Alert[`${o}FilledColor`],backgroundColor:t.vars.palette.Alert[`${o}FilledBg`]}:{backgroundColor:t.palette.mode==="dark"?t.palette[o].dark:t.palette[o].main,color:t.palette.getContrastText(t.palette[o].main)})}))]})}),st=d("div",{name:"MuiAlert",slot:"Icon",overridesResolver:(t,s)=>s.icon})({marginRight:12,padding:"7px 0",display:"flex",fontSize:22,opacity:.9}),et=d("div",{name:"MuiAlert",slot:"Message",overridesResolver:(t,s)=>s.message})({padding:"8px 0",minWidth:0,overflow:"auto"}),j=d("div",{name:"MuiAlert",slot:"Action",overridesResolver:(t,s)=>s.action})({display:"flex",alignItems:"flex-start",padding:"4px 0 0 16px",marginLeft:"auto",marginRight:-8}),z={success:e.jsx(J,{fontSize:"inherit"}),warning:e.jsx(K,{fontSize:"inherit"}),error:e.jsx(q,{fontSize:"inherit"}),info:e.jsx(Q,{fontSize:"inherit"})},nt=_.forwardRef(function(s,r){const o=F({props:s,name:"MuiAlert"}),{action:l,children:u,className:$,closeText:v="Close",color:f,components:x={},componentsProps:L={},icon:C,iconMapping:b=z,onClose:A,role:h="alert",severity:p="success",slotProps:P={},slots:R={},variant:O="standard"}=o,k=U(o,Y),a=n({},o,{color:f,severity:p,variant:O,colorSeverity:f||p}),i=tt(a),m={slots:n({closeButton:x.CloseButton,closeIcon:x.CloseIcon},R),slotProps:n({},L,P)},[B,E]=M("closeButton",{elementType:V,externalForwardedProps:m,ownerState:a}),[N,W]=M("closeIcon",{elementType:X,externalForwardedProps:m,ownerState:a});return e.jsxs(ot,n({role:h,elevation:0,ownerState:a,className:Z(i.root,$),ref:r},k,{children:[C!==!1?e.jsx(st,{ownerState:a,className:i.icon,children:C||b[p]||z[p]}):null,e.jsx(et,{ownerState:a,className:i.message,children:u}),l!=null?e.jsx(j,{ownerState:a,className:i.action,children:l}):null,l==null&&A?e.jsx(j,{ownerState:a,className:i.action,children:e.jsx(B,n({size:"small","aria-label":v,title:v,color:"inherit",onClick:A},E,{children:e.jsx(N,n({fontSize:"small"},W))}))}):null]}))});export{nt as A,X as C};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{X as r,Y as t,j as a}from"./index-
|
|
1
|
+
import{X as r,Y as t,j as a}from"./index-Cicr8_v0.js";var e={},o=t;Object.defineProperty(e,"__esModule",{value:!0});var u=e.default=void 0,i=o(r()),p=a;u=e.default=(0,i.default)((0,p.jsx)("path",{d:"m7 10 5 5 5-5z"}),"ArrowDropDown");export{u as d};
|