twikoo-func 1.7.0 → 1.7.1

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.
Files changed (3) hide show
  1. package/index.js +31 -2
  2. package/package.json +1 -1
  3. package/utils/index.js +55 -26
package/index.js CHANGED
@@ -26,6 +26,7 @@ const {
26
26
  isQQ,
27
27
  addQQMailSuffix,
28
28
  getQQAvatar,
29
+ getQQNick,
29
30
  getPasswordStatus,
30
31
  preCheckSpam,
31
32
  checkTurnstileCaptcha,
@@ -138,6 +139,9 @@ exports.main = async (event, context) => {
138
139
  case 'UPLOAD_IMAGE': // >= 1.5.0
139
140
  res = await uploadImage(event, config)
140
141
  break
142
+ case 'GET_QQ_NICK': // >= 1.7.0
143
+ res = await qqNickGet(event)
144
+ break
141
145
  case 'COMMENT_EXPORT_FOR_ADMIN': // >= 1.6.13
142
146
  res = await commentExportForAdmin(event)
143
147
  break
@@ -714,14 +718,15 @@ async function limitFilter () {
714
718
  }
715
719
 
716
720
  async function checkCaptcha (comment) {
717
- if (config.TURNSTILE_SITE_KEY && config.TURNSTILE_SECRET_KEY) {
721
+ const provider = config.CAPTCHA_PROVIDER
722
+ if ((!provider || provider === 'Turnstile') && config.TURNSTILE_SITE_KEY && config.TURNSTILE_SECRET_KEY) {
718
723
  await checkTurnstileCaptcha({
719
724
  ip: auth.getClientIP(),
720
725
  turnstileToken: comment.turnstileToken,
721
726
  turnstileTokenSecretKey: config.TURNSTILE_SECRET_KEY
722
727
  })
723
728
  }
724
- if (config.GEETEST_CAPTCHA_ID && config.GEETEST_CAPTCHA_KEY) {
729
+ if ((!provider || provider === 'Geetest') && config.GEETEST_CAPTCHA_ID && config.GEETEST_CAPTCHA_KEY) {
725
730
  await checkGeeTestCaptcha({
726
731
  geeTestCaptchaId: config.GEETEST_CAPTCHA_ID,
727
732
  geeTestCaptchaKey: config.GEETEST_CAPTCHA_KEY,
@@ -730,6 +735,15 @@ async function checkCaptcha (comment) {
730
735
  geeTestPassToken: comment.geeTestPassToken,
731
736
  geeTestGenTime: comment.geeTestGenTime
732
737
  })
738
+ } else if (config.TURNSTILE_SITE_KEY) {
739
+ if (!config.TURNSTILE_SECRET_KEY) {
740
+ throw new Error('Turnstile 验证码配置不完整,缺少 TURNSTILE_SECRET_KEY')
741
+ }
742
+ await checkTurnstileCaptcha({
743
+ ip: auth.getClientIP(),
744
+ turnstileToken: comment.turnstileToken,
745
+ turnstileTokenSecretKey: config.TURNSTILE_SECRET_KEY
746
+ })
733
747
  }
734
748
  }
735
749
 
@@ -879,6 +893,21 @@ async function getRecentComments (event) {
879
893
  return res
880
894
  }
881
895
 
896
+ // 获取 QQ 昵称
897
+ async function qqNickGet (event) {
898
+ const res = {}
899
+ try {
900
+ validate(event, ['qq'])
901
+ const nick = await getQQNick(event.qq, config.QQ_API_KEY)
902
+ res.code = RES_CODE.SUCCESS
903
+ res.nick = nick
904
+ } catch (e) {
905
+ res.code = RES_CODE.FAIL
906
+ res.message = e.message
907
+ }
908
+ return res
909
+ }
910
+
882
911
  // 修改配置
883
912
  async function setConfig (event) {
884
913
  const isAdminUser = await isAdmin()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twikoo-func",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "A simple comment system.",
5
5
  "author": "imaegoo <hello@imaegoo.com> (https://github.com/imaegoo)",
6
6
  "license": "MIT",
package/utils/index.js CHANGED
@@ -249,6 +249,23 @@ const fn = {
249
249
  logger.warn('获取 QQ 头像失败:', e)
250
250
  }
251
251
  },
252
+ async getQQNick (qq, qqApiKey) {
253
+ try {
254
+ const qqNum = qq.replace(/@qq.com/ig, '')
255
+ const headers = {}
256
+ if (qqApiKey) {
257
+ headers.Authorization = `Bearer ${qqApiKey}`
258
+ }
259
+ const result = await axios.get(`https://v1.nsuuu.com/api/qqname?qq=${qqNum}`, { headers })
260
+ if (result.data?.code === 200 && result.data?.data?.nick) {
261
+ return result.data.data.nick
262
+ }
263
+ return null
264
+ } catch (e) {
265
+ logger.warn('获取 QQ 昵称失败:', e)
266
+ return null
267
+ }
268
+ },
252
269
  // 判断是否存在管理员密码
253
270
  async getPasswordStatus (config, version) {
254
271
  return {
@@ -338,34 +355,46 @@ const fn = {
338
355
  }
339
356
  },
340
357
  async getConfig ({ config, VERSION, isAdmin }) {
358
+ // 构建对外配置,避免在启用某一验证码供应商时泄露另一个供应商的 key
359
+ const baseConfig = {
360
+ VERSION,
361
+ IS_ADMIN: isAdmin,
362
+ SITE_NAME: config.SITE_NAME,
363
+ SITE_URL: config.SITE_URL,
364
+ MASTER_TAG: config.MASTER_TAG,
365
+ COMMENT_BG_IMG: config.COMMENT_BG_IMG,
366
+ GRAVATAR_CDN: config.GRAVATAR_CDN,
367
+ DEFAULT_GRAVATAR: config.DEFAULT_GRAVATAR,
368
+ SHOW_IMAGE: config.SHOW_IMAGE || 'true',
369
+ IMAGE_CDN: config.IMAGE_CDN,
370
+ LIGHTBOX: config.LIGHTBOX || 'false',
371
+ SHOW_EMOTION: config.SHOW_EMOTION || 'true',
372
+ EMOTION_CDN: config.EMOTION_CDN,
373
+ COMMENT_PLACEHOLDER: config.COMMENT_PLACEHOLDER,
374
+ DISPLAYED_FIELDS: config.DISPLAYED_FIELDS,
375
+ REQUIRED_FIELDS: config.REQUIRED_FIELDS,
376
+ HIDE_ADMIN_CRYPT: config.HIDE_ADMIN_CRYPT,
377
+ HIGHLIGHT: config.HIGHLIGHT || 'true',
378
+ HIGHLIGHT_THEME: config.HIGHLIGHT_THEME,
379
+ HIGHLIGHT_PLUGIN: config.HIGHLIGHT_PLUGIN,
380
+ LIMIT_LENGTH: config.LIMIT_LENGTH,
381
+ CAPTCHA_PROVIDER: config.CAPTCHA_PROVIDER,
382
+ QQ_API_KEY: config.QQ_API_KEY
383
+ }
384
+
385
+ // 仅在明确指定使用 Turnstile 时下发 Turnstile 的 site key
386
+ if (config.CAPTCHA_PROVIDER === 'Turnstile') {
387
+ baseConfig.TURNSTILE_SITE_KEY = config.TURNSTILE_SITE_KEY
388
+ }
389
+
390
+ // 仅在明确指定使用 Geetest 时下发 Geetest 的 id
391
+ if (config.CAPTCHA_PROVIDER === 'Geetest') {
392
+ baseConfig.GEETEST_CAPTCHA_ID = config.GEETEST_CAPTCHA_ID
393
+ }
394
+
341
395
  return {
342
396
  code: RES_CODE.SUCCESS,
343
- config: {
344
- VERSION,
345
- IS_ADMIN: isAdmin,
346
- SITE_NAME: config.SITE_NAME,
347
- SITE_URL: config.SITE_URL,
348
- MASTER_TAG: config.MASTER_TAG,
349
- COMMENT_BG_IMG: config.COMMENT_BG_IMG,
350
- GRAVATAR_CDN: config.GRAVATAR_CDN,
351
- DEFAULT_GRAVATAR: config.DEFAULT_GRAVATAR,
352
- SHOW_IMAGE: config.SHOW_IMAGE || 'true',
353
- IMAGE_CDN: config.IMAGE_CDN,
354
- LIGHTBOX: config.LIGHTBOX || 'false',
355
- SHOW_EMOTION: config.SHOW_EMOTION || 'true',
356
- EMOTION_CDN: config.EMOTION_CDN,
357
- COMMENT_PLACEHOLDER: config.COMMENT_PLACEHOLDER,
358
- DISPLAYED_FIELDS: config.DISPLAYED_FIELDS,
359
- REQUIRED_FIELDS: config.REQUIRED_FIELDS,
360
- HIDE_ADMIN_CRYPT: config.HIDE_ADMIN_CRYPT,
361
- HIGHLIGHT: config.HIGHLIGHT || 'true',
362
- HIGHLIGHT_THEME: config.HIGHLIGHT_THEME,
363
- HIGHLIGHT_PLUGIN: config.HIGHLIGHT_PLUGIN,
364
- LIMIT_LENGTH: config.LIMIT_LENGTH,
365
- TURNSTILE_SITE_KEY: config.TURNSTILE_SITE_KEY,
366
- GEETEST_CAPTCHA_ID: config.GEETEST_CAPTCHA_ID,
367
- QQ_API_KEY: config.QQ_API_KEY
368
- }
397
+ config: baseConfig
369
398
  }
370
399
  },
371
400
  async getConfigForAdmin ({ config, isAdmin }) {