@iobroker/js-controller-cli 7.0.8-alpha.7-20250928-40cb80c18 → 7.1.0

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 (43) hide show
  1. package/build/cjs/lib/cli/cliLogs.js.map +1 -1
  2. package/build/cjs/lib/setup/dbConnection.js +4 -4
  3. package/build/cjs/lib/setup/dbConnection.js.map +2 -2
  4. package/build/cjs/lib/setup/multihostClient.d.ts +58 -22
  5. package/build/cjs/lib/setup/multihostClient.js +31 -24
  6. package/build/cjs/lib/setup/multihostClient.js.map +3 -3
  7. package/build/cjs/lib/setup/setupMultihost.d.ts +16 -4
  8. package/build/cjs/lib/setup/setupMultihost.js +32 -16
  9. package/build/cjs/lib/setup/setupMultihost.js.map +3 -3
  10. package/build/cjs/lib/setup/setupSetup.d.ts +3 -11
  11. package/build/cjs/lib/setup/setupSetup.js +65 -76
  12. package/build/cjs/lib/setup/setupSetup.js.map +2 -2
  13. package/build/cjs/lib/setup/setupVendor.d.ts +3 -1
  14. package/build/cjs/lib/setup/setupVendor.js +72 -35
  15. package/build/cjs/lib/setup/setupVendor.js.map +2 -2
  16. package/build/cjs/lib/setup.js +5 -2
  17. package/build/cjs/lib/setup.js.map +2 -2
  18. package/build/esm/lib/cli/cliLogs.js +1 -1
  19. package/build/esm/lib/cli/cliLogs.js.map +1 -1
  20. package/build/esm/lib/setup/dbConnection.d.ts.map +1 -1
  21. package/build/esm/lib/setup/dbConnection.js +14 -14
  22. package/build/esm/lib/setup/dbConnection.js.map +1 -1
  23. package/build/esm/lib/setup/multihostClient.d.ts +58 -22
  24. package/build/esm/lib/setup/multihostClient.d.ts.map +1 -1
  25. package/build/esm/lib/setup/multihostClient.js +47 -23
  26. package/build/esm/lib/setup/multihostClient.js.map +1 -1
  27. package/build/esm/lib/setup/setupMultihost.d.ts +16 -4
  28. package/build/esm/lib/setup/setupMultihost.d.ts.map +1 -1
  29. package/build/esm/lib/setup/setupMultihost.js +41 -18
  30. package/build/esm/lib/setup/setupMultihost.js.map +1 -1
  31. package/build/esm/lib/setup/setupSetup.d.ts +3 -11
  32. package/build/esm/lib/setup/setupSetup.d.ts.map +1 -1
  33. package/build/esm/lib/setup/setupSetup.js +66 -80
  34. package/build/esm/lib/setup/setupSetup.js.map +1 -1
  35. package/build/esm/lib/setup/setupVendor.d.ts +3 -1
  36. package/build/esm/lib/setup/setupVendor.d.ts.map +1 -1
  37. package/build/esm/lib/setup/setupVendor.js +72 -35
  38. package/build/esm/lib/setup/setupVendor.js.map +1 -1
  39. package/build/esm/lib/setup.d.ts.map +1 -1
  40. package/build/esm/lib/setup.js +6 -3
  41. package/build/esm/lib/setup.js.map +1 -1
  42. package/build/tsconfig.build.tsbuildinfo +1 -1
  43. package/package.json +7 -7
@@ -35,6 +35,7 @@ var import_js_controller_common = require("@iobroker/js-controller-common");
35
35
  var import_fs_extra = __toESM(require("fs-extra"), 1);
36
36
  var import_deep_clone = __toESM(require("deep-clone"), 1);
37
37
  var import_node_util = require("node:util");
38
+ var import_node_crypto = require("node:crypto");
38
39
  const VENDOR_FILE = "/etc/iob-vendor.json";
