@iobroker/socket-classes 2.6.1 → 2.7.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.
- package/README.md +10 -0
- package/build/lib/socketCommands.d.ts +32 -0
- package/build/lib/socketCommands.js +139 -95
- package/build/lib/socketCommands.js.map +1 -1
- package/build/lib/socketCommandsAdmin.js +5 -1
- package/build/lib/socketCommandsAdmin.js.map +1 -1
- package/build/lib/socketCommon.d.ts +20 -0
- package/build/lib/socketCommon.js +57 -8
- package/build/lib/socketCommon.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1043,6 +1043,16 @@ 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.0 (2026-10-05)
|
|
1047
|
+
- (@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 a js-controller that reports `ADAPTER_MESSAGE_USER_CONTEXT` passes on to the message as `obj.user`; an older one ignores it, so nothing breaks, and a receiving adapter has to treat the field as optional
|
|
1048
|
+
|
|
1049
|
+
### 2.6.2 (2026-10-02)
|
|
1050
|
+
- (@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
|
|
1051
|
+
- (@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
|
|
1052
|
+
- (@GermanBluefox) Fixed: `authenticate` of a socket that is waiting for a token is answered when the token arrives, instead of being answered with "authenticated" although the socket has no user
|
|
1053
|
+
- (@GermanBluefox) Fixed: `reauthenticate` was sent twice for the same connection, so a client started two token refreshes and used up two refresh tokens
|
|
1054
|
+
- (@GermanBluefox) Changed: that a socket is not authenticated is logged at `debug` instead of `silly`, so the case is visible without raising the level of the whole adapter
|
|
1055
|
+
|
|
1046
1056
|
### 2.6.1 (2026-10-01)
|
|
1047
1057
|
- (@GermanBluefox) `getCompactRepository` is answered from the objects admin holds in memory instead of asking the host. The host answers `getRepository` with the whole merged repository - several megabytes through the message box for the two fields per adapter that the GUI uses - and every start of the admin GUI waited seconds for it (measured on a fast machine with three active repositories: 3140 ms, now 38 ms, with a byte-identical answer). A host without an object cache, or an active repository that was never downloaded, still goes through the host
|
|
1048
1058
|
- (@GermanBluefox) The host is still asked for the repository, but ten seconds later and at most once an hour, and nobody waits for the answer: the statistics, the check for a new Docker image and for OS updates, the blocklist and the automatic adapter upgrade hang on that command and nothing else triggers them
|
|
@@ -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 the controllers that report
|
|
7
|
+
* `ADAPTER_MESSAGE_USER_CONTEXT` and silently ignored by older ones, and it is not in the older
|
|
8
|
+
* `@iobroker/types` this package builds against - 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;
|
|
@@ -46,6 +59,11 @@ export declare class SocketCommands {
|
|
|
46
59
|
result?: any;
|
|
47
60
|
}) => void) => void) | null;
|
|
48
61
|
states: Record<string, ioBroker.State> | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Finish the authentication of a socket with an access token the client announced.
|
|
64
|
+
* Set by `SocketCommon`, which is the only one that knows how to calculate the ACL of a user.
|
|
65
|
+
*/
|
|
66
|
+
authenticateSocket: ((socket: WebSocketClient, user: string, expiresAt: number, callback: (success: boolean) => void) => void) | null;
|
|
49
67
|
constructor(adapter: ioBroker.Adapter, updateSession?: (socket: WebSocketClient) => boolean, context?: SocketDataContext);
|
|
50
68
|
/**
|
|
51
69
|
* Convert errors into strings and then call cb
|
|
@@ -58,6 +76,19 @@ export declare class SocketCommands {
|
|
|
58
76
|
_checkPermissions(socket: WebSocketClient, command: PermissionCommands, callback: ((error: string | null, ...args: any[]) => void) | undefined, ...args: any[]): boolean;
|
|
59
77
|
publish(socket: WebSocketClient, type: SocketSubscribeTypes, id: string, obj: ioBroker.Object | ioBroker.State | null | undefined): boolean;
|
|
60
78
|
publishFile(socket: WebSocketClient, id: string, fileName: string, size: number | null): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* The send options for a message triggered by this socket: the user it is sent on behalf of.
|
|
81
|
+
*
|
|
82
|
+
* Objects, states and files have always been read and written with `{ user }` so the database
|
|
83
|
+
* applies the ACLs of the logged-in user. A message had no such channel: the receiving instance saw
|
|
84
|
+
* `from` and nothing else, so every adapter reachable over `sendTo` had to act with its own rights,
|
|
85
|
+
* and could not tell one caller from another. The user travels with the message now, for the
|
|
86
|
+
* controller versions that support it - older ones ignore the option, so nothing breaks, but a
|
|
87
|
+
* receiver must treat `obj.user` as optional (`adapter.supportsFeature('ADAPTER_MESSAGE_USER_CONTEXT')`).
|
|
88
|
+
*
|
|
89
|
+
* @param socket the socket the command came in on
|
|
90
|
+
*/
|
|
91
|
+
protected static sendOptionsOf(socket: WebSocketClient): MessageSendOptions | undefined;
|
|
61
92
|
publishInstanceMessage(socket: WebSocketClient, sourceInstance: string, messageType: string, data: any): boolean;
|
|
62
93
|
_showSubscribes(socket: WebSocketClient, type: SocketSubscribeTypes): void;
|
|
63
94
|
isLogEnabled(): boolean;
|
|
@@ -85,3 +116,4 @@ export declare class SocketCommands {
|
|
|
85
116
|
disableEventThreshold(): void;
|
|
86
117
|
destroy(): void;
|
|
87
118
|
}
|
|
119
|
+
export {};
|