@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.
Files changed (119) hide show
  1. package/lib/api/node.js +67 -69
  2. package/lib/api/team.js +386 -55
  3. package/lib/blocklet/downloader/blocklet-downloader.js +226 -0
  4. package/lib/blocklet/downloader/bundle-downloader.js +272 -0
  5. package/lib/blocklet/downloader/constants.js +3 -0
  6. package/lib/blocklet/downloader/resolve-download.js +199 -0
  7. package/lib/blocklet/extras.js +83 -26
  8. package/lib/blocklet/hooks.js +18 -65
  9. package/lib/blocklet/manager/base.js +10 -16
  10. package/lib/blocklet/manager/disk.js +1679 -1566
  11. package/lib/blocklet/manager/helper/install-application-from-backup.js +177 -0
  12. package/lib/blocklet/manager/helper/install-application-from-dev.js +94 -0
  13. package/lib/blocklet/manager/helper/install-application-from-general.js +188 -0
  14. package/lib/blocklet/manager/helper/install-component-from-dev.js +84 -0
  15. package/lib/blocklet/manager/helper/install-component-from-upload.js +181 -0
  16. package/lib/blocklet/manager/helper/install-component-from-url.js +173 -0
  17. package/lib/blocklet/manager/helper/migrate-application-to-struct-v2.js +450 -0
  18. package/lib/blocklet/manager/helper/rollback-cache.js +41 -0
  19. package/lib/blocklet/manager/helper/upgrade-components.js +152 -0
  20. package/lib/blocklet/migration.js +30 -52
  21. package/lib/blocklet/storage/backup/audit-log.js +27 -0
  22. package/lib/blocklet/storage/backup/base.js +62 -0
  23. package/lib/blocklet/storage/backup/blocklet-extras.js +92 -0
  24. package/lib/blocklet/storage/backup/blocklet.js +70 -0
  25. package/lib/blocklet/storage/backup/blocklets.js +74 -0
  26. package/lib/blocklet/storage/backup/data.js +19 -0
  27. package/lib/blocklet/storage/backup/logs.js +24 -0
  28. package/lib/blocklet/storage/backup/routing-rule.js +19 -0
  29. package/lib/blocklet/storage/backup/spaces.js +240 -0
  30. package/lib/blocklet/storage/restore/base.js +67 -0
  31. package/lib/blocklet/storage/restore/blocklet-extras.js +86 -0
  32. package/lib/blocklet/storage/restore/blocklet.js +56 -0
  33. package/lib/blocklet/storage/restore/blocklets.js +43 -0
  34. package/lib/blocklet/storage/restore/logs.js +21 -0
  35. package/lib/blocklet/storage/restore/spaces.js +156 -0
  36. package/lib/blocklet/storage/utils/hash.js +51 -0
  37. package/lib/blocklet/storage/utils/zip.js +43 -0
  38. package/lib/cert.js +206 -0
  39. package/lib/event.js +237 -64
  40. package/lib/index.js +191 -83
  41. package/lib/migrations/1.0.21-update-config.js +1 -1
  42. package/lib/migrations/1.0.22-max-memory.js +1 -1
  43. package/lib/migrations/1.0.25.js +1 -1
  44. package/lib/migrations/1.0.32-update-config.js +1 -1
  45. package/lib/migrations/1.0.33-blocklets.js +1 -1
  46. package/lib/migrations/1.5.20-registry.js +15 -0
  47. package/lib/migrations/1.6.17-blocklet-children.js +48 -0
  48. package/lib/migrations/1.6.21-rename-ip-echo-domain.js +35 -0
  49. package/lib/migrations/1.6.4-security.js +59 -0
  50. package/lib/migrations/1.6.5-security.js +60 -0
  51. package/lib/migrations/1.6.9-update-node-info-and-certificate.js +38 -0
  52. package/lib/migrations/1.7.1-blocklet-setup.js +18 -0
  53. package/lib/migrations/1.7.12-blocklet-meta.js +51 -0
  54. package/lib/migrations/1.7.15-blocklet-bundle-source.js +42 -0
  55. package/lib/migrations/1.7.20-blocklet-component.js +41 -0
  56. package/lib/migrations/1.8.33-blocklet-mem-limit.js +20 -0
  57. package/lib/migrations/README.md +1 -1
  58. package/lib/migrations/index.js +6 -2
  59. package/lib/monitor/blocklet-runtime-monitor.js +200 -0
  60. package/lib/monitor/get-history-list.js +37 -0
  61. package/lib/monitor/node-runtime-monitor.js +228 -0
  62. package/lib/router/helper.js +572 -497
  63. package/lib/router/index.js +85 -21
  64. package/lib/router/manager.js +146 -187
  65. package/lib/states/README.md +36 -1
  66. package/lib/states/access-key.js +39 -17
  67. package/lib/states/audit-log.js +462 -0
  68. package/lib/states/base.js +4 -213
  69. package/lib/states/blocklet-extras.js +194 -138
  70. package/lib/states/blocklet.js +361 -104
  71. package/lib/states/cache.js +8 -6
  72. package/lib/states/challenge.js +5 -5
  73. package/lib/states/index.js +19 -36
  74. package/lib/states/migration.js +4 -4
  75. package/lib/states/node.js +135 -46
  76. package/lib/states/notification.js +22 -35
  77. package/lib/states/session.js +17 -9
  78. package/lib/states/site.js +50 -25
  79. package/lib/states/user.js +74 -20
  80. package/lib/states/webhook.js +10 -6
  81. package/lib/team/manager.js +124 -7
  82. package/lib/util/blocklet.js +1223 -246
  83. package/lib/util/chain.js +1 -1
  84. package/lib/util/default-node-config.js +5 -23
  85. package/lib/util/disk-monitor.js +13 -10
  86. package/lib/util/domain-status.js +84 -15
  87. package/lib/util/get-accessible-external-node-ip.js +2 -2
  88. package/lib/util/get-domain-for-blocklet.js +13 -0
  89. package/lib/util/get-meta-from-url.js +33 -0
  90. package/lib/util/index.js +207 -272
  91. package/lib/util/ip.js +6 -0
  92. package/lib/util/maintain.js +233 -0
  93. package/lib/util/public-to-store.js +85 -0
  94. package/lib/util/ready.js +1 -1
  95. package/lib/util/requirement.js +28 -9
  96. package/lib/util/reset-node.js +22 -7
  97. package/lib/util/router.js +13 -0
  98. package/lib/util/rpc.js +16 -0
  99. package/lib/util/store.js +179 -0
  100. package/lib/util/sysinfo.js +44 -0
  101. package/lib/util/ua.js +54 -0
  102. package/lib/validators/blocklet-extra.js +24 -0
  103. package/lib/validators/node.js +25 -12
  104. package/lib/validators/permission.js +16 -1
  105. package/lib/validators/role.js +17 -3
  106. package/lib/validators/router.js +40 -20
  107. package/lib/validators/trusted-passport.js +1 -0
  108. package/lib/validators/util.js +22 -5
  109. package/lib/webhook/index.js +45 -35
  110. package/lib/webhook/sender/index.js +5 -0
  111. package/lib/webhook/sender/slack/index.js +1 -1
  112. package/lib/webhook/sender/wallet/index.js +48 -0
  113. package/package.json +54 -36
  114. package/lib/blocklet/registry.js +0 -205
  115. package/lib/states/https-cert.js +0 -67
  116. package/lib/util/get-ip-dns-domain-for-blocklet.js +0 -19
  117. package/lib/util/service.js +0 -66
  118. package/lib/util/upgrade.js +0 -178
  119. /package/lib/{queue.js → util/queue.js} +0 -0
