@waline/vercel 1.18.8 → 1.19.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.
- package/__tests__/katex.spec.js +2 -0
- package/index.js +2 -0
- package/package.json +9 -9
- package/src/config/adapter.js +16 -0
- package/src/config/config.js +2 -1
- package/src/config/extend.js +6 -4
- package/src/controller/article.js +1 -0
- package/src/controller/comment.js +29 -0
- package/src/controller/db.js +54 -2
- package/src/controller/oauth.js +14 -8
- package/src/controller/rest.js +1 -0
- package/src/controller/token/2fa.js +4 -0
- package/src/controller/token.js +4 -0
- package/src/controller/user/password.js +2 -0
- package/src/controller/user.js +3 -0
- package/src/controller/verification.js +3 -0
- package/src/extend/controller.js +4 -0
- package/src/extend/think.js +8 -1
- package/src/logic/base.js +6 -0
- package/src/logic/comment.js +5 -0
- package/src/logic/db.js +1 -0
- package/src/logic/token/2fa.js +1 -0
- package/src/logic/user.js +2 -0
- package/src/service/akismet.js +1 -0
- package/src/service/avatar.js +5 -0
- package/src/service/markdown/katex.js +2 -0
- package/src/service/markdown/mathCommon.js +5 -0
- package/src/service/markdown/mathjax.js +3 -0
- package/src/service/notify.js +109 -80
- package/src/service/storage/cloudbase.js +21 -0
- package/src/service/storage/deta.js +28 -0
- package/src/service/storage/github.js +77 -49
- package/src/service/storage/leancloud.js +42 -1
- package/src/service/storage/mongodb.js +17 -0
- package/src/service/storage/mysql.js +11 -0
- package/src/service/storage/postgresql.js +23 -2
- package/vanilla.js +1 -0
|
@@ -12,18 +12,21 @@ module.exports = class extends BaseRest {
|
|
|
12
12
|
async getAction() {
|
|
13
13
|
const { token, email } = this.get();
|
|
14
14
|
const users = await this.modelInstance.select({ email });
|
|
15
|
+
|
|
15
16
|
if (think.isEmpty(users)) {
|
|
16
17
|
return this.fail(this.locale('USER_NOT_EXIST'));
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
const user = users[0];
|
|
20
21
|
const match = user.type.match(/^verify:(\d{4}):(\d+)$/i);
|
|
22
|
+
|
|
21
23
|
if (!match) {
|
|
22
24
|
return this.fail(this.locale('USER_REGISTED'));
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
if (token === match[1] && Date.now() < parseInt(match[2])) {
|
|
26
28
|
await this.modelInstance.update({ type: 'guest' }, { email });
|
|
29
|
+
|
|
27
30
|
return this.redirect('/ui/login');
|
|
28
31
|
}
|
|
29
32
|
|
package/src/extend/controller.js
CHANGED
|
@@ -4,18 +4,22 @@ const locales = require('../locales');
|
|
|
4
4
|
module.exports = {
|
|
5
5
|
success(...args) {
|
|
6
6
|
this.ctx.success(...args);
|
|
7
|
+
|
|
7
8
|
return think.prevent();
|
|
8
9
|
},
|
|
9
10
|
fail(...args) {
|
|
10
11
|
this.ctx.fail(...args);
|
|
12
|
+
|
|
11
13
|
return think.prevent();
|
|
12
14
|
},
|
|
13
15
|
locale(message, variables) {
|
|
14
16
|
const { lang } = this.get();
|
|
15
17
|
const locale = locales[(lang || '').toLowerCase()];
|
|
18
|
+
|
|
16
19
|
if (locale && locale[message]) {
|
|
17
20
|
message = locale[message];
|
|
18
21
|
}
|
|
22
|
+
|
|
19
23
|
return nunjucks.renderString(message, variables);
|
|
20
24
|
},
|
|
21
25
|
};
|
package/src/extend/think.js
CHANGED
|
@@ -14,9 +14,11 @@ module.exports = {
|
|
|
14
14
|
findLastIndex(arr, fn) {
|
|
15
15
|
for (let i = arr.length - 1; i >= 0; i--) {
|
|
16
16
|
const ret = fn(arr[i], i, arr);
|
|
17
|
+
|
|
17
18
|
if (!ret) {
|
|
18
19
|
continue;
|
|
19
20
|
}
|
|
21
|
+
|
|
20
22
|
return i;
|
|
21
23
|
}
|
|
22
24
|
|
|
@@ -34,6 +36,7 @@ module.exports = {
|
|
|
34
36
|
|
|
35
37
|
function runTask() {
|
|
36
38
|
const idx = index;
|
|
39
|
+
|
|
37
40
|
index += 1;
|
|
38
41
|
if (index > promises.length) {
|
|
39
42
|
return Promise.resolve();
|
|
@@ -45,6 +48,7 @@ module.exports = {
|
|
|
45
48
|
if (count === promises.length) {
|
|
46
49
|
resolve(ret);
|
|
47
50
|
}
|
|
51
|
+
|
|
48
52
|
return runTask();
|
|
49
53
|
}, reject);
|
|
50
54
|
}
|
|
@@ -55,20 +59,23 @@ module.exports = {
|
|
|
55
59
|
});
|
|
56
60
|
},
|
|
57
61
|
async ip2region(ip, { depth = 1 }) {
|
|
58
|
-
if (!ip) return '';
|
|
62
|
+
if (!ip || ip.includes(':')) return '';
|
|
59
63
|
|
|
60
64
|
try {
|
|
61
65
|
const search = helper.promisify(regionSearch.btreeSearch, regionSearch);
|
|
62
66
|
const result = await search(ip);
|
|
67
|
+
|
|
63
68
|
if (!result) {
|
|
64
69
|
return '';
|
|
65
70
|
}
|
|
66
71
|
const { region } = result;
|
|
67
72
|
const [, , province, city, isp] = region.split('|');
|
|
68
73
|
const address = Array.from(new Set([province, city, isp]));
|
|
74
|
+
|
|
69
75
|
return address.slice(0, depth).join(' ');
|
|
70
76
|
} catch (e) {
|
|
71
77
|
console.log(e);
|
|
78
|
+
|
|
72
79
|
return '';
|
|
73
80
|
}
|
|
74
81
|
},
|
package/src/logic/base.js
CHANGED
|
@@ -16,6 +16,7 @@ module.exports = class extends think.Logic {
|
|
|
16
16
|
async __before() {
|
|
17
17
|
const referrer = this.ctx.referrer(true);
|
|
18
18
|
let { secureDomains } = this.config();
|
|
19
|
+
|
|
19
20
|
if (secureDomains && referrer && this.ctx.host.indexOf(referrer) !== 0) {
|
|
20
21
|
secureDomains = think.isArray(secureDomains)
|
|
21
22
|
? secureDomains
|
|
@@ -33,6 +34,7 @@ module.exports = class extends think.Logic {
|
|
|
33
34
|
? domain.test(referrer)
|
|
34
35
|
: domain === referrer
|
|
35
36
|
);
|
|
37
|
+
|
|
36
38
|
if (!match) {
|
|
37
39
|
return this.ctx.throw(403);
|
|
38
40
|
}
|
|
@@ -41,11 +43,13 @@ module.exports = class extends think.Logic {
|
|
|
41
43
|
this.ctx.state.userInfo = {};
|
|
42
44
|
const { authorization } = this.ctx.req.headers;
|
|
43
45
|
const { state } = this.get();
|
|
46
|
+
|
|
44
47
|
if (!authorization && !state) {
|
|
45
48
|
return;
|
|
46
49
|
}
|
|
47
50
|
const token = state || authorization.replace(/^Bearer /, '');
|
|
48
51
|
const userMail = jwt.verify(token, think.config('jwtKey'));
|
|
52
|
+
|
|
49
53
|
if (think.isEmpty(userMail) || !think.isString(userMail)) {
|
|
50
54
|
return;
|
|
51
55
|
}
|
|
@@ -71,6 +75,7 @@ module.exports = class extends think.Logic {
|
|
|
71
75
|
],
|
|
72
76
|
}
|
|
73
77
|
);
|
|
78
|
+
|
|
74
79
|
if (think.isEmpty(user)) {
|
|
75
80
|
return;
|
|
76
81
|
}
|
|
@@ -85,6 +90,7 @@ module.exports = class extends think.Logic {
|
|
|
85
90
|
link: userInfo.url,
|
|
86
91
|
});
|
|
87
92
|
const { avatarProxy } = think.config();
|
|
93
|
+
|
|
88
94
|
if (avatarProxy) {
|
|
89
95
|
avatarUrl = avatarProxy + '?url=' + encodeURIComponent(avatarUrl);
|
|
90
96
|
}
|
package/src/logic/comment.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const Base = require('./base');
|
|
2
|
+
|
|
2
3
|
module.exports = class extends Base {
|
|
3
4
|
async __before() {
|
|
4
5
|
await super.__before();
|
|
@@ -7,6 +8,7 @@ module.exports = class extends Base {
|
|
|
7
8
|
const { like } = this.post();
|
|
8
9
|
const isAllowedGet = this.isGet && (type !== 'list' || path);
|
|
9
10
|
const isAllowedPut = this.ctx.isMethod('PUT') && think.isBoolean(like);
|
|
11
|
+
|
|
10
12
|
if (this.isPost || isAllowedGet || isAllowedPut) {
|
|
11
13
|
return;
|
|
12
14
|
}
|
|
@@ -114,6 +116,7 @@ module.exports = class extends Base {
|
|
|
114
116
|
*/
|
|
115
117
|
getAction() {
|
|
116
118
|
const { type } = this.get();
|
|
119
|
+
|
|
117
120
|
switch (type) {
|
|
118
121
|
case 'recent':
|
|
119
122
|
this.rules = {
|
|
@@ -135,6 +138,7 @@ module.exports = class extends Base {
|
|
|
135
138
|
|
|
136
139
|
case 'list': {
|
|
137
140
|
const { userInfo } = this.ctx.state;
|
|
141
|
+
|
|
138
142
|
if (userInfo.type !== 'administrator') {
|
|
139
143
|
return this.fail();
|
|
140
144
|
}
|
|
@@ -224,6 +228,7 @@ module.exports = class extends Base {
|
|
|
224
228
|
*/
|
|
225
229
|
putAction() {
|
|
226
230
|
const { userInfo } = this.ctx.state;
|
|
231
|
+
|
|
227
232
|
if (think.isEmpty(userInfo) || userInfo.type !== 'administrator') {
|
|
228
233
|
this.rules = {
|
|
229
234
|
like: {
|
package/src/logic/db.js
CHANGED
package/src/logic/token/2fa.js
CHANGED
package/src/logic/user.js
CHANGED
|
@@ -3,6 +3,7 @@ const Base = require('./base');
|
|
|
3
3
|
module.exports = class extends Base {
|
|
4
4
|
getAction() {
|
|
5
5
|
const { userInfo } = this.ctx.state;
|
|
6
|
+
|
|
6
7
|
if (think.isEmpty(userInfo) || userInfo.type !== 'administrator') {
|
|
7
8
|
return this.fail();
|
|
8
9
|
}
|
|
@@ -50,6 +51,7 @@ module.exports = class extends Base {
|
|
|
50
51
|
putAction() {
|
|
51
52
|
// you need login to update yourself profile
|
|
52
53
|
const { userInfo } = this.ctx.state;
|
|
54
|
+
|
|
53
55
|
if (think.isEmpty(userInfo)) {
|
|
54
56
|
return this.fail();
|
|
55
57
|
}
|
package/src/service/akismet.js
CHANGED
package/src/service/avatar.js
CHANGED
|
@@ -3,6 +3,7 @@ const helper = require('think-helper');
|
|
|
3
3
|
const { GRAVATAR_STR } = process.env;
|
|
4
4
|
|
|
5
5
|
const env = new nunjucks.Environment();
|
|
6
|
+
|
|
6
7
|
env.addFilter('md5', (str) => helper.md5(str));
|
|
7
8
|
|
|
8
9
|
const DEFAULT_GRAVATAR_STR = `{%- set numExp = r/^[0-9]+$/g -%}
|
|
@@ -14,17 +15,21 @@ const DEFAULT_GRAVATAR_STR = `{%- set numExp = r/^[0-9]+$/g -%}
|
|
|
14
15
|
{%- else -%}
|
|
15
16
|
https://seccdn.libravatar.org/avatar/{{mail|md5}}
|
|
16
17
|
{%- endif -%}`;
|
|
18
|
+
|
|
17
19
|
module.exports = class extends think.Service {
|
|
18
20
|
async stringify(comment) {
|
|
19
21
|
const fn = think.config('avatarUrl');
|
|
22
|
+
|
|
20
23
|
if (think.isFunction(fn)) {
|
|
21
24
|
const ret = await fn(comment);
|
|
25
|
+
|
|
22
26
|
if (think.isString(ret) && ret) {
|
|
23
27
|
return ret;
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
const gravatarStr = GRAVATAR_STR || DEFAULT_GRAVATAR_STR;
|
|
32
|
+
|
|
28
33
|
return env.renderString(gravatarStr, comment);
|
|
29
34
|
}
|
|
30
35
|
};
|
|
@@ -9,6 +9,7 @@ const katexInline = (tex, options) => {
|
|
|
9
9
|
return katex.renderToString(tex, options);
|
|
10
10
|
} catch (error) {
|
|
11
11
|
if (options.throwOnError) console.warn(error);
|
|
12
|
+
|
|
12
13
|
return `<span class='katex-error' title='${escapeHtml(
|
|
13
14
|
error.toString()
|
|
14
15
|
)}'>${escapeHtml(tex)}</span>`;
|
|
@@ -21,6 +22,7 @@ const katexBlock = (tex, options) => {
|
|
|
21
22
|
return `<p class='katex-block'>${katex.renderToString(tex, options)}</p>`;
|
|
22
23
|
} catch (error) {
|
|
23
24
|
if (options.throwOnError) console.warn(error);
|
|
25
|
+
|
|
24
26
|
return `<p class='katex-block katex-error' title='${escapeHtml(
|
|
25
27
|
error.toString()
|
|
26
28
|
)}'>${escapeHtml(tex)}</p>`;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
const isValidDelim = (state, pos) => {
|
|
6
6
|
const prevChar = pos > 0 ? state.src.charAt(pos - 1) : '';
|
|
7
7
|
const nextChar = pos + 1 <= state.posMax ? state.src.charAt(pos + 1) : '';
|
|
8
|
+
|
|
8
9
|
return {
|
|
9
10
|
canOpen: nextChar !== ' ' && nextChar !== '\t',
|
|
10
11
|
/*
|
|
@@ -31,6 +32,7 @@ const inlineTex = (state, silent) => {
|
|
|
31
32
|
if (!res.canOpen) {
|
|
32
33
|
if (!silent) state.pending += '$';
|
|
33
34
|
state.pos += 1;
|
|
35
|
+
|
|
34
36
|
return true;
|
|
35
37
|
}
|
|
36
38
|
/*
|
|
@@ -58,6 +60,7 @@ const inlineTex = (state, silent) => {
|
|
|
58
60
|
if (match === -1) {
|
|
59
61
|
if (!silent) state.pending += '$';
|
|
60
62
|
state.pos = start;
|
|
63
|
+
|
|
61
64
|
return true;
|
|
62
65
|
}
|
|
63
66
|
|
|
@@ -65,6 +68,7 @@ const inlineTex = (state, silent) => {
|
|
|
65
68
|
if (match - start === 0) {
|
|
66
69
|
if (!silent) state.pending += '$$';
|
|
67
70
|
state.pos = start + 1;
|
|
71
|
+
|
|
68
72
|
return true;
|
|
69
73
|
}
|
|
70
74
|
|
|
@@ -74,6 +78,7 @@ const inlineTex = (state, silent) => {
|
|
|
74
78
|
if (!res.canClose) {
|
|
75
79
|
if (!silent) state.pending += '$';
|
|
76
80
|
state.pos = start;
|
|
81
|
+
|
|
77
82
|
return true;
|
|
78
83
|
}
|
|
79
84
|
|
|
@@ -12,6 +12,7 @@ const { inlineTex, blockTex } = require('./mathCommon');
|
|
|
12
12
|
class MathToSvg {
|
|
13
13
|
constructor() {
|
|
14
14
|
const adaptor = liteAdaptor();
|
|
15
|
+
|
|
15
16
|
RegisterHTMLHandler(adaptor);
|
|
16
17
|
|
|
17
18
|
const packages = AllPackages.sort();
|
|
@@ -27,6 +28,7 @@ class MathToSvg {
|
|
|
27
28
|
|
|
28
29
|
if (svg.includes('data-mml-node="merror"')) {
|
|
29
30
|
const errorTitle = svg.match(/<title>(.*?)<\/title>/)[1];
|
|
31
|
+
|
|
30
32
|
svg = `<span class='katex-error' title='${escapeHtml(
|
|
31
33
|
errorTitle
|
|
32
34
|
)}'>${escapeHtml(tex)}</span>`;
|
|
@@ -41,6 +43,7 @@ class MathToSvg {
|
|
|
41
43
|
|
|
42
44
|
if (svg.includes('data-mml-node="merror"')) {
|
|
43
45
|
const errorTitle = svg.match(/<title>(.*?)<\/title>/)[1];
|
|
46
|
+
|
|
44
47
|
svg = `<p class='katex-block katex-error' title='${escapeHtml(
|
|
45
48
|
errorTitle
|
|
46
49
|
)}'>${escapeHtml(tex)}</p>`;
|
package/src/service/notify.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
const FormData = require('form-data');
|
|
1
2
|
const nodemailer = require('nodemailer');
|
|
3
|
+
const fetch = require('node-fetch');
|
|
2
4
|
const nunjucks = require('nunjucks');
|
|
3
|
-
|
|
5
|
+
|
|
4
6
|
module.exports = class extends think.Service {
|
|
5
7
|
constructor(...args) {
|
|
6
8
|
super(...args);
|
|
@@ -13,10 +15,12 @@ module.exports = class extends think.Service {
|
|
|
13
15
|
SMTP_SECURE,
|
|
14
16
|
SMTP_SERVICE,
|
|
15
17
|
} = process.env;
|
|
18
|
+
|
|
16
19
|
if (SMTP_HOST || SMTP_SERVICE) {
|
|
17
20
|
const config = {
|
|
18
21
|
auth: { user: SMTP_USER, pass: SMTP_PASS },
|
|
19
22
|
};
|
|
23
|
+
|
|
20
24
|
if (SMTP_SERVICE) {
|
|
21
25
|
config.service = SMTP_SERVICE;
|
|
22
26
|
} else {
|
|
@@ -48,6 +52,7 @@ module.exports = class extends think.Service {
|
|
|
48
52
|
postUrl: SITE_URL + self.url + '#' + self.objectId,
|
|
49
53
|
},
|
|
50
54
|
};
|
|
55
|
+
|
|
51
56
|
title = nunjucks.renderString(title, data);
|
|
52
57
|
content = nunjucks.renderString(content, data);
|
|
53
58
|
|
|
@@ -64,6 +69,7 @@ module.exports = class extends think.Service {
|
|
|
64
69
|
|
|
65
70
|
async wechat({ title, content }, self, parent) {
|
|
66
71
|
const { SC_KEY, SITE_NAME, SITE_URL } = process.env;
|
|
72
|
+
|
|
67
73
|
if (!SC_KEY) {
|
|
68
74
|
return false;
|
|
69
75
|
}
|
|
@@ -77,22 +83,25 @@ module.exports = class extends think.Service {
|
|
|
77
83
|
postUrl: SITE_URL + self.url + '#' + self.objectId,
|
|
78
84
|
},
|
|
79
85
|
};
|
|
86
|
+
|
|
80
87
|
title = nunjucks.renderString(title, data);
|
|
81
88
|
content = nunjucks.renderString(content, data);
|
|
82
89
|
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
const form = new FormData();
|
|
91
|
+
|
|
92
|
+
form.append('text', title);
|
|
93
|
+
form.append('desp', content);
|
|
94
|
+
|
|
95
|
+
return fetch(`https://sctapi.ftqq.com/${SC_KEY}.send`, {
|
|
85
96
|
method: 'POST',
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
},
|
|
90
|
-
json: true,
|
|
91
|
-
});
|
|
97
|
+
headers: form.getHeaders(),
|
|
98
|
+
body: form,
|
|
99
|
+
}).then((resp) => resp.json());
|
|
92
100
|
}
|
|
93
101
|
|
|
94
102
|
async qywxAmWechat({ title, content }, self, parent) {
|
|
95
103
|
const { QYWX_AM, SITE_NAME, SITE_URL } = process.env;
|
|
104
|
+
|
|
96
105
|
if (!QYWX_AM) {
|
|
97
106
|
return false;
|
|
98
107
|
}
|
|
@@ -126,48 +135,55 @@ module.exports = class extends think.Service {
|
|
|
126
135
|
|
|
127
136
|
title = nunjucks.renderString(title, data);
|
|
128
137
|
const desp = nunjucks.renderString(contentWechat, data);
|
|
138
|
+
|
|
129
139
|
content = desp.replace(/\n/g, '<br/>');
|
|
130
140
|
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
});
|
|
142
|
-
return request({
|
|
143
|
-
url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${access_token}`,
|
|
144
|
-
body: {
|
|
145
|
-
touser: `${QYWX_AM_AY[2]}`,
|
|
146
|
-
agentid: `${QYWX_AM_AY[3]}`,
|
|
147
|
-
msgtype: 'mpnews',
|
|
148
|
-
mpnews: {
|
|
149
|
-
articles: [
|
|
150
|
-
{
|
|
151
|
-
title,
|
|
152
|
-
thumb_media_id: `${QYWX_AM_AY[4]}`,
|
|
153
|
-
author: `Waline Comment`,
|
|
154
|
-
content_source_url: `${data.site.postUrl}`,
|
|
155
|
-
content: `${content}`,
|
|
156
|
-
digest: `${desp}`,
|
|
157
|
-
},
|
|
158
|
-
],
|
|
141
|
+
const querystring = new URLSearchParams();
|
|
142
|
+
|
|
143
|
+
querystring.set('corpid', `${QYWX_AM_AY[0]}`);
|
|
144
|
+
querystring.set('corpsecret', `${QYWX_AM_AY[1]}`);
|
|
145
|
+
|
|
146
|
+
const { access_token } = await fetch(
|
|
147
|
+
`https://qyapi.weixin.qq.com/cgi-bin/gettoken`,
|
|
148
|
+
{
|
|
149
|
+
headers: {
|
|
150
|
+
'content-type': 'application/json',
|
|
159
151
|
},
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
152
|
+
body: querystring,
|
|
153
|
+
}
|
|
154
|
+
).then((resp) => resp.json());
|
|
155
|
+
|
|
156
|
+
return fetch(
|
|
157
|
+
`https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${access_token}`,
|
|
158
|
+
{
|
|
159
|
+
method: 'POST',
|
|
160
|
+
headers: {
|
|
161
|
+
'content-type': 'application/json',
|
|
162
|
+
},
|
|
163
|
+
body: JSON.stringify({
|
|
164
|
+
touser: `${QYWX_AM_AY[2]}`,
|
|
165
|
+
agentid: `${QYWX_AM_AY[3]}`,
|
|
166
|
+
msgtype: 'mpnews',
|
|
167
|
+
mpnews: {
|
|
168
|
+
articles: [
|
|
169
|
+
{
|
|
170
|
+
title,
|
|
171
|
+
thumb_media_id: `${QYWX_AM_AY[4]}`,
|
|
172
|
+
author: `Waline Comment`,
|
|
173
|
+
content_source_url: `${data.site.postUrl}`,
|
|
174
|
+
content: `${content}`,
|
|
175
|
+
digest: `${desp}`,
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
}),
|
|
180
|
+
}
|
|
181
|
+
).then((resp) => resp.json());
|
|
167
182
|
}
|
|
168
183
|
|
|
169
184
|
async qq(self, parent) {
|
|
170
185
|
const { QMSG_KEY, QQ_ID, SITE_NAME, SITE_URL } = process.env;
|
|
186
|
+
|
|
171
187
|
if (!QMSG_KEY) {
|
|
172
188
|
return false;
|
|
173
189
|
}
|
|
@@ -196,24 +212,28 @@ module.exports = class extends think.Service {
|
|
|
196
212
|
{{self.comment}}
|
|
197
213
|
仅供预览评论,请前往上述页面查看完整內容。`;
|
|
198
214
|
|
|
199
|
-
|
|
200
|
-
|
|
215
|
+
const form = new FormData();
|
|
216
|
+
|
|
217
|
+
form.append('msg', nunjucks.renderString(contentQQ, data));
|
|
218
|
+
form.append('qq', QQ_ID);
|
|
219
|
+
|
|
220
|
+
return fetch(`https://qmsg.zendee.cn/send/${QMSG_KEY}`, {
|
|
201
221
|
method: 'POST',
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
},
|
|
206
|
-
});
|
|
222
|
+
header: form.getHeaders(),
|
|
223
|
+
body: form,
|
|
224
|
+
}).then((resp) => resp.json());
|
|
207
225
|
}
|
|
208
226
|
|
|
209
227
|
async telegram(self, parent) {
|
|
210
228
|
const { TG_BOT_TOKEN, TG_CHAT_ID, SITE_NAME, SITE_URL } = process.env;
|
|
229
|
+
|
|
211
230
|
if (!TG_BOT_TOKEN || !TG_CHAT_ID) {
|
|
212
231
|
return false;
|
|
213
232
|
}
|
|
214
233
|
|
|
215
234
|
let commentLink = '';
|
|
216
235
|
const href = self.comment.match(/<a href="(.*?)">(.*?)<\/a>/g);
|
|
236
|
+
|
|
217
237
|
if (href !== null) {
|
|
218
238
|
for (var i = 0; i < href.length; i++) {
|
|
219
239
|
href[i] =
|
|
@@ -261,16 +281,17 @@ module.exports = class extends think.Service {
|
|
|
261
281
|
},
|
|
262
282
|
};
|
|
263
283
|
|
|
264
|
-
|
|
265
|
-
|
|
284
|
+
const form = new FormData();
|
|
285
|
+
|
|
286
|
+
form.append('text', nunjucks.renderString(contentTG, data));
|
|
287
|
+
form.append('chat_id', TG_CHAT_ID);
|
|
288
|
+
form.append('parse_mode', 'MarkdownV2');
|
|
289
|
+
|
|
290
|
+
return fetch(`https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage`, {
|
|
266
291
|
method: 'POST',
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
parse_mode: 'MarkdownV2',
|
|
271
|
-
},
|
|
272
|
-
json: true,
|
|
273
|
-
});
|
|
292
|
+
header: form.getHeaders(),
|
|
293
|
+
body: form,
|
|
294
|
+
}).then((resp) => resp.json());
|
|
274
295
|
}
|
|
275
296
|
|
|
276
297
|
async pushplus({ title, content }, self, parent) {
|
|
@@ -298,27 +319,30 @@ module.exports = class extends think.Service {
|
|
|
298
319
|
postUrl: SITE_URL + self.url + '#' + self.objectId,
|
|
299
320
|
},
|
|
300
321
|
};
|
|
322
|
+
|
|
301
323
|
title = nunjucks.renderString(title, data);
|
|
302
324
|
content = nunjucks.renderString(content, data);
|
|
303
325
|
|
|
304
|
-
|
|
305
|
-
|
|
326
|
+
const form = new FormData();
|
|
327
|
+
|
|
328
|
+
form.append('topic', topic);
|
|
329
|
+
form.append('template', template);
|
|
330
|
+
form.append('channel', channel);
|
|
331
|
+
form.append('webhook', webhook);
|
|
332
|
+
form.append('callbackUrl', callbackUrl);
|
|
333
|
+
form.append('title', title);
|
|
334
|
+
form.append('content', content);
|
|
335
|
+
|
|
336
|
+
return fetch(`http://www.pushplus.plus/send/${PUSH_PLUS_KEY}`, {
|
|
306
337
|
method: 'POST',
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
topic,
|
|
311
|
-
template,
|
|
312
|
-
channel,
|
|
313
|
-
webhook,
|
|
314
|
-
callbackUrl,
|
|
315
|
-
},
|
|
316
|
-
json: true,
|
|
317
|
-
});
|
|
338
|
+
header: form.getHeaders(),
|
|
339
|
+
body: form,
|
|
340
|
+
}).then((resp) => resp.json());
|
|
318
341
|
}
|
|
319
342
|
|
|
320
343
|
async discord({ title, content }, self, parent) {
|
|
321
344
|
const { DISCORD_WEBHOOK, SITE_NAME, SITE_URL } = process.env;
|
|
345
|
+
|
|
322
346
|
if (!DISCORD_WEBHOOK) {
|
|
323
347
|
return false;
|
|
324
348
|
}
|
|
@@ -332,6 +356,7 @@ module.exports = class extends think.Service {
|
|
|
332
356
|
postUrl: SITE_URL + self.url + '#' + self.objectId,
|
|
333
357
|
},
|
|
334
358
|
};
|
|
359
|
+
|
|
335
360
|
title = nunjucks.renderString(title, data);
|
|
336
361
|
content = nunjucks.renderString(
|
|
337
362
|
think.config('DiscordTemplate') ||
|
|
@@ -343,14 +368,15 @@ module.exports = class extends think.Service {
|
|
|
343
368
|
data
|
|
344
369
|
);
|
|
345
370
|
|
|
346
|
-
|
|
347
|
-
|
|
371
|
+
const form = new FormData();
|
|
372
|
+
|
|
373
|
+
form.append('content', `${title}\n${content}`);
|
|
374
|
+
|
|
375
|
+
return fetch(DISCORD_WEBHOOK, {
|
|
348
376
|
method: 'POST',
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
json: true,
|
|
353
|
-
});
|
|
377
|
+
header: form.getHeaders(),
|
|
378
|
+
body: form,
|
|
379
|
+
}).then((resp) => resp.json());
|
|
354
380
|
}
|
|
355
381
|
|
|
356
382
|
async run(comment, parent, disableAuthorNotify = false) {
|
|
@@ -394,6 +420,7 @@ module.exports = class extends think.Service {
|
|
|
394
420
|
const telegram = await this.telegram(comment, parent);
|
|
395
421
|
const pushplus = await this.pushplus({ title, content }, comment, parent);
|
|
396
422
|
const discord = await this.discord({ title, content }, comment, parent);
|
|
423
|
+
|
|
397
424
|
if (
|
|
398
425
|
[wechat, qq, telegram, qywxAmWechat, pushplus, discord].every(
|
|
399
426
|
think.isEmpty
|
|
@@ -408,6 +435,7 @@ module.exports = class extends think.Service {
|
|
|
408
435
|
(social) => 'mail.' + social
|
|
409
436
|
);
|
|
410
437
|
const fakeMail = new RegExp(`@(${disallowList.join('|')})$`, 'i');
|
|
438
|
+
|
|
411
439
|
if (parent && !fakeMail.test(parent.mail) && comment.status !== 'waiting') {
|
|
412
440
|
mailList.push({
|
|
413
441
|
to: parent.mail,
|
|
@@ -436,6 +464,7 @@ module.exports = class extends think.Service {
|
|
|
436
464
|
for (let i = 0; i < mailList.length; i++) {
|
|
437
465
|
try {
|
|
438
466
|
const response = await this.mail(mailList[i], comment, parent);
|
|
467
|
+
|
|
439
468
|
console.log('Notification mail send success: %s', response);
|
|
440
469
|
} catch (e) {
|
|
441
470
|
console.log('Mail send fail:', e);
|