@abtnode/blocklet-services 1.16.52-beta-20250908-085420-224a58fa → 1.16.52-beta-20250911-023851-d988be85
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/emails/_components/footer.js +7 -2
- package/api/libs/email.js +5 -1
- package/api/routes/user.js +52 -2
- package/api/services/auth/connect/verify-destroy.js +42 -9
- package/api/socket/util.js +4 -1
- package/api/state/message.js +9 -1
- package/api/util/utm.js +241 -0
- package/dist/assets/{AdapterDayjs-ffU9bx7e.js → AdapterDayjs-CKA_54eZ.js} +1 -1
- package/dist/assets/{Google-GRs7AwNK.js → Google-DzJt8j2p.js} +1 -1
- package/dist/assets/{access-control-D02QLhEy.js → access-control-DTQ50N6V.js} +1 -1
- package/dist/assets/{add-component-core-DmrTn-fB.js → add-component-core-BrVCLSN6.js} +1 -1
- package/dist/assets/{add-resource-BuXNw0by.js → add-resource-c90mXjXe.js} +1 -1
- package/dist/assets/{addon-CJVfVQdN.js → addon-CxluIuPz.js} +1 -1
- package/dist/assets/{advanced-BQI2sreZ.js → advanced-DFALg-CZ.js} +1 -1
- package/dist/assets/{aigne-CzGA8IUU.js → aigne-C4_yXAUg.js} +1 -1
- package/dist/assets/{appearance-BsyCLclh.js → appearance-DKolOYs4.js} +1 -1
- package/dist/assets/{ar-CPI6kJBB.js → ar-DGfbWcRb.js} +1 -1
- package/dist/assets/{arrow-down.svg-CeA5tsyp.js → arrow-down.svg-CGgLriRk.js} +1 -1
- package/dist/assets/{audit-logs-DE_zWK7V.js → audit-logs-numMr61S.js} +1 -1
- package/dist/assets/{authorize-D07NMtq7.js → authorize-Cs-nLZVa.js} +1 -1
- package/dist/assets/{base32-DUdjIQpj.js → base32-2BTO5zmk.js} +1 -1
- package/dist/assets/{bind-account-D809ACvG.js → bind-account-DATlcjGM.js} +1 -1
- package/dist/assets/{branding-IdArDAjP.js → branding-ChMkwmNu.js} +1 -1
- package/dist/assets/{branding-DZQe1PsD.js → branding-CpqfcsE-.js} +1 -1
- package/dist/assets/{branding-DLVsPMDM.js → branding-Dv6FvDLK.js} +2 -2
- package/dist/assets/{bundle-avatar-bJGgXPJZ.js → bundle-avatar-CfoJFi5J.js} +1 -1
- package/dist/assets/{button-C0DX42gM.js → button-VDZIHEym.js} +1 -1
- package/dist/assets/{click-to-copy-r3y_3V-6.js → click-to-copy-CH3FJWJo.js} +1 -1
- package/dist/assets/{complete-C_LldbSL.js → complete-CshVhiET.js} +1 -1
- package/dist/assets/{component-EW2m-2Hq.js → component-B1O9WT7z.js} +3 -3
- package/dist/assets/{config-BppAex79.js → config-Bmq4DJl0.js} +1 -1
- package/dist/assets/{config-CJ2tOrVe.js → config-CmIvwzmQ.js} +1 -1
- package/dist/assets/{config-navigation-QgsadD0w.js → config-navigation-R4T6jiU3.js} +3 -3
- package/dist/assets/{config-space-v48mujCK.js → config-space-BVAKDgsX.js} +1 -1
- package/dist/assets/{config-CeYMoY4R.js → config-vTUk_Yfk.js} +1 -1
- package/dist/assets/{confirm-CV_ukxE_.js → confirm-DV4YCyEc.js} +1 -1
- package/dist/assets/{connect-DUM8FA7f.js → connect-C9A-I8R8.js} +1 -1
- package/dist/assets/{connect-to-B_ABoYFh.js → connect-to-CtS-ZsP9.js} +1 -1
- package/dist/assets/{connect-DcYdVgbK.js → connect-vQygM1gc.js} +1 -1
- package/dist/assets/{createClass-CpGAUQg2.js → createClass-DNqt7UI8.js} +1 -1
- package/dist/assets/{dashboard-CmGsGxlD.js → dashboard-CzGF4PYs.js} +3 -3
- package/dist/assets/{de-DXdF82Jr.js → de-DGZI-Bsh.js} +1 -1
- package/dist/assets/{delete-confirm-gyn7XAac.js → delete-confirm-ad8t0UXs.js} +1 -1
- package/dist/assets/{did-address-CPLUdwKY.js → did-address-4KKI5Z_V.js} +1 -1
- package/dist/assets/{domain-UrJgIaK0.js → domain-D-3zw7uG.js} +1 -1
- package/dist/assets/{domain-action-card-YXDKcuVT.js → domain-action-card-wBZ8YZ_K.js} +1 -1
- package/dist/assets/{domains-4FokCnh1.js → domains-BjPU8dXK.js} +1 -1
- package/dist/assets/{email-YS4JhMeS.js → email-DCapsREm.js} +1 -1
- package/dist/assets/engine-CRVby1S4.js +1 -0
- package/dist/assets/{es-Cdb297yS.js → es-CMwFpp7C.js} +1 -1
- package/dist/assets/{exchange-passport-P_xK2-vf.js → exchange-passport-CuSVCQpP.js} +1 -1
- package/dist/assets/{form-DT1p2SWd.js → form-2mrhORLa.js} +1 -1
- package/dist/assets/{form-text-input-B8adEKSe.js → form-text-input-CyaKz-aW.js} +1 -1
- package/dist/assets/{fr-CQValz_y.js → fr-eKsI9Vcp.js} +1 -1
- package/dist/assets/{fuel-DP0Q8hTa.js → fuel-DHo_QvBk.js} +1 -1
- package/dist/assets/{gen-access-key-BG7JXR4u.js → gen-access-key-D3bzBUlQ.js} +1 -1
- package/dist/assets/{gen-simple-access-key-DaNnWhrp.js → gen-simple-access-key-BKkuz2Fk.js} +1 -1
- package/dist/assets/get-safe-url-D4-uUwWa.js +1 -0
- package/dist/assets/{hdkey-BCusmuac.js → hdkey-CZt5k06-.js} +1 -1
- package/dist/assets/{hi-CAensap9.js → hi-C0JqybmN.js} +1 -1
- package/dist/assets/{home-Bhiyk77K.js → home-DgBfnhbE.js} +1 -1
- package/dist/assets/{id-6AFgcYKj.js → id-DHF6PX-M.js} +1 -1
- package/dist/assets/{iframe-Ce3kroAM.js → iframe-amFSSPgY.js} +1 -1
- package/dist/assets/{index-BWBlDFjU.js → index-B0DwBoe3.js} +1 -1
- package/dist/assets/{index-Br7RGSFv.js → index-B2EmOTH7.js} +61 -61
- package/dist/assets/{index-BLonWJ__.js → index-BFMIW-KL.js} +1 -1
- package/dist/assets/{index-DPwiaPyc.js → index-BFQzptXM.js} +1 -1
- package/dist/assets/{index-Cb8NmoOI.js → index-BNWq4zK7.js} +1 -1
- package/dist/assets/{index-O6p0L2t4.js → index-BV5aEWS1.js} +1 -1
- package/dist/assets/{index-JrJd98Of.js → index-BWhAMS1Q.js} +1 -1
- package/dist/assets/{index-CcYh_TwI.js → index-BjLb1HBo.js} +1 -1
- package/dist/assets/{index-CipehFwZ.js → index-BmPcC1s0.js} +1 -1
- package/dist/assets/{index-Ed1obN0N.js → index-C1-AZbYf.js} +1 -1
- package/dist/assets/{index-DK4dVb7h.js → index-C1pPU9qq.js} +1 -1
- package/dist/assets/{index-C14bbQSS.js → index-C4j3gH0o.js} +1 -1
- package/dist/assets/{index-h9p2Gwwd.js → index-CBP6lyxa.js} +1 -1
- package/dist/assets/{index-DffJvJ-f.js → index-CZYE2JtK.js} +4 -4
- package/dist/assets/{index-DCsimtEZ.js → index-Ca0DgcTh.js} +1 -1
- package/dist/assets/{index-CcGgdXu3.js → index-CcuDh75j.js} +1 -1
- package/dist/assets/{index-BrgPswzL.js → index-Cgvk2QQ_.js} +1 -1
- package/dist/assets/index-DBhVhw1v.js +124 -0
- package/dist/assets/{index-ejiOKw1E.js → index-DVMWAhrt.js} +1 -1
- package/dist/assets/{index-DNgNPmIn.js → index-DkTLhY6N.js} +1 -1
- package/dist/assets/{index-sflWxhj_.js → index-FBIc-uda.js} +1 -1
- package/dist/assets/{index-CDP_L1qy.js → index-HB59rGor.js} +3 -3
- package/dist/assets/index-LTZrTPAZ.js +113 -0
- package/dist/assets/{index-BC_z-zsl.js → index-S5gZ547W.js} +1 -1
- package/dist/assets/{index-_sKq7vql.js → index-Vdt8KS2l.js} +1 -1
- package/dist/assets/{index-B9WrGYJf.js → index-ub2vI299.js} +1 -1
- package/dist/assets/{index-ClwjZe6L.js → index-zmlRlLsp.js} +1 -1
- package/dist/assets/{invitation-BZnf93ev.js → invitation-CsaolrG3.js} +1 -1
- package/dist/assets/{invite-CBTmzhwp.js → invite-Bz_emQWL.js} +1 -1
- package/dist/assets/{isURL-C56b9oXx.js → isURL-DviHJNBO.js} +1 -1
- package/dist/assets/{issue-passport-B0hsJjTB.js → issue-passport-ZQsWd3Dr.js} +1 -1
- package/dist/assets/{item-DFbQgetg.js → item-vw_cuyBZ.js} +1 -1
- package/dist/assets/{ja-D59y1sZ9.js → ja-c-6MaUg1.js} +1 -1
- package/dist/assets/{ko-DlSyClni.js → ko-CTFi4Ndk.js} +1 -1
- package/dist/assets/{landing-page-hbXRmObM.js → landing-page-CVL3NbvQ.js} +1 -1
- package/dist/assets/{layout-n_wdIvvX.js → layout-BKp8C5F-.js} +1 -1
- package/dist/assets/{list-Dg6YcsMU.js → list-CY0v9mkZ.js} +1 -1
- package/dist/assets/{list-DkhTNTRK.js → list-zVgARuTW.js} +3 -3
- package/dist/assets/localization-UoEVomCp.js +1 -0
- package/dist/assets/{log-C_yeI_wV.js → log-CuQWYZCB.js} +1 -1
- package/dist/assets/logger-DtNL0LIQ.js +1 -0
- package/dist/assets/{login-BUd7xYia.js → login-1ZsKClLU.js} +1 -1
- package/dist/assets/{login-oauth-callback-YoW0x_7a.js → login-oauth-callback-YZd7R3pO.js} +1 -1
- package/dist/assets/{logo-uploader-BMMUJR7a.js → logo-uploader-DuDo-4bO.js} +2 -2
- package/dist/assets/{lost-passport-DNLvYerq.js → lost-passport-Dx86JuPR.js} +1 -1
- package/dist/assets/{open-window-BbZDdsmg.js → open-window-DnjhXMUE.js} +1 -1
- package/dist/assets/{over-due-invoice-payment-BY3BR46r.js → over-due-invoice-payment-Dam76xor.js} +1 -1
- package/dist/assets/{overview-BFVzb-zB.js → overview-DiuRZ10x.js} +1 -1
- package/dist/assets/{passport-item-CRrICCXE.js → passport-item-CwFxbGyQ.js} +1 -1
- package/dist/assets/{permission-UQGu_-Cf.js → permission-DwyNIiFn.js} +1 -1
- package/dist/assets/{preferences-CyALDCap.js → preferences-D93Xc9AW.js} +1 -1
- package/dist/assets/profile-embed-C7ST7lEr.js +1 -0
- package/dist/assets/{pt-C_3CX1PR.js → pt-QkdDdQuw.js} +1 -1
- package/dist/assets/{publish-resource-Dp_w1Dsi.js → publish-resource-DU3M6kAz.js} +1 -1
- package/dist/assets/{react-beautiful-dnd.esm-U2orHJvj.js → react-beautiful-dnd.esm-DFIGUIPG.js} +1 -1
- package/dist/assets/{ru-FBGLUlo5.js → ru-swMH4bvc.js} +1 -1
- package/dist/assets/{runtime--G1ujVXp.js → runtime-Cp_2Mkns.js} +1 -1
- package/dist/assets/sdk-j_z17Rma.js +1 -0
- package/dist/assets/{security-B3L7qXQI.js → security-DNzyYn22.js} +1 -1
- package/dist/assets/{session-Ba0-LWgc.js → session-DGj-_oAZ.js} +1 -1
- package/dist/assets/{setup-DnpqJaf3.js → setup-IfocPlKr.js} +1 -1
- package/dist/assets/{spaces-BhyNdJUR.js → spaces-CoMtZGNH.js} +1 -1
- package/dist/assets/{start-C4D5Pzw8.js → start-CtfSNTEq.js} +1 -1
- package/dist/assets/{starting-progress-lkMq6cOR.js → starting-progress-BTBrLO78.js} +1 -1
- package/dist/assets/{status-eTkWlbrh.js → status-DYzeHwu5.js} +1 -1
- package/dist/assets/{step-actions-vRB4cPjs.js → step-actions-CJGBq_RL.js} +1 -1
- package/dist/assets/{studio-1TB86ZrO.js → studio-cTiQkJ_r.js} +1 -1
- package/dist/assets/{switch-control-BSK_y5_P.js → switch-control-AvyGKeHh.js} +1 -1
- package/dist/assets/{table-tips-Da_IM0mp.js → table-tips-1QxzlCjR.js} +1 -1
- package/dist/assets/{team-cktMvdm0.js → team-B8B1ZhIQ.js} +1 -1
- package/dist/assets/{th-DmSMYMH5.js → th-DuqieD90.js} +1 -1
- package/dist/assets/{traffic-h0HcpbzT.js → traffic-DqTwvxdl.js} +1 -1
- package/dist/assets/{transfer-B1a67F8a.js → transfer-Yhxjz3He.js} +1 -1
- package/dist/assets/{unsubscribe-CS5n7_0d.js → unsubscribe-D98i3Dcl.js} +1 -1
- package/dist/assets/{use-app-logo-CPHV51wY.js → use-app-logo-wJojGoX8.js} +1 -1
- package/dist/assets/{use-window-close-WM1XwCg5.js → use-window-close-Dxp_DCzQ.js} +1 -1
- package/dist/assets/{useLocalStorage-CKq67DKE.js → useLocalStorage-DyyYsV_-.js} +1 -1
- package/dist/assets/{user-center-CNEk-tbg.js → user-center-4QiBEXkz.js} +4 -4
- package/dist/assets/user-follower-daqBbJjL.js +32 -0
- package/dist/assets/{user-sessions-vBiV3ZpR.js → user-sessions-gPGe7NTf.js} +1 -1
- package/dist/assets/{util-BhLlQ2DE.js → util-6fgrHxDz.js} +1 -1
- package/dist/assets/{util-DgyQXNeO.js → util-BkJCSJXb.js} +1 -1
- package/dist/assets/{vendor-arcblock-DNHIum0y.js → vendor-arcblock-CzdgnaKl.js} +1 -1
- package/dist/assets/{vendor-ux-D0eHYGOw.js → vendor-ux-DnuP69h2.js} +1 -1
- package/dist/assets/{vi-CjDg6MoB.js → vi-42QzvOuM.js} +1 -1
- package/dist/assets/{wait-connect-a1iJrIWL.js → wait-connect-D0ORg2Ga.js} +1 -1
- package/dist/assets/{wizard-DJ-ny10T.js → wizard-C7eP8Bda.js} +1 -1
- package/dist/assets/{wizard-components-BTwaxDI2.js → wizard-components-CXkOVy_c.js} +2 -2
- package/dist/assets/wrap-locale-BARiwFz6.js +1 -0
- package/dist/assets/{zh-wVmF24jB.js → zh-Blu7Gys0.js} +1 -1
- package/dist/assets/{zh-DaR6QxjC.js → zh-C-k4DKK-.js} +1 -1
- package/dist/assets/{zh-DzdD_L9N.js → zh-D04z7ZNH.js} +1 -1
- package/dist/assets/{zh-tw-yfBxbyqP.js → zh-tw-BLENKI0o.js} +1 -1
- package/dist/assets/{zh-tw-DaxtX1HY.js → zh-tw-Dxa4oubT.js} +1 -1
- package/dist/index.html +3 -3
- package/dist/service-worker.js +1 -1
- package/package.json +31 -31
- package/dist/assets/engine-7LquCtMt.js +0 -1
- package/dist/assets/get-safe-url-DPk9Y1BS.js +0 -1
- package/dist/assets/index-CpGvMg-0.js +0 -124
- package/dist/assets/index-RVnyxqfr.js +0 -113
- package/dist/assets/localization-BZqBkopy.js +0 -1
- package/dist/assets/logger-CjTCwj01.js +0 -1
- package/dist/assets/profile-embed-pDRs_z78.js +0 -1
- package/dist/assets/sdk-jN4-Pc0q.js +0 -1
- package/dist/assets/user-follower-CKUYyDFI.js +0 -32
- package/dist/assets/wrap-locale-DVJLDD-_.js +0 -1
|
@@ -11,6 +11,7 @@ const constant_1 = require("@abtnode/constant");
|
|
|
11
11
|
const copyright_1 = __importDefault(require("./copyright"));
|
|
12
12
|
const powered_by_1 = __importDefault(require("./powered-by"));
|
|
13
13
|
const style_1 = require("../_libs/style");
|
|
14
|
+
const react_1 = require("react");
|
|
14
15
|
const linkStyle = Object.assign(Object.assign({}, style_1.linkStyle), { color: '#898989', fontSize: '12px' });
|
|
15
16
|
function PointDivider() {
|
|
16
17
|
return (0, jsx_runtime_1.jsx)("span", { style: { color: '#757575', fontSize: '12px', fontWeight: 'bold' }, children: "\u00A0\u00B7\u00A0" });
|
|
@@ -30,10 +31,14 @@ function Footer({ showLogo = false, showCopyright = false, appInfo, locale = 'en
|
|
|
30
31
|
if (!userInfoContent) {
|
|
31
32
|
return null;
|
|
32
33
|
}
|
|
34
|
+
const unsubscribeTokenUrl = (0, react_1.useMemo)(() => {
|
|
35
|
+
// @note: Cannot use joinURL here because appInfo.url may contain query strings
|
|
36
|
+
return (0, ufo_1.resolveURL)(appInfo.url, constant_1.WELLKNOWN_SERVICE_PATH_PREFIX, `/user/unsubscribe?token=${unsubscribeToken}`);
|
|
37
|
+
}, [unsubscribeToken, appInfo.url]);
|
|
33
38
|
if (locale === 'zh') {
|
|
34
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["\u7531\u4E8E\u60A8\u662F", (0, jsx_runtime_1.jsx)(components_1.Link, { href: appInfo.url, target: "_blank", style: linkStyle, children: appInfo.title }), "\u7684\u8BA2\u9605\u8005\u6216\u7528\u6237\uFF0C\u6B64\u7535\u5B50\u90AE\u4EF6\u5DF2\u53D1\u9001\u5230", (userInfo === null || userInfo === void 0 ? void 0 : userInfo.email) ? ((0, jsx_runtime_1.jsx)(components_1.Link, { href: `mailto:${userInfo === null || userInfo === void 0 ? void 0 : userInfo.email}`, style: linkStyle, children: userInfo === null || userInfo === void 0 ? void 0 : userInfo.email })) : (userInfoContent), "\u3002", unsubscribeToken ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["\u5982\u679C\u60A8\u4E0D\u60F3\u518D\u6536\u5230\u6B64\u7C7B\u90AE\u4EF6\uFF0C\u60A8\u53EF\u4EE5", ' ', (0, jsx_runtime_1.jsx)(components_1.Link, { href:
|
|
39
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["\u7531\u4E8E\u60A8\u662F", (0, jsx_runtime_1.jsx)(components_1.Link, { href: appInfo.url, target: "_blank", style: linkStyle, children: appInfo.title }), "\u7684\u8BA2\u9605\u8005\u6216\u7528\u6237\uFF0C\u6B64\u7535\u5B50\u90AE\u4EF6\u5DF2\u53D1\u9001\u5230", (userInfo === null || userInfo === void 0 ? void 0 : userInfo.email) ? ((0, jsx_runtime_1.jsx)(components_1.Link, { href: `mailto:${userInfo === null || userInfo === void 0 ? void 0 : userInfo.email}`, style: linkStyle, children: userInfo === null || userInfo === void 0 ? void 0 : userInfo.email })) : (userInfoContent), "\u3002", unsubscribeToken ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["\u5982\u679C\u60A8\u4E0D\u60F3\u518D\u6536\u5230\u6B64\u7C7B\u90AE\u4EF6\uFF0C\u60A8\u53EF\u4EE5", ' ', (0, jsx_runtime_1.jsx)(components_1.Link, { href: unsubscribeTokenUrl, style: linkStyle, target: "_blank", children: "\u9000\u8BA2" }), "\u3002"] })) : null] }));
|
|
35
40
|
}
|
|
36
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["This email was sent to", ' ', (userInfo === null || userInfo === void 0 ? void 0 : userInfo.email) ? ((0, jsx_runtime_1.jsx)(components_1.Link, { href: `mailto:${userInfo === null || userInfo === void 0 ? void 0 : userInfo.email}`, style: linkStyle, children: userInfo === null || userInfo === void 0 ? void 0 : userInfo.email })) : (userInfoContent), ' ', "as you are a subscriber or a user of", ' ', (0, jsx_runtime_1.jsx)(components_1.Link, { href: appInfo.url, target: "_blank", style: linkStyle, children: appInfo.title }), ".", ' ', unsubscribeToken ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["If you'd rather not receive this kind of email, you can", ' ', (0, jsx_runtime_1.jsx)(components_1.Link, { href:
|
|
41
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["This email was sent to", ' ', (userInfo === null || userInfo === void 0 ? void 0 : userInfo.email) ? ((0, jsx_runtime_1.jsx)(components_1.Link, { href: `mailto:${userInfo === null || userInfo === void 0 ? void 0 : userInfo.email}`, style: linkStyle, children: userInfo === null || userInfo === void 0 ? void 0 : userInfo.email })) : (userInfoContent), ' ', "as you are a subscriber or a user of", ' ', (0, jsx_runtime_1.jsx)(components_1.Link, { href: appInfo.url, target: "_blank", style: linkStyle, children: appInfo.title }), ".", ' ', unsubscribeToken ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["If you'd rather not receive this kind of email, you can", ' ', (0, jsx_runtime_1.jsx)(components_1.Link, { href: unsubscribeTokenUrl, style: linkStyle, target: "_blank", children: "unsubscribe" }), "."] })) : null] }));
|
|
37
42
|
}
|
|
38
43
|
return ((0, jsx_runtime_1.jsxs)(components_1.Section, { children: [showLogo && (0, jsx_runtime_1.jsx)(components_1.Img, { src: appInfo.logo, width: "32", height: "32", alt: appInfo.title }), !showContactUs ? null : (0, jsx_runtime_1.jsx)(ContactUs, { signatureConfig: signatureConfig }), (0, jsx_runtime_1.jsx)(components_1.Text, { style: style_1.footerStyle, children: (0, jsx_runtime_1.jsx)(UnsubscribeContent, {}) }), (0, jsx_runtime_1.jsx)(components_1.Text, { style: { margin: '8px 0' } }), poweredBy && (0, jsx_runtime_1.jsx)(powered_by_1.default, Object.assign({}, poweredBy)), showCopyright && (0, jsx_runtime_1.jsx)(copyright_1.default, {})] }));
|
|
39
44
|
}
|
package/api/libs/email.js
CHANGED
|
@@ -13,6 +13,7 @@ const { ActivityNotificationEmail } = require('../emails/_templates/activity-not
|
|
|
13
13
|
const { VerifyCodeEmail } = require('../emails/_templates/verify-code');
|
|
14
14
|
const { KycCodeVerifyEmail } = require('../emails/_templates/kyc-code-verify');
|
|
15
15
|
const cache = require('../cache');
|
|
16
|
+
const { attachNotificationUTM, getUTMUrl } = require('../util/utm');
|
|
16
17
|
|
|
17
18
|
const schemaEmail = Joi.string().email().required();
|
|
18
19
|
|
|
@@ -52,6 +53,9 @@ async function sendEmail(
|
|
|
52
53
|
throw new Error('Email Service is not available.');
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
// eslint-disable-next-line no-param-reassign
|
|
57
|
+
notification = attachNotificationUTM(notification);
|
|
58
|
+
|
|
55
59
|
if (provider === 'service') {
|
|
56
60
|
const config = blocklet.settings?.notification?.email;
|
|
57
61
|
const info = getBlockletInfo(blocklet);
|
|
@@ -62,7 +66,7 @@ async function sendEmail(
|
|
|
62
66
|
description: info.description,
|
|
63
67
|
title: info.name,
|
|
64
68
|
version: info.version,
|
|
65
|
-
url: info.appUrl,
|
|
69
|
+
url: getUTMUrl(info.appUrl, notification.utm, notification?.sender?.componentDid),
|
|
66
70
|
};
|
|
67
71
|
|
|
68
72
|
const emailSignature = getEmailSignatureConfig(blocklet);
|
package/api/routes/user.js
CHANGED
|
@@ -1019,7 +1019,21 @@ module.exports = {
|
|
|
1019
1019
|
did: req.user.did,
|
|
1020
1020
|
extra: JSON.stringify(preSaveData),
|
|
1021
1021
|
});
|
|
1022
|
-
|
|
1022
|
+
|
|
1023
|
+
const result = user?.extra?.privacy || {};
|
|
1024
|
+
|
|
1025
|
+
await node.createAuditLog(
|
|
1026
|
+
{
|
|
1027
|
+
action: 'updateUserExtra',
|
|
1028
|
+
args: { teamDid, userDid: req.user.did, type: 'privacy' },
|
|
1029
|
+
context: formatContext(req),
|
|
1030
|
+
result: {
|
|
1031
|
+
privacy: value, // @FIXME: liushuang,多传一层的目的是为了保持和 SDK 相同结构
|
|
1032
|
+
},
|
|
1033
|
+
},
|
|
1034
|
+
node
|
|
1035
|
+
);
|
|
1036
|
+
res.json(result);
|
|
1023
1037
|
});
|
|
1024
1038
|
|
|
1025
1039
|
server.get(
|
|
@@ -1078,7 +1092,17 @@ module.exports = {
|
|
|
1078
1092
|
did: req.user.did,
|
|
1079
1093
|
extra: JSON.stringify(preSaveData),
|
|
1080
1094
|
});
|
|
1081
|
-
|
|
1095
|
+
const result = pick(user.extra || {}, ['notifications', 'webhooks']);
|
|
1096
|
+
await node.createAuditLog(
|
|
1097
|
+
{
|
|
1098
|
+
action: 'updateUserExtra',
|
|
1099
|
+
args: { teamDid, userDid: req.user.did, type: value.webhooks ? 'webhooks' : 'notifications' },
|
|
1100
|
+
context: formatContext(req),
|
|
1101
|
+
result,
|
|
1102
|
+
},
|
|
1103
|
+
node
|
|
1104
|
+
);
|
|
1105
|
+
res.json(result);
|
|
1082
1106
|
}
|
|
1083
1107
|
);
|
|
1084
1108
|
|
|
@@ -1355,6 +1379,16 @@ module.exports = {
|
|
|
1355
1379
|
return;
|
|
1356
1380
|
}
|
|
1357
1381
|
|
|
1382
|
+
await node.createAuditLog(
|
|
1383
|
+
{
|
|
1384
|
+
action: 'updateUserInfo',
|
|
1385
|
+
args: { teamDid, userDid: req.user.did },
|
|
1386
|
+
context: formatContext(req),
|
|
1387
|
+
result: updateData,
|
|
1388
|
+
},
|
|
1389
|
+
node
|
|
1390
|
+
);
|
|
1391
|
+
|
|
1358
1392
|
res.json(
|
|
1359
1393
|
pick(user || {}, [
|
|
1360
1394
|
'did',
|
|
@@ -1550,6 +1584,14 @@ module.exports = {
|
|
|
1550
1584
|
|
|
1551
1585
|
try {
|
|
1552
1586
|
const result = await node.followUser({ teamDid, userDid, followerDid });
|
|
1587
|
+
await node.createAuditLog(
|
|
1588
|
+
{
|
|
1589
|
+
action: 'followUser',
|
|
1590
|
+
args: { teamDid, userDid, followerDid },
|
|
1591
|
+
context: formatContext(req),
|
|
1592
|
+
},
|
|
1593
|
+
node
|
|
1594
|
+
);
|
|
1553
1595
|
res.json(result);
|
|
1554
1596
|
} catch (err) {
|
|
1555
1597
|
logger.error('Failed to follow user', { error: err, userDid: req.user.did });
|
|
@@ -1579,6 +1621,14 @@ module.exports = {
|
|
|
1579
1621
|
|
|
1580
1622
|
try {
|
|
1581
1623
|
const result = await node.unfollowUser({ teamDid, userDid, followerDid });
|
|
1624
|
+
await node.createAuditLog(
|
|
1625
|
+
{
|
|
1626
|
+
action: 'unfollowUser',
|
|
1627
|
+
args: { teamDid, userDid, followerDid },
|
|
1628
|
+
context: formatContext(req),
|
|
1629
|
+
},
|
|
1630
|
+
node
|
|
1631
|
+
);
|
|
1582
1632
|
res.json(result);
|
|
1583
1633
|
} catch (err) {
|
|
1584
1634
|
logger.error('Failed to unfollow user', { error: err, userDid: req.user.did });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { messages } = require('@abtnode/auth/lib/auth');
|
|
2
2
|
const { authenticateByVc, getVerifyAccessClaims, validateVerifyDestroyRequest } = require('@abtnode/auth/lib/server');
|
|
3
|
-
const { ROLES } = require('@abtnode/constant');
|
|
3
|
+
const { ROLES, PASSPORT_STATUS } = require('@abtnode/constant');
|
|
4
4
|
const { getSourceAppPid } = require('@blocklet/sdk/lib/util/login');
|
|
5
5
|
const { fromBase64 } = require('@ocap/util');
|
|
6
6
|
const { LOGIN_PROVIDER } = require('@blocklet/constant');
|
|
@@ -11,14 +11,27 @@ const logger = require('../../../libs/logger')();
|
|
|
11
11
|
const { createTokenFn, getDidConnectVersion } = require('../../../util');
|
|
12
12
|
const { getTrustedIssuers } = require('../../../util/blocklet-utils');
|
|
13
13
|
|
|
14
|
+
// GUEST 角色包含两种情况:
|
|
15
|
+
// 1. 用户没有任何身份凭证(passport)
|
|
16
|
+
// 2. 用户有身份凭证,但角色为 guest
|
|
14
17
|
const ALLOWED_ROLES = [ROLES.OWNER, ROLES.ADMIN, ROLES.MEMBER, ROLES.GUEST];
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {*} shouldCheckRole boolean or string
|
|
21
|
+
* @returns boolean
|
|
22
|
+
*/
|
|
23
|
+
const parseShouldCheckRole = (shouldCheckRole) => {
|
|
24
|
+
if (typeof shouldCheckRole === 'boolean') {
|
|
25
|
+
return shouldCheckRole;
|
|
26
|
+
}
|
|
27
|
+
return shouldCheckRole === 'true';
|
|
28
|
+
};
|
|
16
29
|
|
|
17
30
|
// eslint-disable-next-line no-unused-vars
|
|
18
31
|
module.exports = function createRoutes(node, authenticator, createSessionToken) {
|
|
19
32
|
return {
|
|
20
33
|
action: 'verify-destroy',
|
|
21
|
-
onConnect: async ({ request, userDid, extraParams: { locale, payload, roles } }) => {
|
|
34
|
+
onConnect: async ({ request, userDid, extraParams: { locale, payload, roles, shouldCheckRole = true } }) => {
|
|
22
35
|
const blocklet = await request.getBlocklet();
|
|
23
36
|
const user = await node.getUser({
|
|
24
37
|
teamDid: blocklet.appPid,
|
|
@@ -32,11 +45,18 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
32
45
|
throw new Error(messages.notAuthorized[locale]);
|
|
33
46
|
}
|
|
34
47
|
|
|
35
|
-
const
|
|
36
|
-
|
|
48
|
+
const allowedRoles = user.passports
|
|
49
|
+
.filter((x) => x.status === PASSPORT_STATUS.VALID && x.scope === 'passport')
|
|
50
|
+
.map((x) => x.role);
|
|
51
|
+
let expected = [];
|
|
52
|
+
if (parseShouldCheckRole(shouldCheckRole)) {
|
|
53
|
+
expected = validateVerifyDestroyRequest({ payload, roles, locale, allowedRoles: ALLOWED_ROLES });
|
|
54
|
+
} else {
|
|
55
|
+
expected = allowedRoles;
|
|
56
|
+
}
|
|
37
57
|
|
|
38
58
|
const sourceAppPid = getSourceAppPid(request);
|
|
39
|
-
if (!
|
|
59
|
+
if (!allowedRoles.length) {
|
|
40
60
|
return {
|
|
41
61
|
verifiableCredential: {
|
|
42
62
|
type: 'verifiableCredential',
|
|
@@ -60,7 +80,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
60
80
|
},
|
|
61
81
|
|
|
62
82
|
onAuth: async ({ request, claims, challenge, userDid, updateSession, extraParams }) => {
|
|
63
|
-
const { locale, payload } = extraParams;
|
|
83
|
+
const { locale, payload, shouldCheckRole } = extraParams;
|
|
64
84
|
const sourceAppPid = getSourceAppPid(request);
|
|
65
85
|
const [blocklet, blockletInfo] = await Promise.all([request.getBlocklet(), request.getBlockletInfo()]);
|
|
66
86
|
const userInfo = await node.getUser({
|
|
@@ -68,9 +88,22 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
68
88
|
user: { did: userDid },
|
|
69
89
|
options: { enableConnectedAccount: true },
|
|
70
90
|
});
|
|
91
|
+
|
|
92
|
+
if (!userInfo) {
|
|
93
|
+
throw new Error(messages.notAllowed[locale]);
|
|
94
|
+
}
|
|
95
|
+
if (!userInfo.approved) {
|
|
96
|
+
throw new Error(messages.notAuthorized[locale]);
|
|
97
|
+
}
|
|
98
|
+
|
|
71
99
|
const parsed = JSON.parse(fromBase64(payload).toString());
|
|
72
100
|
|
|
73
|
-
|
|
101
|
+
const userRoles = userInfo.passports
|
|
102
|
+
.filter((x) => x.status === PASSPORT_STATUS.VALID && x.scope === 'passport')
|
|
103
|
+
.map((x) => x.role);
|
|
104
|
+
|
|
105
|
+
// 如果用户没有任何 passport,则不进行验证
|
|
106
|
+
if (!parseShouldCheckRole(shouldCheckRole) && !userRoles.length) {
|
|
74
107
|
return;
|
|
75
108
|
}
|
|
76
109
|
|
|
@@ -86,7 +119,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
86
119
|
action: 'verify-destroy',
|
|
87
120
|
});
|
|
88
121
|
|
|
89
|
-
if (!
|
|
122
|
+
if (!userRoles.includes(role)) {
|
|
90
123
|
throw new Error(messages.notAllowed[locale]);
|
|
91
124
|
}
|
|
92
125
|
|
package/api/socket/util.js
CHANGED
|
@@ -5,7 +5,7 @@ const { getApplicationInfo } = require('@abtnode/auth/lib/auth');
|
|
|
5
5
|
const logger = require('../libs/logger')('socket');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @param {
|
|
8
|
+
* @param {import('@blocklet/sdk/lib/types/notification').TNotification} notification
|
|
9
9
|
* @param {{
|
|
10
10
|
* {string} name
|
|
11
11
|
* {Wallet} wallet
|
|
@@ -28,6 +28,7 @@ const parseNotification = (notification, senderInfo) => {
|
|
|
28
28
|
// actualDid is the did of the application that is used to decrypt the message if needed
|
|
29
29
|
actualDid: senderInfo.wallet.address,
|
|
30
30
|
actualPk: senderInfo.wallet.pk,
|
|
31
|
+
componentDid: senderInfo.componentDid,
|
|
31
32
|
};
|
|
32
33
|
});
|
|
33
34
|
|
|
@@ -60,6 +61,8 @@ const ensureSenderApp = async ({ sender, node, nodeInfo }) => {
|
|
|
60
61
|
throw new Error(`Invalid authentication token for sender blocklet: ${sender.appDid}`);
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
appInfo.componentDid = sender.componentDid;
|
|
65
|
+
|
|
63
66
|
return appInfo;
|
|
64
67
|
};
|
|
65
68
|
|
package/api/state/message.js
CHANGED
|
@@ -59,11 +59,19 @@ class MessageState extends BaseState {
|
|
|
59
59
|
const timeAgo = new Date();
|
|
60
60
|
timeAgo.setMinutes(timeAgo.getMinutes() - DEFAULT_TTL); // 设置过期时间
|
|
61
61
|
|
|
62
|
+
const isPostgres = this.model.sequelize.getDialect() === 'postgres';
|
|
63
|
+
|
|
62
64
|
const where = {
|
|
63
65
|
createdAt: { [Op.lt]: timeAgo },
|
|
64
66
|
expiredAt: { [Op.is]: null },
|
|
65
67
|
event: 'message',
|
|
66
|
-
[Op.and]: [
|
|
68
|
+
[Op.and]: [
|
|
69
|
+
Sequelize.literal(
|
|
70
|
+
isPostgres
|
|
71
|
+
? "data->>'type' IN ('feed', 'connect', 'passthrough')"
|
|
72
|
+
: "json_extract(data, '$.type') IN ('feed', 'connect', 'passthrough')"
|
|
73
|
+
),
|
|
74
|
+
],
|
|
67
75
|
};
|
|
68
76
|
|
|
69
77
|
const deletedCount = await this.remove({
|
package/api/util/utm.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
const { withQuery, getQuery } = require('ufo');
|
|
2
|
+
const isUrl = require('is-url');
|
|
3
|
+
const cloneDeep = require('lodash/cloneDeep');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* 为外部 URL 添加 UTM 追踪参数
|
|
8
|
+
* @param {string} url - 原始 URL 地址
|
|
9
|
+
* @param {{
|
|
10
|
+
* source?: string;
|
|
11
|
+
* medium?: string;
|
|
12
|
+
* campaign?: string;
|
|
13
|
+
* content?: string;
|
|
14
|
+
* }} utm - 导航区域,默认是 notification 的 utm
|
|
15
|
+
* @param {string} componentDid - 组件 DID
|
|
16
|
+
* @returns {string} 添加 UTM 参数后的 URL
|
|
17
|
+
* @see https://team.arcblock.io/comment/discussions/7504c5ce-7453-4223-a539-27620efcf38e#ffed52a7-916e-4586-aa78-a29a377804e6
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
function getUTMUrl(url, utm, componentDid) {
|
|
21
|
+
try {
|
|
22
|
+
if (!isUrl(url)) {
|
|
23
|
+
return url;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const existsQueryParams = getQuery(url);
|
|
27
|
+
|
|
28
|
+
// 根据 componentDid 设置默认的 emailUTMSource
|
|
29
|
+
const getDefaultUTMSource = (_componentDid) => {
|
|
30
|
+
const transactionalEmailComponents = [
|
|
31
|
+
'z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk', // Payment Kit
|
|
32
|
+
'z8iZkFBbrVQxZHvcWWB3Sa2TrfGmSeFz9MSU7', // Launcher
|
|
33
|
+
'z2qaGosS3rZ7m5ttP3Nd4V4qczR9TryTcRV4p', // DID Names
|
|
34
|
+
'z8iZnaYxnkMD5AKRjTKiCb8pQr1ut8UantAcf', // DID Spaces
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
return transactionalEmailComponents.includes(_componentDid) ? 'transactional_email' : 'activity_notification';
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const emailUTMSource = process.env.EMAIL_UTM_SOURCE || getDefaultUTMSource(componentDid);
|
|
41
|
+
const emailUTMMedium = process.env.EMAIL_UTM_MEDIUM || 'email';
|
|
42
|
+
const emailUTMCampaign = process.env.EMAIL_UTM_CAMPAIGN || 'notification';
|
|
43
|
+
const emailUTMContent = process.env.EMAIL_UTM_CONTENT || 'email_body';
|
|
44
|
+
const queryParams = {
|
|
45
|
+
// 自身站点的 hostname
|
|
46
|
+
utm_source: utm?.source || emailUTMSource,
|
|
47
|
+
// 默认为 email
|
|
48
|
+
utm_medium: utm?.medium || emailUTMMedium,
|
|
49
|
+
// 全局导航统一标签
|
|
50
|
+
utm_campaign: utm?.campaign || emailUTMCampaign,
|
|
51
|
+
// 目标站点标识
|
|
52
|
+
utm_content: utm?.content || emailUTMContent,
|
|
53
|
+
...existsQueryParams,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return withQuery(url, queryParams);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error('Failed to generate UTM URL:', error);
|
|
59
|
+
return url;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 将 notification 中的 url 添加 UTM 参数
|
|
65
|
+
* @param {import('@blocklet/sdk/lib/types/notification').TNotification} notification
|
|
66
|
+
* @returns {import('@blocklet/sdk/lib/types/notification').TNotification} 处理后的 notification 对象
|
|
67
|
+
*/
|
|
68
|
+
function attachNotificationUTM(notification) {
|
|
69
|
+
if (!notification || typeof notification !== 'object') {
|
|
70
|
+
return notification;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const componentDid = notification.sender?.componentDid;
|
|
74
|
+
|
|
75
|
+
// 创建一个深拷贝避免修改原对象
|
|
76
|
+
const notificationClone = cloneDeep(notification);
|
|
77
|
+
|
|
78
|
+
// 处理顶层的 url 字段
|
|
79
|
+
if (notificationClone.url) {
|
|
80
|
+
notificationClone.url = getUTMUrl(notificationClone.url, notificationClone.utm, componentDid);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 处理顶层的 checkUrl 字段
|
|
84
|
+
if (notificationClone.checkUrl) {
|
|
85
|
+
notificationClone.checkUrl = getUTMUrl(notificationClone.checkUrl, notificationClone.utm, componentDid);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 处理 actions 中的 link 字段
|
|
89
|
+
if (notificationClone.actions && Array.isArray(notificationClone.actions)) {
|
|
90
|
+
notificationClone.actions.forEach((action) => {
|
|
91
|
+
if (action && action.link) {
|
|
92
|
+
action.link = getUTMUrl(
|
|
93
|
+
action.link,
|
|
94
|
+
{
|
|
95
|
+
...notificationClone.utm,
|
|
96
|
+
...action.utm,
|
|
97
|
+
},
|
|
98
|
+
componentDid
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 处理 attachments 和 blocks 中的 URL
|
|
105
|
+
const processAttachments = (attachments) => {
|
|
106
|
+
if (!Array.isArray(attachments)) return;
|
|
107
|
+
|
|
108
|
+
attachments.forEach((attachment) => {
|
|
109
|
+
if (!attachment) return;
|
|
110
|
+
|
|
111
|
+
const { type, data } = attachment;
|
|
112
|
+
|
|
113
|
+
switch (type) {
|
|
114
|
+
case 'image':
|
|
115
|
+
if (data && data.url) {
|
|
116
|
+
data.url = getUTMUrl(
|
|
117
|
+
data.url,
|
|
118
|
+
{
|
|
119
|
+
...notificationClone.utm,
|
|
120
|
+
...data.utm,
|
|
121
|
+
},
|
|
122
|
+
componentDid
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
break;
|
|
126
|
+
|
|
127
|
+
case 'dapp':
|
|
128
|
+
if (data) {
|
|
129
|
+
if (data.url) {
|
|
130
|
+
data.url = getUTMUrl(
|
|
131
|
+
data.url,
|
|
132
|
+
{
|
|
133
|
+
...notificationClone.utm,
|
|
134
|
+
...data.utm,
|
|
135
|
+
},
|
|
136
|
+
componentDid
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
if (data.logo) {
|
|
140
|
+
data.logo = getUTMUrl(
|
|
141
|
+
data.logo,
|
|
142
|
+
{
|
|
143
|
+
...notificationClone.utm,
|
|
144
|
+
...data.utm,
|
|
145
|
+
},
|
|
146
|
+
componentDid
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
|
|
152
|
+
case 'link':
|
|
153
|
+
if (data) {
|
|
154
|
+
if (data.url) {
|
|
155
|
+
data.url = getUTMUrl(
|
|
156
|
+
data.url,
|
|
157
|
+
{
|
|
158
|
+
...notificationClone.utm,
|
|
159
|
+
...data.utm,
|
|
160
|
+
},
|
|
161
|
+
componentDid
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
if (data.image) {
|
|
165
|
+
data.image = getUTMUrl(
|
|
166
|
+
data.image,
|
|
167
|
+
{
|
|
168
|
+
...notificationClone.utm,
|
|
169
|
+
...data.utm,
|
|
170
|
+
},
|
|
171
|
+
componentDid
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
|
|
177
|
+
case 'section':
|
|
178
|
+
// 处理 section 中的 fields,可能包含嵌套的 attachments
|
|
179
|
+
if (attachment.fields && Array.isArray(attachment.fields)) {
|
|
180
|
+
processAttachments(attachment.fields);
|
|
181
|
+
}
|
|
182
|
+
break;
|
|
183
|
+
|
|
184
|
+
default:
|
|
185
|
+
// 对于其他类型,检查是否有通用的 url 字段
|
|
186
|
+
if (data && data.url) {
|
|
187
|
+
data.url = getUTMUrl(
|
|
188
|
+
data.url,
|
|
189
|
+
{
|
|
190
|
+
...notificationClone.utm,
|
|
191
|
+
...data.utm,
|
|
192
|
+
},
|
|
193
|
+
componentDid
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// 处理 attachments
|
|
202
|
+
if (notificationClone.attachments) {
|
|
203
|
+
processAttachments(notificationClone.attachments);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// 处理 blocks
|
|
207
|
+
if (notificationClone.blocks) {
|
|
208
|
+
processAttachments(notificationClone.blocks);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 处理 activity 中的 target.id(可能是 URL)
|
|
212
|
+
if (notificationClone.activity && notificationClone.activity.target && notificationClone.activity.target.id) {
|
|
213
|
+
notificationClone.activity.target.id = getUTMUrl(
|
|
214
|
+
notificationClone.activity.target.id,
|
|
215
|
+
{
|
|
216
|
+
...notificationClone.utm,
|
|
217
|
+
...notificationClone.activity.target.utm,
|
|
218
|
+
},
|
|
219
|
+
componentDid
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// 处理 activity 中的 meta.id(可能是 URL)
|
|
224
|
+
if (notificationClone.activity && notificationClone.activity.meta && notificationClone.activity.meta.id) {
|
|
225
|
+
notificationClone.activity.meta.id = getUTMUrl(
|
|
226
|
+
notificationClone.activity.meta.id,
|
|
227
|
+
{
|
|
228
|
+
...notificationClone.utm,
|
|
229
|
+
...notificationClone.activity.meta.utm,
|
|
230
|
+
},
|
|
231
|
+
componentDid
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return notificationClone;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
module.exports = {
|
|
239
|
+
getUTMUrl,
|
|
240
|
+
attachNotificationUTM,
|
|
241
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{_ as lt}from"./vendor-mui-core-Bq_sfmbr.js";import{d as c}from"./vendor-hooks-DLNZ8kxG.js";import{g as G}from"./vendor-react-Dvs43sk9.js";import{am as yt}from"./vendor-ux-
|
|
1
|
+
import{_ as lt}from"./vendor-mui-core-Bq_sfmbr.js";import{d as c}from"./vendor-hooks-DLNZ8kxG.js";import{g as G}from"./vendor-react-Dvs43sk9.js";import{am as yt}from"./vendor-ux-DnuP69h2.js";var b={exports:{}},pt=b.exports,rt;function Mt(){return rt||(rt=1,function(Y,z){(function(m,t){Y.exports=t()})(pt,function(){var m="week",t="year";return function(e,i,a){var r=i.prototype;r.week=function(s){if(s===void 0&&(s=null),s!==null)return this.add(7*(s-this.week()),"day");var u=this.$locale().yearStart||1;if(this.month()===11&&this.date()>25){var h=a(this).startOf(t).add(1,t).date(u),l=a(this).endOf(m);if(h.isBefore(l))return 1}var O=a(this).startOf(t).date(u).startOf(m).subtract(1,"millisecond"),$=this.diff(O,m,!0);return $<0?a(this).startOf("week").week():Math.ceil($)},r.weeks=function(s){return s===void 0&&(s=null),this.week(s)}}})}(b)),b.exports}var Tt=Mt();const gt=G(Tt);var I={exports:{}},Dt=I.exports,st;function wt(){return st||(st=1,function(Y,z){(function(m,t){Y.exports=t()})(Dt,function(){var m={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},t=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,e=/\d/,i=/\d\d/,a=/\d\d?/,r=/\d*[^-_:/,()\s\d]+/,s={},u=function(n){return(n=+n)+(n>68?1900:2e3)},h=function(n){return function(o){this[n]=+o}},l=[/[+-]\d\d:?(\d\d)?|Z/,function(n){(this.zone||(this.zone={})).offset=function(o){if(!o||o==="Z")return 0;var f=o.match(/([+-]|\d\d)/g),d=60*f[1]+(+f[2]||0);return d===0?0:f[0]==="+"?-d:d}(n)}],O=function(n){var o=s[n];return o&&(o.indexOf?o:o.s.concat(o.f))},$=function(n,o){var f,d=s.meridiem;if(d){for(var T=1;T<=24;T+=1)if(n.indexOf(d(T,0,o))>-1){f=T>12;break}}else f=n===(o?"pm":"PM");return f},ot={A:[r,function(n){this.afternoon=$(n,!1)}],a:[r,function(n){this.afternoon=$(n,!0)}],Q:[e,function(n){this.month=3*(n-1)+1}],S:[e,function(n){this.milliseconds=100*+n}],SS:[i,function(n){this.milliseconds=10*+n}],SSS:[/\d{3}/,function(n){this.milliseconds=+n}],s:[a,h("seconds")],ss:[a,h("seconds")],m:[a,h("minutes")],mm:[a,h("minutes")],H:[a,h("hours")],h:[a,h("hours")],HH:[a,h("hours")],hh:[a,h("hours")],D:[a,h("day")],DD:[i,h("day")],Do:[r,function(n){var o=s.ordinal,f=n.match(/\d+/);if(this.day=f[0],o)for(var d=1;d<=31;d+=1)o(d).replace(/\[|\]/g,"")===n&&(this.day=d)}],w:[a,h("week")],ww:[i,h("week")],M:[a,h("month")],MM:[i,h("month")],MMM:[r,function(n){var o=O("months"),f=(O("monthsShort")||o.map(function(d){return d.slice(0,3)})).indexOf(n)+1;if(f<1)throw new Error;this.month=f%12||f}],MMMM:[r,function(n){var o=O("months").indexOf(n)+1;if(o<1)throw new Error;this.month=o%12||o}],Y:[/[+-]?\d+/,h("year")],YY:[i,function(n){this.year=u(n)}],YYYY:[/\d{4}/,h("year")],Z:l,ZZ:l};function ht(n){var o,f;o=n,f=s&&s.formats;for(var d=(n=o.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(C,x,M){var p=M&&M.toUpperCase();return x||f[M]||m[M]||f[p].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(k,L,j){return L||j.slice(1)})})).match(t),T=d.length,g=0;g<T;g+=1){var U=d[g],S=ot[U],D=S&&S[0],w=S&&S[1];d[g]=w?{regex:D,parser:w}:U.replace(/^\[|\]$/g,"")}return function(C){for(var x={},M=0,p=0;M<T;M+=1){var k=d[M];if(typeof k=="string")p+=k.length;else{var L=k.regex,j=k.parser,A=C.slice(p),v=L.exec(A)[0];j.call(x,v),C=C.replace(v,"")}}return function(P){var F=P.afternoon;if(F!==void 0){var y=P.hours;F?y<12&&(P.hours+=12):y===12&&(P.hours=0),delete P.afternoon}}(x),x}}return function(n,o,f){f.p.customParseFormat=!0,n&&n.parseTwoDigitYear&&(u=n.parseTwoDigitYear);var d=o.prototype,T=d.parse;d.parse=function(g){var U=g.date,S=g.utc,D=g.args;this.$u=S;var w=D[1];if(typeof w=="string"){var C=D[2]===!0,x=D[3]===!0,M=C||x,p=D[2];x&&(p=D[2]),s=this.$locale(),!C&&p&&(s=f.Ls[p]),this.$d=function(A,v,P,F){try{if(["x","X"].indexOf(v)>-1)return new Date((v==="X"?1e3:1)*A);var y=ht(v)(A),Z=y.year,W=y.month,ut=y.day,ft=y.hours,dt=y.minutes,ct=y.seconds,mt=y.milliseconds,tt=y.zone,et=y.week,N=new Date,_=ut||(Z||W?1:N.getDate()),q=Z||N.getFullYear(),H=0;Z&&!W||(H=W>0?W-1:N.getMonth());var B,R=ft||0,Q=dt||0,X=ct||0,J=mt||0;return tt?new Date(Date.UTC(q,H,_,R,Q,X,J+60*tt.offset*1e3)):P?new Date(Date.UTC(q,H,_,R,Q,X,J)):(B=new Date(q,H,_,R,Q,X,J),et&&(B=F(B).week(et).toDate()),B)}catch{return new Date("")}}(U,w,S,f),this.init(),p&&p!==!0&&(this.$L=this.locale(p).$L),M&&U!=this.format(w)&&(this.$d=new Date("")),s={}}else if(w instanceof Array)for(var k=w.length,L=1;L<=k;L+=1){D[1]=w[L-1];var j=f.apply(this,D);if(j.isValid()){this.$d=j.$d,this.$L=j.$L,this.init();break}L===k&&(this.$d=new Date(""))}else T.call(this,g)}}})}(I)),I.exports}var Yt=wt();const Ot=G(Yt);var E={exports:{}},xt=E.exports,nt;function kt(){return nt||(nt=1,function(Y,z){(function(m,t){Y.exports=t()})(xt,function(){return function(m,t,e){t.prototype.isBetween=function(i,a,r,s){var u=e(i),h=e(a),l=(s=s||"()")[0]==="(",O=s[1]===")";return(l?this.isAfter(u,r):!this.isBefore(u,r))&&(O?this.isBefore(h,r):!this.isAfter(h,r))||(l?this.isBefore(u,r):!this.isAfter(u,r))&&(O?this.isAfter(h,r):!this.isBefore(h,r))}}})}(E)),E.exports}var Lt=kt();const zt=G(Lt);var V={exports:{}},St=V.exports,it;function Ct(){return it||(it=1,function(Y,z){(function(m,t){Y.exports=t()})(St,function(){return function(m,t){var e=t.prototype,i=e.format;e.format=function(a){var r=this,s=this.$locale();if(!this.isValid())return i.bind(this)(a);var u=this.$utils(),h=(a||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(l){switch(l){case"Q":return Math.ceil((r.$M+1)/3);case"Do":return s.ordinal(r.$D);case"gggg":return r.weekYear();case"GGGG":return r.isoWeekYear();case"wo":return s.ordinal(r.week(),"W");case"w":case"ww":return u.s(r.week(),l==="w"?1:2,"0");case"W":case"WW":return u.s(r.isoWeek(),l==="W"?1:2,"0");case"k":case"kk":return u.s(String(r.$H===0?24:r.$H),l==="k"?1:2,"0");case"X":return Math.floor(r.$d.getTime()/1e3);case"x":return r.$d.getTime();case"z":return"["+r.offsetName()+"]";case"zzz":return"["+r.offsetName("long")+"]";default:return l}});return i.bind(this)(h)}}})}(V)),V.exports}var jt=Ct();const Pt=G(jt);c.extend(yt);c.extend(gt);c.extend(zt);c.extend(Pt);const vt={YY:"year",YYYY:{sectionType:"year",contentType:"digit",maxLength:4},M:{sectionType:"month",contentType:"digit",maxLength:2},MM:"month",MMM:{sectionType:"month",contentType:"letter"},MMMM:{sectionType:"month",contentType:"letter"},D:{sectionType:"day",contentType:"digit",maxLength:2},DD:"day",Do:{sectionType:"day",contentType:"digit-with-letter"},d:{sectionType:"weekDay",contentType:"digit",maxLength:2},dd:{sectionType:"weekDay",contentType:"letter"},ddd:{sectionType:"weekDay",contentType:"letter"},dddd:{sectionType:"weekDay",contentType:"letter"},A:"meridiem",a:"meridiem",H:{sectionType:"hours",contentType:"digit",maxLength:2},HH:"hours",h:{sectionType:"hours",contentType:"digit",maxLength:2},hh:"hours",m:{sectionType:"minutes",contentType:"digit",maxLength:2},mm:"minutes",s:{sectionType:"seconds",contentType:"digit",maxLength:2},ss:"seconds"},$t={year:"YYYY",month:"MMMM",monthShort:"MMM",dayOfMonth:"D",dayOfMonthFull:"Do",weekday:"dddd",weekdayShort:"dd",hours24h:"HH",hours12h:"hh",meridiem:"A",minutes:"mm",seconds:"ss",fullDate:"ll",keyboardDate:"L",shortDate:"MMM D",normalDate:"D MMMM",normalDateWithWeekday:"ddd, MMM D",fullTime12h:"hh:mm A",fullTime24h:"HH:mm",keyboardDateTime12h:"L hh:mm A",keyboardDateTime24h:"L HH:mm"},K=["Missing UTC plugin","To be able to use UTC or timezones, you have to enable the `utc` plugin","Find more information on https://mui.com/x/react-date-pickers/timezone/#day-js-and-utc"].join(`
|
|
2
2
|
`),at=["Missing timezone plugin","To be able to use timezones, you have to enable both the `utc` and the `timezone` plugin","Find more information on https://mui.com/x/react-date-pickers/timezone/#day-js-and-timezone"].join(`
|
|
3
3
|
`);class Bt{constructor({locale:z,formats:m}={}){this.isMUIAdapter=!0,this.isTimezoneCompatible=!0,this.lib="dayjs",this.locale=void 0,this.formats=void 0,this.escapedCharacters={start:"[",end:"]"},this.formatTokenMap=vt,this.setLocaleToValue=t=>{const e=this.getCurrentLocaleCode();return e===t.locale()?t:t.locale(e)},this.hasUTCPlugin=()=>typeof c.utc<"u",this.hasTimezonePlugin=()=>typeof c.tz<"u",this.isSame=(t,e,i)=>{const a=this.setTimezone(e,this.getTimezone(t));return t.format(i)===a.format(i)},this.cleanTimezone=t=>{switch(t){case"default":return;case"system":return c.tz.guess();default:return t}},this.createSystemDate=t=>{let e;if(this.hasUTCPlugin()&&this.hasTimezonePlugin()){const i=c.tz.guess();i==="UTC"?e=c(t):e=c.tz(t,i)}else e=c(t);return this.setLocaleToValue(e)},this.createUTCDate=t=>{if(!this.hasUTCPlugin())throw new Error(K);return this.setLocaleToValue(c.utc(t))},this.createTZDate=(t,e)=>{if(!this.hasUTCPlugin())throw new Error(K);if(!this.hasTimezonePlugin())throw new Error(at);const i=t!==void 0&&!t.endsWith("Z");return this.setLocaleToValue(c(t).tz(this.cleanTimezone(e),i))},this.getLocaleFormats=()=>{const t=c.Ls,e=this.locale||"en";let i=t[e];return i===void 0&&(i=t.en),i.formats},this.adjustOffset=t=>{if(!this.hasTimezonePlugin())return t;const e=this.getTimezone(t);if(e!=="UTC"){const i=t.tz(this.cleanTimezone(e),!0);if(i.$offset===(t.$offset??0))return t;t.$offset=i.$offset}return t},this.date=(t,e="default")=>t===null?null:e==="UTC"?this.createUTCDate(t):e==="system"||e==="default"&&!this.hasTimezonePlugin()?this.createSystemDate(t):this.createTZDate(t,e),this.getInvalidDate=()=>c(new Date("Invalid date")),this.getTimezone=t=>{if(this.hasTimezonePlugin()){const e=t.$x?.$timezone;if(e)return e}return this.hasUTCPlugin()&&t.isUTC()?"UTC":"system"},this.setTimezone=(t,e)=>{if(this.getTimezone(t)===e)return t;if(e==="UTC"){if(!this.hasUTCPlugin())throw new Error(K);return t.utc()}if(e==="system")return t.local();if(!this.hasTimezonePlugin()){if(e==="default")return t;throw new Error(at)}return this.setLocaleToValue(c.tz(t,this.cleanTimezone(e)))},this.toJsDate=t=>t.toDate(),this.parse=(t,e)=>t===""?null:c(t,e,this.locale,!0),this.getCurrentLocaleCode=()=>this.locale||"en",this.is12HourCycleInCurrentLocale=()=>/A|a/.test(this.getLocaleFormats().LT||""),this.expandFormat=t=>{const e=this.getLocaleFormats(),i=a=>a.replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(r,s,u)=>s||u.slice(1));return t.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(a,r,s)=>{const u=s&&s.toUpperCase();return r||e[s]||i(e[u])})},this.isValid=t=>t==null?!1:t.isValid(),this.format=(t,e)=>this.formatByString(t,this.formats[e]),this.formatByString=(t,e)=>this.setLocaleToValue(t).format(e),this.formatNumber=t=>t,this.isEqual=(t,e)=>t===null&&e===null?!0:t===null||e===null?!1:t.toDate().getTime()===e.toDate().getTime(),this.isSameYear=(t,e)=>this.isSame(t,e,"YYYY"),this.isSameMonth=(t,e)=>this.isSame(t,e,"YYYY-MM"),this.isSameDay=(t,e)=>this.isSame(t,e,"YYYY-MM-DD"),this.isSameHour=(t,e)=>t.isSame(e,"hour"),this.isAfter=(t,e)=>t>e,this.isAfterYear=(t,e)=>this.hasUTCPlugin()?!this.isSameYear(t,e)&&t.utc()>e.utc():t.isAfter(e,"year"),this.isAfterDay=(t,e)=>this.hasUTCPlugin()?!this.isSameDay(t,e)&&t.utc()>e.utc():t.isAfter(e,"day"),this.isBefore=(t,e)=>t<e,this.isBeforeYear=(t,e)=>this.hasUTCPlugin()?!this.isSameYear(t,e)&&t.utc()<e.utc():t.isBefore(e,"year"),this.isBeforeDay=(t,e)=>this.hasUTCPlugin()?!this.isSameDay(t,e)&&t.utc()<e.utc():t.isBefore(e,"day"),this.isWithinRange=(t,[e,i])=>t>=e&&t<=i,this.startOfYear=t=>this.adjustOffset(t.startOf("year")),this.startOfMonth=t=>this.adjustOffset(t.startOf("month")),this.startOfWeek=t=>this.adjustOffset(this.setLocaleToValue(t).startOf("week")),this.startOfDay=t=>this.adjustOffset(t.startOf("day")),this.endOfYear=t=>this.adjustOffset(t.endOf("year")),this.endOfMonth=t=>this.adjustOffset(t.endOf("month")),this.endOfWeek=t=>this.adjustOffset(this.setLocaleToValue(t).endOf("week")),this.endOfDay=t=>this.adjustOffset(t.endOf("day")),this.addYears=(t,e)=>this.adjustOffset(t.add(e,"year")),this.addMonths=(t,e)=>this.adjustOffset(t.add(e,"month")),this.addWeeks=(t,e)=>this.adjustOffset(t.add(e,"week")),this.addDays=(t,e)=>this.adjustOffset(t.add(e,"day")),this.addHours=(t,e)=>this.adjustOffset(t.add(e,"hour")),this.addMinutes=(t,e)=>this.adjustOffset(t.add(e,"minute")),this.addSeconds=(t,e)=>this.adjustOffset(t.add(e,"second")),this.getYear=t=>t.year(),this.getMonth=t=>t.month(),this.getDate=t=>t.date(),this.getHours=t=>t.hour(),this.getMinutes=t=>t.minute(),this.getSeconds=t=>t.second(),this.getMilliseconds=t=>t.millisecond(),this.setYear=(t,e)=>this.adjustOffset(t.set("year",e)),this.setMonth=(t,e)=>this.adjustOffset(t.set("month",e)),this.setDate=(t,e)=>this.adjustOffset(t.set("date",e)),this.setHours=(t,e)=>this.adjustOffset(t.set("hour",e)),this.setMinutes=(t,e)=>this.adjustOffset(t.set("minute",e)),this.setSeconds=(t,e)=>this.adjustOffset(t.set("second",e)),this.setMilliseconds=(t,e)=>this.adjustOffset(t.set("millisecond",e)),this.getDaysInMonth=t=>t.daysInMonth(),this.getWeekArray=t=>{const e=this.startOfWeek(this.startOfMonth(t)),i=this.endOfWeek(this.endOfMonth(t));let a=0,r=e;const s=[];for(;r<i;){const u=Math.floor(a/7);s[u]=s[u]||[],s[u].push(r),r=this.addDays(r,1),a+=1}return s},this.getWeekNumber=t=>t.week(),this.getYearRange=([t,e])=>{const i=this.startOfYear(t),a=this.endOfYear(e),r=[];let s=i;for(;this.isBefore(s,a);)r.push(s),s=this.addYears(s,1);return r},this.locale=z,this.formats=lt({},$t,m),c.extend(Ot)}getDayOfWeek(z){return z.day()+1}}export{Bt as A};
|