@waline/vercel 1.26.3 → 1.26.4

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 (60) hide show
  1. package/dist/404.html +39 -0
  2. package/dist/500.html +275 -0
  3. package/dist/index.js +58501 -0
  4. package/dist/package.json +54 -0
  5. package/dist/src/config/adapter.js +170 -0
  6. package/dist/src/config/config.js +134 -0
  7. package/dist/src/config/extend.js +38 -0
  8. package/dist/src/config/middleware.js +66 -0
  9. package/dist/src/config/router.js +1 -0
  10. package/dist/src/controller/article.js +91 -0
  11. package/dist/src/controller/comment.js +758 -0
  12. package/dist/src/controller/db.js +71 -0
  13. package/dist/src/controller/index.js +36 -0
  14. package/dist/src/controller/oauth.js +136 -0
  15. package/dist/src/controller/rest.js +60 -0
  16. package/dist/src/controller/token/2fa.js +66 -0
  17. package/dist/src/controller/token.js +75 -0
  18. package/dist/src/controller/user/password.js +52 -0
  19. package/dist/src/controller/user.js +289 -0
  20. package/dist/src/controller/verification.js +35 -0
  21. package/dist/src/extend/controller.js +25 -0
  22. package/dist/src/extend/think.js +84 -0
  23. package/dist/src/locales/en.json +19 -0
  24. package/dist/src/locales/index.js +12 -0
  25. package/dist/src/locales/zh-CN.json +19 -0
  26. package/dist/src/locales/zh-TW.json +19 -0
  27. package/dist/src/logic/article.js +27 -0
  28. package/dist/src/logic/base.js +164 -0
  29. package/dist/src/logic/comment.js +317 -0
  30. package/dist/src/logic/db.js +81 -0
  31. package/dist/src/logic/oauth.js +10 -0
  32. package/dist/src/logic/token/2fa.js +28 -0
  33. package/dist/src/logic/token.js +53 -0
  34. package/dist/src/logic/user/password.js +11 -0
  35. package/dist/src/logic/user.js +117 -0
  36. package/dist/src/middleware/dashboard.js +23 -0
  37. package/dist/src/middleware/version.js +6 -0
  38. package/dist/src/service/akismet.js +41 -0
  39. package/dist/src/service/avatar.js +35 -0
  40. package/dist/src/service/markdown/highlight.js +32 -0
  41. package/dist/src/service/markdown/index.js +63 -0
  42. package/dist/src/service/markdown/katex.js +49 -0
  43. package/dist/src/service/markdown/mathCommon.js +156 -0
  44. package/dist/src/service/markdown/mathjax.js +78 -0
  45. package/dist/src/service/markdown/utils.js +11 -0
  46. package/dist/src/service/markdown/xss.js +44 -0
  47. package/dist/src/service/notify.js +537 -0
  48. package/dist/src/service/storage/base.js +31 -0
  49. package/dist/src/service/storage/cloudbase.js +221 -0
  50. package/dist/src/service/storage/deta.js +307 -0
  51. package/dist/src/service/storage/github.js +377 -0
  52. package/dist/src/service/storage/leancloud.js +430 -0
  53. package/dist/src/service/storage/mongodb.js +179 -0
  54. package/dist/src/service/storage/mysql.js +123 -0
  55. package/dist/src/service/storage/postgresql.js +84 -0
  56. package/dist/src/service/storage/sqlite.js +11 -0
  57. package/dist/src/service/storage/tidb.js +3 -0
  58. package/package.json +1 -1
  59. package/src/controller/comment.js +1 -2
  60. package/src/extend/think.js +19 -0
