@abtnode/core 1.16.45-beta-20250610-112229-2eb0face → 1.16.45-beta-20250614-101901-d1700f8d
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 +4 -0
- package/lib/blocklet/manager/disk.js +33 -6
- package/lib/blocklet/manager/ensure-blocklet-running.js +8 -2
- package/lib/blocklet/migration-dist/migration.cjs +4 -3
- package/lib/index.js +4 -5
- package/lib/router/helper.js +11 -10
- package/lib/router/security/limiter.js +4 -1
- package/lib/states/audit-log.js +15 -3
- package/lib/states/node.js +1 -1
- package/lib/team/manager.js +4 -10
- package/lib/util/blocklet.js +4 -5
- package/lib/util/cache.js +12 -0
- package/lib/util/check-dns.js +1 -12
- package/lib/util/docker/docker-exec-chown.js +1 -1
- package/lib/util/docker/docker-network.js +1 -1
- package/lib/util/launcher.js +66 -2
- package/lib/validators/theme.js +10 -9
- package/lib/webhook/reduce-queue.js +1 -1
- package/package.json +26 -26
package/lib/api/node.js
CHANGED
|
@@ -70,6 +70,10 @@ class NodeAPI {
|
|
|
70
70
|
|
|
71
71
|
async getDiskInfo() {
|
|
72
72
|
let diskInfo = { app: 0, cache: 0, log: 0, data: 0, blocklets: 0 };
|
|
73
|
+
if (process.env.ABT_NODE_FAKE_DISK_INFO === '1') {
|
|
74
|
+
return diskInfo;
|
|
75
|
+
}
|
|
76
|
+
|
|
73
77
|
try {
|
|
74
78
|
const [app, cache, log, data, blocklets] = await Promise.all([
|
|
75
79
|
getFolderSize(this.state.dataDirs.core),
|
|
@@ -100,6 +100,7 @@ const {
|
|
|
100
100
|
SUSPENDED_REASON,
|
|
101
101
|
APP_CONFIG_DIR,
|
|
102
102
|
COMPONENT_ENV_FILE_NAME,
|
|
103
|
+
BLOCKLET_PREFERENCE_PREFIX,
|
|
103
104
|
} = require('@blocklet/constant');
|
|
104
105
|
|
|
105
106
|
const { WELLKNOWN_SERVICE_PATH_PREFIX, WELLKNOWN_BLOCKLET_ADMIN_PATH } = require('@abtnode/constant');
|
|
@@ -1669,10 +1670,12 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1669
1670
|
}
|
|
1670
1671
|
|
|
1671
1672
|
// 对用户输入的配置进行 XSS 清理
|
|
1672
|
-
const sanitizedConfigs = newConfigs
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1673
|
+
const sanitizedConfigs = newConfigs
|
|
1674
|
+
.map((c) => ({
|
|
1675
|
+
...c,
|
|
1676
|
+
value: sanitizeTag(c.value),
|
|
1677
|
+
}))
|
|
1678
|
+
.filter((x) => (x.key.startsWith(BLOCKLET_PREFERENCE_PREFIX) ? omit(x, 'shared') : x));
|
|
1676
1679
|
|
|
1677
1680
|
const tmpDids = Array.isArray(did) ? did : [did];
|
|
1678
1681
|
const [rootDid, childDid] = tmpDids;
|
|
@@ -2768,8 +2771,32 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2768
2771
|
return summary;
|
|
2769
2772
|
}
|
|
2770
2773
|
|
|
2771
|
-
async
|
|
2772
|
-
|
|
2774
|
+
async updateBlockletSettings({ did, enableSessionHardening, invite, gateway }, context) {
|
|
2775
|
+
const params = {};
|
|
2776
|
+
if (!isNil(enableSessionHardening)) {
|
|
2777
|
+
params.enableSessionHardening = enableSessionHardening;
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
if (!isNil(invite)) {
|
|
2781
|
+
params.invite = invite;
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
if (!isNil(gateway)) {
|
|
2785
|
+
params.gateway = gateway;
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
const keys = Object.keys(params);
|
|
2789
|
+
if (!keys.length) {
|
|
2790
|
+
throw new Error('No settings to update');
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
await states.blockletExtras.setSettings(did, params);
|
|
2794
|
+
|
|
2795
|
+
if (!isNil(gateway)) {
|
|
2796
|
+
const nodeState = states.node;
|
|
2797
|
+
const doc = await nodeState.read();
|
|
2798
|
+
nodeState.emit(EVENTS.RELOAD_GATEWAY, doc);
|
|
2799
|
+
}
|
|
2773
2800
|
|
|
2774
2801
|
const newState = await this.getBlocklet(did);
|
|
2775
2802
|
this.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
|
|
@@ -12,6 +12,8 @@ const inProgressStatuses = [BlockletStatus.stopping, BlockletStatus.restarting,
|
|
|
12
12
|
class EnsureBlockletRunning {
|
|
13
13
|
initialized = false;
|
|
14
14
|
|
|
15
|
+
firstChecked = false;
|
|
16
|
+
|
|
15
17
|
// 每次任务的最小间隔时间
|
|
16
18
|
checkInterval = +process.env.ABT_NODE_ENSURE_RUNNING_CHECK_INTERVAL || 60 * 1000;
|
|
17
19
|
|
|
@@ -52,12 +54,15 @@ class EnsureBlockletRunning {
|
|
|
52
54
|
|
|
53
55
|
isBlockletPortHealthyWithRetries = async (blocklet, isDoing = false) => {
|
|
54
56
|
let error;
|
|
55
|
-
|
|
57
|
+
const maxAttempts = this.firstChecked ? 10 : 2;
|
|
58
|
+
const timeout = this.firstChecked ? 6000 : 3000;
|
|
59
|
+
|
|
60
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
56
61
|
try {
|
|
57
62
|
// eslint-disable-next-line no-await-in-loop
|
|
58
63
|
await this.isBlockletPortHealthy(blocklet, {
|
|
59
64
|
minConsecutiveTime: 3000,
|
|
60
|
-
timeout
|
|
65
|
+
timeout,
|
|
61
66
|
});
|
|
62
67
|
return true;
|
|
63
68
|
} catch (e) {
|
|
@@ -141,6 +146,7 @@ class EnsureBlockletRunning {
|
|
|
141
146
|
logger.error('ensure blocklet status failed', e);
|
|
142
147
|
}
|
|
143
148
|
this.runningRootBlocklets = {};
|
|
149
|
+
this.firstChecked = true;
|
|
144
150
|
};
|
|
145
151
|
|
|
146
152
|
getRunningBlocklets = async () => {
|
|
@@ -762,6 +762,7 @@ module.exports = Object.freeze({
|
|
|
762
762
|
readNotifications: true,
|
|
763
763
|
unreadNotifications: true,
|
|
764
764
|
launchBlockletByLauncher: true,
|
|
765
|
+
launchBlockletWithoutWallet: true,
|
|
765
766
|
},
|
|
766
767
|
NOTIFICATION_SEND_STATUS: {
|
|
767
768
|
PENDING: 0, // 待发送
|
|
@@ -8202,7 +8203,7 @@ function save(namespaces) {
|
|
|
8202
8203
|
function load() {
|
|
8203
8204
|
let r;
|
|
8204
8205
|
try {
|
|
8205
|
-
r = exports.storage.getItem('debug');
|
|
8206
|
+
r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;
|
|
8206
8207
|
} catch (error) {
|
|
8207
8208
|
// Swallow
|
|
8208
8209
|
// XXX (@Qix-) should we be logging these?
|
|
@@ -8430,7 +8431,7 @@ function setup(env) {
|
|
|
8430
8431
|
|
|
8431
8432
|
const split = (typeof namespaces === 'string' ? namespaces : '')
|
|
8432
8433
|
.trim()
|
|
8433
|
-
.replace(
|
|
8434
|
+
.replace(/\s+/g, ',')
|
|
8434
8435
|
.split(',')
|
|
8435
8436
|
.filter(Boolean);
|
|
8436
8437
|
|
|
@@ -38888,7 +38889,7 @@ module.exports = require("zlib");
|
|
|
38888
38889
|
/***/ ((module) => {
|
|
38889
38890
|
|
|
38890
38891
|
"use strict";
|
|
38891
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.44","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","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.44","@abtnode/auth":"1.16.44","@abtnode/certificate-manager":"1.16.44","@abtnode/client":"1.16.44","@abtnode/constant":"1.16.44","@abtnode/cron":"1.16.44","@abtnode/db-cache":"1.16.44","@abtnode/docker-utils":"1.16.44","@abtnode/logger":"1.16.44","@abtnode/models":"1.16.44","@abtnode/queue":"1.16.44","@abtnode/rbac":"1.16.44","@abtnode/router-provider":"1.16.44","@abtnode/static-server":"1.16.44","@abtnode/timemachine":"1.16.44","@abtnode/util":"1.16.44","@arcblock/did":"1.20.14","@arcblock/did-auth":"1.20.14","@arcblock/did-ext":"1.20.14","@arcblock/did-motif":"^1.1.13","@arcblock/did-util":"1.20.14","@arcblock/event-hub":"1.20.14","@arcblock/jwt":"1.20.14","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"1.20.14","@arcblock/vc":"1.20.14","@blocklet/constant":"1.16.44","@blocklet/did-space-js":"^1.0.
|
|
38892
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.44","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","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.44","@abtnode/auth":"1.16.44","@abtnode/certificate-manager":"1.16.44","@abtnode/client":"1.16.44","@abtnode/constant":"1.16.44","@abtnode/cron":"1.16.44","@abtnode/db-cache":"1.16.44","@abtnode/docker-utils":"1.16.44","@abtnode/logger":"1.16.44","@abtnode/models":"1.16.44","@abtnode/queue":"1.16.44","@abtnode/rbac":"1.16.44","@abtnode/router-provider":"1.16.44","@abtnode/static-server":"1.16.44","@abtnode/timemachine":"1.16.44","@abtnode/util":"1.16.44","@arcblock/did":"1.20.14","@arcblock/did-auth":"1.20.14","@arcblock/did-ext":"1.20.14","@arcblock/did-motif":"^1.1.13","@arcblock/did-util":"1.20.14","@arcblock/event-hub":"1.20.14","@arcblock/jwt":"1.20.14","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"1.20.14","@arcblock/vc":"1.20.14","@blocklet/constant":"1.16.44","@blocklet/did-space-js":"^1.0.60","@blocklet/env":"1.16.44","@blocklet/error":"^0.2.5","@blocklet/meta":"1.16.44","@blocklet/resolver":"1.16.44","@blocklet/sdk":"1.16.44","@blocklet/store":"1.16.44","@blocklet/theme":"^2.13.67","@fidm/x509":"^1.2.1","@ocap/mcrypto":"1.20.14","@ocap/util":"1.20.14","@ocap/wallet":"1.20.14","@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","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":"^9.0.1","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"}');
|
|
38892
38893
|
|
|
38893
38894
|
/***/ }),
|
|
38894
38895
|
|
package/lib/index.js
CHANGED
|
@@ -23,6 +23,7 @@ const {
|
|
|
23
23
|
isLauncherSessionConsumed,
|
|
24
24
|
setupAppOwner,
|
|
25
25
|
launchBlockletByLauncher,
|
|
26
|
+
launchBlockletWithoutWallet,
|
|
26
27
|
} = require('./util/launcher');
|
|
27
28
|
const WebHook = require('./webhook');
|
|
28
29
|
const states = require('./states');
|
|
@@ -287,7 +288,6 @@ function ABTNode(options) {
|
|
|
287
288
|
const webhookAPI = new WebhookAPI({ states, teamManager });
|
|
288
289
|
|
|
289
290
|
const {
|
|
290
|
-
updateBlockletWafSettings,
|
|
291
291
|
handleBlockletWafChange,
|
|
292
292
|
handleRouting,
|
|
293
293
|
resetSiteByDid,
|
|
@@ -454,8 +454,6 @@ function ABTNode(options) {
|
|
|
454
454
|
// check update
|
|
455
455
|
updateAutoCheckUpdate: blockletManager.updateAutoCheckUpdate.bind(blockletManager),
|
|
456
456
|
|
|
457
|
-
updateInviteSettings: blockletManager.updateInviteSettings.bind(blockletManager),
|
|
458
|
-
|
|
459
457
|
// Store
|
|
460
458
|
getBlockletMeta: StoreUtil.getBlockletMeta,
|
|
461
459
|
getStoreMeta: StoreUtil.getStoreMeta,
|
|
@@ -506,7 +504,7 @@ function ABTNode(options) {
|
|
|
506
504
|
getConnectedAccount: teamAPI.getConnectedAccount.bind(teamAPI),
|
|
507
505
|
getOwner: teamAPI.getOwner.bind(teamAPI),
|
|
508
506
|
getNodeUsers: () => teamAPI.getUsers({ teamDid: options.nodeDid }),
|
|
509
|
-
getNodeUser: (user) => teamAPI.getUser({ teamDid: options.nodeDid, user }),
|
|
507
|
+
getNodeUser: (user, _options) => teamAPI.getUser({ teamDid: options.nodeDid, user, options: _options }),
|
|
510
508
|
addUser: teamAPI.addUser.bind(teamAPI),
|
|
511
509
|
loginUser: teamAPI.loginUser.bind(teamAPI),
|
|
512
510
|
disconnectUserAccount: teamAPI.disconnectUserAccount.bind(teamAPI),
|
|
@@ -719,6 +717,7 @@ function ABTNode(options) {
|
|
|
719
717
|
isLauncherSessionConsumed,
|
|
720
718
|
setupAppOwner,
|
|
721
719
|
launchBlockletByLauncher: (params, context) => launchBlockletByLauncher(instance, params, context),
|
|
720
|
+
launchBlockletWithoutWallet: (params, context) => launchBlockletWithoutWallet(instance, params, context),
|
|
722
721
|
|
|
723
722
|
// init security default data
|
|
724
723
|
initializeSecurityDefaultData: securityAPI.initializeDefaultData.bind(securityAPI),
|
|
@@ -777,7 +776,7 @@ function ABTNode(options) {
|
|
|
777
776
|
createOAuthClient: teamAPI.createOAuthClient.bind(teamAPI),
|
|
778
777
|
updateOAuthClient: teamAPI.updateOAuthClient.bind(teamAPI),
|
|
779
778
|
|
|
780
|
-
|
|
779
|
+
updateBlockletSettings: blockletManager.updateBlockletSettings.bind(blockletManager),
|
|
781
780
|
};
|
|
782
781
|
|
|
783
782
|
blockletManager.createAuditLog = (params) => states.auditLog.create(params, instance);
|
package/lib/router/helper.js
CHANGED
|
@@ -1444,7 +1444,7 @@ module.exports = function getRouterHelpers({
|
|
|
1444
1444
|
entityType: 'server',
|
|
1445
1445
|
severity: 'error',
|
|
1446
1446
|
source: 'system',
|
|
1447
|
-
sticky:
|
|
1447
|
+
sticky: false,
|
|
1448
1448
|
});
|
|
1449
1449
|
});
|
|
1450
1450
|
}
|
|
@@ -1459,7 +1459,16 @@ module.exports = function getRouterHelpers({
|
|
|
1459
1459
|
if (daemon && info.routing.blockPolicy?.autoBlocking?.enabled && providers[providerName].supportsModSecurity()) {
|
|
1460
1460
|
scanner.stopLogWatcher();
|
|
1461
1461
|
const logs = providers[providerName].getLogFilesForToday();
|
|
1462
|
-
const limiter = createLimiter(info.routing.blockPolicy.autoBlocking)
|
|
1462
|
+
const limiter = createLimiter(info.routing.blockPolicy.autoBlocking, (entry) => {
|
|
1463
|
+
teamManager.createNotification({
|
|
1464
|
+
title: 'User IP Blocked',
|
|
1465
|
+
description: `User IP blocked: ${JSON.stringify(entry, null, 2)}`,
|
|
1466
|
+
entityType: 'server',
|
|
1467
|
+
severity: 'error',
|
|
1468
|
+
source: 'system',
|
|
1469
|
+
sticky: false,
|
|
1470
|
+
});
|
|
1471
|
+
});
|
|
1463
1472
|
scanner.startLogWatcher(logs.error, async (logEntries) => {
|
|
1464
1473
|
const blocked = [];
|
|
1465
1474
|
const grouped = countBy(logEntries, 'ip');
|
|
@@ -1894,13 +1903,6 @@ module.exports = function getRouterHelpers({
|
|
|
1894
1903
|
return uniq([...blacklist]);
|
|
1895
1904
|
};
|
|
1896
1905
|
|
|
1897
|
-
const updateBlockletWafSettings = async ({ teamDid, wafPolicy }) => {
|
|
1898
|
-
await states.blockletExtras.setSettings(teamDid, { gateway: { wafPolicy } });
|
|
1899
|
-
|
|
1900
|
-
const doc = await nodeState.read();
|
|
1901
|
-
nodeState.emit(EVENTS.RELOAD_GATEWAY, doc);
|
|
1902
|
-
};
|
|
1903
|
-
|
|
1904
1906
|
const handleBlockletWafChange = async ({ teamDid, wafPolicy }) => {
|
|
1905
1907
|
const blocklet = await blockletManager.detail({ did: teamDid });
|
|
1906
1908
|
if (!blocklet) {
|
|
@@ -1925,7 +1927,6 @@ module.exports = function getRouterHelpers({
|
|
|
1925
1927
|
};
|
|
1926
1928
|
|
|
1927
1929
|
return {
|
|
1928
|
-
updateBlockletWafSettings,
|
|
1929
1930
|
handleBlockletWafChange,
|
|
1930
1931
|
ensureDashboardRouting,
|
|
1931
1932
|
ensureBlockletRouting,
|
|
@@ -16,9 +16,10 @@ const states = require('../../states');
|
|
|
16
16
|
* windowQuota: number;
|
|
17
17
|
* blockDuration: number;
|
|
18
18
|
* }} options
|
|
19
|
+
* @param {(entry: { scope: string, key: string, expiresAt: number }) => void} onBlocked
|
|
19
20
|
* @returns {{ check: (ip: string, points?: number) => Promise<number> }}
|
|
20
21
|
*/
|
|
21
|
-
function createLimiter(options) {
|
|
22
|
+
function createLimiter(options, onBlocked = () => {}) {
|
|
22
23
|
const limiter = new RateLimiterMemory({
|
|
23
24
|
points: options.windowQuota,
|
|
24
25
|
duration: options.windowSize,
|
|
@@ -35,8 +36,10 @@ function createLimiter(options) {
|
|
|
35
36
|
logger.info('Rate limit has exceeded', { ip, err });
|
|
36
37
|
const expiresAt = dayjs().add(err.msBeforeNext, 'ms').unix();
|
|
37
38
|
const added = await states.blacklist.addItem(BLACKLIST_SCOPE.ROUTER, ip, expiresAt);
|
|
39
|
+
|
|
38
40
|
if (added) {
|
|
39
41
|
logger.info('User IP blocked', { ip, expiresAt });
|
|
42
|
+
onBlocked({ scope: BLACKLIST_SCOPE.ROUTER, key: ip, expiresAt });
|
|
40
43
|
return err.msBeforeNext;
|
|
41
44
|
}
|
|
42
45
|
}
|
package/lib/states/audit-log.js
CHANGED
|
@@ -536,8 +536,20 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
536
536
|
case 'deleteOAuthClient':
|
|
537
537
|
return `Delete ${args.teamDid} OAuth Client:(${args.clientId})`;
|
|
538
538
|
|
|
539
|
-
case '
|
|
540
|
-
|
|
539
|
+
case 'updateBlockletSettings': {
|
|
540
|
+
const changes = [];
|
|
541
|
+
if (!isNil(args.enableSessionHardening)) {
|
|
542
|
+
changes.push(`* Session Hardening: ${args.enableSessionHardening}`);
|
|
543
|
+
}
|
|
544
|
+
if (!isNil(args.invite)) {
|
|
545
|
+
changes.push(`* Invite: ${JSON.stringify(args.invite)}`);
|
|
546
|
+
}
|
|
547
|
+
if (!isNil(args.gateway)) {
|
|
548
|
+
changes.push(`* Gateway: ${JSON.stringify(args.gateway)}`);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return `Update Blocklet Extras Settings:(${args.did} to ${changes.join(', ')})`;
|
|
552
|
+
}
|
|
541
553
|
|
|
542
554
|
default:
|
|
543
555
|
return action;
|
|
@@ -586,7 +598,7 @@ const getLogCategory = (action) => {
|
|
|
586
598
|
case 'deleteOAuthClient':
|
|
587
599
|
case 'createOAuthClient':
|
|
588
600
|
case 'updateOAuthClient':
|
|
589
|
-
case '
|
|
601
|
+
case 'updateBlockletSettings':
|
|
590
602
|
return 'blocklet';
|
|
591
603
|
|
|
592
604
|
case 'addUploadEndpoint':
|
package/lib/states/node.js
CHANGED
package/lib/team/manager.js
CHANGED
|
@@ -105,9 +105,9 @@ class TeamManager extends EventEmitter {
|
|
|
105
105
|
this.init();
|
|
106
106
|
|
|
107
107
|
this.lock = new DBCache(() => ({
|
|
108
|
-
...getAbtNodeRedisAndSQLiteUrl(),
|
|
109
108
|
prefix: 'team-manager-locks',
|
|
110
109
|
ttl: 1000 * 30,
|
|
110
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
111
111
|
}));
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -222,15 +222,9 @@ class TeamManager extends EventEmitter {
|
|
|
222
222
|
users = users.concat(roleUsers);
|
|
223
223
|
}
|
|
224
224
|
if (userDids.length > 0) {
|
|
225
|
-
const queryUsers = await
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
approved: true,
|
|
229
|
-
selection,
|
|
230
|
-
includeConnectedAccounts,
|
|
231
|
-
includePassports: true,
|
|
232
|
-
},
|
|
233
|
-
});
|
|
225
|
+
const queryUsers = await Promise.all(
|
|
226
|
+
userDids.map((did) => userState.getUser(did, { includePassports: true, enableConnectedAccount: true }))
|
|
227
|
+
);
|
|
234
228
|
|
|
235
229
|
const validUsers = queryUsers.filter((user) => {
|
|
236
230
|
const { passports = [] } = user;
|
package/lib/util/blocklet.js
CHANGED
|
@@ -147,9 +147,9 @@ const startLock = new DBCache(() => ({
|
|
|
147
147
|
}));
|
|
148
148
|
|
|
149
149
|
const blockletCache = new DBCache(() => ({
|
|
150
|
-
...getAbtNodeRedisAndSQLiteUrl(),
|
|
151
150
|
prefix: 'blocklet-state',
|
|
152
151
|
ttl: BLOCKLET_CACHE_TTL,
|
|
152
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
153
153
|
}));
|
|
154
154
|
|
|
155
155
|
const getVersionScope = (meta) => {
|
|
@@ -1577,8 +1577,8 @@ const _getBlocklet = async ({
|
|
|
1577
1577
|
blocklet.settings.storeList = blocklet.settings.storeList || [];
|
|
1578
1578
|
blocklet.settings.theme = mergeWith(
|
|
1579
1579
|
cloneDeep({
|
|
1580
|
-
light: BLOCKLET_THEME_LIGHT,
|
|
1581
|
-
dark: BLOCKLET_THEME_DARK,
|
|
1580
|
+
light: { palette: BLOCKLET_THEME_LIGHT.palette },
|
|
1581
|
+
dark: { palette: BLOCKLET_THEME_DARK.palette },
|
|
1582
1582
|
prefer: 'light',
|
|
1583
1583
|
}),
|
|
1584
1584
|
blocklet.settings.theme,
|
|
@@ -1655,7 +1655,6 @@ const getBlocklet = ({
|
|
|
1655
1655
|
|
|
1656
1656
|
if (useCache) {
|
|
1657
1657
|
cacheKey = JSON.stringify({
|
|
1658
|
-
did,
|
|
1659
1658
|
ensureIntegrity,
|
|
1660
1659
|
getOptionalComponents,
|
|
1661
1660
|
});
|
|
@@ -2322,7 +2321,7 @@ const getConfigsFromInput = (configs = [], oldConfigs = []) => {
|
|
|
2322
2321
|
|
|
2323
2322
|
configs.forEach((config) => {
|
|
2324
2323
|
const oldConfig = oldConfigs.find((y) => y.key === config.key);
|
|
2325
|
-
if (isEnvShareable(config) || isEnvShareable(oldConfig)) {
|
|
2324
|
+
if (!config.key.startsWith(BLOCKLET_PREFERENCE_PREFIX) && (isEnvShareable(config) || isEnvShareable(oldConfig))) {
|
|
2326
2325
|
sharedConfigs.push(config);
|
|
2327
2326
|
} else {
|
|
2328
2327
|
selfConfigs.push(config);
|
package/lib/util/cache.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { getAppImageCacheDir, getAppOgCacheDir } = require('@abtnode/util/lib/blocklet');
|
|
4
|
+
const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
4
5
|
|
|
5
6
|
const clearCacheDir = (dir) => {
|
|
6
7
|
if (fs.existsSync(dir)) {
|
|
@@ -9,6 +10,15 @@ const clearCacheDir = (dir) => {
|
|
|
9
10
|
}
|
|
10
11
|
};
|
|
11
12
|
|
|
13
|
+
const clearDBCache = async () => {
|
|
14
|
+
const dbCache = new DBCache(() => ({
|
|
15
|
+
prefix: '*',
|
|
16
|
+
ttl: 1000 * 60,
|
|
17
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
18
|
+
}));
|
|
19
|
+
await dbCache.flushAll();
|
|
20
|
+
};
|
|
21
|
+
|
|
12
22
|
/**
|
|
13
23
|
* The `clearCache` function is used to clear cache files based on different
|
|
14
24
|
* parameters and directories.
|
|
@@ -18,6 +28,8 @@ const clearCacheDir = (dir) => {
|
|
|
18
28
|
* @returns String[] list of files removed from the cache.
|
|
19
29
|
*/
|
|
20
30
|
const clearCache = async (params, node, blockletManager) => {
|
|
31
|
+
await clearDBCache();
|
|
32
|
+
|
|
21
33
|
const baseDir = path.dirname(node.dataDirs.core);
|
|
22
34
|
|
|
23
35
|
// reset cache by pattern
|
package/lib/util/check-dns.js
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
const dns = require('dns');
|
|
2
2
|
const { promisify } = require('util');
|
|
3
|
-
const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
4
3
|
const logger = require('@abtnode/logger')('checkDNS');
|
|
5
4
|
|
|
6
5
|
const resolveCname = promisify(dns.resolveCname);
|
|
7
6
|
const resolve = promisify(dns.resolve);
|
|
8
7
|
|
|
9
|
-
const cache = new DBCache(() => ({
|
|
10
|
-
...getAbtNodeRedisAndSQLiteUrl(),
|
|
11
|
-
prefix: 'check-dns',
|
|
12
|
-
ttl: 60 * 60 * 1000,
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
8
|
async function checkDnsAndCname(domain, expectedCname = '') {
|
|
16
9
|
try {
|
|
17
10
|
await resolve(domain);
|
|
@@ -50,8 +43,4 @@ async function checkDnsAndCname(domain, expectedCname = '') {
|
|
|
50
43
|
}
|
|
51
44
|
}
|
|
52
45
|
|
|
53
|
-
|
|
54
|
-
return cache.autoCache(domain, () => checkDnsAndCname(domain, expectedCname));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
module.exports = getDNSInfo;
|
|
46
|
+
module.exports = checkDnsAndCname;
|
|
@@ -11,9 +11,9 @@ const filterParentDirs = require('./filter-parent-dirs');
|
|
|
11
11
|
const { createDockerImage } = require('./create-docker-image');
|
|
12
12
|
|
|
13
13
|
const lockFile = new DBCache(() => ({
|
|
14
|
-
...getAbtNodeRedisAndSQLiteUrl(),
|
|
15
14
|
prefix: 'docker-exec-chown-locks',
|
|
16
15
|
ttl: 1000 * 60 * 2,
|
|
16
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
17
17
|
}));
|
|
18
18
|
|
|
19
19
|
async function dockerExecChown({ name, dirs, code = 777, force = false }) {
|
|
@@ -5,9 +5,9 @@ const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
|
5
5
|
const { checkDockerInstalled } = require('./check-docker-installed');
|
|
6
6
|
|
|
7
7
|
const lockNetwork = new DBCache(() => ({
|
|
8
|
-
...getAbtNodeRedisAndSQLiteUrl(),
|
|
9
8
|
prefix: 'docker-network-locks',
|
|
10
9
|
ttl: 1000 * 10,
|
|
10
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
11
11
|
}));
|
|
12
12
|
|
|
13
13
|
async function getDockerNetworks() {
|
package/lib/util/launcher.js
CHANGED
|
@@ -15,6 +15,7 @@ const {
|
|
|
15
15
|
getAvatarByUrl,
|
|
16
16
|
getAppAvatarUrl,
|
|
17
17
|
} = require('@abtnode/util/lib/user');
|
|
18
|
+
const { CustomError } = require('@blocklet/error');
|
|
18
19
|
const { createLaunchBlockletHandler, createServerlessInstallGuard } = require('@abtnode/auth/lib/server');
|
|
19
20
|
const { getDisplayName } = require('@blocklet/meta/lib/util');
|
|
20
21
|
const { fromAppDid } = require('@arcblock/did-ext');
|
|
@@ -24,7 +25,7 @@ const { getBlockletLogos } = require('@abtnode/util/lib/blocklet');
|
|
|
24
25
|
const { PASSPORT_SOURCE, PASSPORT_LOG_ACTION, PASSPORT_ISSUE_ACTION } = require('@abtnode/constant');
|
|
25
26
|
|
|
26
27
|
const { getLauncherUser, getLauncherSession: getLauncherSessionRaw, doRequest } = require('@abtnode/auth/lib/launcher');
|
|
27
|
-
const { createAuthToken, getPassportStatusEndpoint } = require('@abtnode/auth/lib/auth');
|
|
28
|
+
const { createAuthToken, getPassportStatusEndpoint, messages } = require('@abtnode/auth/lib/auth');
|
|
28
29
|
const { createPassportVC, createPassport, createUserPassport } = require('@abtnode/auth/lib/passport');
|
|
29
30
|
|
|
30
31
|
const { LOGIN_PROVIDER, fromBlockletStatus } = require('@blocklet/constant');
|
|
@@ -245,7 +246,7 @@ const setupAppOwner = async ({ node, sessionId, justCreate = false, context, pro
|
|
|
245
246
|
appOwnerProfile.avatar = await extractUserAvatar(avatarBase64, { dataDir });
|
|
246
247
|
logger.info('Create owner from launcher for blocklet', { appDid, ownerDid, ownerPk, sessionId, appOwnerProfile });
|
|
247
248
|
} else {
|
|
248
|
-
user = await node.getUser({ teamDid: info.did, user: { did: userDid } });
|
|
249
|
+
user = await node.getUser({ teamDid: info.did, user: { did: userDid }, options: { enableConnectedAccount: true } });
|
|
249
250
|
if (!user) {
|
|
250
251
|
throw new Error(`Owner user not found in server: ${userDid}`);
|
|
251
252
|
}
|
|
@@ -537,6 +538,68 @@ const launchBlockletByLauncher = async (node, extraParams, context) => {
|
|
|
537
538
|
return data;
|
|
538
539
|
};
|
|
539
540
|
|
|
541
|
+
const launchBlockletWithoutWallet = async (node, extraParams, context) => {
|
|
542
|
+
logger.debug('launchBlockletWithoutWallet', { extraParams, context });
|
|
543
|
+
|
|
544
|
+
extraParams.locale = context.locale || 'en';
|
|
545
|
+
|
|
546
|
+
const { blockletMetaUrl, title, description, locale } = extraParams;
|
|
547
|
+
|
|
548
|
+
if (!blockletMetaUrl && !title && !description) {
|
|
549
|
+
logger.error('blockletMetaUrl | title + description must be provided');
|
|
550
|
+
throw new CustomError(400, messages.missingBlockletUrl[locale]);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const blocklet = blockletMetaUrl
|
|
554
|
+
? await node.getBlockletMetaFromUrl({ url: blockletMetaUrl, checkPrice: true })
|
|
555
|
+
: {
|
|
556
|
+
meta: {
|
|
557
|
+
title,
|
|
558
|
+
description,
|
|
559
|
+
},
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
if (!blocklet) {
|
|
563
|
+
throw new Error('Blocklet not found');
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// generate app key pair
|
|
567
|
+
const type = (blocklet?.meta?.environments || []).find((x) => x.name === 'CHAIN_TYPE')?.default || 'default';
|
|
568
|
+
const appWallet = fromRandom(type);
|
|
569
|
+
|
|
570
|
+
// use the server user to set up the app owner, this account only allows using the passkey to login
|
|
571
|
+
const { user } = context;
|
|
572
|
+
|
|
573
|
+
let data = {};
|
|
574
|
+
|
|
575
|
+
const handler = createLaunchBlockletHandler(node, 'session');
|
|
576
|
+
await handler(
|
|
577
|
+
{
|
|
578
|
+
extraParams,
|
|
579
|
+
userDid: user.did,
|
|
580
|
+
claims: [
|
|
581
|
+
{
|
|
582
|
+
type: 'keyPair',
|
|
583
|
+
secret: appWallet.secretKey,
|
|
584
|
+
userDid: user.did,
|
|
585
|
+
userPk: user.pk,
|
|
586
|
+
},
|
|
587
|
+
],
|
|
588
|
+
didwallet: {
|
|
589
|
+
os: 'managed',
|
|
590
|
+
version,
|
|
591
|
+
},
|
|
592
|
+
updateSession: (updates) => {
|
|
593
|
+
data = merge(data, updates);
|
|
594
|
+
},
|
|
595
|
+
provider: LOGIN_PROVIDER.EMAIL,
|
|
596
|
+
},
|
|
597
|
+
context
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
return data;
|
|
601
|
+
};
|
|
602
|
+
|
|
540
603
|
module.exports = {
|
|
541
604
|
consumeServerlessNFT,
|
|
542
605
|
consumeLauncherSession,
|
|
@@ -550,4 +613,5 @@ module.exports = {
|
|
|
550
613
|
isBlockletTerminated,
|
|
551
614
|
notifyBlockletUpdated,
|
|
552
615
|
launchBlockletByLauncher,
|
|
616
|
+
launchBlockletWithoutWallet,
|
|
553
617
|
};
|
package/lib/validators/theme.js
CHANGED
|
@@ -59,15 +59,15 @@ const actionSchema = Joi.object({
|
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
const paletteSchema = Joi.object({
|
|
62
|
-
mode: Joi.string().valid('light', 'dark').
|
|
63
|
-
primary: paletteColorSchema.
|
|
64
|
-
secondary: paletteColorSchema.
|
|
65
|
-
error: paletteColorSchema.
|
|
66
|
-
warning: paletteColorSchema.
|
|
67
|
-
info: paletteColorSchema.
|
|
68
|
-
success: paletteColorSchema.
|
|
69
|
-
grey: greySchema.
|
|
70
|
-
text: textSchema.
|
|
62
|
+
mode: Joi.string().valid('light', 'dark').optional(),
|
|
63
|
+
primary: paletteColorSchema.optional(),
|
|
64
|
+
secondary: paletteColorSchema.optional(),
|
|
65
|
+
error: paletteColorSchema.optional(),
|
|
66
|
+
warning: paletteColorSchema.optional(),
|
|
67
|
+
info: paletteColorSchema.optional(),
|
|
68
|
+
success: paletteColorSchema.optional(),
|
|
69
|
+
grey: greySchema.optional(),
|
|
70
|
+
text: textSchema.optional(),
|
|
71
71
|
divider: colorString.optional(),
|
|
72
72
|
background: backgroundSchema.optional(),
|
|
73
73
|
common: commonSchema.optional(),
|
|
@@ -148,6 +148,7 @@ const muiThemeSchema = Joi.object({
|
|
|
148
148
|
}).options({ allowUnknown: true, stripUnknown: true });
|
|
149
149
|
|
|
150
150
|
const blockletThemeSchema = Joi.object({
|
|
151
|
+
common: muiThemeSchema.required(),
|
|
151
152
|
light: muiThemeSchema.required(),
|
|
152
153
|
dark: muiThemeSchema.required(),
|
|
153
154
|
prefer: Joi.string().valid('light', 'dark', 'system').default('light'),
|
|
@@ -2,9 +2,9 @@ const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
|
2
2
|
|
|
3
3
|
// 确保多进程只会有一个任务在执行
|
|
4
4
|
const reduceQueue = new DBCache(() => ({
|
|
5
|
-
...getAbtNodeRedisAndSQLiteUrl(),
|
|
6
5
|
prefix: 'reduce-queue',
|
|
7
6
|
ttl: 5 * 1000,
|
|
7
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
10
|
module.exports = reduceQueue;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.45-beta-
|
|
6
|
+
"version": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,22 +19,22 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.45-beta-
|
|
23
|
-
"@abtnode/auth": "1.16.45-beta-
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.45-beta-
|
|
25
|
-
"@abtnode/client": "1.16.45-beta-
|
|
26
|
-
"@abtnode/constant": "1.16.45-beta-
|
|
27
|
-
"@abtnode/cron": "1.16.45-beta-
|
|
28
|
-
"@abtnode/db-cache": "1.16.45-beta-
|
|
29
|
-
"@abtnode/docker-utils": "1.16.45-beta-
|
|
30
|
-
"@abtnode/logger": "1.16.45-beta-
|
|
31
|
-
"@abtnode/models": "1.16.45-beta-
|
|
32
|
-
"@abtnode/queue": "1.16.45-beta-
|
|
33
|
-
"@abtnode/rbac": "1.16.45-beta-
|
|
34
|
-
"@abtnode/router-provider": "1.16.45-beta-
|
|
35
|
-
"@abtnode/static-server": "1.16.45-beta-
|
|
36
|
-
"@abtnode/timemachine": "1.16.45-beta-
|
|
37
|
-
"@abtnode/util": "1.16.45-beta-
|
|
22
|
+
"@abtnode/analytics": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
23
|
+
"@abtnode/auth": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
25
|
+
"@abtnode/client": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
26
|
+
"@abtnode/constant": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
27
|
+
"@abtnode/cron": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
28
|
+
"@abtnode/db-cache": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
29
|
+
"@abtnode/docker-utils": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
30
|
+
"@abtnode/logger": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
31
|
+
"@abtnode/models": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
32
|
+
"@abtnode/queue": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
33
|
+
"@abtnode/rbac": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
34
|
+
"@abtnode/router-provider": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
35
|
+
"@abtnode/static-server": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
36
|
+
"@abtnode/timemachine": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
37
|
+
"@abtnode/util": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
38
38
|
"@arcblock/did": "1.20.14",
|
|
39
39
|
"@arcblock/did-auth": "1.20.14",
|
|
40
40
|
"@arcblock/did-ext": "1.20.14",
|
|
@@ -45,15 +45,15 @@
|
|
|
45
45
|
"@arcblock/pm2-events": "^0.0.5",
|
|
46
46
|
"@arcblock/validator": "1.20.14",
|
|
47
47
|
"@arcblock/vc": "1.20.14",
|
|
48
|
-
"@blocklet/constant": "1.16.45-beta-
|
|
49
|
-
"@blocklet/did-space-js": "^1.0.
|
|
50
|
-
"@blocklet/env": "1.16.45-beta-
|
|
48
|
+
"@blocklet/constant": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
49
|
+
"@blocklet/did-space-js": "^1.0.60",
|
|
50
|
+
"@blocklet/env": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
51
51
|
"@blocklet/error": "^0.2.5",
|
|
52
|
-
"@blocklet/meta": "1.16.45-beta-
|
|
53
|
-
"@blocklet/resolver": "1.16.45-beta-
|
|
54
|
-
"@blocklet/sdk": "1.16.45-beta-
|
|
55
|
-
"@blocklet/store": "1.16.45-beta-
|
|
56
|
-
"@blocklet/theme": "^2.13.
|
|
52
|
+
"@blocklet/meta": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
53
|
+
"@blocklet/resolver": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
54
|
+
"@blocklet/sdk": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
55
|
+
"@blocklet/store": "1.16.45-beta-20250614-101901-d1700f8d",
|
|
56
|
+
"@blocklet/theme": "^2.13.67",
|
|
57
57
|
"@fidm/x509": "^1.2.1",
|
|
58
58
|
"@ocap/mcrypto": "1.20.14",
|
|
59
59
|
"@ocap/util": "1.20.14",
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"jest": "^29.7.0",
|
|
117
117
|
"unzipper": "^0.10.11"
|
|
118
118
|
},
|
|
119
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "5fb4c294b2754d660fa946ac85c962edb2deaad2"
|
|
120
120
|
}
|