homebridge-config-ui-x 5.9.1-beta.0 → 5.9.1-beta.2

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 (359) hide show
  1. package/CHANGELOG.md +7 -2
  2. package/dist/app.controller.d.ts +1 -1
  3. package/dist/app.controller.js +14 -12
  4. package/dist/app.controller.js.map +1 -1
  5. package/dist/app.gateway.js +7 -10
  6. package/dist/app.gateway.js.map +1 -1
  7. package/dist/app.module.js +40 -43
  8. package/dist/app.module.js.map +1 -1
  9. package/dist/app.service.js +4 -7
  10. package/dist/app.service.js.map +1 -1
  11. package/dist/bin/base-platform.d.ts +1 -1
  12. package/dist/bin/base-platform.js +11 -17
  13. package/dist/bin/base-platform.js.map +1 -1
  14. package/dist/bin/fork.js +7 -45
  15. package/dist/bin/fork.js.map +1 -1
  16. package/dist/bin/hb-service.js +224 -243
  17. package/dist/bin/hb-service.js.map +1 -1
  18. package/dist/bin/platforms/darwin.d.ts +1 -1
  19. package/dist/bin/platforms/darwin.js +61 -65
  20. package/dist/bin/platforms/darwin.js.map +1 -1
  21. package/dist/bin/platforms/freebsd.d.ts +1 -1
  22. package/dist/bin/platforms/freebsd.js +42 -47
  23. package/dist/bin/platforms/freebsd.js.map +1 -1
  24. package/dist/bin/platforms/linux.d.ts +1 -1
  25. package/dist/bin/platforms/linux.js +127 -132
  26. package/dist/bin/platforms/linux.js.map +1 -1
  27. package/dist/bin/platforms/win32.d.ts +1 -1
  28. package/dist/bin/platforms/win32.js +30 -36
  29. package/dist/bin/platforms/win32.js.map +1 -1
  30. package/dist/bin/standalone.js +15 -53
  31. package/dist/bin/standalone.js.map +1 -1
  32. package/dist/core/auth/auth.controller.d.ts +3 -3
  33. package/dist/core/auth/auth.controller.js +40 -39
  34. package/dist/core/auth/auth.controller.js.map +1 -1
  35. package/dist/core/auth/auth.dto.js +17 -18
  36. package/dist/core/auth/auth.dto.js.map +1 -1
  37. package/dist/core/auth/auth.module.js +28 -31
  38. package/dist/core/auth/auth.module.js.map +1 -1
  39. package/dist/core/auth/auth.service.d.ts +3 -3
  40. package/dist/core/auth/auth.service.js +65 -62
  41. package/dist/core/auth/auth.service.js.map +1 -1
  42. package/dist/core/auth/guards/admin.guard.js +4 -7
  43. package/dist/core/auth/guards/admin.guard.js.map +1 -1
  44. package/dist/core/auth/guards/custom.guard.js +6 -9
  45. package/dist/core/auth/guards/custom.guard.js.map +1 -1
  46. package/dist/core/auth/guards/ws-admin-guard.d.ts +1 -1
  47. package/dist/core/auth/guards/ws-admin-guard.js +13 -11
  48. package/dist/core/auth/guards/ws-admin-guard.js.map +1 -1
  49. package/dist/core/auth/guards/ws.guard.d.ts +1 -1
  50. package/dist/core/auth/guards/ws.guard.js +13 -11
  51. package/dist/core/auth/guards/ws.guard.js.map +1 -1
  52. package/dist/core/auth/jwt.strategy.d.ts +3 -2
  53. package/dist/core/auth/jwt.strategy.js +21 -16
  54. package/dist/core/auth/jwt.strategy.js.map +1 -1
  55. package/dist/core/config/config.interfaces.js +1 -2
  56. package/dist/core/config/config.module.js +8 -10
  57. package/dist/core/config/config.module.js.map +1 -1
  58. package/dist/core/config/config.service.d.ts +2 -2
  59. package/dist/core/config/config.service.js +88 -82
  60. package/dist/core/config/config.service.js.map +1 -1
  61. package/dist/core/config/config.startup.d.ts +1 -1
  62. package/dist/core/config/config.startup.js +23 -28
  63. package/dist/core/config/config.startup.js.map +1 -1
  64. package/dist/core/feature-flags/feature-flags.registry.js +1 -4
  65. package/dist/core/feature-flags/feature-flags.registry.js.map +1 -1
  66. package/dist/core/homebridge-ipc/homebridge-ipc.module.js +11 -14
  67. package/dist/core/homebridge-ipc/homebridge-ipc.module.js.map +1 -1
  68. package/dist/core/homebridge-ipc/homebridge-ipc.service.d.ts +2 -2
  69. package/dist/core/homebridge-ipc/homebridge-ipc.service.js +24 -19
  70. package/dist/core/homebridge-ipc/homebridge-ipc.service.js.map +1 -1
  71. package/dist/core/logger/logger.module.js +8 -10
  72. package/dist/core/logger/logger.module.js.map +1 -1
  73. package/dist/core/logger/logger.service.js +13 -23
  74. package/dist/core/logger/logger.service.js.map +1 -1
  75. package/dist/core/node-pty/node-pty.module.js +7 -10
  76. package/dist/core/node-pty/node-pty.module.js.map +1 -1
  77. package/dist/core/node-pty/node-pty.service.js +6 -11
  78. package/dist/core/node-pty/node-pty.service.js.map +1 -1
  79. package/dist/core/node-version.constants.js +4 -11
  80. package/dist/core/node-version.constants.js.map +1 -1
  81. package/dist/core/scheduler/scheduler.module.js +7 -10
  82. package/dist/core/scheduler/scheduler.module.js.map +1 -1
  83. package/dist/core/scheduler/scheduler.service.js +9 -14
  84. package/dist/core/scheduler/scheduler.service.js.map +1 -1
  85. package/dist/core/spa/spa-html.service.js +9 -15
  86. package/dist/core/spa/spa-html.service.js.map +1 -1
  87. package/dist/core/spa/spa.filter.d.ts +1 -1
  88. package/dist/core/spa/spa.filter.js +11 -16
  89. package/dist/core/spa/spa.filter.js.map +1 -1
  90. package/dist/core/ssl/ssl-cert-generator.service.d.ts +1 -1
  91. package/dist/core/ssl/ssl-cert-generator.service.js +34 -36
  92. package/dist/core/ssl/ssl-cert-generator.service.js.map +1 -1
  93. package/dist/env-setup.d.ts +1 -0
  94. package/dist/env-setup.js +7 -0
  95. package/dist/env-setup.js.map +1 -0
  96. package/dist/globalDefaults.d.ts +1 -0
  97. package/dist/globalDefaults.js +1 -0
  98. package/dist/index.d.ts +1 -1
  99. package/dist/index.js +16 -19
  100. package/dist/index.js.map +1 -1
  101. package/dist/main.d.ts +5 -3
  102. package/dist/main.js +44 -51
  103. package/dist/main.js.map +1 -1
  104. package/dist/modules/accessories/accessories.controller.d.ts +2 -2
  105. package/dist/modules/accessories/accessories.controller.js +27 -29
  106. package/dist/modules/accessories/accessories.controller.js.map +1 -1
  107. package/dist/modules/accessories/accessories.dto.js +11 -13
  108. package/dist/modules/accessories/accessories.dto.js.map +1 -1
  109. package/dist/modules/accessories/accessories.gateway.d.ts +1 -1
  110. package/dist/modules/accessories/accessories.gateway.js +18 -16
  111. package/dist/modules/accessories/accessories.gateway.js.map +1 -1
  112. package/dist/modules/accessories/accessories.module.js +17 -20
  113. package/dist/modules/accessories/accessories.module.js.map +1 -1
  114. package/dist/modules/accessories/accessories.service.d.ts +2 -2
  115. package/dist/modules/accessories/accessories.service.js +37 -35
  116. package/dist/modules/accessories/accessories.service.js.map +1 -1
  117. package/dist/modules/backup/backup.controller.d.ts +2 -2
  118. package/dist/modules/backup/backup.controller.js +68 -67
  119. package/dist/modules/backup/backup.controller.js.map +1 -1
  120. package/dist/modules/backup/backup.gateway.d.ts +2 -2
  121. package/dist/modules/backup/backup.gateway.js +25 -21
  122. package/dist/modules/backup/backup.gateway.js.map +1 -1
  123. package/dist/modules/backup/backup.module.js +22 -25
  124. package/dist/modules/backup/backup.module.js.map +1 -1
  125. package/dist/modules/backup/backup.service.d.ts +5 -5
  126. package/dist/modules/backup/backup.service.js +143 -133
  127. package/dist/modules/backup/backup.service.js.map +1 -1
  128. package/dist/modules/child-bridges/child-bridges.gateway.d.ts +2 -2
  129. package/dist/modules/child-bridges/child-bridges.gateway.js +23 -21
  130. package/dist/modules/child-bridges/child-bridges.gateway.js.map +1 -1
  131. package/dist/modules/child-bridges/child-bridges.interfaces.js +1 -2
  132. package/dist/modules/child-bridges/child-bridges.module.js +19 -22
  133. package/dist/modules/child-bridges/child-bridges.module.js.map +1 -1
  134. package/dist/modules/child-bridges/child-bridges.service.d.ts +3 -3
  135. package/dist/modules/child-bridges/child-bridges.service.js +15 -11
  136. package/dist/modules/child-bridges/child-bridges.service.js.map +1 -1
  137. package/dist/modules/config-editor/config-editor.controller.d.ts +6 -6
  138. package/dist/modules/config-editor/config-editor.controller.js +94 -95
  139. package/dist/modules/config-editor/config-editor.controller.js.map +1 -1
  140. package/dist/modules/config-editor/config-editor.module.js +21 -24
  141. package/dist/modules/config-editor/config-editor.module.js.map +1 -1
  142. package/dist/modules/config-editor/config-editor.service.d.ts +6 -6
  143. package/dist/modules/config-editor/config-editor.service.js +65 -57
  144. package/dist/modules/config-editor/config-editor.service.js.map +1 -1
  145. package/dist/modules/custom-plugins/custom-plugins.module.js +10 -13
  146. package/dist/modules/custom-plugins/custom-plugins.module.js.map +1 -1
  147. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.controller.d.ts +1 -1
  148. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.controller.js +21 -19
  149. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.controller.js.map +1 -1
  150. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.module.js +14 -17
  151. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.module.js.map +1 -1
  152. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.service.d.ts +1 -1
  153. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.service.js +18 -15
  154. package/dist/modules/custom-plugins/homebridge-deconz/homebridge-deconz.service.js.map +1 -1
  155. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.controller.d.ts +1 -1
  156. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.controller.js +21 -19
  157. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.controller.js.map +1 -1
  158. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.module.js +14 -17
  159. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.module.js.map +1 -1
  160. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.service.d.ts +1 -1
  161. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.service.js +18 -15
  162. package/dist/modules/custom-plugins/homebridge-hue/homebridge-hue.service.js.map +1 -1
  163. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.controller.d.ts +1 -1
  164. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.controller.js +18 -19
  165. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.controller.js.map +1 -1
  166. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.gateway.d.ts +1 -1
  167. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.gateway.js +15 -13
  168. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.gateway.js.map +1 -1
  169. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.module.js +18 -21
  170. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.module.js.map +1 -1
  171. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.d.ts +4 -4
  172. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.js +47 -41
  173. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.js.map +1 -1
  174. package/dist/modules/log/log.gateway.d.ts +2 -2
  175. package/dist/modules/log/log.gateway.js +15 -13
  176. package/dist/modules/log/log.gateway.js.map +1 -1
  177. package/dist/modules/log/log.interfaces.js +1 -2
  178. package/dist/modules/log/log.module.js +14 -17
  179. package/dist/modules/log/log.module.js.map +1 -1
  180. package/dist/modules/log/log.service.d.ts +3 -3
  181. package/dist/modules/log/log.service.js +47 -43
  182. package/dist/modules/log/log.service.js.map +1 -1
  183. package/dist/modules/platform-tools/docker/docker.controller.d.ts +1 -1
  184. package/dist/modules/platform-tools/docker/docker.controller.js +24 -25
  185. package/dist/modules/platform-tools/docker/docker.controller.js.map +1 -1
  186. package/dist/modules/platform-tools/docker/docker.module.js +14 -17
  187. package/dist/modules/platform-tools/docker/docker.module.js.map +1 -1
  188. package/dist/modules/platform-tools/docker/docker.service.d.ts +2 -2
  189. package/dist/modules/platform-tools/docker/docker.service.js +20 -16
  190. package/dist/modules/platform-tools/docker/docker.service.js.map +1 -1
  191. package/dist/modules/platform-tools/hb-service/hb-service.controller.d.ts +2 -2
  192. package/dist/modules/platform-tools/hb-service/hb-service.controller.js +35 -36
  193. package/dist/modules/platform-tools/hb-service/hb-service.controller.js.map +1 -1
  194. package/dist/modules/platform-tools/hb-service/hb-service.dto.js +20 -19
  195. package/dist/modules/platform-tools/hb-service/hb-service.dto.js.map +1 -1
  196. package/dist/modules/platform-tools/hb-service/hb-service.module.js +14 -17
  197. package/dist/modules/platform-tools/hb-service/hb-service.module.js.map +1 -1
  198. package/dist/modules/platform-tools/hb-service/hb-service.service.d.ts +3 -3
  199. package/dist/modules/platform-tools/hb-service/hb-service.service.js +37 -30
  200. package/dist/modules/platform-tools/hb-service/hb-service.service.js.map +1 -1
  201. package/dist/modules/platform-tools/linux/linux.controller.d.ts +1 -1
  202. package/dist/modules/platform-tools/linux/linux.controller.js +23 -21
  203. package/dist/modules/platform-tools/linux/linux.controller.js.map +1 -1
  204. package/dist/modules/platform-tools/linux/linux.module.js +14 -17
  205. package/dist/modules/platform-tools/linux/linux.module.js.map +1 -1
  206. package/dist/modules/platform-tools/linux/linux.service.d.ts +2 -2
  207. package/dist/modules/platform-tools/linux/linux.service.js +18 -14
  208. package/dist/modules/platform-tools/linux/linux.service.js.map +1 -1
  209. package/dist/modules/platform-tools/platform-tools.module.js +12 -15
  210. package/dist/modules/platform-tools/platform-tools.module.js.map +1 -1
  211. package/dist/modules/platform-tools/terminal/terminal.controller.d.ts +1 -1
  212. package/dist/modules/platform-tools/terminal/terminal.controller.js +15 -13
  213. package/dist/modules/platform-tools/terminal/terminal.controller.js.map +1 -1
  214. package/dist/modules/platform-tools/terminal/terminal.gateway.d.ts +2 -2
  215. package/dist/modules/platform-tools/terminal/terminal.gateway.js +17 -15
  216. package/dist/modules/platform-tools/terminal/terminal.gateway.js.map +1 -1
  217. package/dist/modules/platform-tools/terminal/terminal.interfaces.js +1 -2
  218. package/dist/modules/platform-tools/terminal/terminal.module.js +18 -21
  219. package/dist/modules/platform-tools/terminal/terminal.module.js.map +1 -1
  220. package/dist/modules/platform-tools/terminal/terminal.service.d.ts +4 -4
  221. package/dist/modules/platform-tools/terminal/terminal.service.js +33 -28
  222. package/dist/modules/platform-tools/terminal/terminal.service.js.map +1 -1
  223. package/dist/modules/plugins/plugins.controller.d.ts +6 -6
  224. package/dist/modules/plugins/plugins.controller.js +51 -52
  225. package/dist/modules/plugins/plugins.controller.js.map +1 -1
  226. package/dist/modules/plugins/plugins.dto.js +26 -24
  227. package/dist/modules/plugins/plugins.dto.js.map +1 -1
  228. package/dist/modules/plugins/plugins.gateway.d.ts +3 -3
  229. package/dist/modules/plugins/plugins.gateway.js +38 -34
  230. package/dist/modules/plugins/plugins.gateway.js.map +1 -1
  231. package/dist/modules/plugins/plugins.interfaces.js +1 -2
  232. package/dist/modules/plugins/plugins.module.js +23 -26
  233. package/dist/modules/plugins/plugins.module.js.map +1 -1
  234. package/dist/modules/plugins/plugins.service.d.ts +9 -7
  235. package/dist/modules/plugins/plugins.service.js +231 -202
  236. package/dist/modules/plugins/plugins.service.js.map +1 -1
  237. package/dist/modules/server/server.controller.d.ts +34 -4
  238. package/dist/modules/server/server.controller.js +294 -177
  239. package/dist/modules/server/server.controller.js.map +1 -1
  240. package/dist/modules/server/server.dto.js +13 -16
  241. package/dist/modules/server/server.dto.js.map +1 -1
  242. package/dist/modules/server/server.module.js +23 -26
  243. package/dist/modules/server/server.module.js.map +1 -1
  244. package/dist/modules/server/server.service.d.ts +36 -6
  245. package/dist/modules/server/server.service.js +406 -150
  246. package/dist/modules/server/server.service.js.map +1 -1
  247. package/dist/modules/setup-wizard/setup-wizard.controller.d.ts +2 -2
  248. package/dist/modules/setup-wizard/setup-wizard.controller.js +19 -20
  249. package/dist/modules/setup-wizard/setup-wizard.controller.js.map +1 -1
  250. package/dist/modules/setup-wizard/setup-wizard.gateway.d.ts +2 -2
  251. package/dist/modules/setup-wizard/setup-wizard.gateway.js +25 -21
  252. package/dist/modules/setup-wizard/setup-wizard.gateway.js.map +1 -1
  253. package/dist/modules/setup-wizard/setup-wizard.guard.d.ts +1 -1
  254. package/dist/modules/setup-wizard/setup-wizard.guard.js +11 -9
  255. package/dist/modules/setup-wizard/setup-wizard.guard.js.map +1 -1
  256. package/dist/modules/setup-wizard/setup-wizard.module.js +12 -15
  257. package/dist/modules/setup-wizard/setup-wizard.module.js.map +1 -1
  258. package/dist/modules/status/status.controller.d.ts +5 -5
  259. package/dist/modules/status/status.controller.js +40 -36
  260. package/dist/modules/status/status.controller.js.map +1 -1
  261. package/dist/modules/status/status.gateway.d.ts +9 -9
  262. package/dist/modules/status/status.gateway.js +51 -47
  263. package/dist/modules/status/status.gateway.js.map +1 -1
  264. package/dist/modules/status/status.interfaces.js +2 -5
  265. package/dist/modules/status/status.interfaces.js.map +1 -1
  266. package/dist/modules/status/status.module.js +26 -29
  267. package/dist/modules/status/status.module.js.map +1 -1
  268. package/dist/modules/status/status.service.d.ts +7 -7
  269. package/dist/modules/status/status.service.js +100 -88
  270. package/dist/modules/status/status.service.js.map +1 -1
  271. package/dist/modules/users/users.controller.d.ts +2 -2
  272. package/dist/modules/users/users.controller.js +59 -60
  273. package/dist/modules/users/users.controller.js.map +1 -1
  274. package/dist/modules/users/users.dto.js +51 -45
  275. package/dist/modules/users/users.dto.js.map +1 -1
  276. package/dist/modules/users/users.module.js +14 -17
  277. package/dist/modules/users/users.module.js.map +1 -1
  278. package/dist/self-check.js +25 -25
  279. package/dist/self-check.js.map +1 -1
  280. package/docs/ssl-upload-pr.md +103 -0
  281. package/package.json +6 -7
  282. package/public/{chunk-PPA66JI2.js → chunk-2FNQEOXF.js} +1 -1
  283. package/public/{chunk-HERKNFLL.js → chunk-2SCTALGY.js} +1 -1
  284. package/public/{chunk-BQTGMLQB.js → chunk-3IJXQMYZ.js} +1 -1
  285. package/public/chunk-425ZEUU6.js +1 -0
  286. package/public/{chunk-EHHNHG6Q.js → chunk-4T6CM7M3.js} +1 -1
  287. package/public/{chunk-IKY3F7MM.js → chunk-7SKTJO5M.js} +1 -1
  288. package/public/{chunk-E4ZKIFZH.js → chunk-7UDDRMZZ.js} +1 -1
  289. package/public/{chunk-Y2N6WV2O.js → chunk-ATMY4YI2.js} +1 -1
  290. package/public/{chunk-UKEKNQEJ.js → chunk-AZIRJR4B.js} +1 -1
  291. package/public/{chunk-2UQL2OTF.js → chunk-B2XE365J.js} +1 -1
  292. package/public/{chunk-JWHZQ7YI.js → chunk-BMKJTHFC.js} +1 -1
  293. package/public/{chunk-R2PMDKTD.js → chunk-CGYD722J.js} +1 -1
  294. package/public/{chunk-BI2TS6NN.js → chunk-CQREAKPC.js} +4 -4
  295. package/public/{chunk-WMGV3KS6.js → chunk-CYBDQV2B.js} +1 -1
  296. package/public/{chunk-TJEQFEML.js → chunk-D5RKKI2A.js} +1 -1
  297. package/public/{chunk-NUCXRR5D.js → chunk-EAGKQ5OJ.js} +1 -1
  298. package/public/{chunk-EYO3XCE2.js → chunk-FGNMMSZH.js} +1 -1
  299. package/public/{chunk-FGS4HIPD.js → chunk-FTKWC2Q2.js} +1 -1
  300. package/public/{chunk-QU4I4QSX.js → chunk-HFW5E2OW.js} +1 -1
  301. package/public/chunk-IIDLQ7XY.js +1 -0
  302. package/public/{chunk-4E4YMHG4.js → chunk-INX52LH2.js} +1 -1
  303. package/public/{chunk-VFIOPF3O.js → chunk-JD5JQTN5.js} +1 -1
  304. package/public/{chunk-RLWY3GD4.js → chunk-JFRCT5V7.js} +1 -1
  305. package/public/{chunk-JWCVCB6V.js → chunk-JJ7TVAIH.js} +4 -4
  306. package/public/{chunk-JWY7RFE6.js → chunk-JPCV77W6.js} +1 -1
  307. package/public/{chunk-ISV4M72Q.js → chunk-K7D2P3SM.js} +1 -1
  308. package/public/chunk-L66ATRVT.js +1 -0
  309. package/public/{chunk-IXIZVUXX.js → chunk-LARQLRNL.js} +1 -1
  310. package/public/{chunk-BVTPAZF3.js → chunk-LHCMU3MO.js} +1 -1
  311. package/public/{chunk-5T6O4JCR.js → chunk-LZQVKA4S.js} +1 -1
  312. package/public/{chunk-7F6JT34E.js → chunk-M7QUT5ZZ.js} +1 -1
  313. package/public/{chunk-2MFBHUTD.js → chunk-MDBZMB6Y.js} +1 -1
  314. package/public/{chunk-HVGUNGBB.js → chunk-MNVUSYOZ.js} +1 -1
  315. package/public/{chunk-ZC3JEQZ5.js → chunk-N2TWGDNX.js} +1 -1
  316. package/public/{chunk-XS5JK2LY.js → chunk-NKNWXFAK.js} +1 -1
  317. package/public/{chunk-SOA3BB36.js → chunk-OS2SEJZU.js} +1 -1
  318. package/public/{chunk-IEO2AG2N.js → chunk-PXSEH255.js} +1 -1
  319. package/public/{chunk-QJLKBB62.js → chunk-PZ2ZCCFR.js} +1 -1
  320. package/public/{chunk-CWTDHTPI.js → chunk-QCZ4VVDL.js} +1 -1
  321. package/public/{chunk-5W7EKO7F.js → chunk-QSVZNI3M.js} +1 -1
  322. package/public/{chunk-4H7ODI34.js → chunk-QUA46GZJ.js} +1 -1
  323. package/public/{chunk-D4LRW76J.js → chunk-QVLCTKQH.js} +1 -1
  324. package/public/{chunk-DL2QDFLD.js → chunk-RQ4B2IIV.js} +1 -1
  325. package/public/{chunk-OTOQR5Z2.js → chunk-RQAFAZAK.js} +1 -1
  326. package/public/{chunk-4AWJ2PWG.js → chunk-S4OE2ITZ.js} +1 -1
  327. package/public/{chunk-ZF6W5Z5R.js → chunk-SA5C7QVC.js} +1 -1
  328. package/public/{chunk-USXMCNIE.js → chunk-SSZBNSOM.js} +1 -1
  329. package/public/{chunk-E7S36RMO.js → chunk-TA6DOQC5.js} +1 -1
  330. package/public/{chunk-VB4UAZWJ.js → chunk-TC77PFBQ.js} +1 -1
  331. package/public/{chunk-5WTTTYNS.js → chunk-TKGKVKOW.js} +1 -1
  332. package/public/{chunk-FOSFENMV.js → chunk-TSFGO3MA.js} +1 -1
  333. package/public/{chunk-IBO6BDNZ.js → chunk-UEDMHOPK.js} +1 -1
  334. package/public/{chunk-LI4BZAUI.js → chunk-UOPWP4RR.js} +1 -1
  335. package/public/chunk-UTFHCUKB.js +1 -0
  336. package/public/{chunk-SXOLKD36.js → chunk-UTN2R7WG.js} +1 -1
  337. package/public/chunk-UV24H47X.js +1 -0
  338. package/public/{chunk-B5Z4M7ZJ.js → chunk-VSBBKD6B.js} +1 -1
  339. package/public/{chunk-AO7VT6PL.js → chunk-VYC5JLE6.js} +1 -1
  340. package/public/{chunk-AOALMLGY.js → chunk-W7UNXMCL.js} +1 -1
  341. package/public/{chunk-NIERW5KT.js → chunk-WVCOONJF.js} +1 -1
  342. package/public/{chunk-RON3LUMX.js → chunk-WWSLIQVD.js} +1 -1
  343. package/public/{chunk-4DVF333O.js → chunk-X3IVSHIL.js} +1 -1
  344. package/public/{chunk-5G7T74GR.js → chunk-XE5VJDQL.js} +1 -1
  345. package/public/chunk-XMNXI4QP.js +50 -0
  346. package/public/{chunk-W26VKO62.js → chunk-XX5GWADI.js} +1 -1
  347. package/public/{chunk-TGX55EFG.js → chunk-Y5XBENWZ.js} +1 -1
  348. package/public/{chunk-Z6VQEXUS.js → chunk-YNONXMOG.js} +1 -1
  349. package/public/{chunk-DIWD6B4C.js → chunk-ZEI3HZ6P.js} +1 -1
  350. package/public/index.html +2 -2
  351. package/public/{main-QP5R7HI3.js → main-UGYHSCMY.js} +1 -1
  352. package/public/{styles-CSF457UW.css → styles-WNHDEKE4.css} +1 -1
  353. package/scripts/extract-plugin-alias.js +8 -4
  354. package/public/chunk-2ADAW5AD.js +0 -1
  355. package/public/chunk-2Y63WBU6.js +0 -1
  356. package/public/chunk-I3QQTGGZ.js +0 -1
  357. package/public/chunk-LGE6SGDN.js +0 -1
  358. package/public/chunk-PZD3OMMY.js +0 -1
  359. package/public/chunk-QOSAHW73.js +0 -50
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
2
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
3
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -8,70 +7,80 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
7
  var __metadata = (this && this.__metadata) || function (k, v) {
9
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
9
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
13
12
  };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.ServerService = void 0;