@@ -0,0 +1,164 @@
1
+ const path = require('path');
2
+ const qs = require('querystring');
3
+ const fetch = require('node-fetch');
4
+ const jwt = require('jsonwebtoken');
5
+ const helper = require('think-helper');
6
+
7
+ module.exports = class extends think.Logic {
8
+ constructor(...args) {
9
+ super(...args);
10
+ this.modelInstance = this.service(
11
+ `storage/${this.config('storage')}`,
12
+ 'Users'
13
+ );
14
+ this.resource = this.getResource();
15
+ this.id = this.getId();
16
+ }
17
+
18
+ async __before() {
19
+ const referrer = this.ctx.referrer(true);
20
+ let { secureDomains } = this.config();
21
+
22
+ if (secureDomains && referrer && this.ctx.host.indexOf(referrer) !== 0) {
23
+ secureDomains = think.isArray(secureDomains)
24
+ ? secureDomains
25
+ : [secureDomains];
26
+ secureDomains.push(
27
+ 'localhost',
28
+ '127.0.0.1',
29
+ 'github.com',
30
+ 'api.twitter.com',
31
+ 'www.facebook.com'
32
+ );
33
+
34
+ const match = secureDomains.some((domain) =>
35
+ think.isFunction(domain.test)
36
+ ? domain.test(referrer)
37
+ : domain === referrer
38
+ );
39
+
40
+ if (!match) {
41
+ return this.ctx.throw(403);
42
+ }
43
+ }
44
+
45
+ this.ctx.state.userInfo = {};
46
+ const { authorization } = this.ctx.req.headers;
47
+ const { state } = this.get();
48
+
49
+ if (!authorization && !state) {
50
+ return;
51
+ }
52
+ const token = state || authorization.replace(/^Bearer /, '');
53
+ let userMail = '';
54
+
55
+ try {
56
+ userMail = jwt.verify(token, think.config('jwtKey'));
57
+ } catch (e) {
58
+ think.logger.debug(e);
59
+ }
60
+
61
+ if (think.isEmpty(userMail) || !think.isString(userMail)) {
62
+ return;
63
+ }
64
+
65
+ const user = await this.modelInstance.select(
66
+ { email: userMail },
67
+ {
68
+ field: [
69
+ 'id',
70
+ 'email',
71
+ 'url',
72
+ 'display_name',
73
+ 'type',
74
+ 'github',
75
+ 'twitter',
76
+ 'facebook',
77
+ 'google',
78
+ 'weibo',
79
+ 'qq',
80
+ 'avatar',
81
+ '2fa',
82
+ 'label',
83
+ ],
84
+ }
85
+ );
86
+
87
+ if (think.isEmpty(user)) {
88
+ return;
89
+ }
90
+
91
+ const userInfo = user[0];
92
+
93
+ let avatarUrl = userInfo.avatar
94
+ ? userInfo.avatar
95
+ : await think.service('avatar').stringify({
96
+ mail: userInfo.email,
97
+ nick: userInfo.display_name,
98
+ link: userInfo.url,
99
+ });
100
+ const { avatarProxy } = think.config();
101
+
102
+ if (avatarProxy) {
103
+ avatarUrl = avatarProxy + '?url=' + encodeURIComponent(avatarUrl);
104
+ }
105
+ userInfo.avatar = avatarUrl;
106
+ userInfo.mailMd5 = helper.md5(userInfo.email);
107
+ this.ctx.state.userInfo = userInfo;
108
+ this.ctx.state.token = token;
109
+ }
110
+
111
+ getResource() {
112
+ const filename = this.__filename || __filename;
113
+ const last = filename.lastIndexOf(path.sep);
114
+
115
+ return filename.substr(last + 1, filename.length - last - 4);
116
+ }
117
+
118
+ getId() {
119
+ const id = this.get('id');
120
+
121
+ if (id && (think.isString(id) || think.isNumber(id))) {
122
+ return id;
123
+ }
124
+
125
+ const last = decodeURIComponent(this.ctx.path.split('/').pop());
126
+
127
+ if (last !== this.resource && /^([a-z0-9]+,?)*$/i.test(last)) {
128
+ return last;
129
+ }
130
+
131
+ return '';
132
+ }
133
+
134
+ async useCaptchaCheck() {
135
+ const { RECAPTCHA_V3_SECRET } = process.env;
136
+
137
+ if (!RECAPTCHA_V3_SECRET) {
138
+ return;
139
+ }
140
+ const { recaptchaV3 } = this.post();
141
+
142
+ if (!recaptchaV3) {
143
+ return this.ctx.throw(403);
144
+ }
145
+
146
+ const query = qs.stringify({
147
+ secret: RECAPTCHA_V3_SECRET,
148
+ response: recaptchaV3,
149
+ remoteip: this.ctx.ip,
150
+ });
151
+ const recaptchaV3Result = await fetch(
152
+ `https://recaptcha.net/recaptcha/api/siteverify?${query}`
153
+ ).then((resp) => resp.json());
154
+
155
+ if (!recaptchaV3Result.success) {
156
+ think.logger.debug(
157
+ 'RecaptchaV3 Result:',
158
+ JSON.stringify(recaptchaV3Result, null, '\t')
159
+ );
160
+
161
+ return this.ctx.throw(403);
162
+ }
163
+ }
164
+ };
@@ -0,0 +1,317 @@
1
+ const Base = require('./base');
2
+
3
+ module.exports = class extends Base {
4
+ checkAdmin() {
5
+ const { userInfo } = this.ctx.state;
6
+
7
+ if (think.isEmpty(userInfo)) {
8
+ return this.ctx.throw(401);
9
+ }
10
+
11
+ if (userInfo.type !== 'administrator') {
12
+ return this.ctx.throw(403);
13
+ }
14
+ }
15
+
16
+ /**
17
+ * @api {GET} /comment Get comment list for client
18
+ * @apiGroup Comment
19
+ * @apiVersion 0.0.1
20
+ *
21
+ * @apiParam {String} path comment url path
22
+ * @apiParam {String} page page
23
+ * @apiParam {String} pageSize page size
24
+ * @apiParam {String} sortBy comment sort type, one of 'insertedAt_desc', 'insertedAt_asc', 'like_desc'
25
+ * @apiParam {String} lang language
26
+ *
27
+ * @apiSuccess (200) {Number} page return current comments list page
28
+ * @apiSuccess (200) {Number} pageSize to return error message if error
29
+ * @apiSuccess (200) {Object[]} data comments list
30
+ * @apiSuccess (200) {String} data.nick comment user nick name
31
+ * @apiSuccess (200) {String} data.mail comment user mail md5
32
+ * @apiSuccess (200) {String} data.link comment user link
33
+ * @apiSuccess (200) {String} data.objectId comment id
34
+ * @apiSuccess (200) {String} data.browser comment user browser
35
+ * @apiSuccess (200) {String} data.os comment user os
36
+ * @apiSuccess (200) {String} data.insertedAt comment created time
37
+ * @apiSuccess (200) {String} data.avatar comment user avatar
38
+ * @apiSuccess (200) {String} data.type comment login user type
39
+ * @apiSuccess (200) {Object[]} data.children children comments list
40
+ * @apiSuccess (200) {String} data.children.nick comment user nick name
41
+ * @apiSuccess (200) {String} data.children.mail comment user mail md5
42
+ * @apiSuccess (200) {String} data.children.link comment user link
43
+ * @apiSuccess (200) {String} data.children.objectId comment id
44
+ * @apiSuccess (200) {String} data.children.browser comment user browser
45
+ * @apiSuccess (200) {String} data.children.os comment user os
46
+ * @apiSuccess (200) {String} data.children.insertedAt comment created time
47
+ * @apiSuccess (200) {String} data.children.avatar comment user avatar
48
+ * @apiSuccess (200) {String} data.children.type comment login user type
49
+ */
50
+ /**
51
+ * @api {GET} /comment?type=list Get comment list for admin
52
+ * @apiGroup Comment
53
+ * @apiVersion 0.0.1
54
+ *
55
+ * @apiParam {String} page page
56
+ * @apiParam {String} pageSize page size
57
+ * @apiParam {String} lang language
58
+ *
59
+ * @apiSuccess (200) {Number} errno 0
60
+ * @apiSuccess (200) {String} errmsg return error message if error
61
+ * @apiSuccess (200) {Object} data
62
+ * @apiSuccess (200) {Number} data.page comments list current page
63
+ * @apiSuccess (200) {Number} data.pageSize comments list page size
64
+ * @apiSuccess (200) {Number} data.totalPages comments list total pages
65
+ * @apiSuccess (200) {Number} data.spamCount spam comments count
66
+ * @apiSuccess (200) {Number} data.waitingCount waiting comments count
67
+ * @apiSuccess (200) {Object[]} data.data comments list data
68
+ * @apiSuccess (200) {String} data.data.ip comment user ip address
69
+ * @apiSuccess (200) {String} data.data.nick comment user nick name
70
+ * @apiSuccess (200) {String} data.data.mail comment user mail md5
71
+ * @apiSuccess (200) {String} data.data.link comment user link
72
+ * @apiSuccess (200) {String} data.data.objectId comment id
73
+ * @apiSuccess (200) {String} data.data.status comment status, approved, waiting or spam
74
+ * @apiSuccess (200) {String} data.data.ua comment user agent
75
+ * @apiSuccess (200) {String} data.data.insertedAt comment created time
76
+ * @apiSuccess (200) {String} data.data.avatar comment user avatar
77
+ * @apiSuccess (200) {String} data.data.url comment article link
78
+ */
79
+ /**
80
+ * @api {GET} /comment?type=count Get comment count for articles
81
+ * @apiGroup Comment
82
+ * @apiVersion 0.0.1
83
+ *
84
+ * @apiParam {String} url a array string join by comma just like `a` or `a,b`, return site comment count if url empty
85
+ * @apiParam {String} lang language
86
+ *
87
+ * @apiSuccessExample {Number} Single Path Response:
88
+ * 300
89
+ * @apiSuccessExample {Number} Multiple Path Response:
90
+ * [300, 100]
91
+ */
92
+ /**
93
+ * @api {GET} /comment?type=recent Get recent comments
94
+ * @apiGroup Comment
95
+ * @apiVersion 0.0.1
96
+ *
97
+ * @apiParam {String} count return comments number, default value is 10
98
+ * @apiParam {String} lang language
99
+ *
100
+ * @apiSuccess (200) {Object[]} response
101
+ * @apiSuccess (200) {String} response.nick comment user nick name
102
+ * @apiSuccess (200) {String} response.mail comment user mail md5
103
+ * @apiSuccess (200) {String} response.link comment user link
104
+ * @apiSuccess (200) {String} response.objectId comment id
105
+ * @apiSuccess (200) {String} response.browser comment user browser
106
+ * @apiSuccess (200) {String} response.os comment user os
107
+ * @apiSuccess (200) {String} response.insertedAt comment created time
108
+ * @apiSuccess (200) {String} response.avatar comment user avatar
109
+ * @apiSuccess (200) {String} response.type comment login user type
110
+ */
111
+ getAction() {
112
+ const { type, path } = this.get();
113
+ const isAllowedGet = type !== 'list' || path;
114
+
115
+ if (!isAllowedGet) {
116
+ this.checkAdmin();
117
+ }
118
+
119
+ switch (type) {
120
+ case 'recent':
121
+ this.rules = {
122
+ count: {
123
+ int: { max: 50 },
124
+ default: 10,
125
+ },
126
+ };
127
+ break;
128
+
129
+ case 'count':
130
+ this.rules = {
131
+ url: {
132
+ array: true,
133
+ },
134
+ };
135
+ break;
136
+
137
+ case 'list': {
138
+ const { userInfo } = this.ctx.state;
139
+
140
+ if (userInfo.type !== 'administrator') {
141
+ return this.fail();
142
+ }
143
+ this.rules = {
144
+ page: {
145
+ int: true,
146
+ default: 1,
147
+ },
148
+ pageSize: {
149
+ int: { max: 100 },
150
+ default: 10,
151
+ },
152
+ };
153
+ break;
154
+ }
155
+
156
+ default:
157
+ this.rules = {
158
+ path: {
159
+ string: true,
160
+ required: true,
161
+ },
162
+ page: {
163
+ int: true,
164
+ default: 1,
165
+ },
166
+ pageSize: {
167
+ int: { max: 100 },
168
+ default: 10,
169
+ },
170
+ sortBy: {
171
+ in: ['insertedAt_desc', 'insertedAt_asc', 'like_desc'],
172
+ default: 'insertedAt_desc',
173
+ },
174
+ };
175
+ break;
176
+ }
177
+ }
178
+
179
+ /**
180
+ * @api {POST} /comment post comment
181
+ * @apiGroup Comment
182
+ * @apiVersion 0.0.1
183
+ *
184
+ * @apiParam {String} nick post comment user nick name
185
+ * @apiParam {String} mail post comment user mail address
186
+ * @apiParam {String} link post comment user link
187
+ * @apiParam {String} comment post comment text
188
+ * @apiParam {String} url the article url path of comment
189
+ * @apiParam {String} ua browser user agent
190
+ * @apiParam {String} pid parent comment id
191
+ * @apiParam {String} rid root comment id
192
+ * @apiParam {String} at parent comment user nick name
193
+ * @apiParam {String} lang language
194
+ *
195
+ * @apiSuccess (200) {Number} errno 0
196
+ * @apiSuccess (200) {String} errmsg return error message if error
197
+ * @apiSuccess (200) {Object} data return comment data
198
+ * @apiSuccess (200) {String} data.nick comment user nick name
199
+ * @apiSuccess (200) {String} data.mail comment user mail md5
200
+ * @apiSuccess (200) {String} data.link comment user link
201
+ * @apiSuccess (200) {String} data.objectId comment id
202
+ * @apiSuccess (200) {String} data.browser comment user browser
203
+ * @apiSuccess (200) {String} data.os comment user os
204
+ * @apiSuccess (200) {String} data.insertedAt comment created time
205
+ * @apiSuccess (200) {String} data.avatar comment user avatar
206
+ * @apiSuccess (200) {String} data.type comment login user type
207
+ */
208
+ async postAction() {
209
+ const { LOGIN } = process.env;
210
+ const { userInfo } = this.ctx.state;
211
+
212
+ if (!think.isEmpty(userInfo)) {
213
+ return;
214
+ }
215
+
216
+ if (LOGIN === 'force') {
217
+ return this.ctx.throw(401);
218
+ }
219
+
220
+ return this.useCaptchaCheck();
221
+ }
222
+
223
+ /**
224
+ * @api {PUT} /comment/:id update comment data
225
+ * @apiGroup Comment
226
+ * @apiVersion 0.0.1
227
+ *
228
+ * @apiParam {String} [nick] post comment user nick name
229
+ * @apiParam {String} [mail] post comment user mail address
230
+ * @apiParam {String} [link] post comment user link
231
+ * @apiParam {String} [comment] post comment text
232
+ * @apiParam {String} [url] the article url path of comment
233
+ * @apiParam {Boolean} [like] like comment
234
+ * @apiParam {String} lang language
235
+ *
236
+ * @apiSuccess (200) {Number} errno 0
237
+ * @apiSuccess (200) {String} errmsg return error message if error
238
+ */
239
+ async putAction() {
240
+ const { userInfo } = this.ctx.state;
241
+ const { like } = this.post();
242
+
243
+ // 1. like
244
+ if (think.isEmpty(userInfo) && think.isBoolean(like)) {
245
+ this.rules = {
246
+ like: {
247
+ required: true,
248
+ boolean: true,
249
+ },
250
+ };
251
+
252
+ return;
253
+ }
254
+
255
+ if (think.isEmpty(userInfo)) {
256
+ return this.ctx.throw(401);
257
+ }
258
+
259
+ // 2. administrator
260
+ if (userInfo.type === 'administrator') {
261
+ return;
262
+ }
263
+
264
+ // 3. comment author modify comment content
265
+ const modelInstance = this.service(
266
+ `storage/${this.config('storage')}`,
267
+ 'Comment'
268
+ );
269
+ const commentData = await modelInstance.select({
270
+ user_id: userInfo.objectId,
271
+ objectId: this.id,
272
+ });
273
+
274
+ if (!think.isEmpty(commentData)) {
275
+ return;
276
+ }
277
+
278
+ return this.ctx.throw(403);
279
+ }
280
+
281
+ /**
282
+ * @api {DELETE} /comment/:id delete comment
283
+ * @apiGroup Comment
284
+ * @apiVersion 0.0.1
285
+ *
286
+ * @apiParam {String} lang language
287
+ *
288
+ * @apiSuccess (200) {Number} errno 0
289
+ * @apiSuccess (200) {String} errmsg return error message if error
290
+ */
291
+ async deleteAction() {
292
+ const { userInfo } = this.ctx.state;
293
+
294
+ if (think.isEmpty(userInfo)) {
295
+ return this.ctx.throw(401);
296
+ }
297
+
298
+ if (userInfo.type === 'administrator') {
299
+ return;
300
+ }
301
+
302
+ const modelInstance = this.service(
303
+ `storage/${this.config('storage')}`,
304
+ 'Comment'
305
+ );
306
+ const commentData = await modelInstance.select({
307
+ user_id: userInfo.objectId,
308
+ objectId: this.id,
309
+ });
310
+
311
+ if (!think.isEmpty(commentData)) {
312
+ return;
313
+ }
314
+
315
+ return this.ctx.throw(403);
316
+ }
317
+ };
@@ -0,0 +1,81 @@
1
+ const Base = require('./base');
2
+
3
+ module.exports = class extends Base {
4
+ async __before(...args) {
5
+ await super.__before(...args);
6
+
7
+ const { userInfo } = this.ctx.state;
8
+
9
+ if (think.isEmpty(userInfo)) {
10
+ return this.fail(401);
11
+ }
12
+
13
+ if (userInfo.type !== 'administrator') {
14
+ return this.fail(403);
15
+ }
16
+ }
17
+
18
+ /**
19
+ * @api {GET} /db export site data
20
+ * @apiGroup Site
21
+ * @apiVersion 0.0.1
22
+ *
23
+ * @apiParam {String} lang language
24
+ */
25
+ async getAction() {}
26
+
27
+ /**
28
+ * @api {POST} /db import site data
29
+ * @apiGroup Site
30
+ * @apiVersion 0.0.1
31
+ *
32
+ * @apiParam {String} lang language
33
+ */
34
+ async postAction() {
35
+ this.rules = {
36
+ table: {
37
+ string: true,
38
+ required: true,
39
+ method: 'GET',
40
+ },
41
+ };
42
+ }
43
+
44
+ /**
45
+ * @api {PUT} /db update site table data
46
+ * @apiGroup Site
47
+ * @apiVersion 0.0.1
48
+ *
49
+ * @apiParam {String} lang language
50
+ */
51
+ async putAction() {
52
+ this.rules = {
53
+ table: {
54
+ string: true,
55
+ required: true,
56
+ method: 'GET',
57
+ },
58
+ objectId: {
59
+ required: true,
60
+ method: 'GET',
61
+ },
62
+ };
63
+ }
64
+
65
+ /**
66
+ * @api {DELETE} /db clean site data
67
+ * @apiGroup Site
68
+ * @apiVersion 0.0.1
69
+ *
70
+ * @apiParam {String} lang language
71
+ */
72
+ async deleteAction() {
73
+ this.rules = {
74
+ table: {
75
+ string: true,
76
+ required: true,
77
+ method: 'GET',
78
+ },
79
+ };
80
+ }
81
+ };
@@ -0,0 +1,10 @@
1
+ const Base = require('./base');
2
+
3
+ module.exports = class extends Base {
4
+ /**
5
+ * @api {GET} /oauth oauth api
6
+ * @apiGroup OAuth
7
+ * @apiVersion 0.0.1
8
+ */
9
+ indexAction() {}
10
+ };
@@ -0,0 +1,28 @@
1
+ const Base = require('../base');
2
+
3
+ module.exports = class extends Base {
4
+ async getAction() {
5
+ const { email } = this.get();
6
+ const { userInfo } = this.ctx.state;
7
+
8
+ if (think.isEmpty(userInfo) && !email) {
9
+ return this.fail(401);
10
+ }
11
+ }
12
+
13
+ async postAction() {
14
+ const { userInfo } = this.ctx.state;
15
+
16
+ if (think.isEmpty(userInfo)) {
17
+ return this.fail(401);
18
+ }
19
+
20
+ this.rules = {
21
+ code: {
22
+ required: true,
23
+ string: true,
24
+ length: 6,
25
+ },
26
+ };
27
+ }
28
+ };
@@ -0,0 +1,53 @@
1
+ const Base = require('./base');
2
+
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
+ * @apiParam {String} lang language
10
+ *
11
+ * @apiSuccess (200) {Number} errno 0
12
+ * @apiSuccess (200) {String} errmsg return error message if error
13
+ * @apiSuccess (200) {Object} data user info
14
+ * @apiSuccess (200) {String} data.avatar user avatar
15
+ * @apiSuccess (200) {String} data.createdAt user register time
16
+ * @apiSuccess (200) {String} data.display_name user nick name
17
+ * @apiSuccess (200) {String} data.email user email address
18
+ * @apiSuccess (200) {String} data.github user github account name
19
+ * @apiSuccess (200) {String} data.mailMd5 user mail md5
20
+ * @apiSuccess (200) {String} data.objectId user id
21
+ * @apiSuccess (200) {String} data.type user type, administrator or guest
22
+ * @apiSuccess (200) {String} data.url user link
23
+ */
24
+ getAction() {}
25
+
26
+ /**
27
+ * @api {POST} /token user login
28
+ * @apiGroup User
29
+ * @apiVersion 0.0.1
30
+ *
31
+ * @apiParam {String} email login user email
32
+ * @apiParam {String} password login user password
33
+ * @apiParam {String} lang language
34
+ *
35
+ * @apiSuccess (200) {Number} errno 0
36
+ * @apiSuccess (200) {String} errmsg return error message if error
37
+ */
38
+ postAction() {
39
+ return this.useCaptchaCheck();
40
+ }
41
+
42
+ /**
43
+ * @api {DELETE} /token user logout
44
+ * @apiGroup User
45
+ * @apiVersion 0.0.1
46
+ *
47
+ * @apiParam {String} lang language
48
+ *
49
+ * @apiSuccess (200) {Number} errno 0
50
+ * @apiSuccess (200) {String} errmsg return error message if error
51
+ */
52
+ deleteAction() {}
53
+ };
@@ -0,0 +1,11 @@
1
+ const Base = require('../base');
2
+
3
+ module.exports = class extends Base {
4
+ async putAction() {
5
+ this.rules = {
6
+ email: {
7
+ required: true,
8
+ },
9
+ };
10
+ }
11
+ };