@abtnode/blocklet-services 1.16.14-beta-dc99d0a2 → 1.16.14-beta-a90ba909
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/api/libs/connect/session.js +33 -25
- package/api/middlewares/check-federated-cors-call.js +1 -0
- package/api/routes/federated.js +108 -45
- package/api/util/blocklet-utils.js +34 -4
- package/build/asset-manifest.json +15 -15
- package/build/index.html +1 -1
- package/build/service-worker.js +1 -1
- package/build/static/js/{1237.1d0b8f1e.chunk.js → 1237.1018f6da.chunk.js} +3 -3
- package/build/static/js/{3042.c9fe1ced.chunk.js → 3042.0066bb3c.chunk.js} +2 -2
- package/build/static/js/{3162.6bbe08fc.chunk.js → 3162.834ccffb.chunk.js} +3 -3
- package/build/static/js/{4603.ee59facc.chunk.js → 4603.c6657383.chunk.js} +2 -2
- package/build/static/js/5430.090296e0.chunk.js +2 -0
- package/build/static/js/8395.40dc877e.chunk.js +2 -0
- package/build/static/js/main.adfe46cb.js +3 -0
- package/package.json +24 -24
- package/build/static/js/5430.8114614c.chunk.js +0 -2
- package/build/static/js/8395.e5aa519c.chunk.js +0 -2
- package/build/static/js/main.3b4d58d1.js +0 -3
- /package/build/static/js/{1237.1d0b8f1e.chunk.js.LICENSE.txt → 1237.1018f6da.chunk.js.LICENSE.txt} +0 -0
- /package/build/static/js/{3162.6bbe08fc.chunk.js.LICENSE.txt → 3162.834ccffb.chunk.js.LICENSE.txt} +0 -0
- /package/build/static/js/{main.3b4d58d1.js.LICENSE.txt → main.adfe46cb.js.LICENSE.txt} +0 -0
|
@@ -47,15 +47,14 @@ const { isInvitedUserOnly, createTokenFn, getDidConnectVersion } = require('../.
|
|
|
47
47
|
const { transferPassport } = require('../auth/utils');
|
|
48
48
|
const { generateTranslate } = require('../translate');
|
|
49
49
|
const { migrateAccount, declareAccount } = require('../../services/oauth');
|
|
50
|
-
const { getTrustedIssuers, getLoginProvider } = require('../../util/blocklet-utils');
|
|
50
|
+
const { getTrustedIssuers, getLoginProvider, getFederatedTrustedIssuers } = require('../../util/blocklet-utils');
|
|
51
51
|
const { getFederatedMaster, getUserAvatarUrl } = require('../../util/federated');
|
|
52
52
|
const { api } = require('../api');
|
|
53
53
|
|
|
54
54
|
const vcTypes = [VC_TYPE_GENERAL_PASSPORT, VC_TYPE_NODE_PASSPORT];
|
|
55
55
|
|
|
56
|
-
const getPassportVc = async ({ blocklet, claims, challenge, locale }) => {
|
|
57
|
-
const
|
|
58
|
-
const trustedIssuers = [...getBlockletAppIdList(blocklet), ...trustedPassports].filter(Boolean);
|
|
56
|
+
const getPassportVc = async ({ blocklet, claims, challenge, locale, provider }) => {
|
|
57
|
+
const trustedIssuers = await getTrustedIssuers(blocklet, { provider });
|
|
59
58
|
const { vc } = await getVCFromClaims({
|
|
60
59
|
claims,
|
|
61
60
|
challenge,
|
|
@@ -67,7 +66,7 @@ const getPassportVc = async ({ blocklet, claims, challenge, locale }) => {
|
|
|
67
66
|
return vc;
|
|
68
67
|
};
|
|
69
68
|
|
|
70
|
-
const getRoleFromVC = async ({ vc, node, locale, blocklet, teamDid }) => {
|
|
69
|
+
const getRoleFromVC = async ({ vc, node, locale, blocklet, teamDid, provider }) => {
|
|
71
70
|
let role = ROLES.GUEST;
|
|
72
71
|
if (vc) {
|
|
73
72
|
await validatePassport(get(vc, 'credentialSubject.passport'));
|
|
@@ -76,8 +75,12 @@ const getRoleFromVC = async ({ vc, node, locale, blocklet, teamDid }) => {
|
|
|
76
75
|
if (expectedIssuers.includes(actualIssuer)) {
|
|
77
76
|
role = getRoleFromLocalPassport(get(vc, 'credentialSubject.passport'));
|
|
78
77
|
} else {
|
|
78
|
+
// MEMO: 如果是 federated,需要将 actualIssuer 做一个转换
|
|
79
|
+
const actualIssuerList =
|
|
80
|
+
provider === LOGIN_PROVIDER.FEDERATED ? await getFederatedTrustedIssuers(blocklet) : [actualIssuer];
|
|
79
81
|
// map external passport to local role
|
|
80
|
-
const { mappings = [] } =
|
|
82
|
+
const { mappings = [] } =
|
|
83
|
+
(blocklet.trustedPassports || []).find((x) => actualIssuerList.includes(x.issuerDid)) || {};
|
|
81
84
|
role = await getRoleFromExternalPassport({
|
|
82
85
|
passport: get(vc, 'credentialSubject.passport'),
|
|
83
86
|
node,
|
|
@@ -156,7 +159,7 @@ module.exports = {
|
|
|
156
159
|
if (action === 'login') {
|
|
157
160
|
const [invitedUserOnly] = config ? await isInvitedUserOnly(config, node, teamDid) : [false];
|
|
158
161
|
|
|
159
|
-
const trustedIssuers = getTrustedIssuers(blocklet, { provider });
|
|
162
|
+
const trustedIssuers = await getTrustedIssuers(blocklet, { provider });
|
|
160
163
|
claims.verifiableCredential = {
|
|
161
164
|
type: 'verifiableCredential',
|
|
162
165
|
description: messages.requestPassport[locale],
|
|
@@ -242,9 +245,11 @@ module.exports = {
|
|
|
242
245
|
let defaultTtlPolicy = 'never';
|
|
243
246
|
let issuePassport = false;
|
|
244
247
|
|
|
248
|
+
const provider = getLoginProvider(request);
|
|
249
|
+
|
|
245
250
|
// Get passport vc
|
|
246
251
|
if (action === 'login') {
|
|
247
|
-
vc = await getPassportVc({ blocklet, claims, challenge, locale });
|
|
252
|
+
vc = await getPassportVc({ blocklet, claims, challenge, locale, provider });
|
|
248
253
|
[invitedUserOnly, defaultRole, issuePassport] = await isInvitedUserOnly(authConfig, node, teamDid);
|
|
249
254
|
if (invitedUserOnly && !vc) {
|
|
250
255
|
throw new Error(messages.missingCredentialClaim[locale]);
|
|
@@ -317,7 +322,7 @@ module.exports = {
|
|
|
317
322
|
}
|
|
318
323
|
|
|
319
324
|
// Get role
|
|
320
|
-
const role = await getRoleFromVC({ vc, node, locale, blocklet, teamDid });
|
|
325
|
+
const role = await getRoleFromVC({ vc, node, locale, blocklet, teamDid, provider });
|
|
321
326
|
await validateRole({ role, authConfig, locale, node, teamDid });
|
|
322
327
|
|
|
323
328
|
checkAppOwner({ role, blocklet, userDid, locale });
|
|
@@ -333,10 +338,16 @@ module.exports = {
|
|
|
333
338
|
let fullName = user?.fullName;
|
|
334
339
|
// Update profile
|
|
335
340
|
const passportForLog = passport || { name: 'Guest', role: 'guest' };
|
|
336
|
-
|
|
341
|
+
|
|
342
|
+
const masterSite = getFederatedMaster(blocklet);
|
|
343
|
+
let connectAccount = { provider, did: realDid, pk: realPk };
|
|
344
|
+
|
|
337
345
|
let updatedUser;
|
|
338
346
|
if (user) {
|
|
339
347
|
// Update user
|
|
348
|
+
if (masterSite && provider === LOGIN_PROVIDER.FEDERATED) {
|
|
349
|
+
connectAccount = { provider, did: realDid, pk: realPk, id: masterSite.appPid };
|
|
350
|
+
}
|
|
340
351
|
updatedUser = await node.loginUser({
|
|
341
352
|
teamDid,
|
|
342
353
|
user: {
|
|
@@ -345,7 +356,7 @@ module.exports = {
|
|
|
345
356
|
locale,
|
|
346
357
|
passport,
|
|
347
358
|
lastLoginIp: get(request, 'headers[x-real-ip]') || '',
|
|
348
|
-
connectedAccount: [
|
|
359
|
+
connectedAccount: [connectAccount, connectedNft],
|
|
349
360
|
},
|
|
350
361
|
});
|
|
351
362
|
await node.createAuditLog(
|
|
@@ -362,6 +373,10 @@ module.exports = {
|
|
|
362
373
|
const profile = claims.find((x) => x.type === 'profile');
|
|
363
374
|
fullName = profile.fullName;
|
|
364
375
|
|
|
376
|
+
if (masterSite && provider === LOGIN_PROVIDER.FEDERATED) {
|
|
377
|
+
connectAccount = { provider, did: realDid, pk: realPk, id: masterSite.appPid };
|
|
378
|
+
}
|
|
379
|
+
|
|
365
380
|
updatedUser = await node.loginUser({
|
|
366
381
|
teamDid,
|
|
367
382
|
user: {
|
|
@@ -374,14 +389,7 @@ module.exports = {
|
|
|
374
389
|
locale,
|
|
375
390
|
passport,
|
|
376
391
|
lastLoginIp: get(request, 'headers[x-real-ip]') || '',
|
|
377
|
-
connectedAccount: [
|
|
378
|
-
{
|
|
379
|
-
provider,
|
|
380
|
-
did: realDid,
|
|
381
|
-
pk: realPk,
|
|
382
|
-
},
|
|
383
|
-
connectedNft,
|
|
384
|
-
],
|
|
392
|
+
connectedAccount: [connectAccount, connectedNft],
|
|
385
393
|
},
|
|
386
394
|
});
|
|
387
395
|
await node.createAuditLog(
|
|
@@ -422,12 +430,12 @@ module.exports = {
|
|
|
422
430
|
await node.setBlockletInitialized({ did: teamDid, owner: { did: realDid, pk: realPk } });
|
|
423
431
|
}
|
|
424
432
|
|
|
425
|
-
const { permanentWallet } =
|
|
433
|
+
const { permanentWallet } = blockletInfo;
|
|
426
434
|
|
|
427
|
-
const masterSite = getFederatedMaster(blocklet);
|
|
428
435
|
let federatedSessionToken;
|
|
429
436
|
let federatedRefreshToken;
|
|
430
|
-
|
|
437
|
+
// member 使用 deferated login 时,总是会让 Master 自动登录
|
|
438
|
+
if (masterSite && provider === LOGIN_PROVIDER.FEDERATED) {
|
|
431
439
|
const postUser = pick(updatedUser, ['did', 'pk', 'fullName', 'locale']);
|
|
432
440
|
postUser.lastLoginAt = get(request, 'headers[x-real-ip]') || '';
|
|
433
441
|
|
|
@@ -444,7 +452,6 @@ module.exports = {
|
|
|
444
452
|
signer: permanentWallet.address,
|
|
445
453
|
data: signV2(permanentWallet.address, permanentWallet.secretKey, {
|
|
446
454
|
user: postUser,
|
|
447
|
-
appId: blocklet.did,
|
|
448
455
|
passport,
|
|
449
456
|
}),
|
|
450
457
|
}
|
|
@@ -593,7 +600,7 @@ module.exports = {
|
|
|
593
600
|
|
|
594
601
|
const blocklet = await request.getBlocklet();
|
|
595
602
|
const provider = getLoginProvider(request);
|
|
596
|
-
const trustedIssuers = getTrustedIssuers(blocklet, { provider });
|
|
603
|
+
const trustedIssuers = await getTrustedIssuers(blocklet, { provider });
|
|
597
604
|
|
|
598
605
|
return {
|
|
599
606
|
verifiableCredential: {
|
|
@@ -646,6 +653,7 @@ module.exports = {
|
|
|
646
653
|
claims: [verifiableCredential],
|
|
647
654
|
challenge,
|
|
648
655
|
locale,
|
|
656
|
+
provider,
|
|
649
657
|
});
|
|
650
658
|
|
|
651
659
|
// Validate passport required
|
|
@@ -661,7 +669,7 @@ module.exports = {
|
|
|
661
669
|
}
|
|
662
670
|
|
|
663
671
|
// Get role
|
|
664
|
-
const role = await getRoleFromVC({ vc, node, locale, blocklet, teamDid });
|
|
672
|
+
const role = await getRoleFromVC({ vc, node, locale, blocklet, teamDid, provider });
|
|
665
673
|
await validateRole({ role, authConfig, locale, node, teamDid });
|
|
666
674
|
|
|
667
675
|
checkAppOwner({ role, blocklet, userDid, locale });
|
|
@@ -4,6 +4,7 @@ function checkFederatedCorsCall() {
|
|
|
4
4
|
const { blocklet } = req;
|
|
5
5
|
const federated = blocklet.settings.federated || {};
|
|
6
6
|
const sites = federated?.sites || [];
|
|
7
|
+
// TODO: @zhanghan 增加 aliasAppUrl 判断
|
|
7
8
|
if (sites.find((item) => item.appUrl === caller && item.status === 'approved')) {
|
|
8
9
|
next();
|
|
9
10
|
return;
|
package/api/routes/federated.js
CHANGED
|
@@ -3,12 +3,16 @@ const { signV2 } = require('@arcblock/jwt');
|
|
|
3
3
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
4
4
|
const cloneDeep = require('lodash/cloneDeep');
|
|
5
5
|
const get = require('lodash/get');
|
|
6
|
+
const pLimit = require('p-limit');
|
|
7
|
+
const pRetry = require('p-retry');
|
|
6
8
|
|
|
7
9
|
const cors = require('cors');
|
|
8
10
|
const { LOGIN_PROVIDER } = require('@blocklet/constant');
|
|
9
|
-
const pick = require('lodash/pick');
|
|
10
11
|
const { getAvatarByUrl, extractUserAvatar } = require('@abtnode/util/lib/user');
|
|
11
12
|
const { getApplicationInfo } = require('@abtnode/auth/lib/auth');
|
|
13
|
+
const pick = require('lodash/pick');
|
|
14
|
+
const defaults = require('lodash/defaults');
|
|
15
|
+
const remove = require('lodash/remove');
|
|
12
16
|
|
|
13
17
|
const { api } = require('../libs/api');
|
|
14
18
|
const initJwt = require('../libs/jwt');
|
|
@@ -21,6 +25,7 @@ const { getUserAvatarUrl } = require('../util/federated');
|
|
|
21
25
|
const PREFIX = WELLKNOWN_SERVICE_PATH_PREFIX;
|
|
22
26
|
|
|
23
27
|
const prefix = `${PREFIX}/api/federated`;
|
|
28
|
+
const limitSync = pLimit(1);
|
|
24
29
|
|
|
25
30
|
module.exports = {
|
|
26
31
|
preInit(server) {
|
|
@@ -31,18 +36,24 @@ module.exports = {
|
|
|
31
36
|
init(server, node, options) {
|
|
32
37
|
// step 1 申请加入(member 向 master 申请)
|
|
33
38
|
server.post(`${prefix}/join`, ensureBlocklet(), async (req, res) => {
|
|
39
|
+
// master blocklet
|
|
34
40
|
const { blocklet } = req;
|
|
35
41
|
const { site } = req.body;
|
|
36
42
|
|
|
37
|
-
const federated = cloneDeep(blocklet.settings.federated || {})
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
|
|
44
|
+
config: {
|
|
45
|
+
appId: blocklet.appDid,
|
|
46
|
+
appPid: blocklet.appPid,
|
|
47
|
+
},
|
|
48
|
+
sites: [],
|
|
49
|
+
});
|
|
50
|
+
if (federated.sites.length === 0) {
|
|
40
51
|
const nodeInfo = await req.getNodeInfo();
|
|
41
52
|
const blockletInfo = await req.getBlockletInfo();
|
|
42
53
|
const masterSite = {
|
|
43
54
|
appId: blockletInfo.wallet.address,
|
|
44
55
|
appPid: blockletInfo.permanentWallet.address,
|
|
45
|
-
|
|
56
|
+
aliasDid: (blocklet.migratedFrom || []).map((item) => item.appDid),
|
|
46
57
|
appName: blockletInfo.name,
|
|
47
58
|
appDescription: blockletInfo.description,
|
|
48
59
|
appUrl: blockletInfo.appUrl,
|
|
@@ -51,24 +62,17 @@ module.exports = {
|
|
|
51
62
|
normalizePathPrefix(`${WELLKNOWN_SERVICE_PATH_PREFIX}/blocklet/logo`) ||
|
|
52
63
|
'/',
|
|
53
64
|
appLogoRect: blocklet.environmentObj.BLOCKLET_APP_LOGO_RECT,
|
|
54
|
-
did: blockletInfo.
|
|
65
|
+
did: blockletInfo.permanentWallet.address,
|
|
55
66
|
pk: blockletInfo.permanentWallet.publicKey,
|
|
56
67
|
serverId: nodeInfo.did,
|
|
57
68
|
serverVersion: nodeInfo.version,
|
|
58
69
|
version: blocklet.meta.version,
|
|
59
70
|
};
|
|
60
|
-
sites = [masterSite];
|
|
71
|
+
federated.sites = [masterSite];
|
|
61
72
|
}
|
|
62
73
|
|
|
63
|
-
let masterConfig = federated.config;
|
|
64
|
-
if (!masterConfig) {
|
|
65
|
-
masterConfig = {
|
|
66
|
-
appId: blocklet.appDid,
|
|
67
|
-
appPid: blocklet.appPid || blocklet.appDid,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
74
|
if (site) {
|
|
71
|
-
sites.push({
|
|
75
|
+
federated.sites.push({
|
|
72
76
|
...site,
|
|
73
77
|
appliedAt: new Date(),
|
|
74
78
|
status: 'pending',
|
|
@@ -78,36 +82,81 @@ module.exports = {
|
|
|
78
82
|
// member 申请后,将 member 展示在列表中
|
|
79
83
|
// 更新的是自己
|
|
80
84
|
await node.setFederated({
|
|
81
|
-
did: blocklet.
|
|
82
|
-
config:
|
|
83
|
-
config: masterConfig,
|
|
84
|
-
sites,
|
|
85
|
-
},
|
|
85
|
+
did: blocklet.appPid,
|
|
86
|
+
config: federated,
|
|
86
87
|
});
|
|
87
88
|
|
|
88
89
|
// 将新增的数据返回给 member
|
|
89
90
|
res.json({
|
|
90
|
-
sites,
|
|
91
|
+
sites: federated.sites,
|
|
91
92
|
});
|
|
92
93
|
});
|
|
93
94
|
|
|
95
|
+
// member 向 master 请求退出统一登录
|
|
96
|
+
server.post(`${prefix}/quit`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
|
|
97
|
+
const { blocklet } = req;
|
|
98
|
+
const { memberPid } = req.body.verifyData;
|
|
99
|
+
|
|
100
|
+
const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
|
|
101
|
+
config: {
|
|
102
|
+
appId: blocklet.appDid,
|
|
103
|
+
appPid: blocklet.appPid,
|
|
104
|
+
},
|
|
105
|
+
sites: [],
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
remove(federated.sites, (item) => item.appPid === memberPid);
|
|
109
|
+
|
|
110
|
+
const { permanentWallet } = await req.getBlockletInfo();
|
|
111
|
+
const postData = {
|
|
112
|
+
signer: permanentWallet.address,
|
|
113
|
+
data: signV2(permanentWallet.address, permanentWallet.secretKey, { sites: federated.sites }),
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const waitingList = federated.sites
|
|
117
|
+
.filter((item) => item.appId !== federated.config.appId)
|
|
118
|
+
.map((item) => {
|
|
119
|
+
return limitSync(() =>
|
|
120
|
+
pRetry(() => api.post(`${item.appUrl}/${WELLKNOWN_SERVICE_PATH_PREFIX}/api/federated/sync`, postData), {
|
|
121
|
+
retries: 3,
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
await Promise.all(waitingList);
|
|
126
|
+
|
|
127
|
+
await node.setFederated({
|
|
128
|
+
did: blocklet.appPid,
|
|
129
|
+
config: federated,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
res.json({});
|
|
133
|
+
});
|
|
134
|
+
|
|
94
135
|
// step 2 审批(master 申批 member)
|
|
95
136
|
// core/state/lib/blocklet/manager/disk.js -> auditFederatedLogin
|
|
137
|
+
// audit-res 接受 master 的处理结果同步,保存 delegation
|
|
96
138
|
server.post(`${prefix}/audit-res`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
|
|
97
139
|
const { blocklet } = req;
|
|
98
|
-
const { delegation, roles,
|
|
99
|
-
const federated = cloneDeep(blocklet.settings.federated || {})
|
|
140
|
+
const { delegation, roles, masterPid, status } = req.body.verifyData;
|
|
141
|
+
const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
|
|
142
|
+
config: {
|
|
143
|
+
appId: blocklet.appDid,
|
|
144
|
+
appPid: blocklet.appPid,
|
|
145
|
+
isMaster: false,
|
|
146
|
+
},
|
|
147
|
+
sites: [],
|
|
148
|
+
});
|
|
100
149
|
federated.config.delegation = delegation;
|
|
101
150
|
if (status === 'approved') {
|
|
102
151
|
const trustedPassports = blocklet.trustedPassports || [];
|
|
103
|
-
const hasTrustedPassport = trustedPassports.find((item) => item.issuerDid ===
|
|
152
|
+
const hasTrustedPassport = trustedPassports.find((item) => item.issuerDid === masterPid);
|
|
104
153
|
if (!hasTrustedPassport) {
|
|
105
154
|
await node.configTrustedPassports({
|
|
106
|
-
teamDid: blocklet.
|
|
155
|
+
teamDid: blocklet.appPid,
|
|
107
156
|
trustedPassports: [
|
|
108
157
|
...trustedPassports,
|
|
109
158
|
{
|
|
110
|
-
issuerDid:
|
|
159
|
+
issuerDid: masterPid,
|
|
111
160
|
remark: 'Generated on join federated login',
|
|
112
161
|
mappings: roles.map((item) => {
|
|
113
162
|
return {
|
|
@@ -122,7 +171,7 @@ module.exports = {
|
|
|
122
171
|
}
|
|
123
172
|
|
|
124
173
|
await node.setFederated({
|
|
125
|
-
did: blocklet.
|
|
174
|
+
did: blocklet.appPid,
|
|
126
175
|
config: federated,
|
|
127
176
|
});
|
|
128
177
|
res.json(federated);
|
|
@@ -136,7 +185,7 @@ module.exports = {
|
|
|
136
185
|
const federated = cloneDeep(blocklet.settings.federated || {});
|
|
137
186
|
federated.sites = sites;
|
|
138
187
|
await node.setFederated({
|
|
139
|
-
did: blocklet.
|
|
188
|
+
did: blocklet.appPid,
|
|
140
189
|
config: federated,
|
|
141
190
|
});
|
|
142
191
|
res.json(federated);
|
|
@@ -151,7 +200,7 @@ module.exports = {
|
|
|
151
200
|
async (req, res) => {
|
|
152
201
|
const { blocklet } = req;
|
|
153
202
|
|
|
154
|
-
const teamDid = blocklet.
|
|
203
|
+
const teamDid = blocklet.appPid;
|
|
155
204
|
let user = null;
|
|
156
205
|
if (req.user) {
|
|
157
206
|
user = { ...req.user };
|
|
@@ -168,8 +217,8 @@ module.exports = {
|
|
|
168
217
|
}
|
|
169
218
|
const blockletInfo = await req.getBlockletInfo();
|
|
170
219
|
const site = {
|
|
171
|
-
appId:
|
|
172
|
-
appPid:
|
|
220
|
+
appId: blocklet.appDid,
|
|
221
|
+
appPid: blocklet.appPid,
|
|
173
222
|
appName: blockletInfo.name,
|
|
174
223
|
appDescription: blockletInfo.description,
|
|
175
224
|
appUrl: blockletInfo.appUrl,
|
|
@@ -178,7 +227,6 @@ module.exports = {
|
|
|
178
227
|
normalizePathPrefix(`${WELLKNOWN_SERVICE_PATH_PREFIX}/blocklet/logo`) ||
|
|
179
228
|
'/',
|
|
180
229
|
appLogoRect: blocklet.environmentObj.BLOCKLET_APP_LOGO_RECT,
|
|
181
|
-
did: blockletInfo.did,
|
|
182
230
|
};
|
|
183
231
|
res.json({ user, site });
|
|
184
232
|
}
|
|
@@ -201,8 +249,9 @@ module.exports = {
|
|
|
201
249
|
if (!onlyWriteCookie) {
|
|
202
250
|
const { blocklet } = req;
|
|
203
251
|
const { permanentWallet } = await req.getBlockletInfo();
|
|
204
|
-
const teamDid = blocklet.
|
|
252
|
+
const teamDid = blocklet.appPid;
|
|
205
253
|
const federatedSites = blocklet.settings?.federated?.sites || [];
|
|
254
|
+
// TODO: @zhanghan 增加 aliasAppUrl 判断
|
|
206
255
|
const loginSite = federatedSites.find((item) => item.appUrl === req.headers.origin);
|
|
207
256
|
|
|
208
257
|
const currentUser = await node.getUser({
|
|
@@ -229,7 +278,7 @@ module.exports = {
|
|
|
229
278
|
({ data } = await api.post(`${loginSite.appUrl}${prefix}/token`, {
|
|
230
279
|
signer: permanentWallet.address,
|
|
231
280
|
data: signV2(permanentWallet.address, permanentWallet.secretKey, {
|
|
232
|
-
|
|
281
|
+
masterPid: teamDid,
|
|
233
282
|
role: req.user.role,
|
|
234
283
|
user,
|
|
235
284
|
passport: req.user.passport,
|
|
@@ -253,16 +302,17 @@ module.exports = {
|
|
|
253
302
|
|
|
254
303
|
// step 6 发放自动登录 token(master 向 member 发起生成 token 请求)
|
|
255
304
|
server.post(`${prefix}/token`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
|
|
256
|
-
const { user,
|
|
305
|
+
const { user, masterPid, role, passport } = req.body.verifyData;
|
|
257
306
|
const { createSessionToken } = initJwt(node, options);
|
|
258
307
|
const createToken = createTokenFn(createSessionToken);
|
|
259
308
|
const { secret } = await req.getBlockletInfo();
|
|
260
309
|
const { blocklet } = req;
|
|
261
|
-
const teamDid = blocklet.
|
|
310
|
+
const teamDid = blocklet.appPid;
|
|
262
311
|
|
|
263
312
|
const sessionConfig = blocklet.settings?.session || {};
|
|
264
313
|
const trustedPassports = blocklet.trustedPassports || [];
|
|
265
|
-
|
|
314
|
+
// HACK: 这里只对比 pid,因为自动生成的数据只有 master-site 的 pid
|
|
315
|
+
const masterPassport = trustedPassports.find((item) => item.issuerDid === masterPid);
|
|
266
316
|
const findMapping = masterPassport ? masterPassport.mappings.find((item) => item.from.passport === role) : null;
|
|
267
317
|
const targetPassport = findMapping
|
|
268
318
|
? {
|
|
@@ -292,7 +342,7 @@ module.exports = {
|
|
|
292
342
|
// passport: findMapping ? targetPassport : null,
|
|
293
343
|
connectedAccount: {
|
|
294
344
|
provider: LOGIN_PROVIDER.FEDERATED,
|
|
295
|
-
id:
|
|
345
|
+
id: masterPid,
|
|
296
346
|
did: user.did,
|
|
297
347
|
pk: user.pk,
|
|
298
348
|
},
|
|
@@ -329,14 +379,15 @@ module.exports = {
|
|
|
329
379
|
);
|
|
330
380
|
|
|
331
381
|
// member 主动调起 master 登录(实现登录 member 时,自动登录 master)
|
|
382
|
+
// member 传递过来的 user.did 和 user.pk 均为 master-site 与钱包生成的
|
|
332
383
|
|
|
333
384
|
server.post(`${prefix}/loginByMember`, ensureBlocklet(), verifyFederatedCall(), async (req, res) => {
|
|
334
|
-
const { user,
|
|
385
|
+
const { user, passport } = req.body.verifyData;
|
|
335
386
|
const { createSessionToken } = initJwt(node, options);
|
|
336
387
|
const createToken = createTokenFn(createSessionToken);
|
|
337
388
|
const { secret } = await req.getBlockletInfo();
|
|
338
389
|
const { blocklet } = req;
|
|
339
|
-
const teamDid = blocklet.
|
|
390
|
+
const teamDid = blocklet.appPid;
|
|
340
391
|
|
|
341
392
|
const sessionConfig = blocklet.settings?.session || {};
|
|
342
393
|
const prevUser = await node.getUser({
|
|
@@ -348,15 +399,27 @@ module.exports = {
|
|
|
348
399
|
const targetPassport = passport?.id ? (prevUser?.passports || []).find((item) => item.id === passport.id) : null;
|
|
349
400
|
|
|
350
401
|
// HACK: 用户在 master 中存在时,不更新任何用户信息;不存在时,将新增一个用户
|
|
351
|
-
const filterUserInfo = prevUser ?
|
|
352
|
-
|
|
402
|
+
const filterUserInfo = prevUser ? {} : user;
|
|
403
|
+
if (filterUserInfo.avatar) {
|
|
404
|
+
let avatar = await getAvatarByUrl(filterUserInfo.avatar);
|
|
405
|
+
const nodeInfo = await req.getNodeInfo();
|
|
406
|
+
|
|
407
|
+
const { dataDir } = await getApplicationInfo({ node, nodeInfo, teamDid });
|
|
408
|
+
avatar = await extractUserAvatar(avatar, { dataDir });
|
|
409
|
+
filterUserInfo.avatar = avatar;
|
|
410
|
+
}
|
|
411
|
+
const realDid = prevUser?.did || user.did;
|
|
412
|
+
const realPk = prevUser?.pk || user.pk;
|
|
413
|
+
const newUser = await node.loginUser({
|
|
353
414
|
teamDid,
|
|
354
415
|
user: {
|
|
355
416
|
...filterUserInfo,
|
|
417
|
+
did: realDid,
|
|
418
|
+
pk: realPk,
|
|
356
419
|
passport: targetPassport,
|
|
357
420
|
connectedAccount: {
|
|
421
|
+
// member 在使用 federated login 时,本质还是使用 wallet 来登录的,所以对 master-site 来说,登录的 provider 就是 wallet
|
|
358
422
|
provider: LOGIN_PROVIDER.WALLET,
|
|
359
|
-
id: appId,
|
|
360
423
|
did: user.did,
|
|
361
424
|
pk: user.pk,
|
|
362
425
|
},
|
|
@@ -364,12 +427,12 @@ module.exports = {
|
|
|
364
427
|
});
|
|
365
428
|
|
|
366
429
|
const { sessionToken, refreshToken } = createToken(
|
|
367
|
-
|
|
430
|
+
user.did,
|
|
368
431
|
{
|
|
369
432
|
secret,
|
|
370
433
|
passport: targetPassport,
|
|
371
434
|
role: targetPassport?.role || 'guest',
|
|
372
|
-
fullName:
|
|
435
|
+
fullName: newUser.fullName,
|
|
373
436
|
},
|
|
374
437
|
{
|
|
375
438
|
...sessionConfig,
|
|
@@ -1,13 +1,42 @@
|
|
|
1
1
|
const { LOGIN_PROVIDER } = require('@blocklet/constant');
|
|
2
2
|
const { getBlockletAppIdList } = require('@blocklet/meta/lib/util');
|
|
3
|
+
const pick = require('lodash/pick');
|
|
4
|
+
const logger = require('@abtnode/logger')(require('../../package.json').name);
|
|
3
5
|
|
|
4
6
|
const { getFederatedMaster } = require('./federated');
|
|
7
|
+
const { api } = require('../libs/api');
|
|
5
8
|
|
|
6
|
-
function
|
|
9
|
+
async function getFederatedTrustedIssuers(blocklet) {
|
|
10
|
+
const masterSite = getFederatedMaster(blocklet);
|
|
11
|
+
const id = masterSite?.appId;
|
|
12
|
+
const pid = masterSite?.appPid;
|
|
13
|
+
const appUrl = masterSite?.appUrl;
|
|
14
|
+
// 使用 masterSite.appPid 作为兜底方案
|
|
15
|
+
const issuers = [id, pid];
|
|
16
|
+
try {
|
|
17
|
+
if (appUrl) {
|
|
18
|
+
const { data } = await api.get(`${appUrl}/__blocklet__.js`, {
|
|
19
|
+
params: { type: 'json' },
|
|
20
|
+
});
|
|
21
|
+
const { appId, appPid, alsoKnownAs = [] } = data;
|
|
22
|
+
issuers.push(appId);
|
|
23
|
+
issuers.push(appPid);
|
|
24
|
+
issuers.push(...alsoKnownAs);
|
|
25
|
+
}
|
|
26
|
+
} catch (error) {
|
|
27
|
+
logger.error('Failed to fetch master __blocklet__.js', {
|
|
28
|
+
error,
|
|
29
|
+
masterSite: pick(masterSite, ['appId', 'appPid', 'appName', 'appDescription', 'appUrl']),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return [...new Set(issuers.filter(Boolean))];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function getTrustedIssuers(blocklet, { provider = LOGIN_PROVIDER.WALLET } = {}) {
|
|
7
36
|
if (provider === LOGIN_PROVIDER.FEDERATED) {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
return
|
|
37
|
+
const federatedTrustedIssuers = await getFederatedTrustedIssuers(blocklet);
|
|
38
|
+
|
|
39
|
+
return federatedTrustedIssuers;
|
|
11
40
|
}
|
|
12
41
|
|
|
13
42
|
const trustedPassports = (blocklet.trustedPassports || []).map((x) => x.issuerDid);
|
|
@@ -28,4 +57,5 @@ function getLoginProvider(request) {
|
|
|
28
57
|
module.exports = {
|
|
29
58
|
getLoginProvider,
|
|
30
59
|
getTrustedIssuers,
|
|
60
|
+
getFederatedTrustedIssuers,
|
|
31
61
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
3
|
"main.css": "/.well-known/service/static/static/css/main.7ea79dc8.css",
|
|
4
|
-
"main.js": "/.well-known/service/static/static/js/main.
|
|
4
|
+
"main.js": "/.well-known/service/static/static/js/main.adfe46cb.js",
|
|
5
5
|
"static/js/4716.a1240199.chunk.js": "/.well-known/service/static/static/js/4716.a1240199.chunk.js",
|
|
6
6
|
"static/js/4359.5ed52fe3.chunk.js": "/.well-known/service/static/static/js/4359.5ed52fe3.chunk.js",
|
|
7
7
|
"static/js/1255.0e8a8a45.chunk.js": "/.well-known/service/static/static/js/1255.0e8a8a45.chunk.js",
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
"static/js/5176.68fd3fde.chunk.js": "/.well-known/service/static/static/js/5176.68fd3fde.chunk.js",
|
|
23
23
|
"static/js/2139.341406d2.chunk.js": "/.well-known/service/static/static/js/2139.341406d2.chunk.js",
|
|
24
24
|
"static/js/5052.91c69c75.chunk.js": "/.well-known/service/static/static/js/5052.91c69c75.chunk.js",
|
|
25
|
-
"static/js/8395.
|
|
25
|
+
"static/js/8395.40dc877e.chunk.js": "/.well-known/service/static/static/js/8395.40dc877e.chunk.js",
|
|
26
26
|
"static/js/5233.faabaae9.chunk.js": "/.well-known/service/static/static/js/5233.faabaae9.chunk.js",
|
|
27
27
|
"static/css/4603.dce369d5.chunk.css": "/.well-known/service/static/static/css/4603.dce369d5.chunk.css",
|
|
28
|
-
"static/js/4603.
|
|
28
|
+
"static/js/4603.c6657383.chunk.js": "/.well-known/service/static/static/js/4603.c6657383.chunk.js",
|
|
29
29
|
"static/js/5050.538edf89.chunk.js": "/.well-known/service/static/static/js/5050.538edf89.chunk.js",
|
|
30
30
|
"static/css/780.e3db6e49.chunk.css": "/.well-known/service/static/static/css/780.e3db6e49.chunk.css",
|
|
31
31
|
"static/js/780.32bf1f5b.chunk.js": "/.well-known/service/static/static/js/780.32bf1f5b.chunk.js",
|
|
32
32
|
"static/js/766.5dd16d47.chunk.js": "/.well-known/service/static/static/js/766.5dd16d47.chunk.js",
|
|
33
|
-
"static/js/5430.
|
|
33
|
+
"static/js/5430.090296e0.chunk.js": "/.well-known/service/static/static/js/5430.090296e0.chunk.js",
|
|
34
34
|
"static/js/3800.faac00ca.chunk.js": "/.well-known/service/static/static/js/3800.faac00ca.chunk.js",
|
|
35
35
|
"static/js/1832.4cd8a983.chunk.js": "/.well-known/service/static/static/js/1832.4cd8a983.chunk.js",
|
|
36
|
-
"static/js/3042.
|
|
37
|
-
"static/js/3162.
|
|
36
|
+
"static/js/3042.0066bb3c.chunk.js": "/.well-known/service/static/static/js/3042.0066bb3c.chunk.js",
|
|
37
|
+
"static/js/3162.834ccffb.chunk.js": "/.well-known/service/static/static/js/3162.834ccffb.chunk.js",
|
|
38
38
|
"static/js/655.cdee65b4.chunk.js": "/.well-known/service/static/static/js/655.cdee65b4.chunk.js",
|
|
39
39
|
"static/js/576.d7d4814e.chunk.js": "/.well-known/service/static/static/js/576.d7d4814e.chunk.js",
|
|
40
40
|
"static/js/2631.54f86f84.chunk.js": "/.well-known/service/static/static/js/2631.54f86f84.chunk.js",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"static/js/2130.59fef4ad.chunk.js": "/.well-known/service/static/static/js/2130.59fef4ad.chunk.js",
|
|
53
53
|
"static/js/5711.aa17ef28.chunk.js": "/.well-known/service/static/static/js/5711.aa17ef28.chunk.js",
|
|
54
54
|
"static/js/7345.4b4f8941.chunk.js": "/.well-known/service/static/static/js/7345.4b4f8941.chunk.js",
|
|
55
|
-
"static/js/1237.
|
|
55
|
+
"static/js/1237.1018f6da.chunk.js": "/.well-known/service/static/static/js/1237.1018f6da.chunk.js",
|
|
56
56
|
"static/js/8031.9944bf3c.chunk.js": "/.well-known/service/static/static/js/8031.9944bf3c.chunk.js",
|
|
57
57
|
"static/js/3963.2e06f9bc.chunk.js": "/.well-known/service/static/static/js/3963.2e06f9bc.chunk.js",
|
|
58
58
|
"static/js/6891.6c7018ab.chunk.js": "/.well-known/service/static/static/js/6891.6c7018ab.chunk.js",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"router-template-styles/styles.css": "/.well-known/service/static/router-template-styles/styles.css",
|
|
87
87
|
"index.html": "/.well-known/service/static/index.html",
|
|
88
88
|
"main.7ea79dc8.css.map": "/.well-known/service/static/static/css/main.7ea79dc8.css.map",
|
|
89
|
-
"main.
|
|
89
|
+
"main.adfe46cb.js.map": "/.well-known/service/static/static/js/main.adfe46cb.js.map",
|
|
90
90
|
"4716.a1240199.chunk.js.map": "/.well-known/service/static/static/js/4716.a1240199.chunk.js.map",
|
|
91
91
|
"4359.5ed52fe3.chunk.js.map": "/.well-known/service/static/static/js/4359.5ed52fe3.chunk.js.map",
|
|
92
92
|
"1255.0e8a8a45.chunk.js.map": "/.well-known/service/static/static/js/1255.0e8a8a45.chunk.js.map",
|
|
@@ -107,19 +107,19 @@
|
|
|
107
107
|
"5176.68fd3fde.chunk.js.map": "/.well-known/service/static/static/js/5176.68fd3fde.chunk.js.map",
|
|
108
108
|
"2139.341406d2.chunk.js.map": "/.well-known/service/static/static/js/2139.341406d2.chunk.js.map",
|
|
109
109
|
"5052.91c69c75.chunk.js.map": "/.well-known/service/static/static/js/5052.91c69c75.chunk.js.map",
|
|
110
|
-
"8395.
|
|
110
|
+
"8395.40dc877e.chunk.js.map": "/.well-known/service/static/static/js/8395.40dc877e.chunk.js.map",
|
|
111
111
|
"5233.faabaae9.chunk.js.map": "/.well-known/service/static/static/js/5233.faabaae9.chunk.js.map",
|
|
112
112
|
"4603.dce369d5.chunk.css.map": "/.well-known/service/static/static/css/4603.dce369d5.chunk.css.map",
|
|
113
|
-
"4603.
|
|
113
|
+
"4603.c6657383.chunk.js.map": "/.well-known/service/static/static/js/4603.c6657383.chunk.js.map",
|
|
114
114
|
"5050.538edf89.chunk.js.map": "/.well-known/service/static/static/js/5050.538edf89.chunk.js.map",
|
|
115
115
|
"780.e3db6e49.chunk.css.map": "/.well-known/service/static/static/css/780.e3db6e49.chunk.css.map",
|
|
116
116
|
"780.32bf1f5b.chunk.js.map": "/.well-known/service/static/static/js/780.32bf1f5b.chunk.js.map",
|
|
117
117
|
"766.5dd16d47.chunk.js.map": "/.well-known/service/static/static/js/766.5dd16d47.chunk.js.map",
|
|
118
|
-
"5430.
|
|
118
|
+
"5430.090296e0.chunk.js.map": "/.well-known/service/static/static/js/5430.090296e0.chunk.js.map",
|
|
119
119
|
"3800.faac00ca.chunk.js.map": "/.well-known/service/static/static/js/3800.faac00ca.chunk.js.map",
|
|
120
120
|
"1832.4cd8a983.chunk.js.map": "/.well-known/service/static/static/js/1832.4cd8a983.chunk.js.map",
|
|
121
|
-
"3042.
|
|
122
|
-
"3162.
|
|
121
|
+
"3042.0066bb3c.chunk.js.map": "/.well-known/service/static/static/js/3042.0066bb3c.chunk.js.map",
|
|
122
|
+
"3162.834ccffb.chunk.js.map": "/.well-known/service/static/static/js/3162.834ccffb.chunk.js.map",
|
|
123
123
|
"655.cdee65b4.chunk.js.map": "/.well-known/service/static/static/js/655.cdee65b4.chunk.js.map",
|
|
124
124
|
"576.d7d4814e.chunk.js.map": "/.well-known/service/static/static/js/576.d7d4814e.chunk.js.map",
|
|
125
125
|
"2631.54f86f84.chunk.js.map": "/.well-known/service/static/static/js/2631.54f86f84.chunk.js.map",
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"2130.59fef4ad.chunk.js.map": "/.well-known/service/static/static/js/2130.59fef4ad.chunk.js.map",
|
|
138
138
|
"5711.aa17ef28.chunk.js.map": "/.well-known/service/static/static/js/5711.aa17ef28.chunk.js.map",
|
|
139
139
|
"7345.4b4f8941.chunk.js.map": "/.well-known/service/static/static/js/7345.4b4f8941.chunk.js.map",
|
|
140
|
-
"1237.
|
|
140
|
+
"1237.1018f6da.chunk.js.map": "/.well-known/service/static/static/js/1237.1018f6da.chunk.js.map",
|
|
141
141
|
"8031.9944bf3c.chunk.js.map": "/.well-known/service/static/static/js/8031.9944bf3c.chunk.js.map",
|
|
142
142
|
"3963.2e06f9bc.chunk.js.map": "/.well-known/service/static/static/js/3963.2e06f9bc.chunk.js.map",
|
|
143
143
|
"6891.6c7018ab.chunk.js.map": "/.well-known/service/static/static/js/6891.6c7018ab.chunk.js.map",
|
|
@@ -151,6 +151,6 @@
|
|
|
151
151
|
},
|
|
152
152
|
"entrypoints": [
|
|
153
153
|
"static/css/main.7ea79dc8.css",
|
|
154
|
-
"static/js/main.
|
|
154
|
+
"static/js/main.adfe46cb.js"
|
|
155
155
|
]
|
|
156
156
|
}
|