@coffeerunhobby/mcp-ha-connect 2.2.1 → 2.4.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 (293) hide show
  1. package/.env.example +1 -1
  2. package/README.md +24 -2
  3. package/dist/omadaClient/accessControl.d.ts +290 -0
  4. package/dist/omadaClient/accessControl.js +509 -0
  5. package/dist/omadaClient/accessControl.js.map +1 -0
  6. package/dist/omadaClient/client.d.ts +6 -1
  7. package/dist/omadaClient/client.js +12 -1
  8. package/dist/omadaClient/client.js.map +1 -1
  9. package/dist/omadaClient/diagnose.d.ts +68 -0
  10. package/dist/omadaClient/diagnose.js +164 -0
  11. package/dist/omadaClient/diagnose.js.map +1 -0
  12. package/dist/omadaClient/index.d.ts +9 -0
  13. package/dist/omadaClient/index.js +19 -0
  14. package/dist/omadaClient/index.js.map +1 -1
  15. package/dist/omadaClient/macGroups.d.ts +58 -0
  16. package/dist/omadaClient/macGroups.js +110 -0
  17. package/dist/omadaClient/macGroups.js.map +1 -0
  18. package/dist/omadaClient/serialize.d.ts +13 -0
  19. package/dist/omadaClient/serialize.js +29 -0
  20. package/dist/omadaClient/serialize.js.map +1 -0
  21. package/dist/omadaClient/timeRange.d.ts +41 -0
  22. package/dist/omadaClient/timeRange.js +109 -0
  23. package/dist/omadaClient/timeRange.js.map +1 -0
  24. package/dist/tools/infra/actions.d.ts +1 -1
  25. package/dist/tools/infra/actions.js +1 -1
  26. package/dist/tools/omada/accessControl.d.ts +151 -0
  27. package/dist/tools/omada/accessControl.js +158 -0
  28. package/dist/tools/omada/accessControl.js.map +1 -0
  29. package/dist/tools/omada/index.js +9 -0
  30. package/dist/tools/omada/index.js.map +1 -1
  31. package/dist/tools/omada/macGroups.d.ts +19 -0
  32. package/dist/tools/omada/macGroups.js +77 -0
  33. package/dist/tools/omada/macGroups.js.map +1 -0
  34. package/dist/tools/omada/namespace.js +16 -0
  35. package/dist/tools/omada/namespace.js.map +1 -1
  36. package/dist/version.d.ts +1 -1
  37. package/dist/version.js +1 -1
  38. package/package.json +5 -1
  39. package/.codex/review-rules.md +0 -16
  40. package/.dockerignore +0 -8
  41. package/.gitattributes +0 -30
  42. package/.github/workflows/ci.yml +0 -193
  43. package/AGENTS.md +0 -389
  44. package/Dockerfile +0 -50
  45. package/docker-compose.yml +0 -23
  46. package/docs/CHANGELOG.md +0 -341
  47. package/docs/COVERAGE.md +0 -219
  48. package/docs/QUICK_START.md +0 -240
  49. package/eslint.config.js +0 -33
  50. package/n8n/ai-agent-safety-monitor.json +0 -355
  51. package/openapi.json +0 -1259
  52. package/scripts/check-version-sync.mjs +0 -69
  53. package/scripts/generate-jwt.ts +0 -121
  54. package/src/config.ts +0 -440
  55. package/src/haClient/automations.ts +0 -261
  56. package/src/haClient/calendars.ts +0 -94
  57. package/src/haClient/config.ts +0 -52
  58. package/src/haClient/devices.ts +0 -653
  59. package/src/haClient/entities.ts +0 -128
  60. package/src/haClient/events.ts +0 -689
  61. package/src/haClient/history.ts +0 -73
  62. package/src/haClient/index.ts +0 -336
  63. package/src/haClient/request.ts +0 -142
  64. package/src/haClient/services.ts +0 -45
  65. package/src/haClient/states.ts +0 -60
  66. package/src/haClient/updates.ts +0 -58
  67. package/src/haClient/wsCommand.ts +0 -44
  68. package/src/index.ts +0 -164
  69. package/src/localAI/index.ts +0 -88
  70. package/src/localAI/prompts.ts +0 -50
  71. package/src/localAI/providers/base.ts +0 -120
  72. package/src/localAI/providers/ollama.ts +0 -78
  73. package/src/localAI/providers/openai.ts +0 -86
  74. package/src/localAI/types.ts +0 -67
  75. package/src/omadaClient/auth.ts +0 -178
  76. package/src/omadaClient/client.ts +0 -337
  77. package/src/omadaClient/device.ts +0 -118
  78. package/src/omadaClient/index.ts +0 -310
  79. package/src/omadaClient/network.ts +0 -284
  80. package/src/omadaClient/request.ts +0 -365
  81. package/src/omadaClient/security.ts +0 -51
  82. package/src/omadaClient/site.ts +0 -344
  83. package/src/ownerQuestions/service.ts +0 -536
  84. package/src/permissions/index.ts +0 -143
  85. package/src/resources/index.ts +0 -213
  86. package/src/server/auth.ts +0 -175
  87. package/src/server/chatFace.ts +0 -789
  88. package/src/server/chatSlice.ts +0 -57
  89. package/src/server/common.ts +0 -170
  90. package/src/server/eventSubscription.ts +0 -343
  91. package/src/server/http.ts +0 -626
  92. package/src/server/instructions.ts +0 -97
  93. package/src/server/rateLimiter.ts +0 -227
  94. package/src/server/stdio.ts +0 -41
  95. package/src/server/stream.ts +0 -205
  96. package/src/tools/ai/analyzeSensors.ts +0 -33
  97. package/src/tools/ai/index.ts +0 -20
  98. package/src/tools/common.ts +0 -442
  99. package/src/tools/homeassistant/askOwner.ts +0 -133
  100. package/src/tools/homeassistant/automationControls.ts +0 -66
  101. package/src/tools/homeassistant/calendar.ts +0 -97
  102. package/src/tools/homeassistant/callService.ts +0 -25
  103. package/src/tools/homeassistant/controlClimate.ts +0 -68
  104. package/src/tools/homeassistant/controlCover.ts +0 -48
  105. package/src/tools/homeassistant/controlFan.ts +0 -44
  106. package/src/tools/homeassistant/controlLight.ts +0 -38
  107. package/src/tools/homeassistant/controlMediaPlayer.ts +0 -50
  108. package/src/tools/homeassistant/createAutomation.ts +0 -35
  109. package/src/tools/homeassistant/deleteAutomation.ts +0 -24
  110. package/src/tools/homeassistant/entityAction.ts +0 -35
  111. package/src/tools/homeassistant/entityGuard.ts +0 -28
  112. package/src/tools/homeassistant/getAllSensors.ts +0 -46
  113. package/src/tools/homeassistant/getAutomationTrace.ts +0 -30
  114. package/src/tools/homeassistant/getDomainSummary.ts +0 -29
  115. package/src/tools/homeassistant/getEntitiesByDomain.ts +0 -56
  116. package/src/tools/homeassistant/getHistory.ts +0 -24
  117. package/src/tools/homeassistant/getState.ts +0 -24
  118. package/src/tools/homeassistant/getStates.ts +0 -46
  119. package/src/tools/homeassistant/getVersion.ts +0 -21
  120. package/src/tools/homeassistant/index.ts +0 -121
  121. package/src/tools/homeassistant/listAutomations.ts +0 -35
  122. package/src/tools/homeassistant/listEntities.ts +0 -44
  123. package/src/tools/homeassistant/listPersons.ts +0 -46
  124. package/src/tools/homeassistant/sceneAndScript.ts +0 -53
  125. package/src/tools/homeassistant/searchEntities.ts +0 -58
  126. package/src/tools/homeassistant/sendNotification.ts +0 -179
  127. package/src/tools/homeassistant/systemTools.ts +0 -52
  128. package/src/tools/homeassistant/triggerAutomation.ts +0 -24
  129. package/src/tools/index.ts +0 -78
  130. package/src/tools/infra/actions.ts +0 -95
  131. package/src/tools/infra/index.ts +0 -138
  132. package/src/tools/omada/blockClient.ts +0 -28
  133. package/src/tools/omada/cyclePoePort.ts +0 -32
  134. package/src/tools/omada/deleteClient.ts +0 -27
  135. package/src/tools/omada/disableClientRateLimit.ts +0 -23
  136. package/src/tools/omada/getClient.ts +0 -14
  137. package/src/tools/omada/getDevice.ts +0 -14
  138. package/src/tools/omada/getFirewallSetting.ts +0 -14
  139. package/src/tools/omada/getInternetInfo.ts +0 -14
  140. package/src/tools/omada/getLanNetworkList.ts +0 -14
  141. package/src/tools/omada/getLanProfileList.ts +0 -14
  142. package/src/tools/omada/getPortForwardingStatus.ts +0 -26
  143. package/src/tools/omada/getRateLimitProfiles.ts +0 -14
  144. package/src/tools/omada/getSiteNtpStatus.ts +0 -14
  145. package/src/tools/omada/getSsidDetail.ts +0 -22
  146. package/src/tools/omada/getSsidList.ts +0 -21
  147. package/src/tools/omada/getSwitchStackDetail.ts +0 -14
  148. package/src/tools/omada/getThreatList.ts +0 -42
  149. package/src/tools/omada/getWlanGroupList.ts +0 -14
  150. package/src/tools/omada/graph.ts +0 -187
  151. package/src/tools/omada/index.ts +0 -153
  152. package/src/tools/omada/listBlockedClients.ts +0 -17
  153. package/src/tools/omada/listClients.ts +0 -14
  154. package/src/tools/omada/listClientsActivity.ts +0 -25
  155. package/src/tools/omada/listClientsPastConnections.ts +0 -44
  156. package/src/tools/omada/listDevices.ts +0 -14
  157. package/src/tools/omada/listDevicesStats.ts +0 -41
  158. package/src/tools/omada/listMostActiveClients.ts +0 -14
  159. package/src/tools/omada/listSites.ts +0 -18
  160. package/src/tools/omada/namespace.ts +0 -1164
  161. package/src/tools/omada/searchDevices.ts +0 -20
  162. package/src/tools/omada/setClientRateLimit.ts +0 -26
  163. package/src/tools/omada/setClientRateLimitProfile.ts +0 -25
  164. package/src/tools/omada/setSiteNtpServers.ts +0 -36
  165. package/src/tools/omada/setSsidEnabled.ts +0 -38
  166. package/src/tools/omada/unblockClient.ts +0 -26
  167. package/src/tools/types.ts +0 -11
  168. package/src/tools/utils/pagination-schema.ts +0 -27
  169. package/src/types/ai/index.ts +0 -11
  170. package/src/types/ai/types.ts +0 -67
  171. package/src/types/homeassistant/automations.ts +0 -43
  172. package/src/types/homeassistant/calendars.ts +0 -26
  173. package/src/types/homeassistant/config.ts +0 -14
  174. package/src/types/homeassistant/entities.ts +0 -14
  175. package/src/types/homeassistant/errors.ts +0 -33
  176. package/src/types/homeassistant/haConfig.ts +0 -7
  177. package/src/types/homeassistant/history.ts +0 -13
  178. package/src/types/homeassistant/index.ts +0 -46
  179. package/src/types/homeassistant/request.ts +0 -6
  180. package/src/types/homeassistant/serviceCall.ts +0 -18
  181. package/src/types/homeassistant/states.ts +0 -58
  182. package/src/types/homeassistant/updates.ts +0 -28
  183. package/src/types/index.ts +0 -12
  184. package/src/types/omada/activeClientInfo.ts +0 -17
  185. package/src/types/omada/clientActivity.ts +0 -32
  186. package/src/types/omada/clientBlockStatus.ts +0 -11
  187. package/src/types/omada/clientPastConnection.ts +0 -82
  188. package/src/types/omada/index.ts +0 -14
  189. package/src/types/omada/omadaApiResponse.ts +0 -5
  190. package/src/types/omada/omadaClientInfo.ts +0 -11
  191. package/src/types/omada/omadaDeviceInfo.ts +0 -11
  192. package/src/types/omada/omadaDeviceStats.ts +0 -31
  193. package/src/types/omada/omadaSiteSummary.ts +0 -5
  194. package/src/types/omada/oswStackDetail.ts +0 -11
  195. package/src/types/omada/paginatedResult.ts +0 -6
  196. package/src/types/omada/rateLimitProfile.ts +0 -58
  197. package/src/types/omada/threatInfo.ts +0 -38
  198. package/src/types/omada/tokenResult.ts +0 -6
  199. package/src/types.ts +0 -2
  200. package/src/utils/config-validations.ts +0 -68
  201. package/src/utils/jwt.ts +0 -112
  202. package/src/utils/logger.ts +0 -121
  203. package/src/utils/plainText.ts +0 -48
  204. package/src/utils/redact.ts +0 -59
  205. package/src/utils/sanitizeError.ts +0 -18
  206. package/src/utils/tlsDispatcher.ts +0 -69
  207. package/src/version.ts +0 -5
  208. package/tests/bdd/automation-creation.spec.ts +0 -214
  209. package/tests/bdd/automation-management.spec.ts +0 -267
  210. package/tests/bdd/calendar.spec.ts +0 -190
  211. package/tests/bdd/configuration.spec.ts +0 -283
  212. package/tests/bdd/device-control.spec.ts +0 -344
  213. package/tests/bdd/entity-listing.spec.ts +0 -208
  214. package/tests/bdd/entity-search.spec.ts +0 -183
  215. package/tests/bdd/history-retrieval.spec.ts +0 -195
  216. package/tests/bdd/notifications.spec.ts +0 -238
  217. package/tests/bdd/service-calls.spec.ts +0 -144
  218. package/tests/bdd/state-retrieval.spec.ts +0 -204
  219. package/tests/bench/hotpaths.bench.ts +0 -68
  220. package/tests/config.test.ts +0 -355
  221. package/tests/features/automation-creation.feature +0 -36
  222. package/tests/features/automation-management.feature +0 -54
  223. package/tests/features/calendar.feature +0 -37
  224. package/tests/features/configuration.feature +0 -70
  225. package/tests/features/device-control.feature +0 -100
  226. package/tests/features/entity-listing.feature +0 -51
  227. package/tests/features/entity-search.feature +0 -44
  228. package/tests/features/history-retrieval.feature +0 -38
  229. package/tests/features/notifications.feature +0 -37
  230. package/tests/features/service-calls.feature +0 -35
  231. package/tests/features/state-retrieval.feature +0 -37
  232. package/tests/fixtures/openapi-default-slice.json +0 -290
  233. package/tests/haClient/automationTrace.test.ts +0 -59
  234. package/tests/haClient/automations.test.ts +0 -149
  235. package/tests/haClient/config.test.ts +0 -117
  236. package/tests/haClient/entities.test.ts +0 -188
  237. package/tests/haClient/events.test.ts +0 -455
  238. package/tests/haClient/eventsTls.test.ts +0 -52
  239. package/tests/haClient/history.test.ts +0 -228
  240. package/tests/haClient/index.test.ts +0 -243
  241. package/tests/haClient/request.test.ts +0 -217
  242. package/tests/haClient/services.test.ts +0 -120
  243. package/tests/haClient/states.test.ts +0 -119
  244. package/tests/haClient/updates.test.ts +0 -193
  245. package/tests/index.test.ts +0 -160
  246. package/tests/integration/homeassistant.test.ts +0 -144
  247. package/tests/integration/omada.test.ts +0 -167
  248. package/tests/integration/server.test.ts +0 -151
  249. package/tests/localAI/index.test.ts +0 -177
  250. package/tests/localAI/ollama.test.ts +0 -187
  251. package/tests/localAI/openai.test.ts +0 -257
  252. package/tests/omadaClient/actions.test.ts +0 -161
  253. package/tests/omadaClient/clientBlocks.test.ts +0 -170
  254. package/tests/omadaClient/ntp.test.ts +0 -381
  255. package/tests/omadaClient/site.test.ts +0 -37
  256. package/tests/ownerQuestions/service.test.ts +0 -499
  257. package/tests/ownerQuestions/tools.test.ts +0 -186
  258. package/tests/permissions/index.test.ts +0 -217
  259. package/tests/resources/index.test.ts +0 -288
  260. package/tests/scripts/generateJwt.test.ts +0 -44
  261. package/tests/security/accessControl.test.ts +0 -223
  262. package/tests/security/authentication.test.ts +0 -117
  263. package/tests/security/configuration.test.ts +0 -170
  264. package/tests/security/cryptoTransport.test.ts +0 -172
  265. package/tests/security/dependencies.test.ts +0 -152
  266. package/tests/security/injection.test.ts +0 -117
  267. package/tests/security/insecureDesign.test.ts +0 -121
  268. package/tests/security/logging.test.ts +0 -131
  269. package/tests/security/resourceConsumption.test.ts +0 -142
  270. package/tests/server/auth.test.ts +0 -249
  271. package/tests/server/chatFace.test.ts +0 -320
  272. package/tests/server/common.test.ts +0 -84
  273. package/tests/server/http.test.ts +0 -561
  274. package/tests/server/instructions.test.ts +0 -152
  275. package/tests/server/memoizeJsonSchema.test.ts +0 -71
  276. package/tests/server/stdio.test.ts +0 -99
  277. package/tests/server/stream.test.ts +0 -285
  278. package/tests/server/toolVisibility.http.test.ts +0 -111
  279. package/tests/server/toolVisibility.test.ts +0 -129
  280. package/tests/tools/ai/analyzeSensors.test.ts +0 -227
  281. package/tests/tools/common.test.ts +0 -123
  282. package/tests/tools/homeassistant/handlers.test.ts +0 -872
  283. package/tests/tools/infra/invokeAction.test.ts +0 -280
  284. package/tests/tools/omada/graph.test.ts +0 -385
  285. package/tests/tools/omada/handlers.test.ts +0 -897
  286. package/tests/tools/omada/namespace.test.ts +0 -483
  287. package/tests/tools/registry.test.ts +0 -168
  288. package/tests/utils/config-validations.test.ts +0 -352
  289. package/tests/utils/jwt.test.ts +0 -115
  290. package/tests/utils/logger.test.ts +0 -327
  291. package/tests/utils/redact.test.ts +0 -105
  292. package/tsconfig.json +0 -24
  293. package/vitest.config.ts +0 -38
