@abtnode/core 1.16.14-beta-dc99d0a2 → 1.16.14-beta-dd4f6a50

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.
@@ -51,6 +51,7 @@ const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
51
51
  const { titleSchema, updateMountPointSchema, environmentNameSchema } = require('@blocklet/meta/lib/schema');
52
52
  const { emailConfigSchema } = require('@blocklet/sdk/lib/validators/email');
53
53
  const Lock = require('@abtnode/util/lib/lock');
54
+ const defaults = require('lodash/defaults');
54
55
 
55
56
  const {
56
57
  BlockletStatus,
@@ -3419,21 +3420,24 @@ class DiskBlockletManager extends BaseBlockletManager {
3419
3420
  class FederatedBlockletManager extends DiskBlockletManager {
3420
3421
  /**
3421
3422
  * Joins federated login.
3422
- * @param {{appUrl: string, did: string;}} options - The federated login appUrl.
3423
- * @returns {Promise<any>} The data received from the appUrl.
3423
+ * @param {object} options
3424
+ * @param {{string}} options.did - blocklet pid
3425
+ * @param {{string}} options.appUrl - 申请加入统一登录的 master appUrl
3426
+ * @returns {Promise<any>} 更新后的 blocklet 数据
3424
3427
  */
3425
3428
  async joinFederatedLogin({ appUrl, did }) {
3426
3429
  const url = new URL(appUrl);
3430
+ // master service api 的地址
3427
3431
  url.pathname = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/federated/join`;
3428
3432
 
3429
3433
  const blocklet = await this.getBlocklet(did);
3430
3434
  const nodeInfo = await states.node.read();
3431
3435
  const blockletInfo = getBlockletInfo(blocklet, nodeInfo.sk);
3432
- const { permanentWallet, wallet } = blockletInfo;
3436
+ const { permanentWallet } = blockletInfo;
3433
3437
  const memberSite = {
3434
- appId: wallet.address,
3435
- appPid: permanentWallet.address,
3436
- migratedFrom: blocklet.migratedFrom || [],
3438
+ appId: blocklet.appDid,
3439
+ appPid: blocklet.appPid,
3440
+ aliasDid: (blocklet.migratedFrom || []).map((item) => item.appDid),
3437
3441
  appName: blockletInfo.name,
3438
3442
  appDescription: blockletInfo.description,
3439
3443
  appUrl: blockletInfo.appUrl,
@@ -3442,33 +3446,99 @@ class FederatedBlockletManager extends DiskBlockletManager {
3442
3446
  normalizePathPrefix(`${WELLKNOWN_SERVICE_PATH_PREFIX}/blocklet/logo`) ||
3443
3447
  '/',
3444
3448
  appLogoRect: blocklet.environmentObj.BLOCKLET_APP_LOGO_RECT,
3445
- did: blockletInfo.did,
3449
+ did: permanentWallet.address,
3446
3450
  pk: permanentWallet.publicKey,
3447
3451
  serverId: nodeInfo.did,
3448
3452
  serverVersion: nodeInfo.version,
3449
3453
  version: blockletInfo.version,
3450
3454
  };
3451
3455
 
3452
- const { data } = await request.post(url.href, {
3453
- // 初次申请时,member 不在站点群中,不需要对数据进行加密
3454
- site: memberSite,
3456
+ logger.info('Apply to join federated login', {
3457
+ memberSite: pick(memberSite, ['appId', 'appPid', 'appName', 'appDescription', 'appUrl']),
3458
+ masterAppUrl: appUrl,
3455
3459
  });
3456
- await states.blockletExtras.setSettings(blocklet.meta.did, {
3460
+
3461
+ let data;
3462
+ try {
3463
+ const result = await request.post(url.href, {
3464
+ // 初次申请时,member 不在站点群中,不需要对数据进行加密
3465
+ site: memberSite,
3466
+ });
3467
+ data = result.data;
3468
+ } catch (error) {
3469
+ logger.error('Failed to join federated login', { error, did, url: url.href });
3470
+ throw error;
3471
+ }
3472
+
3473
+ await states.blockletExtras.setSettings(blocklet.appPid, {
3457
3474
  federated: {
3458
3475
  config: {
3459
3476
  appId: blocklet.appDid,
3460
- appPid: blocklet.appPid || blocklet.appDid,
3477
+ appPid: blocklet.appPid,
3461
3478
  isMaster: false,
3462
3479
  },
3463
3480
  sites: data.sites,
3464
3481
  },
3465
3482
  });
3466
3483
 
3484
+ const newState = await this.getBlocklet(did);
3485
+ this.emit(BlockletEvents.updated, {
3486
+ masterAppUrl: appUrl,
3487
+ });
3488
+ return newState;
3489
+ }
3490
+
3491
+ async quitFederatedLogin({ did }) {
3492
+ const blocklet = await this.getBlocklet(did);
3493
+ const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
3494
+ config: {},
3495
+ sites: [],
3496
+ });
3497
+ const masterSite = federated.sites[0];
3498
+ if (masterSite && masterSite.isMaster !== false) {
3499
+ const nodeInfo = await states.node.read();
3500
+ const blockletInfo = getBlockletInfo(blocklet, nodeInfo.sk);
3501
+ const { permanentWallet } = blockletInfo;
3502
+ logger.info('Quit federated login', {
3503
+ memberSite: {
3504
+ appId: blocklet.appDid,
3505
+ appPid: blocklet.appPid,
3506
+ appName: blockletInfo.name,
3507
+ appDescription: blockletInfo.description,
3508
+ appUrl: blockletInfo.appUrl,
3509
+ },
3510
+ masterAppUrl: masterSite.appUrl,
3511
+ });
3512
+ const url = new URL(masterSite.appUrl);
3513
+ url.pathname = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/federated/quit`;
3514
+ try {
3515
+ await request.post(url.href, {
3516
+ signer: permanentWallet.address,
3517
+ data: signV2(permanentWallet.address, permanentWallet.secretKey, {
3518
+ memberPid: blocklet.appPid,
3519
+ }),
3520
+ });
3521
+ } catch (error) {
3522
+ logger.error('Failed to quit blocklet', { error, did, url: url.href });
3523
+ throw error;
3524
+ }
3525
+ }
3526
+
3527
+ await states.blockletExtras.setSettings(blocklet.appPid, {
3528
+ federated: null,
3529
+ });
3467
3530
  const newState = await this.getBlocklet(did);
3468
3531
  this.emit(BlockletEvents.updated, newState);
3469
3532
  return newState;
3470
3533
  }
3471
3534
 
3535
+ /**
3536
+ * 更改 federated 配置
3537
+ * @param {object} param
3538
+ * @param {string} param.did blocklet pid
3539
+ * @param {object} param.config federated 配置内容
3540
+ * @returns {Promise<any>} 更新后的 blocklet 数据
3541
+ */
3472
3542
  async setFederated({ did, config }) {
3473
3543
  await states.blockletExtras.setSettings(did, { federated: config });
3474
3544
 
@@ -3477,6 +3547,13 @@ class FederatedBlockletManager extends DiskBlockletManager {
3477
3547
  return newState;
3478
3548
  }
3479
3549
 
3550
+ /**
3551
+ * 配置 federated 设置
3552
+ * @param {object} param
3553
+ * @param {string} param.did blocklet pid
3554
+ * @param {boolean} param.autoLogin 是否自动登录
3555
+ * @returns {Promise<any>} 更新后的 blocklet 数据
3556
+ */
3480
3557
  async configFederated({ did, autoLogin = false }) {
3481
3558
  const blocklet = await this.getBlocklet(did);
3482
3559
  const federated = cloneDeep(blocklet.settings.federated || {});
@@ -3488,23 +3565,40 @@ class FederatedBlockletManager extends DiskBlockletManager {
3488
3565
  return newState;
3489
3566
  }
3490
3567
 
3491
- async auditFederatedLogin({ appId, did, status }) {
3568
+ /**
3569
+ * 审核 federated 申请
3570
+ * @param {object} param
3571
+ * @param {string} param.did master blocklet pid
3572
+ * @param {string} param.memberPid member blocklet pid
3573
+ * @param {boolean} param.autoLogin 是否自动登录
3574
+ * @returns {Promise<any>} 更新后的 blocklet 数据
3575
+ */
3576
+ async auditFederatedLogin({ memberPid, did, status }) {
3492
3577
  const blocklet = await this.getBlocklet(did);
3493
3578
 
3494
- const federated = cloneDeep(blocklet.settings.federated || {});
3495
- const memberSite = federated.sites.find((item) => item.appId === appId);
3579
+ const federated = defaults(cloneDeep(blocklet.settings.federated || {}), {
3580
+ config: {},
3581
+ sites: [],
3582
+ });
3583
+ const memberSite = federated.sites.find((item) => item.appPid === memberPid);
3496
3584
  memberSite.status = status;
3497
3585
  if ([null, undefined].includes(federated.config.isMaster)) {
3498
- const masterSite = federated.sites.find((item) => item.appId === blocklet.meta.did);
3586
+ const { sites, config } = federated;
3587
+ const masterSite = sites.find((item) => item.appPid === blocklet.appPid);
3499
3588
 
3500
3589
  masterSite.isMaster = true;
3501
- federated.config.isMaster = true;
3590
+ config.isMaster = true;
3502
3591
  }
3503
3592
  // 有审批操作的一方,自动成为 master
3504
3593
  const newState = await this.setFederated({
3505
- did: blocklet.meta.did,
3594
+ did: blocklet.appPid,
3506
3595
  config: federated,
3507
3596
  });
3597
+ logger.info('Audit member join federated login', {
3598
+ memberSite: pick(memberSite, ['appId', 'appPid', 'appName', 'appDescription', 'appUrl']),
3599
+ status,
3600
+ });
3601
+
3508
3602
  const nodeInfo = await states.node.read();
3509
3603
  const { permanentWallet } = getBlockletInfo(blocklet, nodeInfo.sk);
3510
3604
  let delegation;
@@ -3530,18 +3624,30 @@ class FederatedBlockletManager extends DiskBlockletManager {
3530
3624
  ],
3531
3625
  exp: Math.floor(new Date().getTime() / 1000) + 86400 * 365 * 100, // valid for 100 year
3532
3626
  });
3533
- roles = await this.teamManager.getRoles(blocklet.meta.did);
3627
+ roles = await this.teamManager.getRoles(blocklet.appPid);
3534
3628
  }
3535
3629
 
3536
- await request.post(`${memberSite.appUrl}/${WELLKNOWN_SERVICE_PATH_PREFIX}/api/federated/audit-res`, {
3537
- signer: permanentWallet.address,
3538
- data: signV2(permanentWallet.address, permanentWallet.secretKey, {
3539
- appId: blocklet.meta.did,
3540
- status,
3541
- delegation,
3542
- roles: roles.map((item) => pick(item, ['name', 'title', 'description'])),
3543
- }),
3630
+ const postUrl = `${memberSite.appUrl}/${WELLKNOWN_SERVICE_PATH_PREFIX}/api/federated/audit-res`;
3631
+
3632
+ logger.info('Audit member join federated login', {
3633
+ status,
3634
+ postUrl,
3544
3635
  });
3636
+ try {
3637
+ const roleList = roles.map((item) => pick(item, ['name', 'title', 'description']));
3638
+ await request.post(postUrl, {
3639
+ signer: permanentWallet.address,
3640
+ data: signV2(permanentWallet.address, permanentWallet.secretKey, {
3641
+ masterPid: blocklet.appPid,
3642
+ status,
3643
+ delegation,
3644
+ roles: roleList,
3645
+ }),
3646
+ });
3647
+ } catch (error) {
3648
+ logger.error('Failed to post audit res to member-site', { error, did, url: postUrl });
3649
+ throw error;
3650
+ }
3545
3651
  const waitingList = federated.sites
3546
3652
  .filter((item) => item.appId !== federated.config.appId)
3547
3653
  .map((item) => {
package/lib/index.js CHANGED
@@ -259,6 +259,7 @@ function ABTNode(options) {
259
259
  configNavigations: blockletManager.configNavigations.bind(blockletManager),
260
260
  configOAuth: blockletManager.configOAuth.bind(blockletManager),
261
261
  joinFederatedLogin: blockletManager.joinFederatedLogin.bind(blockletManager),
262
+ quitFederatedLogin: blockletManager.quitFederatedLogin.bind(blockletManager),
262
263
  auditFederatedLogin: blockletManager.auditFederatedLogin.bind(blockletManager),
263
264
  configFederated: blockletManager.configFederated.bind(blockletManager),
264
265
  setFederated: blockletManager.setFederated.bind(blockletManager),
@@ -138,16 +138,21 @@ const getLogContent = async (action, args, context, result, info, node) => {
138
138
  return `set publicToStore to ${args.publicToStore ? 'true' : 'false'}`;
139
139
  case 'configNavigations':
140
140
  // eslint-disable-next-line prettier/prettier
141
- return `updated following navigations:\n${args.navigations.map(
142
- (x) => `- ${x.title}: ${x.link}\n`
143
- )}`;
141
+ return `updated following navigations:\n${args.navigations.map((x) => `- ${x.title}: ${x.link}\n`)}`;
144
142
  case 'configOAuth':
145
143
  return `updated following OAuth for blocklet ${getBlockletInfo(result, info)}:\n${args.oauth}`;
146
- // TODO: @zhanghan 配置审计日志
147
144
  case 'joinFederatedLogin':
148
- return `updated following OAuth for blocklet ${getBlockletInfo(result, info)}:\n${args.oauth}`;
145
+ return `blocklet ${getBlockletInfo(result, info)} join federated login to ${args.appUrl}`;
146
+ case 'quitFederatedLogin':
147
+ return `blocklet ${getBlockletInfo(result, info)} quit federated login`;
149
148
  case 'auditFederatedLogin':
150
- return `updated following OAuth:\n${args.oauth}`;
149
+ return `blocklet ${getBlockletInfo(result, info)} audit federated login member ${args.memberPid} with status: ${
150
+ args.status
151
+ }`;
152
+ case 'configFederated':
153
+ return `blocklet ${getBlockletInfo(result, info)} config federated login settings with autoLogin: ${
154
+ args.autoLogin
155
+ }`;
151
156
  case 'configNotification':
152
157
  return `updated following notification setting: ${args.notification}`;
153
158
  case 'updateComponentTitle':
@@ -315,6 +320,10 @@ const getLogCategory = (action) => {
315
320
  case 'updateComponentTitle':
316
321
  case 'updateComponentMountPoint':
317
322
  case 'backupToSpaces':
323
+ case 'joinFederatedLogin':
324
+ case 'quitFederatedLogin':
325
+ case 'auditFederatedLogin':
326
+ case 'configFederated':
318
327
  return 'blocklet';
319
328
 
320
329
  // store,此处应该返回 server
@@ -1229,6 +1229,7 @@ const getBlocklet = async ({
1229
1229
  }
1230
1230
 
1231
1231
  // app settings
1232
+ // FIXME: @zhanghan 在 server 开发模式下,使用 `node /workspace/arcblock/blocklet-server/core/cli/tools/dev.js` 运行的 blocklet,blocklet.meta.did 和 blocklet.appPid 是不一致的
1232
1233
  const settings = await states.blockletExtras.getSettings(blocklet.meta.did);
1233
1234
  blocklet.trustedPassports = get(settings, 'trustedPassports') || [];
1234
1235
  blocklet.trustedFactories = (get(settings, 'trustedFactories') || []).map((x) => {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.14-beta-dc99d0a2",
6
+ "version": "1.16.14-beta-dd4f6a50",
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.14-beta-dc99d0a2",
23
- "@abtnode/auth": "1.16.14-beta-dc99d0a2",
24
- "@abtnode/certificate-manager": "1.16.14-beta-dc99d0a2",
25
- "@abtnode/constant": "1.16.14-beta-dc99d0a2",
26
- "@abtnode/cron": "1.16.14-beta-dc99d0a2",
27
- "@abtnode/logger": "1.16.14-beta-dc99d0a2",
28
- "@abtnode/models": "1.16.14-beta-dc99d0a2",
29
- "@abtnode/queue": "1.16.14-beta-dc99d0a2",
30
- "@abtnode/rbac": "1.16.14-beta-dc99d0a2",
31
- "@abtnode/router-provider": "1.16.14-beta-dc99d0a2",
32
- "@abtnode/static-server": "1.16.14-beta-dc99d0a2",
33
- "@abtnode/timemachine": "1.16.14-beta-dc99d0a2",
34
- "@abtnode/util": "1.16.14-beta-dc99d0a2",
22
+ "@abtnode/analytics": "1.16.14-beta-dd4f6a50",
23
+ "@abtnode/auth": "1.16.14-beta-dd4f6a50",
24
+ "@abtnode/certificate-manager": "1.16.14-beta-dd4f6a50",
25
+ "@abtnode/constant": "1.16.14-beta-dd4f6a50",
26
+ "@abtnode/cron": "1.16.14-beta-dd4f6a50",
27
+ "@abtnode/logger": "1.16.14-beta-dd4f6a50",
28
+ "@abtnode/models": "1.16.14-beta-dd4f6a50",
29
+ "@abtnode/queue": "1.16.14-beta-dd4f6a50",
30
+ "@abtnode/rbac": "1.16.14-beta-dd4f6a50",
31
+ "@abtnode/router-provider": "1.16.14-beta-dd4f6a50",
32
+ "@abtnode/static-server": "1.16.14-beta-dd4f6a50",
33
+ "@abtnode/timemachine": "1.16.14-beta-dd4f6a50",
34
+ "@abtnode/util": "1.16.14-beta-dd4f6a50",
35
35
  "@arcblock/did": "1.18.87",
36
36
  "@arcblock/did-auth": "1.18.87",
37
37
  "@arcblock/did-ext": "^1.18.87",
@@ -42,10 +42,10 @@
42
42
  "@arcblock/pm2-events": "^0.0.5",
43
43
  "@arcblock/validator": "^1.18.87",
44
44
  "@arcblock/vc": "1.18.87",
45
- "@blocklet/constant": "1.16.14-beta-dc99d0a2",
46
- "@blocklet/meta": "1.16.14-beta-dc99d0a2",
47
- "@blocklet/resolver": "1.16.14-beta-dc99d0a2",
48
- "@blocklet/sdk": "1.16.14-beta-dc99d0a2",
45
+ "@blocklet/constant": "1.16.14-beta-dd4f6a50",
46
+ "@blocklet/meta": "1.16.14-beta-dd4f6a50",
47
+ "@blocklet/resolver": "1.16.14-beta-dd4f6a50",
48
+ "@blocklet/sdk": "1.16.14-beta-dd4f6a50",
49
49
  "@did-space/client": "^0.2.129",
50
50
  "@fidm/x509": "^1.2.1",
51
51
  "@ocap/mcrypto": "1.18.87",
@@ -99,5 +99,5 @@
99
99
  "jest": "^27.5.1",
100
100
  "unzipper": "^0.10.11"
101
101
  },
102
- "gitHead": "a00766d660ede97e2036f3a785f4f5cfb2e6d870"
102
+ "gitHead": "fb3858f842b221f0a8c298307b393d55c555af45"
103
103
  }