@abtnode/core 1.15.17 → 1.16.0-beta-b16cb035
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 +1679 -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 +572 -497
- 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 +194 -138
- package/lib/states/blocklet.js +361 -104
- 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,78 @@
|
|
|
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 dayjs = require('dayjs');
|
|
6
9
|
|
|
7
10
|
const BaseState = require('./base');
|
|
8
11
|
|
|
9
|
-
const { mergeConfigs } = require('../blocklet/extras');
|
|
12
|
+
const { mergeConfigs, parseConfigs, encryptConfigs } = require('../blocklet/extras');
|
|
13
|
+
const { validateAddMeta, validateExpiredInfo } = require('../validators/blocklet-extra');
|
|
14
|
+
|
|
15
|
+
const noop = (k) => (v) => v[k];
|
|
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
|
+
// };
|
|
10
60
|
|
|
11
61
|
class BlockletExtrasState extends BaseState {
|
|
12
|
-
constructor(baseDir,
|
|
13
|
-
super(baseDir, { filename: 'blocklet_extras.db', ...
|
|
62
|
+
constructor(baseDir, config = {}) {
|
|
63
|
+
super(baseDir, { filename: 'blocklet_extras.db', ...config });
|
|
14
64
|
|
|
15
65
|
this.extras = [
|
|
16
66
|
// environment
|
|
17
67
|
{
|
|
18
68
|
name: 'configs',
|
|
19
69
|
beforeSet: mergeConfigs,
|
|
70
|
+
afterGet: parseConfigs,
|
|
20
71
|
},
|
|
21
72
|
|
|
22
73
|
// setting
|
|
23
74
|
{
|
|
24
75
|
name: 'settings',
|
|
25
|
-
beforeSet: (old, cur) => {
|
|
76
|
+
beforeSet: ({ old, cur }) => {
|
|
26
77
|
const merged = { ...old, ...cur };
|
|
27
78
|
Object.keys(merged).forEach((key) => {
|
|
28
79
|
if (merged[key] === undefined || merged[key] === null) {
|
|
@@ -33,25 +84,29 @@ class BlockletExtrasState extends BaseState {
|
|
|
33
84
|
},
|
|
34
85
|
},
|
|
35
86
|
];
|
|
87
|
+
|
|
88
|
+
this.childExtras = this.extras.filter((x) => ['configs'].includes(x.name));
|
|
89
|
+
|
|
36
90
|
this.generateExtraFns();
|
|
37
91
|
}
|
|
38
92
|
|
|
93
|
+
delete(did) {
|
|
94
|
+
return this.remove({ did });
|
|
95
|
+
}
|
|
96
|
+
|
|
39
97
|
generateExtraFns() {
|
|
40
|
-
const methods = ['get', 'set', 'del'];
|
|
98
|
+
const methods = ['get', 'set', 'del', 'list'];
|
|
41
99
|
methods.forEach((method) => {
|
|
42
100
|
this.extras.forEach((extra) => {
|
|
43
101
|
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);
|
|
102
|
+
this[fn] = this.generateFn(method, extra);
|
|
48
103
|
});
|
|
49
104
|
});
|
|
50
105
|
}
|
|
51
106
|
|
|
52
|
-
// generate
|
|
107
|
+
// generate functions
|
|
53
108
|
|
|
54
|
-
|
|
109
|
+
generateFn(method, extra) {
|
|
55
110
|
if (method === 'get') {
|
|
56
111
|
return this.generateGetFn(extra);
|
|
57
112
|
}
|
|
@@ -63,176 +118,177 @@ class BlockletExtrasState extends BaseState {
|
|
|
63
118
|
if (method === 'del') {
|
|
64
119
|
return this.generateDelFn(extra);
|
|
65
120
|
}
|
|
121
|
+
|
|
122
|
+
if (method === 'list') {
|
|
123
|
+
return this.generateListFn(extra);
|
|
124
|
+
}
|
|
66
125
|
}
|
|
67
126
|
|
|
68
127
|
generateGetFn(extra) {
|
|
69
|
-
return async (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
128
|
+
return async (dids, path, defaultValue) => {
|
|
129
|
+
// eslint-disable-next-line no-param-reassign
|
|
130
|
+
dids = [].concat(dids);
|
|
131
|
+
const [rootDid, ...childDids] = dids;
|
|
132
|
+
const { dek } = this.config;
|
|
133
|
+
const { name, afterGet = noop('data') } = extra;
|
|
134
|
+
|
|
135
|
+
let item = await this.findOne({ did: rootDid });
|
|
136
|
+
while (item && childDids.length) {
|
|
137
|
+
const did = childDids.shift();
|
|
138
|
+
item = (item.children || []).find((x) => x.did === did);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const data = afterGet({ data: item ? item[name] : item, did: rootDid, dek });
|
|
142
|
+
if (!path) {
|
|
143
|
+
return data;
|
|
144
|
+
}
|
|
145
|
+
return get(data, path, defaultValue);
|
|
73
146
|
};
|
|
74
147
|
}
|
|
75
148
|
|
|
76
149
|
generateSetFn(extra) {
|
|
77
|
-
return async (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
150
|
+
return async (dids, data) => {
|
|
151
|
+
// eslint-disable-next-line no-param-reassign
|
|
152
|
+
dids = [].concat(dids);
|
|
153
|
+
const [rootDid, ...childDids] = dids;
|
|
154
|
+
const { dek } = this.config;
|
|
155
|
+
const { name, beforeSet = noop('cur') } = extra;
|
|
156
|
+
const exist = await this.findOne({ did: rootDid });
|
|
157
|
+
|
|
158
|
+
const item = exist || { did: rootDid };
|
|
159
|
+
let component = item;
|
|
160
|
+
while (childDids.length) {
|
|
161
|
+
const did = childDids.shift();
|
|
162
|
+
component.children = component.children || [];
|
|
163
|
+
let child = component.children.find((x) => x.did === did);
|
|
164
|
+
if (!child) {
|
|
165
|
+
child = { did };
|
|
166
|
+
component.children.push(child);
|
|
167
|
+
}
|
|
168
|
+
component = child;
|
|
169
|
+
}
|
|
81
170
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
171
|
+
const old = component[name];
|
|
172
|
+
const newData = beforeSet({ old, cur: data, did: rootDid, dek });
|
|
173
|
+
component[name] = newData;
|
|
174
|
+
|
|
175
|
+
if (!exist) {
|
|
176
|
+
await this.insert(item);
|
|
177
|
+
logger.info('create extra success', { name, dids });
|
|
178
|
+
} else {
|
|
179
|
+
await this.update(item._id, item);
|
|
180
|
+
logger.info('update extra success', { name, dids });
|
|
91
181
|
}
|
|
92
182
|
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
[name]: hasBeforeSet ? beforeSet(itemNameValue, data) : data,
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
return updated[name];
|
|
183
|
+
// re get data because should return decrypted secure value
|
|
184
|
+
const getFn = this[camelCase(`get ${extra.name}`)].bind(this);
|
|
185
|
+
return getFn(dids);
|
|
100
186
|
};
|
|
101
187
|
}
|
|
102
188
|
|
|
103
189
|
generateDelFn(extra) {
|
|
104
|
-
return async (
|
|
190
|
+
return async (dids) => {
|
|
191
|
+
// eslint-disable-next-line no-param-reassign
|
|
192
|
+
dids = [].concat(dids);
|
|
193
|
+
const [rootDid, ...childDids] = dids;
|
|
105
194
|
const { name } = extra;
|
|
106
|
-
const item = await this.
|
|
195
|
+
const item = await this.findOne({ did: rootDid });
|
|
107
196
|
|
|
108
197
|
if (!item) {
|
|
109
|
-
return
|
|
198
|
+
return null;
|
|
110
199
|
}
|
|
111
200
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
201
|
+
let component = item;
|
|
202
|
+
while (component && childDids.length) {
|
|
203
|
+
const did = childDids.shift();
|
|
204
|
+
component = (component.children || []).find((x) => x.did === did);
|
|
205
|
+
}
|
|
116
206
|
|
|
117
|
-
|
|
207
|
+
if (!component) {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
118
210
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return this.generateGetChildFn(extra);
|
|
122
|
-
}
|
|
211
|
+
const updated = component[name];
|
|
212
|
+
component[name] = null;
|
|
123
213
|
|
|
124
|
-
|
|
125
|
-
return this.generateSetChildFn(extra);
|
|
126
|
-
}
|
|
214
|
+
await this.update(item._id, item);
|
|
127
215
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
216
|
+
return updated;
|
|
217
|
+
};
|
|
131
218
|
}
|
|
132
219
|
|
|
133
|
-
|
|
134
|
-
return async (
|
|
135
|
-
const {
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
const
|
|
139
|
-
|
|
220
|
+
generateListFn(extra) {
|
|
221
|
+
return async () => {
|
|
222
|
+
const { dek } = this.config;
|
|
223
|
+
const { name, afterGet = noop('data') } = extra;
|
|
224
|
+
const docs = await this.find({});
|
|
225
|
+
const list = docs
|
|
226
|
+
.filter((x) => x[name])
|
|
227
|
+
.map((x) => ({
|
|
228
|
+
did: x.did,
|
|
229
|
+
[name]: afterGet({ data: x[name], did: x.did, dek }),
|
|
230
|
+
}));
|
|
231
|
+
return list;
|
|
140
232
|
};
|
|
141
233
|
}
|
|
142
234
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
235
|
+
async addMeta({ did, meta, controller } = {}) {
|
|
236
|
+
const entity = { did, meta };
|
|
237
|
+
if (controller) {
|
|
238
|
+
entity.controller = controller;
|
|
239
|
+
}
|
|
148
240
|
|
|
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
|
-
}
|
|
241
|
+
await validateAddMeta(entity);
|
|
166
242
|
|
|
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
|
-
}
|
|
243
|
+
return super.update({ did }, { $set: entity }, { upsert: true });
|
|
244
|
+
}
|
|
184
245
|
|
|
185
|
-
|
|
246
|
+
async getMeta(did) {
|
|
247
|
+
return super.findOne({ did }, { did: 1, controller: 1, meta: 1 });
|
|
248
|
+
}
|
|
186
249
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
});
|
|
250
|
+
async updateExpireInfo({ did, expiredAt } = {}) {
|
|
251
|
+
const entity = { did, expiredAt };
|
|
252
|
+
await validateExpiredInfo(entity);
|
|
192
253
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
children,
|
|
196
|
-
},
|
|
197
|
-
});
|
|
254
|
+
return super.update({ did }, { $set: { expiredAt } });
|
|
255
|
+
}
|
|
198
256
|
|
|
199
|
-
|
|
200
|
-
|
|
257
|
+
async getExpiredList() {
|
|
258
|
+
const now = dayjs();
|
|
259
|
+
|
|
260
|
+
return super.find({
|
|
261
|
+
'controller.nftId': { $exists: true },
|
|
262
|
+
expiredAt: { $exists: true, $lte: now.subtract(EXPIRED_BLOCKLET_DATA_RETENTION_DAYS, 'days').toISOString() },
|
|
263
|
+
});
|
|
201
264
|
}
|
|
202
265
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
266
|
+
encryptSecurityData({ data, _rootDid } = {}) {
|
|
267
|
+
if (!data) {
|
|
268
|
+
return data;
|
|
269
|
+
}
|
|
207
270
|
|
|
208
|
-
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
271
|
+
const { dek } = this.config;
|
|
211
272
|
|
|
212
|
-
|
|
213
|
-
|
|
273
|
+
if (!dek) {
|
|
274
|
+
return data;
|
|
275
|
+
}
|
|
214
276
|
|
|
215
|
-
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
277
|
+
const did = _rootDid || data.did;
|
|
218
278
|
|
|
219
|
-
|
|
279
|
+
if (!did) {
|
|
280
|
+
throw new Error('data.did does not exist');
|
|
281
|
+
}
|
|
220
282
|
|
|
221
|
-
|
|
222
|
-
if (x.did === childDid) {
|
|
223
|
-
updated = x[name];
|
|
224
|
-
x[name] = null;
|
|
225
|
-
}
|
|
226
|
-
});
|
|
283
|
+
encryptConfigs({ data: data.configs, did, dek });
|
|
227
284
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
285
|
+
if (Array.isArray(data.children)) {
|
|
286
|
+
for (const child of data.children) {
|
|
287
|
+
this.encryptSecurityData({ data: child, _rootDid: did });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
233
290
|
|
|
234
|
-
|
|
235
|
-
};
|
|
291
|
+
return data;
|
|
236
292
|
}
|
|
237
293
|
}
|
|
238
294
|
|