From fe59c26151eb44388f07fc24db17db442d841a8b Mon Sep 17 00:00:00 2001 From: Tao Xin Date: Tue, 14 May 2024 02:17:33 -0700 Subject: [PATCH] =?UTF-8?q?=E4=BD=BFtwikoo=E6=94=AF=E6=8C=81Cloudflare=20w?= =?UTF-8?q?orker=E7=9A=84=E5=85=BC=E5=AE=B9=E6=80=A7=E6=94=B9=E5=8A=A8=20(?= =?UTF-8?q?#695)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Patch to allow Cloudflare workers to read environment variables * Move getDomPurify out of lib.js * Remove the env-var workaround that doesn't work * Complete all changes for Cloudflare compatibility * refactor: only require lib when needed 仅在需要时导入第三方依赖,避免某一个依赖出现兼容性问题而无法导入其他依赖。 --------- Co-authored-by: Tao Xin Co-authored-by: iMaeGoo --- .eslintignore | 3 +- src/server/function/twikoo/index.js | 9 +- src/server/function/twikoo/utils/image.js | 4 +- src/server/function/twikoo/utils/import.js | 4 +- src/server/function/twikoo/utils/index.js | 26 +++++- src/server/function/twikoo/utils/lib.js | 97 +++++++++++++--------- src/server/function/twikoo/utils/notify.js | 9 +- src/server/function/twikoo/utils/spam.js | 24 +++++- src/server/self-hosted/index.js | 9 +- src/server/self-hosted/mongo.js | 9 +- src/server/vercel/api/index.js | 12 ++- 11 files changed, 143 insertions(+), 63 deletions(-) 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 2d72b0251..d064bd734 100644 --- a/src/server/function/twikoo/index.js +++ b/src/server/function/twikoo/index.js @@ -7,10 +7,10 @@ const { version: VERSION } = require('./package.json') const tcb = require('@cloudbase/node-sdk') // 云开发 SDK const { - $, + getCheerio, getDomPurify, - md5, - xml2js + getMd5, + getXml2js } = require('./utils/lib') const { getFuncVersion, @@ -50,7 +50,10 @@ 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/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 b827b3e07..ecf9d1747 100644 --- a/src/server/function/twikoo/utils/import.js +++ b/src/server/function/twikoo/utils/import.js @@ -1,5 +1,7 @@ const { getRelativeUrl, normalizeMail } = require('.') -const { marked, getDomPurify, md5 } = require('./lib') +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 3fbf044a1..580dcb1d1 100644 --- a/src/server/function/twikoo/utils/index.js +++ b/src/server/function/twikoo/utils/index.js @@ -1,9 +1,29 @@ const { URL } = require('url') -const { axios, FormData, bowser, ipToRegion, 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 ipRegionSearcher = ipToRegion.create() // 初始化 IP 属地 const logger = require('./logger') +let ipRegionSearcher + +// IP 属地查询 +function getIpRegionSearcher () { + if (!ipRegionSearcher) { + ipRegionSearcher = ipToRegion.create() // 初始化 IP 属地 + } + return ipRegionSearcher +} + const fn = { // 获取 Twikoo 云函数版本 getFuncVersion (VERSION) { @@ -119,7 +139,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 861995820..13c9f5fb6 100644 --- a/src/server/function/twikoo/utils/lib.js +++ b/src/server/function/twikoo/utils/lib.js @@ -1,39 +1,62 @@ -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 加解密 -const nodemailer = require('nodemailer') // 发送邮件 -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, - CryptoJS, - FormData, - axios, - bowser, - getDomPurify, - ipToRegion, - marked, - md5, - nodemailer, - pushoo, - tencentcloud, - 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 95c76e64a..13d870595 100644 --- a/src/server/function/twikoo/utils/spam.js +++ b/src/server/function/twikoo/utils/spam.js @@ -1,10 +1,26 @@ const { - AkismetClient, - CryptoJS, - tencentcloud + getAkismetClient, + getCryptoJS, + getTencentcloud } = require('./lib') +const AkismetClient = getAkismetClient() +const CryptoJS = getCryptoJS() + const logger = require('./logger') +let tencentcloud + +function getTencentCloud () { + if (!tencentcloud) { + try { + tencentcloud = getTencentcloud() // 腾讯云 API NODEJS SDK + } catch (e) { + logger.warn('加载 "tencentcloud-sdk-nodejs" 失败', e) + } + } + return tencentcloud +} + const fn = { // 后垃圾评论检测 async postCheckSpam (comment, config) { @@ -15,7 +31,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' } } diff --git a/src/server/self-hosted/index.js b/src/server/self-hosted/index.js index d1fb7c94a..a7df61938 100644 --- a/src/server/self-hosted/index.js +++ b/src/server/self-hosted/index.js @@ -12,10 +12,10 @@ const getUserIP = require('get-user-ip') const Lfsa = require('lokijs/src/loki-fs-structured-adapter') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { - $, + getCheerio, getDomPurify, - md5, - xml2js + getMd5, + getXml2js } = require('twikoo-func/utils/lib') const { getFuncVersion, @@ -50,7 +50,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/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 e44db3b2a..a7c38c069 100644 --- a/src/server/vercel/api/index.js +++ b/src/server/vercel/api/index.js @@ -10,11 +10,11 @@ const getUserIP = require('get-user-ip') const { URL } = require('url') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { - $, - axios, + getCheerio, + getAxios, getDomPurify, - md5, - xml2js + getMd5, + getXml2js } = require('twikoo-func/utils/lib') const { getFuncVersion, @@ -49,7 +49,11 @@ 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 axios = getAxios() const DOMPurify = getDomPurify() +const md5 = getMd5() +const xml2js = getXml2js() // 常量 / constants const { RES_CODE, MAX_REQUEST_TIMES } = require('twikoo-func/utils/constants')