@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.
Files changed (111) hide show
  1. package/dist/esm/components/dialogs/acl/acl-actions.d.ts +12 -0
  2. package/dist/esm/components/dialogs/acl/acl-actions.d.ts.map +1 -0
  3. package/dist/esm/components/dialogs/acl/acl-actions.js +56 -0
  4. package/dist/esm/components/dialogs/acl/acl-actions.js.map +6 -0
  5. package/dist/esm/components/dialogs/acl/model.d.ts +2 -2
  6. package/dist/esm/components/dialogs/acl/model.d.ts.map +1 -1
  7. package/dist/esm/components/dialogs/acl/model.js +11 -15
  8. package/dist/esm/components/dialogs/acl/model.js.map +1 -1
  9. package/dist/esm/components/dialogs/acl/node-acl-add-dialog.d.ts +43 -0
  10. package/dist/esm/components/dialogs/acl/node-acl-add-dialog.d.ts.map +1 -0
  11. package/dist/esm/components/dialogs/acl/node-acl-add-dialog.js +353 -0
  12. package/dist/esm/components/dialogs/acl/node-acl-add-dialog.js.map +6 -0
  13. package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.d.ts +8 -0
  14. package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.d.ts.map +1 -0
  15. package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.js +15 -0
  16. package/dist/esm/components/dialogs/acl/show-node-acl-add-dialog.js.map +6 -0
  17. package/dist/esm/components/dialogs/binding/binding-actions.d.ts +17 -0
  18. package/dist/esm/components/dialogs/binding/binding-actions.d.ts.map +1 -0
  19. package/dist/esm/components/dialogs/binding/binding-actions.js +135 -0
  20. package/dist/esm/components/dialogs/binding/binding-actions.js.map +6 -0
  21. package/dist/esm/components/dialogs/binding/model.d.ts +1 -1
  22. package/dist/esm/components/dialogs/binding/model.d.ts.map +1 -1
  23. package/dist/esm/components/dialogs/binding/model.js +8 -3
  24. package/dist/esm/components/dialogs/binding/model.js.map +1 -1
  25. package/dist/esm/components/dialogs/binding/node-binding-dialog.d.ts +16 -24
  26. package/dist/esm/components/dialogs/binding/node-binding-dialog.d.ts.map +1 -1
  27. package/dist/esm/components/dialogs/binding/node-binding-dialog.js +210 -332
  28. package/dist/esm/components/dialogs/binding/node-binding-dialog.js.map +1 -1
  29. package/dist/esm/pages/cluster-commands/clusters/access-control-commands.d.ts +37 -0
  30. package/dist/esm/pages/cluster-commands/clusters/access-control-commands.d.ts.map +1 -0
  31. package/dist/esm/pages/cluster-commands/clusters/access-control-commands.js +387 -0
  32. package/dist/esm/pages/cluster-commands/clusters/access-control-commands.js.map +6 -0
  33. package/dist/esm/pages/cluster-commands/clusters/binding-commands.d.ts +35 -0
  34. package/dist/esm/pages/cluster-commands/clusters/binding-commands.d.ts.map +1 -0
  35. package/dist/esm/pages/cluster-commands/clusters/binding-commands.js +254 -0
  36. package/dist/esm/pages/cluster-commands/clusters/binding-commands.js.map +6 -0
  37. package/dist/esm/pages/cluster-commands/index.d.ts +2 -0
  38. package/dist/esm/pages/cluster-commands/index.d.ts.map +1 -1
  39. package/dist/esm/pages/cluster-commands/index.js +2 -0
  40. package/dist/esm/pages/cluster-commands/index.js.map +1 -1
  41. package/dist/esm/pages/components/node-details.d.ts +0 -1
  42. package/dist/esm/pages/components/node-details.d.ts.map +1 -1
  43. package/dist/esm/pages/components/node-details.js +2 -18
  44. package/dist/esm/pages/components/node-details.js.map +1 -1
  45. package/dist/esm/pages/components/server-details.js +3 -3
  46. package/dist/esm/pages/components/server-details.js.map +1 -1
  47. package/dist/esm/pages/matter-cluster-view.d.ts.map +1 -1
  48. package/dist/esm/pages/matter-cluster-view.js +2 -1
  49. package/dist/esm/pages/matter-cluster-view.js.map +1 -1
  50. package/dist/esm/pages/matter-endpoint-view.d.ts +3 -3
  51. package/dist/esm/pages/matter-endpoint-view.d.ts.map +1 -1
  52. package/dist/esm/pages/matter-endpoint-view.js +13 -10
  53. package/dist/esm/pages/matter-endpoint-view.js.map +1 -1
  54. package/dist/esm/pages/matter-node-view.js +2 -2
  55. package/dist/esm/pages/matter-node-view.js.map +1 -1
  56. package/dist/esm/pages/network/network-utils.d.ts +1 -5
  57. package/dist/esm/pages/network/network-utils.d.ts.map +1 -1
  58. package/dist/esm/pages/network/network-utils.js +1 -11
  59. package/dist/esm/pages/network/network-utils.js.map +1 -1
  60. package/dist/esm/util/access-control.d.ts +54 -0
  61. package/dist/esm/util/access-control.d.ts.map +1 -0
  62. package/dist/esm/util/access-control.js +100 -0
  63. package/dist/esm/util/access-control.js.map +6 -0
  64. package/dist/esm/util/binding.d.ts +54 -0
  65. package/dist/esm/util/binding.d.ts.map +1 -0
  66. package/dist/esm/util/binding.js +113 -0
  67. package/dist/esm/util/binding.js.map +6 -0
  68. package/dist/esm/util/endpoints.d.ts +9 -0
  69. package/dist/esm/util/endpoints.d.ts.map +1 -0
  70. package/dist/esm/util/endpoints.js +18 -0
  71. package/dist/esm/util/endpoints.js.map +6 -0
  72. package/dist/esm/util/node-name.d.ts +12 -0
  73. package/dist/esm/util/node-name.d.ts.map +1 -0
  74. package/dist/esm/util/node-name.js +15 -0
  75. package/dist/esm/util/node-name.js.map +6 -0
  76. package/dist/web/js/{attribute-write-dialog-W7xpCE2E.js → attribute-write-dialog-CqqdRniU.js} +1 -1
  77. package/dist/web/js/{command-invoke-dialog-BAqAAdJw.js → command-invoke-dialog-BuvBOrdC.js} +1 -1
  78. package/dist/web/js/{commission-node-dialog-BTzCGgdy.js → commission-node-dialog-nVZp3go0.js} +5 -5
  79. package/dist/web/js/{commission-node-existing-B2M2hyDh.js → commission-node-existing-Cx3Ahk2t.js} +2 -2
  80. package/dist/web/js/{commission-node-thread-djdz2dXW.js → commission-node-thread-CI8mWWPs.js} +2 -2
  81. package/dist/web/js/{commission-node-wifi-DxAYNS1A.js → commission-node-wifi-lUX4LK2R.js} +2 -2
  82. package/dist/web/js/{dialog-box-tHvPVxDN.js → dialog-box-bAdbnf-T.js} +1 -1
  83. package/dist/web/js/{fire_event-BleYfTLc.js → fire_event-tWhqPfdz.js} +1 -1
  84. package/dist/web/js/main.js +1 -1
  85. package/dist/web/js/{matter-dashboard-app-CVi_GDky.js → matter-dashboard-app-CONA_608.js} +1485 -390
  86. package/dist/web/js/node-acl-add-dialog-DlR-sF-b.js +320 -0
  87. package/dist/web/js/node-binding-dialog-DhnX_86M.js +267 -0
  88. package/dist/web/js/{node-label-dialog-DVZSjsXU.js → node-label-dialog-T3nPG-Qy.js} +1 -1
  89. package/dist/web/js/{settings-dialog-BG5MgZcO.js → settings-dialog-DrHzJtsi.js} +1 -1
  90. package/package.json +4 -4
  91. package/src/components/dialogs/acl/acl-actions.ts +71 -0
  92. package/src/components/dialogs/acl/model.ts +18 -17
  93. package/src/components/dialogs/acl/node-acl-add-dialog.ts +350 -0
  94. package/src/components/dialogs/acl/show-node-acl-add-dialog.ts +14 -0
  95. package/src/components/dialogs/binding/binding-actions.ts +201 -0
  96. package/src/components/dialogs/binding/model.ts +11 -4
  97. package/src/components/dialogs/binding/node-binding-dialog.ts +221 -399
  98. package/src/pages/cluster-commands/clusters/access-control-commands.ts +407 -0
  99. package/src/pages/cluster-commands/clusters/binding-commands.ts +273 -0
  100. package/src/pages/cluster-commands/index.ts +2 -0
  101. package/src/pages/components/node-details.ts +2 -21
  102. package/src/pages/components/server-details.ts +3 -3
  103. package/src/pages/matter-cluster-view.ts +4 -1
  104. package/src/pages/matter-endpoint-view.ts +16 -10
  105. package/src/pages/matter-node-view.ts +2 -2
  106. package/src/pages/network/network-utils.ts +1 -18
  107. package/src/util/access-control.ts +135 -0
  108. package/src/util/binding.ts +182 -0
  109. package/src/util/endpoints.ts +17 -0
  110. package/src/util/node-name.ts +18 -0
  111. 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: any): AccessControlTargetStruct;
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: any): AccessControlEntryStruct;
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;AAEF,qBAAa,8BAA8B;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAMjC;IAEF,OAAc,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,yBAAyB,CAmB7D;CACJ;AAED,qBAAa,iCAAiC;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAQjC;IAEF,OAAc,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,wBAAwB,CAiC5D;CACJ"}
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 || typeof input !== "object") {
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 === void 0) continue;
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 || typeof input !== "object") {
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 === void 0) continue;
57
+ if (value == null) continue;
55
58
  if (mappedKey === "subjects") {
56
- result[mappedKey] = Array.isArray(value) ? value : void 0;
59
+ result.subjects = Array.isArray(value) ? value : void 0;
57
60
  } else if (mappedKey === "targets") {
58
- if (Array.isArray(value)) {
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;AA4BO,MAAM,+BAA+B;AAAA,EACxC;AAAA,SAAwB,cAEpB;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACT;AAAA;AAAA,EAEA,OAAc,UAAU,OAAuC;AAC3D,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACrC,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;AACvB,cAAI,UAAU,OAAW;AACzB,iBAAO,SAAS,IAAI;AAAA,QACxB;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,OAAsC;AAC1D,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACrC,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,UAAU,OAAW;AACzB,cAAI,cAAc,YAAY;AAC1B,mBAAO,SAAS,IAAI,MAAM,QAAQ,KAAK,IAAI,QAAQ;AAAA,UACvD,WAAW,cAAc,WAAW;AAChC,gBAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,oBAAM,WAAW,OAAO,OAAO,KAAK,EAAE;AAAA,gBAAI,SACtC,+BAA+B,UAAU,GAAG;AAAA,cAChD;AACA,qBAAO,SAAS,IAAI;AAAA,YACxB,OAAO;AACH,qBAAO,SAAS,IAAI;AAAA,YACxB;AAAA,UACJ,OAAO;AACH,mBAAO,SAAS,IAAI;AAAA,UACxB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AACJ;",
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