@iobroker/socket-classes 1.4.6 → 1.5.2

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020-2023 bluefox <dogafox@gmail.com>
3
+ Copyright (c) 2020-2024 bluefox <dogafox@gmail.com>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -264,7 +264,7 @@ Unsubscribe from object changes by pattern.
264
264
  Make a query to the object database.
265
265
  * design *(string)*: 'system' or other designs like `custom`, but it must exist object `_design/custom`. Too 99,9% use `system`.
266
266
  * search *(string)*: object type, like `state`, `instance`, `adapter`, `host`, ...
267
- * params *(string)*: parameters for the query in form `{startkey: 'system.adapter.', endkey: 'system.adapter.\u9999'}`
267
+ * params *(string)*: parameters for the query in form `{startkey: 'system.adapter.', endkey?: 'system.adapter.\u9999', depth?: number}`
268
268
  * callback *(function)*: `function (error)`
269
269
 
270
270
  ### <a name="setobject_w"></a>setObject(id, obj, callback)
@@ -740,8 +740,9 @@ Get one object
740
740
  * id *(string)*: object ID.
741
741
  * callback *(function)*: `function (error, obj)`
742
742
 
743
- ### <a name="getobjects_a"></a>getObjects(callback)
743
+ ### <a name="getobjects_a"></a>getObjects(list, callback)
744
744
  Read absolutely all objects. Same as `getAllObjects`.
745
+ * list *(string[])*: optional list of IDs.
745
746
  * callback *(function)*: `function (error, objects)`, where `objects` is an object like `{'system.adapter.admin.0': {...}, 'system.adapter.web.0': {...}}`
746
747
 
747
748
  ### <a name="subscribeobjects_a"></a>subscribeObjects(pattern, callback)
@@ -758,7 +759,7 @@ Unsubscribe from object changes by pattern.
758
759
  Make a query to the object database.
759
760
  * design *(string)*: 'system' or other designs like `custom`, but it must exist object `_design/custom`. Too 99,9% use `system`.
760
761
  * search *(string)*: object type, like `state`, `instance`, `adapter`, `host`, ...
761
- * params *(string)*: parameters for the query in form `{startkey: 'system.adapter.', endkey: 'system.adapter.\u9999'}`
762
+ * params *(string)*: parameters for the query in form `{startkey: 'system.adapter.', endkey?: 'system.adapter.\u9999', depth?: number}`
762
763
  * callback *(function)*: `function (error)`
763
764
 
764
765
  ### <a name="setobject_a"></a>setObject(id, obj, callback)
@@ -978,6 +979,12 @@ Read all instances of the given adapter, or all instances of all adapters if ada
978
979
  -->
979
980
 
980
981
  ## Changelog
982
+ ### 1.5.2 (2024-05-28)
983
+ * (foxriver76) ensure compatible `adapter-core` version
984
+
985
+ ### 1.5.0 (2024-02-22)
986
+ * (bluefox) Extended getObjects function with the possibility to read the list of IDs in admin
987
+
981
988
  ### 1.4.6 (2023-10-19)
982
989
  * (bluefox) Added `publishInstanceMessageAll` command
983
990
 
@@ -1116,7 +1123,7 @@ Read all instances of the given adapter, or all instances of all adapters if ada
1116
1123
  ## License
1117
1124
  The MIT License (MIT)
1118
1125
 
1119
- Copyright (c) 2020-2023 Bluefox <dogafox@gmail.com>
1126
+ Copyright (c) 2020-2024 Bluefox <dogafox@gmail.com>
1120
1127
 
1121
1128
  Permission is hereby granted, free of charge, to any person obtaining a copy
1122
1129
  of this software and associated documentation files (the "Software"), to deal
