@abtnode/core 1.17.8-beta-20260109-075740-5f484e08 → 1.17.8-beta-20260113-015027-32a1cec4

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 (65) hide show
  1. package/lib/api/team/access-key-manager.js +104 -0
  2. package/lib/api/team/invitation-manager.js +461 -0
  3. package/lib/api/team/notification-manager.js +189 -0
  4. package/lib/api/team/oauth-manager.js +60 -0
  5. package/lib/api/team/org-crud-manager.js +202 -0
  6. package/lib/api/team/org-manager.js +56 -0
  7. package/lib/api/team/org-member-manager.js +403 -0
  8. package/lib/api/team/org-query-manager.js +126 -0
  9. package/lib/api/team/org-resource-manager.js +186 -0
  10. package/lib/api/team/passport-manager.js +670 -0
  11. package/lib/api/team/rbac-manager.js +335 -0
  12. package/lib/api/team/session-manager.js +540 -0
  13. package/lib/api/team/store-manager.js +198 -0
  14. package/lib/api/team/tag-manager.js +230 -0
  15. package/lib/api/team/user-auth-manager.js +132 -0
  16. package/lib/api/team/user-manager.js +78 -0
  17. package/lib/api/team/user-query-manager.js +299 -0
  18. package/lib/api/team/user-social-manager.js +354 -0
  19. package/lib/api/team/user-update-manager.js +224 -0
  20. package/lib/api/team/verify-code-manager.js +161 -0
  21. package/lib/api/team.js +439 -3287
  22. package/lib/blocklet/manager/disk/auth-manager.js +68 -0
  23. package/lib/blocklet/manager/disk/backup-manager.js +288 -0
  24. package/lib/blocklet/manager/disk/cleanup-manager.js +157 -0
  25. package/lib/blocklet/manager/disk/component-manager.js +83 -0
  26. package/lib/blocklet/manager/disk/config-manager.js +191 -0
  27. package/lib/blocklet/manager/disk/controller-manager.js +64 -0
  28. package/lib/blocklet/manager/disk/delete-reset-manager.js +328 -0
  29. package/lib/blocklet/manager/disk/download-manager.js +96 -0
  30. package/lib/blocklet/manager/disk/env-config-manager.js +311 -0
  31. package/lib/blocklet/manager/disk/federated-manager.js +651 -0
  32. package/lib/blocklet/manager/disk/hook-manager.js +124 -0
  33. package/lib/blocklet/manager/disk/install-component-manager.js +95 -0
  34. package/lib/blocklet/manager/disk/install-core-manager.js +448 -0
  35. package/lib/blocklet/manager/disk/install-download-manager.js +313 -0
  36. package/lib/blocklet/manager/disk/install-manager.js +36 -0
  37. package/lib/blocklet/manager/disk/install-upgrade-manager.js +340 -0
  38. package/lib/blocklet/manager/disk/job-manager.js +467 -0
  39. package/lib/blocklet/manager/disk/lifecycle-manager.js +26 -0
  40. package/lib/blocklet/manager/disk/notification-manager.js +343 -0
  41. package/lib/blocklet/manager/disk/query-manager.js +562 -0
  42. package/lib/blocklet/manager/disk/settings-manager.js +507 -0
  43. package/lib/blocklet/manager/disk/start-manager.js +611 -0
  44. package/lib/blocklet/manager/disk/stop-restart-manager.js +292 -0
  45. package/lib/blocklet/manager/disk/update-manager.js +153 -0
  46. package/lib/blocklet/manager/disk.js +669 -5796
  47. package/lib/blocklet/manager/helper/blue-green-start-blocklet.js +5 -0
  48. package/lib/blocklet/manager/lock.js +18 -0
  49. package/lib/event/index.js +28 -24
  50. package/lib/util/blocklet/app-utils.js +192 -0
  51. package/lib/util/blocklet/blocklet-loader.js +258 -0
  52. package/lib/util/blocklet/config-manager.js +232 -0
  53. package/lib/util/blocklet/did-document.js +240 -0
  54. package/lib/util/blocklet/environment.js +555 -0
  55. package/lib/util/blocklet/health-check.js +449 -0
  56. package/lib/util/blocklet/install-utils.js +365 -0
  57. package/lib/util/blocklet/logo.js +57 -0
  58. package/lib/util/blocklet/meta-utils.js +269 -0
  59. package/lib/util/blocklet/port-manager.js +141 -0
  60. package/lib/util/blocklet/process-manager.js +504 -0
  61. package/lib/util/blocklet/runtime-info.js +105 -0
  62. package/lib/util/blocklet/validation.js +418 -0
  63. package/lib/util/blocklet.js +98 -3066
  64. package/lib/util/wallet-app-notification.js +40 -0
  65. package/package.json +22 -22
