matterbridge 3.3.5-dev-20251025-26d5c31 → 3.3.5-dev-20251029-a0d9d11
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/CHANGELOG.md +10 -0
- package/README-SERVICE-LOCAL.md +1 -54
- package/README.md +4 -0
- package/dist/deviceManager.js +7 -0
- package/dist/frontend.js +136 -62
- package/dist/matterbridge.js +3 -0
- package/dist/pluginManager.js +9 -1
- package/frontend/build/assets/index.js +4 -4
- package/frontend/package.json +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -30,9 +30,19 @@ Advantages:
|
|
|
30
30
|
|
|
31
31
|
## [3.3.5] - 2025-10-??
|
|
32
32
|
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- [thread]: Added get_log_level and set_log_level to BroadcastServer.
|
|
36
|
+
- [frontend]: Added password check to WebSocket.
|
|
37
|
+
|
|
33
38
|
### Changed
|
|
34
39
|
|
|
35
40
|
- [package]: Updated dependencies.
|
|
41
|
+
- [frontend]: Bumped `frontend` version to 3.2.4.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- [service]: Fixed systemd configuration with local global node_modules.
|
|
36
46
|
|
|
37
47
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
38
48
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
package/README-SERVICE-LOCAL.md
CHANGED
|
@@ -51,7 +51,7 @@ Create a systemctl configuration file for Matterbridge
|
|
|
51
51
|
sudo nano /etc/systemd/system/matterbridge.service
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Add the following to this file, replacing
|
|
54
|
+
Add the following to this file, replacing 4 times (!) USER with your user name (e.g. WorkingDirectory=/home/pi/Matterbridge, User=pi and Group=pi and Environment="NPM_CONFIG_PREFIX=/home/pi/.npm-global"):
|
|
55
55
|
|
|
56
56
|
```
|
|
57
57
|
[Unit]
|
|
@@ -171,56 +171,3 @@ save it and run
|
|
|
171
171
|
```bash
|
|
172
172
|
sudo systemctl restart systemd-journald
|
|
173
173
|
```
|
|
174
|
-
|
|
175
|
-
## Verify that with your distro you can run sudo npm install -g matterbridge without the password
|
|
176
|
-
|
|
177
|
-
Run the following command to verify if you can install Matterbridge globally without being prompted for a password:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
sudo npm install -g matterbridge --omit=dev
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
If you are not prompted for a password, no further action is required.
|
|
184
|
-
|
|
185
|
-
If that is not the case, open the sudoers file for editing using visudo
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
sudo visudo
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
verify the presence of of a line
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
@includedir /etc/sudoers.d
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
exit and create a configuration file for sudoers
|
|
198
|
-
|
|
199
|
-
```bash
|
|
200
|
-
sudo nano /etc/sudoers.d/matterbridge
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
add this line replacing USER with your user name (e.g. radxa ALL=(ALL) NOPASSWD: ALL)
|
|
204
|
-
|
|
205
|
-
```
|
|
206
|
-
<USER> ALL=(ALL) NOPASSWD: ALL
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
or if you prefers to only give access to npm without password try with (e.g. radxa ALL=(ALL) NOPASSWD: /usr/bin/npm)
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
<USER> ALL=(ALL) NOPASSWD: /usr/bin/npm
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
save the file and reload the settings with:
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
sudo chmod 0440 /etc/sudoers.d/matterbridge
|
|
219
|
-
sudo visudo -c
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
Verify if you can install Matterbridge globally without being prompted for a password:
|
|
223
|
-
|
|
224
|
-
```bash
|
|
225
|
-
sudo npm install -g matterbridge --omit=dev
|
|
226
|
-
```
|
package/README.md
CHANGED
|
@@ -172,6 +172,10 @@ Config editor:
|
|
|
172
172
|
|
|
173
173
|
[Service configurations](README-SERVICE.md)
|
|
174
174
|
|
|
175
|
+
or with local global node_modules
|
|
176
|
+
|
|
177
|
+
[Service configurations with local global node_modules](README-SERVICE-LOCAL.md)
|
|
178
|
+
|
|
175
179
|
### Run matterbridge as a system service with launchctl (macOS only)
|
|
176
180
|
|
|
177
181
|
[Launchctl configurations](README-MACOS-PLIST.md)
|
package/dist/deviceManager.js
CHANGED
|
@@ -20,6 +20,13 @@ export class DeviceManager {
|
|
|
20
20
|
if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'devices')) {
|
|
21
21
|
this.log.debug(`**Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
22
22
|
switch (msg.type) {
|
|
23
|
+
case 'get_log_level':
|
|
24
|
+
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
25
|
+
break;
|
|
26
|
+
case 'set_log_level':
|
|
27
|
+
this.log.logLevel = msg.params.logLevel;
|
|
28
|
+
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
29
|
+
break;
|
|
23
30
|
case 'devices_length':
|
|
24
31
|
this.server.respond({ ...msg, response: { length: this.length } });
|
|
25
32
|
break;
|
package/dist/frontend.js
CHANGED
|
@@ -26,6 +26,7 @@ export class Frontend extends EventEmitter {
|
|
|
26
26
|
log;
|
|
27
27
|
port = 8283;
|
|
28
28
|
listening = false;
|
|
29
|
+
storedPassword = undefined;
|
|
29
30
|
expressApp;
|
|
30
31
|
httpServer;
|
|
31
32
|
httpsServer;
|
|
@@ -46,6 +47,13 @@ export class Frontend extends EventEmitter {
|
|
|
46
47
|
if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'frontend')) {
|
|
47
48
|
this.log.debug(`Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
48
49
|
switch (msg.type) {
|
|
50
|
+
case 'get_log_level':
|
|
51
|
+
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
52
|
+
break;
|
|
53
|
+
case 'set_log_level':
|
|
54
|
+
this.log.logLevel = msg.params.logLevel;
|
|
55
|
+
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
56
|
+
break;
|
|
49
57
|
case 'frontend_start':
|
|
50
58
|
await this.start(msg.params.port);
|
|
51
59
|
this.server.respond({ ...msg, response: { success: true } });
|
|
@@ -54,6 +62,30 @@ export class Frontend extends EventEmitter {
|
|
|
54
62
|
await this.stop();
|
|
55
63
|
this.server.respond({ ...msg, response: { success: true } });
|
|
56
64
|
break;
|
|
65
|
+
case 'frontend_refreshrequired':
|
|
66
|
+
this.wssSendRefreshRequired(msg.params.changed, { matter: msg.params.matter });
|
|
67
|
+
this.server.respond({ ...msg, response: { success: true } });
|
|
68
|
+
break;
|
|
69
|
+
case 'frontend_restartrequired':
|
|
70
|
+
this.wssSendRestartRequired(msg.params.snackbar, msg.params.fixed);
|
|
71
|
+
this.server.respond({ ...msg, response: { success: true } });
|
|
72
|
+
break;
|
|
73
|
+
case 'frontend_restartnotrequired':
|
|
74
|
+
this.wssSendRestartNotRequired(msg.params.snackbar);
|
|
75
|
+
this.server.respond({ ...msg, response: { success: true } });
|
|
76
|
+
break;
|
|
77
|
+
case 'frontend_updaterequired':
|
|
78
|
+
this.wssSendUpdateRequired(msg.params.devVersion);
|
|
79
|
+
this.server.respond({ ...msg, response: { success: true } });
|
|
80
|
+
break;
|
|
81
|
+
case 'frontend_snackbarmessage':
|
|
82
|
+
this.wssSendSnackbarMessage(msg.params.message, msg.params.timeout, msg.params.severity);
|
|
83
|
+
this.server.respond({ ...msg, response: { success: true } });
|
|
84
|
+
break;
|
|
85
|
+
case 'frontend_attributechanged':
|
|
86
|
+
this.wssSendAttributeChangedMessage(msg.params.plugin, msg.params.serialNumber, msg.params.uniqueId, msg.params.number, msg.params.id, msg.params.cluster, msg.params.attribute, msg.params.value);
|
|
87
|
+
this.server.respond({ ...msg, response: { success: true } });
|
|
88
|
+
break;
|
|
57
89
|
default:
|
|
58
90
|
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
59
91
|
}
|
|
@@ -61,6 +93,9 @@ export class Frontend extends EventEmitter {
|
|
|
61
93
|
if (this.server.isWorkerResponse(msg, msg.type)) {
|
|
62
94
|
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
63
95
|
switch (msg.type) {
|
|
96
|
+
case 'get_log_level':
|
|
97
|
+
case 'set_log_level':
|
|
98
|
+
break;
|
|
64
99
|
case 'plugins_install':
|
|
65
100
|
this.wssSendCloseSnackbarMessage(`Installing package ${msg.response.packageName}...`);
|
|
66
101
|
if (msg.response.success) {
|
|
@@ -93,6 +128,7 @@ export class Frontend extends EventEmitter {
|
|
|
93
128
|
}
|
|
94
129
|
async start(port = 8283) {
|
|
95
130
|
this.port = port;
|
|
131
|
+
this.storedPassword = await this.matterbridge.nodeContext?.get('password', '');
|
|
96
132
|
this.log.debug(`Initializing the frontend ${hasParameter('ssl') ? 'https' : 'http'} server on port ${YELLOW}${this.port}${db}`);
|
|
97
133
|
const multer = await import('multer');
|
|
98
134
|
const uploadDir = path.join(this.matterbridge.matterbridgeDirectory, 'uploads');
|
|
@@ -100,6 +136,47 @@ export class Frontend extends EventEmitter {
|
|
|
100
136
|
const express = await import('express');
|
|
101
137
|
this.expressApp = express.default();
|
|
102
138
|
this.expressApp.use(express.static(path.join(this.matterbridge.rootDirectory, 'frontend/build')));
|
|
139
|
+
this.log.debug(`Creating WebSocketServer...`);
|
|
140
|
+
const ws = await import('ws');
|
|
141
|
+
this.webSocketServer = new ws.WebSocketServer({ noServer: true });
|
|
142
|
+
this.emit('websocket_server_listening', hasParameter('ssl') ? 'wss' : 'ws');
|
|
143
|
+
this.webSocketServer.on('connection', (ws, request) => {
|
|
144
|
+
const clientIp = request.socket.remoteAddress;
|
|
145
|
+
let callbackLogLevel = "notice";
|
|
146
|
+
if (this.matterbridge.getLogLevel() === "info" || Logger.level === MatterLogLevel.INFO)
|
|
147
|
+
callbackLogLevel = "info";
|
|
148
|
+
if (this.matterbridge.getLogLevel() === "debug" || Logger.level === MatterLogLevel.DEBUG)
|
|
149
|
+
callbackLogLevel = "debug";
|
|
150
|
+
AnsiLogger.setGlobalCallback(this.wssSendLogMessage.bind(this), callbackLogLevel);
|
|
151
|
+
this.log.debug(`WebSocketServer logger global callback set to ${callbackLogLevel}`);
|
|
152
|
+
this.log.info(`WebSocketServer client "${clientIp}" connected to Matterbridge`);
|
|
153
|
+
ws.on('message', (message) => {
|
|
154
|
+
this.wsMessageHandler(ws, message);
|
|
155
|
+
});
|
|
156
|
+
ws.on('ping', () => {
|
|
157
|
+
this.log.debug('WebSocket client ping');
|
|
158
|
+
ws.pong();
|
|
159
|
+
});
|
|
160
|
+
ws.on('pong', () => {
|
|
161
|
+
this.log.debug('WebSocket client pong');
|
|
162
|
+
});
|
|
163
|
+
ws.on('close', () => {
|
|
164
|
+
this.log.info('WebSocket client disconnected');
|
|
165
|
+
if (this.webSocketServer?.clients.size === 0) {
|
|
166
|
+
AnsiLogger.setGlobalCallback(undefined);
|
|
167
|
+
this.log.debug('All WebSocket clients disconnected. WebSocketServer logger global callback removed');
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
ws.on('error', (error) => {
|
|
171
|
+
this.log.error(`WebSocket client error: ${error}`);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
this.webSocketServer.on('close', () => {
|
|
175
|
+
this.log.debug(`WebSocketServer closed`);
|
|
176
|
+
});
|
|
177
|
+
this.webSocketServer.on('error', (ws, error) => {
|
|
178
|
+
this.log.error(`WebSocketServer error: ${error}`);
|
|
179
|
+
});
|
|
103
180
|
if (!hasParameter('ssl')) {
|
|
104
181
|
const http = await import('node:http');
|
|
105
182
|
try {
|
|
@@ -128,6 +205,32 @@ export class Frontend extends EventEmitter {
|
|
|
128
205
|
this.emit('server_listening', 'http', this.port);
|
|
129
206
|
});
|
|
130
207
|
}
|
|
208
|
+
this.httpServer.on('upgrade', async (req, socket, head) => {
|
|
209
|
+
try {
|
|
210
|
+
if ((req.headers.upgrade || '').toLowerCase() !== 'websocket') {
|
|
211
|
+
socket.write('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n');
|
|
212
|
+
return socket.destroy();
|
|
213
|
+
}
|
|
214
|
+
const url = new URL(req.url ?? '/', `http://${req.headers.host || 'localhost'}`);
|
|
215
|
+
const password = url.searchParams.get('password') ?? '';
|
|
216
|
+
if (password !== this.storedPassword) {
|
|
217
|
+
this.log.error(`WebSocket upgrade error: Invalid password ${password ? '[redacted]' : '(empty)'}`);
|
|
218
|
+
socket.write('HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n');
|
|
219
|
+
return socket.destroy();
|
|
220
|
+
}
|
|
221
|
+
this.log.debug(`WebSocket upgrade success host ${url.host} password ${password ? '[redacted]' : '(empty)'}`);
|
|
222
|
+
this.webSocketServer?.handleUpgrade(req, socket, head, (ws) => {
|
|
223
|
+
this.webSocketServer?.emit('connection', ws, req);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
{
|
|
228
|
+
inspectError(this.log, 'WebSocket upgrade error:', err);
|
|
229
|
+
socket.write('HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\n\r\n');
|
|
230
|
+
socket.destroy();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
131
234
|
this.httpServer.on('error', (error) => {
|
|
132
235
|
this.log.error(`Frontend http server error listening on ${this.port}`);
|
|
133
236
|
switch (error.code) {
|
|
@@ -233,6 +336,32 @@ export class Frontend extends EventEmitter {
|
|
|
233
336
|
this.emit('server_listening', 'https', this.port);
|
|
234
337
|
});
|
|
235
338
|
}
|
|
339
|
+
this.httpsServer.on('upgrade', async (req, socket, head) => {
|
|
340
|
+
try {
|
|
341
|
+
if ((req.headers.upgrade || '').toLowerCase() !== 'websocket') {
|
|
342
|
+
socket.write('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n');
|
|
343
|
+
return socket.destroy();
|
|
344
|
+
}
|
|
345
|
+
const url = new URL(req.url ?? '/', `https://${req.headers.host || 'localhost'}`);
|
|
346
|
+
const password = url.searchParams.get('password') ?? '';
|
|
347
|
+
if (password !== this.storedPassword) {
|
|
348
|
+
this.log.error(`WebSocket upgrade error: Invalid password ${password ? '[redacted]' : '(empty)'}`);
|
|
349
|
+
socket.write('HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n');
|
|
350
|
+
return socket.destroy();
|
|
351
|
+
}
|
|
352
|
+
this.log.debug(`WebSocket upgrade success host ${url.host} password ${password ? '[redacted]' : '(empty)'}`);
|
|
353
|
+
this.webSocketServer?.handleUpgrade(req, socket, head, (ws) => {
|
|
354
|
+
this.webSocketServer?.emit('connection', ws, req);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
{
|
|
359
|
+
inspectError(this.log, 'WebSocket upgrade error:', err);
|
|
360
|
+
socket.write('HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\n\r\n');
|
|
361
|
+
socket.destroy();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
});
|
|
236
365
|
this.httpsServer.on('error', (error) => {
|
|
237
366
|
this.log.error(`Frontend https server error listening on ${this.port}`);
|
|
238
367
|
switch (error.code) {
|
|
@@ -247,50 +376,6 @@ export class Frontend extends EventEmitter {
|
|
|
247
376
|
return;
|
|
248
377
|
});
|
|
249
378
|
}
|
|
250
|
-
const ws = await import('ws');
|
|
251
|
-
this.log.debug(`Creating WebSocketServer...`);
|
|
252
|
-
this.webSocketServer = new ws.WebSocketServer(hasParameter('ssl') ? { server: this.httpsServer } : { server: this.httpServer });
|
|
253
|
-
this.webSocketServer.on('connection', (ws, request) => {
|
|
254
|
-
const clientIp = request.socket.remoteAddress;
|
|
255
|
-
let callbackLogLevel = "notice";
|
|
256
|
-
if (this.matterbridge.getLogLevel() === "info" || Logger.level === MatterLogLevel.INFO)
|
|
257
|
-
callbackLogLevel = "info";
|
|
258
|
-
if (this.matterbridge.getLogLevel() === "debug" || Logger.level === MatterLogLevel.DEBUG)
|
|
259
|
-
callbackLogLevel = "debug";
|
|
260
|
-
AnsiLogger.setGlobalCallback(this.wssSendLogMessage.bind(this), callbackLogLevel);
|
|
261
|
-
this.log.debug(`WebSocketServer logger global callback set to ${callbackLogLevel}`);
|
|
262
|
-
this.log.info(`WebSocketServer client "${clientIp}" connected to Matterbridge`);
|
|
263
|
-
ws.on('message', (message) => {
|
|
264
|
-
this.wsMessageHandler(ws, message);
|
|
265
|
-
});
|
|
266
|
-
ws.on('ping', () => {
|
|
267
|
-
this.log.debug('WebSocket client ping');
|
|
268
|
-
ws.pong();
|
|
269
|
-
});
|
|
270
|
-
ws.on('pong', () => {
|
|
271
|
-
this.log.debug('WebSocket client pong');
|
|
272
|
-
});
|
|
273
|
-
ws.on('close', () => {
|
|
274
|
-
this.log.info('WebSocket client disconnected');
|
|
275
|
-
if (this.webSocketServer?.clients.size === 0) {
|
|
276
|
-
AnsiLogger.setGlobalCallback(undefined);
|
|
277
|
-
this.log.debug('All WebSocket clients disconnected. WebSocketServer logger global callback removed');
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
ws.on('error', (error) => {
|
|
281
|
-
this.log.error(`WebSocket client error: ${error}`);
|
|
282
|
-
});
|
|
283
|
-
});
|
|
284
|
-
this.webSocketServer.on('close', () => {
|
|
285
|
-
this.log.debug(`WebSocketServer closed`);
|
|
286
|
-
});
|
|
287
|
-
this.webSocketServer.on('listening', () => {
|
|
288
|
-
this.log.info(`The WebSocketServer is listening`);
|
|
289
|
-
this.emit('websocket_server_listening', hasParameter('ssl') ? 'wss' : 'ws');
|
|
290
|
-
});
|
|
291
|
-
this.webSocketServer.on('error', (ws, error) => {
|
|
292
|
-
this.log.error(`WebSocketServer error: ${error}`);
|
|
293
|
-
});
|
|
294
379
|
cliEmitter.removeAllListeners();
|
|
295
380
|
cliEmitter.on('uptime', (systemUptime, processUptime) => {
|
|
296
381
|
this.wssSendUptimeUpdate(systemUptime, processUptime);
|
|
@@ -303,25 +388,13 @@ export class Frontend extends EventEmitter {
|
|
|
303
388
|
});
|
|
304
389
|
this.expressApp.post('/api/login', express.json(), async (req, res) => {
|
|
305
390
|
const { password } = req.body;
|
|
306
|
-
this.log.debug(
|
|
307
|
-
if (
|
|
308
|
-
this.log.
|
|
309
|
-
res.json({ valid:
|
|
310
|
-
return;
|
|
391
|
+
this.log.debug(`The frontend sent /api/login with password ${password ? '[redacted]' : '(empty)'}`);
|
|
392
|
+
if (this.storedPassword === '' || password === this.storedPassword) {
|
|
393
|
+
this.log.debug('/api/login password valid');
|
|
394
|
+
res.json({ valid: true });
|
|
311
395
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (storedPassword === '' || password === storedPassword) {
|
|
315
|
-
this.log.debug('/api/login password valid');
|
|
316
|
-
res.json({ valid: true });
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
this.log.warn('/api/login error wrong password');
|
|
320
|
-
res.json({ valid: false });
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
catch (error) {
|
|
324
|
-
this.log.error('/api/login error getting password');
|
|
396
|
+
else {
|
|
397
|
+
this.log.warn('/api/login error wrong password');
|
|
325
398
|
res.json({ valid: false });
|
|
326
399
|
}
|
|
327
400
|
});
|
|
@@ -1480,6 +1553,7 @@ export class Frontend extends EventEmitter {
|
|
|
1480
1553
|
case 'setpassword':
|
|
1481
1554
|
if (isValidString(data.params.value)) {
|
|
1482
1555
|
await this.matterbridge.nodeContext?.set('password', data.params.value);
|
|
1556
|
+
this.storedPassword = data.params.value;
|
|
1483
1557
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1484
1558
|
}
|
|
1485
1559
|
break;
|
package/dist/matterbridge.js
CHANGED
|
@@ -146,6 +146,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
146
146
|
if (this.server.isWorkerResponse(msg, msg.type)) {
|
|
147
147
|
this.log.debug(`**Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
148
148
|
switch (msg.type) {
|
|
149
|
+
case 'get_log_level':
|
|
150
|
+
case 'set_log_level':
|
|
151
|
+
break;
|
|
149
152
|
default:
|
|
150
153
|
this.log.debug(`Unknown broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
151
154
|
}
|
package/dist/pluginManager.js
CHANGED
|
@@ -2,6 +2,7 @@ import EventEmitter from 'node:events';
|
|
|
2
2
|
import { AnsiLogger, UNDERLINE, UNDERLINEOFF, BLUE, db, er, nf, nt, rs, wr, debugStringify, CYAN } from 'node-ansi-logger';
|
|
3
3
|
import { plg, typ } from './matterbridgeTypes.js';
|
|
4
4
|
import { inspectError, logError } from './utils/error.js';
|
|
5
|
+
import { hasParameter } from './utils/commandLine.js';
|
|
5
6
|
import { BroadcastServer } from './broadcastServer.js';
|
|
6
7
|
export class PluginManager extends EventEmitter {
|
|
7
8
|
_plugins = new Map();
|
|
@@ -11,7 +12,7 @@ export class PluginManager extends EventEmitter {
|
|
|
11
12
|
constructor(matterbridge) {
|
|
12
13
|
super();
|
|
13
14
|
this.matterbridge = matterbridge;
|
|
14
|
-
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel:
|
|
15
|
+
this.log = new AnsiLogger({ logName: 'PluginManager', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
|
|
15
16
|
this.log.debug('Matterbridge plugin manager starting...');
|
|
16
17
|
this.server = new BroadcastServer('plugins', this.log);
|
|
17
18
|
this.server.on('broadcast_message', this.msgHandler.bind(this));
|
|
@@ -24,6 +25,13 @@ export class PluginManager extends EventEmitter {
|
|
|
24
25
|
if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'plugins')) {
|
|
25
26
|
this.log.debug(`**Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
26
27
|
switch (msg.type) {
|
|
28
|
+
case 'get_log_level':
|
|
29
|
+
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
30
|
+
break;
|
|
31
|
+
case 'set_log_level':
|
|
32
|
+
this.log.logLevel = msg.params.logLevel;
|
|
33
|
+
this.server.respond({ ...msg, response: { success: true, logLevel: this.log.logLevel } });
|
|
34
|
+
break;
|
|
27
35
|
case 'plugins_length':
|
|
28
36
|
this.server.respond({ ...msg, response: { length: this.length } });
|
|
29
37
|
break;
|