matterbridge 3.1.4-dev-20250715-075e722 → 3.1.4-dev-20250717-d36e252
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 +7 -2
- package/README.md +25 -2
- package/dist/frontend.js +65 -31
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,18 +8,23 @@ If you like this project and find it useful, please consider giving it a star on
|
|
|
8
8
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="120">
|
|
9
9
|
</a>
|
|
10
10
|
|
|
11
|
-
## [3.1.4] - 2025-07
|
|
11
|
+
## [3.1.4] - 2025-07-16
|
|
12
12
|
|
|
13
13
|
### Added
|
|
14
14
|
|
|
15
|
+
- [frontend]: Added support for p12 certificates. Add cert.p12 and cert.pass in the '.matterbridge/cert' directory. If both .p12 and cert.pem are present, only the .p12 will be used. See the README.md for more info.
|
|
16
|
+
- [frontend]: Added support for p12 certificates with mTLS: both the server and the client must present the correct certificate. Add the parameter '-mtls'. See the README.md for more info.
|
|
17
|
+
- [frontend]: Improved test units on Frontend class (total coverage 98%).
|
|
18
|
+
|
|
15
19
|
### Changed
|
|
16
20
|
|
|
17
21
|
- [package]: Updated dependencies.
|
|
18
|
-
- [bin]: Updated matterbridge bin.
|
|
19
22
|
- [network]: Refactor network logging to improve clarity and update logging format.
|
|
20
23
|
|
|
21
24
|
### Fixed
|
|
22
25
|
|
|
26
|
+
- [bin]: Updated matterbridge bin.
|
|
27
|
+
|
|
23
28
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
24
29
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
25
30
|
</a>
|
package/README.md
CHANGED
|
@@ -456,7 +456,7 @@ This will reset the internal storages. All commissioning informations will be lo
|
|
|
456
456
|
|
|
457
457
|
## How to enable HTTPS for the frontend
|
|
458
458
|
|
|
459
|
-
### Provide your own
|
|
459
|
+
### Provide your own standard certificate, key and ca (optional)
|
|
460
460
|
|
|
461
461
|
Place your own certificates in the `.matterbridge/cert` directory:
|
|
462
462
|
|
|
@@ -466,14 +466,35 @@ Place your own certificates in the `.matterbridge/cert` directory:
|
|
|
466
466
|
|
|
467
467
|

|
|
468
468
|
|
|
469
|
+
Matterbridge looks first for .p12 certificate and if it is not found it looks for cert.pem and key.pem.
|
|
470
|
+
|
|
471
|
+
### Provide your own 'PKCS#12' certificate and the passphrase
|
|
472
|
+
|
|
473
|
+
Place your own p12 certificate (binary file) and the passphrase (text file) in the `.matterbridge/cert` directory:
|
|
474
|
+
|
|
475
|
+
- `cert.p12`
|
|
476
|
+
- `cert.pass`
|
|
477
|
+
|
|
478
|
+
Matterbridge looks first for .p12 certificate and if it is not found it looks for cert.pem and key.pem.
|
|
479
|
+
|
|
469
480
|
### Change the command line
|
|
470
481
|
|
|
471
|
-
Add the **-ssl** parameter to the command line.
|
|
482
|
+
Add the **-ssl** parameter to the command line.
|
|
483
|
+
|
|
484
|
+
If desired, you can also change the frontend port with **-frontend 443**.
|
|
472
485
|
|
|
473
486
|
```bash
|
|
474
487
|
matterbridge -ssl -frontend 443
|
|
475
488
|
```
|
|
476
489
|
|
|
490
|
+
Add the **-mtls** parameter to the command line if you want Matterbridge to request the client (your browser) to authenticate itself (this is the most secure connection possible).
|
|
491
|
+
|
|
492
|
+
The browser must provide the client certificate: on Windows you need to import it in Current User → Personal → Certificates with certmgr.msc.
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
matterbridge -ssl -mtls -frontend 443
|
|
496
|
+
```
|
|
497
|
+
|
|
477
498
|
### Restart
|
|
478
499
|
|
|
479
500
|
If the certificate are correctly configured, you will be able to connect with https to the frontend.
|
|
@@ -498,6 +519,8 @@ Then, from the dots menu in the frontend, download the `matterbridge.log` and `m
|
|
|
498
519
|
|
|
499
520
|