39
40
  class Vendor {
40
41
  objects;
@@ -65,16 +66,18 @@ class Vendor {
65
66
  *
66
67
  * @param file file path if not given, default path is used
67
68
  * @param password vendor password
69
+ * @param javascriptPassword vendor JavaScript password
68
70
  * @param logger
69
71
  */
70
- async checkVendor(file, password, logger) {
71
- logger = logger || {
72
+ async checkVendor(file, password, javascriptPassword, logger) {
73
+ logger ||= {
72
74
  debug: (text) => console.log(text),
73
75
  info: (text) => console.log(text),
74
76
  error: (text) => console.error(text),
75
- warn: (text) => console.warn(text)
77
+ warn: (text) => console.warn(text),
78
+ silly: (text) => console.log(text)
76
79
  };
77
- file = file || VENDOR_FILE;
80
+ file ||= VENDOR_FILE;
78
81
  let data;
79
82
  if (import_fs_extra.default.existsSync(file)) {
80
83
  try {
@@ -87,15 +90,14 @@ class Vendor {
87
90
  logger.error(`"${file}" does not exist`);
88
91
  throw new Error(`"${file}" does not exist`);
89
92
  }
90
- if (data.uuid) {
93
+ if (data?.uuid) {
91
94
  const uuid = data.uuid;
92
- data.uuid = null;
93
95
  const obj = await this.objects.getObject("system.meta.uuid");
94
96
  if (obj?.native) {
95
97
  if (obj.native.uuid !== uuid) {
96
98
  obj.native.uuid = uuid;
97
99
  logger.info(`Update "system.meta.uuid:native.uuid" = "${obj.native.uuid}"`);
98
- obj.nonEdit = obj.nonEdit || {};
100
+ obj.nonEdit ||= {};
99
101
  obj.nonEdit.password = password;
100
102
  try {
101
103
  await this.objects.setObjectAsync("system.meta.uuid", obj);
@@ -124,40 +126,73 @@ class Vendor {
124
126
  }
125
127
  }
126
128
  }
127
- if (data.iobroker) {
129
+ if (data?.iobroker) {
128
130
  const settings = import_fs_extra.default.readJSONSync(import_js_controller_common.tools.getConfigFileName());
129
131
  logger.info("Update iobroker.json file");
130
132
  this.deepMerge(settings, data.iobroker);
131
133
  import_fs_extra.default.writeFileSync(import_js_controller_common.tools.getConfigFileName(), JSON.stringify(settings, null, 2));
132
134
  }
133
- if (data.vendor) {
135
+ if (data?.vendor) {
134
136
  const vendor = (0, import_deep_clone.default)(data.vendor);
135
- data._vendor = (0, import_deep_clone.default)(vendor);
136
- data.vendor = null;
137
137
  try {
138
- const obj = await this.objects.getObject("system.config");
139
- if (obj && obj.native) {
140
- if (!(0, import_node_util.isDeepStrictEqual)(obj.native.vendor, vendor)) {
141
- obj.native.vendor = vendor;
142
- obj.nonEdit = obj.nonEdit || {};
143
- obj.nonEdit.password = password;
144
- await this.objects.setObjectAsync(obj._id, obj);
138
+ const configObj = await this.objects.getObject("system.config");
139
+ if (configObj?.native) {
140
+ let javascriptPasswordEncrypted;
141
+ if (javascriptPassword) {
142
+ if (!configObj.native?.secret) {
143
+ const buf = (0, import_node_crypto.randomBytes)(24);
144
+ configObj.native.secret = buf.toString("hex");
145
+ }
146
+ javascriptPasswordEncrypted = import_js_controller_common.tools.encrypt(configObj.native.secret, javascriptPassword);
147
+ }
148
+ if (!(0, import_node_util.isDeepStrictEqual)(configObj.native.vendor, vendor) || configObj.native.javascriptPassword !== javascriptPasswordEncrypted) {
149
+ configObj.native.vendor = vendor;
150
+ configObj.nonEdit ||= {};
151
+ if (javascriptPassword) {
152
+ configObj.native.javascriptPassword = javascriptPasswordEncrypted;
153
+ configObj.nonEdit.native ||= {};
154
+ configObj.nonEdit.native.javascriptPassword = javascriptPasswordEncrypted;
155
+ }
156
+ configObj.nonEdit.password = password;
157
+ await this.objects.setObjectAsync(configObj._id, configObj);
145
158
  logger.info("object system.config updated");
146
159
  }
147
160
  }
148
161
  } catch (e) {
149
162
  logger.error(`Cannot update system.config: ${e.message}`);
150
163
  }
164
+ } else if (javascriptPassword) {
165
+ const configObj = await this.objects.getObject("system.config");
166
+ if (configObj?.native) {
167
+ if (!configObj.native?.secret) {
168
+ const buf = (0, import_node_crypto.randomBytes)(24);
169
+ configObj.native.secret = buf.toString("hex");
170
+ }
171
+ const javascriptPasswordEncrypted = import_js_controller_common.tools.encrypt(configObj.native.secret, javascriptPassword);
172
+ if (configObj.native.javascriptPassword !== javascriptPasswordEncrypted) {
173
+ configObj.native.javascriptPassword = javascriptPasswordEncrypted;
174
+ configObj.nonEdit ||= {};
175
+ configObj.nonEdit.password = password;
176
+ configObj.nonEdit.native ||= {};
177
+ configObj.nonEdit.native.javascriptPassword = javascriptPasswordEncrypted;
178
+ try {
179
+ await this.objects.setObjectAsync(configObj._id, configObj);
180
+ logger.info("object system.config updated");
181
+ } catch (e) {
182
+ logger.error(`Cannot update system.config: ${e.message}`);
183
+ }
184
+ }
185
+ }
151
186
  }
152
- if (data.objects) {
187
+ if (data?.objects) {
153
188
  for (let id of Object.keys(data.objects)) {
154
189
  if (!id.includes("*")) {
155
190
  const _newObj = data.objects[id];
156
191
  const obj = await this.objects.getObject(id);
157
192
  if (obj) {
158
- obj.nonEdit = obj.nonEdit || {};
193
+ obj.nonEdit ||= {};
159
194
  const originalObj = (0, import_deep_clone.default)(obj);
160
- _newObj.nonEdit = _newObj.nonEdit || {};
195
+ _newObj.nonEdit ||= {};
161
196
  _newObj.nonEdit.passHash = obj.nonEdit.passHash;
162
197
  import_js_controller_common.tools.copyAttributes(_newObj, obj);
163
198
  if (!(0, import_node_util.isDeepStrictEqual)(originalObj, obj)) {
@@ -186,13 +221,13 @@ class Vendor {
186
221
  startkey: id,
187
222
  endkey: `${id}\u9999`
188
223
  }, { checked: true });
189
- if (arr && arr.rows && arr.rows.length) {
224
+ if (arr?.rows?.length) {
190
225
  for (const row of arr.rows) {
191
226
  const obj = row.value;
192
227
  if (obj) {
193
- obj.nonEdit = obj.nonEdit || {};
228
+ obj.nonEdit ||= {};
194
229
  const originalObj = (0, import_deep_clone.default)(obj);
195
- _obj.nonEdit = _obj.nonEdit || {};
230
+ _obj.nonEdit ||= {};
196
231
  _obj.nonEdit.passHash = obj.nonEdit.passHash;
197
232
  import_js_controller_common.tools.copyAttributes(_obj, obj);
198
233
  if (!(0, import_node_util.isDeepStrictEqual)(originalObj, obj)) {
@@ -212,12 +247,11 @@ class Vendor {
212
247
  }
213
248
  }
214
249
  }
215
- if (data.model) {
250
+ if (data?.model) {
216
251
  const model = data.model;
217
- data.model = null;
218
252
  const hostname = import_js_controller_common.tools.getHostName();
219
253
  const obj = await this.objects.getObject(`system.host.${hostname}`);
220
- if (obj && obj.common) {
254
+ if (obj?.common) {
221
255
  if (model.name && model.name !== "JS controller" && obj.common.title === "JS controller" || model.icon && !obj.common.icon || model.color && !obj.common.color) {
222
256
  if (model.name) {
223
257
  obj.common.title = model.name;
@@ -228,11 +262,17 @@ class Vendor {
228
262
  if (model.color) {
229
263
  obj.common.color = model.color;
230
264
  }
231
- obj.nonEdit = obj.nonEdit || {};
265
+ obj.nonEdit ||= {};
232
266
  obj.nonEdit.password = password;
233
- obj.common.title && logger.info(`Update "system.host.${hostname}:common.title" = "${obj.common.title}"`);
234
- obj.common.icon && logger.info(`Update "system.host.${hostname}:common.icon" = "${!!obj.common.icon}"`);
235
- obj.common.color && logger.info(`Update "system.host.${hostname}:common.color" = "${obj.common.color}"`);
267
+ if (obj.common.title) {
268
+ logger.info(`Update "system.host.${hostname}:common.title" = "${obj.common.title}"`);
269
+ }
270
+ if (obj.common.icon) {
271
+ logger.info(`Update "system.host.${hostname}:common.icon" = "${!!obj.common.icon}"`);
272
+ }
273
+ if (obj.common.color) {
274
+ logger.info(`Update "system.host.${hostname}:common.color" = "${obj.common.color}"`);
275
+ }
236
276
  try {
237
277
  await this.objects.setObjectAsync(obj._id, obj);
238
278
  logger.info(`object "system.host.${hostname}" updated`);
@@ -242,10 +282,7 @@ class Vendor {
242
282
  }
243
283
  }
244
284
  }
245
- setTimeout(() => {
246
- logger.warn("RESTART!");
247
- process.exit(-1);
248
- }, 2e3);
285
+ return true;
249
286
  }
250
287
  }
251
288
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/setup/setupVendor.ts"],
4
- "sourcesContent": ["import type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport { tools } from '@iobroker/js-controller-common';\nimport fs from 'fs-extra';\nimport deepClone from 'deep-clone';\nimport { isDeepStrictEqual } from 'node:util';\n\nexport interface CLIVendorOptions {\n objects: ObjectsRedisClient;\n}\n\nconst VENDOR_FILE = '/etc/iob-vendor.json';\n\nexport class Vendor {\n private readonly objects: ObjectsRedisClient;\n\n constructor(options: CLIVendorOptions) {\n this.objects = options.objects;\n }\n\n /**\n * Deep merge of source into target object\n *\n * @param target target obj\n * @param source source obj\n */\n private deepMerge(target: Record<string, any>, source: Record<string, any>): void {\n Object.keys(source).forEach(attr => {\n if (typeof source[attr] === 'object' && !(source[attr] instanceof Array)) {\n if (target[attr] && typeof target[attr] !== 'object') {\n target[attr] = {};\n }\n target[attr] = target[attr] || {};\n this.deepMerge(target[attr], source[attr]);\n } else {\n target[attr] = source[attr];\n }\n });\n }\n\n /**\n * Read info from '/etc/iob_vendor.json' and executes instructions stored there\n *\n * @param file file path if not given, default path is used\n * @param password vendor password\n * @param logger\n */\n async checkVendor(file: string | undefined, password: string, logger?: any): Promise<void> {\n logger = logger || {\n debug: (text: string) => console.log(text),\n info: (text: string) => console.log(text),\n error: (text: string) => console.error(text),\n warn: (text: string) => console.warn(text),\n };\n\n file = file || VENDOR_FILE;\n let data: Record<string, any>;\n if (fs.existsSync(file)) {\n try {\n data = fs.readJSONSync(file);\n } catch (err) {\n logger.error(`cannot read or parse \"${file}\": ${err.message}`);\n throw new Error(`cannot read or parse \"${file}\": ${err.message}`);\n }\n } else {\n logger.error(`\"${file}\" does not exist`);\n throw new Error(`\"${file}\" does not exist`);\n }\n\n if (data.uuid) {\n const uuid = data.uuid;\n data.uuid = null;\n\n // check UUID\n const obj = await this.objects.getObject('system.meta.uuid');\n if (obj?.native) {\n if (obj.native.uuid !== uuid) {\n obj.native.uuid = uuid;\n\n logger.info(`Update \"system.meta.uuid:native.uuid\" = \"${obj.native.uuid}\"`);\n\n obj.nonEdit = obj.nonEdit || {};\n obj.nonEdit.password = password;\n try {\n await this.objects.setObjectAsync('system.meta.uuid', obj);\n logger.info(`object system.meta.uuid updated: ${uuid}`);\n } catch (e) {\n logger.error(`Cannot update system.meta.uuid: ${e.message}`);\n }\n }\n } else {\n try {\n // @ts-expect-error type uuid is not allowed TODO: allow it for meta?\n await this.objects.setObjectAsync('system.meta.uuid', {\n type: 'meta',\n common: {\n name: 'uuid',\n type: 'uuid',\n },\n ts: new Date().getTime(),\n from: `system.host.${tools.getHostName()}.tools`,\n native: {\n uuid: uuid,\n },\n });\n logger.info(`object system.meta.uuid created: ${uuid}`);\n } catch (e) {\n logger.error(`Cannot create system.meta.uuid: ${e.message}`);\n }\n }\n }\n\n // patch iobroker.json file\n if (data.iobroker) {\n const settings = fs.readJSONSync(tools.getConfigFileName());\n logger.info('Update iobroker.json file');\n this.deepMerge(settings, data.iobroker);\n fs.writeFileSync(tools.getConfigFileName(), JSON.stringify(settings, null, 2));\n }\n\n if (data.vendor) {\n const vendor = deepClone(data.vendor);\n data._vendor = deepClone(vendor);\n data.vendor = null;\n\n // store vendor\n try {\n const obj = await this.objects.getObject('system.config');\n if (obj && obj.native) {\n if (!isDeepStrictEqual(obj.native.vendor, vendor)) {\n obj.native.vendor = vendor;\n obj.nonEdit = obj.nonEdit || {};\n obj.nonEdit.password = password;\n await this.objects.setObjectAsync(obj._id, obj);\n logger.info('object system.config updated');\n }\n }\n } catch (e) {\n logger.error(`Cannot update system.config: ${e.message}`);\n }\n }\n\n // update all existing objects according to vendor\n if (data.objects) {\n for (let id of Object.keys(data.objects)) {\n if (!id.includes('*')) {\n const _newObj = data.objects[id];\n const obj = await this.objects.getObject(id);\n if (obj) {\n obj.nonEdit = obj.nonEdit || {};\n const originalObj = deepClone(obj);\n _newObj.nonEdit = _newObj.nonEdit || {};\n _newObj.nonEdit.passHash = obj.nonEdit.passHash;\n // merge objects\n tools.copyAttributes(_newObj, obj);\n\n if (!isDeepStrictEqual(originalObj, obj)) {\n delete obj.nonEdit.passHash;\n obj.nonEdit.password = password;\n logger.info(`Update \"${obj._id}\"`);\n try {\n await this.objects.setObjectAsync(obj._id, obj);\n logger.info(`object \"${obj._id}\" updated`);\n } catch (e) {\n logger.error(`Cannot update \"${obj._id}\": ${e.message}`);\n }\n }\n } else {\n try {\n await this.objects.setObjectAsync(id, _newObj);\n logger.info(`object \"${_newObj._id}\" updated`);\n } catch (e) {\n logger.error(`Cannot update ${id} \"${JSON.stringify(_newObj)}\": ${e.message}`);\n }\n }\n } else {\n id = id.replace(/\\*/g, '');\n const _obj = data.objects[id];\n const arr = await this.objects.getObjectListAsync(\n {\n startkey: id,\n endkey: `${id}\\u9999`,\n },\n { checked: true },\n );\n\n if (arr && arr.rows && arr.rows.length) {\n for (const row of arr.rows) {\n const obj = row.value;\n if (obj) {\n obj.nonEdit = obj.nonEdit || {};\n const originalObj = deepClone(obj);\n _obj.nonEdit = _obj.nonEdit || {};\n _obj.nonEdit.passHash = obj.nonEdit.passHash;\n // merge objects\n tools.copyAttributes(_obj, obj);\n\n if (!isDeepStrictEqual(originalObj, obj)) {\n delete obj.nonEdit.passHash;\n obj.nonEdit.password = password;\n logger.info(`Update \"${obj._id}\"`);\n try {\n await this.objects.setObjectAsync(obj._id, obj);\n logger.info(`object \"${obj._id}\" updated`);\n } catch (e) {\n logger.error(`Cannot update \"${obj._id}\": ${e.message}`);\n }\n }\n }\n }\n }\n }\n }\n }\n\n // update host as last\n if (data.model) {\n const model = data.model;\n data.model = null;\n const hostname = tools.getHostName();\n const obj = await this.objects.getObject(`system.host.${hostname}`);\n if (obj && obj.common) {\n if (\n (model.name && model.name !== 'JS controller' && obj.common.title === 'JS controller') ||\n (model.icon && !obj.common.icon) ||\n (model.color && !obj.common.color)\n ) {\n if (model.name) {\n obj.common.title = model.name;\n }\n if (model.icon) {\n obj.common.icon = model.icon;\n }\n if (model.color) {\n obj.common.color = model.color;\n }\n\n obj.nonEdit = obj.nonEdit || {};\n obj.nonEdit.password = password;\n\n obj.common.title &&\n logger.info(`Update \"system.host.${hostname}:common.title\" = \"${obj.common.title}\"`);\n obj.common.icon &&\n logger.info(`Update \"system.host.${hostname}:common.icon\" = \"${!!obj.common.icon}\"`);\n obj.common.color &&\n logger.info(`Update \"system.host.${hostname}:common.color\" = \"${obj.common.color}\"`);\n\n try {\n await this.objects.setObjectAsync(obj._id, obj);\n logger.info(`object \"system.host.${hostname}\" updated`);\n } catch (e) {\n logger.error(`Cannot update \"system.host.${hostname}\": ${e.message}`);\n }\n }\n }\n }\n\n // restart ioBroker\n setTimeout(() => {\n logger.warn('RESTART!');\n process.exit(-1);\n }, 2_000);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { Client as ObjectsRedisClient } from '@iobroker/db-objects-redis';\nimport { tools } from '@iobroker/js-controller-common';\nimport fs from 'fs-extra';\nimport deepClone from 'deep-clone';\nimport { isDeepStrictEqual } from 'node:util';\nimport type { InternalLogger } from '@iobroker/js-controller-common-db/tools';\nimport { randomBytes } from 'node:crypto';\n\nexport interface CLIVendorOptions {\n objects: ObjectsRedisClient;\n}\n\ninterface iobVendorFile {\n vendor?: {\n id?: string;\n name?: string;\n /** Logo for login in admin */\n icon?: string;\n /** Logo in the top left corner of admin */\n logo?: string;\n admin?: {\n menu?: {\n // Settings for left menu\n editable?: false; // Hide edit button in menu\n 'tab-hosts'?: false; // Hide hosts item (See all https://github.com/ioBroker/ioBroker.admin/blob/master/src-rx/src/components/Drawer.js#L142)\n 'tab-files'?: false; // Hide files item\n 'tab-users'?: false; // Hide users item\n 'tab-intro'?: false; // Hide intro item\n 'tab-info'?: false; // Hide info item\n 'tab-adapters'?: false; // Hide adapters item\n 'tab-instances'?: false; // Hide instances item\n 'tab-objects'?: false; // Hide objects item\n 'tab-enums'?: false; // Hide enums item\n 'tab-devices'?: false; // Hide devices item\n 'tab-logs'?: false; // Hide logs item\n 'tab-scenes'?: false; // Hide scenes item\n 'tab-events'?: false; // Hide events item\n 'tab-javascript'?: false; // Hide javascript item\n 'tab-text2command-0'?: false; // Hide text2command-0 item\n 'tab-echarts'?: false; // Hide echarts item\n [tabName: string]: false | undefined;\n };\n appBar?: {\n discovery?: false;\n systemSettings?: false;\n toggleTheme?: false;\n expertMode?: false;\n hostSelector?: false;\n };\n settings?: {\n tabConfig?: false; // Main config tab\n tabRepositories?: false; // Repositories tab\n tabCertificates?: false; // Certificates tab\n tabLetsEncrypt?: false; // Let's Encrypt tab\n tabDefaultACL?: false; // Default ACL tab\n tabStatistics?: false; // Statistics tab\n\n language?: false;\n tempUnit?: false;\n currency?: false;\n dateFormat?: false;\n isFloatComma?: false;\n defaultHistory?: false;\n activeRepo?: false;\n expertMode?: false;\n defaultLogLevel?: false;\n };\n adapters?: {\n gitHubInstall?: false; // hide button install from GitHub/npm\n statistics?: false; // hide statistics on the right top\n filterUpdates?: false; // hide button filter updates in adapter tab\n allowAdapterRating?: false; // do not show and do not load adapter ratings\n };\n login?: {\n title?: string;\n motto?: string;\n link?: string;\n };\n };\n /** Favicon for admin */\n ico?: string;\n uuidPrefix?: string;\n };\n model?: {\n /** name for host */\n name?: string;\n /** Icon for host */\n icon?: string;\n /** Color for host */\n color?: string;\n };\n uuid?: string;\n iobroker?: Partial<ioBroker.IoBrokerJson>;\n objects?: {\n [id: string]: ioBroker.Object;\n };\n}\n\nconst VENDOR_FILE = '/etc/iob-vendor.json';\n\nexport class Vendor {\n private readonly objects: ObjectsRedisClient;\n\n constructor(options: CLIVendorOptions) {\n this.objects = options.objects;\n }\n\n /**\n * Deep merge of source into target object\n *\n * @param target target obj\n * @param source source obj\n */\n private deepMerge(target: Record<string, any>, source: Record<string, any>): void {\n Object.keys(source).forEach(attr => {\n if (typeof source[attr] === 'object' && !(source[attr] instanceof Array)) {\n if (target[attr] && typeof target[attr] !== 'object') {\n target[attr] = {};\n }\n target[attr] = target[attr] || {};\n this.deepMerge(target[attr], source[attr]);\n } else {\n target[attr] = source[attr];\n }\n });\n }\n\n /**\n * Read info from '/etc/iob_vendor.json' and executes instructions stored there\n *\n * @param file file path if not given, default path is used\n * @param password vendor password\n * @param javascriptPassword vendor JavaScript password\n * @param logger\n */\n async checkVendor(\n file: string | undefined,\n password: string,\n javascriptPassword: string | undefined,\n logger?: InternalLogger,\n ): Promise<boolean> {\n logger ||= {\n debug: (text: string) => console.log(text),\n info: (text: string) => console.log(text),\n error: (text: string) => console.error(text),\n warn: (text: string) => console.warn(text),\n silly: (text: string) => console.log(text),\n };\n\n file ||= VENDOR_FILE;\n\n let data: iobVendorFile;\n if (fs.existsSync(file)) {\n try {\n data = fs.readJSONSync(file);\n } catch (err) {\n logger.error(`cannot read or parse \"${file}\": ${err.message}`);\n throw new Error(`cannot read or parse \"${file}\": ${err.message}`);\n }\n } else {\n logger.error(`\"${file}\" does not exist`);\n throw new Error(`\"${file}\" does not exist`);\n }\n\n if (data?.uuid) {\n const uuid = data.uuid;\n\n // check UUID\n const obj = await this.objects.getObject('system.meta.uuid');\n if (obj?.native) {\n if (obj.native.uuid !== uuid) {\n obj.native.uuid = uuid;\n\n logger.info(`Update \"system.meta.uuid:native.uuid\" = \"${obj.native.uuid}\"`);\n\n obj.nonEdit ||= {};\n obj.nonEdit.password = password;\n try {\n await this.objects.setObjectAsync('system.meta.uuid', obj);\n logger.info(`object system.meta.uuid updated: ${uuid}`);\n } catch (e) {\n logger.error(`Cannot update system.meta.uuid: ${e.message}`);\n }\n }\n } else {\n try {\n // @ts-expect-error type uuid is not allowed TODO: allow it for meta?\n await this.objects.setObjectAsync('system.meta.uuid', {\n type: 'meta',\n common: {\n name: 'uuid',\n type: 'uuid',\n },\n ts: new Date().getTime(),\n from: `system.host.${tools.getHostName()}.tools`,\n native: {\n uuid,\n },\n });\n logger.info(`object system.meta.uuid created: ${uuid}`);\n } catch (e) {\n logger.error(`Cannot create system.meta.uuid: ${e.message}`);\n }\n }\n }\n\n // patch iobroker.json file\n if (data?.iobroker) {\n const settings = fs.readJSONSync(tools.getConfigFileName());\n logger.info('Update iobroker.json file');\n this.deepMerge(settings, data.iobroker);\n fs.writeFileSync(tools.getConfigFileName(), JSON.stringify(settings, null, 2));\n }\n\n if (data?.vendor) {\n const vendor = deepClone(data.vendor);\n\n // store vendor\n try {\n const configObj = await this.objects.getObject('system.config');\n if (configObj?.native) {\n let javascriptPasswordEncrypted: string | undefined;\n if (javascriptPassword) {\n if (!configObj.native?.secret) {\n const buf = randomBytes(24);\n configObj.native.secret = buf.toString('hex');\n }\n javascriptPasswordEncrypted = tools.encrypt(configObj.native.secret, javascriptPassword);\n }\n\n if (\n !isDeepStrictEqual(configObj.native.vendor, vendor) ||\n configObj.native.javascriptPassword !== javascriptPasswordEncrypted\n ) {\n configObj.native.vendor = vendor;\n configObj.nonEdit ||= {};\n if (javascriptPassword) {\n configObj.native.javascriptPassword = javascriptPasswordEncrypted;\n configObj.nonEdit.native ||= {};\n configObj.nonEdit.native.javascriptPassword = javascriptPasswordEncrypted;\n }\n configObj.nonEdit.password = password;\n await this.objects.setObjectAsync(configObj._id, configObj);\n logger.info('object system.config updated');\n }\n }\n } catch (e) {\n logger.error(`Cannot update system.config: ${e.message}`);\n }\n } else if (javascriptPassword) {\n const configObj = await this.objects.getObject('system.config');\n\n if (configObj?.native) {\n if (!configObj.native?.secret) {\n const buf = randomBytes(24);\n configObj.native.secret = buf.toString('hex');\n }\n const javascriptPasswordEncrypted = tools.encrypt(configObj.native.secret, javascriptPassword);\n if (configObj.native.javascriptPassword !== javascriptPasswordEncrypted) {\n configObj.native.javascriptPassword = javascriptPasswordEncrypted;\n configObj.nonEdit ||= {};\n configObj.nonEdit.password = password;\n configObj.nonEdit.native ||= {};\n configObj.nonEdit.native.javascriptPassword = javascriptPasswordEncrypted;\n try {\n await this.objects.setObjectAsync(configObj._id, configObj);\n logger.info('object system.config updated');\n } catch (e) {\n logger.error(`Cannot update system.config: ${e.message}`);\n }\n }\n }\n }\n\n // update all existing objects according to vendor\n if (data?.objects) {\n for (let id of Object.keys(data.objects)) {\n if (!id.includes('*')) {\n const _newObj = data.objects[id];\n const obj = await this.objects.getObject(id);\n if (obj) {\n obj.nonEdit ||= {} as ioBroker.NonEditable;\n const originalObj = deepClone(obj);\n _newObj.nonEdit ||= {} as ioBroker.NonEditable;\n _newObj.nonEdit.passHash = obj.nonEdit.passHash;\n // merge objects\n tools.copyAttributes(_newObj, obj);\n\n if (!isDeepStrictEqual(originalObj, obj)) {\n delete obj.nonEdit.passHash;\n obj.nonEdit.password = password;\n logger.info(`Update \"${obj._id}\"`);\n try {\n await this.objects.setObjectAsync(obj._id, obj);\n logger.info(`object \"${obj._id}\" updated`);\n } catch (e) {\n logger.error(`Cannot update \"${obj._id}\": ${e.message}`);\n }\n }\n } else {\n try {\n await this.objects.setObjectAsync(id, _newObj);\n logger.info(`object \"${_newObj._id}\" updated`);\n } catch (e) {\n logger.error(`Cannot update ${id} \"${JSON.stringify(_newObj)}\": ${e.message}`);\n }\n }\n } else {\n id = id.replace(/\\*/g, '');\n const _obj = data.objects[id];\n const arr = await this.objects.getObjectListAsync(\n {\n startkey: id,\n endkey: `${id}\\u9999`,\n },\n { checked: true },\n );\n\n if (arr?.rows?.length) {\n for (const row of arr.rows) {\n const obj = row.value;\n if (obj) {\n obj.nonEdit ||= {};\n const originalObj = deepClone(obj);\n _obj.nonEdit ||= {};\n _obj.nonEdit.passHash = obj.nonEdit.passHash;\n // merge objects\n tools.copyAttributes(_obj, obj);\n\n if (!isDeepStrictEqual(originalObj, obj)) {\n delete obj.nonEdit.passHash;\n obj.nonEdit.password = password;\n logger.info(`Update \"${obj._id}\"`);\n try {\n await this.objects.setObjectAsync(obj._id, obj);\n logger.info(`object \"${obj._id}\" updated`);\n } catch (e) {\n logger.error(`Cannot update \"${obj._id}\": ${e.message}`);\n }\n }\n }\n }\n }\n }\n }\n }\n\n // update host as last\n if (data?.model) {\n const model = data.model;\n const hostname = tools.getHostName();\n const obj = await this.objects.getObject(`system.host.${hostname}`);\n if (obj?.common) {\n if (\n (model.name && model.name !== 'JS controller' && obj.common.title === 'JS controller') ||\n (model.icon && !obj.common.icon) ||\n (model.color && !obj.common.color)\n ) {\n if (model.name) {\n obj.common.title = model.name;\n }\n if (model.icon) {\n obj.common.icon = model.icon;\n }\n if (model.color) {\n obj.common.color = model.color;\n }\n\n obj.nonEdit ||= {};\n obj.nonEdit.password = password;\n\n if (obj.common.title) {\n logger.info(`Update \"system.host.${hostname}:common.title\" = \"${obj.common.title}\"`);\n }\n if (obj.common.icon) {\n logger.info(`Update \"system.host.${hostname}:common.icon\" = \"${!!obj.common.icon}\"`);\n }\n if (obj.common.color) {\n logger.info(`Update \"system.host.${hostname}:common.color\" = \"${obj.common.color}\"`);\n }\n\n try {\n await this.objects.setObjectAsync(obj._id, obj);\n logger.info(`object \"system.host.${hostname}\" updated`);\n } catch (e) {\n logger.error(`Cannot update \"system.host.${hostname}\": ${e.message}`);\n }\n }\n }\n }\n\n // restart ioBroker\n return true;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["fs", "deepClone"]
7
7
  }
@@ -2150,6 +2150,7 @@ ${import_js_controller_common.tools.appName} upload /file/picture.png /vis-2.0/m
2150
2150
  case "vendor": {
2151
2151
  const password = args[0];
2152
2152
  const file = args[1];
2153
+ const javascriptPassword = args[2];
2153
2154
  if (!password) {
2154
2155
  console.warn(`Please specify the password to update the vendor information!
2155
2156
  ${import_js_controller_common.tools.appName.toLowerCase()} vendor <PASS_PHRASE> <vendor.json>`);
@@ -2159,7 +2160,7 @@ ${import_js_controller_common.tools.appName.toLowerCase()} vendor <PASS_PHRASE>
2159
2160
  const { Vendor } = await import("./setup/setupVendor.js");
2160
2161
  const vendor = new Vendor({ objects });
2161
2162
  try {
2162
- await vendor.checkVendor(file, password);
2163
+ await vendor.checkVendor(file, password, javascriptPassword);
2163
2164
  console.log(`Synchronised vendor information.`);
2164
2165
  return void callback();
2165
2166
  } catch (err) {
@@ -2297,7 +2298,9 @@ async function unsetup(params, callback) {
2297
2298
  obj.common.language = "en";
2298
2299
  if (!params.keepsecret) {
2299
2300
  obj.common.licenseConfirmed = false;
2300
- obj.native && delete obj.native.secret;
2301
+ if (obj.native) {
2302
+ delete obj.native.secret;
2303
+ }
2301
2304
  }
2302
2305
  obj.from = `system.host.${import_js_controller_common.tools.getHostName()}.cli`;
2303
2306
  obj.ts = (/* @__PURE__ */ new Date()).getTime();