@@ -1,226 +1,17 @@
1
- const fs = require('fs');
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 EventEmitter {
13
- constructor(baseDir, options) {
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, options = {}) {
13
- super(baseDir, { filename: 'blocklet_extras.db', ...options });
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.generateExtraFn(method, extra);
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 extra functions
107
+ // generate functions
53
108
 
54
- generateExtraFn(method, extra) {
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 (did) => {
70
- const { name } = extra;
71
- const item = await this.asyncDB.findOne({ did });
72
- return item ? item[name] : item;
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 (did, data) => {
78
- const { name, beforeSet } = extra;
79
- const hasBeforeSet = beforeSet && typeof beforeSet === 'function';
80
- const item = await this.asyncDB.findOne({ did });
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
- if (!item) {
83
- const insertData = {
84
- did,
85
- [name]: hasBeforeSet ? beforeSet(undefined, data) : data,
86
- };
87
-
88
- const info = await this.asyncDB.insert(insertData);
89
- logger.info('create info success');
90
- return info[name];
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
- const itemNameValue = item[name];
94
- const updated = await this.update(item._id, {
95
- $set: {
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 (did) => {
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.asyncDB.findOne({ did });
195
+ const item = await this.findOne({ did: rootDid });
107
196
 
108
197
  if (!item) {
109
- return item;
198
+ return null;
110
199
  }
111
200
 
112
- await this.update(item._id, { $set: { [name]: null } });
113
- return item[name];
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
- // generate extra child functions
207
+ if (!component) {
208
+ return null;
209
+ }
118
210
 
119
- generateExtraChildFn(method, extra) {
120
- if (method === 'get') {
121
- return this.generateGetChildFn(extra);
122
- }
211
+ const updated = component[name];
212
+ component[name] = null;
123
213
 
124
- if (method === 'set') {
125
- return this.generateSetChildFn(extra);
126
- }
214
+ await this.update(item._id, item);
127
215
 
128
- if (method === 'del') {
129
- return this.generateDelChildFn(extra);
130
- }
216
+ return updated;
217
+ };
131
218
  }
132
219
 
133
- generateGetChildFn(extra) {
134
- return async (did, childDid) => {
135
- const { name } = extra;
136
- const item = await this.asyncDB.findOne({ did });
137
- const children = (item || {}).children || [];
138
- const subItem = (children || []).find((x) => x.did === childDid);
139
- return subItem ? subItem[name] : null;
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
- generateSetChildFn(extra) {
144
- return async (did, childDid, data) => {
145
- const { name, beforeSet } = extra;
146
- const hasBeforeSet = beforeSet && typeof beforeSet === 'function';
147
- const item = await this.asyncDB.findOne({ did });
235
+ async addMeta({ did, meta, controller } = {}) {
236
+ const entity = { did, meta };
237
+ if (controller) {
238
+ entity.controller = controller;
239
+ }
148
240
 
149
- if (!item) {
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
- const children = (item || {}).children || [];
168
- const subItem = (children || []).find((x) => x.did === childDid);
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
- const newData = hasBeforeSet ? beforeSet(subItem[name], data) : data;
246
+ async getMeta(did) {
247
+ return super.findOne({ did }, { did: 1, controller: 1, meta: 1 });
248
+ }
186
249
 
187
- children.forEach((x) => {
188
- if (x.did === childDid) {
189
- x[name] = newData;
190
- }
191
- });
250
+ async updateExpireInfo({ did, expiredAt } = {}) {
251
+ const entity = { did, expiredAt };
252
+ await validateExpiredInfo(entity);
192
253
 
193
- await this.update(item._id, {
194
- $set: {
195
- children,
196
- },
197
- });
254
+ return super.update({ did }, { $set: { expiredAt } });
255
+ }
198
256
 
199
- return newData;
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
- generateDelChildFn(extra) {
204
- return async (did, childDid) => {
205
- const { name } = extra;
206
- const item = await this.asyncDB.findOne({ did });
266
+ encryptSecurityData({ data, _rootDid } = {}) {
267
+ if (!data) {
268
+ return data;
269
+ }
207
270
 
208
- if (!item) {
209
- return null;
210
- }
271
+ const { dek } = this.config;
211
272
 
212
- const children = (item || {}).children || [];
213
- const subItem = (children || []).find((x) => x.did === childDid);
273
+ if (!dek) {
274
+ return data;
275
+ }
214
276
 
215
- if (!subItem) {
216
- return null;
217
- }
277
+ const did = _rootDid || data.did;
218
278
 
219
- let updated = null;
279
+ if (!did) {
280
+ throw new Error('data.did does not exist');
281
+ }
220
282
 
221
- children.forEach((x) => {
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
- await this.update(item._id, {
229
- $set: {
230
- children,
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
- return updated;
235
- };
291
+ return data;
236
292
  }
237
293
  }
238
294