@abtnode/core 1.16.52-beta-20250928-042319-ff3f0e04 → 1.16.52-beta-20251002-030549-0f91dab2
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 +102 -6
- package/lib/blocklet/manager/disk.js +21 -5
- package/lib/blocklet/migration-dist/migration.cjs +1 -1
- package/lib/index.js +4 -0
- package/lib/locales/en.js +6 -6
- package/lib/monitor/get-history-list.js +1 -1
- package/lib/router/helper.js +2 -2
- package/lib/router/manager.js +2 -3
- package/lib/states/access-key.js +7 -3
- package/lib/states/audit-log.js +39 -0
- package/lib/states/tagging.js +8 -0
- package/lib/team/manager.js +9 -0
- package/lib/util/launcher.js +2 -15
- package/lib/validators/theme.js +19 -1
- package/package.json +38 -38
package/lib/api/team.js
CHANGED
|
@@ -8,7 +8,7 @@ const cloneDeep = require('@abtnode/util/lib/deep-clone');
|
|
|
8
8
|
const { joinURL, withoutTrailingSlash } = require('ufo');
|
|
9
9
|
const { Op } = require('sequelize');
|
|
10
10
|
const dayjs = require('@abtnode/util/lib/dayjs');
|
|
11
|
-
|
|
11
|
+
const Joi = require('joi');
|
|
12
12
|
const logger = require('@abtnode/logger')('@abtnode/core:api:team');
|
|
13
13
|
const {
|
|
14
14
|
ROLES,
|
|
@@ -121,6 +121,19 @@ const formatTransferData = (data) => ({
|
|
|
121
121
|
status: data.status || '',
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
const taggingSchema = Joi.object({
|
|
125
|
+
tagId: Joi.number().required(),
|
|
126
|
+
taggableIds: Joi.array().items(Joi.string()).min(1).required().messages({
|
|
127
|
+
'any.required': 'Must specify tagging.taggableIds to create',
|
|
128
|
+
'array.base': 'taggableIds must be an array',
|
|
129
|
+
'array.min': 'taggableIds must contain at least one element',
|
|
130
|
+
}),
|
|
131
|
+
taggableType: Joi.string().required().messages({
|
|
132
|
+
'any.required': 'Must specify tagging.taggableType to create',
|
|
133
|
+
'string.base': 'taggableType must be a string',
|
|
134
|
+
}),
|
|
135
|
+
});
|
|
136
|
+
|
|
124
137
|
const validatePassportDisplay = async (role, display) => {
|
|
125
138
|
if (role.extra?.display === 'custom') {
|
|
126
139
|
if (!display) {
|
|
@@ -270,39 +283,118 @@ class TeamAPI extends EventEmitter {
|
|
|
270
283
|
};
|
|
271
284
|
}
|
|
272
285
|
|
|
286
|
+
// Tagging
|
|
287
|
+
async createTagging({ teamDid, tagging }) {
|
|
288
|
+
const state = await this.getTaggingState(teamDid);
|
|
289
|
+
|
|
290
|
+
const { error, value } = taggingSchema.validate(tagging, { stripUnknown: true });
|
|
291
|
+
if (error) {
|
|
292
|
+
throw new Error(error.details.map((d) => d.message).join('; '));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const fns = value.taggableIds.map(async (id) => {
|
|
296
|
+
const found = await state.findOne({ tagId: tagging.tagId, taggableId: id });
|
|
297
|
+
if (found) return found;
|
|
298
|
+
|
|
299
|
+
return state.insert({ tagId: tagging.tagId, taggableId: id, taggableType: tagging.taggableType });
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
const docs = await Promise.all(fns);
|
|
303
|
+
logger.info('tagging created successfully', { teamDid, tagging });
|
|
304
|
+
return docs;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async deleteTagging({ teamDid, tagging }) {
|
|
308
|
+
const { error, value } = taggingSchema.validate(tagging, { stripUnknown: true });
|
|
309
|
+
if (error) {
|
|
310
|
+
throw new Error(error.details.map((d) => d.message).join('; '));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const state = await this.getTaggingState(teamDid);
|
|
314
|
+
|
|
315
|
+
const { tagId, taggableIds } = value;
|
|
316
|
+
const fns = taggableIds.map((id) => {
|
|
317
|
+
return state.remove({ tagId, taggableId: id });
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
const docs = await Promise.all(fns);
|
|
321
|
+
logger.info('tagging deleted successfully', { teamDid, tagging });
|
|
322
|
+
|
|
323
|
+
return docs;
|
|
324
|
+
}
|
|
325
|
+
|
|
273
326
|
// Tags
|
|
274
|
-
async
|
|
327
|
+
async getTag({ teamDid, tag }) {
|
|
328
|
+
const state = await this.getTagState(teamDid);
|
|
329
|
+
return state.findOne({ id: tag.id });
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async createTag({ teamDid, tag }, context = {}) {
|
|
275
333
|
if (!tag.title) {
|
|
276
334
|
throw new Error('Must specify tag.title to create');
|
|
277
335
|
}
|
|
278
336
|
if (!tag.color || !tag.color.match(/^#[0-9a-f]{6}$/i)) {
|
|
279
337
|
throw new Error('Must specify hex encoded tag.color to create');
|
|
280
338
|
}
|
|
339
|
+
if (!tag.slug) {
|
|
340
|
+
throw new Error('Must specify tag.slug to create');
|
|
341
|
+
}
|
|
281
342
|
|
|
282
343
|
const state = await this.getTagState(teamDid);
|
|
283
|
-
const
|
|
344
|
+
const tagData = pick(tag, ['title', 'description', 'color', 'slug', 'type', 'componentDid', 'parentId']);
|
|
345
|
+
tagData.createdBy = context.user.did;
|
|
346
|
+
tagData.updatedBy = context.user.did;
|
|
347
|
+
const doc = await state.insert(tagData);
|
|
284
348
|
logger.info('tags created successfully', { teamDid, tag });
|
|
285
349
|
return doc;
|
|
286
350
|
}
|
|
287
351
|
|
|
288
|
-
async updateTag({ teamDid, tag }) {
|
|
352
|
+
async updateTag({ teamDid, tag }, context = {}) {
|
|
289
353
|
if (!tag.id) {
|
|
290
354
|
throw new Error('Must specify tag.id to update');
|
|
291
355
|
}
|
|
292
356
|
|
|
357
|
+
const keys = ['title', 'description', 'color', 'slug', 'type', 'componentDid', 'parentId'];
|
|
358
|
+
const tagData = Object.fromEntries(keys.map((key) => [key, tag[key] ?? null]));
|
|
359
|
+
tagData.updatedBy = context.user.did;
|
|
360
|
+
|
|
293
361
|
const state = await this.getTagState(teamDid);
|
|
294
|
-
const result = await state.updateById(tag.id,
|
|
362
|
+
const result = await state.updateById(tag.id, tagData);
|
|
295
363
|
logger.info('tags updated successfully', { teamDid, tag, result });
|
|
296
364
|
return state.findOne({ id: tag.id });
|
|
297
365
|
}
|
|
298
366
|
|
|
299
|
-
async deleteTag({ teamDid, tag }) {
|
|
367
|
+
async deleteTag({ teamDid, tag, moveTo }) {
|
|
300
368
|
if (!tag.id) {
|
|
301
369
|
throw new Error('Must specify tag.id to delete');
|
|
302
370
|
}
|
|
303
371
|
|
|
304
372
|
const state = await this.getTagState(teamDid);
|
|
373
|
+
const taggingState = await this.getTaggingState(teamDid);
|
|
374
|
+
|
|
375
|
+
if (moveTo) {
|
|
376
|
+
const records = await taggingState.find({ tagId: tag.id });
|
|
377
|
+
|
|
378
|
+
await Promise.all(
|
|
379
|
+
records.map(async (record) => {
|
|
380
|
+
const found = await taggingState.findOne({
|
|
381
|
+
tagId: moveTo,
|
|
382
|
+
taggableId: record.taggableId,
|
|
383
|
+
taggableType: record.taggableType,
|
|
384
|
+
});
|
|
385
|
+
if (found) {
|
|
386
|
+
await taggingState.remove(record);
|
|
387
|
+
logger.info('tag already at moveTo, deleted record', { teamDid, tag, record });
|
|
388
|
+
} else {
|
|
389
|
+
await taggingState.update({ tagId: record.tagId }, { $set: { tagId: moveTo } });
|
|
390
|
+
logger.info('tag moved successfully', { teamDid, tag, record, moveTo });
|
|
391
|
+
}
|
|
392
|
+
})
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
305
396
|
const doc = await state.remove({ id: tag.id });
|
|
397
|
+
await taggingState.remove({ tagId: tag.id });
|
|
306
398
|
logger.info('tags deleted successfully', { teamDid, tag });
|
|
307
399
|
return doc;
|
|
308
400
|
}
|
|
@@ -2042,6 +2134,10 @@ class TeamAPI extends EventEmitter {
|
|
|
2042
2134
|
return this.teamManager.getTagState(did);
|
|
2043
2135
|
}
|
|
2044
2136
|
|
|
2137
|
+
getTaggingState(did) {
|
|
2138
|
+
return this.teamManager.getTaggingState(did);
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2045
2141
|
getSessionState(did) {
|
|
2046
2142
|
return this.teamManager.getSessionState(did);
|
|
2047
2143
|
}
|
|
@@ -125,7 +125,7 @@ const toBlockletDid = require('@blocklet/meta/lib/did');
|
|
|
125
125
|
const { updateComponentDid, removeUploadFile } = require('@abtnode/util/lib/upload-component');
|
|
126
126
|
|
|
127
127
|
const groupBy = require('lodash/groupBy');
|
|
128
|
-
const { isDidDomain, isCustomDomain } = require('@abtnode/util/lib/url-evaluation');
|
|
128
|
+
const { isDidDomain, isCustomDomain, getOriginUrl } = require('@abtnode/util/lib/url-evaluation');
|
|
129
129
|
const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
130
130
|
const { isInstanceWorker } = require('@abtnode/util/lib/pm2/is-instence-worker.js');
|
|
131
131
|
const launcher = require('../../util/launcher');
|
|
@@ -2065,7 +2065,16 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2065
2065
|
throw new Error(error.message);
|
|
2066
2066
|
}
|
|
2067
2067
|
|
|
2068
|
-
await states.blockletExtras.
|
|
2068
|
+
const currentSettings = await states.blockletExtras.getSettings(did);
|
|
2069
|
+
const currentTheme = currentSettings.theme || {};
|
|
2070
|
+
|
|
2071
|
+
// 锁定校验
|
|
2072
|
+
if (value.concepts && currentTheme.meta?.locked) {
|
|
2073
|
+
throw new CustomError(403, 'Theme is locked and cannot be modified');
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
const updatedTheme = { ...currentTheme, ...value };
|
|
2077
|
+
await states.blockletExtras.setSettings(did, { theme: updatedTheme });
|
|
2069
2078
|
|
|
2070
2079
|
const newState = await this.getBlocklet(did);
|
|
2071
2080
|
this.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
|
|
@@ -2325,6 +2334,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2325
2334
|
|
|
2326
2335
|
async setInitialized({ did, owner, purpose = '' }, context) {
|
|
2327
2336
|
if (!validateOwner(owner)) {
|
|
2337
|
+
logger.warn('Blocklet owner is invalid for setInitialized', { did, owner });
|
|
2328
2338
|
throw new Error('Blocklet owner is invalid');
|
|
2329
2339
|
}
|
|
2330
2340
|
|
|
@@ -2340,7 +2350,8 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2340
2350
|
|
|
2341
2351
|
async updateOwner({ did, owner }, context) {
|
|
2342
2352
|
if (!validateOwner(owner)) {
|
|
2343
|
-
|
|
2353
|
+
logger.warn('Blocklet owner is invalid for updateOwner', { did, owner });
|
|
2354
|
+
throw new Error('Blocklet owner is invalid');
|
|
2344
2355
|
}
|
|
2345
2356
|
|
|
2346
2357
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
@@ -2923,7 +2934,10 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2923
2934
|
if (key && !decryptedKey) {
|
|
2924
2935
|
throw new CustomError(400, 'Save failed, the API key is not encrypted');
|
|
2925
2936
|
}
|
|
2926
|
-
params.aigne =
|
|
2937
|
+
params.aigne = {
|
|
2938
|
+
...aigne,
|
|
2939
|
+
url: getOriginUrl(aigne.url),
|
|
2940
|
+
};
|
|
2927
2941
|
}
|
|
2928
2942
|
const keys = Object.keys(params);
|
|
2929
2943
|
if (!keys.length) {
|
|
@@ -3023,7 +3037,9 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3023
3037
|
throw new CustomError(400, 'blocklet did invalid, no blocklet found');
|
|
3024
3038
|
}
|
|
3025
3039
|
const aigneSetting = get(blocklet, 'settings.aigne', {});
|
|
3026
|
-
|
|
3040
|
+
const _url = getOriginUrl(url);
|
|
3041
|
+
const settingUrl = getOriginUrl(aigneSetting.url);
|
|
3042
|
+
if (aigneSetting.key !== key && _url !== settingUrl) {
|
|
3027
3043
|
throw new CustomError(400, 'Invalid key or url provided');
|
|
3028
3044
|
}
|
|
3029
3045
|
await states.blockletExtras.setSettings(did, {
|
|
@@ -38946,7 +38946,7 @@ module.exports = require("zlib");
|
|
|
38946
38946
|
/***/ ((module) => {
|
|
38947
38947
|
|
|
38948
38948
|
"use strict";
|
|
38949
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.51","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"node tools/jest.js","test:disk":"node tools/jest.js tests/blocklet/manager/disk.spec.js","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.51","@abtnode/auth":"1.16.51","@abtnode/certificate-manager":"1.16.51","@abtnode/constant":"1.16.51","@abtnode/cron":"1.16.51","@abtnode/db-cache":"1.16.51","@abtnode/docker-utils":"1.16.51","@abtnode/logger":"1.16.51","@abtnode/models":"1.16.51","@abtnode/queue":"1.16.51","@abtnode/rbac":"1.16.51","@abtnode/router-provider":"1.16.51","@abtnode/static-server":"1.16.51","@abtnode/timemachine":"1.16.51","@abtnode/util":"1.16.51","@aigne/aigne-hub":"^0.
|
|
38949
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.51","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"node tools/jest.js","test:disk":"node tools/jest.js tests/blocklet/manager/disk.spec.js","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.51","@abtnode/auth":"1.16.51","@abtnode/certificate-manager":"1.16.51","@abtnode/constant":"1.16.51","@abtnode/cron":"1.16.51","@abtnode/db-cache":"1.16.51","@abtnode/docker-utils":"1.16.51","@abtnode/logger":"1.16.51","@abtnode/models":"1.16.51","@abtnode/queue":"1.16.51","@abtnode/rbac":"1.16.51","@abtnode/router-provider":"1.16.51","@abtnode/static-server":"1.16.51","@abtnode/timemachine":"1.16.51","@abtnode/util":"1.16.51","@aigne/aigne-hub":"^0.10.0","@arcblock/did":"1.25.6","@arcblock/did-connect-js":"1.25.6","@arcblock/did-ext":"1.25.6","@arcblock/did-motif":"^1.1.14","@arcblock/did-util":"1.25.6","@arcblock/event-hub":"1.25.6","@arcblock/jwt":"1.25.6","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"1.25.6","@arcblock/vc":"1.25.6","@blocklet/constant":"1.16.51","@blocklet/did-space-js":"^1.1.29","@blocklet/env":"1.16.51","@blocklet/error":"^0.2.5","@blocklet/meta":"1.16.51","@blocklet/resolver":"1.16.51","@blocklet/sdk":"1.16.51","@blocklet/server-js":"1.16.51","@blocklet/store":"1.16.51","@blocklet/theme":"^3.1.44","@fidm/x509":"^1.2.1","@ocap/mcrypto":"1.25.6","@ocap/util":"1.25.6","@ocap/wallet":"1.25.6","@slack/webhook":"^5.0.4","archiver":"^7.0.1","axios":"^1.7.9","axon":"^2.0.3","chalk":"^4.1.2","cross-spawn":"^7.0.3","dayjs":"^1.11.13","deep-diff":"^1.0.2","detect-port":"^1.5.1","envfile":"^7.1.0","escape-string-regexp":"^4.0.0","fast-glob":"^3.3.2","filesize":"^10.1.1","flat":"^5.0.2","fs-extra":"^11.2.0","get-port":"^5.1.1","hasha":"^5.2.2","is-base64":"^1.1.0","is-cidr":"4","is-ip":"3","is-url":"^1.2.4","joi":"17.12.2","joi-extension-semver":"^5.0.0","js-yaml":"^4.1.0","kill-port":"^2.0.1","lodash":"^4.17.21","node-stream-zip":"^1.15.0","p-all":"^3.0.0","p-limit":"^3.1.0","p-map":"^4.0.0","p-retry":"^4.6.2","p-wait-for":"^3.2.0","private-ip":"^2.3.4","rate-limiter-flexible":"^5.0.5","read-last-lines":"^1.8.0","semver":"^7.6.3","sequelize":"^6.35.0","shelljs":"^0.8.5","slugify":"^1.6.6","ssri":"^8.0.1","stream-throttle":"^0.1.3","stream-to-promise":"^3.0.0","systeminformation":"^5.23.3","tail":"^2.2.4","tar":"^6.1.11","transliteration":"^2.3.5","ua-parser-js":"^1.0.2","ufo":"^1.5.3","uuid":"^11.1.0","valid-url":"^1.0.9","which":"^2.0.2","xbytes":"^1.8.0"},"devDependencies":{"expand-tilde":"^2.0.2","express":"^4.18.2","jest":"^29.7.0","unzipper":"^0.10.11"},"gitHead":"e5764f753181ed6a7c615cd4fc6682aacf0cb7cd"}');
|
|
38950
38950
|
|
|
38951
38951
|
/***/ }),
|
|
38952
38952
|
|
package/lib/index.js
CHANGED
|
@@ -547,11 +547,15 @@ function ABTNode(options) {
|
|
|
547
547
|
getUserInvites: teamAPI.getUserInvites.bind(teamAPI),
|
|
548
548
|
|
|
549
549
|
// Tagging
|
|
550
|
+
getTag: teamAPI.getTag.bind(teamAPI),
|
|
550
551
|
createTag: teamAPI.createTag.bind(teamAPI),
|
|
551
552
|
updateTag: teamAPI.updateTag.bind(teamAPI),
|
|
552
553
|
deleteTag: teamAPI.deleteTag.bind(teamAPI),
|
|
553
554
|
getTags: teamAPI.getTags.bind(teamAPI),
|
|
554
555
|
|
|
556
|
+
createTagging: teamAPI.createTagging.bind(teamAPI),
|
|
557
|
+
deleteTagging: teamAPI.deleteTagging.bind(teamAPI),
|
|
558
|
+
|
|
555
559
|
// Access Control
|
|
556
560
|
getRBAC: (did = options.nodeDid) => teamManager.getRBAC(did),
|
|
557
561
|
|
package/lib/locales/en.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/* eslint-disable prettier/prettier */
|
|
2
2
|
module.exports = {
|
|
3
3
|
registry: {
|
|
4
|
-
getListError: '
|
|
4
|
+
getListError: 'Failed to get blocklet list from registry "{registryUrl}"',
|
|
5
5
|
},
|
|
6
6
|
backup: {
|
|
7
7
|
space: {
|
|
8
8
|
error: {
|
|
9
|
-
title: 'Backup to DID Spaces
|
|
9
|
+
title: 'Backup to DID Spaces Failed',
|
|
10
10
|
forbidden:
|
|
11
|
-
'You
|
|
11
|
+
'You don\'t have permission to back up. Try restoring the license on DID Spaces or reconnect.',
|
|
12
12
|
},
|
|
13
|
-
isFull: '
|
|
13
|
+
isFull: 'Your DID Spaces storage is full. Expand storage and try again.',
|
|
14
14
|
lackOfSpace:
|
|
15
|
-
'
|
|
16
|
-
unableEnableAutoBackup: '
|
|
15
|
+
'Not enough storage space. Expand storage and try again.',
|
|
16
|
+
unableEnableAutoBackup: 'Connect to DID Spaces before enabling auto backup.',
|
|
17
17
|
},
|
|
18
18
|
},
|
|
19
19
|
};
|
|
@@ -2,7 +2,7 @@ const maxBy = require('lodash/maxBy');
|
|
|
2
2
|
|
|
3
3
|
const getHistoryList = ({ history, hours, recordIntervalSec, props = [] }) => {
|
|
4
4
|
if (hours < 1 || hours > 24) {
|
|
5
|
-
throw new Error('hours should between 1
|
|
5
|
+
throw new Error('hours should be between 1 and 24');
|
|
6
6
|
}
|
|
7
7
|
const intHours = Math.floor(hours);
|
|
8
8
|
|
package/lib/router/helper.js
CHANGED
|
@@ -798,11 +798,11 @@ module.exports = function getRouterHelpers({
|
|
|
798
798
|
const privateKeyFilePath = path.join(destFolder, 'privkey.pem');
|
|
799
799
|
|
|
800
800
|
if (!fs.existsSync(certificateFilePath)) {
|
|
801
|
-
throw new Error('dashboard certificate invalid: cert.pem not
|
|
801
|
+
throw new Error('dashboard certificate invalid: cert.pem does not exist');
|
|
802
802
|
}
|
|
803
803
|
|
|
804
804
|
if (!fs.existsSync(privateKeyFilePath)) {
|
|
805
|
-
throw new Error('dashboard certificate invalid: privkey.pem not
|
|
805
|
+
throw new Error('dashboard certificate invalid: privkey.pem does not exist');
|
|
806
806
|
}
|
|
807
807
|
|
|
808
808
|
const certificate = fs.readFileSync(certificateFilePath).toString();
|
package/lib/router/manager.js
CHANGED
|
@@ -179,8 +179,7 @@ class RouterManager extends EventEmitter {
|
|
|
179
179
|
async deleteRoutingSite({ id }, context = {}) {
|
|
180
180
|
const site = await states.site.findOne({ id });
|
|
181
181
|
if ([DOMAIN_FOR_IP_SITE, DOMAIN_FOR_DEFAULT_SITE].includes(site.domain)) {
|
|
182
|
-
|
|
183
|
-
throw new Error("Can not delete this site because it's protected");
|
|
182
|
+
throw new Error('Cannot delete this site because it is protected');
|
|
184
183
|
}
|
|
185
184
|
|
|
186
185
|
const removedSiteCount = await states.site.remove({ id });
|
|
@@ -198,7 +197,7 @@ class RouterManager extends EventEmitter {
|
|
|
198
197
|
const site = await validateUpdateSite(params, context);
|
|
199
198
|
const existed = await states.site.findOne({ id: site.id });
|
|
200
199
|
if (!existed) {
|
|
201
|
-
throw new Error('
|
|
200
|
+
throw new Error('Cannot update non-existing site');
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
const updateSet = {};
|
package/lib/states/access-key.js
CHANGED
|
@@ -101,7 +101,7 @@ class AccessKeyState extends BaseState {
|
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
findPaginated({ remark, componentDid, resourceId, resourceType, paging } = {}, context) {
|
|
104
|
+
findPaginated({ remark: keywords, componentDid, resourceId, resourceType, paging } = {}, context) {
|
|
105
105
|
validateOperator(context);
|
|
106
106
|
const conditions = {
|
|
107
107
|
where: {},
|
|
@@ -115,8 +115,12 @@ class AccessKeyState extends BaseState {
|
|
|
115
115
|
if (resourceType) {
|
|
116
116
|
conditions.where.resourceType = resourceType;
|
|
117
117
|
}
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
// 模糊搜索
|
|
119
|
+
if (keywords) {
|
|
120
|
+
conditions.where[Op.or] = [
|
|
121
|
+
{ remark: { [Op.like]: `%${keywords}%` } },
|
|
122
|
+
{ accessKeyId: { [Op.like]: `%${keywords}%` } },
|
|
123
|
+
];
|
|
120
124
|
}
|
|
121
125
|
const pathname = getEndpoint(context);
|
|
122
126
|
const queryCreatedById = isUserCenterPath(pathname) ? context.user.did : '';
|
package/lib/states/audit-log.js
CHANGED
|
@@ -202,6 +202,31 @@ const getResponseHeaderPolicyInfo = (policy) => {
|
|
|
202
202
|
.join(', ');
|
|
203
203
|
};
|
|
204
204
|
|
|
205
|
+
const getTaggingInfo = async (args, node, info) => {
|
|
206
|
+
const { teamDid, tagging } = args;
|
|
207
|
+
const { routing, did } = info;
|
|
208
|
+
|
|
209
|
+
const prefix = process.env.NODE_ENV === 'production' ? routing.adminPath : '';
|
|
210
|
+
|
|
211
|
+
const [tag, users] = await Promise.all([
|
|
212
|
+
node.getTag({ teamDid, tag: { id: tagging.tagId } }),
|
|
213
|
+
Promise.allSettled(tagging.taggableIds.map((id) => node.getUser({ teamDid, user: { did: id } }))),
|
|
214
|
+
]);
|
|
215
|
+
|
|
216
|
+
const basePath =
|
|
217
|
+
teamDid === did ? joinURL(prefix, '/team/members') : joinURL(prefix, '/blocklets/', teamDid, '/members');
|
|
218
|
+
|
|
219
|
+
const userLinks = users
|
|
220
|
+
.filter((r) => r.status === 'fulfilled' && r.value)
|
|
221
|
+
.map(({ value: u }) => `[${u.fullName}](${basePath})`)
|
|
222
|
+
.join(', ');
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
tag: tag?.title || tagging.tagId,
|
|
226
|
+
userLinks,
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
|
|
205
230
|
/**
|
|
206
231
|
* 隐藏私密信息,主要字段有
|
|
207
232
|
* 1. email
|
|
@@ -499,6 +524,20 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
499
524
|
return `deleted tag ${args.tag.id}`;
|
|
500
525
|
case 'destroySelf':
|
|
501
526
|
return `user ${result.did} initiated account deletion`;
|
|
527
|
+
case 'createTagging':
|
|
528
|
+
if (args.tagging.taggableType === 'user') {
|
|
529
|
+
const { tag, userLinks } = await getTaggingInfo(args, node, info);
|
|
530
|
+
return `created tagging **${tag}** for ${userLinks}`;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return `created tagging **${args.tagging.tagId}** for ${args.tagging.taggableIds.join(', ')}`;
|
|
534
|
+
case 'deleteTagging':
|
|
535
|
+
if (args.tagging.taggableType === 'user') {
|
|
536
|
+
const { tag, userLinks } = await getTaggingInfo(args, node, info);
|
|
537
|
+
return `deleted tagging **${tag}** for ${userLinks}`;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
return `deleted tagging ${args.tagging.tagId} for ${args.tagging.taggableIds.join(', ')}`;
|
|
502
541
|
|
|
503
542
|
// accessKeys
|
|
504
543
|
case 'createAccessKey':
|
package/lib/team/manager.js
CHANGED
|
@@ -41,6 +41,7 @@ const States = {
|
|
|
41
41
|
ConnectedAccount: require('../states/connect-account'),
|
|
42
42
|
Session: require('../states/session'),
|
|
43
43
|
Tag: require('../states/tag'),
|
|
44
|
+
Tagging: require('../states/tagging'),
|
|
44
45
|
Project: require('../states/project'),
|
|
45
46
|
Release: require('../states/release'),
|
|
46
47
|
Notification: require('../states/notification'),
|
|
@@ -67,6 +68,7 @@ const getDefaultTeamState = () => ({
|
|
|
67
68
|
connectedAccount: null,
|
|
68
69
|
session: null,
|
|
69
70
|
tag: null,
|
|
71
|
+
tagging: null,
|
|
70
72
|
project: null,
|
|
71
73
|
release: null,
|
|
72
74
|
notification: null,
|
|
@@ -140,6 +142,7 @@ class TeamManager extends EventEmitter {
|
|
|
140
142
|
user: await this.createState(this.nodeDid, 'User'),
|
|
141
143
|
userSession: await this.createState(this.nodeDid, 'UserSession'),
|
|
142
144
|
tag: await this.createState(this.nodeDid, 'Tag'),
|
|
145
|
+
tagging: await this.createState(this.nodeDid, 'Tagging'),
|
|
143
146
|
passport: await this.createState(this.nodeDid, 'Passport'),
|
|
144
147
|
passportLog: await this.createState(this.nodeDid, 'PassportLog'),
|
|
145
148
|
connectedAccount: await this.createState(this.nodeDid, 'ConnectedAccount'),
|
|
@@ -170,6 +173,10 @@ class TeamManager extends EventEmitter {
|
|
|
170
173
|
return this.getState(teamDid, 'tag');
|
|
171
174
|
}
|
|
172
175
|
|
|
176
|
+
getTaggingState(teamDid) {
|
|
177
|
+
return this.getState(teamDid, 'tagging');
|
|
178
|
+
}
|
|
179
|
+
|
|
173
180
|
getPassportState(teamDid) {
|
|
174
181
|
return this.getState(teamDid, 'passport');
|
|
175
182
|
}
|
|
@@ -817,6 +824,7 @@ class TeamManager extends EventEmitter {
|
|
|
817
824
|
const rbac = await this.getRBAC(did);
|
|
818
825
|
const user = await this.createState(did, 'User');
|
|
819
826
|
const tag = await this.createState(did, 'Tag');
|
|
827
|
+
const tagging = await this.createState(did, 'Tagging');
|
|
820
828
|
const passport = await this.createState(did, 'Passport');
|
|
821
829
|
const passportLog = await this.createState(did, 'PassportLog');
|
|
822
830
|
const connectedAccount = await this.createState(did, 'ConnectedAccount');
|
|
@@ -828,6 +836,7 @@ class TeamManager extends EventEmitter {
|
|
|
828
836
|
user,
|
|
829
837
|
userSession,
|
|
830
838
|
tag,
|
|
839
|
+
tagging,
|
|
831
840
|
session,
|
|
832
841
|
passport,
|
|
833
842
|
passportLog,
|
package/lib/util/launcher.js
CHANGED
|
@@ -329,7 +329,6 @@ const setupAppOwner = async ({
|
|
|
329
329
|
},
|
|
330
330
|
node
|
|
331
331
|
);
|
|
332
|
-
logger.info('Create owner for blocklet', { appDid, ownerDid, sessionId });
|
|
333
332
|
|
|
334
333
|
if (passport) {
|
|
335
334
|
await node.createPassportLog(appDid, {
|
|
@@ -358,8 +357,10 @@ const setupAppOwner = async ({
|
|
|
358
357
|
});
|
|
359
358
|
|
|
360
359
|
if (justCreate || autoStart) {
|
|
360
|
+
logger.info('Create owner for blocklet: setBlockletInitialized', { appDid, ownerDid, sessionId });
|
|
361
361
|
await node.setBlockletInitialized({ did: appDid, owner: { did: ownerDid, pk: ownerPk } });
|
|
362
362
|
} else {
|
|
363
|
+
logger.info('Create owner for blocklet: setBlockletOwner', { appDid, ownerDid, sessionId });
|
|
363
364
|
await node.setBlockletOwner({ did: appDid, owner: { did: ownerDid, pk: ownerPk } });
|
|
364
365
|
}
|
|
365
366
|
|
|
@@ -389,20 +390,6 @@ const setupAppOwner = async ({
|
|
|
389
390
|
|
|
390
391
|
logger.info('created user session', { appDid, ownerDid, userSession });
|
|
391
392
|
|
|
392
|
-
// FIXME: this always throw error
|
|
393
|
-
// if (autoStart) {
|
|
394
|
-
// node
|
|
395
|
-
// .startBlocklet({
|
|
396
|
-
// did: appDid,
|
|
397
|
-
// checkHealthImmediately: false,
|
|
398
|
-
// throwOnError: true,
|
|
399
|
-
// atomic: false,
|
|
400
|
-
// })
|
|
401
|
-
// .catch((error) => {
|
|
402
|
-
// logger.error('blocklet auto start failed', { error, appDid });
|
|
403
|
-
// });
|
|
404
|
-
// }
|
|
405
|
-
|
|
406
393
|
return {
|
|
407
394
|
session,
|
|
408
395
|
blocklet,
|
package/lib/validators/theme.js
CHANGED
|
@@ -187,12 +187,30 @@ const conceptSchema = Joi.object({
|
|
|
187
187
|
editor: editorStateSchema.required(),
|
|
188
188
|
}).options({ allowUnknown: true, stripUnknown: true });
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
// Theme data schema (concepts and currentConceptId)
|
|
191
|
+
const themeDataSchema = Joi.object({
|
|
191
192
|
concepts: Joi.array().items(conceptSchema).required(),
|
|
192
193
|
currentConceptId: Joi.string().required(),
|
|
193
194
|
}).options({ allowUnknown: true, stripUnknown: true });
|
|
194
195
|
|
|
196
|
+
// Theme meta schema for storing metadata like locked status
|
|
197
|
+
const themeMetaSchema = Joi.object({
|
|
198
|
+
meta: Joi.object({
|
|
199
|
+
locked: Joi.boolean().required(),
|
|
200
|
+
}).required(),
|
|
201
|
+
}).options({ allowUnknown: true, stripUnknown: true });
|
|
202
|
+
|
|
203
|
+
// Top-level blocklet theme schema - either theme data OR meta, not both
|
|
204
|
+
const blockletThemeSchema = Joi.alternatives().try(
|
|
205
|
+
// Theme data schema
|
|
206
|
+
themeDataSchema,
|
|
207
|
+
// Meta-only schema
|
|
208
|
+
themeMetaSchema
|
|
209
|
+
);
|
|
210
|
+
|
|
195
211
|
module.exports = {
|
|
196
212
|
muiThemeSchema,
|
|
197
213
|
blockletThemeSchema,
|
|
214
|
+
themeDataSchema,
|
|
215
|
+
themeMetaSchema,
|
|
198
216
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.52-beta-
|
|
6
|
+
"version": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -20,46 +20,46 @@
|
|
|
20
20
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
21
21
|
"license": "Apache-2.0",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@abtnode/analytics": "1.16.52-beta-
|
|
24
|
-
"@abtnode/auth": "1.16.52-beta-
|
|
25
|
-
"@abtnode/certificate-manager": "1.16.52-beta-
|
|
26
|
-
"@abtnode/constant": "1.16.52-beta-
|
|
27
|
-
"@abtnode/cron": "1.16.52-beta-
|
|
28
|
-
"@abtnode/db-cache": "1.16.52-beta-
|
|
29
|
-
"@abtnode/docker-utils": "1.16.52-beta-
|
|
30
|
-
"@abtnode/logger": "1.16.52-beta-
|
|
31
|
-
"@abtnode/models": "1.16.52-beta-
|
|
32
|
-
"@abtnode/queue": "1.16.52-beta-
|
|
33
|
-
"@abtnode/rbac": "1.16.52-beta-
|
|
34
|
-
"@abtnode/router-provider": "1.16.52-beta-
|
|
35
|
-
"@abtnode/static-server": "1.16.52-beta-
|
|
36
|
-
"@abtnode/timemachine": "1.16.52-beta-
|
|
37
|
-
"@abtnode/util": "1.16.52-beta-
|
|
38
|
-
"@aigne/aigne-hub": "^0.
|
|
39
|
-
"@arcblock/did": "1.
|
|
40
|
-
"@arcblock/did-connect-js": "1.
|
|
41
|
-
"@arcblock/did-ext": "1.
|
|
23
|
+
"@abtnode/analytics": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
24
|
+
"@abtnode/auth": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
25
|
+
"@abtnode/certificate-manager": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
26
|
+
"@abtnode/constant": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
27
|
+
"@abtnode/cron": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
28
|
+
"@abtnode/db-cache": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
29
|
+
"@abtnode/docker-utils": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
30
|
+
"@abtnode/logger": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
31
|
+
"@abtnode/models": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
32
|
+
"@abtnode/queue": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
33
|
+
"@abtnode/rbac": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
34
|
+
"@abtnode/router-provider": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
35
|
+
"@abtnode/static-server": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
36
|
+
"@abtnode/timemachine": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
37
|
+
"@abtnode/util": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
38
|
+
"@aigne/aigne-hub": "^0.10.0",
|
|
39
|
+
"@arcblock/did": "1.25.6",
|
|
40
|
+
"@arcblock/did-connect-js": "1.25.6",
|
|
41
|
+
"@arcblock/did-ext": "1.25.6",
|
|
42
42
|
"@arcblock/did-motif": "^1.1.14",
|
|
43
|
-
"@arcblock/did-util": "1.
|
|
44
|
-
"@arcblock/event-hub": "1.
|
|
45
|
-
"@arcblock/jwt": "1.
|
|
43
|
+
"@arcblock/did-util": "1.25.6",
|
|
44
|
+
"@arcblock/event-hub": "1.25.6",
|
|
45
|
+
"@arcblock/jwt": "1.25.6",
|
|
46
46
|
"@arcblock/pm2-events": "^0.0.5",
|
|
47
|
-
"@arcblock/validator": "1.
|
|
48
|
-
"@arcblock/vc": "1.
|
|
49
|
-
"@blocklet/constant": "1.16.52-beta-
|
|
50
|
-
"@blocklet/did-space-js": "^1.1.
|
|
51
|
-
"@blocklet/env": "1.16.52-beta-
|
|
47
|
+
"@arcblock/validator": "1.25.6",
|
|
48
|
+
"@arcblock/vc": "1.25.6",
|
|
49
|
+
"@blocklet/constant": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
50
|
+
"@blocklet/did-space-js": "^1.1.29",
|
|
51
|
+
"@blocklet/env": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
52
52
|
"@blocklet/error": "^0.2.5",
|
|
53
|
-
"@blocklet/meta": "1.16.52-beta-
|
|
54
|
-
"@blocklet/resolver": "1.16.52-beta-
|
|
55
|
-
"@blocklet/sdk": "1.16.52-beta-
|
|
56
|
-
"@blocklet/server-js": "1.16.52-beta-
|
|
57
|
-
"@blocklet/store": "1.16.52-beta-
|
|
58
|
-
"@blocklet/theme": "^3.1.
|
|
53
|
+
"@blocklet/meta": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
54
|
+
"@blocklet/resolver": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
55
|
+
"@blocklet/sdk": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
56
|
+
"@blocklet/server-js": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
57
|
+
"@blocklet/store": "1.16.52-beta-20251002-030549-0f91dab2",
|
|
58
|
+
"@blocklet/theme": "^3.1.44",
|
|
59
59
|
"@fidm/x509": "^1.2.1",
|
|
60
|
-
"@ocap/mcrypto": "1.
|
|
61
|
-
"@ocap/util": "1.
|
|
62
|
-
"@ocap/wallet": "1.
|
|
60
|
+
"@ocap/mcrypto": "1.25.6",
|
|
61
|
+
"@ocap/util": "1.25.6",
|
|
62
|
+
"@ocap/wallet": "1.25.6",
|
|
63
63
|
"@slack/webhook": "^5.0.4",
|
|
64
64
|
"archiver": "^7.0.1",
|
|
65
65
|
"axios": "^1.7.9",
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
"jest": "^29.7.0",
|
|
120
120
|
"unzipper": "^0.10.11"
|
|
121
121
|
},
|
|
122
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "57e57e5edc99bfbb7e4591d682f1057ec05655a8"
|
|
123
123
|
}
|