@waline/vercel 1.36.4 → 1.37.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.
- package/__tests__/xss.spec.js +8 -19
- package/development.js +1 -0
- package/index.js +4 -3
- package/package.json +17 -18
- package/src/config/adapter.js +9 -11
- package/src/config/config.js +4 -12
- package/src/config/extend.js +0 -6
- package/src/config/middleware.js +2 -5
- package/src/controller/article.js +5 -12
- package/src/controller/comment.js +33 -53
- package/src/controller/db.js +3 -9
- package/src/controller/oauth.js +8 -8
- package/src/controller/rest.js +1 -1
- package/src/controller/user/password.js +3 -12
- package/src/controller/user.js +18 -45
- package/src/controller/verification.js +3 -2
- package/src/extend/think.js +33 -23
- package/src/logic/base.js +31 -47
- package/src/logic/comment.js +7 -4
- package/src/logic/db.js +1 -1
- package/src/logic/token.js +2 -2
- package/src/middleware/dashboard.js +1 -0
- package/src/middleware/plugin.js +1 -1
- package/src/service/akismet.js +10 -3
- package/src/service/avatar.js +2 -4
- package/src/service/markdown/highlight.js +1 -1
- package/src/service/markdown/mathCommon.js +2 -8
- package/src/service/markdown/mathjax.js +1 -2
- package/src/service/markdown/utils.js +5 -5
- package/src/service/markdown/xss.js +5 -10
- package/src/service/notify.js +111 -135
- package/src/service/storage/base.js +2 -7
- package/src/service/storage/cloudbase.js +9 -7
- package/src/service/storage/github.js +39 -42
- package/src/service/storage/leancloud.js +41 -54
- package/src/service/storage/mongodb.js +11 -8
- package/src/service/storage/mysql.js +7 -13
- package/src/service/storage/postgresql.js +7 -11
- package/src/service/storage/deta.js +0 -310
|
@@ -60,8 +60,7 @@ const mathjaxPlugin = (md) => {
|
|
|
60
60
|
|
|
61
61
|
md.renderer.rules.inlineTeX = (tokens, idx) => inline(tokens[idx].content);
|
|
62
62
|
|
|
63
|
-
md.renderer.rules.blockTeX = (tokens, idx) =>
|
|
64
|
-
`${block(tokens[idx].content)}\n`;
|
|
63
|
+
md.renderer.rules.blockTeX = (tokens, idx) => `${block(tokens[idx].content)}\n`;
|
|
65
64
|
};
|
|
66
65
|
|
|
67
66
|
module.exports = {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const escapeHtml = (unsafeHTML) =>
|
|
2
2
|
unsafeHTML
|
|
3
|
-
.
|
|
4
|
-
.
|
|
5
|
-
.
|
|
6
|
-
.
|
|
7
|
-
.
|
|
3
|
+
.replaceAll('&', '&')
|
|
4
|
+
.replaceAll('<', '<')
|
|
5
|
+
.replaceAll('>', '>')
|
|
6
|
+
.replaceAll('"', '"')
|
|
7
|
+
.replaceAll("'", ''');
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
escapeHtml,
|
|
@@ -28,16 +28,11 @@ DOMPurify.addHook('afterSanitizeAttributes', (node) => {
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
const sanitize = (content) =>
|
|
31
|
-
DOMPurify.sanitize(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
FORBID_ATTR: ['autoplay', 'style'],
|
|
37
|
-
},
|
|
38
|
-
think.config('domPurify') || {},
|
|
39
|
-
),
|
|
40
|
-
);
|
|
31
|
+
DOMPurify.sanitize(content, {
|
|
32
|
+
FORBID_TAGS: ['form', 'input', 'style'],
|
|
33
|
+
FORBID_ATTR: ['autoplay', 'style'],
|
|
34
|
+
...think.config('domPurify'),
|
|
35
|
+
});
|
|
41
36
|
|
|
42
37
|
module.exports = {
|
|
43
38
|
sanitize,
|
package/src/service/notify.js
CHANGED
|
@@ -4,19 +4,12 @@ const FormData = require('form-data');
|
|
|
4
4
|
const nodemailer = require('nodemailer');
|
|
5
5
|
const nunjucks = require('nunjucks');
|
|
6
6
|
|
|
7
|
-
module.exports = class extends think.Service {
|
|
7
|
+
module.exports = class NotifyService extends think.Service {
|
|
8
8
|
constructor(controller) {
|
|
9
9
|
super(controller);
|
|
10
10
|
|
|
11
11
|
this.controller = controller;
|
|
12
|
-
const {
|
|
13
|
-
SMTP_USER,
|
|
14
|
-
SMTP_PASS,
|
|
15
|
-
SMTP_HOST,
|
|
16
|
-
SMTP_PORT,
|
|
17
|
-
SMTP_SECURE,
|
|
18
|
-
SMTP_SERVICE,
|
|
19
|
-
} = process.env;
|
|
12
|
+
const { SMTP_USER, SMTP_PASS, SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_SERVICE } = process.env;
|
|
20
13
|
|
|
21
14
|
if (SMTP_HOST || SMTP_SERVICE) {
|
|
22
15
|
const config = {
|
|
@@ -27,7 +20,7 @@ module.exports = class extends think.Service {
|
|
|
27
20
|
config.service = SMTP_SERVICE;
|
|
28
21
|
} else {
|
|
29
22
|
config.host = SMTP_HOST;
|
|
30
|
-
config.port = parseInt(SMTP_PORT);
|
|
23
|
+
config.port = Number.parseInt(SMTP_PORT, 10);
|
|
31
24
|
config.secure = SMTP_SECURE && SMTP_SECURE !== 'false';
|
|
32
25
|
}
|
|
33
26
|
this.transporter = nodemailer.createTransport(config);
|
|
@@ -35,7 +28,9 @@ module.exports = class extends think.Service {
|
|
|
35
28
|
}
|
|
36
29
|
|
|
37
30
|
async sleep(second) {
|
|
38
|
-
return new Promise((resolve) =>
|
|
31
|
+
return new Promise((resolve) => {
|
|
32
|
+
setTimeout(resolve, second * 1000);
|
|
33
|
+
});
|
|
39
34
|
}
|
|
40
35
|
|
|
41
36
|
async mail({ to, title, content }, self, parent) {
|
|
@@ -43,15 +38,14 @@ module.exports = class extends think.Service {
|
|
|
43
38
|
return;
|
|
44
39
|
}
|
|
45
40
|
|
|
46
|
-
const { SITE_NAME, SITE_URL, SMTP_USER, SENDER_EMAIL, SENDER_NAME } =
|
|
47
|
-
process.env;
|
|
41
|
+
const { SITE_NAME, SITE_URL, SMTP_USER, SENDER_EMAIL, SENDER_NAME } = process.env;
|
|
48
42
|
const data = {
|
|
49
43
|
self,
|
|
50
44
|
parent,
|
|
51
45
|
site: {
|
|
52
46
|
name: SITE_NAME,
|
|
53
47
|
url: SITE_URL,
|
|
54
|
-
postUrl: SITE_URL
|
|
48
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
55
49
|
},
|
|
56
50
|
};
|
|
57
51
|
|
|
@@ -59,10 +53,7 @@ module.exports = class extends think.Service {
|
|
|
59
53
|
content = this.controller.locale(content, data);
|
|
60
54
|
|
|
61
55
|
return this.transporter.sendMail({
|
|
62
|
-
from:
|
|
63
|
-
SENDER_EMAIL && SENDER_NAME
|
|
64
|
-
? `"${SENDER_NAME}" <${SENDER_EMAIL}>`
|
|
65
|
-
: SMTP_USER,
|
|
56
|
+
from: SENDER_EMAIL && SENDER_NAME ? `"${SENDER_NAME}" <${SENDER_EMAIL}>` : SMTP_USER,
|
|
66
57
|
to,
|
|
67
58
|
subject: title,
|
|
68
59
|
html: content,
|
|
@@ -82,7 +73,7 @@ module.exports = class extends think.Service {
|
|
|
82
73
|
site: {
|
|
83
74
|
name: SITE_NAME,
|
|
84
75
|
url: SITE_URL,
|
|
85
|
-
postUrl: SITE_URL
|
|
76
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
86
77
|
},
|
|
87
78
|
};
|
|
88
79
|
|
|
@@ -110,8 +101,7 @@ module.exports = class extends think.Service {
|
|
|
110
101
|
}
|
|
111
102
|
|
|
112
103
|
async qywxAmWechat({ title, content }, self, parent) {
|
|
113
|
-
const { QYWX_AM, QYWX_PROXY, QYWX_PROXY_PORT, SITE_NAME, SITE_URL } =
|
|
114
|
-
process.env;
|
|
104
|
+
const { QYWX_AM, QYWX_PROXY, QYWX_PROXY_PORT, SITE_NAME, SITE_URL } = process.env;
|
|
115
105
|
|
|
116
106
|
if (!QYWX_AM) {
|
|
117
107
|
return false;
|
|
@@ -119,8 +109,8 @@ module.exports = class extends think.Service {
|
|
|
119
109
|
|
|
120
110
|
const QYWX_AM_AY = QYWX_AM.split(',');
|
|
121
111
|
const comment = self.comment
|
|
122
|
-
.
|
|
123
|
-
.
|
|
112
|
+
.replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '\n[$2] $1\n')
|
|
113
|
+
.replaceAll(/<[^>]+>/g, '');
|
|
124
114
|
const postName = self.url;
|
|
125
115
|
|
|
126
116
|
const data = {
|
|
@@ -133,7 +123,7 @@ module.exports = class extends think.Service {
|
|
|
133
123
|
site: {
|
|
134
124
|
name: SITE_NAME,
|
|
135
125
|
url: SITE_URL,
|
|
136
|
-
postUrl: SITE_URL
|
|
126
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
137
127
|
},
|
|
138
128
|
};
|
|
139
129
|
|
|
@@ -148,7 +138,7 @@ module.exports = class extends think.Service {
|
|
|
148
138
|
title = this.controller.locale(title, data);
|
|
149
139
|
const desp = this.controller.locale(contentWechat, data);
|
|
150
140
|
|
|
151
|
-
content = desp.
|
|
141
|
+
content = desp.replaceAll('\n', '<br/>');
|
|
152
142
|
|
|
153
143
|
const querystring = new URLSearchParams();
|
|
154
144
|
|
|
@@ -158,48 +148,38 @@ module.exports = class extends think.Service {
|
|
|
158
148
|
let baseUrl = 'https://qyapi.weixin.qq.com';
|
|
159
149
|
|
|
160
150
|
if (QYWX_PROXY) {
|
|
161
|
-
|
|
162
|
-
baseUrl = `http://${QYWX_PROXY}`;
|
|
163
|
-
} else {
|
|
164
|
-
baseUrl = `http://${QYWX_PROXY}:${QYWX_PROXY_PORT}`;
|
|
165
|
-
}
|
|
151
|
+
baseUrl = `http://${QYWX_PROXY}${QYWX_PROXY_PORT ? `:${QYWX_PROXY_PORT}` : ''}`;
|
|
166
152
|
}
|
|
167
153
|
|
|
168
|
-
const { access_token } = await fetch(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
headers: {
|
|
172
|
-
'content-type': 'application/json',
|
|
173
|
-
},
|
|
154
|
+
const { access_token } = await fetch(`${baseUrl}/cgi-bin/gettoken?${querystring.toString()}`, {
|
|
155
|
+
headers: {
|
|
156
|
+
'content-type': 'application/json',
|
|
174
157
|
},
|
|
175
|
-
).then((resp) => resp.json());
|
|
176
|
-
|
|
177
|
-
return fetch(
|
|
178
|
-
|
|
179
|
-
{
|
|
180
|
-
|
|
181
|
-
headers: {
|
|
182
|
-
'content-type': 'application/json',
|
|
183
|
-
},
|
|
184
|
-
body: JSON.stringify({
|
|
185
|
-
touser: `${QYWX_AM_AY[2]}`,
|
|
186
|
-
agentid: `${QYWX_AM_AY[3]}`,
|
|
187
|
-
msgtype: 'mpnews',
|
|
188
|
-
mpnews: {
|
|
189
|
-
articles: [
|
|
190
|
-
{
|
|
191
|
-
title,
|
|
192
|
-
thumb_media_id: `${QYWX_AM_AY[4]}`,
|
|
193
|
-
author: `Waline Comment`,
|
|
194
|
-
content_source_url: `${data.site.postUrl}`,
|
|
195
|
-
content: `${content}`,
|
|
196
|
-
digest: `${desp}`,
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
},
|
|
200
|
-
}),
|
|
158
|
+
}).then((resp) => resp.json());
|
|
159
|
+
|
|
160
|
+
return fetch(`${baseUrl}/cgi-bin/message/send?access_token=${access_token}`, {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
headers: {
|
|
163
|
+
'content-type': 'application/json',
|
|
201
164
|
},
|
|
202
|
-
|
|
165
|
+
body: JSON.stringify({
|
|
166
|
+
touser: `${QYWX_AM_AY[2]}`,
|
|
167
|
+
agentid: `${QYWX_AM_AY[3]}`,
|
|
168
|
+
msgtype: 'mpnews',
|
|
169
|
+
mpnews: {
|
|
170
|
+
articles: [
|
|
171
|
+
{
|
|
172
|
+
title,
|
|
173
|
+
thumb_media_id: `${QYWX_AM_AY[4]}`,
|
|
174
|
+
author: `Waline Comment`,
|
|
175
|
+
content_source_url: `${data.site.postUrl}`,
|
|
176
|
+
content: `${content}`,
|
|
177
|
+
digest: `${desp}`,
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
}),
|
|
182
|
+
}).then((resp) => resp.json());
|
|
203
183
|
}
|
|
204
184
|
|
|
205
185
|
async qq(self, parent) {
|
|
@@ -210,8 +190,8 @@ module.exports = class extends think.Service {
|
|
|
210
190
|
}
|
|
211
191
|
|
|
212
192
|
const comment = self.comment
|
|
213
|
-
.
|
|
214
|
-
.
|
|
193
|
+
.replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '')
|
|
194
|
+
.replaceAll(/<[^>]+>/g, '');
|
|
215
195
|
|
|
216
196
|
const data = {
|
|
217
197
|
self: {
|
|
@@ -222,7 +202,7 @@ module.exports = class extends think.Service {
|
|
|
222
202
|
site: {
|
|
223
203
|
name: SITE_NAME,
|
|
224
204
|
url: SITE_URL,
|
|
225
|
-
postUrl: SITE_URL
|
|
205
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
226
206
|
},
|
|
227
207
|
};
|
|
228
208
|
|
|
@@ -233,20 +213,29 @@ module.exports = class extends think.Service {
|
|
|
233
213
|
{{self.comment}}
|
|
234
214
|
仅供预览评论,请前往上述页面查看完整內容。`;
|
|
235
215
|
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
form.append('msg', this.controller.locale(contentQQ, data));
|
|
239
|
-
form.append('qq', QQ_ID);
|
|
216
|
+
const qmsgHost = QMSG_HOST ? QMSG_HOST.replace(/\/$/, '') : 'https://qmsg.zendee.cn';
|
|
240
217
|
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
:
|
|
218
|
+
const postBodyData = {
|
|
219
|
+
qq: QQ_ID,
|
|
220
|
+
msg: this.controller.locale(contentQQ, data),
|
|
221
|
+
};
|
|
222
|
+
const postBody = Object.keys(postBodyData)
|
|
223
|
+
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(postBodyData[key]))
|
|
224
|
+
.join('&');
|
|
244
225
|
|
|
245
226
|
return fetch(`${qmsgHost}/send/${QMSG_KEY}`, {
|
|
246
227
|
method: 'POST',
|
|
247
|
-
headers:
|
|
248
|
-
|
|
249
|
-
|
|
228
|
+
headers: {
|
|
229
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
230
|
+
},
|
|
231
|
+
body: postBody,
|
|
232
|
+
}).then((resp) =>
|
|
233
|
+
resp.json().then((json) => {
|
|
234
|
+
think.logger.debug(`qq notify response: ${JSON.stringify(json)}`);
|
|
235
|
+
|
|
236
|
+
return json;
|
|
237
|
+
}),
|
|
238
|
+
);
|
|
250
239
|
}
|
|
251
240
|
|
|
252
241
|
async telegram(self, parent) {
|
|
@@ -259,23 +248,19 @@ module.exports = class extends think.Service {
|
|
|
259
248
|
let commentLink = '';
|
|
260
249
|
const href = self.comment.match(/<a href="(.*?)">(.*?)<\/a>/g);
|
|
261
250
|
|
|
262
|
-
if (href
|
|
251
|
+
if (href != null) {
|
|
263
252
|
for (let i = 0; i < href.length; i++) {
|
|
264
253
|
href[i] =
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
'](' +
|
|
268
|
-
href[i].replace(/<a href="(.*?)">(.*?)<\/a>/g, '$1') +
|
|
269
|
-
') ';
|
|
270
|
-
commentLink = commentLink + href[i];
|
|
254
|
+
`[Link: ${href[i].replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '$2')}](${href[i].replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '$1')}) `;
|
|
255
|
+
commentLink += href[i];
|
|
271
256
|
}
|
|
272
257
|
}
|
|
273
258
|
if (commentLink !== '') {
|
|
274
|
-
commentLink = `\n
|
|
259
|
+
commentLink = `\n${commentLink}\n`;
|
|
275
260
|
}
|
|
276
261
|
const comment = self.comment
|
|
277
|
-
.
|
|
278
|
-
.
|
|
262
|
+
.replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '[Link:$2]')
|
|
263
|
+
.replaceAll(/<[^>]+>/g, '');
|
|
279
264
|
|
|
280
265
|
const contentTG =
|
|
281
266
|
think.config('TGTemplate') ||
|
|
@@ -302,27 +287,24 @@ module.exports = class extends think.Service {
|
|
|
302
287
|
site: {
|
|
303
288
|
name: SITE_NAME,
|
|
304
289
|
url: SITE_URL,
|
|
305
|
-
postUrl: SITE_URL
|
|
290
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
306
291
|
},
|
|
307
292
|
};
|
|
308
293
|
|
|
309
|
-
const resp = await fetch(
|
|
310
|
-
|
|
311
|
-
{
|
|
312
|
-
|
|
313
|
-
headers: {
|
|
314
|
-
'Content-Type': 'application/json',
|
|
315
|
-
},
|
|
316
|
-
body: JSON.stringify({
|
|
317
|
-
chat_id: TG_CHAT_ID,
|
|
318
|
-
text: this.controller.locale(contentTG, data),
|
|
319
|
-
parse_mode: 'MarkdownV2',
|
|
320
|
-
}),
|
|
294
|
+
const resp = await fetch(`https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage`, {
|
|
295
|
+
method: 'POST',
|
|
296
|
+
headers: {
|
|
297
|
+
'Content-Type': 'application/json',
|
|
321
298
|
},
|
|
322
|
-
|
|
299
|
+
body: JSON.stringify({
|
|
300
|
+
chat_id: TG_CHAT_ID,
|
|
301
|
+
text: this.controller.locale(contentTG, data),
|
|
302
|
+
parse_mode: 'MarkdownV2',
|
|
303
|
+
}),
|
|
304
|
+
}).then((resp) => resp.json());
|
|
323
305
|
|
|
324
306
|
if (!resp.ok) {
|
|
325
|
-
console.log(
|
|
307
|
+
console.log(`Telegram Notification Failed:${JSON.stringify(resp)}`);
|
|
326
308
|
}
|
|
327
309
|
}
|
|
328
310
|
|
|
@@ -348,27 +330,29 @@ module.exports = class extends think.Service {
|
|
|
348
330
|
site: {
|
|
349
331
|
name: SITE_NAME,
|
|
350
332
|
url: SITE_URL,
|
|
351
|
-
postUrl: SITE_URL
|
|
333
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
352
334
|
},
|
|
353
335
|
};
|
|
354
336
|
|
|
355
337
|
title = this.controller.locale(title, data);
|
|
356
338
|
content = this.controller.locale(content, data);
|
|
357
339
|
|
|
358
|
-
const form = new
|
|
340
|
+
const form = new URLSearchParams();
|
|
359
341
|
|
|
360
|
-
if (topic) form.
|
|
361
|
-
if (template) form.
|
|
362
|
-
if (channel) form.
|
|
363
|
-
if (webhook) form.
|
|
364
|
-
if (callbackUrl) form.
|
|
365
|
-
if (title) form.
|
|
366
|
-
if (content) form.
|
|
342
|
+
if (topic) form.set('topic', topic);
|
|
343
|
+
if (template) form.set('template', template);
|
|
344
|
+
if (channel) form.set('channel', channel);
|
|
345
|
+
if (webhook) form.set('webhook', webhook);
|
|
346
|
+
if (callbackUrl) form.set('callbackUrl', callbackUrl);
|
|
347
|
+
if (title) form.set('title', title);
|
|
348
|
+
if (content) form.set('content', content);
|
|
367
349
|
|
|
368
350
|
return fetch(`http://www.pushplus.plus/send/${PUSH_PLUS_KEY}`, {
|
|
369
351
|
method: 'POST',
|
|
370
|
-
headers:
|
|
371
|
-
|
|
352
|
+
headers: {
|
|
353
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
354
|
+
},
|
|
355
|
+
body: form.toString(),
|
|
372
356
|
}).then((resp) => resp.json());
|
|
373
357
|
}
|
|
374
358
|
|
|
@@ -385,7 +369,7 @@ module.exports = class extends think.Service {
|
|
|
385
369
|
site: {
|
|
386
370
|
name: SITE_NAME,
|
|
387
371
|
url: SITE_URL,
|
|
388
|
-
postUrl: SITE_URL
|
|
372
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
389
373
|
},
|
|
390
374
|
};
|
|
391
375
|
|
|
@@ -420,7 +404,7 @@ module.exports = class extends think.Service {
|
|
|
420
404
|
return false;
|
|
421
405
|
}
|
|
422
406
|
|
|
423
|
-
self.comment = self.comment.
|
|
407
|
+
self.comment = self.comment.replaceAll(/(<([^>]+)>)/gi, '');
|
|
424
408
|
|
|
425
409
|
const data = {
|
|
426
410
|
self,
|
|
@@ -428,7 +412,7 @@ module.exports = class extends think.Service {
|
|
|
428
412
|
site: {
|
|
429
413
|
name: SITE_NAME,
|
|
430
414
|
url: SITE_URL,
|
|
431
|
-
postUrl: SITE_URL
|
|
415
|
+
postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
|
|
432
416
|
},
|
|
433
417
|
};
|
|
434
418
|
|
|
@@ -461,13 +445,13 @@ module.exports = class extends think.Service {
|
|
|
461
445
|
};
|
|
462
446
|
|
|
463
447
|
const sign = (timestamp, secret) => {
|
|
464
|
-
const signStr = timestamp
|
|
448
|
+
const signStr = `${timestamp}\n${secret}`;
|
|
465
449
|
|
|
466
450
|
return crypto.createHmac('sha256', signStr).update('').digest('base64');
|
|
467
451
|
};
|
|
468
452
|
|
|
469
453
|
if (LARK_SECRET) {
|
|
470
|
-
const timestamp = parseInt(
|
|
454
|
+
const timestamp = Number.parseInt(Date.now() / 1000, 10);
|
|
471
455
|
|
|
472
456
|
signData = { timestamp: timestamp, sign: sign(timestamp, LARK_SECRET) };
|
|
473
457
|
}
|
|
@@ -484,16 +468,15 @@ module.exports = class extends think.Service {
|
|
|
484
468
|
}).then((resp) => resp.json());
|
|
485
469
|
|
|
486
470
|
if (resp.status !== 200) {
|
|
487
|
-
console.log(
|
|
471
|
+
console.log(`Lark Notification Failed:${JSON.stringify(resp)}`);
|
|
488
472
|
}
|
|
489
473
|
|
|
490
|
-
console.log(
|
|
474
|
+
console.log(`FeiShu Notification Success:${JSON.stringify(resp)}`);
|
|
491
475
|
}
|
|
492
476
|
|
|
493
477
|
async run(comment, parent, disableAuthorNotify = false) {
|
|
494
478
|
const { AUTHOR_EMAIL, DISABLE_AUTHOR_NOTIFY } = process.env;
|
|
495
|
-
const { mailSubject, mailTemplate, mailSubjectAdmin, mailTemplateAdmin } =
|
|
496
|
-
think.config();
|
|
479
|
+
const { mailSubject, mailTemplate, mailSubjectAdmin, mailTemplateAdmin } = think.config();
|
|
497
480
|
const AUTHOR = AUTHOR_EMAIL;
|
|
498
481
|
|
|
499
482
|
const mailList = [];
|
|
@@ -504,19 +487,14 @@ module.exports = class extends think.Service {
|
|
|
504
487
|
? parent && (parent.mail || '').toLowerCase() === AUTHOR.toLowerCase()
|
|
505
488
|
: false;
|
|
506
489
|
const isCommentSelf =
|
|
507
|
-
parent &&
|
|
508
|
-
(parent.mail || '').toLowerCase() === (comment.mail || '').toLowerCase();
|
|
490
|
+
parent && (parent.mail || '').toLowerCase() === (comment.mail || '').toLowerCase();
|
|
509
491
|
|
|
510
492
|
const title = mailSubjectAdmin || 'MAIL_SUBJECT_ADMIN';
|
|
511
493
|
const content = mailTemplateAdmin || 'MAIL_TEMPLATE_ADMIN';
|
|
512
494
|
|
|
513
495
|
if (!DISABLE_AUTHOR_NOTIFY && !isAuthorComment && !disableAuthorNotify) {
|
|
514
496
|
const wechat = await this.wechat({ title, content }, comment, parent);
|
|
515
|
-
const qywxAmWechat = await this.qywxAmWechat(
|
|
516
|
-
{ title, content },
|
|
517
|
-
comment,
|
|
518
|
-
parent,
|
|
519
|
-
);
|
|
497
|
+
const qywxAmWechat = await this.qywxAmWechat({ title, content }, comment, parent);
|
|
520
498
|
const qq = await this.qq(comment, parent);
|
|
521
499
|
const telegram = await this.telegram(comment, parent);
|
|
522
500
|
const pushplus = await this.pushplus({ title, content }, comment, parent);
|
|
@@ -524,17 +502,15 @@ module.exports = class extends think.Service {
|
|
|
524
502
|
const lark = await this.lark({ title, content }, comment, parent);
|
|
525
503
|
|
|
526
504
|
if (
|
|
527
|
-
[wechat, qq, telegram, qywxAmWechat, pushplus, discord, lark].every(
|
|
528
|
-
think.isEmpty,
|
|
505
|
+
[wechat, qq, telegram, qywxAmWechat, pushplus, discord, lark].every((item) =>
|
|
506
|
+
think.isEmpty(item),
|
|
529
507
|
)
|
|
530
508
|
) {
|
|
531
509
|
mailList.push({ to: AUTHOR, title, content });
|
|
532
510
|
}
|
|
533
511
|
}
|
|
534
512
|
|
|
535
|
-
const disallowList = this.controller.ctx.state.oauthServices.map(
|
|
536
|
-
({ name }) => 'mail.' + name,
|
|
537
|
-
);
|
|
513
|
+
const disallowList = this.controller.ctx.state.oauthServices.map(({ name }) => `mail.${name}`);
|
|
538
514
|
const fakeMail = new RegExp(`@(${disallowList.join('|')})$`, 'i');
|
|
539
515
|
|
|
540
516
|
if (
|
|
@@ -556,8 +532,8 @@ module.exports = class extends think.Service {
|
|
|
556
532
|
const response = await this.mail(mail, comment, parent);
|
|
557
533
|
|
|
558
534
|
console.log('Notification mail send success: %s', response);
|
|
559
|
-
} catch (
|
|
560
|
-
console.log('Mail send fail:',
|
|
535
|
+
} catch (err) {
|
|
536
|
+
console.log('Mail send fail:', err);
|
|
561
537
|
}
|
|
562
538
|
}
|
|
563
539
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* eslint-disable
|
|
1
|
+
/* eslint-disable typescript/no-unused-vars */
|
|
2
2
|
|
|
3
3
|
module.exports = class extends think.Service {
|
|
4
4
|
constructor(tableName) {
|
|
@@ -14,12 +14,7 @@ module.exports = class extends think.Service {
|
|
|
14
14
|
//to be implemented
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
async add(
|
|
18
|
-
data,
|
|
19
|
-
{
|
|
20
|
-
access: { read = true, write = true } = { read: true, write: true },
|
|
21
|
-
} = {},
|
|
22
|
-
) {
|
|
17
|
+
async add(data, { access: { read = true, write = true } = { read: true, write: true } } = {}) {
|
|
23
18
|
//to be implemented
|
|
24
19
|
}
|
|
25
20
|
|
|
@@ -27,14 +27,14 @@ module.exports = class extends Base {
|
|
|
27
27
|
collections[tableName] = true;
|
|
28
28
|
|
|
29
29
|
return db.collection(tableName);
|
|
30
|
-
} catch (
|
|
31
|
-
if (
|
|
30
|
+
} catch (err) {
|
|
31
|
+
if (err.code === 'DATABASE_COLLECTION_NOT_EXIST') {
|
|
32
32
|
await db.createCollection(tableName);
|
|
33
33
|
collections[tableName] = true;
|
|
34
34
|
|
|
35
35
|
return db.collection(tableName);
|
|
36
36
|
}
|
|
37
|
-
throw
|
|
37
|
+
throw err;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -46,7 +46,7 @@ module.exports = class extends Base {
|
|
|
46
46
|
const filter = {};
|
|
47
47
|
const parseKey = (k) => (k === 'objectId' ? '_id' : k);
|
|
48
48
|
|
|
49
|
-
for (
|
|
49
|
+
for (const k in where) {
|
|
50
50
|
if (k === '_complex') {
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
@@ -62,12 +62,14 @@ module.exports = class extends Base {
|
|
|
62
62
|
const handler = where[k][0].toUpperCase();
|
|
63
63
|
|
|
64
64
|
switch (handler) {
|
|
65
|
-
case 'IN':
|
|
65
|
+
case 'IN': {
|
|
66
66
|
filter[parseKey(k)] = _.in(where[k][1]);
|
|
67
67
|
break;
|
|
68
|
-
|
|
68
|
+
}
|
|
69
|
+
case 'NOT IN': {
|
|
69
70
|
filter[parseKey(k)] = _.nin(where[k][1]);
|
|
70
71
|
break;
|
|
72
|
+
}
|
|
71
73
|
case 'LIKE': {
|
|
72
74
|
const first = where[k][1][0];
|
|
73
75
|
const last = where[k][1].slice(-1);
|
|
@@ -152,7 +154,7 @@ module.exports = class extends Base {
|
|
|
152
154
|
async select(where, options = {}) {
|
|
153
155
|
let data = [];
|
|
154
156
|
let ret = [];
|
|
155
|
-
|
|
157
|
+
const offset = options.offset ?? 0;
|
|
156
158
|
|
|
157
159
|
do {
|
|
158
160
|
options.offset = offset + data.length;
|