@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/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');
|
|
@@ -45,7 +37,7 @@ const createSessionRoutes = require('./session');
|
|
|
45
37
|
const createPassportRoutes = require('./passport');
|
|
46
38
|
const { getRedirectUrl, shouldIgnoreUrl, redirectWithoutCache } = require('../../util');
|
|
47
39
|
const { createConnectToDidSpacesForUserRoute } = require('./connect/connect-to-did-spaces-for-user');
|
|
48
|
-
const { isEmailKycRequired } = require('../../libs/kyc');
|
|
40
|
+
const { isEmailKycRequired, isPhoneKycRequired } = require('../../libs/kyc');
|
|
49
41
|
|
|
50
42
|
const getTokenFromWsConnect = (req, options) => {
|
|
51
43
|
const cookies = cookie.parse(req.headers.cookie || '');
|
|
@@ -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') {
|
|
@@ -346,13 +311,23 @@ const init = ({ node, options }) => {
|
|
|
346
311
|
}
|
|
347
312
|
|
|
348
313
|
// Security principles: user should not known the reason
|
|
349
|
-
return res.status(403).json({ code: 403, error: REASON_403 });
|
|
314
|
+
return res.status(403).json({ code: 403, error: REASON_403, reason: 'email_not_verified' });
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (isPhoneKycRequired(blocklet) && !req.user.phoneVerified) {
|
|
318
|
+
if (req.accepts(['html', 'json']) === 'html') {
|
|
319
|
+
return redirectWithoutCache(res, getRedirectUrl({ req, pagePath: '/kyc/phone', params: { updateKyc: 1 } }));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Security principles: user should not known the reason
|
|
323
|
+
return res.status(403).json({ code: 403, error: REASON_403, reason: 'phone_not_verified' });
|
|
350
324
|
}
|
|
351
325
|
}
|
|
352
326
|
|
|
353
327
|
return next();
|
|
354
328
|
};
|
|
355
329
|
|
|
330
|
+
// 检查是否符合访问权限控制,不符合的就进行重定向
|
|
356
331
|
middlewares.checkAuth = async (req, res, next) => {
|
|
357
332
|
res.locals.auth = await checkAuth({ req });
|
|
358
333
|
const { blocked, authenticated, authorized, payable, requiredRoles } = res.locals.auth;
|
|
@@ -380,7 +355,11 @@ const init = ({ node, options }) => {
|
|
|
380
355
|
getRedirectUrl({
|
|
381
356
|
req,
|
|
382
357
|
pagePath: '/login',
|
|
383
|
-
params: {
|
|
358
|
+
params: {
|
|
359
|
+
authenticated: 1,
|
|
360
|
+
payable,
|
|
361
|
+
requiredRoles: JSON.stringify(requiredRoles),
|
|
362
|
+
},
|
|
384
363
|
})
|
|
385
364
|
);
|
|
386
365
|
} else {
|
|
@@ -1,14 +1,53 @@
|
|
|
1
1
|
const { WELLKNOWN_SERVICE_PATH_PREFIX, VERIFY_CODE_TTL } = require('@abtnode/constant');
|
|
2
|
-
const
|
|
2
|
+
const createTranslator = require('@abtnode/util/lib/translate');
|
|
3
3
|
|
|
4
4
|
const { emailSchema } = require('../../socket/channel/did');
|
|
5
5
|
const { sendEmail } = require('../../libs/email');
|
|
6
|
-
const {
|
|
6
|
+
const { isEmailBlocked, isEmailAllowed } = require('../../libs/kyc');
|
|
7
7
|
|
|
8
8
|
const logger = require('../../libs/logger')('kyc');
|
|
9
9
|
|
|
10
|
+
const translations = {
|
|
11
|
+
en: {
|
|
12
|
+
emailInvalid: 'Email is invalid',
|
|
13
|
+
emailAlreadyVerified:
|
|
14
|
+
'This email has already been verified. You can recover the verification NFT from your DID Wallet.',
|
|
15
|
+
emailNotAllowed:
|
|
16
|
+
"Sorry, we can't accept email addresses from this domain. Please use an email address from a different provider.",
|
|
17
|
+
emailBlocked: "We're unable to use this email address. Please try a different email address from another provider.",
|
|
18
|
+
emailSendSuccess: 'Verify code successfully sent',
|
|
19
|
+
emailAlreadySent:
|
|
20
|
+
"We've already sent a verification email. Please check your inbox or spam folder. If you don't see it, you can try again in a few minutes.",
|
|
21
|
+
emailVerifySuccess: 'Email is successfully verified',
|
|
22
|
+
emailTitle: 'Verify Your Email for {appName}',
|
|
23
|
+
emailHeadline:
|
|
24
|
+
'To ensure the security of your account and enhance your experience, you need to use following code to verify your email, and you will receive a NFT in your DID Wallet upon verification.',
|
|
25
|
+
emailValidCode:
|
|
26
|
+
"This code is valid for {ttl} minutes. If you don't want to verify your email, you can ignore this message.",
|
|
27
|
+
emailWarning:
|
|
28
|
+
'{appName} will never email you and ask you to disclose your password, credit card, or banking account number.',
|
|
29
|
+
},
|
|
30
|
+
zh: {
|
|
31
|
+
emailInvalid: '邮箱格式不正确',
|
|
32
|
+
emailAlreadyVerified: '此邮箱已验证。您可以从 DID 钱包中恢复验证证书。',
|
|
33
|
+
emailNotAllowed: '对不起,我们不接受此域名的电子邮件地址。请使用来自不同提供商的电子邮件地址。',
|
|
34
|
+
emailBlocked: '我们无法使用此电子邮件地址。请尝试使用来自不同提供商的电子邮件地址。',
|
|
35
|
+
emailSendSuccess: '验证码发送成功',
|
|
36
|
+
emailAlreadySent: '我们已发送验证电子邮件。请检查您的收件箱或垃圾邮件文件夹。如果您没有看到它,您可以稍后再试。',
|
|
37
|
+
emailVerifySuccess: '邮箱验证成功',
|
|
38
|
+
emailTitle: '验证您在 {appName} 的邮箱',
|
|
39
|
+
emailHeadline:
|
|
40
|
+
'为确保您的帐户安全并增强您的体验,您需要使用以下代码验证您的邮箱,并在验证后在您的 DID 钱包中收到 NFT。',
|
|
41
|
+
emailValidCode: '此代码有效期为 {ttl} 分钟。如果您不想验证您的邮箱,您可以忽略此消息。',
|
|
42
|
+
emailWarning: '{appName} 永远不会向您发送电子邮件并要求您披露您的密码、信用卡或银行账户信息。',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const t = createTranslator({ translations });
|
|
47
|
+
|
|
10
48
|
const init = ({ node }) => {
|
|
11
49
|
const onStartEmailVerify = async (req, res) => {
|
|
50
|
+
const { locale = 'en' } = req.query;
|
|
12
51
|
try {
|
|
13
52
|
const [blocklet, info] = await Promise.all([req.getBlocklet(), req.getBlockletInfo()]);
|
|
14
53
|
const teamDid = blocklet.meta.did;
|
|
@@ -16,28 +55,14 @@ const init = ({ node }) => {
|
|
|
16
55
|
const { error, value: subject } = emailSchema.validate(req.body.email);
|
|
17
56
|
|
|
18
57
|
if (error) {
|
|
19
|
-
return res.status(400).send({ error: '
|
|
58
|
+
return res.status(400).send({ error: t('emailInvalid', locale), code: 'email_invalid' });
|
|
20
59
|
}
|
|
21
60
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
teamDid,
|
|
26
|
-
email: subject,
|
|
27
|
-
verified: isEmailKycRequired(blocklet),
|
|
28
|
-
sourceProvider: LOGIN_PROVIDER.WALLET,
|
|
29
|
-
})
|
|
30
|
-
) {
|
|
31
|
-
return res.status(400).send({
|
|
32
|
-
error: 'This email address is already in use. Please try a different email address.',
|
|
33
|
-
code: 'email_already_used',
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (await node.isSubjectIssued({ teamDid, subject })) {
|
|
61
|
+
// Do not issue duplicate email nft to same user
|
|
62
|
+
if (req.user) {
|
|
63
|
+
if (await node.isSubjectIssued({ teamDid, userDid: req.user.did, subject })) {
|
|
38
64
|
return res.status(400).send({
|
|
39
|
-
error:
|
|
40
|
-
'This email has already been verified. You can log in using your DID Wallet or recover your certificate from the login page.',
|
|
65
|
+
error: t('emailAlreadyVerified', locale),
|
|
41
66
|
code: 'email_already_verified',
|
|
42
67
|
});
|
|
43
68
|
}
|
|
@@ -47,8 +72,7 @@ const init = ({ node }) => {
|
|
|
47
72
|
if (!isAllowed) {
|
|
48
73
|
logger.warn('Email domain is not allowed', { teamDid, subject });
|
|
49
74
|
return res.status(400).send({
|
|
50
|
-
error:
|
|
51
|
-
"Sorry, we can't accept email addresses from this domain. Please use an email address from a different provider.",
|
|
75
|
+
error: t('emailNotAllowed', locale),
|
|
52
76
|
code: 'email_not_allowed',
|
|
53
77
|
});
|
|
54
78
|
}
|
|
@@ -57,15 +81,14 @@ const init = ({ node }) => {
|
|
|
57
81
|
if (isBlocked) {
|
|
58
82
|
logger.warn('Email domain is blocked', { teamDid, subject });
|
|
59
83
|
return res.status(400).send({
|
|
60
|
-
error:
|
|
84
|
+
error: t('emailBlocked', locale),
|
|
61
85
|
code: 'email_blocked',
|
|
62
86
|
});
|
|
63
87
|
}
|
|
64
88
|
|
|
65
89
|
if (await node.isSubjectSent({ teamDid, subject })) {
|
|
66
90
|
return res.status(400).send({
|
|
67
|
-
error:
|
|
68
|
-
"We've already sent a verification email. Please check your inbox or spam folder. If you don't see it, you can try again in a few minutes.",
|
|
91
|
+
error: t('emailAlreadySent', locale),
|
|
69
92
|
code: 'email_already_sent',
|
|
70
93
|
});
|
|
71
94
|
}
|
|
@@ -76,11 +99,11 @@ const init = ({ node }) => {
|
|
|
76
99
|
const result = await sendEmail(
|
|
77
100
|
subject,
|
|
78
101
|
{
|
|
79
|
-
title:
|
|
80
|
-
body: `<p style="font-size:14px;line-height:24px;margin:16px 0;"
|
|
102
|
+
title: t('emailTitle', locale, { appName: info.name }),
|
|
103
|
+
body: `<p style="font-size:14px;line-height:24px;margin:16px 0;">${t('emailHeadline', locale)}</p>
|
|
81
104
|
<p style="font-size:36px; line-height:24px; color: #333; font-weight: bold; text-align: center;">${doc.code}</p>
|
|
82
|
-
<p style="font-size:14px;line-height:24px;margin:16px 0;"
|
|
83
|
-
<p style="font-size:14px;line-height:24px;margin:16px 0;">${
|
|
105
|
+
<p style="font-size:14px;line-height:24px;margin:16px 0;">${t('emailValidCode', locale, { ttl: VERIFY_CODE_TTL / 60 / 1000 })}</p>
|
|
106
|
+
<p style="font-size:14px;line-height:24px;margin:16px 0;">${t('emailWarning', locale, { appName: info.name })}</p>`,
|
|
84
107
|
},
|
|
85
108
|
{
|
|
86
109
|
teamDid,
|
|
@@ -92,7 +115,7 @@ const init = ({ node }) => {
|
|
|
92
115
|
logger.info('send verify code', { teamDid, result });
|
|
93
116
|
await node.sendVerifyCode({ teamDid, code: doc.code });
|
|
94
117
|
|
|
95
|
-
return res.status(200).send({ message: '
|
|
118
|
+
return res.status(200).send({ message: t('emailSendSuccess', locale) });
|
|
96
119
|
} catch (error) {
|
|
97
120
|
logger.error('Send mail failed', { error });
|
|
98
121
|
return res.status(400).send(error.message);
|
|
@@ -100,6 +123,7 @@ const init = ({ node }) => {
|
|
|
100
123
|
};
|
|
101
124
|
|
|
102
125
|
const onEndEmailVerify = async (req, res) => {
|
|
126
|
+
const { locale = 'en' } = req.query;
|
|
103
127
|
try {
|
|
104
128
|
const blocklet = await req.getBlocklet();
|
|
105
129
|
const teamDid = blocklet.meta.did;
|
|
@@ -108,7 +132,7 @@ const init = ({ node }) => {
|
|
|
108
132
|
const result = await node.consumeVerifyCode({ teamDid, code });
|
|
109
133
|
logger.info('consume verify code', { teamDid, code, result });
|
|
110
134
|
|
|
111
|
-
return res.status(200).send({ message: '
|
|
135
|
+
return res.status(200).send({ message: t('emailVerifySuccess', locale) });
|
|
112
136
|
} catch (error) {
|
|
113
137
|
logger.error('Verify mail failed', { error });
|
|
114
138
|
return res.status(400).send(error.message);
|