From e8c576f488d3700fa1ff21559aa59678bcc97912 Mon Sep 17 00:00:00 2001 From: Tao Xin Date: Sat, 11 May 2024 08:11:53 -0700 Subject: [PATCH 1/5] Patch to allow Cloudflare workers to read environment variables --- src/server/function/twikoo/utils/constants.js | 2 +- src/server/function/twikoo/utils/image.js | 4 ++-- src/server/function/twikoo/utils/logger.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/function/twikoo/utils/constants.js b/src/server/function/twikoo/utils/constants.js index ca995e57e..8d9d45fdb 100644 --- a/src/server/function/twikoo/utils/constants.js +++ b/src/server/function/twikoo/utils/constants.js @@ -15,5 +15,5 @@ module.exports = { AKISMET_ERROR: 1030, UPLOAD_FAILED: 1040 }, - MAX_REQUEST_TIMES: parseInt(process.env.TWIKOO_THROTTLE) || 250 + MAX_REQUEST_TIMES: parseInt((process ? process.env : env).TWIKOO_THROTTLE) || 250 } diff --git a/src/server/function/twikoo/utils/image.js b/src/server/function/twikoo/utils/image.js index fdd21b5a8..815a20c63 100644 --- a/src/server/function/twikoo/utils/image.js +++ b/src/server/function/twikoo/utils/image.js @@ -49,8 +49,8 @@ const fn = { // 自定义兰空图床(v2)URL const formData = new FormData() formData.append('file', fn.base64UrlToReadStream(photo, fileName)) - if (process.env.TWIKOO_LSKY_STRATEGY_ID) { - formData.append('strategy_id', parseInt(process.env.TWIKOO_LSKY_STRATEGY_ID)) + if ((process ? process.env : env).env.TWIKOO_LSKY_STRATEGY_ID) { + formData.append('strategy_id', parseInt((process ? process.env : env).env.TWIKOO_LSKY_STRATEGY_ID)) } const url = `${imageCdn}/api/v1/upload` let token = config.IMAGE_CDN_TOKEN diff --git a/src/server/function/twikoo/utils/logger.js b/src/server/function/twikoo/utils/logger.js index f53422777..e0c967889 100644 --- a/src/server/function/twikoo/utils/logger.js +++ b/src/server/function/twikoo/utils/logger.js @@ -1,4 +1,4 @@ -let envLogLevel = process.env.TWIKOO_LOG_LEVEL || 'info' +let envLogLevel = (process ? process.env : env).TWIKOO_LOG_LEVEL || 'info' envLogLevel = envLogLevel.toLowerCase() const logLevel = { verbose: 1, info: 2, warn: 3, error: 4 }[envLogLevel] || 2 From fa89fe02ae073adbded2f7f58638eaabb44ebf55 Mon Sep 17 00:00:00 2001 From: Tao Xin Date: Sun, 12 May 2024 09:06:27 -0700 Subject: [PATCH 2/5] Move getDomPurify out of lib.js --- src/server/function/twikoo/index.js | 2 +- src/server/function/twikoo/package.json | 4 ++-- src/server/function/twikoo/utils/dom.js | 13 +++++++++++++ src/server/function/twikoo/utils/import.js | 3 ++- src/server/function/twikoo/utils/lib.js | 10 ---------- src/server/self-hosted/index.js | 2 +- src/server/vercel/api/index.js | 2 +- 7 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 src/server/function/twikoo/utils/dom.js diff --git a/src/server/function/twikoo/index.js b/src/server/function/twikoo/index.js index 2d72b0251..3b9d59d10 100644 --- a/src/server/function/twikoo/index.js +++ b/src/server/function/twikoo/index.js @@ -8,7 +8,6 @@ const { version: VERSION } = require('./package.json') const tcb = require('@cloudbase/node-sdk') // 云开发 SDK const { $, - getDomPurify, md5, xml2js } = require('./utils/lib') @@ -44,6 +43,7 @@ const { postCheckSpam } = require('./utils/spam') const { sendNotice, emailTest } = require('./utils/notify') const { uploadImage } = require('./utils/image') const logger = require('./utils/logger') +const { getDomPurify } = require('./utils/dom') // 云函数 SDK / tencent cloudbase sdk const app = tcb.init({ env: tcb.SYMBOL_CURRENT_ENV }) diff --git a/src/server/function/twikoo/package.json b/src/server/function/twikoo/package.json index 26726f4f6..3e6a1451e 100644 --- a/src/server/function/twikoo/package.json +++ b/src/server/function/twikoo/package.json @@ -1,6 +1,6 @@ { - "name": "twikoo-func", - "version": "1.6.32", + "name": "twikoo-func-cloudflare-patch", + "version": "1.6.33-rc.0", "description": "A simple comment system.", "author": "imaegoo (https://github.com/imaegoo)", "license": "MIT", diff --git a/src/server/function/twikoo/utils/dom.js b/src/server/function/twikoo/utils/dom.js new file mode 100644 index 000000000..96e857fc3 --- /dev/null +++ b/src/server/function/twikoo/utils/dom.js @@ -0,0 +1,13 @@ +const { JSDOM } = require('jsdom') // document.window 服务器版 +const createDOMPurify = require('dompurify') // 反 XSS + +function getDomPurify () { + // 初始化反 XSS + const window = new JSDOM('').window + const DOMPurify = createDOMPurify(window) + return DOMPurify +} + +module.exports = { + getDomPurify +} diff --git a/src/server/function/twikoo/utils/import.js b/src/server/function/twikoo/utils/import.js index b827b3e07..0ca6e924a 100644 --- a/src/server/function/twikoo/utils/import.js +++ b/src/server/function/twikoo/utils/import.js @@ -1,5 +1,6 @@ const { getRelativeUrl, normalizeMail } = require('.') -const { marked, getDomPurify, md5 } = require('./lib') +const { marked, md5 } = require('./lib') +const { getDomPurify } = require('./dom') const fn = { // 兼容 Leancloud 两种 JSON 导出格式 diff --git a/src/server/function/twikoo/utils/lib.js b/src/server/function/twikoo/utils/lib.js index 861995820..d9eefb4cd 100644 --- a/src/server/function/twikoo/utils/lib.js +++ b/src/server/function/twikoo/utils/lib.js @@ -2,10 +2,8 @@ const $ = require('cheerio') // jQuery 服务器版 const { AkismetClient } = require('akismet-api') // 反垃圾 API const CryptoJS = require('crypto-js') // 编解码 const FormData = require('form-data') // 图片上传 -const { JSDOM } = require('jsdom') // document.window 服务器版 const axios = require('axios') // 发送 REST 请求 const bowser = require('bowser') // UserAgent 格式化 -const createDOMPurify = require('dompurify') // 反 XSS const ipToRegion = require('@imaegoo/node-ip2region') // IP 属地查询 const marked = require('marked') // Markdown 解析 const md5 = require('blueimp-md5') // MD5 加解密 @@ -14,13 +12,6 @@ const pushoo = require('pushoo').default // 即时消息通知 const tencentcloud = require('tencentcloud-sdk-nodejs') // 腾讯云 API NODEJS SDK const xml2js = require('xml2js') // XML 解析 -function getDomPurify () { - // 初始化反 XSS - const window = new JSDOM('').window - const DOMPurify = createDOMPurify(window) - return DOMPurify -} - module.exports = { $, AkismetClient, @@ -28,7 +19,6 @@ module.exports = { FormData, axios, bowser, - getDomPurify, ipToRegion, marked, md5, diff --git a/src/server/self-hosted/index.js b/src/server/self-hosted/index.js index d1fb7c94a..1d6bcdeec 100644 --- a/src/server/self-hosted/index.js +++ b/src/server/self-hosted/index.js @@ -13,7 +13,6 @@ const Lfsa = require('lokijs/src/loki-fs-structured-adapter') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { $, - getDomPurify, md5, xml2js } = require('twikoo-func/utils/lib') @@ -49,6 +48,7 @@ const { postCheckSpam } = require('twikoo-func/utils/spam') const { sendNotice, emailTest } = require('twikoo-func/utils/notify') const { uploadImage } = require('twikoo-func/utils/image') const logger = require('twikoo-func/utils/logger') +const { getDomPurify } = require('twikoo-func/utils/dom') const DOMPurify = getDomPurify() diff --git a/src/server/vercel/api/index.js b/src/server/vercel/api/index.js index e44db3b2a..68e30a4ef 100644 --- a/src/server/vercel/api/index.js +++ b/src/server/vercel/api/index.js @@ -12,7 +12,6 @@ const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { $, axios, - getDomPurify, md5, xml2js } = require('twikoo-func/utils/lib') @@ -48,6 +47,7 @@ const { postCheckSpam } = require('twikoo-func/utils/spam') const { sendNotice, emailTest } = require('twikoo-func/utils/notify') const { uploadImage } = require('twikoo-func/utils/image') const logger = require('twikoo-func/utils/logger') +const { getDomPurify } = require('twikoo-func/utils/dom') const DOMPurify = getDomPurify() From a6a0840a1cdd22e7590357c001eae9f047983ee7 Mon Sep 17 00:00:00 2001 From: Tao Xin Date: Sun, 12 May 2024 09:15:11 -0700 Subject: [PATCH 3/5] Remove the env-var workaround that doesn't work --- src/server/function/twikoo/utils/constants.js | 2 +- src/server/function/twikoo/utils/image.js | 4 ++-- src/server/function/twikoo/utils/logger.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/function/twikoo/utils/constants.js b/src/server/function/twikoo/utils/constants.js index 8d9d45fdb..ca995e57e 100644 --- a/src/server/function/twikoo/utils/constants.js +++ b/src/server/function/twikoo/utils/constants.js @@ -15,5 +15,5 @@ module.exports = { AKISMET_ERROR: 1030, UPLOAD_FAILED: 1040 }, - MAX_REQUEST_TIMES: parseInt((process ? process.env : env).TWIKOO_THROTTLE) || 250 + MAX_REQUEST_TIMES: parseInt(process.env.TWIKOO_THROTTLE) || 250 } diff --git a/src/server/function/twikoo/utils/image.js b/src/server/function/twikoo/utils/image.js index 815a20c63..fdd21b5a8 100644 --- a/src/server/function/twikoo/utils/image.js +++ b/src/server/function/twikoo/utils/image.js @@ -49,8 +49,8 @@ const fn = { // 自定义兰空图床(v2)URL const formData = new FormData() formData.append('file', fn.base64UrlToReadStream(photo, fileName)) - if ((process ? process.env : env).env.TWIKOO_LSKY_STRATEGY_ID) { - formData.append('strategy_id', parseInt((process ? process.env : env).env.TWIKOO_LSKY_STRATEGY_ID)) + if (process.env.TWIKOO_LSKY_STRATEGY_ID) { + formData.append('strategy_id', parseInt(process.env.TWIKOO_LSKY_STRATEGY_ID)) } const url = `${imageCdn}/api/v1/upload` let token = config.IMAGE_CDN_TOKEN diff --git a/src/server/function/twikoo/utils/logger.js b/src/server/function/twikoo/utils/logger.js index e0c967889..f53422777 100644 --- a/src/server/function/twikoo/utils/logger.js +++ b/src/server/function/twikoo/utils/logger.js @@ -1,4 +1,4 @@ -let envLogLevel = (process ? process.env : env).TWIKOO_LOG_LEVEL || 'info' +let envLogLevel = process.env.TWIKOO_LOG_LEVEL || 'info' envLogLevel = envLogLevel.toLowerCase() const logLevel = { verbose: 1, info: 2, warn: 3, error: 4 }[envLogLevel] || 2 From ed68d518d72e0420bef5ab666e9e881b06b0f55b Mon Sep 17 00:00:00 2001 From: Tao Xin Date: Mon, 13 May 2024 15:59:34 -0700 Subject: [PATCH 4/5] Complete all changes for Cloudflare compatibility --- src/server/function/twikoo/package.json | 7 +++-- .../function/twikoo/utils/cloudflare.js | 7 +++++ src/server/function/twikoo/utils/dom.js | 31 +++++++++++++++---- src/server/function/twikoo/utils/index.js | 12 +++++-- src/server/function/twikoo/utils/lib.js | 6 ---- src/server/function/twikoo/utils/spam.js | 14 +++++++-- 6 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 src/server/function/twikoo/utils/cloudflare.js diff --git a/src/server/function/twikoo/package.json b/src/server/function/twikoo/package.json index 3e6a1451e..592e392d9 100644 --- a/src/server/function/twikoo/package.json +++ b/src/server/function/twikoo/package.json @@ -1,6 +1,6 @@ { - "name": "twikoo-func-cloudflare-patch", - "version": "1.6.33-rc.0", + "name": "twikoo-func", + "version": "1.6.33", "description": "A simple comment system.", "author": "imaegoo (https://github.com/imaegoo)", "license": "MIT", @@ -27,6 +27,7 @@ "nodemailer": "^6.4.17", "pushoo": "latest", "tencentcloud-sdk-nodejs": "^4.0.65", - "xml2js": "^0.6.0" + "xml2js": "^0.6.0", + "xss": "^1.0.15" } } diff --git a/src/server/function/twikoo/utils/cloudflare.js b/src/server/function/twikoo/utils/cloudflare.js new file mode 100644 index 000000000..d7ceb3ec4 --- /dev/null +++ b/src/server/function/twikoo/utils/cloudflare.js @@ -0,0 +1,7 @@ +function isInCloudflare () { + return typeof addEventListener === "function" +} + +module.exports = { + isInCloudflare +} diff --git a/src/server/function/twikoo/utils/dom.js b/src/server/function/twikoo/utils/dom.js index 96e857fc3..1015801bd 100644 --- a/src/server/function/twikoo/utils/dom.js +++ b/src/server/function/twikoo/utils/dom.js @@ -1,11 +1,30 @@ -const { JSDOM } = require('jsdom') // document.window 服务器版 -const createDOMPurify = require('dompurify') // 反 XSS +const { isInCloudflare } = require('./cloudflare') +const xss = require('xss') + +let createDOMPurify, JSDOM + +if (!isInCloudflare()) { + createDOMPurify = require('dompurify') // 反 XSS + JSDOM = require('jsdom') // document.window 服务器版 +} + +function getXssPurify () { + return { + sanitize(input) { + return xss(input) + } + } +} function getDomPurify () { - // 初始化反 XSS - const window = new JSDOM('').window - const DOMPurify = createDOMPurify(window) - return DOMPurify + if (createDOMPurify) { + // 初始化反 XSS + const window = new JSDOM('').window + const DOMPurify = createDOMPurify(window) + return DOMPurify + } else { + return getXssPurify() + } } module.exports = { diff --git a/src/server/function/twikoo/utils/index.js b/src/server/function/twikoo/utils/index.js index 3fbf044a1..4718e418b 100644 --- a/src/server/function/twikoo/utils/index.js +++ b/src/server/function/twikoo/utils/index.js @@ -1,9 +1,15 @@ const { URL } = require('url') -const { axios, FormData, bowser, ipToRegion, md5 } = require('./lib') +const { axios, FormData, bowser, md5 } = require('./lib') const { RES_CODE } = require('./constants') -const ipRegionSearcher = ipToRegion.create() // 初始化 IP 属地 const logger = require('./logger') +let ipRegionSearcher + +// IP 属地查询 +function getIpRegionSearcher () { + return ipRegionSearcher ?? (ipRegionSearcher = require('@imaegoo/node-ip2region').create()) +} + const fn = { // 获取 Twikoo 云函数版本 getFuncVersion (VERSION) { @@ -119,7 +125,7 @@ const fn = { ip = ip.replace(/^::ffff:/, '') // Zeabur 返回的地址带端口号,去掉端口号。TODO: 不知道该怎么去掉 IPv6 地址后面的端口号 ip = ip.replace(/:[0-9]*$/, '') - const { region } = ipRegionSearcher.binarySearchSync(ip) + const { region } = getIpRegionSearcher().binarySearchSync(ip) const [country,, province, city, isp] = region.split('|') // 有省显示省,没有省显示国家 const area = province.trim() && province !== '0' ? province : country diff --git a/src/server/function/twikoo/utils/lib.js b/src/server/function/twikoo/utils/lib.js index d9eefb4cd..3f39aeb9e 100644 --- a/src/server/function/twikoo/utils/lib.js +++ b/src/server/function/twikoo/utils/lib.js @@ -4,12 +4,9 @@ const CryptoJS = require('crypto-js') // 编解码 const FormData = require('form-data') // 图片上传 const axios = require('axios') // 发送 REST 请求 const bowser = require('bowser') // UserAgent 格式化 -const ipToRegion = require('@imaegoo/node-ip2region') // IP 属地查询 const marked = require('marked') // Markdown 解析 const md5 = require('blueimp-md5') // MD5 加解密 -const nodemailer = require('nodemailer') // 发送邮件 const pushoo = require('pushoo').default // 即时消息通知 -const tencentcloud = require('tencentcloud-sdk-nodejs') // 腾讯云 API NODEJS SDK const xml2js = require('xml2js') // XML 解析 module.exports = { @@ -19,11 +16,8 @@ module.exports = { FormData, axios, bowser, - ipToRegion, marked, md5, - nodemailer, pushoo, - tencentcloud, xml2js } diff --git a/src/server/function/twikoo/utils/spam.js b/src/server/function/twikoo/utils/spam.js index 95c76e64a..cc2c70e2e 100644 --- a/src/server/function/twikoo/utils/spam.js +++ b/src/server/function/twikoo/utils/spam.js @@ -1,9 +1,19 @@ const { AkismetClient, CryptoJS, - tencentcloud } = require('./lib') const logger = require('./logger') +let tencentcloud + +function getTencentCloud () { + if (tencentcloud) return tencentcloud + try { + tencentcloud = require('tencentcloud-sdk-nodejs') // 腾讯云 API NODEJS SDK + } catch (e) { + logger.log('加载 "tencentcloud-sdk-nodejs" 失败', e) + } + return tencentcloud +} const fn = { // 后垃圾评论检测 @@ -15,7 +25,7 @@ const fn = { isSpam = true } else if (config.QCLOUD_SECRET_ID && config.QCLOUD_SECRET_KEY) { // 腾讯云内容安全 - const client = new tencentcloud.tms.v20200713.Client({ + const client = new getTencentCloud().tms.v20200713.Client({ credential: { secretId: config.QCLOUD_SECRET_ID, secretKey: config.QCLOUD_SECRET_KEY }, region: 'ap-shanghai', profile: { httpProfile: { endpoint: 'tms.tencentcloudapi.com' } } From 113e678a28e93a2f07334a0bff298a8e9f5ac554 Mon Sep 17 00:00:00 2001 From: iMaeGoo Date: Tue, 14 May 2024 16:53:39 +0800 Subject: [PATCH 5/5] =?UTF-8?q?refactor:=20only=20require=20lib=20when=20n?= =?UTF-8?q?eeded=20=E4=BB=85=E5=9C=A8=E9=9C=80=E8=A6=81=E6=97=B6=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E7=AC=AC=E4=B8=89=E6=96=B9=E4=BE=9D=E8=B5=96=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E6=9F=90=E4=B8=80=E4=B8=AA=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E5=85=BC=E5=AE=B9=E6=80=A7=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E8=80=8C=E6=97=A0=E6=B3=95=E5=AF=BC=E5=85=A5=E5=85=B6=E4=BB=96?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 3 +- src/server/function/twikoo/index.js | 11 ++- src/server/function/twikoo/package.json | 5 +- .../function/twikoo/utils/cloudflare.js | 7 -- src/server/function/twikoo/utils/dom.js | 32 -------- src/server/function/twikoo/utils/image.js | 4 +- src/server/function/twikoo/utils/import.js | 5 +- src/server/function/twikoo/utils/index.js | 18 ++++- src/server/function/twikoo/utils/lib.js | 81 ++++++++++++++----- src/server/function/twikoo/utils/notify.js | 9 ++- src/server/function/twikoo/utils/spam.js | 22 +++-- src/server/self-hosted/index.js | 11 ++- src/server/self-hosted/mongo.js | 9 ++- src/server/vercel/api/index.js | 14 ++-- 14 files changed, 135 insertions(+), 96 deletions(-) delete mode 100644 src/server/function/twikoo/utils/cloudflare.js delete mode 100644 src/server/function/twikoo/utils/dom.js diff --git a/.eslintignore b/.eslintignore index f3a24f38f..97c366766 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,4 +8,5 @@ yarn.lock src/server/pkg/dist/* src/server/pkg/patches/* src/server/pkg/web.config -pnpm-lock.yaml \ No newline at end of file +pnpm-lock.yaml +Spacefile diff --git a/src/server/function/twikoo/index.js b/src/server/function/twikoo/index.js index 3b9d59d10..d064bd734 100644 --- a/src/server/function/twikoo/index.js +++ b/src/server/function/twikoo/index.js @@ -7,9 +7,10 @@ const { version: VERSION } = require('./package.json') const tcb = require('@cloudbase/node-sdk') // 云开发 SDK const { - $, - md5, - xml2js + getCheerio, + getDomPurify, + getMd5, + getXml2js } = require('./utils/lib') const { getFuncVersion, @@ -43,14 +44,16 @@ const { postCheckSpam } = require('./utils/spam') const { sendNotice, emailTest } = require('./utils/notify') const { uploadImage } = require('./utils/image') const logger = require('./utils/logger') -const { getDomPurify } = require('./utils/dom') // 云函数 SDK / tencent cloudbase sdk const app = tcb.init({ env: tcb.SYMBOL_CURRENT_ENV }) const auth = app.auth() const db = app.database() const _ = db.command +const $ = getCheerio() const DOMPurify = getDomPurify() +const md5 = getMd5() +const xml2js = getXml2js() // 常量 / constants const { RES_CODE, MAX_REQUEST_TIMES } = require('./utils/constants') diff --git a/src/server/function/twikoo/package.json b/src/server/function/twikoo/package.json index 592e392d9..26726f4f6 100644 --- a/src/server/function/twikoo/package.json +++ b/src/server/function/twikoo/package.json @@ -1,6 +1,6 @@ { "name": "twikoo-func", - "version": "1.6.33", + "version": "1.6.32", "description": "A simple comment system.", "author": "imaegoo (https://github.com/imaegoo)", "license": "MIT", @@ -27,7 +27,6 @@ "nodemailer": "^6.4.17", "pushoo": "latest", "tencentcloud-sdk-nodejs": "^4.0.65", - "xml2js": "^0.6.0", - "xss": "^1.0.15" + "xml2js": "^0.6.0" } } diff --git a/src/server/function/twikoo/utils/cloudflare.js b/src/server/function/twikoo/utils/cloudflare.js deleted file mode 100644 index d7ceb3ec4..000000000 --- a/src/server/function/twikoo/utils/cloudflare.js +++ /dev/null @@ -1,7 +0,0 @@ -function isInCloudflare () { - return typeof addEventListener === "function" -} - -module.exports = { - isInCloudflare -} diff --git a/src/server/function/twikoo/utils/dom.js b/src/server/function/twikoo/utils/dom.js deleted file mode 100644 index 1015801bd..000000000 --- a/src/server/function/twikoo/utils/dom.js +++ /dev/null @@ -1,32 +0,0 @@ -const { isInCloudflare } = require('./cloudflare') -const xss = require('xss') - -let createDOMPurify, JSDOM - -if (!isInCloudflare()) { - createDOMPurify = require('dompurify') // 反 XSS - JSDOM = require('jsdom') // document.window 服务器版 -} - -function getXssPurify () { - return { - sanitize(input) { - return xss(input) - } - } -} - -function getDomPurify () { - if (createDOMPurify) { - // 初始化反 XSS - const window = new JSDOM('').window - const DOMPurify = createDOMPurify(window) - return DOMPurify - } else { - return getXssPurify() - } -} - -module.exports = { - getDomPurify -} diff --git a/src/server/function/twikoo/utils/image.js b/src/server/function/twikoo/utils/image.js index fdd21b5a8..5b93d3f33 100644 --- a/src/server/function/twikoo/utils/image.js +++ b/src/server/function/twikoo/utils/image.js @@ -3,7 +3,9 @@ const os = require('os') const path = require('path') const { isUrl } = require('.') const { RES_CODE } = require('./constants') -const { axios, FormData } = require('./lib') +const { getAxios, getFormData } = require('./lib') +const axios = getAxios() +const FormData = getFormData() const logger = require('./logger') const fn = { diff --git a/src/server/function/twikoo/utils/import.js b/src/server/function/twikoo/utils/import.js index 0ca6e924a..ecf9d1747 100644 --- a/src/server/function/twikoo/utils/import.js +++ b/src/server/function/twikoo/utils/import.js @@ -1,6 +1,7 @@ const { getRelativeUrl, normalizeMail } = require('.') -const { marked, md5 } = require('./lib') -const { getDomPurify } = require('./dom') +const { getMarked, getDomPurify, getMd5 } = require('./lib') +const marked = getMarked() +const md5 = getMd5() const fn = { // 兼容 Leancloud 两种 JSON 导出格式 diff --git a/src/server/function/twikoo/utils/index.js b/src/server/function/twikoo/utils/index.js index 4718e418b..580dcb1d1 100644 --- a/src/server/function/twikoo/utils/index.js +++ b/src/server/function/twikoo/utils/index.js @@ -1,5 +1,16 @@ const { URL } = require('url') -const { axios, FormData, bowser, md5 } = require('./lib') +const { + getAxios, + getFormData, + getBowser, + getIpToRegion, + getMd5 +} = require('./lib') +const axios = getAxios() +const FormData = getFormData() +const bowser = getBowser() +const ipToRegion = getIpToRegion() +const md5 = getMd5() const { RES_CODE } = require('./constants') const logger = require('./logger') @@ -7,7 +18,10 @@ let ipRegionSearcher // IP 属地查询 function getIpRegionSearcher () { - return ipRegionSearcher ?? (ipRegionSearcher = require('@imaegoo/node-ip2region').create()) + if (!ipRegionSearcher) { + ipRegionSearcher = ipToRegion.create() // 初始化 IP 属地 + } + return ipRegionSearcher } const fn = { diff --git a/src/server/function/twikoo/utils/lib.js b/src/server/function/twikoo/utils/lib.js index 3f39aeb9e..13c9f5fb6 100644 --- a/src/server/function/twikoo/utils/lib.js +++ b/src/server/function/twikoo/utils/lib.js @@ -1,23 +1,62 @@ -const $ = require('cheerio') // jQuery 服务器版 -const { AkismetClient } = require('akismet-api') // 反垃圾 API -const CryptoJS = require('crypto-js') // 编解码 -const FormData = require('form-data') // 图片上传 -const axios = require('axios') // 发送 REST 请求 -const bowser = require('bowser') // UserAgent 格式化 -const marked = require('marked') // Markdown 解析 -const md5 = require('blueimp-md5') // MD5 加解密 -const pushoo = require('pushoo').default // 即时消息通知 -const xml2js = require('xml2js') // XML 解析 - module.exports = { - $, - AkismetClient, - CryptoJS, - FormData, - axios, - bowser, - marked, - md5, - pushoo, - xml2js + getCheerio () { + const $ = require('cheerio') // jQuery 服务器版 + return $ + }, + getAkismetClient () { + const { AkismetClient } = require('akismet-api') // 反垃圾 API + return AkismetClient + }, + getCryptoJS () { + const CryptoJS = require('crypto-js') // 编解码 + return CryptoJS + }, + getFormData () { + const FormData = require('form-data') // 图片上传 + return FormData + }, + getAxios () { + const axios = require('axios') // 发送 REST 请求 + return axios + }, + getBowser () { + const bowser = require('bowser') // UserAgent 格式化 + return bowser + }, + getDomPurify () { + // 初始化反 XSS + const { JSDOM } = require('jsdom') // document.window 服务器版 + const createDOMPurify = require('dompurify') // 反 XSS + const window = new JSDOM('').window + const DOMPurify = createDOMPurify(window) + return DOMPurify + }, + getIpToRegion () { + const ipToRegion = require('@imaegoo/node-ip2region') // IP 属地查询 + return ipToRegion + }, + getMarked () { + const marked = require('marked') // Markdown 解析 + return marked + }, + getMd5 () { + const md5 = require('blueimp-md5') // MD5 加解密 + return md5 + }, + getNodemailer () { + const nodemailer = require('nodemailer') // 发送邮件 + return nodemailer + }, + getPushoo () { + const pushoo = require('pushoo').default // 即时消息通知 + return pushoo + }, + getTencentcloud () { + const tencentcloud = require('tencentcloud-sdk-nodejs') // 腾讯云 API NODEJS SDK + return tencentcloud + }, + getXml2js () { + const xml2js = require('xml2js') // XML 解析 + return xml2js + } } diff --git a/src/server/function/twikoo/utils/notify.js b/src/server/function/twikoo/utils/notify.js index d63647cd0..b835103c6 100644 --- a/src/server/function/twikoo/utils/notify.js +++ b/src/server/function/twikoo/utils/notify.js @@ -1,9 +1,12 @@ const { equalsMail, getAvatar } = require('.') const { - $, - nodemailer, - pushoo + getCheerio, + getNodemailer, + getPushoo } = require('./lib') +const $ = getCheerio() +const nodemailer = getNodemailer() +const pushoo = getPushoo() const { RES_CODE } = require('./constants') const logger = require('./logger') diff --git a/src/server/function/twikoo/utils/spam.js b/src/server/function/twikoo/utils/spam.js index cc2c70e2e..13d870595 100644 --- a/src/server/function/twikoo/utils/spam.js +++ b/src/server/function/twikoo/utils/spam.js @@ -1,16 +1,22 @@ const { - AkismetClient, - CryptoJS, + getAkismetClient, + getCryptoJS, + getTencentcloud } = require('./lib') +const AkismetClient = getAkismetClient() +const CryptoJS = getCryptoJS() + const logger = require('./logger') + let tencentcloud function getTencentCloud () { - if (tencentcloud) return tencentcloud - try { - tencentcloud = require('tencentcloud-sdk-nodejs') // 腾讯云 API NODEJS SDK - } catch (e) { - logger.log('加载 "tencentcloud-sdk-nodejs" 失败', e) + if (!tencentcloud) { + try { + tencentcloud = getTencentcloud() // 腾讯云 API NODEJS SDK + } catch (e) { + logger.warn('加载 "tencentcloud-sdk-nodejs" 失败', e) + } } return tencentcloud } @@ -25,7 +31,7 @@ const fn = { isSpam = true } else if (config.QCLOUD_SECRET_ID && config.QCLOUD_SECRET_KEY) { // 腾讯云内容安全 - const client = new getTencentCloud().tms.v20200713.Client({ + const client = new (getTencentCloud().tms.v20200713.Client)({ credential: { secretId: config.QCLOUD_SECRET_ID, secretKey: config.QCLOUD_SECRET_KEY }, region: 'ap-shanghai', profile: { httpProfile: { endpoint: 'tms.tencentcloudapi.com' } } diff --git a/src/server/self-hosted/index.js b/src/server/self-hosted/index.js index 1d6bcdeec..a7df61938 100644 --- a/src/server/self-hosted/index.js +++ b/src/server/self-hosted/index.js @@ -12,9 +12,10 @@ const getUserIP = require('get-user-ip') const Lfsa = require('lokijs/src/loki-fs-structured-adapter') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { - $, - md5, - xml2js + getCheerio, + getDomPurify, + getMd5, + getXml2js } = require('twikoo-func/utils/lib') const { getFuncVersion, @@ -48,9 +49,11 @@ const { postCheckSpam } = require('twikoo-func/utils/spam') const { sendNotice, emailTest } = require('twikoo-func/utils/notify') const { uploadImage } = require('twikoo-func/utils/image') const logger = require('twikoo-func/utils/logger') -const { getDomPurify } = require('twikoo-func/utils/dom') +const $ = getCheerio() const DOMPurify = getDomPurify() +const md5 = getMd5() +const xml2js = getXml2js() // 常量 / constants const { RES_CODE, MAX_REQUEST_TIMES } = require('twikoo-func/utils/constants') diff --git a/src/server/self-hosted/mongo.js b/src/server/self-hosted/mongo.js index 3bf00b574..62c8b4626 100644 --- a/src/server/self-hosted/mongo.js +++ b/src/server/self-hosted/mongo.js @@ -10,10 +10,10 @@ const getUserIP = require('get-user-ip') const { URL } = require('url') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { - $, + getCheerio, getDomPurify, - md5, - xml2js + getMd5, + getXml2js } = require('twikoo-func/utils/lib') const { getFuncVersion, @@ -48,7 +48,10 @@ const { sendNotice, emailTest } = require('twikoo-func/utils/notify') const { uploadImage } = require('twikoo-func/utils/image') const logger = require('twikoo-func/utils/logger') +const $ = getCheerio() const DOMPurify = getDomPurify() +const md5 = getMd5() +const xml2js = getXml2js() // 常量 / constants const { RES_CODE, MAX_REQUEST_TIMES } = require('twikoo-func/utils/constants') diff --git a/src/server/vercel/api/index.js b/src/server/vercel/api/index.js index 68e30a4ef..a7c38c069 100644 --- a/src/server/vercel/api/index.js +++ b/src/server/vercel/api/index.js @@ -10,10 +10,11 @@ const getUserIP = require('get-user-ip') const { URL } = require('url') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { - $, - axios, - md5, - xml2js + getCheerio, + getAxios, + getDomPurify, + getMd5, + getXml2js } = require('twikoo-func/utils/lib') const { getFuncVersion, @@ -47,9 +48,12 @@ const { postCheckSpam } = require('twikoo-func/utils/spam') const { sendNotice, emailTest } = require('twikoo-func/utils/notify') const { uploadImage } = require('twikoo-func/utils/image') const logger = require('twikoo-func/utils/logger') -const { getDomPurify } = require('twikoo-func/utils/dom') +const $ = getCheerio() +const axios = getAxios() const DOMPurify = getDomPurify() +const md5 = getMd5() +const xml2js = getXml2js() // 常量 / constants const { RES_CODE, MAX_REQUEST_TIMES } = require('twikoo-func/utils/constants')