@@ -0,0 +1,509 @@
1
+ /**
2
+ * Controller-side access control: time-range profiles, IP/MAC group profiles,
3
+ * DHCP reservations, gateway ACL rules and the SSID MAC filter. These let a
4
+ * schedule (e.g. a curfew) be enforced by the controller itself instead of a
5
+ * daily block/unblock loop.
6
+ *
7
+ * Omada's create endpoints return no id, so new objects are found again by
8
+ * their (required unique) name or description. Deletes refuse objects that are
9
+ * still in use, and the SSID MAC filter refuses to lock out connected clients
10
+ * unless told to.
11
+ */
12
+ import { formatMac, normalizeMac } from './client.js';
13
+ import { MAC_GROUP_TYPE } from './macGroups.js';
14
+ import { ALWAYS_PROFILE_NAME } from './network.js';
15
+ import { accessControlLockKey, serialize } from './serialize.js';
16
+ import { buildTimeRange, describeTimeRange } from './timeRange.js';
17
+ export const IP_GROUP_TYPE = 0;
18
+ /** All protocols, in Omada's ACL protocol numbering. */
19
+ export const ALL_PROTOCOLS = 256;
20
+ const SOURCE_TYPES = { network: 0, ipGroup: 1, ssid: 4 };
21
+ const DESTINATION_TYPES = { network: 0, ipGroup: 1 };
22
+ export class AccessControlOperations {
23
+ request;
24
+ site;
25
+ buildPath;
26
+ network;
27
+ macGroups;
28
+ clients;
29
+ constructor(request, site, buildPath, network, macGroups, clients) {
30
+ this.request = request;
31
+ this.site = site;
32
+ this.buildPath = buildPath;
33
+ this.network = network;
34
+ this.macGroups = macGroups;
35
+ this.clients = clients;
36
+ }
37
+ // Writes are serialized per site, together with MAC group edits: Omada replaces
38
+ // whole objects, and objects reference each other (a rule its time range and
39
+ // groups, an SSID filter its MAC group), so no two changes may interleave.
40
+ createTimeRange(...a) {
41
+ return this.locked(a[2]?.siteId, () => this.createTimeRangeUnlocked(...a));
42
+ }
43
+ updateTimeRange(...a) {
44
+ return this.locked(a[2]?.siteId, () => this.updateTimeRangeUnlocked(...a));
45
+ }
46
+ deleteTimeRange(...a) {
47
+ return this.locked(a[1], () => this.deleteTimeRangeUnlocked(...a));
48
+ }
49
+ createGroup(...a) {
50
+ return this.locked(a[1], () => this.createGroupUnlocked(...a));
51
+ }
52
+ deleteGroup(...a) {
53
+ return this.locked(a[2], () => this.deleteGroupUnlocked(...a));
54
+ }
55
+ setDhcpReservation(...a) {
56
+ return this.locked(a[3], () => this.setDhcpReservationUnlocked(...a));
57
+ }
58
+ removeDhcpReservation(...a) {
59
+ return this.locked(a[1], () => this.removeDhcpReservationUnlocked(...a));
60
+ }
61
+ createGatewayAcl(...a) {
62
+ return this.locked(a[1], () => this.createGatewayAclUnlocked(...a));
63
+ }
64
+ updateGatewayAcl(...a) {
65
+ return this.locked(a[2], () => this.updateGatewayAclUnlocked(...a));
66
+ }
67
+ deleteGatewayAcl(...a) {
68
+ return this.locked(a[1], () => this.deleteGatewayAclUnlocked(...a));
69
+ }
70
+ moveGatewayAcl(...a) {
71
+ return this.locked(a[2], () => this.moveGatewayAclUnlocked(...a));
72
+ }
73
+ setSsidMacFilter(...a) {
74
+ return this.locked(a[2]?.siteId, () => this.setSsidMacFilterUnlocked(...a));
75
+ }
76
+ locked(siteId, task) {
77
+ return serialize(accessControlLockKey(this.site.resolveSiteId(siteId)), task);
78
+ }
79
+ sitePath(siteId, path) {
80
+ return this.buildPath(`/sites/${encodeURIComponent(siteId)}${path}`);
81
+ }
82
+ async send(method, url, data) {
83
+ this.request.ensureSuccess(await this.request.request({ method, url, data }));
84
+ }
85
+ // ---- time-range profiles ------------------------------------------------
86
+ async listTimeRanges(siteId) {
87
+ const resolved = this.site.resolveSiteId(siteId);
88
+ const profiles = this.request.ensureSuccess(await this.request.get(this.sitePath(resolved, '/time-range-profiles')));
89
+ return (profiles ?? []).map((p) => ({ ...p, windows: describeTimeRange(p) }));
90
+ }
91
+ async createTimeRangeUnlocked(name, windows, options = {}) {
92
+ const resolved = this.site.resolveSiteId(options.siteId);
93
+ const body = buildTimeRange(checkTimeRangeName(name), windows, options.invert);
94
+ if ((await this.listTimeRanges(resolved)).some((p) => p.name === body.name)) {
95
+ throw new Error(`A time range named '${body.name}' already exists; update it or pick another name`);
96
+ }
97
+ await this.send('POST', this.sitePath(resolved, '/time-range-profiles'), body);
98
+ const created = (await this.listTimeRanges(resolved)).find((p) => p.name === body.name);
99
+ if (!created)
100
+ throw new Error(`Created time range '${body.name}' but could not find it again`);
101
+ return { profileId: created.profileId, name: created.name, windows: created.windows };
102
+ }
103
+ async updateTimeRangeUnlocked(profile, windows, options = {}) {
104
+ const resolved = this.site.resolveSiteId(options.siteId);
105
+ const current = this.resolveTimeRange(await this.listTimeRanges(resolved), profile);
106
+ const name = options.name !== undefined ? checkTimeRangeName(options.name) : current.name;
107
+ const body = buildTimeRange(name, windows, options.invert);
108
+ await this.send('PUT', this.sitePath(resolved, `/time-range-profile/${encodeURIComponent(current.profileId)}`), body);
109
+ return { profileId: current.profileId, name, before: current.windows, after: describeTimeRange(body) };
110
+ }
111
+ async deleteTimeRangeUnlocked(profile, siteId) {
112
+ const resolved = this.site.resolveSiteId(siteId);
113
+ const current = this.resolveTimeRange(await this.listTimeRanges(resolved), profile);
114
+ const users = await this.timeRangeUsers(current.profileId, resolved);
115
+ if (users.length)
116
+ throw new Error(`Time range '${current.name}' is used by ${users.join(', ')}; change or delete those first`);
117
+ await this.send('DELETE', this.sitePath(resolved, `/time-range-profile/${encodeURIComponent(current.profileId)}`));
118
+ return { profileId: current.profileId, name: current.name, deleted: true };
119
+ }
120
+ /** What references a time range: gateway and switch ACL rules, SSID WLAN schedules. */
121
+ async timeRangeUsers(profileId, siteId) {
122
+ const users = (await this.listGatewayAcls(siteId)).filter((a) => a.timeRangeId === profileId).map((a) => `gateway ACL '${a.description}'`);
123
+ const switchAcls = await this.request.fetchPaginated(this.sitePath(siteId, '/acls/osw-acls'));
124
+ users.push(...switchAcls.filter((a) => a.timeRangeId === profileId).map((a) => `switch ACL '${a.description}'`));
125
+ for (const wlan of await this.network.listAllSsids(siteId)) {
126
+ for (const ssid of wlan.ssidList ?? []) {
127
+ const detail = (await this.network.getSsidDetail(wlan.wlanId, ssid.ssidId, siteId));
128
+ if (detail?.wlanSchedule?.scheduleId === profileId)
129
+ users.push(`the Wi-Fi schedule of SSID ${ssid.ssidName}`);
130
+ }
131
+ }
132
+ return users;
133
+ }
134
+ resolveTimeRange(profiles, profile) {
135
+ const found = resolveByIdOrName(profiles, profile, (p) => p.profileId, (p) => p.name, 'time range');
136
+ if (found.name === ALWAYS_PROFILE_NAME) {
137
+ throw new Error(`Time range '${found.name}' belongs to omada_setSsidEnabled and cannot be changed here`);
138
+ }
139
+ return found;
140
+ }
141
+ // ---- group profiles -------------------------------------------------------
142
+ async listIpGroups(siteId) {
143
+ const resolved = this.site.resolveSiteId(siteId);
144
+ const groups = this.request.ensureSuccess(await this.request.get(this.sitePath(resolved, `/profiles/groups/${IP_GROUP_TYPE}`)));
145
+ return groups ?? [];
146
+ }
147
+ /** Create an IP group (addresses as "a.b.c.d" or "a.b.c.d/n") or a MAC group. */
148
+ async createGroupUnlocked(input, siteId) {
149
+ const resolved = this.site.resolveSiteId(siteId);
150
+ const name = input.name.trim();
151
+ if (name.length < 1 || name.length > 64)
152
+ throw new Error('Group name must be 1 to 64 characters');
153
+ const existing = input.type === 'ip' ? await this.listIpGroups(resolved) : await this.macGroups.listMacGroups(resolved);
154
+ if (existing.some((g) => g.name.toLowerCase() === name.toLowerCase())) {
155
+ throw new Error(`A ${input.type.toUpperCase()} group named '${name}' already exists`);
156
+ }
157
+ const body = input.type === 'ip'
158
+ ? { name, type: IP_GROUP_TYPE, ipList: input.ips.map(parseCidr) }
159
+ : { name, type: MAC_GROUP_TYPE, macAddressList: input.macs.map((m) => ({ name: m.name, macAddress: formatMac(m.mac) })) };
160
+ if ((input.type === 'ip' ? input.ips : input.macs).length === 0)
161
+ throw new Error('A group needs at least one entry');
162
+ await this.send('POST', this.sitePath(resolved, '/profiles/groups'), body);
163
+ const after = input.type === 'ip' ? await this.listIpGroups(resolved) : await this.macGroups.listMacGroups(resolved);
164
+ const created = after.find((g) => g.name === name);
165
+ if (!created)
166
+ throw new Error(`Created group '${name}' but could not find it again`);
167
+ return { groupId: created.groupId, name, type: input.type, entries: input.type === 'ip' ? body.ipList : body.macAddressList };
168
+ }
169
+ async deleteGroupUnlocked(group, type, siteId) {
170
+ const resolved = this.site.resolveSiteId(siteId);
171
+ const groups = type === 'ip' ? await this.listIpGroups(resolved) : await this.macGroups.listMacGroups(resolved);
172
+ const target = resolveByIdOrName(groups, group, (g) => g.groupId, (g) => g.name, `${type.toUpperCase()} group`);
173
+ if (target.buildIn || target.name === 'IPGroup_Any')
174
+ throw new Error(`Group '${target.name}' is built in and cannot be deleted`);
175
+ const users = [];
176
+ for (const acl of await this.listGatewayAcls(resolved)) {
177
+ const asSource = acl.sourceType === SOURCE_TYPES.ipGroup && acl.sourceIds.includes(target.groupId);
178
+ const asDestination = acl.destinationType === DESTINATION_TYPES.ipGroup && (acl.destinationIds ?? []).includes(target.groupId);
179
+ if (asSource || asDestination)
180
+ users.push(`gateway ACL '${acl.description}'`);
181
+ }
182
+ if (type === 'mac') {
183
+ for (const s of await this.listSsidFilters(resolved)) {
184
+ if (s.filter.macFilterId === target.groupId)
185
+ users.push(`the MAC filter of SSID ${s.ssidName}`);
186
+ }
187
+ }
188
+ if (users.length)
189
+ throw new Error(`Group '${target.name}' is used by ${users.join(', ')}; change those first`);
190
+ const groupType = type === 'ip' ? IP_GROUP_TYPE : MAC_GROUP_TYPE;
191
+ await this.send('DELETE', this.sitePath(resolved, `/profiles/groups/${groupType}/${encodeURIComponent(target.groupId)}`));
192
+ return { groupId: target.groupId, name: target.name, type, deleted: true };
193
+ }
194
+ // ---- DHCP reservations -----------------------------------------------------
195
+ async listDhcpReservations(siteId) {
196
+ const resolved = this.site.resolveSiteId(siteId);
197
+ return await this.request.fetchPaginated(this.sitePath(resolved, '/setting/service/dhcp'));
198
+ }
199
+ /** Reserve `ip` for a MAC (create or change). The LAN network is the one whose subnet holds the IP. */
200
+ async setDhcpReservationUnlocked(clientMac, ip, description, siteId) {
201
+ const resolved = this.site.resolveSiteId(siteId);
202
+ const mac = formatMac(clientMac);
203
+ const address = ipToNumber(ip);
204
+ const networks = (await this.network.getLanNetworkList(resolved));
205
+ const net = networks.find((n) => n.gatewaySubnet && inSubnet(address, n.gatewaySubnet));
206
+ if (!net) {
207
+ throw new Error(`${ip} is in no LAN network (${networks.map((n) => `${n.name} ${n.gatewaySubnet ?? '?'}`).join(', ') || 'none'})`);
208
+ }
209
+ const reservations = await this.listDhcpReservations(resolved);
210
+ const clash = reservations.find((r) => r.ip === ip && normalizeMac(r.mac) !== normalizeMac(mac));
211
+ if (clash)
212
+ throw new Error(`${ip} is already reserved for ${clash.mac}${clash.description ? ` (${clash.description})` : ''}`);
213
+ const current = reservations.find((r) => normalizeMac(r.mac) === normalizeMac(mac));
214
+ const text = description?.trim() || current?.description;
215
+ if (text !== undefined && text.length > 128)
216
+ throw new Error('Description must be at most 128 characters');
217
+ if (current && current.ip === ip && current.netId === net.id && current.status !== false && current.description === text) {
218
+ return { mac, ip, network: net.name, action: 'unchanged' };
219
+ }
220
+ const body = { netId: net.id, mac, ip, description: text || undefined, status: true, options: current?.options ?? [] };
221
+ if (current) {
222
+ await this.send('PATCH', this.sitePath(resolved, `/setting/service/dhcp/${encodeURIComponent(mac)}`), body);
223
+ }
224
+ else {
225
+ await this.send('POST', this.sitePath(resolved, '/setting/service/dhcp'), body);
226
+ }
227
+ return {
228
+ mac,
229
+ ip,
230
+ network: net.name,
231
+ action: current ? 'updated' : 'created',
232
+ ...(current ? { previousIp: current.ip } : {}),
233
+ note: 'The device gets the reserved address at its next DHCP renewal (reconnect it to apply now).',
234
+ };
235
+ }
236
+ async removeDhcpReservationUnlocked(clientMac, siteId) {
237
+ const resolved = this.site.resolveSiteId(siteId);
238
+ const mac = formatMac(clientMac);
239
+ const current = (await this.listDhcpReservations(resolved)).find((r) => normalizeMac(r.mac) === normalizeMac(mac));
240
+ if (!current)
241
+ return { mac, action: 'not-present' };
242
+ await this.send('DELETE', this.sitePath(resolved, `/setting/service/dhcp/${encodeURIComponent(formatMac(current.mac))}`));
243
+ return { mac, ip: current.ip, action: 'removed' };
244
+ }
245
+ // ---- gateway ACL -------------------------------------------------------------
246
+ async listGatewayAcls(siteId) {
247
+ const resolved = this.site.resolveSiteId(siteId);
248
+ const acls = await this.request.fetchPaginated(this.sitePath(resolved, '/acls/osg-acls'));
249
+ return [...acls].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
250
+ }
251
+ async createGatewayAclUnlocked(input, siteId) {
252
+ const resolved = this.site.resolveSiteId(siteId);
253
+ const description = checkDescription(input.description);
254
+ const existing = await this.listGatewayAcls(resolved);
255
+ if (existing.some((a) => a.description === description)) {
256
+ throw new Error(`A gateway ACL described '${description}' already exists; descriptions must be unique`);
257
+ }
258
+ const body = {
259
+ description,
260
+ status: input.enabled ?? true,
261
+ policy: input.policy === 'allow' ? 1 : 0,
262
+ protocols: input.protocols?.length ? input.protocols : [ALL_PROTOCOLS],
263
+ ...(await this.resolveEndpoints(input.source, input.destination, resolved)),
264
+ syslog: false,
265
+ direction: { lanToWan: true, lanToLan: false, wanInIds: [], vpnInIds: [] },
266
+ stateMode: 0,
267
+ };
268
+ if (input.timeRange)
269
+ body.timeRangeId = await this.timeRangeId(input.timeRange, resolved);
270
+ await this.send('POST', this.sitePath(resolved, '/acls/osg-acls'), body);
271
+ const created = (await this.listGatewayAcls(resolved)).find((a) => a.description === description);
272
+ if (!created)
273
+ throw new Error(`Created gateway ACL '${description}' but could not find it again`);
274
+ return await this.describeAcl(created, resolved);
275
+ }
276
+ async updateGatewayAclUnlocked(acl, changes, siteId) {
277
+ const resolved = this.site.resolveSiteId(siteId);
278
+ const acls = await this.listGatewayAcls(resolved);
279
+ const current = resolveByIdOrName(acls, acl, (a) => a.id, (a) => a.description, 'gateway ACL');
280
+ const description = changes.description !== undefined ? checkDescription(changes.description) : current.description;
281
+ if (description !== current.description && acls.some((a) => a.description === description)) {
282
+ throw new Error(`A gateway ACL described '${description}' already exists`);
283
+ }
284
+ const body = {
285
+ description,
286
+ status: changes.enabled ?? current.status,
287
+ policy: changes.policy ? (changes.policy === 'allow' ? 1 : 0) : current.policy,
288
+ protocols: changes.protocols?.length ? changes.protocols : current.protocols,
289
+ sourceType: current.sourceType,
290
+ sourceIds: current.sourceIds,
291
+ destinationType: current.destinationType,
292
+ destinationIds: current.destinationIds ?? [],
293
+ syslog: current.syslog ?? false,
294
+ direction: current.direction ?? { lanToWan: true, lanToLan: false, wanInIds: [], vpnInIds: [] },
295
+ stateMode: current.stateMode ?? 0,
296
+ ...(current.states ? { states: current.states } : {}),
297
+ };
298
+ if (changes.source || changes.destination) {
299
+ const endpoints = await this.resolveEndpoints(changes.source ?? { type: typeName(SOURCE_TYPES, current.sourceType), ids: current.sourceIds }, changes.destination ?? { type: typeName(DESTINATION_TYPES, current.destinationType), ids: current.destinationIds ?? [] }, resolved);
300
+ Object.assign(body, endpoints);
301
+ }
302
+ const timeRangeId = changes.timeRange === undefined ? current.timeRangeId : changes.timeRange === null ? undefined : await this.timeRangeId(changes.timeRange, resolved);
303
+ if (timeRangeId)
304
+ body.timeRangeId = timeRangeId;
305
+ // Re-read right before writing; refuse if the rule changed in between (e.g. in the web UI).
306
+ const latest = (await this.listGatewayAcls(resolved)).find((a) => a.id === current.id);
307
+ if (!latest || JSON.stringify(latest) !== JSON.stringify(current)) {
308
+ throw new Error(`Gateway ACL '${current.description}' changed while preparing the update; nothing was written. Try again.`);
309
+ }
310
+ await this.send('PUT', this.sitePath(resolved, `/acls/osg-acls/${encodeURIComponent(current.id)}`), body);
311
+ const updated = (await this.listGatewayAcls(resolved)).find((a) => a.id === current.id) ?? { ...current, ...body };
312
+ return await this.describeAcl(updated, resolved);
313
+ }
314
+ async deleteGatewayAclUnlocked(acl, siteId) {
315
+ const resolved = this.site.resolveSiteId(siteId);
316
+ const current = resolveByIdOrName(await this.listGatewayAcls(resolved), acl, (a) => a.id, (a) => a.description, 'gateway ACL');
317
+ await this.send('DELETE', this.sitePath(resolved, `/acls/${encodeURIComponent(current.id)}`));
318
+ return { id: current.id, description: current.description, deleted: true };
319
+ }
320
+ /** Move a rule to `position` (1 = evaluated first); the others keep their order. */
321
+ async moveGatewayAclUnlocked(acl, position, siteId) {
322
+ const resolved = this.site.resolveSiteId(siteId);
323
+ const acls = await this.listGatewayAcls(resolved);
324
+ const current = resolveByIdOrName(acls, acl, (a) => a.id, (a) => a.description, 'gateway ACL');
325
+ if (!Number.isInteger(position) || position < 1 || position > acls.length) {
326
+ throw new Error(`Position must be 1 to ${acls.length}`);
327
+ }
328
+ const order = acls.filter((a) => a.id !== current.id);
329
+ order.splice(position - 1, 0, current);
330
+ const indexes = Object.fromEntries(order.map((a, i) => [a.id, i + 1]));
331
+ await this.send('POST', this.sitePath(resolved, '/acls/modifyIndex'), { type: 'gateway', indexes });
332
+ return { order: order.map((a, i) => `${i + 1}. ${a.description}`) };
333
+ }
334
+ /** A rule with names instead of ids, for responses. */
335
+ async describeAcl(acl, siteId) {
336
+ const resolved = this.site.resolveSiteId(siteId);
337
+ const names = await this.endpointNames(resolved);
338
+ // Display only: a type these tools do not edit (e.g. an IP-port group) is shown by its number.
339
+ const label = (type, ids, table) => `${Object.keys(table).find((key) => table[key] === type) ?? `type ${type}`}: ${(ids ?? []).map((id) => names.get(id) ?? id).join(', ') || '(none)'}`;
340
+ const ranges = await this.listTimeRanges(resolved);
341
+ const range = acl.timeRangeId ? ranges.find((p) => p.profileId === acl.timeRangeId) : undefined;
342
+ return {
343
+ id: acl.id,
344
+ position: acl.index,
345
+ description: acl.description,
346
+ enabled: acl.status,
347
+ policy: acl.policy === 1 ? 'allow' : 'deny',
348
+ source: label(acl.sourceType, acl.sourceIds, SOURCE_TYPES),
349
+ destination: label(acl.destinationType, acl.destinationIds, DESTINATION_TYPES),
350
+ schedule: acl.timeRangeId ? { profileId: acl.timeRangeId, name: range?.name, windows: range?.windows } : 'always',
351
+ };
352
+ }
353
+ async resolveEndpoints(source, destination, siteId) {
354
+ if (!(source.type in SOURCE_TYPES))
355
+ throw new Error(`Source type must be one of ${Object.keys(SOURCE_TYPES).join(', ')}`);
356
+ if (source.ids.length === 0)
357
+ throw new Error('The rule needs at least one source');
358
+ const dest = destination ?? { type: 'ipGroup', ids: ['IPGroup_Any'] };
359
+ if (!(dest.type in DESTINATION_TYPES))
360
+ throw new Error(`Destination type must be one of ${Object.keys(DESTINATION_TYPES).join(', ')}`);
361
+ if (dest.ids.length === 0)
362
+ throw new Error('The rule needs at least one destination');
363
+ return {
364
+ sourceType: SOURCE_TYPES[source.type],
365
+ sourceIds: await this.resolveIds(source.type, source.ids, siteId),
366
+ destinationType: DESTINATION_TYPES[dest.type],
367
+ destinationIds: await this.resolveIds(dest.type, dest.ids, siteId),
368
+ };
369
+ }
370
+ /** Ids or names of IP groups, LAN networks or SSIDs -> ids. */
371
+ async resolveIds(type, values, siteId) {
372
+ const candidates = type === 'ipGroup'
373
+ ? (await this.listIpGroups(siteId)).map((g) => ({ id: g.groupId, name: g.name }))
374
+ : type === 'network'
375
+ ? (await this.network.getLanNetworkList(siteId)).map((n) => ({ id: n.id, name: n.name }))
376
+ : (await this.network.listAllSsids(siteId)).flatMap((w) => (w.ssidList ?? []).map((s) => ({ id: s.ssidId, name: s.ssidName })));
377
+ return values.map((v) => resolveByIdOrName(candidates, v, (c) => c.id, (c) => c.name, typeLabel(type)).id);
378
+ }
379
+ async endpointNames(siteId) {
380
+ const names = new Map();
381
+ const safe = async (read) => await read().catch(() => []);
382
+ for (const g of await safe(() => this.listIpGroups(siteId)))
383
+ names.set(g.groupId, g.name);
384
+ for (const n of await safe(() => this.network.getLanNetworkList(siteId)))
385
+ names.set(n.id, n.name);
386
+ for (const w of await safe(() => this.network.listAllSsids(siteId)))
387
+ for (const s of w.ssidList ?? [])
388
+ names.set(s.ssidId, s.ssidName);
389
+ return names;
390
+ }
391
+ async timeRangeId(profile, siteId) {
392
+ return resolveByIdOrName(await this.listTimeRanges(siteId), profile, (p) => p.profileId, (p) => p.name, 'time range').profileId;
393
+ }
394
+ // ---- SSID MAC filter -----------------------------------------------------------
395
+ async listSsidFilters(siteId) {
396
+ const result = [];
397
+ for (const wlan of await this.network.listAllSsids(siteId)) {
398
+ for (const s of wlan.ssidList ?? []) {
399
+ const detail = (await this.network.getSsidDetail(wlan.wlanId, s.ssidId, siteId));
400
+ result.push({ wlanId: wlan.wlanId, ssidId: s.ssidId, ssidName: s.ssidName, filter: (detail?.macFilter ?? {}) });
401
+ }
402
+ }
403
+ return result;
404
+ }
405
+ /**
406
+ * Turn an SSID's MAC filter on (allow or deny list = a MAC group) or off.
407
+ * Reports which connected clients of that SSID the new setting would cut off,
408
+ * and refuses to apply then unless `allowLockout` is set. dryRun only reports.
409
+ */
410
+ async setSsidMacFilterUnlocked(ssid, setting, options = {}) {
411
+ const resolved = this.site.resolveSiteId(options.siteId);
412
+ const filters = await this.listSsidFilters(resolved);
413
+ const target = resolveByIdOrName(filters, ssid, (f) => f.ssidId, (f) => f.ssidName, 'SSID');
414
+ const groups = await this.macGroups.listMacGroups(resolved);
415
+ const groupName = (id) => groups.find((g) => g.groupId === id)?.name ?? id;
416
+ const policyName = (p) => (p === undefined ? undefined : p === 1 ? 'allow' : 'deny');
417
+ const before = { enabled: target.filter.macFilterEnable === true, policy: policyName(target.filter.policy), group: groupName(target.filter.macFilterId) };
418
+ let after = { enabled: false, policy: before.policy, group: before.group };
419
+ let body = { macFilterEnable: false };
420
+ let wouldLockOut = [];
421
+ if (setting.enabled) {
422
+ const policy = setting.policy ?? before.policy;
423
+ if (!policy)
424
+ throw new Error('Say whether the group is an allow list or a deny list (policy)');
425
+ const groupKey = setting.group ?? target.filter.macFilterId;
426
+ if (!groupKey)
427
+ throw new Error('Name the MAC group to filter by (group)');
428
+ const group = this.macGroups.resolveGroup(groups, groupKey);
429
+ const members = new Set((group.macAddressList ?? []).map((e) => normalizeMac(e.macAddress)));
430
+ const connected = (await this.clients.listClients(resolved)).filter((c) => c.ssid === target.ssidName);
431
+ wouldLockOut = connected
432
+ .filter((c) => (policy === 'allow' ? !members.has(normalizeMac(c.mac)) : members.has(normalizeMac(c.mac))))
433
+ .map((c) => ({ mac: formatMac(c.mac), name: c.name }));
434
+ after = { enabled: true, policy, group: group.name };
435
+ body = { macFilterEnable: true, policy: policy === 'allow' ? 1 : 0, macFilterId: group.groupId };
436
+ }
437
+ const change = { ssid: target.ssidName, ssidId: target.ssidId, before, after, wouldLockOut, applied: false };
438
+ if (options.dryRun)
439
+ return change;
440
+ if (wouldLockOut.length && !options.allowLockout) {
441
+ throw new Error(`This would disconnect ${wouldLockOut.length} connected client(s) of ${target.ssidName}: ` +
442
+ `${wouldLockOut.map((c) => `${c.name ?? '?'} (${c.mac})`).join(', ')}. ` +
443
+ 'Add them to the group first, or repeat with allowLockout if that is intended. Nothing was changed.');
444
+ }
445
+ await this.send('PATCH', this.sitePath(resolved, `/wireless-network/wlans/${encodeURIComponent(target.wlanId)}/ssids/${encodeURIComponent(target.ssidId)}/update-mac-filter`), body);
446
+ return { ...change, applied: true };
447
+ }
448
+ }
449
+ /** A user profile must not take the reserved name omada_setSsidEnabled finds its 24/7 profile by. */
450
+ function checkTimeRangeName(value) {
451
+ const name = value.trim();
452
+ if (name.length < 1 || name.length > 64)
453
+ throw new Error('Time range name must be 1 to 64 characters');
454
+ if (name === ALWAYS_PROFILE_NAME)
455
+ throw new Error(`The name '${ALWAYS_PROFILE_NAME}' is reserved for omada_setSsidEnabled`);
456
+ return name;
457
+ }
458
+ function resolveByIdOrName(items, wanted, id, name, what) {
459
+ const byId = items.find((item) => id(item) === wanted);
460
+ if (byId)
461
+ return byId;
462
+ const needle = wanted.trim().toLowerCase();
463
+ const byName = items.filter((item) => name(item).toLowerCase() === needle);
464
+ if (byName.length === 1)
465
+ return byName[0];
466
+ if (byName.length > 1)
467
+ throw new Error(`Several ${what}s are named '${wanted}'; use the id`);
468
+ const available = items.map((item) => `${name(item)} (${id(item)})`).join(', ');
469
+ throw new Error(`${what[0].toUpperCase()}${what.slice(1)} '${wanted}' not found. Available: ${available || '(none)'}`);
470
+ }
471
+ function typeName(table, value) {
472
+ const found = Object.keys(table).find((key) => table[key] === value);
473
+ if (!found)
474
+ throw new Error(`This rule uses an endpoint type (${value}) these tools do not handle; edit it in the Omada web UI`);
475
+ return found;
476
+ }
477
+ function typeLabel(type) {
478
+ return type === 'ipGroup' ? 'IP group' : type === 'network' ? 'LAN network' : 'SSID';
479
+ }
480
+ function checkDescription(value) {
481
+ const text = value.trim();
482
+ if (text.length < 1 || text.length > 512)
483
+ throw new Error('Description must be 1 to 512 characters');
484
+ return text;
485
+ }
486
+ function ipToNumber(ip) {
487
+ const parts = ip.trim().split('.');
488
+ if (parts.length !== 4 || parts.some((p) => !/^\d{1,3}$/.test(p) || Number(p) > 255)) {
489
+ throw new Error(`'${ip}' is not an IPv4 address`);
490
+ }
491
+ return parts.reduce((n, p) => n * 256 + Number(p), 0);
492
+ }
493
+ function inSubnet(address, cidr) {
494
+ const [base, bits] = cidr.split('/');
495
+ const mask = Number(bits);
496
+ if (!base || !Number.isInteger(mask) || mask < 0 || mask > 32)
497
+ return false;
498
+ const size = 2 ** (32 - mask);
499
+ return Math.floor(address / size) === Math.floor(ipToNumber(base) / size);
500
+ }
501
+ function parseCidr(value) {
502
+ const [ip, bits] = value.trim().split('/');
503
+ ipToNumber(ip);
504
+ const mask = bits === undefined ? 32 : Number(bits);
505
+ if (!Number.isInteger(mask) || mask < 1 || mask > 32)
506
+ throw new Error(`'${value}': the mask must be 1 to 32`);
507
+ return { ip, mask };
508
+ }
509
+ //# sourceMappingURL=accessControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessControl.js","sourceRoot":"","sources":["../../src/omadaClient/accessControl.ts"],"names":[],"mappings":"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"}
@@ -127,5 +127,10 @@ export interface KnownClient {
127
127
  block?: boolean;
128
128
  [field: string]: unknown;
129
129
  }
