@waline/vercel 0.26.9 → 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/vercel",
3
- "version": "0.26.9",
3
+ "version": "1.0.0",
4
4
  "description": "vercel server for waline comment system",
5
5
  "repository": "https://github.com/walinejs/waline",
6
6
  "license": "MIT",
@@ -9,12 +9,12 @@
9
9
  "@cloudbase/node-sdk": "^2.7.1",
10
10
  "@koa/cors": "^3.1.0",
11
11
  "akismet": "^2.0.6",
12
- "dompurify": "^2.3.1",
12
+ "dompurify": "^2.3.3",
13
13
  "fast-csv": "^4.3.6",
14
14
  "jsdom": "^17.0.0",
15
15
  "jsonwebtoken": "^8.5.1",
16
- "katex": "^0.13.13",
17
- "leancloud-storage": "^4.11.1",
16
+ "katex": "^0.13.18",
17
+ "leancloud-storage": "^4.12.0",
18
18
  "markdown-it": "^12.2.0",
19
19
  "markdown-it-emoji": "^2.0.0",
20
20
  "markdown-it-sub": "^1.0.0",
@@ -23,7 +23,7 @@
23
23
  "nodemailer": "^6.6.3",
24
24
  "nunjucks": "^3.2.3",
25
25
  "phpass": "^0.1.1",
26
- "prismjs": "^1.24.1",
26
+ "prismjs": "^1.25.0",
27
27
  "request": "^2.88.2",
28
28
  "request-promise-native": "^1.0.9",
29
29
  "think-logger3": "^1.2.1",