|
|
500
521
|
|
|
522
|
+
Don't forget to unselect the debug mode when is no more needed. The network traffic and cpu usage is very high in debug mode.
|
|
523
|
+
|
|
501
524
|
# Known general issues
|
|
502
525
|
|
|
503
526
|
## Session XYZ does not exist or Cannot find a session for ID XYZ
|
package/dist/frontend.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createServer } from 'node:http';
|
|
|
2
2
|
import https from 'node:https';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { promises as fs } from 'node:fs';
|
|
5
|
+
import { existsSync, promises as fs } from 'node:fs';
|
|
6
6
|
import EventEmitter from 'node:events';
|
|
7
7
|
import express from 'express';
|
|
8
8
|
import WebSocket, { WebSocketServer } from 'ws';
|
|
@@ -30,7 +30,6 @@ export class Frontend extends EventEmitter {
|
|
|
30
30
|
matterbridge;
|
|
31
31
|
log;
|
|
32
32
|
port = 8283;
|
|
33
|
-
initializeError = false;
|
|
34
33
|
expressApp;
|
|
35
34
|
httpServer;
|
|
36
35
|
httpsServer;
|
|
@@ -53,6 +52,7 @@ export class Frontend extends EventEmitter {
|
|
|
53
52
|
this.expressApp.use(express.static(path.join(this.matterbridge.rootDirectory, 'frontend/build')));
|
|
54
53
|
if (!hasParameter('ssl')) {
|
|
55
54
|
try {
|
|
55
|
+
this.log.debug(`Creating HTTP server...`);
|
|
56
56
|
this.httpServer = createServer(this.expressApp);
|
|
57
57
|
}
|
|
58
58
|
catch (error) {
|
|
@@ -85,43 +85,76 @@ export class Frontend extends EventEmitter {
|
|
|
85
85
|
this.log.error(`Port ${this.port} is already in use`);
|
|
86
86
|
break;
|
|
87
87
|
}
|
|
88
|
-
this.initializeError = true;
|
|
89
88
|
this.emit('server_error', error);
|
|
90
89
|
return;
|
|
91
90
|
});
|
|
92
91
|
}
|
|
93
92
|
else {
|
|
94
93
|
let cert;
|
|
95
|
-
try {
|
|
96
|
-
cert = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem'), 'utf8');
|
|
97
|
-
this.log.info(`Loaded certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem')}`);
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
this.log.error(`Error reading certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem')}: ${error}`);
|
|
101
|
-
this.emit('server_error', error);
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
94
|
let key;
|
|
105
|
-
try {
|
|
106
|
-
key = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/key.pem'), 'utf8');
|
|
107
|
-
this.log.info(`Loaded key file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/key.pem')}`);
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
this.log.error(`Error reading key file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/key.pem')}: ${error}`);
|
|
111
|
-
this.emit('server_error', error);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
95
|
let ca;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
96
|
+
let fullChain;
|
|
97
|
+
let pfx;
|
|
98
|
+
let passphrase;
|
|
99
|
+
let httpsServerOptions = {};
|
|
100
|
+
if (existsSync(path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.p12'))) {
|
|
101
|
+
try {
|
|
102
|
+
pfx = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.p12'));
|
|
103
|
+
this.log.info(`Loaded p12 certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.p12')}`);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
this.log.error(`Error reading p12 certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.p12')}: ${error}`);
|
|
107
|
+
this.emit('server_error', error);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
passphrase = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pass'), 'utf8');
|
|
112
|
+
passphrase = passphrase.trim();
|
|
113
|
+
this.log.info(`Loaded p12 passphrase file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pass')}`);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
this.log.error(`Error reading p12 passphrase file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pass')}: ${error}`);
|
|
117
|
+
this.emit('server_error', error);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
httpsServerOptions = { pfx, passphrase };
|
|
118
121
|
}
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
else {
|
|
123
|
+
try {
|
|
124
|
+
cert = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem'), 'utf8');
|
|
125
|
+
this.log.info(`Loaded certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem')}`);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
this.log.error(`Error reading certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/cert.pem')}: ${error}`);
|
|
129
|
+
this.emit('server_error', error);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
key = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/key.pem'), 'utf8');
|
|
134
|
+
this.log.info(`Loaded key file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/key.pem')}`);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
this.log.error(`Error reading key file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/key.pem')}: ${error}`);
|
|
138
|
+
this.emit('server_error', error);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
ca = await fs.readFile(path.join(this.matterbridge.matterbridgeDirectory, 'certs/ca.pem'), 'utf8');
|
|
143
|
+
fullChain = `${cert}\n${ca}`;
|
|
144
|
+
this.log.info(`Loaded CA certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/ca.pem')}`);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
this.log.info(`CA certificate file ${path.join(this.matterbridge.matterbridgeDirectory, 'certs/ca.pem')} not loaded: ${error}`);
|
|
148
|
+
}
|
|
149
|
+
httpsServerOptions = { cert: fullChain ?? cert, key, ca };
|
|
150
|
+
}
|
|
151
|
+
if (hasParameter('mtls')) {
|
|
152
|
+
httpsServerOptions.requestCert = true;
|
|
153
|
+
httpsServerOptions.rejectUnauthorized = true;
|
|
121
154
|
}
|
|
122
|
-
const serverOptions = { cert, key, ca };
|
|
123
155
|
try {
|
|
124
|
-
this.
|
|
156
|
+
this.log.debug(`Creating HTTPS server...`);
|
|
157
|
+
this.httpsServer = https.createServer(httpsServerOptions, this.expressApp);
|
|
125
158
|
}
|
|
126
159
|
catch (error) {
|
|
127
160
|
this.log.error(`Failed to create HTTPS server: ${error}`);
|
|
@@ -153,15 +186,13 @@ export class Frontend extends EventEmitter {
|
|
|
153
186
|
this.log.error(`Port ${this.port} is already in use`);
|
|
154
187
|
break;
|
|
155
188
|
}
|
|
156
|
-
this.initializeError = true;
|
|
157
189
|
this.emit('server_error', error);
|
|
158
190
|
return;
|
|
159
191
|
});
|
|
160
192
|
}
|
|
161
|
-
if (this.initializeError)
|
|
162
|
-
return;
|
|
163
193
|
const wssPort = this.port;
|
|
164
194
|
const wssHost = hasParameter('ssl') ? `wss://${this.matterbridge.systemInformation.ipv4Address}:${wssPort}` : `ws://${this.matterbridge.systemInformation.ipv4Address}:${wssPort}`;
|
|
195
|
+
this.log.debug(`Creating WebSocketServer on host ${CYAN}${wssHost}${db}...`);
|
|
165
196
|
this.webSocketServer = new WebSocketServer(hasParameter('ssl') ? { server: this.httpsServer } : { server: this.httpServer });
|
|
166
197
|
this.webSocketServer.on('connection', (ws, request) => {
|
|
167
198
|
const clientIp = request.socket.remoteAddress;
|
|
@@ -492,6 +523,7 @@ export class Frontend extends EventEmitter {
|
|
|
492
523
|
}
|
|
493
524
|
else {
|
|
494
525
|
this.log.debug('WebSocket server closed successfully');
|
|
526
|
+
this.emit('websocket_server_stopped');
|
|
495
527
|
}
|
|
496
528
|
resolve();
|
|
497
529
|
});
|
|
@@ -508,6 +540,7 @@ export class Frontend extends EventEmitter {
|
|
|
508
540
|
}
|
|
509
541
|
else {
|
|
510
542
|
this.log.debug('Http server closed successfully');
|
|
543
|
+
this.emit('server_stopped');
|
|
511
544
|
}
|
|
512
545
|
resolve();
|
|
513
546
|
});
|
|
@@ -525,6 +558,7 @@ export class Frontend extends EventEmitter {
|
|
|
525
558
|
}
|
|
526
559
|
else {
|
|
527
560
|
this.log.debug('Https server closed successfully');
|
|
561
|
+
this.emit('server_stopped');
|
|
528
562
|
}
|
|
529
563
|
resolve();
|
|
530
564
|
});
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge",
|
|
3
|
-
"version": "3.1.4-dev-
|
|
3
|
+
"version": "3.1.4-dev-20250717-d36e252",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge",
|
|
9
|
-
"version": "3.1.4-dev-
|
|
9
|
+
"version": "3.1.4-dev-20250717-d36e252",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@matter/main": "0.15.1",
|
package/package.json
CHANGED