130
- /** "4c:1d:96:8d:37:c7", "4C-1D-96-8D-37-C7" and "4c1d968d37c7" compare equal. */
130
+ /**
131
+ * A complete MAC in Omada's format (AA-BB-CC-DD-EE-FF). Anything that is not
132
+ * exactly 12 hex digits is refused, so a write never runs with a partial MAC.
133
+ */
134
+ export declare function formatMac(mac: string): string;
135
+ /** "02:1a:2b:3c:4d:5e", "02-1A-2B-3C-4D-5E" and "021a2b3c4d5e" compare equal. */
131
136
  export declare function normalizeMac(mac: string): string;
@@ -252,7 +252,18 @@ export class ClientOperations {
252
252
  }
253
253
  /** Omada error code: "This client does not exist." */
254
254
  export const CLIENT_DOES_NOT_EXIST = -41004;
255
- /** "4c:1d:96:8d:37:c7", "4C-1D-96-8D-37-C7" and "4c1d968d37c7" compare equal. */
255
+ /**
256
+ * A complete MAC in Omada's format (AA-BB-CC-DD-EE-FF). Anything that is not
257
+ * exactly 12 hex digits is refused, so a write never runs with a partial MAC.
258
+ */
259
+ export function formatMac(mac) {
260
+ const hex = normalizeMac(mac);
261
+ if (!/^[0-9A-F]{12}$/.test(hex)) {
262
+ throw new Error(`'${mac}' is not a complete MAC address (expected 12 hex digits, e.g. 02-1A-2B-3C-4D-5E)`);
263
+ }
264
+ return hex.match(/../g).join('-');
265
+ }
266
+ /** "02:1a:2b:3c:4d:5e", "02-1A-2B-3C-4D-5E" and "021a2b3c4d5e" compare equal. */
256
267
  export function normalizeMac(mac) {
257
268
  return mac.replace(/[^0-9a-f]/gi, '').toUpperCase();
258
269
  }