smart-home-engine 1.53.3 → 1.53.4
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/dist/web/assets/{index-BsO7OQRT.css → index-Cp--IWao.css} +1 -1
- package/dist/web/assets/index-DPRtP55L.js +298 -0
- package/dist/web/assets/{tsMode-CWVhEJ2t.js → tsMode-Ci4l56iF.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/src/matter/controller.js +93 -3
- package/dist/web/assets/index-D2gZU7ce.js +0 -298
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{m as O}from"./monaco-langs-DKJI_o9J.js";import{t as I}from"./index-
|
|
1
|
+
import{m as O}from"./monaco-langs-DKJI_o9J.js";import{t as I}from"./index-DPRtP55L.js";/*!-----------------------------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
|
|
4
4
|
* Released under the MIT license
|
package/dist/web/index.html
CHANGED
|
@@ -175,10 +175,10 @@
|
|
|
175
175
|
}
|
|
176
176
|
})();
|
|
177
177
|
</script>
|
|
178
|
-
<script type="module" crossorigin src="/assets/index-
|
|
178
|
+
<script type="module" crossorigin src="/assets/index-DPRtP55L.js"></script>
|
|
179
179
|
<link rel="modulepreload" crossorigin href="/assets/monaco-langs-DKJI_o9J.js">
|
|
180
180
|
<link rel="stylesheet" crossorigin href="/assets/monaco-langs-DyX1CsEw.css">
|
|
181
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
181
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Cp--IWao.css">
|
|
182
182
|
</head>
|
|
183
183
|
<body>
|
|
184
184
|
<div id="app"></div>
|
package/package.json
CHANGED
package/src/matter/controller.js
CHANGED
|
@@ -81,9 +81,15 @@ function _resolveEndpoint(node, endpointIdOrName) {
|
|
|
81
81
|
throw new Error(`Endpoint not found: ${endpointIdOrName}`);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Recursively convert values so the result is JSON-serialisable: BigInt to a number (or a string
|
|
86
|
+
* beyond 2^53), byte arrays to `{ $bytes: "<hex>" }` — JSON.stringify would turn a Uint8Array into
|
|
87
|
+
* an object of numbered keys, which the UI cannot tell from a struct.
|
|
88
|
+
*/
|
|
85
89
|
function _jsonSafe(v) {
|
|
86
90
|
if (typeof v === 'bigint') return v <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(v) : v.toString();
|
|
91
|
+
if (ArrayBuffer.isView(v)) return { $bytes: Buffer.from(v.buffer, v.byteOffset, v.byteLength).toString('hex') };
|
|
92
|
+
if (v instanceof ArrayBuffer) return { $bytes: Buffer.from(v).toString('hex') };
|
|
87
93
|
if (Array.isArray(v)) return v.map(_jsonSafe);
|
|
88
94
|
if (v !== null && typeof v === 'object') {
|
|
89
95
|
const out = {};
|
|
@@ -448,7 +454,7 @@ function getEndpoints(nodeId) {
|
|
|
448
454
|
const attrs = {};
|
|
449
455
|
if (clusterState && typeof clusterState === 'object') {
|
|
450
456
|
for (const [k, v] of Object.entries(clusterState)) {
|
|
451
|
-
attrs[k] =
|
|
457
|
+
attrs[k] = _attrValue(clusterName, k, v);
|
|
452
458
|
}
|
|
453
459
|
}
|
|
454
460
|
clusters.push({ name: clusterName, attrs });
|
|
@@ -638,6 +644,88 @@ async function sendCommand(nodeId, endpointId, clusterName, commandName, args) {
|
|
|
638
644
|
* @param {object} node ClientNode
|
|
639
645
|
* @param {string} nodeId decimal string
|
|
640
646
|
*/
|
|
647
|
+
/** Matter's attribute OIDs (1.3.6.1.4.1.37244.1.x, Matter core spec 6.5.6.1) by name. */
|
|
648
|
+
const MATTER_DN_OIDS = {
|
|
649
|
+
'1.3.6.1.4.1.37244.1.1': 'matter-node-id',
|
|
650
|
+
'1.3.6.1.4.1.37244.1.2': 'matter-firmware-signing-id',
|
|
651
|
+
'1.3.6.1.4.1.37244.1.3': 'matter-icac-id',
|
|
652
|
+
'1.3.6.1.4.1.37244.1.4': 'matter-rcac-id',
|
|
653
|
+
'1.3.6.1.4.1.37244.1.5': 'matter-fabric-id',
|
|
654
|
+
'1.3.6.1.4.1.37244.1.6': 'matter-noc-cat',
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
/** node's X509Certificate distinguished name ("oid=value\n…") with Matter's OIDs named */
|
|
658
|
+
function _matterDn(dn) {
|
|
659
|
+
return String(dn || '')
|
|
660
|
+
.split('\n')
|
|
661
|
+
.filter(Boolean)
|
|
662
|
+
.map((part) => {
|
|
663
|
+
const eq = part.indexOf('=');
|
|
664
|
+
const key = part.slice(0, eq);
|
|
665
|
+
return `${MATTER_DN_OIDS[key] || key}=${part.slice(eq + 1)}`;
|
|
666
|
+
})
|
|
667
|
+
.join(', ');
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* A Matter operational certificate (TLV, as the OperationalCredentials cluster holds it) as
|
|
672
|
+
* `{ $cert: { kind, subject, validFrom, validTo, fingerprint, pem } }`: converted to X.509 DER by
|
|
673
|
+
* matter.js, read back by node's X509Certificate. Anything that does not convert stays `$bytes`.
|
|
674
|
+
*/
|
|
675
|
+
function _certValue(kind, bytes) {
|
|
676
|
+
if (!ArrayBuffer.isView(bytes)) return _jsonSafe(bytes);
|
|
677
|
+
try {
|
|
678
|
+
const { Noc, Icac, Rcac } = require('@matter/protocol');
|
|
679
|
+
const cert = { NOC: Noc, ICAC: Icac, RCAC: Rcac }[kind].fromTlv(bytes);
|
|
680
|
+
const der = Buffer.from(cert.asSignedDer());
|
|
681
|
+
const x509 = new (require('crypto').X509Certificate)(der);
|
|
682
|
+
const lines = der
|
|
683
|
+
.toString('base64')
|
|
684
|
+
.match(/.{1,64}/g)
|
|
685
|
+
.join('\n');
|
|
686
|
+
return {
|
|
687
|
+
$cert: {
|
|
688
|
+
kind,
|
|
689
|
+
// Matter's own fields (nodeId, fabricId, rcacId, icacId, caseAuthenticatedTags …)
|
|
690
|
+
subject: _jsonSafe(cert.cert.subject),
|
|
691
|
+
issuer: _jsonSafe(cert.cert.issuer),
|
|
692
|
+
// the same as X.509 distinguished names, with Matter's OIDs named
|
|
693
|
+
subjectDn: _matterDn(x509.subject),
|
|
694
|
+
issuerDn: _matterDn(x509.issuer),
|
|
695
|
+
serialNumber: x509.serialNumber,
|
|
696
|
+
validFrom: new Date(x509.validFrom).toISOString(),
|
|
697
|
+
validTo: new Date(x509.validTo).toISOString(),
|
|
698
|
+
ca: x509.ca,
|
|
699
|
+
// key usage, extended key usage, basic constraints, key identifiers — all the
|
|
700
|
+
// certificate carries; Matter operational certificates have no CRL distribution point
|
|
701
|
+
extensions: _jsonSafe(cert.cert.extensions),
|
|
702
|
+
fingerprint: x509.fingerprint256,
|
|
703
|
+
pem: `-----BEGIN CERTIFICATE-----\n${lines}\n-----END CERTIFICATE-----`,
|
|
704
|
+
},
|
|
705
|
+
};
|
|
706
|
+
} catch {
|
|
707
|
+
return _jsonSafe(bytes);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/** An attribute value for the UI and the REST API: certificates as PEM, the rest via _jsonSafe. */
|
|
712
|
+
function _attrValue(clusterName, attrName, value) {
|
|
713
|
+
if (clusterName === 'operationalCredentials') {
|
|
714
|
+
if (attrName === 'nocs' && Array.isArray(value)) {
|
|
715
|
+
return value.map((entry) => {
|
|
716
|
+
const out = _jsonSafe(entry);
|
|
717
|
+
if (entry?.noc) out.noc = _certValue('NOC', entry.noc);
|
|
718
|
+
if (entry?.icac) out.icac = _certValue('ICAC', entry.icac);
|
|
719
|
+
return out;
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
if (attrName === 'trustedRootCertificates' && Array.isArray(value)) {
|
|
723
|
+
return value.map((root) => _certValue('RCAC', root));
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
return _jsonSafe(value);
|
|
727
|
+
}
|
|
728
|
+
|
|
641
729
|
function _broadcastNodeAttributes(node, nodeId) {
|
|
642
730
|
if (!_broadcast) return;
|
|
643
731
|
if (_attrBroadcastNodes.has(nodeId)) return;
|
|
@@ -664,7 +752,7 @@ function _broadcastNodeAttributes(node, nodeId) {
|
|
|
664
752
|
endpointId,
|
|
665
753
|
clusterName,
|
|
666
754
|
attrName,
|
|
667
|
-
value:
|
|
755
|
+
value: _attrValue(clusterName, attrName, value),
|
|
668
756
|
ts: Date.now(),
|
|
669
757
|
});
|
|
670
758
|
// Device/endpoint labels feed the device list — rebroadcast it
|
|
@@ -806,6 +894,8 @@ function isStarted() {
|
|
|
806
894
|
}
|
|
807
895
|
|
|
808
896
|
module.exports = {
|
|
897
|
+
// for the unit tests: the value conversion, without a running controller
|
|
898
|
+
_attrValue,
|
|
809
899
|
init,
|
|
810
900
|
close,
|
|
811
901
|
isStarted,
|