@abtnode/auth 1.8.69-beta-b0bb2d67 → 1.8.69-beta-650a290b

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/auth.js CHANGED
@@ -184,6 +184,10 @@ const messages = {
184
184
  en: 'Invalid Blocklet VC',
185
185
  zh: '无效的 Blocklet VC',
186
186
  },
187
+ invalidAppVersion: {
188
+ en: 'App key-pair rotating can only be performed on the latest version',
189
+ zh: '只有最新版应用可以变更钥匙对',
190
+ },
187
191
 
188
192
  // NFT related
189
193
  missingProfileClaim: {
@@ -1,11 +1,12 @@
1
1
  const path = require('path');
2
2
  const joinUrl = require('url-join');
3
3
  const uniqBy = require('lodash/uniqBy');
4
+ const uniq = require('lodash/uniq');
4
5
  const getBlockletInfo = require('@blocklet/meta/lib/info');
5
6
  const formatContext = require('@abtnode/util/lib/format-context');
6
7
  const getRandomMessage = require('@abtnode/util/lib/get-random-message');
7
8
  const getNodeWallet = require('@abtnode/util/lib/get-app-wallet');
8
- const { getDisplayName } = require('@blocklet/meta/lib/util');
9
+ const { getDisplayName, getBlockletAppIdList } = require('@blocklet/meta/lib/util');
9
10
  const { VC_TYPE_NODE_PASSPORT, PASSPORT_STATUS, NODE_DATA_DIR_NAME } = require('@abtnode/constant');
10
11
  const get = require('lodash/get');
11
12
  const { parseUserAvatar } = require('@abtnode/util/lib/user-avatar');
@@ -31,6 +32,7 @@ const TEAM_TYPES = {
31
32
  const getTeamInfo = async ({ type, node, req }) => {
32
33
  let teamDid;
33
34
  let issuerDid;
35
+ let issuerDidList;
34
36
  let issuerName;
35
37
  let issuerWallet;
36
38
  let passportColor;
@@ -40,6 +42,7 @@ const getTeamInfo = async ({ type, node, req }) => {
40
42
  if (type === TEAM_TYPES.NODE) {
41
43
  teamDid = info.did;
42
44
  issuerDid = info.did;
45
+ issuerDidList = [info.did];
43
46
  issuerName = info.name;
44
47
  issuerWallet = getNodeWallet(info.sk);
45
48
  passportColor = 'default';
@@ -49,6 +52,7 @@ const getTeamInfo = async ({ type, node, req }) => {
49
52
  const blocklet = await node.getBlocklet({ did: teamDid, attachRuntimeInfo: false });
50
53
  const blockletInfo = getBlockletInfo(blocklet, info.sk);
51
54
  issuerDid = blockletInfo.wallet.address;
55
+ issuerDidList = uniq([blockletInfo.wallet.address, ...getBlockletAppIdList(blocklet)]);
52
56
  issuerName = getDisplayName(blocklet, true);
53
57
  issuerWallet = blockletInfo.wallet;
54
58
  passportColor = blockletInfo.passportColor;
@@ -60,6 +64,7 @@ const getTeamInfo = async ({ type, node, req }) => {
60
64
  return {
61
65
  teamDid,
62
66
  issuerDid,
67
+ issuerDidList,
63
68
  issuerName,
64
69
  issuerWallet,
65
70
  passportColor,
@@ -95,7 +100,7 @@ const createLostPassportListRoute = ({ node, type }) => ({
95
100
  onAuth: async ({ userDid, extraParams, updateSession, req }) => {
96
101
  const { locale } = extraParams;
97
102
 
98
- const { teamDid, issuerDid, dataDir } = await getTeamInfo({ node, req, type });
103
+ const { teamDid, issuerDidList, dataDir } = await getTeamInfo({ node, req, type });
99
104
 
100
105
  // check user approved
101
106
  const user = await getUser(node, teamDid, userDid);
@@ -114,7 +119,7 @@ const createLostPassportListRoute = ({ node, type }) => ({
114
119
  return false;
115
120
  }
116
121
 
117
- if (x.issuer.id !== issuerDid) {
122
+ if (!issuerDidList.includes(x.issuer.id)) {
118
123
  return false;
119
124
  }
120
125
  return !(x.expirationDate && Date.now() > new Date(x.expirationDate).getTime());
@@ -193,7 +198,7 @@ const createLostPassportIssueRoute = ({ node, type, authServicePrefix }) => ({
193
198
  onAuth: async ({ claims, userDid, userPk, extraParams, updateSession, baseUrl, req }) => {
194
199
  const { locale = 'en', receiverDid, passportName } = extraParams;
195
200
 
196
- const { teamDid, issuerDid, issuerName, issuerWallet, passportColor, dataDir } = await getTeamInfo({
201
+ const { teamDid, issuerDidList, issuerName, issuerWallet, passportColor, dataDir } = await getTeamInfo({
197
202
  node,
198
203
  req,
199
204
  type,
@@ -226,7 +231,7 @@ const createLostPassportIssueRoute = ({ node, type, authServicePrefix }) => ({
226
231
  (x) =>
227
232
  x.name === passportName &&
228
233
  x.status === PASSPORT_STATUS.VALID &&
229
- x.issuer.id === issuerDid &&
234
+ issuerDidList.includes(x.issuer.id) &&
230
235
  (!x.expirationDate || Date.now() > new Date(x.expirationDate).getTime())
231
236
  );
232
237
  if (!exist) {
package/lib/server.js CHANGED
@@ -8,6 +8,7 @@ const { fromPublicKey } = require('@ocap/wallet');
8
8
  const { fromBase58, toAddress, toHex } = require('@ocap/util');
9
9
  const { toTypeInfo, isFromPublicKey } = require('@arcblock/did');
10
10
  const urlFriendly = require('@blocklet/meta/lib/url-friendly').default;
11
+ const getApplicationWallet = require('@blocklet/meta/lib/wallet');
11
12
  const { slugify } = require('transliteration');
12
13
  const { getChainInfo } = require('@blocklet/meta/lib/util');
13
14
  const getBlockletInfo = require('@blocklet/meta/lib/info');
@@ -20,8 +21,8 @@ const {
20
21
  SERVER_ROLES,
21
22
  NFT_TYPE_SERVERLESS,
22
23
  MAIN_CHAIN_ENDPOINT,
24
+ APP_STRUCT_VERSION,
23
25
  } = require('@abtnode/constant');
24
- const { toExternalBlocklet } = require('@blocklet/meta/lib/did');
25
26
  const {
26
27
  messages,
27
28
  getVCFromClaims,
@@ -290,7 +291,7 @@ const getAuthNFTClaim =
290
291
  };
291
292
 
292
293
  const getKeyPairClaim =
293
- (node) =>
294
+ (node, declare = true) =>
294
295
  async ({ extraParams: { locale, appDid, title }, context: { didwallet } }) => {
295
296
  checkWalletVersion({ didwallet, locale });
296
297
 
@@ -319,6 +320,7 @@ const getKeyPairClaim =
319
320
  mfa: !process.env.DID_CONNECT_MFA_DISABLED,
320
321
  description: description[locale] || description.en,
321
322
  moniker: (urlFriendly(slugify(appName)) || 'application').toLowerCase(),
323
+ declare: !!declare,
322
324
  migrateFrom,
323
325
  targetType: {
324
326
  role: 'application',
@@ -334,7 +336,7 @@ const getRotateKeyPairClaims = (node) => {
334
336
  {
335
337
  authPrincipal: async ({ extraParams: { locale, appDid } }) => {
336
338
  const description = {
337
- en: 'Please select ',
339
+ en: 'Please create a new key-pair for this application',
338
340
  zh: '请为应用创建新的钥匙对',
339
341
  };
340
342
 
@@ -348,6 +350,9 @@ const getRotateKeyPairClaims = (node) => {
348
350
  if (!blocklet) {
349
351
  throw new Error(messages.invalidBlocklet[locale]);
350
352
  }
353
+ if (blocklet.structVersion !== APP_STRUCT_VERSION) {
354
+ throw new Error(messages.invalidAppVersion[locale]);
355
+ }
351
356
 
352
357
  // Try to use blocklet chain config if possible
353
358
  // Since migration happens on the chain the app holds some actual assets
@@ -388,18 +393,33 @@ const getLaunchBlockletClaims = (node, authMethod) => {
388
393
  return claims;
389
394
  };
390
395
 
391
- // FIXME: @wangshijun should be changed to blocklet appSK owner claim?
392
- const getSetupBlockletClaims = (node, authMethod, blocklet) => {
393
- const claims = {};
394
-
395
- if (authMethod === 'vc') {
396
- claims.serverPassport = ['verifiableCredential', getAuthVcClaim({ node, blocklet })];
397
- }
398
- if (authMethod === 'nft') {
399
- claims.serverNFT = ['asset', getAuthNFTClaim({ node })];
400
- }
396
+ const getSetupBlockletClaims = () => {
397
+ const description = {
398
+ en: 'Sign following message to prove that you are the owner of the app',
399
+ zh: '签名如下消息以证明你是应用的拥有者',
400
+ };
401
401
 
402
- return claims;
402
+ return [
403
+ {
404
+ authPrincipal: async ({ context, extraParams: { locale } }) => {
405
+ const blocklet = await context.request.getBlocklet();
406
+ return {
407
+ description: description[locale] || description.en,
408
+ target: blocklet.appDid,
409
+ };
410
+ },
411
+ },
412
+ {
413
+ signature: async ({ context, extraParams: { locale } }) => {
414
+ const blocklet = await context.request.getBlocklet();
415
+ return {
416
+ description: messages.receivePassport[locale],
417
+ data: `I am the owner of app ${blocklet.appDid}`,
418
+ type: 'mime:text/plain',
419
+ };
420
+ },
421
+ },
422
+ ];
403
423
  };
404
424
 
405
425
  const getOwnershipNFTClaim = async (node, locale) => {
@@ -580,16 +600,13 @@ const createLaunchBlockletHandler =
580
600
  await updateSession({ sessionToken }, true);
581
601
  }
582
602
 
583
- if (blocklet) {
584
- const blockletDid =
585
- role === SERVER_ROLES.EXTERNAL_BLOCKLET_CONTROLLER
586
- ? toExternalBlocklet(blocklet.meta.name, controller.nftId, { didOnly: true })
587
- : blocklet.meta.did;
588
-
589
- await updateSession({ blockletDid });
603
+ const appSk = toHex(keyPair.secret);
604
+ const appDid = getApplicationWallet(appSk).address;
605
+ await updateSession({ appDid });
590
606
 
607
+ if (blocklet) {
591
608
  // 检查是否已安装,这里不做升级的处理
592
- const existedBlocklet = await node.getBlocklet({ did: blockletDid, attachRuntimeInfo: false });
609
+ const existedBlocklet = await node.getBlocklet({ did: appDid, attachRuntimeInfo: false });
593
610
 
594
611
  // 如果是 serverless, 并且已经消费过了,但是没有安装,则抛出异常
595
612
  if (!existedBlocklet && role === SERVER_ROLES.EXTERNAL_BLOCKLET_CONTROLLER && isNFTConsumed(nft)) {
@@ -598,26 +615,24 @@ const createLaunchBlockletHandler =
598
615
 
599
616
  if (existedBlocklet) {
600
617
  await updateSession({ isInstalled: true });
601
- logger.info('blocklet already exists', { blockletDid });
618
+ logger.info('blocklet already exists', { appDid });
602
619
  return;
603
620
  }
604
621
  }
605
622
 
606
623
  logger.info('start install blocklet', { blockletMetaUrl, title, description });
607
- const tmp = await node.installBlocklet(
624
+ await node.installBlocklet(
608
625
  {
609
626
  url: blockletMetaUrl,
610
627
  title,
611
628
  description,
612
- appSk: toHex(keyPair.secret),
629
+ appSk,
613
630
  delay: 1000 * 4, // delay 4 seconds to download, wait for ws connection from frontend
614
631
  downloadTokenList: extraParams?.previousWorkflowData?.downloadTokenList,
615
632
  controller: role === SERVER_ROLES.EXTERNAL_BLOCKLET_CONTROLLER ? controller : null,
616
633
  },
617
634
  formatContext(Object.assign(req, { user: { ...pick(user, ['did', 'fullName']), role } }))
618
635
  );
619
-
620
- await updateSession({ blockletDid: tmp.meta.did });
621
636
  };
622
637
 
623
638
  const getBlockletPermissionChecker =
@@ -679,7 +694,6 @@ const createRotateKeyPairHandler =
679
694
  did: blocklet.meta.did,
680
695
  configs: [{ key: 'BLOCKLET_APP_SK', value: toHex(keyPair.secret), secure: true }],
681
696
  skipHook: true,
682
- skipDidDocument: true,
683
697
  },
684
698
  formatContext(Object.assign(req, { user: { did: userDid, fullName: 'Owner', role: 'owner' } }))
685
699
  );
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.8.69-beta-b0bb2d67",
6
+ "version": "1.8.69-beta-650a290b",
7
7
  "description": "Simple lib to manage auth in ABT Node",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -20,18 +20,18 @@
20
20
  "author": "linchen <linchen1987@foxmail.com> (http://github.com/linchen1987)",
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
- "@abtnode/constant": "1.8.69-beta-b0bb2d67",
24
- "@abtnode/logger": "1.8.69-beta-b0bb2d67",
25
- "@abtnode/util": "1.8.69-beta-b0bb2d67",
26
- "@arcblock/did": "1.18.57",
27
- "@arcblock/jwt": "^1.18.57",
28
- "@arcblock/vc": "1.18.57",
29
- "@blocklet/constant": "1.8.69-beta-b0bb2d67",
30
- "@blocklet/meta": "1.8.69-beta-b0bb2d67",
31
- "@ocap/client": "1.18.57",
32
- "@ocap/mcrypto": "1.18.57",
33
- "@ocap/util": "1.18.57",
34
- "@ocap/wallet": "1.18.57",
23
+ "@abtnode/constant": "1.8.69-beta-650a290b",
24
+ "@abtnode/logger": "1.8.69-beta-650a290b",
25
+ "@abtnode/util": "1.8.69-beta-650a290b",
26
+ "@arcblock/did": "1.18.59",
27
+ "@arcblock/jwt": "^1.18.59",
28
+ "@arcblock/vc": "1.18.59",
29
+ "@blocklet/constant": "1.8.69-beta-650a290b",
30
+ "@blocklet/meta": "1.8.69-beta-650a290b",
31
+ "@ocap/client": "1.18.59",
32
+ "@ocap/mcrypto": "1.18.59",
33
+ "@ocap/util": "1.18.59",
34
+ "@ocap/wallet": "1.18.59",
35
35
  "axios": "^0.27.2",
36
36
  "joi": "17.7.0",
37
37
  "jsonwebtoken": "^9.0.0",
@@ -43,5 +43,5 @@
43
43
  "devDependencies": {
44
44
  "jest": "^27.5.1"
45
45
  },
46
- "gitHead": "d6853c4b55a67526748017268257b869a5092cb1"
46
+ "gitHead": "a33c9ce6a52b8d522d13860e85809dcbba236712"
47
47
  }