@waline/vercel 1.28.2 → 1.30.0

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.
@@ -3,10 +3,7 @@ const BaseRest = require('./rest');
3
3
  module.exports = class extends BaseRest {
4
4
  constructor(ctx) {
5
5
  super(ctx);
6
- this.modelInstance = this.service(
7
- `storage/${this.config('storage')}`,
8
- 'Counter'
9
- );
6
+ this.modelInstance = this.getModel('Counter');
10
7
  }
11
8
 
12
9
  async getAction() {
@@ -68,10 +68,7 @@ async function formatCmt(
68
68
  module.exports = class extends BaseRest {
69
69
  constructor(ctx) {
70
70
  super(ctx);
71
- this.modelInstance = this.service(
72
- `storage/${this.config('storage')}`,
73
- 'Comment'
74
- );
71
+ this.modelInstance = this.getModel('Comment');
75
72
  }
76
73
 
77
74
  async getAction() {
@@ -114,10 +111,7 @@ module.exports = class extends BaseRest {
114
111
  ],
115
112
  });
116
113
 
117
- const userModel = this.service(
118
- `storage/${this.config('storage')}`,
119
- 'Users'
120
- );
114
+ const userModel = this.getModel('Users');
121
115
  const user_ids = Array.from(
122
116
  new Set(comments.map(({ user_id }) => user_id).filter((v) => v))
123
117
  );
@@ -212,10 +206,7 @@ module.exports = class extends BaseRest {
212
206
  offset: Math.max((page - 1) * pageSize, 0),
213
207
  });
214
208
 
215
- const userModel = this.service(
216
- `storage/${this.config('storage')}`,
217
- 'Users'
218
- );
209
+ const userModel = this.getModel('Users');
219
210
  const user_ids = Array.from(
220
211
  new Set(comments.map(({ user_id }) => user_id).filter((v) => v))
221
212
  );
@@ -355,10 +346,7 @@ module.exports = class extends BaseRest {
355
346
  });
356
347
  }
357
348
 
358
- const userModel = this.service(
359
- `storage/${this.config('storage')}`,
360
- 'Users'
361
- );
349
+ const userModel = this.getModel('Users');
362
350
  const user_ids = Array.from(
363
351
  new Set(comments.map(({ user_id }) => user_id).filter((v) => v))
364
352
  );
