@waline/vercel 1.18.6 → 1.18.9
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 +7 -7
- package/src/config/adapter.js +14 -0
- package/src/config/config.js +1 -1
- package/src/controller/db.js +26 -2
- package/src/controller/user/password.js +1 -1
- package/src/controller/user.js +1 -1
- package/src/extend/think.js +1 -1
- package/src/locales/en.json +2 -2
- package/src/locales/zh-CN.json +2 -2
- package/src/locales/zh-TW.json +2 -2
- package/src/logic/base.js +9 -0
- package/src/service/storage/postgresql.js +29 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waline/vercel",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.9",
|
|
4
4
|
"description": "vercel server for waline comment system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"waline",
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"dompurify": "2.3.8",
|
|
23
23
|
"dy-node-ip2region": "1.0.1",
|
|
24
24
|
"fast-csv": "4.3.6",
|
|
25
|
-
"jsdom": "
|
|
25
|
+
"jsdom": "20.0.0",
|
|
26
26
|
"jsonwebtoken": "8.5.1",
|
|
27
|
-
"katex": "0.
|
|
28
|
-
"leancloud-storage": "4.12.
|
|
27
|
+
"katex": "0.16.0",
|
|
28
|
+
"leancloud-storage": "4.12.3",
|
|
29
29
|
"markdown-it": "13.0.1",
|
|
30
30
|
"markdown-it-emoji": "2.0.2",
|
|
31
31
|
"markdown-it-sub": "1.0.0",
|
|
32
32
|
"markdown-it-sup": "1.0.0",
|
|
33
|
-
"mathjax-full": "3.2.
|
|
34
|
-
"nodemailer": "6.7.
|
|
33
|
+
"mathjax-full": "3.2.2",
|
|
34
|
+
"nodemailer": "6.7.6",
|
|
35
35
|
"nunjucks": "3.2.3",
|
|
36
36
|
"phpass": "0.1.1",
|
|
37
37
|
"prismjs": "1.28.0",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"think-logger3": "1.3.1",
|
|
43
43
|
"think-model": "1.5.4",
|
|
44
44
|
"think-model-mysql": "1.1.7",
|
|
45
|
-
"think-model-postgresql": "1.1.
|
|
45
|
+
"think-model-postgresql": "1.1.7",
|
|
46
46
|
"think-model-sqlite": "1.2.3",
|
|
47
47
|
"think-mongo": "2.2.1",
|
|
48
48
|
"think-router-rest": "1.0.5",
|
package/src/config/adapter.js
CHANGED
|
@@ -18,6 +18,7 @@ const {
|
|
|
18
18
|
MYSQL_PASSWORD,
|
|
19
19
|
MYSQL_PREFIX,
|
|
20
20
|
MYSQL_CHARSET,
|
|
21
|
+
MYSQL_SSL,
|
|
21
22
|
SQLITE_PATH,
|
|
22
23
|
SQLITE_DB,
|
|
23
24
|
SQLITE_PREFIX,
|
|
@@ -27,6 +28,7 @@ const {
|
|
|
27
28
|
PG_PORT,
|
|
28
29
|
PG_PREFIX,
|
|
29
30
|
PG_USER,
|
|
31
|
+
PG_SSL,
|
|
30
32
|
MONGO_AUTHSOURCE,
|
|
31
33
|
MONGO_DB,
|
|
32
34
|
MONGO_HOST,
|
|
@@ -93,6 +95,12 @@ exports.model = {
|
|
|
93
95
|
port: PG_PORT || '3211',
|
|
94
96
|
connectionLimit: 1,
|
|
95
97
|
prefix: PG_PREFIX || 'wl_',
|
|
98
|
+
ssl:
|
|
99
|
+
PG_SSL == 'true'
|
|
100
|
+
? {
|
|
101
|
+
rejectUnauthorized: false,
|
|
102
|
+
}
|
|
103
|
+
: null,
|
|
96
104
|
},
|
|
97
105
|
|
|
98
106
|
sqlite: {
|
|
@@ -113,6 +121,12 @@ exports.model = {
|
|
|
113
121
|
password: MYSQL_PASSWORD,
|
|
114
122
|
prefix: MYSQL_PREFIX || 'wl_',
|
|
115
123
|
charset: MYSQL_CHARSET || 'utf8mb4',
|
|
124
|
+
ssl:
|
|
125
|
+
MYSQL_SSL === 'true'
|
|
126
|
+
? {
|
|
127
|
+
rejectUnauthorized: false,
|
|
128
|
+
}
|
|
129
|
+
: null,
|
|
116
130
|
},
|
|
117
131
|
};
|
|
118
132
|
|
package/src/config/config.js
CHANGED
package/src/controller/db.js
CHANGED
|
@@ -3,6 +3,24 @@ const util = require('util');
|
|
|
3
3
|
const BaseRest = require('./rest');
|
|
4
4
|
|
|
5
5
|
const readFileAsync = util.promisify(fs.readFile);
|
|
6
|
+
|
|
7
|
+
function formatID(data, idGenerator) {
|
|
8
|
+
const objectIdMap = {};
|
|
9
|
+
for (let i = 0; i < data.length; i++) {
|
|
10
|
+
const { objectId } = data[i];
|
|
11
|
+
objectIdMap[objectId] = idGenerator(data[i], i, data);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
for (let i = 0; i < data.length; i++) {
|
|
15
|
+
['objectId', 'pid', 'rid']
|
|
16
|
+
.filter((k) => data[i][k])
|
|
17
|
+
.forEach((k) => {
|
|
18
|
+
data[i][k] = objectIdMap[data[i][k]];
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
6
24
|
module.exports = class extends BaseRest {
|
|
7
25
|
async getAction() {
|
|
8
26
|
const exportData = {
|
|
@@ -43,11 +61,17 @@ module.exports = class extends BaseRest {
|
|
|
43
61
|
const storage = this.config('storage');
|
|
44
62
|
const model = this.service(`storage/${storage}`, tableName);
|
|
45
63
|
|
|
64
|
+
let data = importData.data[tableName];
|
|
65
|
+
if (['postgresql', 'mysql', 'sqlite'].includes(storage)) {
|
|
66
|
+
let i = 0;
|
|
67
|
+
data = formatID(data, () => (i = i + 1));
|
|
68
|
+
}
|
|
69
|
+
|
|
46
70
|
// delete all data at first
|
|
47
71
|
await model.delete({});
|
|
48
72
|
// then add data one by one
|
|
49
|
-
for (let j = 0; j <
|
|
50
|
-
await model.add(
|
|
73
|
+
for (let j = 0; j < data.length; j++) {
|
|
74
|
+
await model.add(data[j]);
|
|
51
75
|
}
|
|
52
76
|
}
|
|
53
77
|
return this.success();
|
|
@@ -36,7 +36,7 @@ module.exports = class extends BaseRest {
|
|
|
36
36
|
? `"${SENDER_NAME}" <${SENDER_EMAIL}>`
|
|
37
37
|
: SMTP_USER,
|
|
38
38
|
to: user[0].email,
|
|
39
|
-
subject: this.locale('[{{name}}] Reset Password', {
|
|
39
|
+
subject: this.locale('[{{name | safe}}] Reset Password', {
|
|
40
40
|
name: SITE_NAME || 'Waline',
|
|
41
41
|
}),
|
|
42
42
|
html: this.locale(
|
package/src/controller/user.js
CHANGED
|
@@ -89,7 +89,7 @@ module.exports = class extends BaseRest {
|
|
|
89
89
|
? `"${SENDER_NAME}" <${SENDER_EMAIL}>`
|
|
90
90
|
: SMTP_USER,
|
|
91
91
|
to: data.email,
|
|
92
|
-
subject: this.locale('[{{name}}] Registration Confirm Mail', {
|
|
92
|
+
subject: this.locale('[{{name | safe}}] Registration Confirm Mail', {
|
|
93
93
|
name: SITE_NAME || 'Waline',
|
|
94
94
|
}),
|
|
95
95
|
html: this.locale(
|
package/src/extend/think.js
CHANGED
package/src/locales/en.json
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"USER_REGISTED": "USER_REGISTED",
|
|
6
6
|
"TOKEN_EXPIRED": "TOKEN_EXPIRED",
|
|
7
7
|
"TWO_FACTOR_AUTH_ERROR_DETAIL": "TWO_FACTOR_AUTH_ERROR_DETAIL",
|
|
8
|
-
"[{{name}}] Registration Confirm Mail": "[{{name}}] Registration Confirm Mail",
|
|
8
|
+
"[{{name | safe}}] Registration Confirm Mail": "[{{name | safe}}] Registration Confirm Mail",
|
|
9
9
|
"Please click <a href=\"{{url}}\">{{url}}<a/> to confirm registration, the link is valid for 1 hour. If you are not registering, please ignore this email.": "Please click <a href=\"{{url}}\">{{url}}<a/> to confirm registration, the link is valid for 1 hour. If you are not registering, please ignore this email.",
|
|
10
|
-
"[{{name}}] Reset Password": "[{{name}}] Reset Password",
|
|
10
|
+
"[{{name | safe}}] Reset Password": "[{{name | safe}}] Reset Password",
|
|
11
11
|
"Please click <a href=\"{{url}}\">{{url}}</a> to login and change your password as soon as possible!": "Please click <a href=\"{{url}}\">{{url}}</a> to login and change your password as soon as possible!",
|
|
12
12
|
"Duplicate Content": "Duplicate Content",
|
|
13
13
|
"Comment too fast": "Comment too fast",
|
package/src/locales/zh-CN.json
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"USER_REGISTED": "用户已注册",
|
|
6
6
|
"TOKEN_EXPIRED": "密钥已过期",
|
|
7
7
|
"TWO_FACTOR_AUTH_ERROR_DETAIL": "二步验证失败",
|
|
8
|
-
"[{{name}}] Registration Confirm Mail": "【{{name}}】注册确认邮件",
|
|
8
|
+
"[{{name | safe}}] Registration Confirm Mail": "【{{name | safe}}】注册确认邮件",
|
|
9
9
|
"Please click <a href=\"{{url}}\">{{url}}<a/> to confirm registration, the link is valid for 1 hour. If you are not registering, please ignore this email.": "请点击 <a href=\"{{url}}\">{{url}}</a> 确认注册,链接有效时间为 1 个小时。如果不是你在注册,请忽略这封邮件。",
|
|
10
|
-
"[{{name}}] Reset Password": "【{{name}}】重置密码",
|
|
10
|
+
"[{{name | safe}}] Reset Password": "【{{name | safe}}】重置密码",
|
|
11
11
|
"Please click <a href=\"{{url}}\">{{url}}</a> to login and change your password as soon as possible!": "请尽快点击链接 <a href=\"{{url}}\">{{url}}</a> 登录并修改你的密码!",
|
|
12
12
|
"Duplicate Content": "发送的内容之前已经发过",
|
|
13
13
|
"Comment too fast": "评论太快啦,请慢点!",
|
package/src/locales/zh-TW.json
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"USER_REGISTED": "用戶已註冊",
|
|
6
6
|
"TOKEN_EXPIRED": "密鑰已過期",
|
|
7
7
|
"TWO_FACTOR_AUTH_ERROR_DETAIL": "二步驗證失敗",
|
|
8
|
-
"[{{name}}] Registration Confirm Mail": "『{{name}}』註冊確認郵件",
|
|
8
|
+
"[{{name | safe}}] Registration Confirm Mail": "『{{name | safe}}』註冊確認郵件",
|
|
9
9
|
"Please click <a href=\"{{url}}\">{{url}}<a/> to confirm registration, the link is valid for 1 hour. If you are not registering, please ignore this email.": "請點擊 <a href=\"{{url}}\">{{url}}</a> 確認註冊,鏈接有效時間為 1 個小時。如果不是你在註冊,請忽略這封郵件。",
|
|
10
|
-
"[{{name}}] Reset Password": "『{{name}}』重置密碼",
|
|
10
|
+
"[{{name | safe}}] Reset Password": "『{{name | safe}}』重置密碼",
|
|
11
11
|
"Please click <a href=\"{{url}}\">{{url}}</a> to login and change your password as soon as possible!": "請盡快點擊鏈接 <a href=\"{{url}}\">{{url}}</a> 登錄並修改你的密碼!",
|
|
12
12
|
"Duplicate Content": "發送的內容之前已經發過",
|
|
13
13
|
"Comment too fast": "評論太快啦,請慢點!",
|
package/src/logic/base.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const path = require('path');
|
|
1
2
|
const jwt = require('jsonwebtoken');
|
|
2
3
|
const helper = require('think-helper');
|
|
3
4
|
|
|
@@ -8,6 +9,7 @@ module.exports = class extends think.Logic {
|
|
|
8
9
|
`storage/${this.config('storage')}`,
|
|
9
10
|
'Users'
|
|
10
11
|
);
|
|
12
|
+
this.resource = this.getResource();
|
|
11
13
|
this.id = this.getId();
|
|
12
14
|
}
|
|
13
15
|
|
|
@@ -92,6 +94,13 @@ module.exports = class extends think.Logic {
|
|
|
92
94
|
this.ctx.state.token = token;
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
getResource() {
|
|
98
|
+
const filename = this.__filename || __filename;
|
|
99
|
+
const last = filename.lastIndexOf(path.sep);
|
|
100
|
+
|
|
101
|
+
return filename.substr(last + 1, filename.length - last - 4);
|
|
102
|
+
}
|
|
103
|
+
|
|
95
104
|
getId() {
|
|
96
105
|
const id = this.get('id');
|
|
97
106
|
|
|
@@ -5,8 +5,21 @@ module.exports = class extends MySQL {
|
|
|
5
5
|
return super.model(tableName.toLowerCase());
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
async select(
|
|
9
|
-
const
|
|
8
|
+
async select(where, options = {}) {
|
|
9
|
+
const lowerWhere = {};
|
|
10
|
+
for (const i in where) {
|
|
11
|
+
lowerWhere[i.toLowerCase()] = where[i];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (options && options.desc) {
|
|
15
|
+
options.desc = options.desc.toLowerCase();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (Array.isArray(options.field)) {
|
|
19
|
+
options.field = options.field.map((field) => field.toLowerCase());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const data = await super.select(where, options);
|
|
10
23
|
return data.map(({ insertedat, createdat, updatedat, ...item }) => {
|
|
11
24
|
const mapFields = {
|
|
12
25
|
insertedAt: insertedat,
|
|
@@ -23,6 +36,20 @@ module.exports = class extends MySQL {
|
|
|
23
36
|
});
|
|
24
37
|
}
|
|
25
38
|
|
|
39
|
+
async add(data) {
|
|
40
|
+
['insertedAt', 'createdAt', 'updatedAt']
|
|
41
|
+
.filter((key) => data[key])
|
|
42
|
+
.forEach((key) => {
|
|
43
|
+
const val = data[key];
|
|
44
|
+
data[key.toLowerCase()] =
|
|
45
|
+
val instanceof Date
|
|
46
|
+
? think.datetime(val, 'YYYY-MM-DD HH:mm:ss')
|
|
47
|
+
: val;
|
|
48
|
+
delete data[key];
|
|
49
|
+
});
|
|
50
|
+
return super.add(data);
|
|
51
|
+
}
|
|
52
|
+
|
|
26
53
|
async count(...args) {
|
|
27
54
|
let result = await super.count(...args);
|
|
28
55
|
try {
|