16
- const node_buffer_1 = require("node:buffer");
17
- const node_child_process_1 = require("node:child_process");
18
- const node_path_1 = require("node:path");
19
- const node_process_1 = __importDefault(require("node:process"));
20
- const node_stream_1 = require("node:stream");
21
- const node_util_1 = require("node:util");
22
- const hap_types_1 = require("@homebridge/hap-client/dist/hap-types");
23
- const common_1 = require("@nestjs/common");
24
- const fs_extra_1 = require("fs-extra");
25
- const node_cache_1 = __importDefault(require("node-cache"));
26
- const systeminformation_1 = require("systeminformation");
27
- const tcp_port_used_1 = require("tcp-port-used");
28
- const config_service_1 = require("../../core/config/config.service");
29
- const homebridge_ipc_service_1 = require("../../core/homebridge-ipc/homebridge-ipc.service");
30
- const logger_service_1 = require("../../core/logger/logger.service");
31
- const accessories_service_1 = require("../accessories/accessories.service");
32
- const config_editor_service_1 = require("../config-editor/config-editor.service");
33
- const pump = (0, node_util_1.promisify)(node_stream_1.pipeline);
13
+ import { Buffer } from 'node:buffer';
14
+ import { exec, spawn } from 'node:child_process';
15
+ import { createPrivateKey, createPublicKey, X509Certificate } from 'node:crypto';
16
+ import { createWriteStream } from 'node:fs';
17
+ import { readdir, unlink } from 'node:fs/promises';
18
+ import { extname, join, resolve } from 'node:path';
19
+ import process from 'node:process';
20
+ import { pipeline } from 'node:stream';
21
+ import { createSecureContext } from 'node:tls';
22
+ import { promisify } from 'node:util';
23
+ import { Categories } from '@homebridge/hap-client/dist/hap-types.js';
24
+ import { BadRequestException, Inject, Injectable, InternalServerErrorException, NotFoundException, ServiceUnavailableException, } from '@nestjs/common';
25
+ import { pathExists, readJson, remove, writeJson } from 'fs-extra/esm';
26
+ import NodeCache from 'node-cache';
27
+ import { networkInterfaces } from 'systeminformation';
28
+ import { check as tcpCheck } from 'tcp-port-used';
29
+ import { ConfigService } from '../../core/config/config.service.js';
30
+ import { HomebridgeIpcService } from '../../core/homebridge-ipc/homebridge-ipc.service.js';
31
+ import { Logger } from '../../core/logger/logger.service.js';
32
+ import { SslCertGeneratorService } from '../../core/ssl/ssl-cert-generator.service.js';
33
+ import { AccessoriesService } from '../accessories/accessories.service.js';
34
+ import { ConfigEditorService } from '../config-editor/config-editor.service.js';
35
+ const pump = promisify(pipeline);
34
36
  let ServerService = class ServerService {
37
+ configService;
38
+ configEditorService;
39
+ accessoriesService;
40
+ homebridgeIpcService;
41
+ logger;
42
+ serverServiceCache = new NodeCache({ stdTTL: 300 });
43
+ accessoryId;
44
+ accessoryInfoPath;
45
+ setupCode = null;
46
+ paired = false;
35
47
  constructor(configService, configEditorService, accessoriesService, homebridgeIpcService, logger) {
36
48
  this.configService = configService;
37
49
  this.configEditorService = configEditorService;
38
50
  this.accessoriesService = accessoriesService;
39
51
  this.homebridgeIpcService = homebridgeIpcService;
40
52
  this.logger = logger;
41
- this.serverServiceCache = new node_cache_1.default({ stdTTL: 300 });
42
- this.setupCode = null;
43
- this.paired = false;
44
53
  this.accessoryId = this.configService.homebridgeConfig.bridge.username.split(':').join('');
45
- this.accessoryInfoPath = (0, node_path_1.join)(this.configService.storagePath, 'persist', `AccessoryInfo.${this.accessoryId}.json`);
54
+ this.accessoryInfoPath = join(this.configService.storagePath, 'persist', `AccessoryInfo.${this.accessoryId}.json`);
46
55
  }
47
56
  async deleteSingleDeviceAccessories(id, cachedAccessoriesDir, protocol = 'both') {
48
57
  if (protocol === 'hap' || protocol === 'both') {
49
- const cachedAccessories = (0, node_path_1.join)(cachedAccessoriesDir, `cachedAccessories.${id}`);
50
- const cachedAccessoriesBackup = (0, node_path_1.join)(cachedAccessoriesDir, `.cachedAccessories.${id}.bak`);
51
- if (await (0, fs_extra_1.pathExists)(cachedAccessories)) {
52
- await (0, fs_extra_1.unlink)(cachedAccessories);
58
+ const cachedAccessories = join(cachedAccessoriesDir, `cachedAccessories.${id}`);
59
+ const cachedAccessoriesBackup = join(cachedAccessoriesDir, `.cachedAccessories.${id}.bak`);
60
+ if (await pathExists(cachedAccessories)) {
61
+ await unlink(cachedAccessories);
53
62
  this.logger.warn(`Bridge ${id} HAP accessory removal: removed ${cachedAccessories}.`);
54
63
  }
55
- if (await (0, fs_extra_1.pathExists)(cachedAccessoriesBackup)) {
56
- await (0, fs_extra_1.unlink)(cachedAccessoriesBackup);
64
+ if (await pathExists(cachedAccessoriesBackup)) {
65
+ await unlink(cachedAccessoriesBackup);
57
66
  this.logger.warn(`Bridge ${id} HAP accessory removal: removed ${cachedAccessoriesBackup}.`);
58
67
  }
59
68
  }
60
69
  if (protocol === 'matter' || protocol === 'both') {
61
70
  const deviceId = id.split(':').join('').toUpperCase();
62
- const matterPath = (0, node_path_1.join)(this.configService.storagePath, 'matter', deviceId);
63
- if (await (0, fs_extra_1.pathExists)(matterPath)) {
64
- await (0, fs_extra_1.remove)(matterPath);
71
+ const matterPath = join(this.configService.storagePath, 'matter', deviceId);
72
+ if (await pathExists(matterPath)) {
73
+ await remove(matterPath);
65
74
  this.logger.warn(`Bridge ${id} Matter accessory removal: removed Matter bridge storage at ${matterPath}.`);
66
75
  }
67
76
  }
68
77
  }
69
78
  async deleteSingleDevicePairing(id, resetPairingInfo) {
70
- const persistPath = (0, node_path_1.join)(this.configService.storagePath, 'persist');
71
- const accessoryInfo = (0, node_path_1.join)(persistPath, `AccessoryInfo.${id}.json`);
72
- const identifierCache = (0, node_path_1.join)(persistPath, `IdentifierCache.${id}.json`);
79
+ const persistPath = join(this.configService.storagePath, 'persist');
80
+ const accessoryInfo = join(persistPath, `AccessoryInfo.${id}.json`);
81
+ const identifierCache = join(persistPath, `IdentifierCache.${id}.json`);
73
82
  const deviceId = id.includes(':') ? id.split(':').join('').toUpperCase() : id.toUpperCase();
74
- const matterPath = (0, node_path_1.join)(this.configService.storagePath, 'matter', deviceId);
83
+ const matterPath = join(this.configService.storagePath, 'matter', deviceId);
75
84
  try {
76
85
  const configFile = await this.configEditorService.getConfigFile();
77
86
  const username = id.includes(':') ? id.toUpperCase() : id.match(/.{1,2}/g)?.join(':').toUpperCase() || id.toUpperCase();
@@ -116,16 +125,16 @@ let ServerService = class ServerService {
116
125
  catch (e) {
117
126
  this.logger.error(`Failed to reset username and pin for child bridge ${id} as ${e.message}.`);
118
127
  }
119
- if (await (0, fs_extra_1.pathExists)(accessoryInfo)) {
120
- await (0, fs_extra_1.unlink)(accessoryInfo);
128
+ if (await pathExists(accessoryInfo)) {
129
+ await unlink(accessoryInfo);
121
130
  this.logger.warn(`Bridge ${id} reset: removed ${accessoryInfo}.`);
122
131
  }
123
- if (await (0, fs_extra_1.pathExists)(identifierCache)) {
124
- await (0, fs_extra_1.unlink)(identifierCache);
132
+ if (await pathExists(identifierCache)) {
133
+ await unlink(identifierCache);
125
134
  this.logger.warn(`Bridge ${id} reset: removed ${identifierCache}.`);
126
135
  }
127
- if (await (0, fs_extra_1.pathExists)(matterPath)) {
128
- await (0, fs_extra_1.remove)(matterPath);
136
+ if (await pathExists(matterPath)) {
137
+ await remove(matterPath);
129
138
  this.logger.warn(`Bridge ${id} reset: removed Matter bridge storage at ${matterPath}.`);
130
139
  }
131
140
  await this.deleteDeviceAccessories(id);
@@ -141,7 +150,7 @@ let ServerService = class ServerService {
141
150
  setTimeout(() => {
142
151
  if (this.configService.ui.restart) {
143
152
  this.logger.log(`Executing restart command ${this.configService.ui.restart}.`);
144
- (0, node_child_process_1.exec)(this.configService.ui.restart, (err) => {
153
+ exec(this.configService.ui.restart, (err) => {
145
154
  if (err) {
146
155
  this.logger.log('Restart command exited with an error, failed to restart Homebridge.');
147
156
  }
@@ -149,7 +158,7 @@ let ServerService = class ServerService {
149
158
  }
150
159
  else {
151
160
  this.logger.log('Sending SIGTERM to process...');
152
- node_process_1.default.kill(node_process_1.default.pid, 'SIGTERM');
161
+ process.kill(process.pid, 'SIGTERM');
153
162
  }
154
163
  }, 500);
155
164
  return { ok: true, command: this.configService.ui.restart, restartingUI: true };
@@ -169,33 +178,33 @@ let ServerService = class ServerService {
169
178
  }
170
179
  this.logger.warn(`Homebridge bridge reset: new username ${configFile.bridge.username} and new pin ${configFile.bridge.pin}.`);
171
180
  await this.configEditorService.updateConfigFile(configFile);
172
- await (0, fs_extra_1.remove)((0, node_path_1.resolve)(this.configService.storagePath, 'accessories'));
173
- await (0, fs_extra_1.remove)((0, node_path_1.resolve)(this.configService.storagePath, 'persist'));
181
+ await remove(resolve(this.configService.storagePath, 'accessories'));
182
+ await remove(resolve(this.configService.storagePath, 'persist'));
174
183
  const deviceId = oldUsername.split(':').join('').toUpperCase();
175
- const matterPath = (0, node_path_1.join)(this.configService.storagePath, 'matter', deviceId);
176
- if (await (0, fs_extra_1.pathExists)(matterPath)) {
177
- await (0, fs_extra_1.remove)(matterPath);
184
+ const matterPath = join(this.configService.storagePath, 'matter', deviceId);
185
+ if (await pathExists(matterPath)) {
186
+ await remove(matterPath);
178
187
  this.logger.warn(`Bridge ${oldUsername} reset: removed Matter bridge storage at ${matterPath}.`);
179
188
  }
180
189
  this.logger.log('Homebridge bridge reset: accessories and persist directories were removed.');
181
190
  }
182
191
  async getDevicePairings() {
183
- const persistPath = (0, node_path_1.join)(this.configService.storagePath, 'persist');
184
- const devices = (await (0, fs_extra_1.readdir)(persistPath))
192
+ const persistPath = join(this.configService.storagePath, 'persist');
193
+ const devices = (await readdir(persistPath))
185
194
  .filter(x => x.match(/AccessoryInfo\.([A-Fa-f0-9]+)\.json$/));
186
195
  const configFile = await this.configEditorService.getConfigFile();
187
196
  const hapDevices = await Promise.all(devices.map(async (x) => {
188
197
  return await this.getDevicePairingById(x.split('.')[1], configFile);
189
198
  }));
190
- const matterExternalDevices = await this.getMatterExternalAccessories(configFile, hapDevices);
199
+ const matterExternalDevices = await this.getMatterExternalAccessories(hapDevices);
191
200
  return [...hapDevices, ...matterExternalDevices].sort((a, b) => a.name.localeCompare(b.name));
192
201
  }
193
- async getMatterExternalAccessories(configFile, hapDevices) {
194
- const matterPath = (0, node_path_1.join)(this.configService.storagePath, 'matter');
195
- if (!await (0, fs_extra_1.pathExists)(matterPath)) {
202
+ async getMatterExternalAccessories(hapDevices) {
203
+ const matterPath = join(this.configService.storagePath, 'matter');
204
+ if (!await pathExists(matterPath)) {
196
205
  return [];
197
206
  }
198
- const matterDirs = (await (0, fs_extra_1.readdir)(matterPath))
207
+ const matterDirs = (await readdir(matterPath))
199
208
  .filter(x => x.match(/^[A-F0-9]{12}$/));
200
209
  const matterExternalDevices = [];
201
210
  for (const deviceId of matterDirs) {
@@ -208,19 +217,19 @@ let ServerService = class ServerService {
208
217
  if (deviceId.toUpperCase() === mainBridgeId) {
209
218
  continue;
210
219
  }
211
- const accessoriesPath = (0, node_path_1.join)(matterPath, deviceId, 'accessories.json');
212
- if (!await (0, fs_extra_1.pathExists)(accessoriesPath)) {
220
+ const accessoriesPath = join(matterPath, deviceId, 'accessories.json');
221
+ if (!await pathExists(accessoriesPath)) {
213
222
  continue;
214
223
  }
215
- const accessories = await (0, fs_extra_1.readJson)(accessoriesPath);
224
+ const accessories = await readJson(accessoriesPath);
216
225
  if (!Array.isArray(accessories) || accessories.length === 0) {
217
226
  continue;
218
227
  }
219
228
  const accessory = accessories[0];
220
- const commissioningPath = (0, node_path_1.join)(matterPath, deviceId, 'commissioning.json');
229
+ const commissioningPath = join(matterPath, deviceId, 'commissioning.json');
221
230
  let commissioned = false;
222
- if (await (0, fs_extra_1.pathExists)(commissioningPath)) {
223
- const commissioningInfo = await (0, fs_extra_1.readJson)(commissioningPath);
231
+ if (await pathExists(commissioningPath)) {
232
+ const commissioningInfo = await readJson(commissioningPath);
224
233
  commissioned = commissioningInfo.commissioned || false;
225
234
  }
226
235
  const device = {
@@ -248,13 +257,13 @@ let ServerService = class ServerService {
248
257
  return matterExternalDevices;
249
258
  }
250
259
  async getDevicePairingById(deviceId, configFile = null) {
251
- const persistPath = (0, node_path_1.join)(this.configService.storagePath, 'persist');
260
+ const persistPath = join(this.configService.storagePath, 'persist');
252
261
  let device;
253
262
  try {
254
- device = await (0, fs_extra_1.readJson)((0, node_path_1.join)(persistPath, `AccessoryInfo.${deviceId}.json`));
263
+ device = await readJson(join(persistPath, `AccessoryInfo.${deviceId}.json`));
255
264
  }
256
265
  catch (e) {
257
- throw new common_1.NotFoundException();
266
+ throw new NotFoundException();
258
267
  }
259
268
  if (!configFile) {
260
269
  configFile = await this.configEditorService.getConfigFile();
@@ -266,7 +275,7 @@ let ServerService = class ServerService {
266
275
  .concat([{ _bridge: configFile.bridge }])
267
276
  .find((block) => block._bridge?.username?.toUpperCase() === username.toUpperCase());
268
277
  try {
269
- device._category = Object.entries(hap_types_1.Categories).find(([, value]) => value === device.category)[0].toLowerCase();
278
+ device._category = Object.entries(Categories).find(([, value]) => value === device.category)[0].toLowerCase();
270
279
  }
271
280
  catch (e) {
272
281
  device._category = 'Other';
@@ -307,7 +316,7 @@ let ServerService = class ServerService {
307
316
  const pluginBlock = pluginBlocks.find((block) => block._bridge?.matter);
308
317
  if (!pluginBlock) {
309
318
  this.logger.error(`Failed to find Matter configuration for child bridge ${id}.`);
310
- throw new common_1.NotFoundException(`Matter configuration not found for bridge ${id}`);
319
+ throw new NotFoundException(`Matter configuration not found for bridge ${id}`);
311
320
  }
312
321
  if ('accessory' in pluginBlock) {
313
322
  this.logger.warn(`Removing Matter configuration from accessory-based plugin block for bridge ${id}. Matter is only supported for platform-based plugins.`);
@@ -317,18 +326,18 @@ let ServerService = class ServerService {
317
326
  await this.configEditorService.updateConfigFile(configFile);
318
327
  }
319
328
  catch (e) {
320
- if (e instanceof common_1.NotFoundException) {
329
+ if (e instanceof NotFoundException) {
321
330
  throw e;
322
331
  }
323
332
  this.logger.error(`Failed to remove Matter configuration for child bridge ${id} as ${e.message}.`);
324
- throw new common_1.InternalServerErrorException(`Failed to remove Matter configuration: ${e.message}`);
333
+ throw new InternalServerErrorException(`Failed to remove Matter configuration: ${e.message}`);
325
334
  }
326
335
  this.logger.warn(`Shutting down Homebridge before removing Matter storage for bridge ${id}...`);
327
336
  await this.homebridgeIpcService.restartAndWaitForClose();
328
337
  const deviceId = id.includes(':') ? id.split(':').join('').toUpperCase() : id.toUpperCase();
329
- const matterPath = (0, node_path_1.join)(this.configService.storagePath, 'matter', deviceId);
330
- if (await (0, fs_extra_1.pathExists)(matterPath)) {
331
- await (0, fs_extra_1.remove)(matterPath);
338
+ const matterPath = join(this.configService.storagePath, 'matter', deviceId);
339
+ if (await pathExists(matterPath)) {
340
+ await remove(matterPath);
332
341
  this.logger.warn(`Bridge ${id} Matter storage removed at ${matterPath}.`);
333
342
  }
334
343
  return { ok: true };
@@ -349,13 +358,13 @@ let ServerService = class ServerService {
349
358
  async deleteDeviceAccessories(id) {
350
359
  this.logger.warn(`Shutting down Homebridge before removing accessories for paired bridge ${id}...`);
351
360
  await this.homebridgeIpcService.restartAndWaitForClose();
352
- const cachedAccessoriesDir = (0, node_path_1.join)(this.configService.storagePath, 'accessories');
361
+ const cachedAccessoriesDir = join(this.configService.storagePath, 'accessories');
353
362
  await this.deleteSingleDeviceAccessories(id, cachedAccessoriesDir);
354
363
  }
355
364
  async deleteDevicesAccessories(bridges) {
356
365
  this.logger.warn(`Shutting down Homebridge before removing accessories for paired bridges ${bridges.map(x => x.id).join(', ')}...`);
357
366
  await this.homebridgeIpcService.restartAndWaitForClose();
358
- const cachedAccessoriesDir = (0, node_path_1.join)(this.configService.storagePath, 'accessories');
367
+ const cachedAccessoriesDir = join(this.configService.storagePath, 'accessories');
359
368
  for (const { id, protocol } of bridges) {
360
369
  try {
361
370
  await this.deleteSingleDeviceAccessories(id, cachedAccessoriesDir, protocol || 'both');
@@ -366,12 +375,12 @@ let ServerService = class ServerService {
366
375
  }
367
376
  }
368
377
  async getCachedAccessories() {
369
- const cachedAccessoriesDir = (0, node_path_1.join)(this.configService.storagePath, 'accessories');
370
- const cachedAccessoryFiles = (await (0, fs_extra_1.readdir)(cachedAccessoriesDir))
378
+ const cachedAccessoriesDir = join(this.configService.storagePath, 'accessories');
379
+ const cachedAccessoryFiles = (await readdir(cachedAccessoriesDir))
371
380
  .filter(x => x.match(/^cachedAccessories\.([A-F,0-9]+)$/) || x === 'cachedAccessories');
372
381
  const cachedAccessories = [];
373
382
  await Promise.all(cachedAccessoryFiles.map(async (x) => {
374
- const accessories = await (0, fs_extra_1.readJson)((0, node_path_1.join)(cachedAccessoriesDir, x));
383
+ const accessories = await readJson(join(cachedAccessoriesDir, x));
375
384
  for (const accessory of accessories) {
376
385
  accessory.$cacheFile = x;
377
386
  cachedAccessories.push(accessory);
@@ -381,19 +390,19 @@ let ServerService = class ServerService {
381
390
  }
382
391
  async deleteCachedAccessory(uuid, cacheFile) {
383
392
  cacheFile = cacheFile || 'cachedAccessories';
384
- const cachedAccessoriesPath = (0, node_path_1.resolve)(this.configService.storagePath, 'accessories', cacheFile);
393
+ const cachedAccessoriesPath = resolve(this.configService.storagePath, 'accessories', cacheFile);
385
394
  this.logger.warn(`Shutting down Homebridge before removing cached accessory ${uuid}...`);
386
395
  await this.homebridgeIpcService.restartAndWaitForClose();
387
- const cachedAccessories = await (0, fs_extra_1.readJson)(cachedAccessoriesPath);
396
+ const cachedAccessories = await readJson(cachedAccessoriesPath);
388
397
  const accessoryIndex = cachedAccessories.findIndex(x => x.UUID === uuid);
389
398
  if (accessoryIndex > -1) {
390
399
  cachedAccessories.splice(accessoryIndex, 1);
391
- await (0, fs_extra_1.writeJson)(cachedAccessoriesPath, cachedAccessories);
400
+ await writeJson(cachedAccessoriesPath, cachedAccessories);
392
401
  this.logger.warn(`Removed cached accessory with UUID ${uuid} from file ${cacheFile}.`);
393
402
  }
394
403
  else {
395
404
  this.logger.error(`Cannot find cached accessory with UUID ${uuid} from file ${cacheFile}.`);
396
- throw new common_1.NotFoundException();
405
+ throw new NotFoundException();
397
406
  }
398
407
  return { ok: true };
399
408
  }
@@ -409,8 +418,8 @@ let ServerService = class ServerService {
409
418
  accessoriesByCacheFile.get(accessoryCacheFile).push({ uuid });
410
419
  }
411
420
  for (const [cacheFile, accessories] of accessoriesByCacheFile.entries()) {
412
- const cachedAccessoriesPath = (0, node_path_1.resolve)(this.configService.storagePath, 'accessories', cacheFile);
413
- const cachedAccessories = await (0, fs_extra_1.readJson)(cachedAccessoriesPath);
421
+ const cachedAccessoriesPath = resolve(this.configService.storagePath, 'accessories', cacheFile);
422
+ const cachedAccessories = await readJson(cachedAccessoriesPath);
414
423
  for (const { uuid } of accessories) {
415
424
  try {
416
425
  const accessoryIndex = cachedAccessories.findIndex(x => x.UUID === uuid);
@@ -426,53 +435,53 @@ let ServerService = class ServerService {
426
435
  this.logger.error(`Failed to remove cached accessory with UUID ${uuid} from file ${cacheFile} as ${e.message}.`);
427
436
  }
428
437
  }
429
- await (0, fs_extra_1.writeJson)(cachedAccessoriesPath, cachedAccessories);
438
+ await writeJson(cachedAccessoriesPath, cachedAccessories);
430
439
  }
431
440
  return { ok: true };
432
441
  }
433
442
  async deleteAllCachedAccessories() {
434
- const cachedAccessoriesDir = (0, node_path_1.join)(this.configService.storagePath, 'accessories');
435
- const cachedAccessoryPaths = (await (0, fs_extra_1.readdir)(cachedAccessoriesDir))
443
+ const cachedAccessoriesDir = join(this.configService.storagePath, 'accessories');
444
+ const cachedAccessoryPaths = (await readdir(cachedAccessoriesDir))
436
445
  .filter(x => x.match(/cachedAccessories\.([A-F,0-9]+)/) || x === 'cachedAccessories' || x === '.cachedAccessories.bak')
437
- .map(x => (0, node_path_1.resolve)(cachedAccessoriesDir, x));
438
- const cachedAccessoriesPath = (0, node_path_1.resolve)(this.configService.storagePath, 'accessories', 'cachedAccessories');
446
+ .map(x => resolve(cachedAccessoriesDir, x));
447
+ const cachedAccessoriesPath = resolve(this.configService.storagePath, 'accessories', 'cachedAccessories');
439
448
  await this.homebridgeIpcService.restartAndWaitForClose();
440
449
  this.logger.warn('Shutting down Homebridge before removing cached accessories');
441
450
  try {
442
451
  this.logger.log('Clearing all HAP cached accessories...');
443
452
  for (const thisCachedAccessoriesPath of cachedAccessoryPaths) {
444
- if (await (0, fs_extra_1.pathExists)(thisCachedAccessoriesPath)) {
445
- await (0, fs_extra_1.unlink)(thisCachedAccessoriesPath);
453
+ if (await pathExists(thisCachedAccessoriesPath)) {
454
+ await unlink(thisCachedAccessoriesPath);
446
455
  this.logger.warn(`Removed ${thisCachedAccessoriesPath}.`);
447
456
  }
448
457
  }
449
- const matterDir = (0, node_path_1.join)(this.configService.storagePath, 'matter');
450
- if (await (0, fs_extra_1.pathExists)(matterDir)) {
458
+ const matterDir = join(this.configService.storagePath, 'matter');
459
+ if (await pathExists(matterDir)) {
451
460
  this.logger.log('Clearing all Matter cached accessories...');
452
- await (0, fs_extra_1.remove)(matterDir);
461
+ await remove(matterDir);
453
462
  this.logger.warn(`Removed Matter storage directory at ${matterDir}.`);
454
463
  }
455
464
  }
456
465
  catch (e) {
457
466
  this.logger.error(`Failed to clear all cached accessories at ${cachedAccessoriesPath} as ${e.message}.`);
458
467
  console.error(e);
459
- throw new common_1.InternalServerErrorException('Failed to clear Homebridge accessory cache - see logs.');
468
+ throw new InternalServerErrorException('Failed to clear Homebridge accessory cache - see logs.');
460
469
  }
461
470
  return { ok: true };
462
471
  }
463
472
  async getMatterAccessories() {
464
- const matterDir = (0, node_path_1.join)(this.configService.storagePath, 'matter');
465
- if (!await (0, fs_extra_1.pathExists)(matterDir)) {
473
+ const matterDir = join(this.configService.storagePath, 'matter');
474
+ if (!await pathExists(matterDir)) {
466
475
  return [];
467
476
  }
468
- const matterBridges = (await (0, fs_extra_1.readdir)(matterDir))
477
+ const matterBridges = (await readdir(matterDir))
469
478
  .filter(x => x.match(/^[A-F0-9]+$/));
470
479
  const matterAccessories = [];
471
480
  await Promise.all(matterBridges.map(async (deviceId) => {
472
481
  try {
473
- const accessoriesPath = (0, node_path_1.join)(matterDir, deviceId, 'accessories.json');
474
- if (await (0, fs_extra_1.pathExists)(accessoriesPath)) {
475
- const accessories = await (0, fs_extra_1.readJson)(accessoriesPath);
482
+ const accessoriesPath = join(matterDir, deviceId, 'accessories.json');
483
+ if (await pathExists(accessoriesPath)) {
484
+ const accessories = await readJson(accessoriesPath);
476
485
  if (Array.isArray(accessories)) {
477
486
  for (const accessory of accessories) {
478
487
  accessory.$deviceId = deviceId;
@@ -489,23 +498,23 @@ let ServerService = class ServerService {
489
498
  return matterAccessories;
490
499
  }
491
500
  async deleteMatterAccessory(deviceId, uuid) {
492
- const matterAccessoriesPath = (0, node_path_1.join)(this.configService.storagePath, 'matter', deviceId, 'accessories.json');
493
- if (!await (0, fs_extra_1.pathExists)(matterAccessoriesPath)) {
501
+ const matterAccessoriesPath = join(this.configService.storagePath, 'matter', deviceId, 'accessories.json');
502
+ if (!await pathExists(matterAccessoriesPath)) {
494
503
  this.logger.error(`Matter accessories file not found for bridge ${deviceId}`);
495
- throw new common_1.NotFoundException();
504
+ throw new NotFoundException();
496
505
  }
497
506
  this.logger.warn(`Shutting down Homebridge before removing Matter accessory ${uuid} from bridge ${deviceId}...`);
498
507
  await this.homebridgeIpcService.restartAndWaitForClose();
499
- const matterAccessories = await (0, fs_extra_1.readJson)(matterAccessoriesPath);
508
+ const matterAccessories = await readJson(matterAccessoriesPath);
500
509
  const accessoryIndex = matterAccessories.findIndex(x => x.uuid === uuid);
501
510
  if (accessoryIndex > -1) {
502
511
  matterAccessories.splice(accessoryIndex, 1);
503
- await (0, fs_extra_1.writeJson)(matterAccessoriesPath, matterAccessories, { spaces: 2 });
512
+ await writeJson(matterAccessoriesPath, matterAccessories, { spaces: 2 });
504
513
  this.logger.warn(`Removed Matter accessory with UUID ${uuid} from bridge ${deviceId}.`);
505
514
  }
506
515
  else {
507
516
  this.logger.error(`Cannot find Matter accessory with UUID ${uuid} in bridge ${deviceId}.`);
508
- throw new common_1.NotFoundException();
517
+ throw new NotFoundException();
509
518
  }
510
519
  return { ok: true };
511
520
  }
@@ -520,13 +529,13 @@ let ServerService = class ServerService {
520
529
  accessoriesByBridge.get(deviceId).push({ uuid });
521
530
  }
522
531
  for (const [deviceId, bridgeAccessories] of accessoriesByBridge.entries()) {
523
- const matterAccessoriesPath = (0, node_path_1.join)(this.configService.storagePath, 'matter', deviceId, 'accessories.json');
532
+ const matterAccessoriesPath = join(this.configService.storagePath, 'matter', deviceId, 'accessories.json');
524
533
  try {
525
- if (!await (0, fs_extra_1.pathExists)(matterAccessoriesPath)) {
534
+ if (!await pathExists(matterAccessoriesPath)) {
526
535
  this.logger.error(`Matter accessories file not found for bridge ${deviceId}`);
527
536
  continue;
528
537
  }
529
- const matterAccessories = await (0, fs_extra_1.readJson)(matterAccessoriesPath);
538
+ const matterAccessories = await readJson(matterAccessoriesPath);
530
539
  for (const { uuid } of bridgeAccessories) {
531
540
  try {
532
541
  const accessoryIndex = matterAccessories.findIndex(x => x.uuid === uuid);
@@ -542,7 +551,7 @@ let ServerService = class ServerService {
542
551
  this.logger.error(`Failed to remove Matter accessory with UUID ${uuid} from bridge ${deviceId} as ${e.message}.`);
543
552
  }
544
553
  }
545
- await (0, fs_extra_1.writeJson)(matterAccessoriesPath, matterAccessories, { spaces: 2 });
554
+ await writeJson(matterAccessoriesPath, matterAccessories, { spaces: 2 });
546
555
  }
547
556
  catch (e) {
548
557
  this.logger.error(`Failed to process Matter accessories for bridge ${deviceId} as ${e.message}.`);
@@ -555,16 +564,16 @@ let ServerService = class ServerService {
555
564
  return this.setupCode;
556
565
  }
557
566
  else {
558
- if (!await (0, fs_extra_1.pathExists)(this.accessoryInfoPath)) {
567
+ if (!await pathExists(this.accessoryInfoPath)) {
559
568
  return null;
560
569
  }
561
- const accessoryInfo = await (0, fs_extra_1.readJson)(this.accessoryInfoPath);
570
+ const accessoryInfo = await readJson(this.accessoryInfoPath);
562
571
  this.setupCode = this.generateSetupCode(accessoryInfo);
563
572
  return this.setupCode;
564
573
  }
565
574
  }
566
575
  generateSetupCode(accessoryInfo) {
567
- const buffer = node_buffer_1.Buffer.allocUnsafe(8);
576
+ const buffer = Buffer.allocUnsafe(8);
568
577
  let valueLow = Number.parseInt(accessoryInfo.pincode.replace(/-/g, ''), 10);
569
578
  const valueHigh = accessoryInfo.category >> 1;
570
579
  valueLow |= 1 << 28;
@@ -582,10 +591,10 @@ let ServerService = class ServerService {
582
591
  return `X-HM://${encodedPayload}${accessoryInfo.setupID}`;
583
592
  }
584
593
  async getBridgePairingInformation() {
585
- if (!await (0, fs_extra_1.pathExists)(this.accessoryInfoPath)) {
586
- return new common_1.ServiceUnavailableException('Pairing Information Not Available Yet');
594
+ if (!await pathExists(this.accessoryInfoPath)) {
595
+ return new ServiceUnavailableException('Pairing Information Not Available Yet');
587
596
  }
588
- const accessoryInfo = await (0, fs_extra_1.readJson)(this.accessoryInfoPath);
597
+ const accessoryInfo = await readJson(this.accessoryInfoPath);
589
598
  return {
590
599
  displayName: accessoryInfo.displayName,
591
600
  pincode: accessoryInfo.pincode,
@@ -595,7 +604,7 @@ let ServerService = class ServerService {
595
604
  }
596
605
  async getSystemNetworkInterfaces() {
597
606
  const fromCache = this.serverServiceCache.get('network-interfaces');
598
- const interfaces = fromCache || (await (0, systeminformation_1.networkInterfaces)()).filter((adapter) => {
607
+ const interfaces = fromCache || (await networkInterfaces()).filter((adapter) => {
599
608
  return !adapter.internal
600
609
  && (adapter.ip4 || (adapter.ip6));
601
610
  });
@@ -649,7 +658,7 @@ let ServerService = class ServerService {
649
658
  const max = this.configService.homebridgeConfig.ports?.end ?? 60000;
650
659
  const randomPort = () => Math.floor(Math.random() * (max - min + 1) + min);
651
660
  let port = randomPort();
652
- while (await (0, tcp_port_used_1.check)(port)) {
661
+ while (await tcpCheck(port)) {
653
662
  port = randomPort();
654
663
  }
655
664
  return { port };
@@ -672,11 +681,11 @@ let ServerService = class ServerService {
672
681
  }
673
682
  }
674
683
  for (let port = min; port <= max; port += 1) {
675
- if (!usedMatterPorts.has(port) && !await (0, tcp_port_used_1.check)(port)) {
684
+ if (!usedMatterPorts.has(port) && !await tcpCheck(port)) {
676
685
  return { port };
677
686
  }
678
687
  }
679
- throw new common_1.InternalServerErrorException('No available ports in the Matter port range (5530-5541)');
688
+ throw new InternalServerErrorException('No available ports in the Matter port range (5530-5541)');
680
689
  }
681
690
  async getHomebridgePort() {
682
691
  const config = await this.configEditorService.getConfigFile();
@@ -698,7 +707,7 @@ let ServerService = class ServerService {
698
707
  }
699
708
  async setHomebridgeName(name) {
700
709
  if (!name || !(/^[\p{L}\p{N}][\p{L}\p{N} ']*[\p{L}\p{N}]$/u).test(name)) {
701
- throw new common_1.BadRequestException('Invalid name');
710
+ throw new BadRequestException('Invalid name');
702
711
  }
703
712
  const config = await this.configEditorService.getConfigFile();
704
713
  config.bridge.name = name;
@@ -706,7 +715,7 @@ let ServerService = class ServerService {
706
715
  }
707
716
  async setHomebridgePort(port) {
708
717
  if (!port || typeof port !== 'number' || !Number.isInteger(port) || port < 1025 || port > 65533) {
709
- throw new common_1.BadRequestException('Invalid port number');
718
+ throw new BadRequestException('Invalid port number');
710
719
  }
711
720
  const config = await this.configEditorService.getConfigFile();
712
721
  config.bridge.port = port;
@@ -721,19 +730,19 @@ let ServerService = class ServerService {
721
730
  delete value.end;
722
731
  }
723
732
  if ('start' in value && (typeof value.start !== 'number' || value.start < 1025 || value.start > 65533)) {
724
- throw new common_1.BadRequestException('Port start must be a number between 1025 and 65533.');
733
+ throw new BadRequestException('Port start must be a number between 1025 and 65533.');
725
734
  }
726
735
  if ('end' in value && (typeof value.end !== 'number' || value.end < 1025 || value.end > 65533)) {
727
- throw new common_1.BadRequestException('Port end must be a number between 1025 and 65533.');
736
+ throw new BadRequestException('Port end must be a number between 1025 and 65533.');
728
737
  }
729
738
  if ('start' in value && 'end' in value && value.start >= value.end) {
730
- throw new common_1.BadRequestException('Ports start must be less than end.');
739
+ throw new BadRequestException('Ports start must be less than end.');
731
740
  }
732
741
  if ('start' in value && !('end' in value) && config.ports?.end && value.start >= config.ports.end) {
733
- throw new common_1.BadRequestException('Ports start must be less than end.');
742
+ throw new BadRequestException('Ports start must be less than end.');
734
743
  }
735
744
  if ('end' in value && !('start' in value) && config.ports?.start && config.ports.start >= value.end) {
736
- throw new common_1.BadRequestException('Ports start must be less than end.');
745
+ throw new BadRequestException('Ports start must be less than end.');
737
746
  }
738
747
  if (!value.start && !value.end) {
739
748
  delete config.ports;
@@ -756,10 +765,10 @@ let ServerService = class ServerService {
756
765
  const uiConfigBlock = configFile.platforms.find(x => x.platform === 'config');
757
766
  if (uiConfigBlock) {
758
767
  if (uiConfigBlock.wallpaper) {
759
- const oldPath = (0, node_path_1.join)(this.configService.storagePath, uiConfigBlock.wallpaper);
760
- if (await (0, fs_extra_1.pathExists)(oldPath)) {
768
+ const oldPath = join(this.configService.storagePath, uiConfigBlock.wallpaper);
769
+ if (await pathExists(oldPath)) {
761
770
  try {
762
- await (0, fs_extra_1.unlink)(oldPath);
771
+ await unlink(oldPath);
763
772
  this.logger.log(`Old wallpaper file ${oldPath} deleted successfully.`);
764
773
  }
765
774
  catch (e) {
@@ -767,9 +776,9 @@ let ServerService = class ServerService {
767
776
  }
768
777
  }
769
778
  }
770
- const fileExtension = (0, node_path_1.extname)(data.filename);
771
- const newPath = (0, node_path_1.join)(this.configService.storagePath, `ui-wallpaper${fileExtension}`);
772
- await pump(data.file, (0, fs_extra_1.createWriteStream)(newPath));
779
+ const fileExtension = extname(data.filename);
780
+ const newPath = join(this.configService.storagePath, `ui-wallpaper${fileExtension}`);
781
+ await pump(data.file, createWriteStream(newPath));
773
782
  uiConfigBlock.wallpaper = `ui-wallpaper${fileExtension}`;
774
783
  await this.configEditorService.updateConfigFile(configFile);
775
784
  this.logger.log('Wallpaper uploaded and set in the config file.');
@@ -778,11 +787,11 @@ let ServerService = class ServerService {
778
787
  async deleteWallpaper() {
779
788
  const configFile = await this.configEditorService.getConfigFile();
780
789
  const uiConfigBlock = configFile.platforms.find(x => x.platform === 'config');
781
- const fullPath = (0, node_path_1.join)(this.configService.storagePath, uiConfigBlock.wallpaper);
790
+ const fullPath = join(this.configService.storagePath, uiConfigBlock.wallpaper);
782
791
  if (uiConfigBlock && uiConfigBlock.wallpaper) {
783
- if (await (0, fs_extra_1.pathExists)(fullPath)) {
792
+ if (await pathExists(fullPath)) {
784
793
  try {
785
- await (0, fs_extra_1.unlink)(fullPath);
794
+ await unlink(fullPath);
786
795
  this.logger.log(`Wallpaper file ${uiConfigBlock.wallpaper} deleted successfully.`);
787
796
  }
788
797
  catch (e) {
@@ -798,9 +807,9 @@ let ServerService = class ServerService {
798
807
  async nodeVersionChanged() {
799
808
  return new Promise((res) => {
800
809
  let result = false;
801
- const child = (0, node_child_process_1.spawn)(node_process_1.default.execPath, ['-v'], { shell: true });
810
+ const child = spawn(process.execPath, ['-v']);
802
811
  child.stdout.once('data', (data) => {
803
- result = data.toString().trim() !== node_process_1.default.version;
812
+ result = data.toString().trim() !== process.version;
804
813
  });
805
814
  child.on('error', () => {
806
815
  result = true;
@@ -810,14 +819,261 @@ let ServerService = class ServerService {
810
819
  });
811
820
  });
812
821
  }
822
+ async uploadSslKeyCert(req) {
823
+ const parts = req.parts ? req.parts() : null;
824
+ const files = [];
825
+ if (parts) {
826
+ for await (const part of parts) {
827
+ if (part.file) {
828
+ files.push(part);
829
+ }
830
+ }
831
+ }
832
+ else {
833
+ const single = await req.file();
834
+ if (single?.file) {
835
+ files.push(single);
836
+ }
837
+ }
838
+ if (!files.length) {
839
+ throw new BadRequestException('No files uploaded. Please upload both the private key and certificate files.');
840
+ }
841
+ const readStreamToBuffer = async (stream) => {
842
+ const chunks = [];
843
+ await new Promise((resolvePromise, rejectPromise) => {
844
+ stream.on('data', (d) => chunks.push(Buffer.isBuffer(d) ? d : Buffer.from(d)));
845
+ stream.on('end', () => resolvePromise());
846
+ stream.on('error', rejectPromise);
847
+ });
848
+ return Buffer.concat(chunks);
849
+ };
850
+ let keyPem = null;
851
+ let certPem = null;
852
+ for (const f of files) {
853
+ if (f.file?.truncated) {
854
+ throw new InternalServerErrorException(`Upload exceeds maximum size ${globalThis.backup.maxBackupSizeText}.`);
855
+ }
856
+ const buf = await readStreamToBuffer(f.file);
857
+ const text = buf.toString('utf8');
858
+ if (/-----BEGIN (?:RSA |EC )?PRIVATE KEY-----/.test(text)) {
859
+ keyPem = buf;
860
+ }
861
+ else if (/-----BEGIN CERTIFICATE-----/.test(text)) {
862
+ certPem = buf;
863
+ }
864
+ else if (f.fieldname === 'key') {
865
+ keyPem = buf;
866
+ }
867
+ else if (f.fieldname === 'cert') {
868
+ certPem = buf;
869
+ }
870
+ }
871
+ if (!keyPem || !certPem) {
872
+ throw new BadRequestException('Both a PEM private key and certificate must be provided.');
873
+ }
874
+ try {
875
+ const x509 = new X509Certificate(certPem);
876
+ const certPub = x509.publicKey.export({ type: 'spki', format: 'der' });
877
+ const priv = createPrivateKey({ key: keyPem });
878
+ const pubFromPriv = createPublicKey(priv).export({ type: 'spki', format: 'der' });
879
+ if (!certPub.equals(pubFromPriv)) {
880
+ throw new BadRequestException('The private key does not match the certificate public key.');
881
+ }
882
+ createSecureContext({ key: keyPem, cert: certPem });
883
+ }
884
+ catch (e) {
885
+ if (e instanceof BadRequestException) {
886
+ throw e;
887
+ }
888
+ throw new BadRequestException(`Invalid key/certificate: ${e?.message || e}`);
889
+ }
890
+ const sslDir = join(this.configService.storagePath, 'ssl-certs');
891
+ const keyPath = join(sslDir, 'ui-ssl.key');
892
+ const certPath = join(sslDir, 'ui-ssl.crt');
893
+ const { ensureDir, writeFile } = await import('fs-extra');
894
+ await ensureDir(sslDir);
895
+ await writeFile(keyPath, keyPem);
896
+ await writeFile(certPath, certPem);
897
+ const configFile = await this.configEditorService.getConfigFile();
898
+ const uiConfigBlock = configFile.platforms.find((x) => x.platform === 'config');
899
+ if (!uiConfigBlock) {
900
+ throw new InternalServerErrorException('Config platform block not found.');
901
+ }
902
+ if (!uiConfigBlock.ssl) {
903
+ uiConfigBlock.ssl = {};
904
+ }
905
+ uiConfigBlock.ssl.key = keyPath;
906
+ uiConfigBlock.ssl.cert = certPath;
907
+ delete uiConfigBlock.ssl.pfx;
908
+ delete uiConfigBlock.ssl.passphrase;
909
+ uiConfigBlock.ssl.selfSigned = false;
910
+ await this.configEditorService.updateConfigFile(configFile);
911
+ return {
912
+ ok: true,
913
+ type: 'keycert',
914
+ keyPath,
915
+ certPath,
916
+ details: 'Certificate and key validated and saved.',
917
+ };
918
+ }
919
+ async uploadSslPfx(req) {
920
+ let passphrase;
921
+ let filePart;
922
+ if (req.parts) {
923
+ for await (const part of req.parts()) {
924
+ if (part.type === 'file' || part.file) {
925
+ filePart = part;
926
+ }
927
+ else if (part.type === 'field' || part.value) {
928
+ if (part.fieldname === 'passphrase') {
929
+ passphrase = part.value;
930
+ }
931
+ }
932
+ }
933
+ }
934
+ else {
935
+ filePart = await req.file();
936
+ passphrase = req.body?.passphrase;
937
+ }
938
+ if (!filePart) {
939
+ throw new BadRequestException('No PFX file uploaded.');
940
+ }
941
+ if (filePart.file?.truncated) {
942
+ throw new InternalServerErrorException(`Upload exceeds maximum size ${globalThis.backup.maxBackupSizeText}.`);
943
+ }
944
+ const readStreamToBuffer = async (stream) => {
945
+ const chunks = [];
946
+ await new Promise((resolvePromise, rejectPromise) => {
947
+ stream.on('data', (d) => chunks.push(Buffer.isBuffer(d) ? d : Buffer.from(d)));
948
+ stream.on('end', () => resolvePromise());
949
+ stream.on('error', rejectPromise);
950
+ });
951
+ return Buffer.concat(chunks);
952
+ };
953
+ const pfxBuffer = await readStreamToBuffer(filePart.file);
954
+ try {
955
+ createSecureContext({ pfx: pfxBuffer, passphrase });
956
+ }
957
+ catch (e) {
958
+ throw new BadRequestException(`Invalid PFX or passphrase: ${e?.message || e}`);
959
+ }
960
+ const sslDir = join(this.configService.storagePath, 'ssl-certs');
961
+ const pfxPath = join(sslDir, 'ui-ssl.pfx');
962
+ const { ensureDir, writeFile } = await import('fs-extra');
963
+ await ensureDir(sslDir);
964
+ await writeFile(pfxPath, pfxBuffer);
965
+ const configFile = await this.configEditorService.getConfigFile();
966
+ const uiConfigBlock = configFile.platforms.find((x) => x.platform === 'config');
967
+ if (!uiConfigBlock) {
968
+ throw new InternalServerErrorException('Config platform block not found.');
969
+ }
970
+ if (!uiConfigBlock.ssl) {
971
+ uiConfigBlock.ssl = {};
972
+ }
973
+ uiConfigBlock.ssl.pfx = pfxPath;
974
+ uiConfigBlock.ssl.passphrase = passphrase || '';
975
+ delete uiConfigBlock.ssl.key;
976
+ delete uiConfigBlock.ssl.cert;
977
+ uiConfigBlock.ssl.selfSigned = false;
978
+ await this.configEditorService.updateConfigFile(configFile);
979
+ return {
980
+ ok: true,
981
+ type: 'pfx',
982
+ pfxPath,
983
+ details: 'PFX validated and saved.',
984
+ };
985
+ }
986
+ async validateCurrentSslConfig() {
987
+ const configFile = await this.configEditorService.getConfigFile();
988
+ const uiConfigBlock = configFile.platforms.find((x) => x.platform === 'config');
989
+ const ssl = uiConfigBlock?.ssl || {};
990
+ if (!ssl || (!ssl.selfSigned && !ssl.key && !ssl.cert && !ssl.pfx)) {
991
+ return { ok: true, valid: true, type: 'off', details: 'HTTPS is disabled.' };
992
+ }
993
+ if (ssl.selfSigned) {
994
+ return { ok: true, valid: true, type: 'selfsigned', details: 'Self-signed mode enabled.' };
995
+ }
996
+ try {
997
+ if (ssl.key && ssl.cert) {
998
+ const { readFile } = await import('fs-extra');
999
+ const keyPem = await readFile(ssl.key);
1000
+ const certPem = await readFile(ssl.cert);
1001
+ const x509 = new X509Certificate(certPem);
1002
+ const certPub = x509.publicKey.export({ type: 'spki', format: 'der' });
1003
+ const priv = createPrivateKey({ key: keyPem });
1004
+ const pubFromPriv = createPublicKey(priv).export({ type: 'spki', format: 'der' });
1005
+ if (!certPub.equals(pubFromPriv)) {
1006
+ return { ok: true, valid: false, type: 'keycert', details: 'Private key does not match certificate.' };
1007
+ }
1008
+ createSecureContext({ key: keyPem, cert: certPem });
1009
+ return { ok: true, valid: true, type: 'keycert', details: 'Key and certificate are valid and match.' };
1010
+ }
1011
+ if (ssl.pfx) {
1012
+ const { readFile } = await import('fs-extra');
1013
+ const pfx = await readFile(ssl.pfx);
1014
+ createSecureContext({ pfx, passphrase: ssl.passphrase });
1015
+ return { ok: true, valid: true, type: 'pfx', details: 'PFX file and passphrase are valid.' };
1016
+ }
1017
+ }
1018
+ catch (e) {
1019
+ return { ok: true, valid: false, type: ssl.pfx ? 'pfx' : 'keycert', details: e?.message || String(e) };
1020
+ }
1021
+ return { ok: true, valid: false, type: 'off', details: 'No SSL configuration found.' };
1022
+ }
1023
+ async generateSelfSignedCertificate(options = {}) {
1024
+ const hostnames = Array.isArray(options.hostnames) && options.hostnames.length
1025
+ ? options.hostnames.map(h => String(h).trim()).filter(Boolean)
1026
+ : ['localhost', '127.0.0.1'];
1027
+ const mode = options.mode || 'keycert';
1028
+ const generator = new SslCertGeneratorService();
1029
+ await generator.generateCertificate(hostnames);
1030
+ const sslDir = join(this.configService.storagePath, 'ssl-certs');
1031
+ const keyPath = join(sslDir, 'private-key.pem');
1032
+ const certPath = join(sslDir, 'certificate.pem');
1033
+ const configFile = await this.configEditorService.getConfigFile();
1034
+ const uiConfigBlock = configFile.platforms.find((x) => x.platform === 'config');
1035
+ if (!uiConfigBlock.ssl) {
1036
+ uiConfigBlock.ssl = {};
1037
+ }
1038
+ if (mode === 'keycert') {
1039
+ uiConfigBlock.ssl.key = keyPath;
1040
+ uiConfigBlock.ssl.cert = certPath;
1041
+ delete uiConfigBlock.ssl.pfx;
1042
+ delete uiConfigBlock.ssl.passphrase;
1043
+ uiConfigBlock.ssl.selfSigned = false;
1044
+ uiConfigBlock.ssl.selfSignedHostnames = hostnames;
1045
+ }
1046
+ else {
1047
+ delete uiConfigBlock.ssl.key;
1048
+ delete uiConfigBlock.ssl.cert;
1049
+ delete uiConfigBlock.ssl.pfx;
1050
+ delete uiConfigBlock.ssl.passphrase;
1051
+ uiConfigBlock.ssl.selfSigned = true;
1052
+ uiConfigBlock.ssl.selfSignedHostnames = hostnames;
1053
+ }
1054
+ await this.configEditorService.updateConfigFile(configFile);
1055
+ return {
1056
+ ok: true,
1057
+ type: 'generated',
1058
+ mode,
1059
+ keyPath: mode === 'keycert' ? keyPath : undefined,
1060
+ certPath: mode === 'keycert' ? certPath : undefined,
1061
+ details: `Self-signed certificate generated for ${hostnames.join(', ')}`,
1062
+ };
1063
+ }
813
1064
  };
814
- exports.ServerService = ServerService;
815
- exports.ServerService = ServerService = __decorate([
816
- (0, common_1.Injectable)(),
817
- __metadata("design:paramtypes", [config_service_1.ConfigService,
818
- config_editor_service_1.ConfigEditorService,
819
- accessories_service_1.AccessoriesService,
820
- homebridge_ipc_service_1.HomebridgeIpcService,
821
- logger_service_1.Logger])
1065
+ ServerService = __decorate([
1066
+ Injectable(),
1067
+ __param(0, Inject(ConfigService)),
1068
+ __param(1, Inject(ConfigEditorService)),
1069
+ __param(2, Inject(AccessoriesService)),
1070
+ __param(3, Inject(HomebridgeIpcService)),
1071
+ __param(4, Inject(Logger)),
1072
+ __metadata("design:paramtypes", [ConfigService,
1073
+ ConfigEditorService,
1074
+ AccessoriesService,
1075
+ HomebridgeIpcService,
1076
+ Logger])
822
1077
  ], ServerService);
1078
+ export { ServerService };
823
1079
  //# sourceMappingURL=server.service.js.map