@@ -34,20 +34,22 @@ function getQuery(url) {
34
34
 
35
35
  function authorize(options) {
36
36
  const defaults = {
37
- key: 'connect.sid',
38
- secret: null,
39
- store: null,
37
+ key: 'connect.sid',
38
+ secret: null,
39
+ store: null,
40
40
  userProperty: 'user'
41
41
  };
42
42
 
43
43
  const auth = Object.assign({}, defaults, options);
44
44
 
45
45
  if (!auth.passport) {
46
- throw new Error('passport is required to use require(\'passport\'), please install passport');
46
+ throw new Error("passport is required to use require('passport'), please install passport");
47
47
  }
48
48
 
49
49
  if (!auth.cookieParser) {
50
- throw new Error('cookieParser is required use require(\'cookie-parser\'), connect.cookieParser or express.cookieParser');
50
+ throw new Error(
51
+ "cookieParser is required use require('cookie-parser'), connect.cookieParser or express.cookieParser"
52
+ );
51
53
  }
52
54
 
53
55
  return function (data, accept) {
@@ -76,18 +78,21 @@ function authorize(options) {
76
78
  auth.store.get(data.sessionID, (err, session) => {
77
79
  if (err) {
78
80
  return auth.fail(data, 'Error in session store:\n' + err.message, true, accept);
79
- } else
80
- if (!session) {
81
+ } else if (!session) {
81
82
  return auth.fail(data, 'No session found', false, accept);
82
- } else
83
- if (!session[auth.passport._key]) {
83
+ } else if (!session[auth.passport._key]) {
84
84
  return auth.fail(data, 'Passport was not initialized', true, accept);
85
85
  }
86
86
 
87
87
  const userKey = session[auth.passport._key].user;
88
88
 
89
89
  if (typeof userKey === 'undefined') {
90
- return auth.fail(data, 'User not authorized through passport. (User Property not found)', false, accept);
90
+ return auth.fail(
91
+ data,
92
+ 'User not authorized through passport. (User Property not found)',
93
+ false,
94
+ accept
95
+ );
91
96
  }
92
97
 
93
98
  data[auth.userProperty] = userKey;
@@ -27,21 +27,22 @@ class SocketAdmin extends SocketCommon {
27
27
  _onAuthorizeSuccess = (data, accept) => {
28
28
  this.adapter.log.debug(`successful connection to socket.io from ${data.connection.remoteAddress}`);
29
29
  accept();
30
- }
30
+ };
31
31
 
32
32
  _onAuthorizeFail = (data, message, error, accept) => {
33
33
  setTimeout(() => data.socket.emit(SocketCommon.COMMAND_RE_AUTHENTICATE), 100);
34
34
 
35
- error && this.adapter.log.info(`failed connection to socket.io from ${data.connection.remoteAddress}: ${message}`);
35
+ error &&
36
+ this.adapter.log.info(`failed connection to socket.io from ${data.connection.remoteAddress}: ${message}`);
36
37
 
37
38
  if (error) {
38
39
  accept(new Error(message));
39
40
  } else {
40
- accept(new Error(`failed connection to socket.io: ${message}`));//null, false);
41
+ accept(new Error(`failed connection to socket.io: ${message}`)); //null, false);
41
42
  }
42
43
  // this error will be sent to the user as a special error-package
43
44
  // see: http://socket.io/docs/client-api/#socket > error-object
44
- }
45
+ };
45
46
 
46
47
  __initAuthentication(authOptions) {
47
48
  passportSocketIo = passportSocketIo || require('./passportSocket');
@@ -50,15 +51,17 @@ class SocketAdmin extends SocketCommon {
50
51
 
51
52
  this.store = authOptions.store;
52
53
 
53
- this.server.use(passportSocketIo.authorize({
54
- passport,
55
- cookieParser,
56
- key: authOptions.userKey, // the name of the cookie where express/connect stores its session_id
57
- secret: authOptions.secret, // the session_secret to parse the cookie
58
- store: authOptions.store, // we NEED to use a sessionstore. no memorystore please
59
- success: this._onAuthorizeSuccess, // *optional* callback on success - read more below
60
- fail: this._onAuthorizeFail // *optional* callback on fail/error - read more below
61
- }));
54
+ this.server.use(
55
+ passportSocketIo.authorize({
56
+ passport,
57
+ cookieParser,
58
+ key: authOptions.userKey, // the name of the cookie where express/connect stores its session_id
59
+ secret: authOptions.secret, // the session_secret to parse the cookie
60
+ store: authOptions.store, // we NEED to use a sessionstore. no memorystore please
61
+ success: this._onAuthorizeSuccess, // *optional* callback on success - read more below
62
+ fail: this._onAuthorizeFail // *optional* callback on fail/error - read more below
63
+ })
64
+ );
62
65
  }
63
66
 
64
67
  // Extract username from socket
@@ -107,17 +110,19 @@ class SocketAdmin extends SocketCommon {
107
110
  return false;
108
111
  }
109
112
  socket._lastActivity = time;
110
- socket._sessionTimer = socket._sessionTimer || setTimeout(() => {
111
- socket._sessionTimer = null;
112
- this.adapter.getSession(socket._sessionID, obj => {
113
- if (obj) {
114
- this.adapter.setSession(socket._sessionID, this.settings.ttl, obj);
115
- } else {
116
- this.adapter.log.warn('REAUTHENTICATE!');
117
- socket.emit(SocketCommon.COMMAND_RE_AUTHENTICATE);
118
- }
119
- });
120
- }, 60_000);
113
+ socket._sessionTimer =
114
+ socket._sessionTimer ||
115
+ setTimeout(() => {
116
+ socket._sessionTimer = null;
117
+ this.adapter.getSession(socket._sessionID, obj => {
118
+ if (obj) {
119
+ this.adapter.setSession(socket._sessionID, this.settings.ttl, obj);
120
+ } else {
121
+ this.adapter.log.warn('REAUTHENTICATE!');
122
+ socket.emit(SocketCommon.COMMAND_RE_AUTHENTICATE);
123
+ }
124
+ });
125
+ }, 60_000);
121
126
  }
122
127
 
123
128
  return true;
@@ -142,24 +147,21 @@ class SocketAdmin extends SocketCommon {
142
147
 
143
148
  const sockets = this.getSocketsList();
144
149
  if (sockets) {
145
- sockets.forEach(socket =>
146
- this.commands.publish(socket, 'stateChange', id, state));
150
+ sockets.forEach(socket => this.commands.publish(socket, 'stateChange', id, state));
147
151
  }
148
152
  }
149
153
 
150
154
  fileChange(id, fileName, size) {
151
155
  const sockets = this.getSocketsList();
152
156
  if (sockets) {
153
- sockets.forEach(socket =>
154
- this.commands.publishFile(socket, id, fileName, size));
157
+ sockets.forEach(socket => this.commands.publishFile(socket, id, fileName, size));
155
158
  }
156
159
  }
157
160
 
158
161
  repoUpdated() {
159
162
  const sockets = this.getSocketsList();
160
163
  if (sockets) {
161
- sockets.forEach(socket =>
162
- this.__updateSession(socket));
164
+ sockets.forEach(socket => this.__updateSession(socket));
163
165
 
164
166
  this.server.sockets.emit('repoUpdated');
165
167
  }
@@ -168,8 +170,7 @@ class SocketAdmin extends SocketCommon {
168
170
  objectChange(id, obj) {
169
171
  const sockets = this.getSocketsList();
170
172
  if (sockets) {
171
- sockets.forEach(socket =>
172
- this.commands.publish(socket, 'objectChange', id, obj));
173
+ sockets.forEach(socket => this.commands.publish(socket, 'objectChange', id, obj));
173
174
  }
174
175
  }
175
176
 
@@ -185,8 +186,7 @@ class SocketAdmin extends SocketCommon {
185
186
  if (this.commands.sendCommand(obj)) {
186
187
  const sockets = this.getSocketsList();
187
188
  if (sockets) {
188
- sockets.forEach(socket =>
189
- this.__updateSession(socket));
189
+ sockets.forEach(socket => this.__updateSession(socket));
190
190
 
191
191
  this.server.sockets.emit(obj.command, obj.message.id, obj.message.data);
192
192
  }
@@ -201,9 +201,9 @@ class SocketCommands {
201
201
  }
202
202
  }
203
203
  return false;
204
- } else {
205
- return true;
206
204
  }
205
+
206
+ return true;
207
207
  }
208
208
 
209
209
  publish(socket, type, id, obj) {
@@ -317,10 +317,12 @@ class SocketCommands {
317
317
  if (this.subscribes[type][key] === undefined) {
318
318
  this.subscribes[type][key] = 1;
319
319
  if (type === 'stateChange') {
320
- this.adapter.subscribeForeignStatesAsync(pattern, options)
320
+ this.adapter
321
+ .subscribeForeignStatesAsync(pattern, options)
321
322
  .catch(e => this.adapter.log.error(`Cannot subscribe "${pattern}": ${e.message}`));
322
323
  } else if (type === 'objectChange') {
323
- this.adapter.subscribeForeignObjectsAsync(pattern, options)
324
+ this.adapter
325
+ .subscribeForeignObjectsAsync(pattern, options)
324
326
  .catch(e => this.adapter.log.error(`Cannot subscribe "${pattern}": ${e.message}`));
325
327
  } else if (type === 'log') {
326
328
  if (!this.logEnabled && this.adapter.requireLog) {
@@ -328,7 +330,8 @@ class SocketCommands {
328
330
  this.adapter.requireLog(true, options);
329
331
  }
330
332
  } else if (type === 'fileChange' && this.adapter.subscribeForeignFiles) {
331
- this.adapter.subscribeForeignFiles(pattern, patternFile, options)
333
+ this.adapter
334
+ .subscribeForeignFiles(pattern, patternFile, options)
332
335
  .catch(e => this.adapter.log.error(`Cannot subscribe "${pattern}": ${e.message}`));
333
336
  }
334
337
  } else {
@@ -336,7 +339,7 @@ class SocketCommands {
336
339
  }
337
340
  }
338
341
 
339
- async unsubscribe(socket, type, pattern, patternFile) {
342
+ unsubscribe(socket, type, pattern, patternFile) {
340
343
  if (!pattern) {
341
344
  return this.adapter.log.warn('Empty pattern on subscribe!');
342
345
  }
@@ -368,19 +371,28 @@ class SocketCommands {
368
371
  this.subscribes[type][key]--;
369
372
  if (this.subscribes[type][key] <= 0) {
370
373
  if (type === 'stateChange') {
371
- this.adapter.unsubscribeForeignStatesAsync(pattern, options)
372
- .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
374
+ this.adapter
375
+ .unsubscribeForeignStatesAsync(pattern, options)
376
+ .catch(e =>
377
+ this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`)
378
+ );
373
379
  } else if (type === 'objectChange') {
374
- this.adapter.unsubscribeForeignObjectsAsync(pattern, options)
375
- .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
380
+ this.adapter
381
+ .unsubscribeForeignObjectsAsync(pattern, options)
382
+ .catch(e =>
383
+ this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`)
384
+ );
376
385
  } else if (type === 'log') {
377
386
  if (this.logEnabled && this.adapter.requireLog) {
378
387
  this.logEnabled = false;
379
388
  this.adapter.requireLog(false, options);
380
389
  }
381
390
  } else if (type === 'fileChange' && this.adapter.unsubscribeForeignFiles) {
382
- this.adapter.unsubscribeForeignFiles(pattern, patternFile, options)
383
- .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
391
+ this.adapter
392
+ .unsubscribeForeignFiles(pattern, patternFile, options)
393
+ .catch(e =>
394
+ this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`)
395
+ );
384
396
  }
385
397
  delete this.subscribes[type][pattern];
386
398
  }
@@ -397,10 +409,12 @@ class SocketCommands {
397
409
  this.subscribes[type][key]--;
398
410
  if (this.subscribes[type][key] <= 0) {
399
411
  if (type === 'stateChange') {
400
- this.adapter.unsubscribeForeignStatesAsync(pattern, options)
412
+ this.adapter
413
+ .unsubscribeForeignStatesAsync(pattern, options)
401
414
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
402
415
  } else if (type === 'objectChange') {
403
- this.adapter.unsubscribeForeignObjectsAsync(pattern, options)
416
+ this.adapter
417
+ .unsubscribeForeignObjectsAsync(pattern, options)
404
418
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
405
419
  } else if (type === 'log') {
406
420
  if (this.adapter.requireLog && this.logEnabled) {
@@ -408,7 +422,8 @@ class SocketCommands {
408
422
  this.adapter.requireLog(false, options);
409
423
  }
410
424
  } else if (type === 'fileChange' && this.adapter.unsubscribeForeignFiles) {
411
- this.adapter.unsubscribeForeignFiles(pattern, patternFile, options)
425
+ this.adapter
426
+ .unsubscribeForeignFiles(pattern, patternFile, options)
412
427
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
413
428
  }
414
429
  delete this.subscribes[type][key];
@@ -417,10 +432,12 @@ class SocketCommands {
417
432
  } else {
418
433
  for (const pattern of Object.keys(this.subscribes[type])) {
419
434
  if (type === 'stateChange') {
420
- this.adapter.unsubscribeForeignStatesAsync(pattern, options)
435
+ this.adapter
436
+ .unsubscribeForeignStatesAsync(pattern, options)
421
437
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
422
438
  } else if (type === 'objectChange') {
423
- this.adapter.unsubscribeForeignObjectsAsync(pattern, options)
439
+ this.adapter
440
+ .unsubscribeForeignObjectsAsync(pattern, options)
424
441
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
425
442
  } else if (type === 'log') {
426
443
  // console.log((socket._name || socket.id) + ' requireLog false');
@@ -430,7 +447,8 @@ class SocketCommands {
430
447
  }
431
448
  } else if (type === 'fileChange' && this.adapter.unsubscribeForeignFiles) {
432
449
  const [id, fileName] = pattern.split('####');
433
- this.adapter.unsubscribeForeignFiles(id, fileName, options)
450
+ this.adapter
451
+ .unsubscribeForeignFiles(id, fileName, options)
434
452
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
435
453
  }
436
454
  }
@@ -439,7 +457,7 @@ class SocketCommands {
439
457
  }
440
458
  }
441
459
 
442
- async subscribeSocket(socket, type) {
460
+ subscribeSocket(socket, type) {
443
461
  if (!socket || !socket.subscribe) {
444
462
  return;
445
463
  }
@@ -460,10 +478,12 @@ class SocketCommands {
460
478
  if (this.subscribes[type][pattern] === undefined) {
461
479
  this.subscribes[type][pattern] = 1;
462
480
  if (type === 'stateChange') {
463
- this.adapter.subscribeForeignStatesAsync(pattern, options)
481
+ this.adapter
482
+ .subscribeForeignStatesAsync(pattern, options)
464
483
  .catch(e => this.adapter.log.error(`Cannot subscribe "${pattern}": ${e.message}`));
465
484
  } else if (type === 'objectChange') {
466
- this.adapter.subscribeForeignObjectsAsync(pattern, options)
485
+ this.adapter
486
+ .subscribeForeignObjectsAsync(pattern, options)
467
487
  .catch(e => this.adapter.log.error(`Cannot subscribe "${pattern}": ${e.message}`));
468
488
  } else if (type === 'log') {
469
489
  if (this.adapter.requireLog && !this.logEnabled) {
@@ -472,7 +492,8 @@ class SocketCommands {
472
492
  }
473
493
  } else if (type === 'fileChange' && this.adapter.subscribeForeignFiles) {
474
494
  const [id, fileName] = pattern.split('####');
475
- this.adapter.subscribeForeignFiles(id, fileName, options)
495
+ this.adapter
496
+ .subscribeForeignFiles(id, fileName, options)
476
497
  .catch(e => this.adapter.log.error(`Cannot subscribe "${pattern}": ${e.message}`));
477
498
  }
478
499
  } else {
@@ -481,7 +502,7 @@ class SocketCommands {
481
502
  }
482
503
  }
483
504
 
484
- async unsubscribeSocket(socket, type) {
505
+ unsubscribeSocket(socket, type) {
485
506
  if (!socket || !socket.subscribe) {
486
507
  return;
487
508
  }
@@ -505,10 +526,12 @@ class SocketCommands {
505
526
  this.subscribes[type][pattern]--;
506
527
  if (this.subscribes[type][pattern] <= 0) {
507
528
  if (type === 'stateChange') {
508
- this.adapter.unsubscribeForeignStatesAsync(pattern, options)
529
+ this.adapter
530
+ .unsubscribeForeignStatesAsync(pattern, options)
509
531
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
510
532
  } else if (type === 'objectChange') {
511
- this.adapter.unsubscribeForeignObjectsAsync(pattern, options)
533
+ this.adapter
534
+ .unsubscribeForeignObjectsAsync(pattern, options)
512
535
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
513
536
  } else if (type === 'log') {
514
537
  if (this.adapter.requireLog && !this.logEnabled) {
@@ -517,7 +540,8 @@ class SocketCommands {
517
540
  }
518
541
  } else if (type === 'fileChange' && this.adapter.unsubscribeForeignFiles) {
519
542
  const [id, fileName] = pattern.split('####');
520
- this.adapter.unsubscribeForeignFiles(id, fileName, options)
543
+ this.adapter
544
+ .unsubscribeForeignFiles(id, fileName, options)
521
545
  .catch(e => this.adapter.log.error(`Cannot unsubscribe "${pattern}": ${e.message}`));
522
546
  }
523
547
  delete this.subscribes[type][pattern];
@@ -593,7 +617,7 @@ class SocketCommands {
593
617
  addCommandHandler(command, handler) {
594
618
  if (handler) {
595
619
  this.commands[command] = handler;
596
- } else if (this.commands.hasOwnProperty(command)) {
620
+ } else if (command in this.commands) {
597
621
  delete this.commands[command];
598
622
  }
599
623
  }
@@ -695,6 +719,8 @@ class SocketCommands {
695
719
  // @param {function} callback - `function (error, isSupported)`
696
720
  if (feature === 'INSTANCE_MESSAGES') {
697
721
  SocketCommands._fixCallback(callback, null, true);
722
+ } else if (feature === 'PARTIAL_OBJECT_TREE') {
723
+ SocketCommands._fixCallback(callback, null, true);
698
724
  } else {
699
725
  SocketCommands._fixCallback(
700
726
  callback,
@@ -958,7 +984,7 @@ class SocketCommands {
958
984
  }
959
985
  }
960
986
 
961
- //Convert buffer to base 64
987
+ // Convert buffer to base 64
962
988
  if (typeof callback === 'function') {
963
989
  callback(error, data64 || '', type);
964
990
  } else {
@@ -1648,12 +1674,73 @@ class SocketCommands {
1648
1674
  // Make a query to the object database.
1649
1675
  // @param {string} design - 'system' or other designs like `custom`, but it must exist object `_design/custom`. Too 99,9% use `system`.
1650
1676
  // @param {string} search - object type, like `state`, `instance`, `adapter`, `host`, ...
1651
- // @param {string} params - parameters for the query in form `{startkey: 'system.adapter.', endkey: 'system.adapter.\u9999'}`
1677
+ // @param {string} params - parameters for the query in form `{startkey: 'system.adapter.', endkey?: 'system.adapter.\u9999', depth?: number}`
1652
1678
  // @param {function} callback - `function (error)`
1653
1679
  if (typeof callback === 'function') {
1654
1680
  if (this._checkPermissions(socket, 'getObjectView', callback, search)) {
1655
1681
  try {
1656
- this.adapter.getObjectView(design, search, params, { user: socket._acl.user }, callback);
1682
+ if (params.root || params.depth) {
1683
+ // To save the bandwidth, the request can define root and depth. Default is depth 1.
1684
+ this.adapter.getObjectView(
1685
+ design,
1686
+ search,
1687
+ params,
1688
+ { user: socket._acl.user },
1689
+ (err, result) => {
1690
+ if (result?.rows?.length && result.rows[0].value?._id) {
1691
+ const rows = [];
1692
+ // filter rows
1693
+ const depth = params.depth || 1;
1694
+ let root = params.startkey;
1695
+ let rootWithoutDot;
1696
+ if (!root.endsWith('.')) {
1697
+ root += '.';
1698
+ rootWithoutDot = root;
1699
+ } else {
1700
+ rootWithoutDot = root.substring(0, root.length - 1);
1701
+ }
1702
+
1703
+ const rootDepth = root.split('.').length;
1704
+ const virtualObjects = {};
1705
+ for (let r = 0; r < result.rows.length; r++) {
1706
+ if (
1707
+ result.rows[r].value._id.startsWith(root) ||
1708
+ result.rows[r].value._id === rootWithoutDot
1709
+ ) {
1710
+ const parts = result.rows[r].id.split('.');
1711
+ if (parts.length - rootDepth <= depth) {
1712
+ rows.push(result.rows[r]);
1713
+ } else {
1714
+ // create virtual objects to show that there are more objects
1715
+ for (let d = depth; d < parts.length - rootDepth; d++) {
1716
+ const id = parts.slice(0, rootDepth + d).join('.');
1717
+ if (!virtualObjects[id]) {
1718
+ virtualObjects[id] = {
1719
+ id,
1720
+ value: {
1721
+ _id: id,
1722
+ common: {},
1723
+ type: 'folder',
1724
+ virtual: true,
1725
+ hasChildren: 1
1726
+ }
1727
+ };
1728
+ rows.push(virtualObjects[id]);
1729
+ } else {
1730
+ virtualObjects[id].value.hasChildren++;
1731
+ }
1732
+ }
1733
+ }
1734
+ }
1735
+ }
1736
+ result.rows = rows;
1737
+ }
1738
+ callback(err, result);
1739
+ }
1740
+ );
1741
+ } else {
1742
+ this.adapter.getObjectView(design, search, params, { user: socket._acl.user }, callback);
1743
+ }
1657
1744
  } catch (error) {
1658
1745
  this.adapter.log.error(`[getObjectView] ERROR: ${error.toString()}`);
1659
1746
  SocketCommands._fixCallback(callback, error);
@@ -1,7 +1,7 @@
1
1
  const SocketCommands = require('./socketCommands');
2
2
  const axios = require('axios');
3
- const path = require('path');
4
- const fs = require('fs');
3
+ const path = require('node:path');
4
+ const fs = require('node:fs');
5
5
 
6
6
  class SocketCommandsAdmin extends SocketCommands {
7
7
  static ALLOW_CACHE = [
@@ -318,7 +318,7 @@ class SocketCommandsAdmin extends SocketCommands {
318
318
  }
319
319
  }
320
320
 
321
- disableEventThreshold(readAll) {
321
+ disableEventThreshold() {
322
322
  if (this.eventsThreshold.active) {
323
323
  this.eventsThreshold.accidents = 0;
324
324
  this.eventsThreshold.count = 0;
@@ -581,7 +581,7 @@ class SocketCommandsAdmin extends SocketCommands {
581
581
  const result = {};
582
582
  for (const id in this.objects) {
583
583
  if (
584
- this.objects.hasOwnProperty(id) &&
584
+ Object.prototype.hasOwnProperty.call(this.objects, id) &&
585
585
  SocketCommandsAdmin._checkObject(this.objects[id], socket._acl, 4 /* 'read' */)
586
586
  ) {
587
587
  result[id] = this.objects[id];
@@ -707,9 +707,8 @@ class SocketCommandsAdmin extends SocketCommands {
707
707
  // if we requested specific name
708
708
  if (obj.common.hostname === ip) {
709
709
  return callback(ip, obj);
710
- }
711
- // try to find this IP in the list
712
- else if (obj.native.hardware && obj.native.hardware.networkInterfaces) {
710
+ } else if (obj.native.hardware && obj.native.hardware.networkInterfaces) {
711
+ // try to find this IP in the list
713
712
  const net = obj.native.hardware.networkInterfaces;
714
713
  for (const eth in net) {
715
714
  if (!Object.prototype.hasOwnProperty.call(net, eth)) {
@@ -796,7 +795,7 @@ class SocketCommandsAdmin extends SocketCommands {
796
795
  });
797
796
  }
798
797
  }
799
- } catch (_error) {
798
+ } catch {
800
799
  // push unchecked
801
800
  // result.list.push('log/' + transport + '/' + files[f]);
802
801
  this.adapter.log.error(
@@ -1333,10 +1332,32 @@ class SocketCommandsAdmin extends SocketCommands {
1333
1332
  };
1334
1333
 
1335
1334
  // Identical to getAllObjects
1336
- this.commands['getObjects'] = (socket, callback) => {
1335
+ this.commands['getObjects'] = (socket, list, callback) => {
1337
1336
  // Read absolutely all objects. Same as `getAllObjects`.
1337
+ // @param {string[]} list - optional list of IDs.
1338
1338
  // @param {function} callback - `function (error, objects)`, where `objects` is an object like `{'system.adapter.admin.0': {...}, 'system.adapter.web.0': {...}}`
1339
- return this._getAllObjects(socket, callback);
1339
+ if (typeof list === 'function') {
1340
+ callback = list;
1341
+ list = null;
1342
+ }
1343
+ if (list && list.length) {
1344
+ if (this._checkPermissions(socket, 'getObject', callback)) {
1345
+ if (typeof callback === 'function') {
1346
+ try {
1347
+ this.adapter.getForeignObjects(list, { user: socket._acl.user }, (error, objs) =>
1348
+ SocketCommands._fixCallback(callback, error, objs)
1349
+ );
1350
+ } catch (error) {
1351
+ this.adapter.log.error(`[getObjects] ERROR: ${error.toString()}`);
1352
+ SocketCommands._fixCallback(callback, error);
1353
+ }
1354
+ } else {
1355
+ this.adapter.log.warn('[getObjects] Invalid callback');
1356
+ }
1357
+ }
1358
+ } else {
1359
+ return this._getAllObjects(socket, callback);
1360
+ }
1340
1361
  };
1341
1362
 
1342
1363
  this.commands['extendObject'] = (socket, id, obj, callback) => {
@@ -25,25 +25,25 @@ class SocketCommon {
25
25
  throw new Error('"__getIsNoDisconnect" must be implemented in SocketCommon!');
26
26
  }
27
27
 
28
- __initAuthentication(authOptions) {
28
+ __initAuthentication(_authOptions) {
29
29
  throw new Error('"__initAuthentication" must be implemented in SocketCommon!');
30
30
  }
31
31
 
32
32
  // Extract username from socket
33
- __getUserFromSocket(socket, callback) {
33
+ __getUserFromSocket(_socket, _callback) {
34
34
  throw new Error('"__getUserFromSocket" must be implemented in SocketCommon!');
35
35
  }
36
36
 
37
- __getClientAddress(socket) {
37
+ __getClientAddress(_socket) {
38
38
  throw new Error('"__getClientAddress" must be implemented in SocketCommon!');
39
39
  }
40
40
 
41
41
  // update session ID, but not ofter than 60 seconds
42
- __updateSession(socket) {
42
+ __updateSession(_socket) {
43
43
  throw new Error('"__updateSession" must be implemented in SocketCommon!');
44
44
  }
45
45
 
46
- __getSessionID(socket) {
46
+ __getSessionID(_socket) {
47
47
  throw new Error('"__getSessionID" must be implemented in SocketCommon!');
48
48
  }
49
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iobroker/socket-classes",
3
- "version": "1.4.6",
3
+ "version": "1.5.2",
4
4
  "description": "ioBroker server-side web sockets",
5
5
  "author": {
6
6
  "name": "bluefox",
@@ -21,19 +21,19 @@
21
21
  "url": "https://github.com/ioBroker/ioBroker.socket-classes"
22
22
  },
23
23
  "dependencies": {
24
- "@iobroker/adapter-core": "^3.0.4",
25
- "axios": "^1.5.1",
24
+ "@iobroker/adapter-core": "^3.1.4",
25
+ "axios": "^1.6.7",
26
26
  "cookie-parser": "^1.4.6",
27
- "passport": "^0.6.0"
27
+ "passport": "^0.7.0"
28
28
  },
29
29
  "devDependencies": {
30
- "@alcalzone/release-script": "^3.6.0",
31
- "@alcalzone/release-script-plugin-license": "^3.5.9",
32
- "@foxriver76/eslint-config": "^1.0.1",
33
- "chai": "^4.3.10",
30
+ "@alcalzone/release-script": "^3.7.0",
31
+ "@alcalzone/release-script-plugin-license": "^3.7.0",
32
+ "@foxriver76/eslint-config": "^1.0.2",
33
+ "chai": "^4.4.1",
34
34
  "gulp": "^4.0.2",
35
35
  "iobroker.js-controller": "dev",
36
- "mocha": "^10.2.0"
36
+ "mocha": "^10.3.0"
37
37
  },
38
38
  "bugs": {
39
39
  "url": "https://github.com/ioBroker/ioBroker.web/issues"
@@ -47,11 +47,12 @@
47
47
  "lib/socketAdmin.js"
48
48
  ],
49
49
  "scripts": {
50
+ "lint": "eslint .",
50
51
  "test": "node node_modules/mocha/bin/mocha --exit",
51
52
  "release": "release-script",
52
- "release-patch": "release-script patch --yes",
53
- "release-minor": "release-script minor --yes",
54
- "release-major": "release-script major --yes",
53
+ "release-patch": "release-script patch --no-update-lockfile --yes",
54
+ "release-minor": "release-script minor --no-update-lockfile --yes",
55
+ "release-major": "release-script major --no-update-lockfile --yes",
55
56
  "update-packages": "ncu --upgrade",
56
57
  "docs": "gulp"
57
58
  },