@iobroker/socket-classes 2.6.2 → 2.7.1
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
CHANGED
|
@@ -1043,6 +1043,13 @@ Unsubscribe from file changes in ioBroker DB
|
|
|
1043
1043
|
Placeholder for the next version (at the beginning of the line):
|
|
1044
1044
|
### **WORK IN PROGRESS**
|
|
1045
1045
|
-->
|
|
1046
|
+
### 2.7.1 (2026-10-07)
|
|
1047
|
+
- (@GermanBluefox) Added: an event only reaches a connection whose user may read what it is about. A subscription says which ids a client is interested in, never which ids it may see - `subscribe` asks whether the user may read states *at all*, so whoever subscribed to `*` was told about every state of the system, the ACL of the single objects notwithstanding, and the same went for objects and for files. The fan-out asks that question now, for state, object and file events alike. Members of the administrator group are not restricted, as everywhere else, and with authentication switched off every connection is the configured default user - so for most installations nothing changes at all. **Where restricted users exist, they will see less than before: that is the point, but it is the kind of change that comes back as "my user stopped getting updates".** The database decides, not this package: `mayRead` of js-controller 8.0 and newer is asked where it exists, which knows the ACL of a state rather than that of its object and the mode of a single file rather than that of the adapter; an older controller is asked for the object instead, which is coarser but refuses in the same direction. One question per user and thing, remembered until the object - or the rights themselves - change, and the objects are watched from the first decision on, so an installation whose connections are all administrators never asks anything
|
|
1048
|
+
- (@GermanBluefox) Changed: `publish` and `publishFile` answer `true` where the event is on its way to the client, which now includes the moment it waits for the decision described above; `false` means the client is not subscribed to it, or may not see it. Only the first event of a thing ever waits, and only the newest one of it, so nothing can overtake it
|
|
1049
|
+
|
|
1050
|
+
### 2.7.0 (2026-10-05)
|
|
1051
|
+
- (@GermanBluefox) Added: every command that sends a message now names the user of the connection - `sendTo`, `sendToHost`, `cmdExec`, `clientSubscribe`, `clientUnsubscribe` and the "nobody subscribed" notice. Objects, states and files have always been read and written with `{ user }` so the database applies the ACLs of the logged-in user; a message had no such channel, so the receiving instance saw `from` and nothing else and had to act with its own rights - a GUI user who may use `sendTo` could have an adapter do things their own ACL forbids. It travels as a send option, which js-controller 7.2.5 and newer pass on to the message as `obj.user`; an older one ignores it, so nothing breaks, and a receiving adapter treats the field as optional
|
|
1052
|
+
|
|
1046
1053
|
### 2.6.2 (2026-10-02)
|
|
1047
1054
|
- (@GermanBluefox) Fixed: a websocket whose access token was not accepted stayed open without a single command handler. The client was asked to re-authenticate, fetched a new token within milliseconds and announced it with `updateTokenExpiration` - the one command that is exempt from the session check exactly for this - but nobody was listening. The client waited for an answer that could not come until its own three second timeout closed the connection, burnt its single-use refresh token for nothing and had to start over, which is why the GUI took seconds to come up with authentication enabled and sometimes did not come up at all. The handlers are installed now, with an empty ACL: every command that needs a permission is still refused, only the announcement of a token gets through
|
|
1048
1055
|
- (@GermanBluefox) Fixed: an announced access token now finishes the authentication of such a socket instead of only moving its expiration date. The connection carries on with the user of the token, so no reconnect and no second refresh is needed
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { Socket as WebSocketClient } from '@iobroker/ws-server';
|
|
2
2
|
import { type PermissionCommands, type SocketSubscribeTypes, type SocketOperation, type SocketCallback } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* The options of an outbound message, as far as this package needs them.
|
|
5
|
+
*
|
|
6
|
+
* `timeout` has always been there. `user` is read by js-controller 7.2.5 and newer and silently
|
|
7
|
+
* ignored by older ones, and it is not in the older `@iobroker/types` this package builds against -
|
|
8
|
+
* hence the own declaration.
|
|
9
|
+
*/
|
|
10
|
+
interface MessageSendOptions {
|
|
11
|
+
/** Reject/err-callback if no answer arrives in time (single targets only) */
|
|
12
|
+
timeout?: number;
|
|
13
|
+
/** The user the message is sent on behalf of */
|
|
14
|
+
user?: `system.user.${string}`;
|
|
15
|
+
}
|
|
3
16
|
export declare const COMMANDS_PERMISSIONS: Record<PermissionCommands, {
|
|
4
17
|
type: 'object' | 'state' | 'users' | 'other' | 'file' | '';
|
|
5
18
|
operation: SocketOperation;
|
|
@@ -61,8 +74,51 @@ export declare class SocketCommands {
|
|
|
61
74
|
*/
|
|
62
75
|
static _fixCallback(callback: SocketCallback | null | undefined, error: string | Error | null | undefined, ...args: any[]): void;
|
|
63
76
|
_checkPermissions(socket: WebSocketClient, command: PermissionCommands, callback: ((error: string | null, ...args: any[]) => void) | undefined, ...args: any[]): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Give one event to one connection, if it is subscribed to it and may see it.
|
|
79
|
+
*
|
|
80
|
+
* Returns whether the event is on its way to this client: `true` where it was sent, and also
|
|
81
|
+
* where it is waiting for the database to decide whether this user may read the object - the
|
|
82
|
+
* answer to that is not worth holding up every other connection for. `false` means the client is
|
|
83
|
+
* not subscribed to it, or may not see it.
|
|
84
|
+
*
|
|
85
|
+
* @param socket the connection
|
|
86
|
+
* @param type what kind of event it is
|
|
87
|
+
* @param id the object it is about
|
|
88
|
+
* @param obj the state or object as it is sent to the client
|
|
89
|
+
*/
|
|
64
90
|
publish(socket: WebSocketClient, type: SocketSubscribeTypes, id: string, obj: ioBroker.Object | ioBroker.State | null | undefined): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Give one file event to one connection, if it is subscribed to it and may see it.
|
|
93
|
+
*
|
|
94
|
+
* The decision is taken per file and user. Where the controller has `mayRead`, it answers for the
|
|
95
|
+
* single file, with its own owner and mode as `chownFile` and `chmodFile` set them. An older
|
|
96
|
+
* controller cannot be asked about a file, so the meta object the files belong to - `vis.0` for
|
|
97
|
+
* every file of vis - stands in for it: still one question per file, but every one of them about
|
|
98
|
+
* the adapter. That also works where the file the event is about has just been deleted.
|
|
99
|
+
*
|
|
100
|
+
* The answer means the same as in {@link publish}: `true` where the event is on its way.
|
|
101
|
+
*
|
|
102
|
+
* @param socket the connection
|
|
103
|
+
* @param id the adapter the file belongs to, e.g. `vis.0`
|
|
104
|
+
* @param fileName the path of the file inside it
|
|
105
|
+
* @param size how big it is now, or null where it is gone
|
|
106
|
+
*/
|
|
65
107
|
publishFile(socket: WebSocketClient, id: string, fileName: string, size: number | null): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* The send options for a message triggered by this socket: the user it is sent on behalf of.
|
|
110
|
+
*
|
|
111
|
+
* Objects, states and files have always been read and written with `{ user }` so the database
|
|
112
|
+
* applies the ACLs of the logged-in user. A message had no such channel: the receiving instance saw
|
|
113
|
+
* `from` and nothing else, so every adapter reachable over `sendTo` had to act with its own rights,
|
|
114
|
+
* and could not tell one caller from another. The user travels with the message now: js-controller
|
|
115
|
+
* 7.2.5 and newer put it into the message as `obj.user`, older ones ignore the option, so nothing
|
|
116
|
+
* breaks. A receiver treats the field as optional - where nobody was named there is nothing to
|
|
117
|
+
* check against, which is how every message looked before.
|
|
118
|
+
*
|
|
119
|
+
* @param socket the socket the command came in on
|
|
120
|
+
*/
|
|
121
|
+
protected static sendOptionsOf(socket: WebSocketClient): MessageSendOptions | undefined;
|
|
66
122
|
publishInstanceMessage(socket: WebSocketClient, sourceInstance: string, messageType: string, data: any): boolean;
|
|
67
123
|
_showSubscribes(socket: WebSocketClient, type: SocketSubscribeTypes): void;
|
|
68
124
|
isLogEnabled(): boolean;
|
|
@@ -90,3 +146,4 @@ export declare class SocketCommands {
|
|
|
90
146
|
disableEventThreshold(): void;
|
|
91
147
|
destroy(): void;
|
|
92
148
|
}
|
|
149
|
+
export {};
|