@@ -65,7 +65,8 @@ if (think.env === 'cloudbase' && storage === 'sqlite') {
65
65
 
66
66
  const forbiddenWords = FORBIDDEN_WORDS ? FORBIDDEN_WORDS.split(/\s*,\s*/) : [];
67
67
 
68
- const isFalse = (content) => content && content.toLowerCase() === 'false';
68
+ const isFalse = (content) =>
69
+ content && ['0', 'false'].includes(content.toLowerCase());
69
70
 
70
71
  const markdown = {
71
72
  config: JSON.parse(MARKDOWN_CONFIG),
@@ -81,6 +82,11 @@ const markdown = {
81
82
 
82
83
  if (isFalse(MARKDOWN_HIGHLIGHT)) markdown.config.highlight = false;
83
84
 
85
+ let avatarProxy = 'https://avatar.75cdn.workers.dev/';
86
+ if (AVATAR_PROXY) {
87
+ avatarProxy = !isFalse(AVATAR_PROXY) ? AVATAR_PROXY : '';
88
+ }
89
+
84
90
  module.exports = {
85
91
  workers: 1,
86
92
  storage,
@@ -88,13 +94,9 @@ module.exports = {
88
94
  forbiddenWords,
89
95
  disallowIPList: [],
90
96
  secureDomains: SECURE_DOMAINS ? SECURE_DOMAINS.split(/\s*,\s*/) : undefined,
91
- disableUserAgent:
92
- DISABLE_USERAGENT &&
93
- !['0', 'false'].includes(DISABLE_USERAGENT.toLowerCase()),
94
- avatarProxy: AVATAR_PROXY || 'https://avatar.75cdn.workers.dev/',
95
-
97
+ disableUserAgent: !isFalse(DISABLE_USERAGENT),
98
+ avatarProxy,
96
99
  markdown,
97
-
98
100
  mailSubject: MAIL_SUBJECT,
99
101
  mailTemplate: MAIL_TEMPLATE,
100
102
  mailSubjectAdmin: MAIL_SUBJECT_ADMIN,
@@ -18,28 +18,28 @@ async function formatCmt(
18
18
  comment.os = [ua.os.name, ua.os.version].filter((v) => v).join(' ');
19
19
  }
20
20
 
21
- if (user_id) {
22
- const user = users.find(({ objectId }) => user_id === objectId);
23
-
24
- if (user) {
25
- comment.nick = user.display_name;
26
- comment.mail = user.email;
27
- comment.link = user.url;
28
- comment.type = user.type;
29
-
30
- let { avatar } = user;
31
- if (avatar) {
32
- if (/(github)/i.test(avatar) && !avatar.includes(avatarProxy)) {
33
- avatar = avatarProxy + '?url=' + encodeURIComponent(avatar);
34
- }
35
- comment.avatar = avatar;
36
- }
37
- }
21
+ const user = users.find(({ objectId }) => user_id === objectId);
22
+ if (user) {
23
+ comment.nick = user.display_name;
24
+ comment.mail = user.email;
25
+ comment.link = user.url;
26
+ comment.type = user.type;
38
27
  }
28
+
39
29
  comment.mail = helper.md5(
40
30
  comment.mail ? comment.mail.toLowerCase() : comment.mail
41
31
  );
42
32
 
33
+ const avatarUrl =
34
+ user && user.avatar
35
+ ? user.avatar
36
+ : `https://seccdn.libravatar.org/avatar/${comment.mail}`;
37
+
38
+ comment.avatar =
39
+ avatarProxy && !avatarUrl.includes(avatarProxy)
40
+ ? avatarProxy + '?url=' + encodeURIComponent(avatarUrl)
41
+ : avatarUrl;
42
+
43
43
  return comment;
44
44
  }
45
45
 
@@ -169,6 +169,7 @@ module.exports = class extends BaseRest {
169
169
  'rid',
170
170
  'ua',
171
171
  'user_id',
172
+ 'sticky',
172
173
  ],
173
174
  }
174
175
  );
@@ -193,9 +194,10 @@ module.exports = class extends BaseRest {
193
194
 
194
195
  const rootCount = comments.filter(({ rid }) => !rid).length;
195
196
  const pageOffset = Math.max((page - 1) * pageSize, 0);
196
- const rootComments = comments
197
- .filter(({ rid }) => !rid)
198
- .slice(pageOffset, pageOffset + pageSize);
197
+ const rootComments = [
198
+ ...comments.filter(({ rid, sticky }) => !rid && sticky),
199
+ ...comments.filter(({ rid, sticky }) => !rid && !sticky),
200
+ ].slice(pageOffset, pageOffset + pageSize);
199
201
 
200
202
  return this.json({
201
203
  page,
package/src/logic/base.js CHANGED
@@ -45,16 +45,21 @@ module.exports = class extends think.Logic {
45
45
  { email: userMail },
46
46
  { field: ['email', 'url', 'display_name', 'type', 'github', 'avatar'] }
47
47
  );
48
- if (!think.isEmpty(user)) {
49
- const userInfo = user[0];
50
- userInfo.mailMd5 = helper.md5(userInfo.email);
51
- if (/(github)/i.test(userInfo.avatar)) {
52
- userInfo.avatar =
53
- this.config('avatarProxy') +
54
- '?url=' +
55
- encodeURIComponent(userInfo.avatar);
56
- }
57
- this.ctx.state.userInfo = userInfo;
48
+ if (think.isEmpty(user)) {
49
+ return;
50
+ }
51
+
52
+ const userInfo = user[0];
53
+ userInfo.mailMd5 = helper.md5(userInfo.mail);
54
+
55
+ let avatarUrl = userInfo.avatar
56
+ ? userInfo.avatar
57
+ : `https://seccdn.libravatar.org/avatar/${userInfo.mailMd5}`;
58
+ const { avatarProxy } = think.config();
59
+ if (avatarProxy) {
60
+ avatarUrl = avatarProxy + '?url=' + encodeURIComponent(avatarUrl);
58
61
  }
62
+ userInfo.avatar = avatarUrl;
63
+ this.ctx.state.userInfo = userInfo;
59
64
  }
60
65
  };
@@ -21,6 +21,96 @@ module.exports = class extends Base {
21
21
  }
22
22
  }
23
23
 
24
+ /**
25
+ * @api {GET} /comment Get comment list for client
26
+ * @apiGroup Comment
27
+ * @apiVersion 0.0.1
28
+ *
29
+ * @apiParam {String} path comment url path
30
+ * @apiParam {String} page page
31
+ * @apiParam {String} pagesize page size
32
+ *
33
+ * @apiSuccess (200) {Number} page return current comments list page
34
+ * @apiSuccess (200) {Number} pageSize to return error message if error
35
+ * @apiSuccess (200) {Object[]} data comments list
36
+ * @apiSuccess (200) {String} data.nick comment user nick name
37
+ * @apiSuccess (200) {String} data.mail comment user mail md5
38
+ * @apiSuccess (200) {String} data.link comment user link
39
+ * @apiSuccess (200) {String} data.objectId comment id
40
+ * @apiSuccess (200) {String} data.browser comment user browser
41
+ * @apiSuccess (200) {String} data.os comment user os
42
+ * @apiSuccess (200) {String} data.insertedAt comment created time
43
+ * @apiSuccess (200) {String} data.avatar comment user avatar
44
+ * @apiSuccess (200) {String} data.type comment login user type
45
+ * @apiSuccess (200) {Object[]} data.children children comments list
46
+ * @apiSuccess (200) {String} data.children.nick comment user nick name
47
+ * @apiSuccess (200) {String} data.children.mail comment user mail md5
48
+ * @apiSuccess (200) {String} data.children.link comment user link
49
+ * @apiSuccess (200) {String} data.children.objectId comment id
50
+ * @apiSuccess (200) {String} data.children.browser comment user browser
51
+ * @apiSuccess (200) {String} data.children.os comment user os
52
+ * @apiSuccess (200) {String} data.children.insertedAt comment created time
53
+ * @apiSuccess (200) {String} data.children.avatar comment user avatar
54
+ * @apiSuccess (200) {String} data.children.type comment login user type
55
+ */
56
+ /**
57
+ * @api {GET} /comment?type=list Get comment list for admin
58
+ * @apiGroup Comment
59
+ * @apiVersion 0.0.1
60
+ *
61
+ * @apiParam {String} page page
62
+ * @apiParam {String} pagesize page size
63
+ *
64
+ * @apiSuccess (200) {Number} errno 0
65
+ * @apiSuccess (200) {String} errmsg return error message if error
66
+ * @apiSuccess (200) {Object} data
67
+ * @apiSuccess (200) {Number} data.page comments list current page
68
+ * @apiSuccess (200) {Number} data.pageSize comments list page size
69
+ * @apiSuccess (200) {Number} data.totalPages comments list total pages
70
+ * @apiSuccess (200) {Number} data.spamCount spam comments count
71
+ * @apiSuccess (200) {Number} data.waitingCount waiting comments count
72
+ * @apiSuccess (200) {Object[]} data.data comments list data
73
+ * @apiSuccess (200) {String} data.data.ip comment user ip address
74
+ * @apiSuccess (200) {String} data.data.nick comment user nick name
75
+ * @apiSuccess (200) {String} data.data.mail comment user mail md5
76
+ * @apiSuccess (200) {String} data.data.link comment user link
77
+ * @apiSuccess (200) {String} data.data.objectId comment id
78
+ * @apiSuccess (200) {String} data.data.status comment status, approved, waiting or spam
79
+ * @apiSuccess (200) {String} data.data.ua comment user agent
80
+ * @apiSuccess (200) {String} data.data.insertedAt comment created time
81
+ * @apiSuccess (200) {String} data.data.avatar comment user avatar
82
+ * @apiSuccess (200) {String} data.data.url comment article link
83
+ */
84
+ /**
85
+ * @api {GET} /comment?type=count Get comment count for articles
86
+ * @apiGroup Comment
87
+ * @apiVersion 0.0.1
88
+ *
89
+ * @apiParam {String} url a array string join by comma just like `a` or `a,b`
90
+ *
91
+ * @apiSuccessExample {Number} Single Path Response:
92
+ * 300
93
+ * @apiSuccessExample {Number} Multiple Path Response:
94
+ * [300, 100]
95
+ */
96
+ /**
97
+ * @api {GET} /comment?type=recent Get recent comments
98
+ * @apiGroup Comment
99
+ * @apiVersion 0.0.1
100
+ *
101
+ * @apiParam {String} count return comments number, default value is 10
102
+ *
103
+ * @apiSuccess (200) {Object[]} response
104
+ * @apiSuccess (200) {String} response.nick comment user nick name
105
+ * @apiSuccess (200) {String} response.mail comment user mail md5
106
+ * @apiSuccess (200) {String} response.link comment user link
107
+ * @apiSuccess (200) {String} response.objectId comment id
108
+ * @apiSuccess (200) {String} response.browser comment user browser
109
+ * @apiSuccess (200) {String} response.os comment user os
110
+ * @apiSuccess (200) {String} response.insertedAt comment created time
111
+ * @apiSuccess (200) {String} response.avatar comment user avatar
112
+ * @apiSuccess (200) {String} response.type comment login user type
113
+ */
24
114
  getAction() {
25
115
  const { type } = this.get();
26
116
  switch (type) {
@@ -79,6 +169,34 @@ module.exports = class extends Base {
79
169
  }
80
170
  }
81
171
 
172
+ /**
173
+ * @api {POST} /comment post comment
174
+ * @apiGroup Comment
175
+ * @apiVersion 0.0.1
176
+ *
177
+ * @apiParam {String} nick post comment user nick name
178
+ * @apiParam {String} mail post comment user mail address
179
+ * @apiParam {String} link post comment user link
180
+ * @apiParam {String} comment post comment text
181
+ * @apiParam {String} url the artcile url path of comment
182
+ * @apiParam {String} ua browser user agent
183
+ * @apiParam {String} pid parent comment id
184
+ * @apiParam {String} rid root comment id
185
+ * @apiParam {String} at parent comment user nick name
186
+ *
187
+ * @apiSuccess (200) {Number} errno 0
188
+ * @apiSuccess (200) {String} errmsg return error message if error
189
+ * @apiSuccess (200) {Object} data return comment data
190
+ * @apiSuccess (200) {String} data.nick comment user nick name
191
+ * @apiSuccess (200) {String} data.mail comment user mail md5
192
+ * @apiSuccess (200) {String} data.link comment user link
193
+ * @apiSuccess (200) {String} data.objectId comment id
194
+ * @apiSuccess (200) {String} data.browser comment user browser
195
+ * @apiSuccess (200) {String} data.os comment user os
196
+ * @apiSuccess (200) {String} data.insertedAt comment created time
197
+ * @apiSuccess (200) {String} data.avatar comment user avatar
198
+ * @apiSuccess (200) {String} data.type comment login user type
199
+ */
82
200
  postAction() {
83
201
  const { LOGIN } = process.env;
84
202
  const { userInfo } = this.ctx.state;
@@ -1,3 +1,10 @@
1
1
  const Base = require('./base');
2
2
 
3
- module.exports = class extends Base {};
3
+ module.exports = class extends Base {
4
+ /**
5
+ * @api {GET} /oauth/github github oauth api
6
+ * @apiGroup OAuth
7
+ * @apiVersion 0.0.1
8
+ */
9
+ githubAction() {}
10
+ };
@@ -1,3 +1,46 @@
1
1
  const Base = require('./base');
2
2
 
3
- module.exports = class extends Base {};
3
+ module.exports = class extends Base {
4
+ /**
5
+ * @api {GET} /token get login user info
6
+ * @apiGroup User
7
+ * @apiVersion 0.0.1
8
+ *
9
+ * @apiSuccess (200) {Number} errno 0
10
+ * @apiSuccess (200) {String} errmsg return error message if error
11
+ * @apiSuccess (200) {Object} data user info
12
+ * @apiSuccess (200) {String} data.avatar user avatar
13
+ * @apiSuccess (200) {String} data.createdAt user register time
14
+ * @apiSuccess (200) {String} data.display_name user nick name
15
+ * @apiSuccess (200) {String} data.emal user email address
16
+ * @apiSuccess (200) {String} data.github user github account name
17
+ * @apiSuccess (200) {String} data.mailMd5 user mail md5
18
+ * @apiSuccess (200) {String} data.objectId user id
19
+ * @apiSuccess (200) {String} data.type user type, administrator or guest
20
+ * @apiSuccess (200) {String} data.url user link
21
+ */
22
+ getAction() {}
23
+
24
+ /**
25
+ * @api {POST} /token user login
26
+ * @apiGroup User
27
+ * @apiVersion 0.0.1
28
+ *
29
+ * @apiParam {String} email login user email
30
+ * @apiParam {String} password login user password
31
+ *
32
+ * @apiSuccess (200) {Number} errno 0
33
+ * @apiSuccess (200) {String} errmsg return error message if error
34
+ */
35
+ postAction() {}
36
+
37
+ /**
38
+ * @api {DELETE} /token user logout
39
+ * @apiGroup User
40
+ * @apiVersion 0.0.1
41
+ *
42
+ * @apiSuccess (200) {Number} errno 0
43
+ * @apiSuccess (200) {String} errmsg return error message if error
44
+ */
45
+ deleteAction() {}
46
+ };
package/src/logic/user.js CHANGED
@@ -1,6 +1,34 @@
1
1
  const Base = require('./base');
2
2
 
3
3
  module.exports = class extends Base {
4
+ /**
5
+ * @api {POST} /user user register
6
+ * @apiGroup User
7
+ * @apiVersion 0.0.1
8
+ *
9
+ * @apiParam {String} display_name user nick name
10
+ * @apiParam {String} email user email
11
+ * @apiParam {String} password user password
12
+ * @apiParam {String} url user link
13
+ *
14
+ * @apiSuccess (200) {Number} errno 0
15
+ * @apiSuccess (200) {String} errmsg return error message if error
16
+ */
17
+ postAction() {}
18
+
19
+ /**
20
+ * @api {PUT} /user update user profile
21
+ * @apiGroup User
22
+ * @apiVersion 0.0.1
23
+ *
24
+ * @apiParam {String} display_name user new nick name
25
+ * @apiParam {String} url user new link
26
+ * @apiParam {String} password user new password
27
+ * @apiParam {String} github user github account name
28
+ *
29
+ * @apiSuccess (200) {Number} errno 0
30
+ * @apiSuccess (200) {String} errmsg return error message if error
31
+ */
4
32
  putAction() {
5
33
  const { userInfo } = this.ctx.state;
6
34
  if (think.isEmpty(userInfo)) {
@@ -119,9 +119,6 @@ module.exports = class extends think.Service {
119
119
  `💬 {{site.name|safe}} 有新评论啦
120
120
  {{self.nick}} 评论道:
121
121
  {{self.comment}}
122
- 邮箱:{{self.mail}}
123
- 状态:{{self.status}}
124
- 评论页面:{{self.url}}
125
122
  仅供预览评论,请前往上述页面查看完整內容。`;
126
123
 
127
124
  return request({