@abtnode/core 1.16.31-beta-4246ab25 → 1.16.31-beta-a0cc72cf
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/lib/blocklet/hooks.js +0 -1
- package/lib/states/user.js +97 -77
- package/lib/util/launcher.js +6 -2
- package/package.json +21 -21
package/lib/blocklet/hooks.js
CHANGED
|
@@ -32,7 +32,6 @@ const runUserHook = async (label, hookName, args) => {
|
|
|
32
32
|
logger.info(`run hook:${hookName}:`, { label, hook });
|
|
33
33
|
|
|
34
34
|
const nodeInfo = await states.node.read();
|
|
35
|
-
// FIXME @linchen timeout 应该动态设置或不设置
|
|
36
35
|
await runScript(hook, [label, hookName].join(':'), {
|
|
37
36
|
cwd: appDir,
|
|
38
37
|
env: {
|
package/lib/states/user.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const cloneDeep = require('lodash/cloneDeep');
|
|
1
2
|
const pickBy = require('lodash/pickBy');
|
|
2
3
|
const get = require('lodash/get');
|
|
3
4
|
const pick = require('lodash/pick');
|
|
@@ -73,7 +74,7 @@ class User extends ExtendBase {
|
|
|
73
74
|
// create user
|
|
74
75
|
await this.insert({
|
|
75
76
|
...user,
|
|
76
|
-
...(await this.
|
|
77
|
+
...(await this._extractInviteInfo(user)),
|
|
77
78
|
sourceProvider: user.sourceProvider || LOGIN_PROVIDER.WALLET,
|
|
78
79
|
approved: !!user.approved,
|
|
79
80
|
});
|
|
@@ -96,12 +97,20 @@ class User extends ExtendBase {
|
|
|
96
97
|
|
|
97
98
|
// FIXME: @wangshijun wrap these in a transaction
|
|
98
99
|
async updateUser(did, updates) {
|
|
99
|
-
const exist = await super.
|
|
100
|
+
const exist = await super.findOne({ did });
|
|
100
101
|
if (!exist) {
|
|
101
102
|
throw new Error(`user does not exist: ${did}`);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
// Allow to update inviter only when inviter is not set
|
|
106
|
+
const pending = cloneDeep(updates);
|
|
107
|
+
if (exist.inviter) {
|
|
108
|
+
delete pending.inviter;
|
|
109
|
+
} else {
|
|
110
|
+
Object.assign(pending, await this._extractInviteInfo({ did, ...pending }));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
await super.update({ did }, { $set: pending });
|
|
105
114
|
await Promise.all(
|
|
106
115
|
(get(updates, 'passports') || [])
|
|
107
116
|
.filter((x) => x.id)
|
|
@@ -187,9 +196,10 @@ class User extends ExtendBase {
|
|
|
187
196
|
/**
|
|
188
197
|
* Get blocklet service user list
|
|
189
198
|
*/
|
|
190
|
-
// eslint-disable-next-line require-await
|
|
191
199
|
async getUsers({ query, sort, paging } = {}) {
|
|
192
200
|
const where = {};
|
|
201
|
+
const replacements = {};
|
|
202
|
+
|
|
193
203
|
const {
|
|
194
204
|
approved,
|
|
195
205
|
role,
|
|
@@ -208,6 +218,11 @@ class User extends ExtendBase {
|
|
|
208
218
|
where.approved = approved;
|
|
209
219
|
}
|
|
210
220
|
|
|
221
|
+
const sorting = pickBy(sort, (x) => !isNullOrUndefined(x));
|
|
222
|
+
if (!Object.keys(sorting).length) {
|
|
223
|
+
sorting.createdAt = -1;
|
|
224
|
+
}
|
|
225
|
+
|
|
211
226
|
if (search) {
|
|
212
227
|
if (search.length > 50) {
|
|
213
228
|
throw new Error('the length of search text should not more than 50');
|
|
@@ -223,44 +238,51 @@ class User extends ExtendBase {
|
|
|
223
238
|
throw new Error('You can not query by inviter and invitee at the same time');
|
|
224
239
|
}
|
|
225
240
|
|
|
226
|
-
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
241
|
+
let total = 0;
|
|
242
|
+
if (!where.did) {
|
|
243
|
+
// handle descendant query
|
|
244
|
+
if (inviter) {
|
|
245
|
+
if (isValid(inviter) === false) {
|
|
246
|
+
throw new Error('inviter did invalid');
|
|
247
|
+
}
|
|
248
|
+
const exist = await this.model.findByPk(toAddress(inviter), { attributes: ['did', 'generation'] });
|
|
249
|
+
if (!exist) {
|
|
250
|
+
throw new Error(`inviter not found: ${inviter}`);
|
|
251
|
+
}
|
|
235
252
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
253
|
+
try {
|
|
254
|
+
const { pageSize: size = 20, page = 1 } = paging || {};
|
|
255
|
+
const pageSize = Math.min(100, size);
|
|
256
|
+
const offset = (page - 1) * pageSize;
|
|
257
|
+
// LIMIT ${pageSize} OFFSET ${offset}
|
|
258
|
+
const subQuery = `
|
|
259
|
+
WITH RECURSIVE UserTree(did,inviter,generation,createdAt) AS (
|
|
260
|
+
SELECT did,inviter,generation,createdAt FROM users WHERE inviter="${exist.did}"
|
|
240
261
|
UNION ALL
|
|
241
|
-
SELECT child.did,child.inviter,child.generation FROM users AS child INNER JOIN UserTree AS parent ON (child.inviter=parent.did)
|
|
262
|
+
SELECT child.did,child.inviter,child.generation,child.createdAt FROM users AS child INNER JOIN UserTree AS parent ON (child.inviter=parent.did) ORDER BY child.createdAt DESC
|
|
242
263
|
)
|
|
243
|
-
SELECT did,inviter,generation FROM UserTree ${generation > 0 ? `WHERE generation=${(exist.generation > 0 ? exist.generation : 0) + generation}` : ''}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
264
|
+
SELECT did,inviter,generation FROM UserTree ${generation > 0 ? `WHERE generation=${(exist.generation > 0 ? exist.generation : 0) + generation}` : ''}`.trim();
|
|
265
|
+
const children = await this.query(subQuery);
|
|
266
|
+
total = children.length;
|
|
267
|
+
where.did = children.slice(offset, offset + pageSize).map((x) => x.did);
|
|
268
|
+
} catch (err) {
|
|
269
|
+
console.error('Failed to get descendants', err);
|
|
270
|
+
where.did = [];
|
|
271
|
+
}
|
|
249
272
|
}
|
|
250
|
-
}
|
|
251
273
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
274
|
+
// handle ancestor query
|
|
275
|
+
if (invitee) {
|
|
276
|
+
if (isValid(invitee) === false) {
|
|
277
|
+
throw new Error('invitee did invalid');
|
|
278
|
+
}
|
|
279
|
+
const exist = await this.model.findByPk(toAddress(invitee), { attributes: ['did', 'generation'] });
|
|
280
|
+
if (!exist) {
|
|
281
|
+
throw new Error(`invitee not found: ${invitee}`);
|
|
282
|
+
}
|
|
261
283
|
|
|
262
|
-
|
|
263
|
-
|
|
284
|
+
try {
|
|
285
|
+
const subQuery = `
|
|
264
286
|
WITH RECURSIVE UserTree(did,inviter,generation) AS (
|
|
265
287
|
SELECT did,inviter,generation FROM users WHERE did="${exist.did}"
|
|
266
288
|
UNION ALL
|
|
@@ -270,39 +292,34 @@ WITH RECURSIVE UserTree(did,inviter,generation) AS (
|
|
|
270
292
|
(SELECT generation FROM users AS parent WHERE parent.did=child.inviter)
|
|
271
293
|
FROM UserTree AS child
|
|
272
294
|
WHERE inviter IS NOT NULL
|
|
273
|
-
LIMIT ${USER_MAX_INVITE_DEPTH}
|
|
274
295
|
)
|
|
275
296
|
SELECT did,inviter,generation FROM UserTree`.trim();
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
297
|
+
const children = await this.query(subQuery);
|
|
298
|
+
where.did = children.map((x) => x.did).filter((x) => x !== exist.did);
|
|
299
|
+
} catch (err) {
|
|
300
|
+
console.error('Failed to get ancestors', err);
|
|
301
|
+
where.did = [];
|
|
302
|
+
}
|
|
281
303
|
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const replacements = {};
|
|
285
304
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
305
|
+
// handle role/status query
|
|
306
|
+
if (role && role !== '$all') {
|
|
307
|
+
replacements.status = PASSPORT_STATUS.VALID;
|
|
308
|
+
if (role === '$none') {
|
|
309
|
+
where.did = {
|
|
310
|
+
[Op.notIn]: Sequelize.literal('(SELECT DISTINCT userDid FROM passports WHERE status = :status)'),
|
|
311
|
+
};
|
|
312
|
+
} else {
|
|
313
|
+
replacements.role = role;
|
|
314
|
+
where.did = {
|
|
315
|
+
[Op.in]: Sequelize.literal(
|
|
316
|
+
'(SELECT DISTINCT userDid FROM passports WHERE name = :role AND status = :status)'
|
|
317
|
+
),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
299
320
|
}
|
|
300
321
|
}
|
|
301
322
|
|
|
302
|
-
const sorting = pickBy(sort, (x) => !isNullOrUndefined(x));
|
|
303
|
-
if (!Object.keys(sorting).length) {
|
|
304
|
-
sorting.createdAt = -1;
|
|
305
|
-
}
|
|
306
323
|
const include = [];
|
|
307
324
|
if (shouldIncludeTag) {
|
|
308
325
|
include.push(this.getTagInclude(tags));
|
|
@@ -325,7 +342,7 @@ SELECT did,inviter,generation FROM UserTree`.trim();
|
|
|
325
342
|
}
|
|
326
343
|
|
|
327
344
|
const result = await this.paginate({ where, include, replacements }, sorting, paging);
|
|
328
|
-
return result;
|
|
345
|
+
return { list: result.list, paging: { ...result.paging, total: total || result.paging.total } };
|
|
329
346
|
}
|
|
330
347
|
|
|
331
348
|
// eslint-disable-next-line require-await
|
|
@@ -490,19 +507,15 @@ SELECT did,inviter,generation FROM UserTree`.trim();
|
|
|
490
507
|
updates.sourceAppPid = null;
|
|
491
508
|
}
|
|
492
509
|
|
|
493
|
-
Object.assign(updates, await this.
|
|
510
|
+
Object.assign(updates, await this._extractInviteInfo(raw));
|
|
494
511
|
|
|
495
512
|
if (exist) {
|
|
496
|
-
// immutable
|
|
497
|
-
if (updates.sourceAppPid) {
|
|
498
|
-
delete updates.sourceAppPid;
|
|
499
|
-
}
|
|
500
|
-
if (updates.inviter) {
|
|
501
|
-
delete updates.inviter;
|
|
502
|
-
delete updates.generation;
|
|
503
|
-
}
|
|
504
|
-
// 登录不再更新 locale
|
|
513
|
+
// immutable fields
|
|
505
514
|
delete updates.locale;
|
|
515
|
+
delete updates.sourceAppPid;
|
|
516
|
+
delete updates.inviter;
|
|
517
|
+
delete updates.generation;
|
|
518
|
+
|
|
506
519
|
// update user, connectedAccount, passport
|
|
507
520
|
updates.connectedAccounts = updateConnectedAccount(exist.connectedAccounts, user.connectedAccount);
|
|
508
521
|
updated = await this.updateUser(exist.did, updates);
|
|
@@ -520,18 +533,25 @@ SELECT did,inviter,generation FROM UserTree`.trim();
|
|
|
520
533
|
return { ...updated, _action: exist ? 'update' : 'add' };
|
|
521
534
|
}
|
|
522
535
|
|
|
523
|
-
async
|
|
536
|
+
async _extractInviteInfo(raw) {
|
|
524
537
|
const info = {};
|
|
525
538
|
|
|
526
|
-
// set inviter and generation
|
|
527
539
|
if (raw.inviter) {
|
|
528
540
|
// sybil-attack
|
|
529
541
|
if (isValid(raw.inviter)) {
|
|
530
542
|
const inviterId = toAddress(raw.inviter);
|
|
531
543
|
const inviter = await this.model.findByPk(inviterId, { attributes: ['did', 'generation'] });
|
|
532
544
|
if (inviter) {
|
|
533
|
-
|
|
534
|
-
|
|
545
|
+
// circle preventing
|
|
546
|
+
const { list: ancestors } = await this.getUsers({ query: { invitee: inviterId } });
|
|
547
|
+
const hasCircle = ancestors.some((x) => x.did === raw.did);
|
|
548
|
+
if (hasCircle) {
|
|
549
|
+
logger.warn('Set inviter result in cycle is not allowed', raw);
|
|
550
|
+
info.inviter = null;
|
|
551
|
+
} else {
|
|
552
|
+
info.inviter = inviterId;
|
|
553
|
+
info.generation = inviter.generation + 1;
|
|
554
|
+
}
|
|
535
555
|
} else {
|
|
536
556
|
logger.warn('Set inviter to non-exist user is not allowed', raw);
|
|
537
557
|
}
|
package/lib/util/launcher.js
CHANGED
|
@@ -357,9 +357,13 @@ const setupAppOwner = async ({ node, sessionId, justCreate = false, context }) =
|
|
|
357
357
|
};
|
|
358
358
|
};
|
|
359
359
|
|
|
360
|
-
const getLauncherSession = async ({ launcherUrl, launcherSessionId, external = true }) => {
|
|
360
|
+
const getLauncherSession = async ({ launcherUrl, launcherSessionId, external = true }, context) => {
|
|
361
361
|
const info = await states.node.read();
|
|
362
|
-
const result = await getLauncherSessionRaw(info.sk, {
|
|
362
|
+
const result = await getLauncherSessionRaw(info.sk, {
|
|
363
|
+
launcherUrl,
|
|
364
|
+
launcherSessionId,
|
|
365
|
+
locale: context?.query?.locale,
|
|
366
|
+
});
|
|
363
367
|
|
|
364
368
|
// strip sensitive data if call from external
|
|
365
369
|
if (external && result.launcherSession) {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.31-beta-
|
|
6
|
+
"version": "1.16.31-beta-a0cc72cf",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.31-beta-
|
|
23
|
-
"@abtnode/auth": "1.16.31-beta-
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.31-beta-
|
|
25
|
-
"@abtnode/constant": "1.16.31-beta-
|
|
26
|
-
"@abtnode/cron": "1.16.31-beta-
|
|
27
|
-
"@abtnode/logger": "1.16.31-beta-
|
|
28
|
-
"@abtnode/models": "1.16.31-beta-
|
|
29
|
-
"@abtnode/queue": "1.16.31-beta-
|
|
30
|
-
"@abtnode/rbac": "1.16.31-beta-
|
|
31
|
-
"@abtnode/router-provider": "1.16.31-beta-
|
|
32
|
-
"@abtnode/static-server": "1.16.31-beta-
|
|
33
|
-
"@abtnode/timemachine": "1.16.31-beta-
|
|
34
|
-
"@abtnode/util": "1.16.31-beta-
|
|
22
|
+
"@abtnode/analytics": "1.16.31-beta-a0cc72cf",
|
|
23
|
+
"@abtnode/auth": "1.16.31-beta-a0cc72cf",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.31-beta-a0cc72cf",
|
|
25
|
+
"@abtnode/constant": "1.16.31-beta-a0cc72cf",
|
|
26
|
+
"@abtnode/cron": "1.16.31-beta-a0cc72cf",
|
|
27
|
+
"@abtnode/logger": "1.16.31-beta-a0cc72cf",
|
|
28
|
+
"@abtnode/models": "1.16.31-beta-a0cc72cf",
|
|
29
|
+
"@abtnode/queue": "1.16.31-beta-a0cc72cf",
|
|
30
|
+
"@abtnode/rbac": "1.16.31-beta-a0cc72cf",
|
|
31
|
+
"@abtnode/router-provider": "1.16.31-beta-a0cc72cf",
|
|
32
|
+
"@abtnode/static-server": "1.16.31-beta-a0cc72cf",
|
|
33
|
+
"@abtnode/timemachine": "1.16.31-beta-a0cc72cf",
|
|
34
|
+
"@abtnode/util": "1.16.31-beta-a0cc72cf",
|
|
35
35
|
"@arcblock/did": "1.18.135",
|
|
36
36
|
"@arcblock/did-auth": "1.18.135",
|
|
37
37
|
"@arcblock/did-ext": "^1.18.135",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
43
43
|
"@arcblock/validator": "^1.18.135",
|
|
44
44
|
"@arcblock/vc": "1.18.135",
|
|
45
|
-
"@blocklet/constant": "1.16.31-beta-
|
|
46
|
-
"@blocklet/env": "1.16.31-beta-
|
|
47
|
-
"@blocklet/meta": "1.16.31-beta-
|
|
48
|
-
"@blocklet/resolver": "1.16.31-beta-
|
|
49
|
-
"@blocklet/sdk": "1.16.31-beta-
|
|
50
|
-
"@blocklet/store": "1.16.31-beta-
|
|
45
|
+
"@blocklet/constant": "1.16.31-beta-a0cc72cf",
|
|
46
|
+
"@blocklet/env": "1.16.31-beta-a0cc72cf",
|
|
47
|
+
"@blocklet/meta": "1.16.31-beta-a0cc72cf",
|
|
48
|
+
"@blocklet/resolver": "1.16.31-beta-a0cc72cf",
|
|
49
|
+
"@blocklet/sdk": "1.16.31-beta-a0cc72cf",
|
|
50
|
+
"@blocklet/store": "1.16.31-beta-a0cc72cf",
|
|
51
51
|
"@did-space/client": "^0.5.31",
|
|
52
52
|
"@fidm/x509": "^1.2.1",
|
|
53
53
|
"@ocap/mcrypto": "1.18.135",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"jest": "^29.7.0",
|
|
104
104
|
"unzipper": "^0.10.11"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "d1eec814979a4086fc5efd7c719687b76c972ec6"
|
|
107
107
|
}
|