@waline/vercel 1.3.0 → 1.4.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/package.json +2 -1
- package/src/config/config.js +4 -0
- package/src/controller/oauth.js +14 -6
- package/src/controller/user.js +8 -4
- package/src/logic/base.js +1 -0
- package/src/logic/oauth.js +2 -2
- package/src/service/storage/inspirecloud.js +151 -0
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waline/vercel",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "vercel server for waline comment system",
|
|
5
5
|
"repository": "https://github.com/walinejs/waline",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "lizheming <i@imnerd.org>",
|
|
8
8
|
"dependencies": {
|
|
9
|
+
"@byteinspire/api": "^1.0.12",
|
|
9
10
|
"@cloudbase/node-sdk": "^2.7.1",
|
|
10
11
|
"@koa/cors": "^3.1.0",
|
|
11
12
|
"akismet": "^2.0.6",
|
package/src/config/config.js
CHANGED
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
AVATAR_PROXY,
|
|
18
18
|
GITHUB_TOKEN,
|
|
19
19
|
DETA_PROJECT_KEY,
|
|
20
|
+
INSPIRECLOUD_SERVICE_SECRET,
|
|
20
21
|
OAUTH_URL,
|
|
21
22
|
|
|
22
23
|
MARKDOWN_CONFIG = '{}',
|
|
@@ -62,6 +63,9 @@ if (LEAN_KEY) {
|
|
|
62
63
|
} else if (DETA_PROJECT_KEY) {
|
|
63
64
|
storage = 'deta';
|
|
64
65
|
jwtKey = jwtKey || DETA_PROJECT_KEY;
|
|
66
|
+
} else if (INSPIRECLOUD_SERVICE_SECRET) {
|
|
67
|
+
storage = 'inspirecloud';
|
|
68
|
+
jwtKey = jwtKey || INSPIRECLOUD_SERVICE_SECRET;
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
if (think.env === 'cloudbase' && storage === 'sqlite') {
|
package/src/controller/oauth.js
CHANGED
|
@@ -12,31 +12,39 @@ module.exports = class extends think.Controller {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
async indexAction() {
|
|
15
|
-
const { code, type, redirect } = this.get();
|
|
15
|
+
const { code, oauth_verifier, oauth_token, type, redirect } = this.get();
|
|
16
16
|
const { oauthUrl } = this.config();
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const hasCode =
|
|
19
|
+
type === 'twitter' ? oauth_token && oauth_verifier : Boolean(code);
|
|
20
|
+
if (!hasCode) {
|
|
19
21
|
const { protocol, host } = this.ctx;
|
|
20
22
|
const redirectUrl = `${protocol}://${host}/oauth?${qs.stringify({
|
|
21
23
|
redirect,
|
|
22
24
|
type,
|
|
23
25
|
})}`;
|
|
24
26
|
return this.redirect(
|
|
25
|
-
`${oauthUrl}/${type}?${qs.stringify({
|
|
27
|
+
`${oauthUrl}/${type}?${qs.stringify({
|
|
28
|
+
redirect: redirectUrl,
|
|
29
|
+
state: this.ctx.state.token,
|
|
30
|
+
})}`
|
|
26
31
|
);
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
/**
|
|
30
35
|
* user = { id, name, email, avatar,url };
|
|
31
36
|
*/
|
|
32
|
-
const params = { code };
|
|
37
|
+
const params = { code, oauth_verifier, oauth_token };
|
|
33
38
|
if (type === 'facebook') {
|
|
34
39
|
const { protocol, host } = this.ctx;
|
|
35
40
|
const redirectUrl = `${protocol}://${host}/oauth?${qs.stringify({
|
|
36
41
|
redirect,
|
|
37
42
|
type,
|
|
38
43
|
})}`;
|
|
39
|
-
params.state = qs.stringify({
|
|
44
|
+
params.state = qs.stringify({
|
|
45
|
+
redirect: redirectUrl,
|
|
46
|
+
state: this.ctx.state.token || '',
|
|
47
|
+
});
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
const user = await request({
|
|
@@ -81,7 +89,7 @@ module.exports = class extends think.Controller {
|
|
|
81
89
|
objectId: current.objectId,
|
|
82
90
|
});
|
|
83
91
|
|
|
84
|
-
return this.
|
|
92
|
+
return this.redirect('/ui/profile');
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
const userByEmail = await this.modelInstance.select({ email: user.email });
|
package/src/controller/user.js
CHANGED
|
@@ -78,7 +78,7 @@ module.exports = class extends BaseRest {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
async putAction() {
|
|
81
|
-
const { display_name, url, password
|
|
81
|
+
const { display_name, url, password } = this.post();
|
|
82
82
|
const { objectId } = this.ctx.state.userInfo;
|
|
83
83
|
|
|
84
84
|
const updateData = {};
|
|
@@ -95,9 +95,13 @@ module.exports = class extends BaseRest {
|
|
|
95
95
|
updateData.password = new PasswordHash().hashPassword(password);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
const socials = ['github', 'twitter', 'facebook', 'google', 'weibo', 'qq'];
|
|
99
|
+
socials.forEach((social) => {
|
|
100
|
+
const nextSocial = this.post(social);
|
|
101
|
+
if (think.isString(nextSocial)) {
|
|
102
|
+
updateData[social] = nextSocial;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
101
105
|
|
|
102
106
|
if (think.isEmpty(updateData)) {
|
|
103
107
|
return this.success();
|
package/src/logic/base.js
CHANGED
package/src/logic/oauth.js
CHANGED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const inspirecloud = require('@byteinspire/api');
|
|
2
|
+
const Base = require('./base');
|
|
3
|
+
|
|
4
|
+
module.exports = class extends Base {
|
|
5
|
+
constructor(tableName) {
|
|
6
|
+
super(tableName);
|
|
7
|
+
this.db = inspirecloud.db;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
where(where) {
|
|
11
|
+
if (think.isEmpty(where)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const _where = {};
|
|
16
|
+
const parseKey = (k) => (k === 'objectId' ? '_id' : k);
|
|
17
|
+
for (const k in where) {
|
|
18
|
+
if (think.isString(where[k])) {
|
|
19
|
+
_where[parseKey(k)] = k === 'objectId' ? this.db.ObjectId(where[k]) : where[k];
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (where[k] === undefined) {
|
|
23
|
+
_where[parseKey(k)] = undefined;
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(where[k])) {
|
|
26
|
+
if (where[k][0]) {
|
|
27
|
+
const handler = where[k][0].toUpperCase();
|
|
28
|
+
switch (handler) {
|
|
29
|
+
case 'IN':
|
|
30
|
+
_where[parseKey(k)] = this.db.in(
|
|
31
|
+
k === 'objectId'
|
|
32
|
+
? where[k][1].map(this.db.ObjectId)
|
|
33
|
+
: where[k][1]
|
|
34
|
+
);
|
|
35
|
+
break;
|
|
36
|
+
case 'NOT IN':
|
|
37
|
+
_where[parseKey(k)] = this.db.nin(
|
|
38
|
+
k === 'objectId'
|
|
39
|
+
? where[k][1].map(this.db.ObjectId)
|
|
40
|
+
: where[k][1]
|
|
41
|
+
);
|
|
42
|
+
break;
|
|
43
|
+
case 'LIKE': {
|
|
44
|
+
const first = where[k][1][0];
|
|
45
|
+
const last = where[k][1].slice(-1);
|
|
46
|
+
let reg;
|
|
47
|
+
if (first === '%' && last === '%') {
|
|
48
|
+
reg = new RegExp(where[k][1].slice(1, -1));
|
|
49
|
+
} else if (first === '%') {
|
|
50
|
+
reg = new RegExp(where[k][1].slice(1) + '$');
|
|
51
|
+
} else if (last === '%') {
|
|
52
|
+
reg = new RegExp('^' + where[k][1].slice(0, -1));
|
|
53
|
+
}
|
|
54
|
+
_where[parseKey(k)] = this.db.regex(reg);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case '!=':
|
|
58
|
+
_where[parseKey(k)] = this.db.ne(where[k]);
|
|
59
|
+
break;
|
|
60
|
+
case '>':
|
|
61
|
+
_where[parseKey(k)] = this.db.gt(where[k]);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return _where;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async _select(where, { desc, limit, offset, field } = {}) {
|
|
72
|
+
const instance = this.db.table(this.tableName);
|
|
73
|
+
const query = instance.where(this.where(where));
|
|
74
|
+
|
|
75
|
+
if (desc) {
|
|
76
|
+
query.sort({ [desc]: -1 });
|
|
77
|
+
}
|
|
78
|
+
if (limit) {
|
|
79
|
+
query.limit(limit);
|
|
80
|
+
}
|
|
81
|
+
if (offset) {
|
|
82
|
+
query.skip(offset);
|
|
83
|
+
}
|
|
84
|
+
if (field) {
|
|
85
|
+
const _field = {};
|
|
86
|
+
field.forEach((f) => {
|
|
87
|
+
_field[f] = 1;
|
|
88
|
+
});
|
|
89
|
+
query.projection(_field);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const data = await query.find();
|
|
93
|
+
data.forEach((item) => {
|
|
94
|
+
item.objectId = item._id.toString();
|
|
95
|
+
delete item._id;
|
|
96
|
+
});
|
|
97
|
+
return data;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async select(where, options = {}) {
|
|
101
|
+
let data = [];
|
|
102
|
+
let ret = [];
|
|
103
|
+
do {
|
|
104
|
+
options.offset = (options.offset || 0) + data.length;
|
|
105
|
+
ret = await this._select(where, options);
|
|
106
|
+
data = data.concat(ret);
|
|
107
|
+
} while (ret.length === 1000);
|
|
108
|
+
|
|
109
|
+
return data;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async count(where = {}) {
|
|
113
|
+
const instance = this.db.table(this.tableName);
|
|
114
|
+
const query = instance.where(this.where(where));
|
|
115
|
+
|
|
116
|
+
return query.count();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async add(data) {
|
|
120
|
+
const instance = this.db.table(this.tableName);
|
|
121
|
+
const tableData = instance.create(data);
|
|
122
|
+
await instance.save(tableData);
|
|
123
|
+
|
|
124
|
+
tableData.objectId = tableData._id.toString();
|
|
125
|
+
delete tableData._id;
|
|
126
|
+
return tableData;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async update(data, where) {
|
|
130
|
+
const instance = this.db.table(this.tableName);
|
|
131
|
+
const query = instance.where(this.where(where));
|
|
132
|
+
const items = await query.find();
|
|
133
|
+
|
|
134
|
+
return Promise.all(
|
|
135
|
+
items.map(async (item) => {
|
|
136
|
+
const updateData = typeof data === 'function' ? data(item) : data;
|
|
137
|
+
for (const k in updateData) {
|
|
138
|
+
item[k] = updateData[k];
|
|
139
|
+
}
|
|
140
|
+
await instance.save(item);
|
|
141
|
+
return item;
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async delete(where) {
|
|
147
|
+
const instance = this.db.table(this.tableName);
|
|
148
|
+
const query = instance.where(this.where(where));
|
|
149
|
+
return query.delete();
|
|
150
|
+
}
|
|
151
|
+
};
|