@matter-server/dashboard 1.0.0 → 1.1.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/dist/esm/components/dialogs/acl/acl-actions.d.ts +12 -0
- package/dist/esm/components/dialogs/acl/acl-actions.d.ts.map +1 -0
- package/dist/esm/components/dialogs/acl/acl-actions.js +56 -0
- package/dist/esm/components/dialogs/acl/acl-actions.js.map +6 -0
- package/dist/esm/components/dialogs/acl/model.d.ts +2 -2
- package/dist/esm/components/dialogs/acl/model.d.ts.map +1 -1
- package/dist/esm/components/dialogs/acl/model.js +11 -15
- package/dist/esm/components/dialogs/acl/model.js.map +1 -1
- package/dist/esm/components/dialogs/acl/node-acl-add-dialog.d.ts +43 -0
- package/dist/esm/components/dialogs/acl/node-acl-add-dialog.d.ts.map +1 -0
- package/dist/esm/components/dialogs/acl/node-acl-add-dialog.js +353 -0
- package/dist/esm/components/dialogs/acl/node-acl-add-dialog.js.map +6 -0
- package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.d.ts +8 -0
- package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.d.ts.map +1 -0
- package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.js +15 -0
- package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.js.map +6 -0
- package/dist/esm/components/dialogs/binding/binding-actions.d.ts +17 -0
- package/dist/esm/components/dialogs/binding/binding-actions.d.ts.map +1 -0
- package/dist/esm/components/dialogs/binding/binding-actions.js +135 -0
- package/dist/esm/components/dialogs/binding/binding-actions.js.map +6 -0
- package/dist/esm/components/dialogs/binding/model.d.ts +1 -1
- package/dist/esm/components/dialogs/binding/model.d.ts.map +1 -1
- package/dist/esm/components/dialogs/binding/model.js +8 -3
- package/dist/esm/components/dialogs/binding/model.js.map +1 -1
- package/dist/esm/components/dialogs/binding/node-binding-dialog.d.ts +16 -24
- package/dist/esm/components/dialogs/binding/node-binding-dialog.d.ts.map +1 -1
- package/dist/esm/components/dialogs/binding/node-binding-dialog.js +210 -332
- package/dist/esm/components/dialogs/binding/node-binding-dialog.js.map +1 -1
- package/dist/esm/pages/cluster-commands/clusters/access-control-commands.d.ts +37 -0
- package/dist/esm/pages/cluster-commands/clusters/access-control-commands.d.ts.map +1 -0
- package/dist/esm/pages/cluster-commands/clusters/access-control-commands.js +387 -0
- package/dist/esm/pages/cluster-commands/clusters/access-control-commands.js.map +6 -0
- package/dist/esm/pages/cluster-commands/clusters/binding-commands.d.ts +35 -0
- package/dist/esm/pages/cluster-commands/clusters/binding-commands.d.ts.map +1 -0
- package/dist/esm/pages/cluster-commands/clusters/binding-commands.js +254 -0
- package/dist/esm/pages/cluster-commands/clusters/binding-commands.js.map +6 -0
- package/dist/esm/pages/cluster-commands/index.d.ts +2 -0
- package/dist/esm/pages/cluster-commands/index.d.ts.map +1 -1
- package/dist/esm/pages/cluster-commands/index.js +2 -0
- package/dist/esm/pages/cluster-commands/index.js.map +1 -1
- package/dist/esm/pages/components/node-details.d.ts +0 -1
- package/dist/esm/pages/components/node-details.d.ts.map +1 -1
- package/dist/esm/pages/components/node-details.js +2 -18
- package/dist/esm/pages/components/node-details.js.map +1 -1
- package/dist/esm/pages/components/server-details.js +3 -3
- package/dist/esm/pages/components/server-details.js.map +1 -1
- package/dist/esm/pages/matter-cluster-view.d.ts.map +1 -1
- package/dist/esm/pages/matter-cluster-view.js +2 -1
- package/dist/esm/pages/matter-cluster-view.js.map +1 -1
- package/dist/esm/pages/matter-endpoint-view.d.ts +3 -3
- package/dist/esm/pages/matter-endpoint-view.d.ts.map +1 -1
- package/dist/esm/pages/matter-endpoint-view.js +13 -10
- package/dist/esm/pages/matter-endpoint-view.js.map +1 -1
- package/dist/esm/pages/matter-node-view.js +2 -2
- package/dist/esm/pages/matter-node-view.js.map +1 -1
- package/dist/esm/pages/network/network-utils.d.ts +1 -5
- package/dist/esm/pages/network/network-utils.d.ts.map +1 -1
- package/dist/esm/pages/network/network-utils.js +1 -11
- package/dist/esm/pages/network/network-utils.js.map +1 -1
- package/dist/esm/util/access-control.d.ts +54 -0
- package/dist/esm/util/access-control.d.ts.map +1 -0
- package/dist/esm/util/access-control.js +100 -0
- package/dist/esm/util/access-control.js.map +6 -0
- package/dist/esm/util/binding.d.ts +54 -0
- package/dist/esm/util/binding.d.ts.map +1 -0
- package/dist/esm/util/binding.js +113 -0
- package/dist/esm/util/binding.js.map +6 -0
- package/dist/esm/util/endpoints.d.ts +9 -0
- package/dist/esm/util/endpoints.d.ts.map +1 -0
- package/dist/esm/util/endpoints.js +18 -0
- package/dist/esm/util/endpoints.js.map +6 -0
- package/dist/esm/util/node-name.d.ts +12 -0
- package/dist/esm/util/node-name.d.ts.map +1 -0
- package/dist/esm/util/node-name.js +15 -0
- package/dist/esm/util/node-name.js.map +6 -0
- package/dist/web/js/{attribute-write-dialog-W7xpCE2E.js → attribute-write-dialog-CqqdRniU.js} +1 -1
- package/dist/web/js/{command-invoke-dialog-BAqAAdJw.js → command-invoke-dialog-BuvBOrdC.js} +1 -1
- package/dist/web/js/{commission-node-dialog-BTzCGgdy.js → commission-node-dialog-nVZp3go0.js} +5 -5
- package/dist/web/js/{commission-node-existing-B2M2hyDh.js → commission-node-existing-Cx3Ahk2t.js} +2 -2
- package/dist/web/js/{commission-node-thread-djdz2dXW.js → commission-node-thread-CI8mWWPs.js} +2 -2
- package/dist/web/js/{commission-node-wifi-DxAYNS1A.js → commission-node-wifi-lUX4LK2R.js} +2 -2
- package/dist/web/js/{dialog-box-tHvPVxDN.js → dialog-box-bAdbnf-T.js} +1 -1
- package/dist/web/js/{fire_event-BleYfTLc.js → fire_event-tWhqPfdz.js} +1 -1
- package/dist/web/js/main.js +1 -1
- package/dist/web/js/{matter-dashboard-app-CVi_GDky.js → matter-dashboard-app-CONA_608.js} +1485 -390
- package/dist/web/js/node-acl-add-dialog-DlR-sF-b.js +320 -0
- package/dist/web/js/node-binding-dialog-DhnX_86M.js +267 -0
- package/dist/web/js/{node-label-dialog-DVZSjsXU.js → node-label-dialog-T3nPG-Qy.js} +1 -1
- package/dist/web/js/{settings-dialog-BG5MgZcO.js → settings-dialog-DrHzJtsi.js} +1 -1
- package/package.json +4 -4
- package/src/components/dialogs/acl/acl-actions.ts +71 -0
- package/src/components/dialogs/acl/model.ts +18 -17
- package/src/components/dialogs/acl/node-acl-add-dialog.ts +350 -0
- package/src/components/dialogs/acl/show-node-acl-add-dialog.ts +14 -0
- package/src/components/dialogs/binding/binding-actions.ts +201 -0
- package/src/components/dialogs/binding/model.ts +11 -4
- package/src/components/dialogs/binding/node-binding-dialog.ts +221 -399
- package/src/pages/cluster-commands/clusters/access-control-commands.ts +407 -0
- package/src/pages/cluster-commands/clusters/binding-commands.ts +273 -0
- package/src/pages/cluster-commands/index.ts +2 -0
- package/src/pages/components/node-details.ts +2 -21
- package/src/pages/components/server-details.ts +3 -3
- package/src/pages/matter-cluster-view.ts +4 -1
- package/src/pages/matter-endpoint-view.ts +16 -10
- package/src/pages/matter-node-view.ts +2 -2
- package/src/pages/network/network-utils.ts +1 -18
- package/src/util/access-control.ts +135 -0
- package/src/util/binding.ts +182 -0
- package/src/util/endpoints.ts +17 -0
- package/src/util/node-name.ts +18 -0
- package/dist/web/js/node-binding-dialog-B9IdqHrZ.js +0 -624
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { MatterClient } from "@matter-server/ws-client";
|
|
7
|
+
import { type AccessControlEntryStruct } from "./model.js";
|
|
8
|
+
export declare function addAclEntry(client: MatterClient, nodeId: number | bigint, entry: AccessControlEntryStruct): Promise<void>;
|
|
9
|
+
export declare function deleteAclEntry(client: MatterClient, nodeId: number | bigint, key: string): Promise<void>;
|
|
10
|
+
/** Downgrade the given entries (by key) to Operate privilege. */
|
|
11
|
+
export declare function downgradeToOperate(client: MatterClient, nodeId: number | bigint, keys: Set<string>): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=acl-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acl-actions.d.ts","sourceRoot":"","sources":["../../../../../src/components/dialogs/acl/acl-actions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAsB,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE5E,OAAO,EAAqC,KAAK,wBAAwB,EAAE,MAAM,YAAY,CAAC;AA8B9F,wBAAsB,WAAW,CAC7B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,KAAK,EAAE,wBAAwB,GAChC,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW9G;AAED,iEAAiE;AACjE,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAClB,OAAO,CAAC,IAAI,CAAC,CAIf"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Privilege, aclEntryKey, attributeArray, entriesForFabric } from "../../../util/access-control.js";
|
|
7
|
+
import { AccessControlEntryDataTransformer } from "./model.js";
|
|
8
|
+
function toApiAcl(e) {
|
|
9
|
+
return {
|
|
10
|
+
privilege: e.privilege,
|
|
11
|
+
auth_mode: e.authMode,
|
|
12
|
+
subjects: e.subjects ?? null,
|
|
13
|
+
targets: e.targets?.map((t) => ({
|
|
14
|
+
cluster: t.cluster ?? null,
|
|
15
|
+
endpoint: t.endpoint ?? null,
|
|
16
|
+
device_type: t.deviceType ?? null
|
|
17
|
+
})) ?? null
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async function freshOurAcl(client, nodeId) {
|
|
21
|
+
const res = await client.readAttribute(nodeId, ["0/31/0", "0/62/5"]);
|
|
22
|
+
const all = attributeArray(res["0/31/0"]).map((v) => AccessControlEntryDataTransformer.transform(v));
|
|
23
|
+
const fi = res["0/62/5"];
|
|
24
|
+
if (typeof fi !== "number") {
|
|
25
|
+
throw new Error(`Cannot determine the current fabric index (0/62/5) for node ${nodeId}`);
|
|
26
|
+
}
|
|
27
|
+
return entriesForFabric(all, fi);
|
|
28
|
+
}
|
|
29
|
+
async function addAclEntry(client, nodeId, entry) {
|
|
30
|
+
const acl = await freshOurAcl(client, nodeId);
|
|
31
|
+
acl.push(entry);
|
|
32
|
+
await client.setACLEntry(nodeId, acl.map(toApiAcl));
|
|
33
|
+
}
|
|
34
|
+
async function deleteAclEntry(client, nodeId, key) {
|
|
35
|
+
const acl = await freshOurAcl(client, nodeId);
|
|
36
|
+
let removed = false;
|
|
37
|
+
const kept = acl.filter((e) => {
|
|
38
|
+
if (!removed && aclEntryKey(e) === key) {
|
|
39
|
+
removed = true;
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
});
|
|
44
|
+
await client.setACLEntry(nodeId, kept.map(toApiAcl));
|
|
45
|
+
}
|
|
46
|
+
async function downgradeToOperate(client, nodeId, keys) {
|
|
47
|
+
const acl = await freshOurAcl(client, nodeId);
|
|
48
|
+
const updated = acl.map((e) => keys.has(aclEntryKey(e)) ? { ...e, privilege: Privilege.Operate } : e);
|
|
49
|
+
await client.setACLEntry(nodeId, updated.map(toApiAcl));
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
addAclEntry,
|
|
53
|
+
deleteAclEntry,
|
|
54
|
+
downgradeToOperate
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=acl-actions.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/dialogs/acl/acl-actions.ts"],
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAS,WAAW,aAAa,gBAAgB,wBAAwB;AACzE,SAAS,yCAAwE;AAEjF,SAAS,SAAS,GAAiD;AAC/D,SAAO;AAAA,IACH,WAAW,EAAE;AAAA,IACb,WAAW,EAAE;AAAA,IACb,UAAU,EAAE,YAAY;AAAA,IACxB,SACI,EAAE,SAAS,IAAI,QAAM;AAAA,MACjB,SAAS,EAAE,WAAW;AAAA,MACtB,UAAU,EAAE,YAAY;AAAA,MACxB,aAAa,EAAE,cAAc;AAAA,IACjC,EAAE,KAAK;AAAA,EACf;AACJ;AAMA,eAAe,YAAY,QAAsB,QAA8D;AAC3G,QAAM,MAAM,MAAM,OAAO,cAAc,QAAQ,CAAC,UAAU,QAAQ,CAAC;AACnE,QAAM,MAAM,eAAe,IAAI,QAAQ,CAAC,EAAE,IAAI,OAAK,kCAAkC,UAAU,CAAC,CAAC;AACjG,QAAM,KAAK,IAAI,QAAQ;AACvB,MAAI,OAAO,OAAO,UAAU;AACxB,UAAM,IAAI,MAAM,+DAA+D,MAAM,EAAE;AAAA,EAC3F;AACA,SAAO,iBAAiB,KAAK,EAAE;AACnC;AAEA,eAAsB,YAClB,QACA,QACA,OACa;AACb,QAAM,MAAM,MAAM,YAAY,QAAQ,MAAM;AAC5C,MAAI,KAAK,KAAK;AACd,QAAM,OAAO,YAAY,QAAQ,IAAI,IAAI,QAAQ,CAAC;AACtD;AAEA,eAAsB,eAAe,QAAsB,QAAyB,KAA4B;AAC5G,QAAM,MAAM,MAAM,YAAY,QAAQ,MAAM;AAC5C,MAAI,UAAU;AACd,QAAM,OAAO,IAAI,OAAO,OAAK;AACzB,QAAI,CAAC,WAAW,YAAY,CAAC,MAAM,KAAK;AACpC,gBAAU;AACV,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX,CAAC;AACD,QAAM,OAAO,YAAY,QAAQ,KAAK,IAAI,QAAQ,CAAC;AACvD;AAGA,eAAsB,mBAClB,QACA,QACA,MACa;AACb,QAAM,MAAM,MAAM,YAAY,QAAQ,MAAM;AAC5C,QAAM,UAAU,IAAI,IAAI,OAAM,KAAK,IAAI,YAAY,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,WAAW,UAAU,QAAQ,IAAI,CAAE;AACpG,QAAM,OAAO,YAAY,QAAQ,QAAQ,IAAI,QAAQ,CAAC;AAC1D;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -24,10 +24,10 @@ export type AccessControlEntryStruct = {
|
|
|
24
24
|
};
|
|
25
25
|
export declare class AccessControlTargetTransformer {
|
|
26
26
|
private static readonly KEY_MAPPING;
|
|
27
|
-
static transform(input:
|
|
27
|
+
static transform(input: unknown): AccessControlTargetStruct;
|
|
28
28
|
}
|
|
29
29
|
export declare class AccessControlEntryDataTransformer {
|
|
30
30
|
private static readonly KEY_MAPPING;
|
|
31
|
-
static transform(input:
|
|
31
|
+
static transform(input: unknown): AccessControlEntryStruct;
|
|
32
32
|
}
|
|
33
33
|
//# sourceMappingURL=model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../../src/components/dialogs/acl/model.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,yBAAyB,GAAG;IACpC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACzB,GAAG,EAAE,yBAAyB,EAAE,GAAG,SAAS,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC9B,OAAO,EAAE,yBAAyB,EAAE,GAAG,SAAS,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../../src/components/dialogs/acl/model.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,yBAAyB,GAAG;IACpC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACzB,GAAG,EAAE,yBAAyB,EAAE,GAAG,SAAS,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC9B,OAAO,EAAE,yBAAyB,EAAE,GAAG,SAAS,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAMF,qBAAa,8BAA8B;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAMjC;IAEF,OAAc,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CAoBjE;CACJ;AAED,qBAAa,iCAAiC;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAQjC;IAEF,OAAc,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CA6BhE;CACJ"}
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
* Copyright 2025-2026 Open Home Foundation
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === "object" && value !== null;
|
|
8
|
+
}
|
|
6
9
|
class AccessControlTargetTransformer {
|
|
7
10
|
static {
|
|
8
11
|
this.KEY_MAPPING = {
|
|
@@ -12,7 +15,7 @@ class AccessControlTargetTransformer {
|
|
|
12
15
|
};
|
|
13
16
|
}
|
|
14
17
|
static transform(input) {
|
|
15
|
-
if (!input
|
|
18
|
+
if (!isRecord(input)) {
|
|
16
19
|
throw new Error("Invalid input: expected an object");
|
|
17
20
|
}
|
|
18
21
|
const result = {};
|
|
@@ -22,8 +25,8 @@ class AccessControlTargetTransformer {
|
|
|
22
25
|
const mappedKey = keyMapping[key];
|
|
23
26
|
if (mappedKey) {
|
|
24
27
|
const value = input[key];
|
|
25
|
-
if (value
|
|
26
|
-
result[mappedKey] = value;
|
|
28
|
+
if (value == null) continue;
|
|
29
|
+
result[mappedKey] = Number(value);
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
}
|
|
@@ -41,7 +44,7 @@ class AccessControlEntryDataTransformer {
|
|
|
41
44
|
};
|
|
42
45
|
}
|
|
43
46
|
static transform(input) {
|
|
44
|
-
if (!input
|
|
47
|
+
if (!isRecord(input)) {
|
|
45
48
|
throw new Error("Invalid input: expected an object");
|
|
46
49
|
}
|
|
47
50
|
const result = {};
|
|
@@ -51,20 +54,13 @@ class AccessControlEntryDataTransformer {
|
|
|
51
54
|
const mappedKey = keyMapping[key];
|
|
52
55
|
if (mappedKey) {
|
|
53
56
|
const value = input[key];
|
|
54
|
-
if (value
|
|
57
|
+
if (value == null) continue;
|
|
55
58
|
if (mappedKey === "subjects") {
|
|
56
|
-
result
|
|
59
|
+
result.subjects = Array.isArray(value) ? value : void 0;
|
|
57
60
|
} else if (mappedKey === "targets") {
|
|
58
|
-
|
|
59
|
-
const _targets = Object.values(value).map(
|
|
60
|
-
(val) => AccessControlTargetTransformer.transform(val)
|
|
61
|
-
);
|
|
62
|
-
result[mappedKey] = _targets;
|
|
63
|
-
} else {
|
|
64
|
-
result[mappedKey] = void 0;
|
|
65
|
-
}
|
|
61
|
+
result.targets = Array.isArray(value) ? value.map((val) => AccessControlTargetTransformer.transform(val)) : void 0;
|
|
66
62
|
} else {
|
|
67
|
-
result[mappedKey] = value;
|
|
63
|
+
result[mappedKey] = Number(value);
|
|
68
64
|
}
|
|
69
65
|
}
|
|
70
66
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/dialogs/acl/model.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AA4BA,SAAS,SAAS,OAAkD;AAChE,SAAO,OAAO,UAAU,YAAY,UAAU;AAClD;AAEO,MAAM,+BAA+B;AAAA,EACxC;AAAA,SAAwB,cAEpB;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACT;AAAA;AAAA,EAEA,OAAc,UAAU,OAA2C;AAC/D,QAAI,CAAC,SAAS,KAAK,GAAG;AAClB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACvD;AAEA,UAAM,SAA6C,CAAC;AACpD,UAAM,aAAa,+BAA+B;AAElD,eAAW,OAAO,OAAO;AACrB,UAAI,OAAO,YAAY;AACnB,cAAM,YAAY,WAAW,GAAG;AAChC,YAAI,WAAW;AACX,gBAAM,QAAQ,MAAM,GAAG;AAEvB,cAAI,SAAS,KAAM;AACnB,iBAAO,SAAS,IAAI,OAAO,KAAK;AAAA,QACpC;AAAA,MACJ;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AACJ;AAEO,MAAM,kCAAkC;AAAA,EAC3C;AAAA,SAAwB,cAEpB;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,OAAO;AAAA,IACX;AAAA;AAAA,EAEA,OAAc,UAAU,OAA0C;AAC9D,QAAI,CAAC,SAAS,KAAK,GAAG;AAClB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACvD;AAEA,UAAM,SAA4C,CAAC;AACnD,UAAM,aAAa,kCAAkC;AAErD,eAAW,OAAO,OAAO;AACrB,UAAI,OAAO,YAAY;AACnB,cAAM,YAAY,WAAW,GAAG;AAChC,YAAI,WAAW;AACX,gBAAM,QAAQ,MAAM,GAAG;AACvB,cAAI,SAAS,KAAM;AACnB,cAAI,cAAc,YAAY;AAC1B,mBAAO,WAAW,MAAM,QAAQ,KAAK,IAAI,QAAQ;AAAA,UACrD,WAAW,cAAc,WAAW;AAChC,mBAAO,UAAU,MAAM,QAAQ,KAAK,IAC9B,MAAM,IAAI,SAAO,+BAA+B,UAAU,GAAG,CAAC,IAC9D;AAAA,UACV,OAAO;AAEH,mBAAO,SAAS,IAAI,OAAO,KAAK;AAAA,UACpC;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AACJ;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import "@material/web/button/text-button";
|
|
7
|
+
import "@material/web/dialog/dialog";
|
|
8
|
+
import "@material/web/select/outlined-select";
|
|
9
|
+
import "@material/web/select/select-option";
|
|
10
|
+
import "@material/web/textfield/outlined-text-field";
|
|
11
|
+
import { MatterClient, MatterNode } from "@matter-server/ws-client";
|
|
12
|
+
import { LitElement } from "lit";
|
|
13
|
+
import "../../../components/ha-svg-icon.js";
|
|
14
|
+
export declare class NodeAclAddDialog extends LitElement {
|
|
15
|
+
client: MatterClient;
|
|
16
|
+
node: MatterNode;
|
|
17
|
+
private _privilege;
|
|
18
|
+
private _subjects;
|
|
19
|
+
private _subjectInput;
|
|
20
|
+
private _targets;
|
|
21
|
+
private _targetEndpoint;
|
|
22
|
+
private _targetCluster;
|
|
23
|
+
private _busy;
|
|
24
|
+
private _knownNodes;
|
|
25
|
+
private _addSubject;
|
|
26
|
+
private _removeSubject;
|
|
27
|
+
private _nodeEndpoints;
|
|
28
|
+
private _clusterOptions;
|
|
29
|
+
private _clusterLabel;
|
|
30
|
+
private _addTarget;
|
|
31
|
+
private _removeTarget;
|
|
32
|
+
private _save;
|
|
33
|
+
private _close;
|
|
34
|
+
private _handleClosed;
|
|
35
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
36
|
+
static styles: import("lit").CSSResult;
|
|
37
|
+
}
|
|
38
|
+
declare global {
|
|
39
|
+
interface HTMLElementTagNameMap {
|
|
40
|
+
"node-acl-add-dialog": NodeAclAddDialog;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=node-acl-add-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-acl-add-dialog.d.ts","sourceRoot":"","sources":["../../../../../src/components/dialogs/acl/node-acl-add-dialog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kCAAkC,CAAC;AAC1C,OAAO,6BAA6B,CAAC;AACrC,OAAO,sCAAsC,CAAC;AAC9C,OAAO,oCAAoC,CAAC;AAC5C,OAAO,6CAA6C,CAAC;AAGrD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAE5C,OAAO,oCAAoC,CAAC;AAY5C,qBACa,gBAAiB,SAAQ,UAAU;IAGrC,MAAM,EAAG,YAAY,CAAC;IAGtB,IAAI,EAAG,UAAU,CAAC;IAEhB,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,KAAK,CAAS;IAE/B,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,UAAU;IAsBlB,OAAO,CAAC,aAAa;YAIP,KAAK;IA0BnB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,aAAa;IAIrB,UAAmB,MAAM,yCAwIxB;IAED,OAAgB,MAAM,0BAiDpB;CACL;AAED,OAAO,CAAC,MAAM,CAAC,CAAC;IACZ,UAAU,qBAAqB;QAC3B,qBAAqB,EAAE,gBAAgB,CAAC;KAC3C;CACJ"}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* @license
|
|
13
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
14
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
15
|
+
*/
|
|
16
|
+
import "@material/web/button/text-button";
|
|
17
|
+
import "@material/web/dialog/dialog";
|
|
18
|
+
import "@material/web/select/outlined-select";
|
|
19
|
+
import "@material/web/select/select-option";
|
|
20
|
+
import "@material/web/textfield/outlined-text-field";
|
|
21
|
+
import { consume } from "@lit/context";
|
|
22
|
+
import { mdiClose } from "@mdi/js";
|
|
23
|
+
import { css, html, LitElement } from "lit";
|
|
24
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
25
|
+
import "../../../components/ha-svg-icon.js";
|
|
26
|
+
import { clientContext } from "../../../client/client-context.js";
|
|
27
|
+
import { clusters } from "../../../client/models/descriptions.js";
|
|
28
|
+
import { AuthMode, Privilege, PRIVILEGE_NAMES, aclCapacity, nodeIdKey } from "../../../util/access-control.js";
|
|
29
|
+
import { handleAsync } from "../../../util/async-handler.js";
|
|
30
|
+
import { targetServerClusters } from "../../../util/binding.js";
|
|
31
|
+
import { getDeviceName } from "../../../util/node-name.js";
|
|
32
|
+
import { preventDefault } from "../../../util/prevent_default.js";
|
|
33
|
+
import { showAlertDialog } from "../../dialog-box/show-dialog-box.js";
|
|
34
|
+
import { addAclEntry } from "./acl-actions.js";
|
|
35
|
+
let NodeAclAddDialog = class extends LitElement {
|
|
36
|
+
constructor() {
|
|
37
|
+
super(...arguments);
|
|
38
|
+
this._privilege = Privilege.Operate;
|
|
39
|
+
this._subjects = new Array();
|
|
40
|
+
this._subjectInput = "";
|
|
41
|
+
this._targets = new Array();
|
|
42
|
+
this._targetEndpoint = "all";
|
|
43
|
+
this._targetCluster = "";
|
|
44
|
+
this._busy = false;
|
|
45
|
+
}
|
|
46
|
+
_knownNodes() {
|
|
47
|
+
return Object.values(this.client.nodes).sort((a, b) => {
|
|
48
|
+
const x = BigInt(a.node_id);
|
|
49
|
+
const y = BigInt(b.node_id);
|
|
50
|
+
return x < y ? -1 : x > y ? 1 : 0;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
_addSubject(raw) {
|
|
54
|
+
const value = raw.trim();
|
|
55
|
+
if (!/^\d+$/.test(value)) return;
|
|
56
|
+
const id = BigInt(value);
|
|
57
|
+
const key = nodeIdKey(id);
|
|
58
|
+
if (this._subjects.some((s) => nodeIdKey(s) === key)) return;
|
|
59
|
+
const max = aclCapacity(this.node).subjectsMax;
|
|
60
|
+
if (max > 0 && this._subjects.length >= max) {
|
|
61
|
+
void showAlertDialog({ title: "Limit reached", text: `At most ${max} subjects per entry.` });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this._subjects = [...this._subjects, id];
|
|
65
|
+
this._subjectInput = "";
|
|
66
|
+
}
|
|
67
|
+
_removeSubject(key) {
|
|
68
|
+
this._subjects = this._subjects.filter((s) => nodeIdKey(s) !== key);
|
|
69
|
+
}
|
|
70
|
+
_nodeEndpoints() {
|
|
71
|
+
const eps = /* @__PURE__ */ new Set();
|
|
72
|
+
for (const key of Object.keys(this.node.attributes)) {
|
|
73
|
+
const m = /^(\d+)\/29\/0$/.exec(key);
|
|
74
|
+
if (m) eps.add(Number(m[1]));
|
|
75
|
+
}
|
|
76
|
+
return Array.from(eps).sort((a, b) => a - b);
|
|
77
|
+
}
|
|
78
|
+
_clusterOptions() {
|
|
79
|
+
if (this._targetEndpoint === "all") {
|
|
80
|
+
const all = /* @__PURE__ */ new Set();
|
|
81
|
+
for (const ep of this._nodeEndpoints()) targetServerClusters(this.node, ep).forEach((c) => all.add(c));
|
|
82
|
+
return Array.from(all).sort((a, b) => a - b);
|
|
83
|
+
}
|
|
84
|
+
return targetServerClusters(this.node, Number(this._targetEndpoint)).sort((a, b) => a - b);
|
|
85
|
+
}
|
|
86
|
+
_clusterLabel(id) {
|
|
87
|
+
return `${clusters[id]?.label ?? "Cluster"} (0x${id.toString(16).padStart(2, "0").toUpperCase()})`;
|
|
88
|
+
}
|
|
89
|
+
_addTarget() {
|
|
90
|
+
const max = aclCapacity(this.node).targetsMax;
|
|
91
|
+
if (max > 0 && this._targets.length >= max) {
|
|
92
|
+
void showAlertDialog({ title: "Limit reached", text: `At most ${max} targets per entry.` });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const endpoint = this._targetEndpoint === "all" || this._targetEndpoint === "" ? void 0 : Number(this._targetEndpoint);
|
|
96
|
+
const cluster = this._targetCluster === "all" || this._targetCluster === "" ? void 0 : Number(this._targetCluster);
|
|
97
|
+
if (endpoint === void 0 && cluster === void 0) {
|
|
98
|
+
void showAlertDialog({
|
|
99
|
+
title: "Validation error",
|
|
100
|
+
text: "Pick an endpoint and/or a cluster for the target."
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this._targets = [...this._targets, { endpoint, cluster, deviceType: void 0 }];
|
|
105
|
+
this._targetEndpoint = "all";
|
|
106
|
+
this._targetCluster = "all";
|
|
107
|
+
}
|
|
108
|
+
_removeTarget(index) {
|
|
109
|
+
this._targets = this._targets.filter((_, i) => i !== index);
|
|
110
|
+
}
|
|
111
|
+
async _save() {
|
|
112
|
+
if (this._subjects.length === 0) {
|
|
113
|
+
await showAlertDialog({ title: "Validation error", text: "Add at least one subject node." });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const entry = {
|
|
117
|
+
privilege: this._privilege,
|
|
118
|
+
authMode: AuthMode.Case,
|
|
119
|
+
subjects: this._subjects,
|
|
120
|
+
targets: this._targets.length ? this._targets : void 0,
|
|
121
|
+
fabricIndex: 0
|
|
122
|
+
};
|
|
123
|
+
this._busy = true;
|
|
124
|
+
try {
|
|
125
|
+
await addAclEntry(this.client, this.node.node_id, entry);
|
|
126
|
+
this._close();
|
|
127
|
+
} catch (err) {
|
|
128
|
+
await showAlertDialog({
|
|
129
|
+
title: "Failed to add entry",
|
|
130
|
+
text: err instanceof Error ? err.message : String(err)
|
|
131
|
+
});
|
|
132
|
+
} finally {
|
|
133
|
+
this._busy = false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
_close() {
|
|
137
|
+
this.shadowRoot.querySelector("md-dialog").close();
|
|
138
|
+
}
|
|
139
|
+
_handleClosed() {
|
|
140
|
+
this.parentNode?.removeChild(this);
|
|
141
|
+
}
|
|
142
|
+
render() {
|
|
143
|
+
return html`
|
|
144
|
+
<md-dialog open @cancel=${preventDefault} @closed=${this._handleClosed}>
|
|
145
|
+
<div slot="headline">Add ACL entry</div>
|
|
146
|
+
<div slot="content">
|
|
147
|
+
<div class="form">
|
|
148
|
+
<md-outlined-select
|
|
149
|
+
label="Privilege"
|
|
150
|
+
.value=${String(this._privilege)}
|
|
151
|
+
?disabled=${this._busy}
|
|
152
|
+
@change=${(e) => this._privilege = Number(e.target.value)}
|
|
153
|
+
>
|
|
154
|
+
${[Privilege.View, Privilege.Operate, Privilege.Manage, Privilege.Administer].map(
|
|
155
|
+
(p) => html`<md-select-option value=${String(p)}
|
|
156
|
+
><div slot="headline">${PRIVILEGE_NAMES[p]} · ${p}</div></md-select-option
|
|
157
|
+
>`
|
|
158
|
+
)}
|
|
159
|
+
</md-outlined-select>
|
|
160
|
+
<div class="note">Auth mode: CASE (node). Group subjects are not supported yet.</div>
|
|
161
|
+
|
|
162
|
+
<div class="label">Subjects (nodes)</div>
|
|
163
|
+
<div class="chips">
|
|
164
|
+
${this._subjects.length === 0 ? html`<span class="mut">none — add at least one</span>` : this._subjects.map((s) => {
|
|
165
|
+
const known = this.client.nodes[nodeIdKey(s)];
|
|
166
|
+
return html`<span class="chip"
|
|
167
|
+
>${known ? getDeviceName(known) : "Node"} · ${s.toString()}
|
|
168
|
+
<ha-svg-icon
|
|
169
|
+
class="x"
|
|
170
|
+
.path=${mdiClose}
|
|
171
|
+
@click=${() => this._removeSubject(nodeIdKey(s))}
|
|
172
|
+
></ha-svg-icon
|
|
173
|
+
></span>`;
|
|
174
|
+
})}
|
|
175
|
+
</div>
|
|
176
|
+
<div class="row">
|
|
177
|
+
<md-outlined-select
|
|
178
|
+
label="Known nodes"
|
|
179
|
+
?disabled=${this._busy}
|
|
180
|
+
@change=${(e) => {
|
|
181
|
+
const v = e.target.value;
|
|
182
|
+
if (v) this._addSubject(v);
|
|
183
|
+
}}
|
|
184
|
+
>
|
|
185
|
+
<md-select-option value=""><div slot="headline">— pick —</div></md-select-option>
|
|
186
|
+
${this._knownNodes().map(
|
|
187
|
+
(n) => html`<md-select-option value=${nodeIdKey(n.node_id)}
|
|
188
|
+
><div slot="headline">
|
|
189
|
+
${n.node_id.toString()} · ${getDeviceName(n)}
|
|
190
|
+
</div></md-select-option
|
|
191
|
+
>`
|
|
192
|
+
)}
|
|
193
|
+
</md-outlined-select>
|
|
194
|
+
<md-outlined-text-field
|
|
195
|
+
label="or raw node id"
|
|
196
|
+
type="text"
|
|
197
|
+
pattern="[0-9]+"
|
|
198
|
+
.value=${this._subjectInput}
|
|
199
|
+
?disabled=${this._busy}
|
|
200
|
+
@input=${(e) => this._subjectInput = e.target.value}
|
|
201
|
+
></md-outlined-text-field>
|
|
202
|
+
<md-text-button ?disabled=${this._busy} @click=${() => this._addSubject(this._subjectInput)}
|
|
203
|
+
>Add</md-text-button
|
|
204
|
+
>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div class="label">Targets (optional — none means whole node)</div>
|
|
208
|
+
<div class="chips">
|
|
209
|
+
${this._targets.length === 0 ? html`<span class="mut">whole node</span>` : this._targets.map(
|
|
210
|
+
(t, i) => html`<span class="chip"
|
|
211
|
+
>${t.endpoint != null ? `EP ${t.endpoint}` : "All endpoints"}
|
|
212
|
+
${t.cluster != null ? `\xB7 ${this._clusterLabel(t.cluster)}` : "\xB7 all clusters"}
|
|
213
|
+
<ha-svg-icon
|
|
214
|
+
class="x"
|
|
215
|
+
.path=${mdiClose}
|
|
216
|
+
@click=${() => this._removeTarget(i)}
|
|
217
|
+
></ha-svg-icon
|
|
218
|
+
></span>`
|
|
219
|
+
)}
|
|
220
|
+
</div>
|
|
221
|
+
<div class="row">
|
|
222
|
+
<md-outlined-select
|
|
223
|
+
label="endpoint"
|
|
224
|
+
.value=${this._targetEndpoint}
|
|
225
|
+
?disabled=${this._busy}
|
|
226
|
+
@change=${(e) => {
|
|
227
|
+
this._targetEndpoint = e.target.value;
|
|
228
|
+
this._targetCluster = "";
|
|
229
|
+
}}
|
|
230
|
+
>
|
|
231
|
+
<md-select-option value="all"
|
|
232
|
+
><div slot="headline">All endpoints</div></md-select-option
|
|
233
|
+
>
|
|
234
|
+
${this._nodeEndpoints().map(
|
|
235
|
+
(ep) => html`<md-select-option value=${String(ep)}
|
|
236
|
+
><div slot="headline">EP ${ep}</div></md-select-option
|
|
237
|
+
>`
|
|
238
|
+
)}
|
|
239
|
+
</md-outlined-select>
|
|
240
|
+
<md-outlined-select
|
|
241
|
+
label="cluster"
|
|
242
|
+
.value=${this._targetCluster}
|
|
243
|
+
?disabled=${this._busy}
|
|
244
|
+
@change=${(e) => this._targetCluster = e.target.value}
|
|
245
|
+
>
|
|
246
|
+
<md-select-option value="all"><div slot="headline">All clusters</div></md-select-option>
|
|
247
|
+
${this._clusterOptions().map(
|
|
248
|
+
(c) => html`<md-select-option value=${String(c)}
|
|
249
|
+
><div slot="headline">${this._clusterLabel(c)}</div></md-select-option
|
|
250
|
+
>`
|
|
251
|
+
)}
|
|
252
|
+
</md-outlined-select>
|
|
253
|
+
<md-text-button ?disabled=${this._busy} @click=${() => this._addTarget()}
|
|
254
|
+
>Add target</md-text-button
|
|
255
|
+
>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
<div slot="actions">
|
|
260
|
+
<md-text-button ?disabled=${this._busy} @click=${handleAsync(() => this._save())}
|
|
261
|
+
>Add</md-text-button
|
|
262
|
+
>
|
|
263
|
+
<md-text-button ?disabled=${this._busy} @click=${this._close}>Cancel</md-text-button>
|
|
264
|
+
</div>
|
|
265
|
+
</md-dialog>
|
|
266
|
+
`;
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
NodeAclAddDialog.styles = css`
|
|
270
|
+
.form {
|
|
271
|
+
display: flex;
|
|
272
|
+
flex-direction: column;
|
|
273
|
+
gap: 10px;
|
|
274
|
+
min-width: 360px;
|
|
275
|
+
}
|
|
276
|
+
.label {
|
|
277
|
+
font-size: 11px;
|
|
278
|
+
text-transform: uppercase;
|
|
279
|
+
letter-spacing: 0.04em;
|
|
280
|
+
opacity: 0.65;
|
|
281
|
+
margin-top: 6px;
|
|
282
|
+
}
|
|
283
|
+
.note {
|
|
284
|
+
font-size: 12px;
|
|
285
|
+
opacity: 0.7;
|
|
286
|
+
}
|
|
287
|
+
.row {
|
|
288
|
+
display: flex;
|
|
289
|
+
gap: 8px;
|
|
290
|
+
align-items: center;
|
|
291
|
+
flex-wrap: wrap;
|
|
292
|
+
}
|
|
293
|
+
.chips {
|
|
294
|
+
display: flex;
|
|
295
|
+
flex-wrap: wrap;
|
|
296
|
+
gap: 6px;
|
|
297
|
+
}
|
|
298
|
+
.chip {
|
|
299
|
+
display: inline-flex;
|
|
300
|
+
align-items: center;
|
|
301
|
+
gap: 4px;
|
|
302
|
+
padding: 3px 8px;
|
|
303
|
+
border-radius: 6px;
|
|
304
|
+
font-size: 12px;
|
|
305
|
+
background: var(--md-sys-color-surface-container-high);
|
|
306
|
+
color: var(--md-sys-color-on-surface);
|
|
307
|
+
}
|
|
308
|
+
.chip .x {
|
|
309
|
+
cursor: pointer;
|
|
310
|
+
--mdc-icon-size: 16px;
|
|
311
|
+
width: 16px;
|
|
312
|
+
height: 16px;
|
|
313
|
+
}
|
|
314
|
+
.mut {
|
|
315
|
+
opacity: 0.6;
|
|
316
|
+
font-size: 12px;
|
|
317
|
+
}
|
|
318
|
+
`;
|
|
319
|
+
__decorateClass([
|
|
320
|
+
consume({ context: clientContext, subscribe: true }),
|
|
321
|
+
property({ attribute: false })
|
|
322
|
+
], NodeAclAddDialog.prototype, "client", 2);
|
|
323
|
+
__decorateClass([
|
|
324
|
+
property({ attribute: false })
|
|
325
|
+
], NodeAclAddDialog.prototype, "node", 2);
|
|
326
|
+
__decorateClass([
|
|
327
|
+
state()
|
|
328
|
+
], NodeAclAddDialog.prototype, "_privilege", 2);
|
|
329
|
+
__decorateClass([
|
|
330
|
+
state()
|
|
331
|
+
], NodeAclAddDialog.prototype, "_subjects", 2);
|
|
332
|
+
__decorateClass([
|
|
333
|
+
state()
|
|
334
|
+
], NodeAclAddDialog.prototype, "_subjectInput", 2);
|
|
335
|
+
__decorateClass([
|
|
336
|
+
state()
|
|
337
|
+
], NodeAclAddDialog.prototype, "_targets", 2);
|
|
338
|
+
__decorateClass([
|
|
339
|
+
state()
|
|
340
|
+
], NodeAclAddDialog.prototype, "_targetEndpoint", 2);
|
|
341
|
+
__decorateClass([
|
|
342
|
+
state()
|
|
343
|
+
], NodeAclAddDialog.prototype, "_targetCluster", 2);
|
|
344
|
+
__decorateClass([
|
|
345
|
+
state()
|
|
346
|
+
], NodeAclAddDialog.prototype, "_busy", 2);
|
|
347
|
+
NodeAclAddDialog = __decorateClass([
|
|
348
|
+
customElement("node-acl-add-dialog")
|
|
349
|
+
], NodeAclAddDialog);
|
|
350
|
+
export {
|
|
351
|
+
NodeAclAddDialog
|
|
352
|
+
};
|
|
353
|
+
//# sourceMappingURL=node-acl-add-dialog.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/dialogs/acl/node-acl-add-dialog.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { MatterNode } from "@matter-server/ws-client";
|
|
7
|
+
export declare const showNodeAclAddDialog: (node: MatterNode) => Promise<void>;
|
|
8
|
+
//# sourceMappingURL=show-node-acl-add-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show-node-acl-add-dialog.d.ts","sourceRoot":"","sources":["../../../../../src/components/dialogs/acl/show-node-acl-add-dialog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,eAAO,MAAM,oBAAoB,SAAgB,UAAU,kBAK1D,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
const showNodeAclAddDialog = async (node) => {
|
|
7
|
+
await import("./node-acl-add-dialog.js");
|
|
8
|
+
const dialog = document.createElement("node-acl-add-dialog");
|
|
9
|
+
dialog.node = node;
|
|
10
|
+
document.querySelector("matter-dashboard-app")?.renderRoot.appendChild(dialog);
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
showNodeAclAddDialog
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=show-node-acl-add-dialog.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/dialogs/acl/show-node-acl-add-dialog.ts"],
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAQO,MAAM,uBAAuB,OAAO,SAAqB;AAC5D,QAAM,OAAO,0BAA0B;AACvC,QAAM,SAAS,SAAS,cAAc,qBAAqB;AAC3D,SAAO,OAAO;AACd,WAAS,cAAc,sBAAsB,GAAG,WAAW,YAAY,MAAM;AACjF;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025-2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { MatterClient, MatterNode } from "@matter-server/ws-client";
|
|
7
|
+
/** Ensure the target grants the source an Operate ACL for {endpoint, cluster}, merging where possible. */
|
|
8
|
+
export declare function ensureBindingAcl(client: MatterClient, sourceNodeId: number | bigint, targetNodeId: number | bigint, targetEndpoint: number, cluster: number | undefined): Promise<void>;
|
|
9
|
+
/** Downgrade an over-privileged (>Operate) binding ACL on the target back to Operate. */
|
|
10
|
+
export declare function fixOverPrivilegedBindingAcl(client: MatterClient, sourceNodeId: number | bigint, targetNodeId: number | bigint, targetEndpoint: number, cluster: number | undefined): Promise<void>;
|
|
11
|
+
export declare function addBinding(client: MatterClient, sourceNode: MatterNode, sourceEndpoint: number, targetNodeId: number | bigint, targetEndpoint: number, cluster: number | undefined): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Remove the binding at `index`, then drop the matching target from the source's ACL entry on the
|
|
14
|
+
* (binding) target node. Matches on the binding's TARGET endpoint + cluster.
|
|
15
|
+
*/
|
|
16
|
+
export declare function deleteBindingAtIndex(client: MatterClient, sourceNode: MatterNode, sourceEndpoint: number, index: number): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=binding-actions.d.ts.map
|