@abtnode/core 1.15.17 → 1.16.0-beta-8ee536d7
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/node.js +67 -69
- package/lib/api/team.js +386 -55
- package/lib/blocklet/downloader/blocklet-downloader.js +226 -0
- package/lib/blocklet/downloader/bundle-downloader.js +272 -0
- package/lib/blocklet/downloader/constants.js +3 -0
- package/lib/blocklet/downloader/resolve-download.js +199 -0
- package/lib/blocklet/extras.js +83 -26
- package/lib/blocklet/hooks.js +18 -65
- package/lib/blocklet/manager/base.js +10 -16
- package/lib/blocklet/manager/disk.js +1680 -1566
- package/lib/blocklet/manager/helper/install-application-from-backup.js +177 -0
- 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 +84 -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 +450 -0
- package/lib/blocklet/manager/helper/rollback-cache.js +41 -0
- package/lib/blocklet/manager/helper/upgrade-components.js +152 -0
- package/lib/blocklet/migration.js +30 -52
- package/lib/blocklet/storage/backup/audit-log.js +27 -0
- package/lib/blocklet/storage/backup/base.js +62 -0
- package/lib/blocklet/storage/backup/blocklet-extras.js +92 -0
- package/lib/blocklet/storage/backup/blocklet.js +70 -0
- package/lib/blocklet/storage/backup/blocklets.js +74 -0
- package/lib/blocklet/storage/backup/data.js +19 -0
- package/lib/blocklet/storage/backup/logs.js +24 -0
- package/lib/blocklet/storage/backup/routing-rule.js +19 -0
- package/lib/blocklet/storage/backup/spaces.js +240 -0
- package/lib/blocklet/storage/restore/base.js +67 -0
- package/lib/blocklet/storage/restore/blocklet-extras.js +86 -0
- package/lib/blocklet/storage/restore/blocklet.js +56 -0
- package/lib/blocklet/storage/restore/blocklets.js +43 -0
- package/lib/blocklet/storage/restore/logs.js +21 -0
- package/lib/blocklet/storage/restore/spaces.js +156 -0
- package/lib/blocklet/storage/utils/hash.js +51 -0
- package/lib/blocklet/storage/utils/zip.js +43 -0
- package/lib/cert.js +206 -0
- package/lib/event.js +237 -64
- package/lib/index.js +191 -83
- package/lib/migrations/1.0.21-update-config.js +1 -1
- package/lib/migrations/1.0.22-max-memory.js +1 -1
- package/lib/migrations/1.0.25.js +1 -1
- package/lib/migrations/1.0.32-update-config.js +1 -1
- package/lib/migrations/1.0.33-blocklets.js +1 -1
- package/lib/migrations/1.5.20-registry.js +15 -0
- package/lib/migrations/1.6.17-blocklet-children.js +48 -0
- package/lib/migrations/1.6.21-rename-ip-echo-domain.js +35 -0
- package/lib/migrations/1.6.4-security.js +59 -0
- package/lib/migrations/1.6.5-security.js +60 -0
- package/lib/migrations/1.6.9-update-node-info-and-certificate.js +38 -0
- package/lib/migrations/1.7.1-blocklet-setup.js +18 -0
- package/lib/migrations/1.7.12-blocklet-meta.js +51 -0
- package/lib/migrations/1.7.15-blocklet-bundle-source.js +42 -0
- package/lib/migrations/1.7.20-blocklet-component.js +41 -0
- package/lib/migrations/1.8.33-blocklet-mem-limit.js +20 -0
- package/lib/migrations/README.md +1 -1
- package/lib/migrations/index.js +6 -2
- package/lib/monitor/blocklet-runtime-monitor.js +200 -0
- package/lib/monitor/get-history-list.js +37 -0
- package/lib/monitor/node-runtime-monitor.js +228 -0
- package/lib/router/helper.js +576 -500
- package/lib/router/index.js +85 -21
- package/lib/router/manager.js +146 -187
- package/lib/states/README.md +36 -1
- package/lib/states/access-key.js +39 -17
- package/lib/states/audit-log.js +462 -0
- package/lib/states/base.js +4 -213
- package/lib/states/blocklet-extras.js +195 -138
- package/lib/states/blocklet.js +371 -110
- package/lib/states/cache.js +8 -6
- package/lib/states/challenge.js +5 -5
- package/lib/states/index.js +19 -36
- package/lib/states/migration.js +4 -4
- package/lib/states/node.js +135 -46
- package/lib/states/notification.js +22 -35
- package/lib/states/session.js +17 -9
- package/lib/states/site.js +50 -25
- package/lib/states/user.js +74 -20
- package/lib/states/webhook.js +10 -6
- package/lib/team/manager.js +124 -7
- package/lib/util/blocklet.js +1223 -246
- package/lib/util/chain.js +1 -1
- package/lib/util/default-node-config.js +5 -23
- package/lib/util/disk-monitor.js +13 -10
- package/lib/util/domain-status.js +84 -15
- package/lib/util/get-accessible-external-node-ip.js +2 -2
- package/lib/util/get-domain-for-blocklet.js +13 -0
- package/lib/util/get-meta-from-url.js +33 -0
- package/lib/util/index.js +207 -272
- package/lib/util/ip.js +6 -0
- package/lib/util/maintain.js +233 -0
- package/lib/util/public-to-store.js +85 -0
- package/lib/util/ready.js +1 -1
- package/lib/util/requirement.js +28 -9
- package/lib/util/reset-node.js +22 -7
- package/lib/util/router.js +13 -0
- package/lib/util/rpc.js +16 -0
- package/lib/util/store.js +179 -0
- package/lib/util/sysinfo.js +44 -0
- package/lib/util/ua.js +54 -0
- package/lib/validators/blocklet-extra.js +24 -0
- package/lib/validators/node.js +25 -12
- package/lib/validators/permission.js +16 -1
- package/lib/validators/role.js +17 -3
- package/lib/validators/router.js +40 -20
- package/lib/validators/trusted-passport.js +1 -0
- package/lib/validators/util.js +22 -5
- package/lib/webhook/index.js +45 -35
- package/lib/webhook/sender/index.js +5 -0
- package/lib/webhook/sender/slack/index.js +1 -1
- package/lib/webhook/sender/wallet/index.js +48 -0
- package/package.json +54 -36
- package/lib/blocklet/registry.js +0 -205
- package/lib/states/https-cert.js +0 -67
- package/lib/util/get-ip-dns-domain-for-blocklet.js +0 -19
- package/lib/util/service.js +0 -66
- package/lib/util/upgrade.js +0 -178
- /package/lib/{queue.js → util/queue.js} +0 -0
package/lib/states/base.js
CHANGED
|
@@ -1,226 +1,17 @@
|
|
|
1
|
-
const
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const util = require('util');
|
|
4
|
-
const { EventEmitter } = require('events');
|
|
5
|
-
const cloneDeep = require('lodash/cloneDeep');
|
|
6
|
-
const DataStore =
|
|
7
|
-
process.env.NODE_ENV === 'test' ? require('@nedb/core') : require('@nedb/multi')(Number(process.env.NEDB_MULTI_PORT));
|
|
1
|
+
const DB = require('@abtnode/db');
|
|
8
2
|
const logger = require('@abtnode/logger')('@abtnode/core:states');
|
|
9
3
|
|
|
10
4
|
const { isCLI } = require('../util');
|
|
11
5
|
|
|
12
|
-
class BaseState extends
|
|
13
|
-
constructor(baseDir,
|
|
14
|
-
super();
|
|
6
|
+
class BaseState extends DB {
|
|
7
|
+
constructor(baseDir, config) {
|
|
8
|
+
super(baseDir, config);
|
|
15
9
|
|
|
16
10
|
// HACK: do not emit any events from CLI
|
|
17
11
|
if (isCLI() && process.env.NODE_ENV !== 'test') {
|
|
18
12
|
this.emit = (name) => logger.debug('stopped state db event in CLI', name);
|
|
19
13
|
}
|
|
20
|
-
|
|
21
|
-
const dbOptions = options.db || {};
|
|
22
|
-
this.filename = path.join(baseDir, options.filename);
|
|
23
|
-
this.options = Object.freeze(cloneDeep(options));
|
|
24
|
-
this.db = new DataStore({
|
|
25
|
-
filename: this.filename,
|
|
26
|
-
timestampData: true,
|
|
27
|
-
...dbOptions,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
logger.info('initialized', { filename: this.filename });
|
|
31
|
-
|
|
32
|
-
this.ready = false;
|
|
33
|
-
this.readyCallbacks = [];
|
|
34
|
-
this.db.loadDatabase((err) => {
|
|
35
|
-
if (err) {
|
|
36
|
-
logger.error(`failed to load disk database ${this.filename}`, { error: err });
|
|
37
|
-
console.error(err);
|
|
38
|
-
} else {
|
|
39
|
-
this.ready = true;
|
|
40
|
-
if (this.readyCallbacks.length) {
|
|
41
|
-
this.readyCallbacks.forEach((x) => x());
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
this.asyncDB = new Proxy(this.db, {
|
|
47
|
-
get(target, property) {
|
|
48
|
-
if (typeof target[property] === 'function') {
|
|
49
|
-
return util
|
|
50
|
-
.promisify((...args) => {
|
|
51
|
-
const cb = args[args.length - 1];
|
|
52
|
-
const rest = args.slice(0, args.length - 1);
|
|
53
|
-
|
|
54
|
-
target[property](...rest, (err, ...result) => {
|
|
55
|
-
if (err) {
|
|
56
|
-
return cb(err);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (result.length === 1) {
|
|
60
|
-
return cb(null, result[0]);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return cb(null, result);
|
|
64
|
-
});
|
|
65
|
-
})
|
|
66
|
-
.bind(target);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return target[property];
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
onReady(cb) {
|
|
75
|
-
if (this.ready) {
|
|
76
|
-
cb();
|
|
77
|
-
} else {
|
|
78
|
-
this.readyCallbacks.push(cb);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
createNotification(payload) {
|
|
83
|
-
if (this.notification && typeof this.notification.create === 'function') {
|
|
84
|
-
this.notification.create(payload);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
paginate(conditions, sort, paging) {
|
|
89
|
-
const { pageSize: size = 20, page = 1 } = paging || {};
|
|
90
|
-
const pageSize = Math.min(100, size);
|
|
91
|
-
|
|
92
|
-
return new Promise((resolve, reject) => {
|
|
93
|
-
this.db
|
|
94
|
-
.find(conditions)
|
|
95
|
-
.sort(sort)
|
|
96
|
-
.exec((err, docs) => {
|
|
97
|
-
if (err) {
|
|
98
|
-
return reject(err);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const pageCount = Math.ceil(docs.length / pageSize);
|
|
102
|
-
const total = docs.length;
|
|
103
|
-
const skip = (page - 1) * pageSize;
|
|
104
|
-
const list = docs.slice(skip, skip + pageSize);
|
|
105
|
-
|
|
106
|
-
list.forEach((doc) => {
|
|
107
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
108
|
-
doc.id = doc._id;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return resolve({
|
|
112
|
-
list,
|
|
113
|
-
paging: {
|
|
114
|
-
total,
|
|
115
|
-
pageSize,
|
|
116
|
-
pageCount,
|
|
117
|
-
page,
|
|
118
|
-
},
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async updateById(id, updates, options = {}) {
|
|
125
|
-
const [, doc] = await this.asyncDB.update({ _id: id }, updates, {
|
|
126
|
-
multi: false,
|
|
127
|
-
upsert: false,
|
|
128
|
-
returnUpdatedDocs: true,
|
|
129
|
-
...options,
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
return doc;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
update(...args) {
|
|
136
|
-
if (args.length === 0) {
|
|
137
|
-
throw new Error('param is required by update method');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (typeof args[0] === 'string') {
|
|
141
|
-
return this.updateById(...args);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return this.asyncDB.update(args[0], args[1], { returnUpdatedDocs: true, ...(args[2] || {}) });
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
count(conditions = {}) {
|
|
148
|
-
return new Promise((resolve, reject) => {
|
|
149
|
-
this.db.count(conditions, (err, num) => {
|
|
150
|
-
if (err) {
|
|
151
|
-
return reject(err);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return resolve(num);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
remove(conditions = {}, options = { multi: false }) {
|
|
160
|
-
return new Promise((resolve, reject) => {
|
|
161
|
-
this.db.remove(conditions, options, (err, num) => {
|
|
162
|
-
if (err) {
|
|
163
|
-
return reject(err);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return resolve(num);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
reset() {
|
|
172
|
-
fs.unlinkSync(this.filename);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
find(...args) {
|
|
176
|
-
if (args.length === 0) {
|
|
177
|
-
return this.asyncDB.find({});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return this.asyncDB.find(...args);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
findOne(...args) {
|
|
184
|
-
if (args.length === 0) {
|
|
185
|
-
return this.asyncDB.findOne({});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return this.asyncDB.findOne(...args);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
insert(...args) {
|
|
192
|
-
return this.asyncDB.insert(...args);
|
|
193
14
|
}
|
|
194
15
|
}
|
|
195
16
|
|
|
196
|
-
/**
|
|
197
|
-
* Rename _id field name to id, this method has side effects
|
|
198
|
-
* @param {object} entities
|
|
199
|
-
*/
|
|
200
|
-
const renameIdFiledName = (entities, from = '_id', to = 'id') => {
|
|
201
|
-
/* eslint-disable no-underscore-dangle, no-param-reassign */
|
|
202
|
-
|
|
203
|
-
if (!entities) {
|
|
204
|
-
return entities;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const mapEntity = (entity) => {
|
|
208
|
-
if (entity[from]) {
|
|
209
|
-
entity[to] = entity[from];
|
|
210
|
-
delete entity[from];
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
if (!Array.isArray(entities)) {
|
|
215
|
-
mapEntity(entities);
|
|
216
|
-
return entities;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
entities.forEach(mapEntity);
|
|
220
|
-
|
|
221
|
-
return entities;
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
BaseState.renameIdFiledName = renameIdFiledName;
|
|
225
|
-
|
|
226
17
|
module.exports = BaseState;
|
|
@@ -2,27 +2,79 @@
|
|
|
2
2
|
/* eslint-disable no-underscore-dangle */
|
|
3
3
|
/* eslint-disable consistent-return */
|
|
4
4
|
const logger = require('@abtnode/logger')('state-blocklet-extras');
|
|
5
|
+
const { EXPIRED_BLOCKLET_DATA_RETENTION_DAYS } = require('@abtnode/constant');
|
|
5
6
|
const camelCase = require('lodash/camelCase');
|
|
7
|
+
const get = require('lodash/get');
|
|
8
|
+
const uniq = require('lodash/uniq');
|
|
9
|
+
const dayjs = require('dayjs');
|
|
6
10
|
|
|
7
11
|
const BaseState = require('./base');
|
|
8
12
|
|
|
9
|
-
const { mergeConfigs } = require('../blocklet/extras');
|
|
13
|
+
const { mergeConfigs, parseConfigs, encryptConfigs } = require('../blocklet/extras');
|
|
14
|
+
const { validateAddMeta, validateExpiredInfo } = require('../validators/blocklet-extra');
|
|
15
|
+
|
|
16
|
+
const noop = (k) => (v) => v[k];
|
|
17
|
+
|
|
18
|
+
// type Settings = {
|
|
19
|
+
// whoCanAccess: string;
|
|
20
|
+
// initialized: boolean;
|
|
21
|
+
// owner: {
|
|
22
|
+
// did: string;
|
|
23
|
+
// pk: string;
|
|
24
|
+
// };
|
|
25
|
+
// storeList: Array<getStoreMeta & {
|
|
26
|
+
// protected: boolean,
|
|
27
|
+
// url: string,
|
|
28
|
+
// }>; // 在 blocklet dashboard 添加组件时的商店列表
|
|
29
|
+
// navigations: any;
|
|
30
|
+
// trustedPassports: any;
|
|
31
|
+
// enablePassportIssuance: boolean;
|
|
32
|
+
// children: Array<any>; // deleted children
|
|
33
|
+
// publicToStore: boolean;
|
|
34
|
+
// navigation: Array[{
|
|
35
|
+
// title: string;
|
|
36
|
+
// child: DID | Name;
|
|
37
|
+
// }]; // deprecated
|
|
38
|
+
// };
|
|
39
|
+
|
|
40
|
+
// type Configs = {
|
|
41
|
+
// [componentDid: string]: Config;
|
|
42
|
+
// };
|
|
43
|
+
|
|
44
|
+
// type Children = Array<{
|
|
45
|
+
// did: string, // application index
|
|
46
|
+
// configs: Configs,
|
|
47
|
+
// children: Children
|
|
48
|
+
// }>;
|
|
49
|
+
|
|
50
|
+
// type ExtraState = {
|
|
51
|
+
// did: string; // application index
|
|
52
|
+
// meta: {
|
|
53
|
+
// did: string; // application index
|
|
54
|
+
// name: string; // application index
|
|
55
|
+
// };
|
|
56
|
+
// controller: BlockletController;
|
|
57
|
+
// settings: Settings;
|
|
58
|
+
// configs: Configs;
|
|
59
|
+
// children: Children
|
|
60
|
+
// };
|
|
10
61
|
|
|
11
62
|
class BlockletExtrasState extends BaseState {
|
|
12
|
-
constructor(baseDir,
|
|
13
|
-
super(baseDir, { filename: 'blocklet_extras.db', ...
|
|
63
|
+
constructor(baseDir, config = {}) {
|
|
64
|
+
super(baseDir, { filename: 'blocklet_extras.db', ...config });
|
|
14
65
|
|
|
15
66
|
this.extras = [
|
|
16
67
|
// environment
|
|
17
68
|
{
|
|
18
69
|
name: 'configs',
|
|
19
70
|
beforeSet: mergeConfigs,
|
|
71
|
+
afterGet: parseConfigs,
|
|
20
72
|
},
|
|
21
73
|
|
|
22
74
|
// setting
|
|
23
75
|
{
|
|
24
76
|
name: 'settings',
|
|
25
|
-
beforeSet: (old, cur) => {
|
|
77
|
+
beforeSet: ({ old, cur }) => {
|
|
26
78
|
const merged = { ...old, ...cur };
|
|
27
79
|
Object.keys(merged).forEach((key) => {
|
|
28
80
|
if (merged[key] === undefined || merged[key] === null) {
|
|
@@ -33,25 +85,29 @@ class BlockletExtrasState extends BaseState {
|
|
|
33
85
|
},
|
|
34
86
|
},
|
|
35
87
|
];
|
|
88
|
+
|
|
89
|
+
this.childExtras = this.extras.filter((x) => ['configs'].includes(x.name));
|
|
90
|
+
|
|
36
91
|
this.generateExtraFns();
|
|
37
92
|
}
|
|
38
93
|
|
|
94
|
+
delete(did) {
|
|
95
|
+
return this.remove({ did });
|
|
96
|
+
}
|
|
97
|
+
|
|
39
98
|
generateExtraFns() {
|
|
40
|
-
const methods = ['get', 'set', 'del'];
|
|
99
|
+
const methods = ['get', 'set', 'del', 'list'];
|
|
41
100
|
methods.forEach((method) => {
|
|
42
101
|
this.extras.forEach((extra) => {
|
|
43
102
|
const fn = camelCase(`${method} ${extra.name}`); // getConfigs, getRules
|
|
44
|
-
this[fn] = this.
|
|
45
|
-
|
|
46
|
-
const childFn = camelCase(`${method} child ${extra.name}`); // getChildConfigs, getChildRules
|
|
47
|
-
this[childFn] = this.generateExtraChildFn(method, extra);
|
|
103
|
+
this[fn] = this.generateFn(method, extra);
|
|
48
104
|
});
|
|
49
105
|
});
|
|
50
106
|
}
|
|
51
107
|
|
|
52
|
-
// generate
|
|
108
|
+
// generate functions
|
|
53
109
|
|
|
54
|
-
|
|
110
|
+
generateFn(method, extra) {
|
|
55
111
|
if (method === 'get') {
|
|
56
112
|
return this.generateGetFn(extra);
|
|
57
113
|
}
|
|
@@ -63,176 +119,177 @@ class BlockletExtrasState extends BaseState {
|
|
|
63
119
|
if (method === 'del') {
|
|
64
120
|
return this.generateDelFn(extra);
|
|
65
121
|
}
|
|
122
|
+
|
|
123
|
+
if (method === 'list') {
|
|
124
|
+
return this.generateListFn(extra);
|
|
125
|
+
}
|
|
66
126
|
}
|
|
67
127
|
|
|
68
128
|
generateGetFn(extra) {
|
|
69
|
-
return async (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
129
|
+
return async (dids, path, defaultValue) => {
|
|
130
|
+
// eslint-disable-next-line no-param-reassign
|
|
131
|
+
dids = uniq([].concat(dids));
|
|
132
|
+
const [rootDid, ...childDids] = dids;
|
|
133
|
+
const { dek } = this.config;
|
|
134
|
+
const { name, afterGet = noop('data') } = extra;
|
|
135
|
+
|
|
136
|
+
let item = await this.findOne({ did: rootDid });
|
|
137
|
+
while (item && childDids.length) {
|
|
138
|
+
const did = childDids.shift();
|
|
139
|
+
item = (item.children || []).find((x) => x.did === did);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const data = afterGet({ data: item ? item[name] : item, did: rootDid, dek });
|
|
143
|
+
if (!path) {
|
|
144
|
+
return data;
|
|
145
|
+
}
|
|
146
|
+
return get(data, path, defaultValue);
|
|
73
147
|
};
|
|
74
148
|
}
|
|
75
149
|
|
|
76
150
|
generateSetFn(extra) {
|
|
77
|
-
return async (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
151
|
+
return async (dids, data) => {
|
|
152
|
+
// eslint-disable-next-line no-param-reassign
|
|
153
|
+
dids = uniq([].concat(dids));
|
|
154
|
+
const [rootDid, ...childDids] = dids;
|
|
155
|
+
const { dek } = this.config;
|
|
156
|
+
const { name, beforeSet = noop('cur') } = extra;
|
|
157
|
+
const exist = await this.findOne({ did: rootDid });
|
|
158
|
+
|
|
159
|
+
const item = exist || { did: rootDid };
|
|
160
|
+
let component = item;
|
|
161
|
+
while (childDids.length) {
|
|
162
|
+
const did = childDids.shift();
|
|
163
|
+
component.children = component.children || [];
|
|
164
|
+
let child = component.children.find((x) => x.did === did);
|
|
165
|
+
if (!child) {
|
|
166
|
+
child = { did };
|
|
167
|
+
component.children.push(child);
|
|
168
|
+
}
|
|
169
|
+
component = child;
|
|
170
|
+
}
|
|
81
171
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
172
|
+
const old = component[name];
|
|
173
|
+
const newData = beforeSet({ old, cur: data, did: rootDid, dek });
|
|
174
|
+
component[name] = newData;
|
|
175
|
+
|
|
176
|
+
if (!exist) {
|
|
177
|
+
await this.insert(item);
|
|
178
|
+
logger.info('create extra success', { name, dids });
|
|
179
|
+
} else {
|
|
180
|
+
await this.update(item._id, item);
|
|
181
|
+
logger.info('update extra success', { name, dids });
|
|
91
182
|
}
|
|
92
183
|
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
[name]: hasBeforeSet ? beforeSet(itemNameValue, data) : data,
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
return updated[name];
|
|
184
|
+
// re get data because should return decrypted secure value
|
|
185
|
+
const getFn = this[camelCase(`get ${extra.name}`)].bind(this);
|
|
186
|
+
return getFn(dids);
|
|
100
187
|
};
|
|
101
188
|
}
|
|
102
189
|
|
|
103
190
|
generateDelFn(extra) {
|
|
104
|
-
return async (
|
|
191
|
+
return async (dids) => {
|
|
192
|
+
// eslint-disable-next-line no-param-reassign
|
|
193
|
+
dids = uniq([].concat(dids));
|
|
194
|
+
const [rootDid, ...childDids] = dids;
|
|
105
195
|
const { name } = extra;
|
|
106
|
-
const item = await this.
|
|
196
|
+
const item = await this.findOne({ did: rootDid });
|
|
107
197
|
|
|
108
198
|
if (!item) {
|
|
109
|
-
return
|
|
199
|
+
return null;
|
|
110
200
|
}
|
|
111
201
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
202
|
+
let component = item;
|
|
203
|
+
while (component && childDids.length) {
|
|
204
|
+
const did = childDids.shift();
|
|
205
|
+
component = (component.children || []).find((x) => x.did === did);
|
|
206
|
+
}
|
|
116
207
|
|
|
117
|
-
|
|
208
|
+
if (!component) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
118
211
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return this.generateGetChildFn(extra);
|
|
122
|
-
}
|
|
212
|
+
const updated = component[name];
|
|
213
|
+
component[name] = null;
|
|
123
214
|
|
|
124
|
-
|
|
125
|
-
return this.generateSetChildFn(extra);
|
|
126
|
-
}
|
|
215
|
+
await this.update(item._id, item);
|
|
127
216
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
217
|
+
return updated;
|
|
218
|
+
};
|
|
131
219
|
}
|
|
132
220
|
|
|
133
|
-
|
|
134
|
-
return async (
|
|
135
|
-
const {
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
const
|
|
139
|
-
|
|
221
|
+
generateListFn(extra) {
|
|
222
|
+
return async () => {
|
|
223
|
+
const { dek } = this.config;
|
|
224
|
+
const { name, afterGet = noop('data') } = extra;
|
|
225
|
+
const docs = await this.find({});
|
|
226
|
+
const list = docs
|
|
227
|
+
.filter((x) => x[name])
|
|
228
|
+
.map((x) => ({
|
|
229
|
+
did: x.did,
|
|
230
|
+
[name]: afterGet({ data: x[name], did: x.did, dek }),
|
|
231
|
+
}));
|
|
232
|
+
return list;
|
|
140
233
|
};
|
|
141
234
|
}
|
|
142
235
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
236
|
+
async addMeta({ did, meta, controller } = {}) {
|
|
237
|
+
const entity = { did, meta };
|
|
238
|
+
if (controller) {
|
|
239
|
+
entity.controller = controller;
|
|
240
|
+
}
|
|
148
241
|
|
|
149
|
-
|
|
150
|
-
const newData = hasBeforeSet ? beforeSet(undefined, data) : data;
|
|
151
|
-
const insertData = {
|
|
152
|
-
did,
|
|
153
|
-
children: [
|
|
154
|
-
{
|
|
155
|
-
did: childDid,
|
|
156
|
-
[name]: newData,
|
|
157
|
-
},
|
|
158
|
-
],
|
|
159
|
-
};
|
|
160
|
-
await this.asyncDB.insert(insertData);
|
|
161
|
-
|
|
162
|
-
logger.info('create info success; insert child info success');
|
|
163
|
-
|
|
164
|
-
return newData;
|
|
165
|
-
}
|
|
242
|
+
await validateAddMeta(entity);
|
|
166
243
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (!subItem) {
|
|
171
|
-
const newData = hasBeforeSet ? beforeSet(undefined, data) : data;
|
|
172
|
-
await this.update(item._id, {
|
|
173
|
-
$addToSet: {
|
|
174
|
-
children: {
|
|
175
|
-
did: childDid,
|
|
176
|
-
[name]: newData,
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
logger.info('insert child info success');
|
|
182
|
-
return newData;
|
|
183
|
-
}
|
|
244
|
+
return super.update({ did }, { $set: entity }, { upsert: true });
|
|
245
|
+
}
|
|
184
246
|
|
|
185
|
-
|
|
247
|
+
async getMeta(did) {
|
|
248
|
+
return super.findOne({ did }, { did: 1, controller: 1, meta: 1 });
|
|
249
|
+
}
|
|
186
250
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
});
|
|
251
|
+
async updateExpireInfo({ did, expiredAt } = {}) {
|
|
252
|
+
const entity = { did, expiredAt };
|
|
253
|
+
await validateExpiredInfo(entity);
|
|
192
254
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
children,
|
|
196
|
-
},
|
|
197
|
-
});
|
|
255
|
+
return super.update({ did }, { $set: { expiredAt } });
|
|
256
|
+
}
|
|
198
257
|
|
|
199
|
-
|
|
200
|
-
|
|
258
|
+
async getExpiredList() {
|
|
259
|
+
const now = dayjs();
|
|
260
|
+
|
|
261
|
+
return super.find({
|
|
262
|
+
'controller.nftId': { $exists: true },
|
|
263
|
+
expiredAt: { $exists: true, $lte: now.subtract(EXPIRED_BLOCKLET_DATA_RETENTION_DAYS, 'days').toISOString() },
|
|
264
|
+
});
|
|
201
265
|
}
|
|
202
266
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
267
|
+
encryptSecurityData({ data, _rootDid } = {}) {
|
|
268
|
+
if (!data) {
|
|
269
|
+
return data;
|
|
270
|
+
}
|
|
207
271
|
|
|
208
|
-
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
272
|
+
const { dek } = this.config;
|
|
211
273
|
|
|
212
|
-
|
|
213
|
-
|
|
274
|
+
if (!dek) {
|
|
275
|
+
return data;
|
|
276
|
+
}
|
|
214
277
|
|
|
215
|
-
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
278
|
+
const did = _rootDid || data.did;
|
|
218
279
|
|
|
219
|
-
|
|
280
|
+
if (!did) {
|
|
281
|
+
throw new Error('data.did does not exist');
|
|
282
|
+
}
|
|
220
283
|
|
|
221
|
-
|
|
222
|
-
if (x.did === childDid) {
|
|
223
|
-
updated = x[name];
|
|
224
|
-
x[name] = null;
|
|
225
|
-
}
|
|
226
|
-
});
|
|
284
|
+
encryptConfigs({ data: data.configs, did, dek });
|
|
227
285
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
286
|
+
if (Array.isArray(data.children)) {
|
|
287
|
+
for (const child of data.children) {
|
|
288
|
+
this.encryptSecurityData({ data: child, _rootDid: did });
|
|
289
|
+
}
|
|
290
|
+
}
|
|
233
291
|
|
|
234
|
-
|
|
235
|
-
};
|
|
292
|
+
return data;
|
|
236
293
|
}
|
|
237
294
|
}
|
|
238
295
|
|