@@ -0,0 +1,507 @@
1
+ const isUrl = require('is-url');
2
+ const get = require('lodash/get');
3
+ const isNil = require('lodash/isNil');
4
+ const isUndefined = require('lodash/isUndefined');
5
+ const isEmpty = require('lodash/isEmpty');
6
+ const uniq = require('lodash/uniq');
7
+ const cloneDeep = require('@abtnode/util/lib/deep-clone');
8
+ const { joinURL } = require('ufo');
9
+ const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager:settings');
10
+ const { CustomError } = require('@blocklet/error');
11
+ const { Joi } = require('@arcblock/validator');
12
+ const { SESSION_CACHE_TTL, BACKUPS, EVENTS } = require('@abtnode/constant');
13
+ const { BlockletEvents, BlockletInternalEvents } = require('@blocklet/constant');
14
+ const { getEmailServiceProvider } = require('@abtnode/auth/lib/email');
15
+
16
+ const { getOriginUrl } = require('@abtnode/util/lib/url-evaluation');
17
+ const request = require('../../../util/request');
18
+
19
+ const states = require('../../../states');
20
+ const { validateOwner } = require('../../../util');
21
+ const { validateAddSpaceGateway, validateUpdateSpaceGateway } = require('../../../validators/space-gateway');
22
+ const { sessionConfigSchema } = require('../../../validators/util');
23
+ const { translate } = require('../../../locales');
24
+ const { SpacesBackup } = require('../../storage/backup/spaces');
25
+ const { getBackupJobId, getBackupEndpoint, getCheckUpdateJobId } = require('../../../util/spaces');
26
+ const { decryptValue } = require('../../../util/aigne-verify');
27
+
28
+ /**
29
+ * Set blocklet blurhash
30
+ * @param {Object} manager - BlockletManager instance
31
+ * @param {Object} params
32
+ * @param {string} params.did - Blocklet DID
33
+ * @param {Object} params.blurhash - Blurhash data
34
+ * @returns {Promise<Object>}
35
+ */
36
+ async function setBlockletBlurhash(manager, { did, blurhash }) {
37
+ await states.blockletExtras.setSettings(did, { blurhash });
38
+ const newState = await manager.getBlocklet(did);
39
+ return newState;
40
+ }
41
+
42
+ /**
43
+ * Get blocklet blurhash
44
+ * @param {Object} manager - BlockletManager instance
45
+ * @param {Object} params
46
+ * @param {string} params.did - Blocklet DID
47
+ * @returns {Promise<Object>}
48
+ */
49
+ async function getBlockletBlurhash(manager, { did }) {
50
+ const blurhash = await states.blockletExtras.getSettings(did, 'blurhash');
51
+ const result = blurhash || {};
52
+ if (!result.splashPortrait) {
53
+ result.splashPortrait = 'U0PQ87~q?b~q?bfQj[fQ~qof9FWB?bfQayj[';
54
+ }
55
+ if (!result.splashLandscape) {
56
+ result.splashLandscape = 'U2PQ87xu-;xu%MayfQj[~qj[D%ay%Mj[fQay';
57
+ }
58
+ return result;
59
+ }
60
+
61
+ /**
62
+ * Update blocklet settings
63
+ * @param {Object} manager - BlockletManager instance
64
+ * @param {Object} params
65
+ * @param {Object} context
66
+ * @returns {Promise<Object>}
67
+ */
68
+ async function updateBlockletSettings(manager, { did, enableSessionHardening, invite, gateway, aigne, org }, context) {
69
+ const params = {};
70
+ if (!isNil(enableSessionHardening)) {
71
+ params.enableSessionHardening = enableSessionHardening;
72
+ }
73
+
74
+ if (!isNil(invite)) {
75
+ params.invite = invite;
76
+ }
77
+
78
+ if (!isNil(gateway)) {
79
+ params.gateway = gateway;
80
+ }
81
+
82
+ if (!isNil(aigne)) {
83
+ const { key, url } = aigne;
84
+ if (url && !isUrl(url)) {
85
+ throw new CustomError(400, 'The AIGNE API Url is either missing or incorrectly formatted');
86
+ }
87
+ if (!key) {
88
+ throw new CustomError(400, 'The AIGNE API key is missing');
89
+ }
90
+
91
+ const decryptedKey = decryptValue(key, did);
92
+ if (key && !decryptedKey) {
93
+ throw new CustomError(400, 'Save failed, the API key is not encrypted');
94
+ }
95
+ params.aigne = {
96
+ ...aigne,
97
+ url: getOriginUrl(aigne.url),
98
+ };
99
+ }
100
+
101
+ let shouldRotateSession = false;
102
+ if (!isNil(org)) {
103
+ const ORG_SCHEMA = Joi.object({
104
+ enabled: Joi.boolean().required(),
105
+ maxMemberPerOrg: Joi.number().required().min(2).default(100),
106
+ maxOrgPerUser: Joi.number().required().min(1).default(10),
107
+ });
108
+ const { error } = ORG_SCHEMA.validate(org);
109
+ if (error) {
110
+ throw new CustomError(400, error.message);
111
+ }
112
+ const currentState = await manager.getBlocklet(did, { useCache: true });
113
+ const orgEnabled = get(currentState, 'settings.org.enabled', false);
114
+ if (orgEnabled !== org.enabled) {
115
+ shouldRotateSession = true;
116
+ }
117
+ params.org = org;
118
+ }
119
+
120
+ const keys = Object.keys(params);
121
+ if (!keys.length) {
122
+ throw new Error('No settings to update');
123
+ }
124
+
125
+ await states.blockletExtras.setSettings(did, params);
126
+
127
+ if (!isNil(gateway)) {
128
+ const nodeState = states.node;
129
+ const doc = await nodeState.read();
130
+ nodeState.emit(EVENTS.RELOAD_GATEWAY, doc);
131
+ }
132
+
133
+ const newState = await manager.getBlocklet(did);
134
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
135
+ manager.emit(BlockletEvents.updated, { ...newState, context });
136
+
137
+ if (shouldRotateSession) {
138
+ manager.teamAPI.rotateSessionKey({ teamDid: did });
139
+ }
140
+
141
+ return newState;
142
+ }
143
+
144
+ /**
145
+ * Update app session config
146
+ * @param {Object} manager - BlockletManager instance
147
+ * @param {Object} params
148
+ * @param {Object} context
149
+ * @returns {Promise<Object>}
150
+ */
151
+ async function updateAppSessionConfig(manager, { did, config }, context) {
152
+ const validateConfig = await sessionConfigSchema.validateAsync(config);
153
+
154
+ const blocklet = await manager.getBlocklet(did);
155
+ if (!blocklet) {
156
+ throw new Error('blocklet does not exist');
157
+ }
158
+
159
+ const sessionConfig = cloneDeep(blocklet.settings.session || {});
160
+
161
+ if (validateConfig.cacheTtl) {
162
+ sessionConfig.cacheTtl = validateConfig.cacheTtl;
163
+ } else {
164
+ sessionConfig.cacheTtl = SESSION_CACHE_TTL;
165
+ }
166
+ if (validateConfig.ttl) {
167
+ sessionConfig.ttl = validateConfig.ttl;
168
+ }
169
+
170
+ sessionConfig.email = validateConfig.email;
171
+ sessionConfig.phone = validateConfig.phone;
172
+ sessionConfig.enableBlacklist = validateConfig.enableBlacklist;
173
+
174
+ if (sessionConfig.email?.enabled && sessionConfig.email?.requireVerified && !getEmailServiceProvider(blocklet)) {
175
+ throw new Error('Email verification is required but email service is not available');
176
+ }
177
+
178
+ await states.blockletExtras.setSettings(blocklet.meta.did, { session: sessionConfig });
179
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
180
+
181
+ const newState = await manager.getBlocklet(did);
182
+ manager.emit(BlockletEvents.updated, { ...newState, context });
183
+
184
+ return newState;
185
+ }
186
+
187
+ /**
188
+ * Update vault
189
+ * @param {Object} manager - BlockletManager instance
190
+ * @param {Object} params
191
+ * @param {Object} context
192
+ * @returns {Promise<Object>}
193
+ */
194
+ async function updateVault(manager, { did, vaults }, context) {
195
+ await states.blocklet.updateBlockletVaults(did, vaults);
196
+ const newState = await manager.getBlocklet(did);
197
+ manager.emit(BlockletEvents.updated, { ...newState, context });
198
+ return newState;
199
+ }
200
+
201
+ /**
202
+ * Add blocklet space gateway
203
+ * @param {Object} manager - BlockletManager instance
204
+ * @param {Object} params
205
+ * @returns {Promise<void>}
206
+ */
207
+ async function addBlockletSpaceGateway(manager, { did, spaceGateway }) {
208
+ const spaceGateways = await getBlockletSpaceGateways(manager, { did });
209
+
210
+ const { error, value } = validateAddSpaceGateway.validate(spaceGateway, {
211
+ stripUnknown: true,
212
+ allowUnknown: true,
213
+ });
214
+
215
+ if (error) {
216
+ throw error;
217
+ }
218
+
219
+ spaceGateways.push(value);
220
+
221
+ await states.blockletExtras.setSettings(did, { spaceGateways });
222
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
223
+ }
224
+
225
+ /**
226
+ * Delete blocklet space gateway
227
+ * @param {Object} manager - BlockletManager instance
228
+ * @param {Object} params
229
+ * @returns {Promise<void>}
230
+ */
231
+ async function deleteBlockletSpaceGateway(manager, { did, spaceGatewayDid }) {
232
+ const spaceGateways = await getBlockletSpaceGateways(manager, { did });
233
+
234
+ const latestSpaceGateways = spaceGateways.filter((s) => {
235
+ if (spaceGatewayDid) {
236
+ return s?.did !== spaceGatewayDid;
237
+ }
238
+ return !isUndefined(s?.did);
239
+ });
240
+
241
+ await states.blockletExtras.setSettings(did, { spaceGateways: latestSpaceGateways });
242
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
243
+ }
244
+
245
+ /**
246
+ * Update blocklet space gateway
247
+ * @param {Object} manager - BlockletManager instance
248
+ * @param {Object} params
249
+ * @returns {Promise<void>}
250
+ */
251
+ async function updateBlockletSpaceGateway(manager, { did, where, spaceGateway }) {
252
+ const { error, value } = validateUpdateSpaceGateway.validate(spaceGateway, {
253
+ stripUnknown: true,
254
+ allowUnknown: true,
255
+ });
256
+
257
+ if (error) {
258
+ throw error;
259
+ }
260
+
261
+ const spaceGateways = await getBlockletSpaceGateways(manager, { did });
262
+
263
+ for (const s of spaceGateways) {
264
+ if (s.did === where?.did) {
265
+ Object.assign(s, value);
266
+ break;
267
+ }
268
+ }
269
+
270
+ await states.blockletExtras.setSettings(did, { spaceGateways });
271
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
272
+ }
273
+
274
+ /**
275
+ * Get blocklet space gateways
276
+ * @param {Object} manager - BlockletManager instance
277
+ * @param {Object} params
278
+ * @returns {Promise<Array>}
279
+ */
280
+ async function getBlockletSpaceGateways(manager, { did }) {
281
+ const spaceGateways = await states.blockletExtras.getSettings(did, 'spaceGateways', []);
282
+ return spaceGateways;
283
+ }
284
+
285
+ /**
286
+ * Update user space hosts
287
+ * @param {Object} manager - BlockletManager instance
288
+ * @param {Object} params
289
+ * @returns {Promise<void>}
290
+ */
291
+ async function updateUserSpaceHosts(manager, { did, url }) {
292
+ if (isUrl(url)) {
293
+ try {
294
+ const { data } = await request.get(joinURL(url, '__blocklet__.js?type=json'), { timeout: 5000 });
295
+ if (Array.isArray(data.domainAliases)) {
296
+ const userSpaceHosts = await getUserSpaceHosts(manager, { did });
297
+ const validHosts = data.domainAliases.filter(
298
+ (x) => x.endsWith('.did.abtnet.io') === false && x.endsWith('.ip.abtnet.io') === false
299
+ );
300
+ if (validHosts.every((x) => userSpaceHosts.includes(x))) {
301
+ return;
302
+ }
303
+
304
+ logger.info('updateUserSpaceHosts', { did, url, domains: data.domainAliases });
305
+ await states.blockletExtras.setSettings(did, {
306
+ userSpaceHosts: uniq([...userSpaceHosts, ...validHosts]),
307
+ });
308
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
309
+ }
310
+ } catch (error) {
311
+ logger.error('updateUserSpaceHosts', { did, url, error });
312
+ }
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Get user space hosts
318
+ * @param {Object} manager - BlockletManager instance
319
+ * @param {Object} params
320
+ * @returns {Promise<Array>}
321
+ */
322
+ async function getUserSpaceHosts(manager, { did }) {
323
+ const userSpaceHosts = await states.blockletExtras.getSettings(did, 'userSpaceHosts', []);
324
+ return userSpaceHosts;
325
+ }
326
+
327
+ /**
328
+ * Update auto backup settings
329
+ * @param {Object} manager - BlockletManager instance
330
+ * @param {Object} params
331
+ * @param {Object} context
332
+ * @returns {Promise<void>}
333
+ */
334
+ async function updateAutoBackup(manager, { did, autoBackup }, context) {
335
+ const value = { ...autoBackup };
336
+
337
+ const jobId = getBackupJobId(did);
338
+ if (typeof manager.backupQueue.delete === 'function') {
339
+ await manager.backupQueue.delete(jobId);
340
+ }
341
+
342
+ logger.info('updateAutoBackup.$value', value);
343
+
344
+ if (value.enabled) {
345
+ const blocklet = await states.blocklet.getBlocklet(did);
346
+ const backupEndpoint = getBackupEndpoint(blocklet?.environments);
347
+
348
+ if (isEmpty(backupEndpoint)) {
349
+ throw new Error(translate(context?.user?.locale, 'backup.space.unableEnableAutoBackup'));
350
+ }
351
+
352
+ const spacesBackup = new SpacesBackup({
353
+ appDid: blocklet.appDid,
354
+ appPid: blocklet.meta.did,
355
+ event: manager,
356
+ userDid: context?.user?.did,
357
+ referrer: context?.referrer,
358
+ locale: context?.user?.locale,
359
+ backup: {},
360
+ });
361
+ await spacesBackup.initialize();
362
+ await spacesBackup.verifySpace();
363
+
364
+ if (!SpacesBackup.isRunning(did)) {
365
+ manager.backupQueue.push(
366
+ {
367
+ entity: 'blocklet',
368
+ action: 'backupToSpaces',
369
+ did,
370
+ context,
371
+ },
372
+ jobId,
373
+ true,
374
+ BACKUPS.JOB.INTERVAL
375
+ );
376
+ }
377
+ }
378
+
379
+ await states.blockletExtras.setSettings(did, { autoBackup: value });
380
+ const newState = await manager.getBlocklet(did);
381
+
382
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
383
+ manager.emit(BlockletEvents.updated, { ...newState, context });
384
+ if (!value.enabled) {
385
+ manager.emit(BlockletEvents.disableAutoBackup, { args: { did, autoBackup }, result: autoBackup, context });
386
+ }
387
+ }
388
+
389
+ /**
390
+ * Get auto backup settings
391
+ * @param {Object} manager - BlockletManager instance
392
+ * @param {Object} params
393
+ * @returns {Promise<Object>}
394
+ */
395
+ async function getAutoBackup(manager, { did }) {
396
+ const autoBackup = await states.blockletExtras.getSettings(did, 'autoBackup', { enabled: false });
397
+ return autoBackup;
398
+ }
399
+
400
+ /**
401
+ * Update auto check update settings
402
+ * @param {Object} manager - BlockletManager instance
403
+ * @param {Object} params
404
+ * @param {Object} context
405
+ * @returns {Promise<void>}
406
+ */
407
+ async function updateAutoCheckUpdate(manager, { did, autoCheckUpdate }, context) {
408
+ const value = { ...autoCheckUpdate };
409
+ await states.blockletExtras.setSettings(did, { autoCheckUpdate: value });
410
+
411
+ const newState = await manager.getBlocklet(did);
412
+ manager.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
413
+ manager.emit(BlockletEvents.updated, { ...newState, context });
414
+
415
+ const jobId = getCheckUpdateJobId(did);
416
+ await manager.checkUpdateQueue.delete(jobId);
417
+
418
+ logger.info('updateAutoCheckUpdate.$value', value);
419
+
420
+ if (value.enabled) {
421
+ manager.checkUpdateQueue.push(
422
+ {
423
+ entity: 'blocklet',
424
+ action: 'autoCheckUpdate',
425
+ did,
426
+ context,
427
+ },
428
+ jobId,
429
+ true
430
+ );
431
+ }
432
+ }
433
+
434
+ /**
435
+ * Get auto check update settings
436
+ * @param {Object} manager - BlockletManager instance
437
+ * @param {Object} params
438
+ * @returns {Promise<Object>}
439
+ */
440
+ function getAutoCheckUpdate(manager, { did }) {
441
+ return states.blockletExtras.getSettings(did, 'autoCheckUpdate', { enabled: false });
442
+ }
443
+
444
+ /**
445
+ * Set blocklet initialized
446
+ * @param {Object} manager - BlockletManager instance
447
+ * @param {Object} params
448
+ * @param {Object} context
449
+ * @returns {Promise<Object>}
450
+ */
451
+ async function setInitialized(manager, { did, owner, purpose = '' }, context) {
452
+ if (!validateOwner(owner)) {
453
+ logger.warn('Blocklet owner is invalid for setInitialized', { did, owner });
454
+ throw new Error('Blocklet owner is invalid');
455
+ }
456
+
457
+ const blocklet = await states.blocklet.getBlocklet(did);
458
+ await states.blockletExtras.setSettings(blocklet.meta.did, { initialized: true, owner, purpose });
459
+ manager.configSynchronizer.throttledSyncAppConfig(blocklet.meta.did);
460
+ logger.info('Blocklet initialized', { did, owner });
461
+
462
+ manager.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did }, context });
463
+
464
+ return manager.getBlocklet(did);
465
+ }
466
+
467
+ /**
468
+ * Update blocklet owner
469
+ * @param {Object} manager - BlockletManager instance
470
+ * @param {Object} params
471
+ * @param {Object} context
472
+ * @returns {Promise<Object>}
473
+ */
474
+ async function updateOwner(manager, { did, owner }, context) {
475
+ if (!validateOwner(owner)) {
476
+ logger.warn('Blocklet owner is invalid for updateOwner', { did, owner });
477
+ throw new Error('Blocklet owner is invalid');
478
+ }
479
+
480
+ const blocklet = await states.blocklet.getBlocklet(did);
481
+ await states.blockletExtras.setSettings(blocklet.meta.did, { owner });
482
+ logger.info('update blocklet owner', { did, owner });
483
+
484
+ manager.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did }, context });
485
+
486
+ return manager.getBlocklet(did);
487
+ }
488
+
489
+ module.exports = {
490
+ setBlockletBlurhash,
491
+ getBlockletBlurhash,
492
+ updateBlockletSettings,
493
+ updateAppSessionConfig,
494
+ updateVault,
495
+ addBlockletSpaceGateway,
496
+ deleteBlockletSpaceGateway,
497
+ updateBlockletSpaceGateway,
498
+ getBlockletSpaceGateways,
499
+ updateUserSpaceHosts,
500
+ getUserSpaceHosts,
501
+ updateAutoBackup,
502
+ getAutoBackup,
503
+ updateAutoCheckUpdate,
504
+ getAutoCheckUpdate,
505
+ setInitialized,
506
+ updateOwner,
507
+ };