@@ -592,10 +580,7 @@ module.exports = class extends BaseRest {
592
580
  parentComment = await this.modelInstance.select({ objectId: pid });
593
581
  parentComment = parentComment[0];
594
582
  if (parentComment.user_id) {
595
- parentUser = await this.service(
596
- `storage/${this.config('storage')}`,
597
- 'Users'
598
- ).select({
583
+ parentUser = await this.getModel('Users').select({
599
584
  objectId: parentComment.user_id,
600
585
  });
601
586
  parentUser = parentUser[0];
@@ -677,10 +662,7 @@ module.exports = class extends BaseRest {
677
662
  let cmtUser;
678
663
 
679
664
  if (!think.isEmpty(newData) && newData[0].user_id) {
680
- cmtUser = await this.service(
681
- `storage/${this.config('storage')}`,
682
- 'Users'
683
- ).select({
665
+ cmtUser = await this.getModel('Users').select({
684
666
  objectId: newData[0].user_id,
685
667
  });
686
668
  cmtUser = cmtUser[0];
@@ -706,10 +688,7 @@ module.exports = class extends BaseRest {
706
688
  let pUser;
707
689
 
708
690
  if (pComment.user_id) {
709
- pUser = await this.service(
710
- `storage/${this.config('storage')}`,
711
- 'Users'
712
- ).select({
691
+ pUser = await this.getModel('Users').select({
713
692
  objectId: pComment.user_id,
714
693
  });
715
694
  pUser = pUser[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/vercel",
3
- "version": "1.28.2",
3
+ "version": "1.30.0",
4
4
  "description": "vercel server for waline comment system",
5
5
  "keywords": [
6
6
  "waline",
@@ -15,40 +15,40 @@
15
15
  "license": "MIT",
16
16
  "author": "lizheming <i@imnerd.org>",
17
17
  "dependencies": {
18
- "@cloudbase/node-sdk": "2.9.1",
19
- "@koa/cors": "4.0.0",
20
- "akismet": "2.0.7",
21
- "deta": "1.1.0",
22
- "dompurify": "3.0.1",
23
- "dy-node-ip2region": "1.0.1",
24
- "fast-csv": "4.3.6",
25
- "form-data": "4.0.0",
26
- "jsdom": "21.1.1",
27
- "jsonwebtoken": "9.0.0",
28
- "katex": "0.16.4",
29
- "leancloud-storage": "4.14.0",
30
- "markdown-it": "13.0.1",
31
- "markdown-it-emoji": "2.0.2",
32
- "markdown-it-sub": "1.0.0",
33
- "markdown-it-sup": "1.0.0",
34
- "mathjax-full": "3.2.2",
35
- "node-fetch": "2.6.9",
36
- "nodemailer": "6.9.1",
37
- "nunjucks": "3.2.3",
38
- "phpass": "0.1.1",
39
- "prismjs": "1.29.0",
40
- "speakeasy": "2.0.0",
41
- "think-helper": "1.1.4",
42
- "think-logger3": "1.3.1",
43
- "think-model": "1.5.4",
44
- "think-model-mysql": "1.1.7",
18
+ "@cloudbase/node-sdk": "^2.9.1",
19
+ "@koa/cors": "^4.0.0",
20
+ "akismet": "^2.0.7",
21
+ "deta": "^1.1.0",
22
+ "dompurify": "^3.0.1",
23
+ "dy-node-ip2region": "^1.0.1",
24
+ "fast-csv": "^4.3.6",
25
+ "form-data": "^4.0.0",
26
+ "jsdom": "^21.1.1",
27
+ "jsonwebtoken": "^9.0.0",
28
+ "katex": "^0.16.4",
29
+ "leancloud-storage": "^4.14.0",
30
+ "markdown-it": "^13.0.1",
31
+ "markdown-it-emoji": "^2.0.2",
32
+ "markdown-it-sub": "^1.0.0",
33
+ "markdown-it-sup": "^1.0.0",
34
+ "mathjax-full": "^3.2.2",
35
+ "node-fetch": "^2.6.9",
36
+ "nodemailer": "^6.9.1",
37
+ "nunjucks": "^3.2.3",
38
+ "phpass": "^0.1.1",
39
+ "prismjs": "^1.29.0",
40
+ "speakeasy": "^2.0.0",
41
+ "think-helper": "^1.1.4",
42
+ "think-logger3": "^1.3.1",
43
+ "think-model": "^1.5.4",
44
+ "think-model-mysql": "^1.1.7",
45
45
  "think-model-mysql2": "^2.0.0",
46
46
  "think-model-postgresql": "1.1.7",
47
- "think-model-sqlite": "1.3.1",
48
- "think-mongo": "2.2.1",
49
- "think-router-rest": "1.0.5",
50
- "thinkjs": "3.2.14",
51
- "ua-parser-js": "1.0.34"
47
+ "think-model-sqlite": "^1.3.1",
48
+ "think-mongo": "^2.2.1",
49
+ "think-router-rest": "^1.0.5",
50
+ "thinkjs": "^3.2.14",
51
+ "ua-parser-js": "^1.0.35"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=14"
@@ -3,10 +3,7 @@ const BaseRest = require('./rest');
3
3
  module.exports = class extends BaseRest {
4
4
  constructor(ctx) {
5
5
  super(ctx);
6
- this.modelInstance = this.service(
7
- `storage/${this.config('storage')}`,
8
- 'Counter'
9
- );
6
+ this.modelInstance = this.getModel('Counter');
10
7
  }
11
8
 
12
9
  async getAction() {
@@ -27,7 +24,9 @@ module.exports = class extends BaseRest {
27
24
  return o;
28
25
  }, {});
29
26
 
30
- return this.jsonOrSuccess((type.length === 1 && deprecated) ? data[type[0]] : data);
27
+ return this.jsonOrSuccess(
28
+ type.length === 1 && deprecated ? data[type[0]] : data
29
+ );
31
30
  }
32
31
 
33
32
  const respObj = resp.reduce((o, n) => {
@@ -61,7 +61,7 @@ async function formatCmt(
61
61
  if (typeof comment.sticky === 'string') {
62
62
  comment.sticky = Boolean(Number(comment.sticky));
63
63
  }
64
-
64
+
65
65
  comment.time = new Date(comment.insertedAt).getTime();
66
66
  if (!deprecated) {
67
67
  delete comment.insertedAt;
@@ -75,10 +75,7 @@ async function formatCmt(
75
75
  module.exports = class extends BaseRest {
76
76
  constructor(ctx) {
77
77
  super(ctx);
78
- this.modelInstance = this.service(
79
- `storage/${this.config('storage')}`,
80
- 'Comment'
81
- );
78
+ this.modelInstance = this.getModel('Comment');
82
79
  }
83
80
 
84
81
  async getAction() {
@@ -121,10 +118,7 @@ module.exports = class extends BaseRest {
121
118
  ],
122
119
  });
123
120
 
124
- const userModel = this.service(
125
- `storage/${this.config('storage')}`,
126
- 'Users'
127
- );
121
+ const userModel = this.getModel('Users');
128
122
  const user_ids = Array.from(
129
123
  new Set(comments.map(({ user_id }) => user_id).filter((v) => v))
130
124
  );
@@ -150,7 +144,12 @@ module.exports = class extends BaseRest {
150
144
  return this.jsonOrSuccess(
151
145
  await Promise.all(
152
146
  comments.map((cmt) =>
153
- formatCmt(cmt, users, { ...this.config(), deprecated: this.ctx.state.deprecated }, userInfo)
147
+ formatCmt(
148
+ cmt,
149
+ users,
150
+ { ...this.config(), deprecated: this.ctx.state.deprecated },
151
+ userInfo
152
+ )
154
153
  )
155
154
  )
156
155
  );
@@ -222,10 +221,7 @@ module.exports = class extends BaseRest {
222
221
  offset: Math.max((page - 1) * pageSize, 0),
223
222
  });
224
223
 
225
- const userModel = this.service(
226
- `storage/${this.config('storage')}`,
227
- 'Users'
228
- );
224
+ const userModel = this.getModel('Users');
229
225
  const user_ids = Array.from(
230
226
  new Set(comments.map(({ user_id }) => user_id).filter((v) => v))
231
227
  );
@@ -256,7 +252,12 @@ module.exports = class extends BaseRest {
256
252
  waitingCount,
257
253
  data: await Promise.all(
258
254
  comments.map((cmt) =>
259
- formatCmt(cmt, users, { ...this.config(), deprecated: this.ctx.state.deprecated }, userInfo)
255
+ formatCmt(
256
+ cmt,
257
+ users,
258
+ { ...this.config(), deprecated: this.ctx.state.deprecated },
259
+ userInfo
260
+ )
260
261
  )
261
262
  ),
262
263
  });
@@ -363,10 +364,7 @@ module.exports = class extends BaseRest {
363
364
  comments = [...rootComments, ...children];
364
365
  }
365
366
 
366
- const userModel = this.service(
367
- `storage/${this.config('storage')}`,
368
- 'Users'
369
- );
367
+ const userModel = this.getModel('Users');
370
368
  const user_ids = Array.from(
371
369
  new Set(comments.map(({ user_id }) => user_id).filter((v) => v))
372
370
  );
@@ -449,7 +447,7 @@ module.exports = class extends BaseRest {
449
447
  comment,
450
448
  users,
451
449
  { ...this.config(), deprecated: this.ctx.state.deprecated },
452
- userInfo,
450
+ userInfo
453
451
  );
454
452
 
455
453
  cmt.children = await Promise.all(
@@ -610,10 +608,7 @@ module.exports = class extends BaseRest {
610
608
  parentComment = await this.modelInstance.select({ objectId: pid });
611
609
  parentComment = parentComment[0];
612
610
  if (parentComment.user_id) {
613
- parentUser = await this.service(
614
- `storage/${this.config('storage')}`,
615
- 'Users'
616
- ).select({
611
+ parentUser = await this.getModel('Users').select({
617
612
  objectId: parentComment.user_id,
618
613
  });
619
614
  parentUser = parentUser[0];
@@ -656,7 +651,12 @@ module.exports = class extends BaseRest {
656
651
  think.logger.debug(`Comment post hooks postSave done!`);
657
652
 
658
653
  return this.success(
659
- await formatCmt(resp, [userInfo], { ...this.config(), deprecated: this.ctx.state.deprecated }, userInfo)
654
+ await formatCmt(
655
+ resp,
656
+ [userInfo],
657
+ { ...this.config(), deprecated: this.ctx.state.deprecated },
658
+ userInfo
659
+ )
660
660
  );
661
661
  }
662
662
 
@@ -695,10 +695,7 @@ module.exports = class extends BaseRest {
695
695
  let cmtUser;
696
696
 
697
697
  if (!think.isEmpty(newData) && newData[0].user_id) {
698
- cmtUser = await this.service(
699
- `storage/${this.config('storage')}`,
700
- 'Users'
701
- ).select({
698
+ cmtUser = await this.getModel('Users').select({
702
699
  objectId: newData[0].user_id,
703
700
  });
704
701
  cmtUser = cmtUser[0];
@@ -724,10 +721,7 @@ module.exports = class extends BaseRest {
724
721
  let pUser;
725
722
 
726
723
  if (pComment.user_id) {
727
- pUser = await this.service(
728
- `storage/${this.config('storage')}`,
729
- 'Users'
730
- ).select({
724
+ pUser = await this.getModel('Users').select({
731
725
  objectId: pComment.user_id,
732
726
  });
733
727
  pUser = pUser[0];
@@ -16,8 +16,7 @@ module.exports = class extends BaseRest {
16
16
 
17
17
  for (let i = 0; i < exportData.tables.length; i++) {
18
18
  const tableName = exportData.tables[i];
19
- const storage = this.config('storage');
20
- const model = this.service(`storage/${storage}`, tableName);
19
+ const model = this.getModel(tableName);
21
20
 
22
21
  const data = await model.select({});
23
22
 
@@ -31,7 +30,7 @@ module.exports = class extends BaseRest {
31
30
  const { table } = this.get();
32
31
  const item = this.post();
33
32
  const storage = this.config('storage');
34
- const model = this.service(`storage/${storage}`, table);
33
+ const model = this.getModel(table);
35
34
 
36
35
  if (storage === 'leancloud' || storage === 'mysql') {
37
36
  item.insertedAt && (item.insertedAt = new Date(item.insertedAt));
@@ -48,8 +47,7 @@ module.exports = class extends BaseRest {
48
47
  async putAction() {
49
48
  const { table, objectId } = this.get();
50
49
  const data = this.post();
51
- const storage = this.config('storage');
52
- const model = this.service(`storage/${storage}`, table);
50
+ const model = this.getModel(table);
53
51
 
54
52
  delete data.objectId;
55
53
  delete data.createdAt;
@@ -61,8 +59,7 @@ module.exports = class extends BaseRest {
61
59
 
62
60
  async deleteAction() {
63
61
  const { table } = this.get();
64
- const storage = this.config('storage');
65
- const model = this.service(`storage/${storage}`, table);
62
+ const model = this.getModel(table);
66
63
 
67
64
  await model.delete({});
68
65
 
@@ -28,6 +28,7 @@ module.exports = class extends think.Controller {
28
28
  lang: params.get('lng'),
29
29
  serverURL: location.protocol + '//' + location.host + location.pathname.replace(/\\/+$/, ''),
30
30
  recaptchaV3Key: '${process.env.RECAPTCHA_V3_KEY || ''}',
31
+ turnstileKey: '${process.env.TURNSTILE_KEY || ''}',
31
32
  });
32
33
  </script>
33
34
  </body>
@@ -1,14 +1,10 @@
1
1
  const jwt = require('jsonwebtoken');
2
2
  const fetch = require('node-fetch');
3
- const { PasswordHash } = require('phpass');
4
3
 
5
4
  module.exports = class extends think.Controller {
6
5
  constructor(ctx) {
7
6
  super(ctx);
8
- this.modelInstance = this.service(
9
- `storage/${this.config('storage')}`,
10
- 'Users'
11
- );
7
+ this.modelInstance = this.getModel('Users');
12
8
  }
13
9
 
14
10
  async indexAction() {
@@ -109,7 +105,7 @@ module.exports = class extends think.Controller {
109
105
  url: user.url,
110
106
  avatar: user.avatar,
111
107
  [type]: user.id,
112
- password: new PasswordHash().hashPassword(Math.random()),
108
+ password: this.hashPassword(Math.random()),
113
109
  type: think.isEmpty(count) ? 'administrator' : 'guest',
114
110
  };
115
111
 
@@ -8,10 +8,7 @@ module.exports = class extends BaseRest {
8
8
  const { email } = this.get();
9
9
 
10
10
  if (think.isEmpty(userInfo) && email) {
11
- const userModel = this.service(
12
- `storage/${this.config('storage')}`,
13
- 'Users'
14
- );
11
+ const userModel = this.getModel('Users');
15
12
 
16
13
  const user = await userModel.select(
17
14
  { email },
@@ -54,10 +51,7 @@ module.exports = class extends BaseRest {
54
51
  return this.fail(this.locale('TWO_FACTOR_AUTH_ERROR_DETAIL'));
55
52
  }
56
53
 
57
- const userModel = this.service(
58
- `storage/${this.config('storage')}`,
59
- 'Users'
60
- );
54
+ const userModel = this.getModel('Users');
61
55
  const { objectId } = this.ctx.state.userInfo;
62
56
 
63
57
  await userModel.update({ ['2fa']: data.secret }, { objectId });
@@ -1,5 +1,4 @@
1
1
  const jwt = require('jsonwebtoken');
2
- const { PasswordHash } = require('phpass');
3
2
  const speakeasy = require('speakeasy');
4
3
  const helper = require('think-helper');
5
4
 
@@ -8,10 +7,7 @@ const BaseRest = require('./rest');
8
7
  module.exports = class extends BaseRest {
9
8
  constructor(...args) {
10
9
  super(...args);
11
- this.modelInstance = this.service(
12
- `storage/${this.config('storage')}`,
13
- 'Users'
14
- );
10
+ this.modelInstance = this.getModel('Users');
15
11
  }
16
12
 
17
13
  getAction() {
@@ -26,10 +22,7 @@ module.exports = class extends BaseRest {
26
22
  return this.fail();
27
23
  }
28
24
 
29
- const checkPassword = new PasswordHash().checkPassword(
30
- password,
31
- user[0].password
32
- );
25
+ const checkPassword = this.checkPassword(password, user[0].password);
33
26
 
34
27
  if (!checkPassword) {
35
28
  return this.fail();
@@ -19,10 +19,7 @@ module.exports = class extends BaseRest {
19
19
  }
20
20
 
21
21
  const { email } = this.post();
22
- const userModel = this.service(
23
- `storage/${this.config('storage')}`,
24
- 'Users'
25
- );
22
+ const userModel = this.getModel('Users');
26
23
  const user = await userModel.select({ email });
27
24
 
28
25
  if (think.isEmpty(user)) {
@@ -1,14 +1,9 @@
1
- const { PasswordHash } = require('phpass');
2
-
3
1
  const BaseRest = require('./rest');
4
2
 
5
3
  module.exports = class extends BaseRest {
6
4
  constructor(...args) {
7
5
  super(...args);
8
- this.modelInstance = this.service(
9
- `storage/${this.config('storage')}`,
10
- 'Users'
11
- );
6
+ this.modelInstance = this.getModel('Users');
12
7
  }
13
8
 
14
9
  async getAction() {
@@ -81,7 +76,7 @@ module.exports = class extends BaseRest {
81
76
  ? `verify:${token}:${Date.now() + 1 * 60 * 60 * 1000}`
82
77
  : 'guest';
83
78
 
84
- data.password = new PasswordHash().hashPassword(data.password);
79
+ data.password = this.hashPassword(data.password);
85
80
  data.type = think.isEmpty(count) ? 'administrator' : normalType;
86
81
 
87
82
  if (think.isEmpty(resp)) {
@@ -157,7 +152,7 @@ module.exports = class extends BaseRest {
157
152
  }
158
153
 
159
154
  if (password) {
160
- updateData.password = new PasswordHash().hashPassword(password);
155
+ updateData.password = this.hashPassword(password);
161
156
  }
162
157
 
163
158
  if (think.isString(twoFactorAuth)) {
@@ -187,10 +182,7 @@ module.exports = class extends BaseRest {
187
182
 
188
183
  async getUsersListByCount() {
189
184
  const { pageSize } = this.get();
190
- const commentModel = this.service(
191
- `storage/${this.config('storage')}`,
192
- 'Comment'
193
- );
185
+ const commentModel = this.getModel('Comment');
194
186
  const counts = await commentModel.count(
195
187
  {
196
188
  status: ['NOT IN', ['waiting', 'spam']],
@@ -3,10 +3,7 @@ const BaseRest = require('./rest');
3
3
  module.exports = class extends BaseRest {
4
4
  constructor(...args) {
5
5
  super(...args);
6
- this.modelInstance = this.service(
7
- `storage/${this.config('storage')}`,
8
- 'Users'
9
- );
6
+ this.modelInstance = this.getModel('Users');
10
7
  }
11
8
 
12
9
  async getAction() {
@@ -1,4 +1,5 @@
1
1
  const nunjucks = require('nunjucks');
2
+ const { PasswordHash } = require('phpass');
2
3
 
3
4
  const locales = require('../locales');
4
5
 
@@ -26,4 +27,29 @@ module.exports = {
26
27
 
27
28
  return nunjucks.renderString(message, variables);
28
29
  },
30
+ getModel(modelName) {
31
+ const { storage, model } = this.config('storage');
32
+
33
+ if (typeof model === 'function') {
34
+ const modelInstance = model(modelName, this);
35
+
36
+ if (modelInstance) {
37
+ return modelInstance;
38
+ }
39
+ }
40
+
41
+ return this.service(`storage/${storage}`, modelName);
42
+ },
43
+ hashPassword(password) {
44
+ const PwdHash = this.config('encryptPassword') || PasswordHash;
45
+ const pwdHash = new PwdHash();
46
+
47
+ return pwdHash.hashPassword(password);
48
+ },
49
+ checkPassword(password, storeHash) {
50
+ const PwdHash = this.config('encryptPassword') || PasswordHash;
51
+ const pwdHash = new PwdHash();
52
+
53
+ return pwdHash.checkPassword(password, storeHash);
54
+ },
29
55
  };
package/src/logic/base.js CHANGED
@@ -8,10 +8,7 @@ const helper = require('think-helper');
8
8
  module.exports = class extends think.Logic {
9
9
  constructor(...args) {
10
10
  super(...args);
11
- this.modelInstance = this.service(
12
- `storage/${this.config('storage')}`,
13
- 'Users'
14
- );
11
+ this.modelInstance = this.getModel('Users');
15
12
  this.resource = this.getResource();
16
13
  this.id = this.getId();
17
14
  }
@@ -135,30 +132,64 @@ module.exports = class extends think.Logic {
135
132
  }
136
133
 
137
134
  async useCaptchaCheck() {
138
- const { RECAPTCHA_V3_SECRET } = process.env;
135
+ const { RECAPTCHA_V3_SECRET, TURNSTILE_SECRET } = process.env;
136
+ const { turnstile, recaptchaV3 } = this.post();
137
+
138
+ if (TURNSTILE_SECRET) {
139
+ return this.useRecaptchaOrTurnstileCheck({
140
+ secret: TURNSTILE_SECRET,
141
+ token: turnstile,
142
+ api: 'https://challenges.cloudflare.com/turnstile/v0/siteverify',
143
+ method: 'POST',
144
+ });
145
+ }
139
146
 
140
- if (!RECAPTCHA_V3_SECRET) {
147
+ if (RECAPTCHA_V3_SECRET) {
148
+ return this.useRecaptchaOrTurnstileCheck({
149
+ secret: RECAPTCHA_V3_SECRET,
150
+ token: recaptchaV3,
151
+ api: 'https://recaptcha.net/recaptcha/api/siteverify',
152
+ method: 'GET',
153
+ });
154
+ }
155
+ }
156
+
157
+ async useRecaptchaOrTurnstileCheck({ secret, token, api, method }) {
158
+ if (!secret) {
141
159
  return;
142
160
  }
143
- const { recaptchaV3 } = this.post();
144
161
 
145
- if (!recaptchaV3) {
162
+ if (!token) {
146
163
  return this.ctx.throw(403);
147
164
  }
148
165
 
149
166
  const query = qs.stringify({
150
- secret: RECAPTCHA_V3_SECRET,
151
- response: recaptchaV3,
167
+ secret,
168
+ response: token,
152
169
  remoteip: this.ctx.ip,
153
170
  });
154
- const recaptchaV3Result = await fetch(
155
- `https://recaptcha.net/recaptcha/api/siteverify?${query}`
156
- ).then((resp) => resp.json());
157
171
 
158
- if (!recaptchaV3Result.success) {
172
+ const requestUrl = method === 'GET' ? api + '?' + query : api;
173
+ const options =
174
+ method === 'GET'
175
+ ? {}
176
+ : {
177
+ method,
178
+ headers: {
179
+ 'content-type':
180
+ 'application/x-www-form-urlencoded; charset=UTF-8',
181
+ },
182
+ body: query,
183
+ };
184
+
185
+ const response = await fetch(requestUrl, options).then((resp) =>
186
+ resp.json()
187
+ );
188
+
189
+ if (!response.success) {
159
190
  think.logger.debug(
160
- 'RecaptchaV3 Result:',
161
- JSON.stringify(recaptchaV3Result, null, '\t')
191
+ 'RecaptchaV3 or Turnstile Result:',
192
+ JSON.stringify(response, null, '\t')
162
193
  );
163
194
 
164
195
  return this.ctx.throw(403);
@@ -262,10 +262,7 @@ module.exports = class extends Base {
262
262
  }
263
263
 
264
264
  // 3. comment author modify comment content
265
- const modelInstance = this.service(
266
- `storage/${this.config('storage')}`,
267
- 'Comment'
268
- );
265
+ const modelInstance = this.getModel('Comment');
269
266
  const commentData = await modelInstance.select({
270
267
  user_id: userInfo.objectId,
271
268
  objectId: this.id,
@@ -299,10 +296,7 @@ module.exports = class extends Base {
299
296
  return;
300
297
  }
301
298
 
302
- const modelInstance = this.service(
303
- `storage/${this.config('storage')}`,
304
- 'Comment'
305
- );
299
+ const modelInstance = this.getModel('Comment');
306
300
  const commentData = await modelInstance.select({
307
301
  user_id: userInfo.objectId,
308
302
  objectId: this.id,
@@ -13,6 +13,7 @@ module.exports = function () {
13
13
  window.SITE_URL = ${JSON.stringify(process.env.SITE_URL)};
14
14
  window.SITE_NAME = ${JSON.stringify(process.env.SITE_NAME)};
15
15
  window.recaptchaV3Key = ${JSON.stringify(process.env.RECAPTCHA_V3_KEY)};
16
+ window.turnstileKey = ${JSON.stringify(process.env.TURNSTILE_KEY)};
16
17
  window.serverURL = '${ctx.serverURL}/api/';
17
18
  </script>
18
19
  <script src="${