@iobroker/socket-classes 1.5.0 → 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/README.md +5 -2
- package/lib/passportSocket.js +15 -10
- package/lib/socketAdmin.js +34 -34
- package/lib/socketCommands.js +117 -30
- package/lib/socketCommandsAdmin.js +26 -27
- package/lib/socketCommon.js +5 -5
- package/package.json +6 -5
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
|
|
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)
|
|
@@ -759,7 +759,7 @@ Unsubscribe from object changes by pattern.
|
|
|
759
759
|
Make a query to the object database.
|
|
760
760
|
* design *(string)*: 'system' or other designs like `custom`, but it must exist object `_design/custom`. Too 99,9% use `system`.
|
|
761
761
|
* search *(string)*: object type, like `state`, `instance`, `adapter`, `host`, ...
|
|
762
|
-
* params *(string)*: parameters for the query in form `{startkey: 'system.adapter.', endkey
|
|
762
|
+
* params *(string)*: parameters for the query in form `{startkey: 'system.adapter.', endkey?: 'system.adapter.\u9999', depth?: number}`
|
|
763
763
|
* callback *(function)*: `function (error)`
|
|
764
764
|
|
|
765
765
|
### <a name="setobject_a"></a>setObject(id, obj, callback)
|
|
@@ -979,6 +979,9 @@ Read all instances of the given adapter, or all instances of all adapters if ada
|
|
|
979
979
|
-->
|
|
980
980
|
|
|
981
981
|
## Changelog
|
|
982
|
+
### 1.5.2 (2024-05-28)
|
|
983
|
+
* (foxriver76) ensure compatible `adapter-core` version
|
|
984
|
+
|
|
982
985
|
### 1.5.0 (2024-02-22)
|
|
983
986
|
* (bluefox) Extended getObjects function with the possibility to read the list of IDs in admin
|
|
984
987
|
|
package/lib/passportSocket.js
CHANGED
|
@@ -34,20 +34,22 @@ function getQuery(url) {
|
|
|
34
34
|
|
|
35
35
|
function authorize(options) {
|
|
36
36
|
const defaults = {
|
|
37
|
-
key:
|
|
38
|
-
secret:
|
|
39
|
-
store:
|
|
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(
|
|
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(
|
|
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(
|
|
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;
|
package/lib/socketAdmin.js
CHANGED
|
@@ -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 &&
|
|
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}`))
|
|
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(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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 =
|
|
111
|
-
socket._sessionTimer
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
}
|
package/lib/socketCommands.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
372
|
-
.
|
|
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
|
|
375
|
-
.
|
|
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
|
|
383
|
-
.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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 = [
|
|
@@ -203,8 +203,8 @@ class SocketCommandsAdmin extends SocketCommands {
|
|
|
203
203
|
if (error.response) {
|
|
204
204
|
throw new Error(
|
|
205
205
|
(error.response.data && error.response.data.error) ||
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
error.response.data ||
|
|
207
|
+
error.response.status
|
|
208
208
|
);
|
|
209
209
|
} else if (error.request) {
|
|
210
210
|
throw new Error('no response');
|
|
@@ -318,7 +318,7 @@ class SocketCommandsAdmin extends SocketCommands {
|
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
disableEventThreshold(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
798
|
+
} catch {
|
|
800
799
|
// push unchecked
|
|
801
800
|
// result.list.push('log/' + transport + '/' + files[f]);
|
|
802
801
|
this.adapter.log.error(
|
|
@@ -1204,16 +1203,16 @@ class SocketCommandsAdmin extends SocketCommands {
|
|
|
1204
1203
|
if (this._checkPermissions(socket, 'getObject', callback)) {
|
|
1205
1204
|
this.adapter.getForeignObject('system.repositories', { user: socket._acl.user }, (error, obj) => {
|
|
1206
1205
|
obj &&
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1206
|
+
obj.native &&
|
|
1207
|
+
obj.native.repositories &&
|
|
1208
|
+
Object.keys(obj.native.repositories).forEach(name => {
|
|
1209
|
+
if (obj.native.repositories[name].json) {
|
|
1210
|
+
// limit information to _repoInfo
|
|
1211
|
+
obj.native.repositories[name].json = {
|
|
1212
|
+
_repoInfo: obj.native.repositories[name].json._repoInfo
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
});
|
|
1217
1216
|
callback(error, obj);
|
|
1218
1217
|
});
|
|
1219
1218
|
}
|
|
@@ -1227,13 +1226,13 @@ class SocketCommandsAdmin extends SocketCommands {
|
|
|
1227
1226
|
// Extract only the version and icon
|
|
1228
1227
|
const result = {};
|
|
1229
1228
|
data &&
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1229
|
+
Object.keys(data).forEach(
|
|
1230
|
+
name =>
|
|
1231
|
+
(result[name] = {
|
|
1232
|
+
version: data[name].version,
|
|
1233
|
+
icon: data[name].extIcon
|
|
1234
|
+
})
|
|
1235
|
+
);
|
|
1237
1236
|
callback(result);
|
|
1238
1237
|
});
|
|
1239
1238
|
}
|
package/lib/socketCommon.js
CHANGED
|
@@ -25,25 +25,25 @@ class SocketCommon {
|
|
|
25
25
|
throw new Error('"__getIsNoDisconnect" must be implemented in SocketCommon!');
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
__initAuthentication(
|
|
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(
|
|
33
|
+
__getUserFromSocket(_socket, _callback) {
|
|
34
34
|
throw new Error('"__getUserFromSocket" must be implemented in SocketCommon!');
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
__getClientAddress(
|
|
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(
|
|
42
|
+
__updateSession(_socket) {
|
|
43
43
|
throw new Error('"__updateSession" must be implemented in SocketCommon!');
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
__getSessionID(
|
|
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.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "ioBroker server-side web sockets",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "bluefox",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"url": "https://github.com/ioBroker/ioBroker.socket-classes"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@iobroker/adapter-core": "^3.
|
|
24
|
+
"@iobroker/adapter-core": "^3.1.4",
|
|
25
25
|
"axios": "^1.6.7",
|
|
26
26
|
"cookie-parser": "^1.4.6",
|
|
27
27
|
"passport": "^0.7.0"
|
|
@@ -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
|
},
|