@abtnode/core 1.8.69-beta-b0bb2d67 → 1.8.69-beta-76f8a46f
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/api/team.js +2 -2
- package/lib/blocklet/downloader/resolve-download.js +31 -0
- package/lib/blocklet/manager/base.js +8 -16
- package/lib/blocklet/manager/disk.js +367 -1659
- package/lib/blocklet/manager/helper/{install-from-backup.js → install-application-from-backup.js} +26 -19
- package/lib/blocklet/manager/helper/install-application-from-dev.js +94 -0
- package/lib/blocklet/manager/helper/install-application-from-general.js +188 -0
- package/lib/blocklet/manager/helper/install-component-from-dev.js +80 -0
- package/lib/blocklet/manager/helper/install-component-from-upload.js +181 -0
- package/lib/blocklet/manager/helper/install-component-from-url.js +173 -0
- package/lib/blocklet/manager/helper/migrate-application-to-struct-v2.js +377 -0
- package/lib/blocklet/manager/helper/upgrade-components.js +152 -0
- package/lib/blocklet/storage/backup/spaces.js +14 -14
- package/lib/index.js +7 -7
- package/lib/router/helper.js +5 -7
- package/lib/states/blocklet-extras.js +44 -0
- package/lib/states/blocklet.js +56 -4
- package/lib/states/node.js +1 -0
- package/lib/states/site.js +15 -6
- package/lib/team/manager.js +5 -0
- package/lib/util/blocklet.js +177 -132
- package/lib/util/get-domain-for-blocklet.js +5 -14
- package/lib/util/get-meta-from-url.js +33 -0
- package/lib/util/index.js +0 -5
- package/lib/util/store.js +44 -6
- package/lib/webhook/sender/wallet/index.js +3 -0
- package/package.json +26 -26
|
@@ -171,7 +171,7 @@ class SpacesBackup {
|
|
|
171
171
|
* @type {import('@abtnode/client').NodeState}
|
|
172
172
|
*/
|
|
173
173
|
const node = await states.node.read();
|
|
174
|
-
const
|
|
174
|
+
const serverDid = node.did;
|
|
175
175
|
|
|
176
176
|
const spaceClient = new SpaceClient({
|
|
177
177
|
endpoint: this.spaceEndpoint,
|
|
@@ -186,7 +186,8 @@ class SpacesBackup {
|
|
|
186
186
|
appDescription: getAppDescription(this.blocklet),
|
|
187
187
|
userDid: this.input.userDid,
|
|
188
188
|
referrer: this.input.referrer,
|
|
189
|
-
|
|
189
|
+
serverDid,
|
|
190
|
+
signerDid: this.securityContext.signer.address,
|
|
190
191
|
|
|
191
192
|
source: join(this.backupDir, '/'),
|
|
192
193
|
debug: true,
|
|
@@ -221,22 +222,21 @@ class SpacesBackup {
|
|
|
221
222
|
|
|
222
223
|
const { wallet, permanentWallet } = getBlockletInfo(blocklet, nodeInfo.sk);
|
|
223
224
|
|
|
224
|
-
// FIXME: @wangshijun migrated apps can not be restored, need to change core/webapp/api/routes/auth/verify-app-ownership.js
|
|
225
225
|
const { secretKey, address } = wallet; // we encrypt using latest wallet, not the permanent wallet
|
|
226
226
|
const password = toBuffer(Hasher.SHA3.hash256(Buffer.concat([secretKey, address].map(toBuffer))));
|
|
227
227
|
const encrypt = (v) => security.encrypt(v, address, password);
|
|
228
228
|
const decrypt = (v) => security.decrypt(v, address, password);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
229
|
+
const isRotated = permanentWallet.address !== wallet.address;
|
|
230
|
+
|
|
231
|
+
const delegation = isRotated
|
|
232
|
+
? signV2(permanentWallet.address, permanentWallet.secretKey, {
|
|
233
|
+
from: permanentWallet.address,
|
|
234
|
+
to: wallet.address,
|
|
235
|
+
userPk: permanentWallet.publicKey,
|
|
236
|
+
permissions: [{ role: 'DIDSpaceAgent', spaces: ['*'] }],
|
|
237
|
+
exp: Math.floor(new Date().getTime() / 1000) + 60 * 60,
|
|
238
|
+
})
|
|
239
|
+
: '';
|
|
240
240
|
|
|
241
241
|
return {
|
|
242
242
|
signer: wallet,
|
package/lib/index.js
CHANGED
|
@@ -32,6 +32,7 @@ const pm2Events = require('./blocklet/manager/pm2-events');
|
|
|
32
32
|
const { createStateReadyQueue, createStateReadyHandler } = require('./util/ready');
|
|
33
33
|
const { createDataArchive } = require('./util/blocklet');
|
|
34
34
|
const { toStatus, fromStatus, ensureDataDirs, getQueueConcurrencyByMem, getStateCrons } = require('./util');
|
|
35
|
+
const getMetaFromUrl = require('./util/get-meta-from-url');
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* @param {object} options
|
|
@@ -219,14 +220,12 @@ function ABTNode(options) {
|
|
|
219
220
|
deleteBlocklet: blockletManager.delete.bind(blockletManager),
|
|
220
221
|
deleteComponent: blockletManager.deleteComponent.bind(blockletManager),
|
|
221
222
|
cancelDownloadBlocklet: blockletManager.cancelDownload.bind(blockletManager),
|
|
222
|
-
upgradeBlocklet: blockletManager.upgrade.bind(blockletManager),
|
|
223
223
|
configBlocklet: blockletManager.config.bind(blockletManager),
|
|
224
224
|
devBlocklet: blockletManager.dev.bind(blockletManager),
|
|
225
|
-
checkComponentsForUpdates: blockletManager.
|
|
226
|
-
upgradeComponents: blockletManager.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
getBlockletByBundle: blockletManager.getBlockletByBundle.bind(blockletManager),
|
|
225
|
+
checkComponentsForUpdates: blockletManager.checkComponentsForUpdates.bind(blockletManager),
|
|
226
|
+
upgradeComponents: blockletManager.upgradeComponents.bind(blockletManager),
|
|
227
|
+
getBlockletMetaFromUrl: getMetaFromUrl.bind(blockletManager),
|
|
228
|
+
getBlockletForLauncher: blockletManager.getBlockletForLauncher.bind(blockletManager),
|
|
230
229
|
resetBlocklet: blockletManager.reset.bind(blockletManager),
|
|
231
230
|
deleteBlockletProcess: blockletManager.deleteProcess.bind(blockletManager),
|
|
232
231
|
configPublicToStore: blockletManager.configPublicToStore.bind(blockletManager),
|
|
@@ -236,6 +235,7 @@ function ABTNode(options) {
|
|
|
236
235
|
updateComponentMountPoint: blockletManager.updateComponentMountPoint.bind(blockletManager),
|
|
237
236
|
backupToSpaces: blockletManager.backupToSpaces.bind(blockletManager),
|
|
238
237
|
restoreFromSpaces: blockletManager.restoreFromSpaces.bind(blockletManager),
|
|
238
|
+
migrateApplicationToStructV2: blockletManager.migrateApplicationToStructV2.bind(blockletManager),
|
|
239
239
|
|
|
240
240
|
// For diagnose purpose
|
|
241
241
|
syncBlockletStatus: blockletManager.status.bind(blockletManager),
|
|
@@ -252,7 +252,7 @@ function ABTNode(options) {
|
|
|
252
252
|
|
|
253
253
|
// Store
|
|
254
254
|
getBlockletMeta: StoreUtil.getBlockletMeta,
|
|
255
|
-
|
|
255
|
+
getStoreMeta: StoreUtil.getStoreMeta,
|
|
256
256
|
|
|
257
257
|
// Node State
|
|
258
258
|
getNodeInfo: nodeAPI.getInfo.bind(nodeAPI),
|
package/lib/router/helper.js
CHANGED
|
@@ -65,6 +65,7 @@ const { getFromCache: getAccessibleExternalNodeIp } = require('../util/get-acces
|
|
|
65
65
|
const Router = require('./index');
|
|
66
66
|
const states = require('../states');
|
|
67
67
|
const { getBlockletDomainGroupName, getDidFromDomainGroupName } = require('../util/router');
|
|
68
|
+
const { getBlockletKnownAs } = require('../util/blocklet');
|
|
68
69
|
|
|
69
70
|
/**
|
|
70
71
|
* replace 888-888-888-888 with accessible ip for domain
|
|
@@ -791,7 +792,8 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
791
792
|
const { wallet } = getBlockletInfo(blocklet, nodeInfo.sk);
|
|
792
793
|
updateBlockletDocument({
|
|
793
794
|
wallet,
|
|
794
|
-
|
|
795
|
+
appPid: blocklet.appPid,
|
|
796
|
+
alsoKnownAs: getBlockletKnownAs(blocklet),
|
|
795
797
|
daemonDidDomain: getServerDidDomain(nodeInfo),
|
|
796
798
|
didRegistryUrl: nodeInfo.didRegistry,
|
|
797
799
|
domain: nodeInfo.didDomain,
|
|
@@ -806,12 +808,8 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
806
808
|
if (!existSite) {
|
|
807
809
|
const domainAliases = [];
|
|
808
810
|
|
|
809
|
-
const didDomain = getDidDomainForBlocklet({
|
|
810
|
-
|
|
811
|
-
didDomain: nodeInfo.didDomain,
|
|
812
|
-
});
|
|
813
|
-
|
|
814
|
-
const ipEchoDnsDomain = getIpDnsDomainForBlocklet(blocklet, webInterface, nodeInfo.did);
|
|
811
|
+
const didDomain = getDidDomainForBlocklet({ appPid: blocklet.appPid, didDomain: nodeInfo.didDomain });
|
|
812
|
+
const ipEchoDnsDomain = getIpDnsDomainForBlocklet(blocklet);
|
|
815
813
|
|
|
816
814
|
// let didDomain in front of ipEchoDnsDomain
|
|
817
815
|
domainAliases.push({ value: didDomain, isProtected: true }, { value: ipEchoDnsDomain, isProtected: true });
|
|
@@ -14,6 +14,50 @@ const { validateAddMeta, validateExpiredInfo } = require('../validators/blocklet
|
|
|
14
14
|
|
|
15
15
|
const noop = (k) => (v) => v[k];
|
|
16
16
|
|
|
17
|
+
// type Settings = {
|
|
18
|
+
// whoCanAccess: string;
|
|
19
|
+
// initialized: boolean;
|
|
20
|
+
// owner: {
|
|
21
|
+
// did: string;
|
|
22
|
+
// pk: string;
|
|
23
|
+
// };
|
|
24
|
+
// storeList: Array<getStoreMeta & {
|
|
25
|
+
// protected: boolean,
|
|
26
|
+
// url: string,
|
|
27
|
+
// }>; // 在 blocklet dashboard 添加组件时的商店列表
|
|
28
|
+
// navigations: any;
|
|
29
|
+
// trustedPassports: any;
|
|
30
|
+
// enablePassportIssuance: boolean;
|
|
31
|
+
// children: Array<any>; // deleted children
|
|
32
|
+
// publicToStore: boolean;
|
|
33
|
+
// navigation: Array[{
|
|
34
|
+
// title: string;
|
|
35
|
+
// child: DID | Name;
|
|
36
|
+
// }]; // deprecated
|
|
37
|
+
// };
|
|
38
|
+
|
|
39
|
+
// type Configs = {
|
|
40
|
+
// [componentDid: string]: Config;
|
|
41
|
+
// };
|
|
42
|
+
|
|
43
|
+
// type Children = Array<{
|
|
44
|
+
// did: string, // application index
|
|
45
|
+
// configs: Configs,
|
|
46
|
+
// children: Children
|
|
47
|
+
// }>;
|
|
48
|
+
|
|
49
|
+
// type ExtraState = {
|
|
50
|
+
// did: string; // application index
|
|
51
|
+
// meta: {
|
|
52
|
+
// did: string; // application index
|
|
53
|
+
// name: string; // application index
|
|
54
|
+
// };
|
|
55
|
+
// controller: BlockletController;
|
|
56
|
+
// settings: Settings;
|
|
57
|
+
// configs: Configs;
|
|
58
|
+
// children: Children
|
|
59
|
+
// };
|
|
60
|
+
|
|
17
61
|
class BlockletExtrasState extends BaseState {
|
|
18
62
|
constructor(baseDir, config = {}) {
|
|
19
63
|
super(baseDir, { filename: 'blocklet_extras.db', ...config });
|
package/lib/states/blocklet.js
CHANGED
|
@@ -17,18 +17,21 @@ const {
|
|
|
17
17
|
BLOCKLET_DEFAULT_PORT_NAME,
|
|
18
18
|
BLOCKLET_INTERFACE_TYPE_SERVICE,
|
|
19
19
|
} = require('@blocklet/constant');
|
|
20
|
+
const { APP_STRUCT_VERSION } = require('@abtnode/constant');
|
|
20
21
|
|
|
21
22
|
const logger = require('@abtnode/logger')('state-blocklet');
|
|
22
23
|
|
|
23
24
|
const BaseState = require('./base');
|
|
24
25
|
const { checkDuplicateComponents, ensureMeta } = require('../util/blocklet');
|
|
25
|
-
const { validateBlockletMeta } = require('../util');
|
|
26
|
+
const { validateBlockletMeta } = require('../util/blocklet');
|
|
26
27
|
|
|
27
28
|
const lock = new Lock('blocklet-port-assign-lock');
|
|
28
29
|
|
|
29
30
|
const isHex = (str) => /^0x[0-9a-f]+$/i.test(str);
|
|
30
31
|
const getMaxPort = (ports = {}) => Math.max(Object.values(ports).map(Number));
|
|
31
|
-
|
|
32
|
+
|
|
33
|
+
// structV1Did is just for migration purpose and should be removed in the future
|
|
34
|
+
const getConditions = (did) => [{ 'meta.did': did }, { appDid: did }, { appPid: did }, { structV1Did: did }];
|
|
32
35
|
|
|
33
36
|
const getExternalPortsFromMeta = (meta) =>
|
|
34
37
|
(meta.interfaces || []).map((x) => x.port && x.port.external).filter(Boolean);
|
|
@@ -88,6 +91,48 @@ const fixChildren = (children) => {
|
|
|
88
91
|
});
|
|
89
92
|
};
|
|
90
93
|
|
|
94
|
+
// type Application = {
|
|
95
|
+
// appDid: DID,
|
|
96
|
+
// appPid: DID,
|
|
97
|
+
// meta: Meta,
|
|
98
|
+
// source: BlockletSource,
|
|
99
|
+
// deployedFrom: string,
|
|
100
|
+
// mode: BLOCKLET_MODES;
|
|
101
|
+
// status: BlockletStatus,
|
|
102
|
+
// children: Component,
|
|
103
|
+
// ports: Ports;
|
|
104
|
+
// mountPoint: string; // deprecated
|
|
105
|
+
// migratedFrom: Array<{ appSk: string, appDid: DID, at: Date }>,
|
|
106
|
+
// externalSk: boolean,
|
|
107
|
+
// structV1Did: DID, // just for migration purpose and should be removed in the future
|
|
108
|
+
// };
|
|
109
|
+
|
|
110
|
+
// type Component = {
|
|
111
|
+
// mountPoint: string;
|
|
112
|
+
// meta: Meta,
|
|
113
|
+
// bundleSource: ComponentSource,
|
|
114
|
+
// source: BlockletSource,
|
|
115
|
+
// deployedFrom: string,
|
|
116
|
+
// mode: BLOCKLET_MODES;
|
|
117
|
+
// status: BlockletStatus,
|
|
118
|
+
// children: Component,
|
|
119
|
+
// ports: Ports;
|
|
120
|
+
// dependents: Array<{
|
|
121
|
+
// did: DID, // blocklet did
|
|
122
|
+
// required: boolean,
|
|
123
|
+
// version: SemverRange,
|
|
124
|
+
// }>;
|
|
125
|
+
// dependencies: Array<{
|
|
126
|
+
// id: string, // format: <did1/did2/did3>
|
|
127
|
+
// required: boolean,
|
|
128
|
+
// }>;
|
|
129
|
+
// dynamic: boolean; // deprecated
|
|
130
|
+
// };
|
|
131
|
+
|
|
132
|
+
// type Ports = {
|
|
133
|
+
// [name: string]: Number; // name is in meta.interfaces[].port
|
|
134
|
+
// };
|
|
135
|
+
|
|
91
136
|
class BlockletState extends BaseState {
|
|
92
137
|
/**
|
|
93
138
|
* Creates an instance of BlockletState
|
|
@@ -211,7 +256,9 @@ class BlockletState extends BaseState {
|
|
|
211
256
|
children: rawChildren = [],
|
|
212
257
|
appPid = null, // the permanent appDid, which will not change after initial set
|
|
213
258
|
migratedFrom = [], // the complete migrate history
|
|
214
|
-
|
|
259
|
+
// whether sk is managed by some party beside server, such as did-wallet
|
|
260
|
+
// externalSk is always true in struct V2 blocklet
|
|
261
|
+
externalSk = true,
|
|
215
262
|
} = {}) {
|
|
216
263
|
return this.getBlocklet(meta.did).then(
|
|
217
264
|
(exist) =>
|
|
@@ -253,6 +300,7 @@ class BlockletState extends BaseState {
|
|
|
253
300
|
children,
|
|
254
301
|
migratedFrom,
|
|
255
302
|
externalSk,
|
|
303
|
+
structVersion: APP_STRUCT_VERSION,
|
|
256
304
|
};
|
|
257
305
|
|
|
258
306
|
// add to db
|
|
@@ -273,6 +321,7 @@ class BlockletState extends BaseState {
|
|
|
273
321
|
);
|
|
274
322
|
}
|
|
275
323
|
|
|
324
|
+
// FIXME: 这个接口比较危险,可能会修改一些本不应该修改的字段,后续需要考虑改进
|
|
276
325
|
updateBlocklet(did, updates) {
|
|
277
326
|
return this.getBlocklet(did).then(
|
|
278
327
|
(doc) =>
|
|
@@ -612,7 +661,6 @@ class BlockletState extends BaseState {
|
|
|
612
661
|
source,
|
|
613
662
|
deployedFrom,
|
|
614
663
|
mode,
|
|
615
|
-
dynamic: true,
|
|
616
664
|
status: BlockletStatus.added,
|
|
617
665
|
children: child.children,
|
|
618
666
|
});
|
|
@@ -628,6 +676,10 @@ class BlockletState extends BaseState {
|
|
|
628
676
|
children: newChildren,
|
|
629
677
|
});
|
|
630
678
|
}
|
|
679
|
+
|
|
680
|
+
async updateStructV1Did(did, v1Did) {
|
|
681
|
+
return this.updateBlocklet(did, { structV1Did: v1Did });
|
|
682
|
+
}
|
|
631
683
|
}
|
|
632
684
|
|
|
633
685
|
BlockletState.BlockletStatus = BlockletStatus;
|
package/lib/states/node.js
CHANGED
package/lib/states/site.js
CHANGED
|
@@ -5,17 +5,26 @@ const BaseState = require('./base');
|
|
|
5
5
|
const { getBlockletDomainGroupName } = require('../util/router');
|
|
6
6
|
const { validateUpdateDomainAliases } = require('../validators/router');
|
|
7
7
|
|
|
8
|
+
// type Site = {
|
|
9
|
+
// id: string;
|
|
10
|
+
// domain: string;
|
|
11
|
+
// domainAliases: Array<{value: string, isProtected: boolean}>;
|
|
12
|
+
// isProtected: boolean;
|
|
13
|
+
// rules: Array<Rule>;
|
|
14
|
+
// corsAllowedOrigins: Array<string>;
|
|
15
|
+
// };
|
|
16
|
+
|
|
8
17
|
class SiteState extends BaseState {
|
|
9
18
|
constructor(baseDir, config = {}) {
|
|
10
19
|
super(baseDir, { filename: 'routing_rule.db', ...config });
|
|
11
20
|
}
|
|
12
21
|
|
|
13
|
-
async add(
|
|
14
|
-
const result = await this.insert(
|
|
22
|
+
async add(site) {
|
|
23
|
+
const result = await this.insert(site);
|
|
15
24
|
|
|
16
|
-
const
|
|
17
|
-
logger.info('
|
|
18
|
-
return
|
|
25
|
+
const tmpSite = SiteState.renameIdFiledName(result);
|
|
26
|
+
logger.info('site created', { site: tmpSite });
|
|
27
|
+
return tmpSite;
|
|
19
28
|
}
|
|
20
29
|
|
|
21
30
|
async addRuleToSite(id, rule) {
|
|
@@ -83,7 +92,7 @@ class SiteState extends BaseState {
|
|
|
83
92
|
|
|
84
93
|
async getBlockletDomains(did) {
|
|
85
94
|
const site = await this.findOneByBlocklet(did);
|
|
86
|
-
return site
|
|
95
|
+
return (site?.domainAliases || []).map((x) => x.value).filter(Boolean);
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
async updateDomainAliasList(id, domainAliases) {
|
package/lib/team/manager.js
CHANGED
|
@@ -12,6 +12,7 @@ const logger = require('@abtnode/logger')('@abtnode/core:team:manager');
|
|
|
12
12
|
const { ROLES, RBAC_CONFIG } = require('@abtnode/constant');
|
|
13
13
|
const { BlockletEvents } = require('@blocklet/constant');
|
|
14
14
|
const Lock = require('@abtnode/util/lib/lock');
|
|
15
|
+
const sleep = require('@abtnode/util/lib/sleep');
|
|
15
16
|
const UserState = require('../states/user');
|
|
16
17
|
const SessionState = require('../states/session');
|
|
17
18
|
|
|
@@ -363,6 +364,10 @@ class TeamManager extends EventEmitter {
|
|
|
363
364
|
if (this.cache[did].session) {
|
|
364
365
|
await closeDatabase(this.cache[did].session.db);
|
|
365
366
|
}
|
|
367
|
+
|
|
368
|
+
// NOTICE: wait for nedb to finish closeDatabase
|
|
369
|
+
const timeout = process.env.NODE_ENV !== 'test' ? 2000 : 200;
|
|
370
|
+
await sleep(timeout);
|
|
366
371
|
} catch (error) {
|
|
367
372
|
logger.error('Failed to close database', { did, error });
|
|
368
373
|
}
|