homebridge-config-ui-x 5.11.2-beta.8 → 5.11.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 (249) hide show
  1. package/CHANGELOG.md +3 -21
  2. package/dist/core/auth/auth.controller.d.ts +0 -4
  3. package/dist/core/config/config.interfaces.d.ts +0 -14
  4. package/dist/core/config/config.service.d.ts +0 -6
  5. package/dist/core/config/config.service.js +0 -8
  6. package/dist/core/config/config.service.js.map +1 -1
  7. package/dist/core/config/config.startup.js +17 -48
  8. package/dist/core/config/config.startup.js.map +1 -1
  9. package/dist/core/feature-flags/feature-flags.registry.js +0 -5
  10. package/dist/core/feature-flags/feature-flags.registry.js.map +1 -1
  11. package/dist/core/homebridge-ipc/homebridge-ipc.service.js +0 -1
  12. package/dist/core/homebridge-ipc/homebridge-ipc.service.js.map +1 -1
  13. package/dist/core/spa/spa.filter.d.ts +0 -3
  14. package/dist/core/spa/spa.filter.js +2 -22
  15. package/dist/core/spa/spa.filter.js.map +1 -1
  16. package/dist/globalDefaults.js +0 -3
  17. package/dist/globalDefaults.js.map +1 -1
  18. package/dist/main.js +4 -18
  19. package/dist/main.js.map +1 -1
  20. package/dist/modules/accessories/accessories.controller.d.ts +1 -1
  21. package/dist/modules/accessories/accessories.module.js +0 -2
  22. package/dist/modules/accessories/accessories.module.js.map +1 -1
  23. package/dist/modules/accessories/accessories.service.d.ts +3 -21
  24. package/dist/modules/accessories/accessories.service.js +17 -280
  25. package/dist/modules/accessories/accessories.service.js.map +1 -1
  26. package/dist/modules/child-bridges/child-bridges.interfaces.d.ts +0 -9
  27. package/dist/modules/config-editor/config-editor.controller.d.ts +0 -4
  28. package/dist/modules/config-editor/config-editor.controller.js +0 -64
  29. package/dist/modules/config-editor/config-editor.controller.js.map +1 -1
  30. package/dist/modules/config-editor/config-editor.service.d.ts +1 -6
  31. package/dist/modules/config-editor/config-editor.service.js +1 -45
  32. package/dist/modules/config-editor/config-editor.service.js.map +1 -1
  33. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.js +1 -1
  34. package/dist/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.js.map +1 -1
  35. package/dist/modules/plugins/plugins.module.js +1 -1
  36. package/dist/modules/plugins/plugins.service.js +2 -17
  37. package/dist/modules/plugins/plugins.service.js.map +1 -1
  38. package/dist/modules/server/server.controller.d.ts +0 -50
  39. package/dist/modules/server/server.controller.js +2 -201
  40. package/dist/modules/server/server.controller.js.map +1 -1
  41. package/dist/modules/server/server.service.d.ts +0 -48
  42. package/dist/modules/server/server.service.js +14 -502
  43. package/dist/modules/server/server.service.js.map +1 -1
  44. package/dist/modules/status/status.gateway.d.ts +0 -2
  45. package/dist/modules/status/status.interfaces.d.ts +0 -11
  46. package/dist/modules/status/status.service.d.ts +1 -4
  47. package/dist/modules/status/status.service.js +2 -21
  48. package/dist/modules/status/status.service.js.map +1 -1
  49. package/package.json +7 -9
  50. package/public/3rdpartylicenses.txt +620 -594
  51. package/public/assets/plugin-ui-utils/ui.js +0 -3
  52. package/public/assets/plugin-ui-utils/ui.js.map +1 -1
  53. package/public/chunk-2BB4D4TW.js +1 -0
  54. package/public/chunk-2GCZ3AMH.js +1 -0
  55. package/public/chunk-2K5FWBCK.js +8 -0
  56. package/public/chunk-2LQBMVWH.js +1 -0
  57. package/public/chunk-34ZN4GVA.js +3 -0
  58. package/public/chunk-3JW6FD5V.js +1 -0
  59. package/public/chunk-57XTQ6PK.js +1 -0
  60. package/public/chunk-5DBV5PYR.js +19 -0
  61. package/public/chunk-5GKTPXPE.js +1 -0
  62. package/public/chunk-5X7ARCKG.js +5 -0
  63. package/public/chunk-67HOYJJ2.js +1 -0
  64. package/public/chunk-6MZHUZRT.js +4 -0
  65. package/public/chunk-77CMUO6J.js +1 -0
  66. package/public/chunk-7LJYL7EH.js +1 -0
  67. package/public/chunk-7TFBELRD.js +1 -0
  68. package/public/chunk-AXOHPUQR.js +1 -0
  69. package/public/chunk-BMAZBLAT.js +1 -0
  70. package/public/chunk-C554TVZA.js +2 -0
  71. package/public/chunk-DGDNSN6I.js +1 -0
  72. package/public/chunk-E6RSPO2D.js +1 -0
  73. package/public/chunk-ESQ665GW.js +5 -0
  74. package/public/chunk-G4QH622U.js +5 -0
  75. package/public/chunk-GKPR5M7S.js +1 -0
  76. package/public/chunk-GT7UMMFF.js +2 -0
  77. package/public/chunk-HBIQJCSE.js +1 -0
  78. package/public/{chunk-BMOLDRJ3.js → chunk-JLZ5WU6N.js} +1 -1
  79. package/public/chunk-JSZIAFBJ.js +1 -0
  80. package/public/chunk-JWQRV434.js +1 -0
  81. package/public/chunk-JX72JCMA.js +1 -0
  82. package/public/chunk-KT26K4DO.js +1 -0
  83. package/public/chunk-L63FND3A.js +1 -0
  84. package/public/chunk-LSXTHVKB.js +1 -0
  85. package/public/chunk-N5VXONVW.js +1 -0
  86. package/public/{chunk-H7F7H5MW.js → chunk-N6JGA2PG.js} +1 -1
  87. package/public/chunk-NVCJ3EJS.js +1 -0
  88. package/public/chunk-OPJZWDSO.js +1 -0
  89. package/public/chunk-OXBXHVWY.js +8 -0
  90. package/public/chunk-QHROK73U.js +50 -0
  91. package/public/chunk-QNEXPAIT.js +1 -0
  92. package/public/chunk-R2G2YWV4.js +51 -0
  93. package/public/chunk-RCNF365Q.js +1 -0
  94. package/public/chunk-RT6EDRIH.js +1 -0
  95. package/public/chunk-RWM6K46M.js +1 -0
  96. package/public/chunk-SVVR6UMH.js +1 -0
  97. package/public/chunk-UI4U37MO.js +1 -0
  98. package/public/chunk-ULKYNDD3.js +16 -0
  99. package/public/chunk-UPZ5UT6G.js +1 -0
  100. package/public/chunk-UQFIBBEZ.js +1 -0
  101. package/public/chunk-UWUTC3BD.js +1 -0
  102. package/public/chunk-UZ6QYM64.js +1 -0
  103. package/public/{chunk-CP6FP6S2.js → chunk-VKHX6FUQ.js} +2 -52
  104. package/public/chunk-VM2MV3DC.js +1 -0
  105. package/public/chunk-VM6FMRHY.js +1 -0
  106. package/public/chunk-VYK3U745.js +1 -0
  107. package/public/chunk-VZJJWHRX.js +1 -0
  108. package/public/chunk-WHC4E7WY.js +1 -0
  109. package/public/chunk-WJKVPIP2.js +1 -0
  110. package/public/chunk-WOBQOQPU.js +1 -0
  111. package/public/chunk-WTGHGHPV.js +1 -0
  112. package/public/chunk-WY6UQ47H.js +1 -0
  113. package/public/chunk-X4ZEQSRY.js +4 -0
  114. package/public/{chunk-WVG4A2SW.js → chunk-XVO5247V.js} +1 -1
  115. package/public/chunk-XWNU2MFJ.js +1 -0
  116. package/public/chunk-YD3GJ2C6.js +1 -0
  117. package/public/chunk-YUEGV7HK.js +4 -0
  118. package/public/chunk-ZLRFR32W.js +1 -0
  119. package/public/chunk-ZZ5IX26U.js +40 -0
  120. package/public/chunk-ZZQEWRDE.js +1 -0
  121. package/public/index.html +2 -2
  122. package/public/main-VKVUZHHA.js +1 -0
  123. package/public/polyfills-5KWHJ7II.js +2 -0
  124. package/public/styles-7EFV5QBG.css +1 -0
  125. package/scripts/extract-plugin-alias.js +2 -53
  126. package/dist/core/spa/spa-html.service.d.ts +0 -5
  127. package/dist/core/spa/spa-html.service.js +0 -32
  128. package/dist/core/spa/spa-html.service.js.map +0 -1
  129. package/dist/core/ssl/ssl-cert-generator.service.d.ts +0 -15
  130. package/dist/core/ssl/ssl-cert-generator.service.js +0 -125
  131. package/dist/core/ssl/ssl-cert-generator.service.js.map +0 -1
  132. package/dist/modules/accessories/accessories.interfaces.d.ts +0 -94
  133. package/dist/modules/accessories/accessories.interfaces.js +0 -2
  134. package/dist/modules/accessories/accessories.interfaces.js.map +0 -1
  135. package/docs/matter-todo.md +0 -15
  136. package/docs/ssl-upload-pr.md +0 -103
  137. package/public/assets/matter.svg +0 -8
  138. package/public/chunk-2V4LIZUH.js +0 -1
  139. package/public/chunk-4UVYLGCZ.js +0 -1
  140. package/public/chunk-4WEBTV3N.js +0 -1
  141. package/public/chunk-4YNYBAGL.js +0 -1
  142. package/public/chunk-52X3LPJH.js +0 -1
  143. package/public/chunk-5R6AJZGA.js +0 -1
  144. package/public/chunk-5WSUQV2C.js +0 -1
  145. package/public/chunk-6DLZEENG.js +0 -1
  146. package/public/chunk-6INJQUJQ.js +0 -16
  147. package/public/chunk-6QWPGE2L.js +0 -1
  148. package/public/chunk-77S5CL3V.js +0 -1
  149. package/public/chunk-7BMHIIBT.js +0 -1
  150. package/public/chunk-7DFQDPRM.js +0 -1
  151. package/public/chunk-7WKZ7EMI.js +0 -1
  152. package/public/chunk-7WUBDTA6.js +0 -1
  153. package/public/chunk-AXMO2G45.js +0 -1
  154. package/public/chunk-B46EWHBD.js +0 -1
  155. package/public/chunk-B4AJQJMI.js +0 -1
  156. package/public/chunk-B75B723G.js +0 -1
  157. package/public/chunk-BB35SJH2.js +0 -2
  158. package/public/chunk-BFGRDXJK.js +0 -35
  159. package/public/chunk-BQRKHSGH.js +0 -1
  160. package/public/chunk-BXRCPOIK.js +0 -1
  161. package/public/chunk-BZ3XB6O4.js +0 -1
  162. package/public/chunk-CEMVTOZG.js +0 -4
  163. package/public/chunk-CMERG3AC.js +0 -1
  164. package/public/chunk-CMO4UANJ.js +0 -1
  165. package/public/chunk-CPT52C2F.js +0 -1
  166. package/public/chunk-D3Q5QTFY.js +0 -1
  167. package/public/chunk-ETWBSGPI.js +0 -1
  168. package/public/chunk-EWS4VSZB.js +0 -1
  169. package/public/chunk-F5AJLGGI.js +0 -1
  170. package/public/chunk-G2GGYHA2.js +0 -3
  171. package/public/chunk-G2KWTNHR.js +0 -1
  172. package/public/chunk-GDWF2NMA.js +0 -2
  173. package/public/chunk-GGTS2YBW.js +0 -4
  174. package/public/chunk-GJG6QZ7P.js +0 -1
  175. package/public/chunk-GU5F3H4I.js +0 -1
  176. package/public/chunk-H3BKW5W3.js +0 -1
  177. package/public/chunk-H4WASUXW.js +0 -1
  178. package/public/chunk-HUTYOGRH.js +0 -4
  179. package/public/chunk-IBUR2RIO.js +0 -1
  180. package/public/chunk-IDJSTIFL.js +0 -1
  181. package/public/chunk-IP6FLYVL.js +0 -1
  182. package/public/chunk-IPI77WYV.js +0 -1
  183. package/public/chunk-J2DDS6ED.js +0 -1
  184. package/public/chunk-J6ND4K5Q.js +0 -1
  185. package/public/chunk-J7UDRE66.js +0 -2
  186. package/public/chunk-JUQRWAIR.js +0 -1
  187. package/public/chunk-JWGWPSC6.js +0 -1
  188. package/public/chunk-JWRZMMRO.js +0 -68
  189. package/public/chunk-JWUEJV6S.js +0 -1
  190. package/public/chunk-JY5ZEEL2.js +0 -1
  191. package/public/chunk-KFPYUDGJ.js +0 -1
  192. package/public/chunk-KIRW7NMH.js +0 -1
  193. package/public/chunk-KTQBVBY4.js +0 -1
  194. package/public/chunk-LKJRMUOE.js +0 -1
  195. package/public/chunk-LVQWSVHA.js +0 -1
  196. package/public/chunk-LZ7S7WKH.js +0 -1
  197. package/public/chunk-MDHWQ5V2.js +0 -8
  198. package/public/chunk-MJP4XVUI.js +0 -1
  199. package/public/chunk-N5ONV6TU.js +0 -1
  200. package/public/chunk-N7UWTPTT.js +0 -1
  201. package/public/chunk-NAICVRJH.js +0 -1
  202. package/public/chunk-NCFDA3W4.js +0 -1
  203. package/public/chunk-NIS65GVY.js +0 -1
  204. package/public/chunk-OBV66CW4.js +0 -1
  205. package/public/chunk-OF2SRCQW.js +0 -5
  206. package/public/chunk-OOILCTQ3.js +0 -19
  207. package/public/chunk-PAZUAFSZ.js +0 -1
  208. package/public/chunk-PEUDPLH6.js +0 -1
  209. package/public/chunk-PRGOUVRO.js +0 -1
  210. package/public/chunk-PWCLNQBI.js +0 -1
  211. package/public/chunk-Q7EXN4JA.js +0 -1
  212. package/public/chunk-QE7VI3JB.js +0 -1
  213. package/public/chunk-QES44GQE.js +0 -1
  214. package/public/chunk-QMWN5KPC.js +0 -1
  215. package/public/chunk-R6MQZ2DW.js +0 -1
  216. package/public/chunk-RESZLSD7.js +0 -1
  217. package/public/chunk-RGWFM4OK.js +0 -1
  218. package/public/chunk-RI4GLH22.js +0 -1
  219. package/public/chunk-RP5JPYDI.js +0 -1
  220. package/public/chunk-RT25QBCQ.js +0 -1
  221. package/public/chunk-RVWZNTDJ.js +0 -1
  222. package/public/chunk-RXDY2NMJ.js +0 -1
  223. package/public/chunk-SDRRZFEQ.js +0 -1
  224. package/public/chunk-SPC2DLZR.js +0 -3
  225. package/public/chunk-TCUQZ3QO.js +0 -1
  226. package/public/chunk-TPUA4UIN.js +0 -1
  227. package/public/chunk-TQBVDY26.js +0 -1
  228. package/public/chunk-U24HWDVU.js +0 -1
  229. package/public/chunk-U2NM4L2D.js +0 -1
  230. package/public/chunk-UWYTPKKV.js +0 -1
  231. package/public/chunk-VKR3GG6K.js +0 -1
  232. package/public/chunk-VY7HWBNV.js +0 -5
  233. package/public/chunk-W55SP3LJ.js +0 -1
  234. package/public/chunk-WP3AD6W5.js +0 -1
  235. package/public/chunk-XNZA4UBO.js +0 -12
  236. package/public/chunk-XOPZ7U6G.js +0 -1
  237. package/public/chunk-XORPUWNC.js +0 -1
  238. package/public/chunk-XPFMPBEG.js +0 -1
  239. package/public/chunk-XTYMIZVV.js +0 -1
  240. package/public/chunk-Y3PXWRYQ.js +0 -1
  241. package/public/chunk-Y5WP66WK.js +0 -1
  242. package/public/chunk-YCQCWGBG.js +0 -1
  243. package/public/chunk-Z5PUNNUZ.js +0 -1
  244. package/public/chunk-ZCGZM7LU.js +0 -1
  245. package/public/chunk-ZNN6GWYK.js +0 -19
  246. package/public/main-O5PA2XOA.js +0 -1
  247. package/public/media/matter-P563JGDL.svg +0 -8
  248. package/public/polyfills-34U4WL3Z.js +0 -1
  249. package/public/styles-CT2LPGES.css +0 -1
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  import { EventEmitter } from 'node:events'
8
- import { readFileSync } from 'node:fs'
9
8
  import { createRequire } from 'node:module'
10
9
  import path from 'node:path'
11
10
  import process from 'node:process'
@@ -41,26 +40,6 @@ const HomebridgeApiMock = {
41
40
  serverVersion: '1.2.3',
42
41
  on: () => { /** mock */ },
43
42
  emit: () => { /** mock */ },
44
- // Mock Matter API
45
- isMatterAvailable() {
46
- return true
47
- },
48
- isMatterEnabled() {
49
- return true
50
- },
51
- matterDeviceTypes: new Proxy({}, {
52
- get() {
53
- return {} // Return empty object for any device type
54
- },
55
- }),
56
- matterClusters: new Proxy({}, {
57
- get() {
58
- return {} // Return empty object for any cluster
59
- },
60
- }),
61
- registerMatterAccessory: () => { /** mock */ },
62
- unregisterMatterAccessory: () => { /** mock */ },
63
- updateMatterAccessoryState: () => { /** mock */ },
64
43
  hap: {
65
44
  Characteristic: new class Characteristic extends EventEmitter {
66
45
  constructor() {
@@ -124,41 +103,11 @@ const HomebridgeApiMock = {
124
103
  },
125
104
  }
126
105
 
127
- async function main() {
106
+ function main() {
128
107
  try {
129
108
  let pluginInitializer
130
109
  const pluginPath = process.env.UIX_EXTRACT_PLUGIN_PATH
131
-
132
- // Read package.json to get the proper entry point
133
- let actualEntryPoint = pluginPath
134
- try {
135
- const packageJsonPath = path.join(pluginPath, 'package.json')
136
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
137
-
138
- if (packageJson.main) {
139
- actualEntryPoint = path.join(pluginPath, packageJson.main)
140
- }
141
- } catch (err) {
142
- console.error('[extract-plugin-alias] Could not read package.json, using directory path')
143
- }
144
-
145
- let pluginModules
146
-
147
- // Try to load as CommonJS first
148
- try {
149
- pluginModules = require(actualEntryPoint)
150
- } catch (requireError) {
151
- // If require fails, try dynamic import for ESM modules
152
- try {
153
- // For ESM, we need to use file:// URL on some platforms
154
- const importPath = actualEntryPoint.startsWith('/') || actualEntryPoint.startsWith('file://')
155
- ? actualEntryPoint
156
- : path.resolve(actualEntryPoint)
157
- pluginModules = await import(importPath)
158
- } catch (importError) {
159
- throw requireError // Throw the original error
160
- }
161
- }
110
+ const pluginModules = require(pluginPath)
162
111
 
163
112
  if (typeof pluginModules === 'function') {
164
113
  pluginInitializer = pluginModules
@@ -1,5 +0,0 @@
1
- export declare class SpaHtmlService {
2
- static updateIndexHtml(webroot: string): Promise<void>;
3
- private static normalizeWebroot;
4
- private static transformHtmlForWebroot;
5
- }
@@ -1,32 +0,0 @@
1
- import { readFile, writeFile } from 'node:fs/promises';
2
- import { resolve } from 'node:path';
3
- import process from 'node:process';
4
- import { pathExists as exists } from 'fs-extra/esm';
5
- export class SpaHtmlService {
6
- static async updateIndexHtml(webroot) {
7
- const indexPath = resolve(process.env.UIX_BASE_PATH, 'public/index.html');
8
- if (!(await exists(indexPath))) {
9
- return;
10
- }
11
- const originalHtml = await readFile(indexPath, 'utf-8');
12
- const normalizedWebroot = this.normalizeWebroot(webroot);
13
- const modifiedHtml = this.transformHtmlForWebroot(originalHtml, normalizedWebroot);
14
- await writeFile(indexPath, modifiedHtml);
15
- }
16
- static normalizeWebroot(webroot) {
17
- if (!webroot || webroot === '/') {
18
- return '';
19
- }
20
- return webroot.replace(/\/+/g, '/').replace(/^\/+|\/+$/g, '');
21
- }
22
- static transformHtmlForWebroot(html, webroot) {
23
- const baseHref = webroot ? `/${webroot}/` : '/';
24
- return html
25
- .replace(/<base href="[^"]*"(\s*)\/?>/g, `<base href="${baseHref}"$1/>`)
26
- .replace(/href="\/(?:.*?\/)?assets\//g, 'href="assets/')
27
- .replace(/href="\/(?:.*?\/)?favicon\.ico"/g, 'href="favicon.ico"')
28
- .replace(/href="\/(?:.*?\/)?([^"/]+\.(png|svg|webmanifest))"/g, 'href="$1"')
29
- .replace(/src="\/(?:.*?\/)?assets\//g, 'src="assets/');
30
- }
31
- }
32
- //# sourceMappingURL=spa-html.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spa-html.service.js","sourceRoot":"","sources":["../../../src/core/spa/spa-html.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,OAAO,EAAE,UAAU,IAAI,MAAM,EAAE,MAAM,cAAc,CAAA;AAEnD,MAAM,OAAO,cAAc;IAKzB,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,OAAe;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAA;QACzE,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QACvD,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QACxD,MAAM,YAAY,GAAG,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAA;QAClF,MAAM,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAC1C,CAAC;IAOO,MAAM,CAAC,gBAAgB,CAAC,OAAe;QAC7C,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YAChC,OAAO,EAAE,CAAA;QACX,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IAC/D,CAAC;IAQO,MAAM,CAAC,uBAAuB,CAAC,IAAY,EAAE,OAAe;QAClE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QAE/C,OAAO,IAAI;aACR,OAAO,CAAC,8BAA8B,EAAE,eAAe,QAAQ,OAAO,CAAC;aACvE,OAAO,CAAC,6BAA6B,EAAE,eAAe,CAAC;aACvD,OAAO,CAAC,kCAAkC,EAAE,oBAAoB,CAAC;aACjE,OAAO,CAAC,qDAAqD,EAAE,WAAW,CAAC;aAC3E,OAAO,CAAC,4BAA4B,EAAE,cAAc,CAAC,CAAA;IAC1D,CAAC;CACF"}
@@ -1,15 +0,0 @@
1
- import { Buffer } from 'node:buffer';
2
- interface SslCertificateData {
3
- privateKey: Buffer;
4
- certificate: Buffer;
5
- }
6
- export declare class SslCertGeneratorService {
7
- private readonly logger;
8
- private readonly certDir;
9
- private readonly privateKeyPath;
10
- private readonly certificatePath;
11
- constructor();
12
- generateOrLoadCertificate(hostnames?: string[]): Promise<SslCertificateData>;
13
- generateCertificate(hostnames: string[]): Promise<SslCertificateData>;
14
- }
15
- export {};
@@ -1,125 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- var SslCertGeneratorService_1;
11
- import { Buffer } from 'node:buffer';
12
- import { existsSync } from 'node:fs';
13
- import { readFile, writeFile } from 'node:fs/promises';
14
- import { homedir } from 'node:os';
15
- import { join, resolve } from 'node:path';
16
- import process from 'node:process';
17
- import { Injectable } from '@nestjs/common';
18
- import { ensureDir } from 'fs-extra/esm';
19
- import forge from 'node-forge';
20
- import { Logger } from '../logger/logger.service.js';
21
- let SslCertGeneratorService = SslCertGeneratorService_1 = class SslCertGeneratorService {
22
- logger = new Logger(SslCertGeneratorService_1.name);
23
- certDir;
24
- privateKeyPath;
25
- certificatePath;
26
- constructor() {
27
- const storagePath = process.env.UIX_STORAGE_PATH || resolve(homedir(), '.homebridge');
28
- this.certDir = join(storagePath, 'ssl-certs');
29
- this.privateKeyPath = join(this.certDir, 'private-key.pem');
30
- this.certificatePath = join(this.certDir, 'certificate.pem');
31
- }
32
- async generateOrLoadCertificate(hostnames = ['localhost']) {
33
- if (existsSync(this.privateKeyPath) && existsSync(this.certificatePath)) {
34
- try {
35
- const privateKey = await readFile(this.privateKeyPath);
36
- const certificate = await readFile(this.certificatePath);
37
- this.logger.log('Loaded existing self-signed certificate');
38
- return { privateKey, certificate };
39
- }
40
- catch (error) {
41
- this.logger.warn('Failed to load existing certificate, generating new one:', error.message);
42
- }
43
- }
44
- return this.generateCertificate(hostnames);
45
- }
46
- async generateCertificate(hostnames) {
47
- this.logger.log('Generating self-signed certificate...');
48
- try {
49
- await ensureDir(this.certDir);
50
- const keys = forge.pki.rsa.generateKeyPair(2048);
51
- const cert = forge.pki.createCertificate();
52
- cert.publicKey = keys.publicKey;
53
- cert.serialNumber = '01';
54
- cert.validity.notBefore = new Date();
55
- cert.validity.notAfter = new Date('2050-01-01T00:00:00Z');
56
- const attrs = [
57
- { name: 'commonName', value: hostnames[0] || 'localhost' },
58
- { name: 'countryName', value: 'US' },
59
- { shortName: 'ST', value: 'State' },
60
- { name: 'localityName', value: 'City' },
61
- { name: 'organizationName', value: 'Homebridge' },
62
- { shortName: 'OU', value: 'Homebridge UI' },
63
- ];
64
- cert.setSubject(attrs);
65
- cert.setIssuer(attrs);
66
- const extensions = [
67
- {
68
- name: 'basicConstraints',
69
- cA: true,
70
- },
71
- {
72
- name: 'keyUsage',
73
- keyCertSign: true,
74
- digitalSignature: true,
75
- nonRepudiation: true,
76
- keyEncipherment: true,
77
- dataEncipherment: true,
78
- },
79
- {
80
- name: 'extKeyUsage',
81
- serverAuth: true,
82
- clientAuth: true,
83
- },
84
- {
85
- name: 'subjectAltName',
86
- altNames: hostnames.map((hostname) => {
87
- if (/^(?:\d{1,3}\.){3}\d{1,3}$/.test(hostname) || /^(?:[0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$/i.test(hostname)) {
88
- return {
89
- type: 7,
90
- ip: hostname,
91
- };
92
- }
93
- else {
94
- return {
95
- type: 2,
96
- value: hostname,
97
- };
98
- }
99
- }),
100
- },
101
- ];
102
- cert.setExtensions(extensions);
103
- cert.sign(keys.privateKey, forge.md.sha256.create());
104
- const privateKeyPem = forge.pki.privateKeyToPem(keys.privateKey);
105
- const certificatePem = forge.pki.certificateToPem(cert);
106
- await writeFile(this.privateKeyPath, privateKeyPem, 'utf8');
107
- await writeFile(this.certificatePath, certificatePem, 'utf8');
108
- this.logger.log(`Self-signed certificate generated successfully for: ${hostnames.join(', ')}`);
109
- return {
110
- privateKey: Buffer.from(privateKeyPem),
111
- certificate: Buffer.from(certificatePem),
112
- };
113
- }
114
- catch (error) {
115
- this.logger.error('Failed to generate self-signed certificate:', error);
116
- throw error;
117
- }
118
- }
119
- };
120
- SslCertGeneratorService = SslCertGeneratorService_1 = __decorate([
121
- Injectable(),
122
- __metadata("design:paramtypes", [])
123
- ], SslCertGeneratorService);
124
- export { SslCertGeneratorService };
125
- //# sourceMappingURL=ssl-cert-generator.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ssl-cert-generator.service.js","sourceRoot":"","sources":["../../../src/core/ssl/ssl-cert-generator.service.ts"],"names":[],"mappings":"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"}
@@ -1,94 +0,0 @@
1
- export interface MatterEvent {
2
- type: 'accessoriesData' | 'accessoryUpdate' | 'accessoryAdded' | 'accessoryRemoved' | 'accessoryControlResponse';
3
- data?: MatterAccessoriesResponse | MatterAccessoryInfo | MatterStateUpdate | MatterControlResponse;
4
- }
5
- export interface MatterAccessoriesResponse {
6
- accessories: MatterAccessory[];
7
- error?: string;
8
- }
9
- export interface MatterAccessory {
10
- uuid: string;
11
- displayName: string;
12
- deviceType: string;
13
- clusters: Record<string, Record<string, unknown>>;
14
- manufacturer?: string;
15
- model?: string;
16
- serialNumber?: string;
17
- firmwareRevision?: string;
18
- bridge?: {
19
- name?: string;
20
- username?: string;
21
- };
22
- plugin?: string;
23
- platform?: string;
24
- commissioned?: boolean;
25
- fabricCount?: number;
26
- fabrics?: unknown[];
27
- parts?: MatterAccessoryPart[];
28
- }
29
- export interface MatterAccessoryPart {
30
- id: string;
31
- displayName: string;
32
- deviceType: string;
33
- clusters: Record<string, Record<string, unknown>>;
34
- }
35
- export interface MatterAccessoryInfo extends MatterAccessory {
36
- error?: string;
37
- }
38
- export interface MatterService {
39
- uniqueId: string;
40
- uuid: string;
41
- serviceName: string;
42
- displayName: string;
43
- deviceType: string;
44
- clusters: Record<string, Record<string, unknown>>;
45
- partId?: string;
46
- protocol: 'matter';
47
- instance: {
48
- name: string;
49
- username: string;
50
- };
51
- accessoryInformation: {
52
- 'Name': string;
53
- 'Manufacturer': string;
54
- 'Model': string;
55
- 'Serial Number': string;
56
- 'Firmware Revision': string;
57
- };
58
- bridge?: {
59
- name?: string;
60
- username?: string;
61
- };
62
- plugin?: string;
63
- platform?: string;
64
- commissioned?: boolean;
65
- fabricCount?: number;
66
- fabrics?: unknown[];
67
- aid: 0;
68
- iid: 0;
69
- }
70
- export interface MatterStateUpdate {
71
- uuid: string;
72
- cluster: string;
73
- state: Record<string, unknown>;
74
- partId?: string;
75
- }
76
- export interface MatterControlResponse {
77
- success: boolean;
78
- error?: string;
79
- }
80
- export interface MatterControlRequest {
81
- uniqueId: string;
82
- cluster: string;
83
- attributes: Record<string, unknown>;
84
- }
85
- export interface AccessoryControlMessage {
86
- set?: {
87
- uniqueId: string;
88
- iid?: number;
89
- value?: string | number | boolean;
90
- cluster?: string;
91
- attributes?: Record<string, unknown>;
92
- };
93
- refresh?: boolean;
94
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=accessories.interfaces.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accessories.interfaces.js","sourceRoot":"","sources":["../../../src/modules/accessories/accessories.interfaces.ts"],"names":[],"mappings":""}
@@ -1,15 +0,0 @@
1
- - diagnose issue with all matter accessories reporting 'Unsupported' after restart
2
- - reduce debug logging especially for case when user has not enabled matter anywhere
3
- - reduce debug logging for ipc connection for accessory control via ui
4
-
5
- - document step in iphone settings to properly 'forget' bridge connections
6
-
7
- - ensure deselecting 'enable matter' in bridge settings properly removes all matter accessories + bridge
8
- - ensure 'remove individual accessories' properly cleans up matter accessory
9
- - ensure 'remove bridge accessories' properly cleans up all matter accessories
10
- - ensure 'reset individual bridges' properly cleans up matter accessories + bridge (or external accessory)
11
- - ensure 'reset all bridges' properly cleans up all matter accessories + bridges (+ external accessories)
12
-
13
- - wire up fan accessory in the ui accessory control page
14
- - wire up thermostat accessory in the ui accessory control page
15
- - enable more 'show as' service types especially for common switch
@@ -1,103 +0,0 @@
1
- # SSL uploads, validation, and self-signed generation
2
-
3
- This PR adds a complete HTTPS management experience to Settings → Security → HTTPS:
4
-
5
- - Upload PEM key + certificate with server-side validation
6
- - Upload PKCS#12 (.pfx/.p12) with optional passphrase and validation
7
- - Validate the currently configured HTTPS mode from the UI (“Validate SSL”)
8
- - Generate a self-signed certificate from the UI with hostnames/SANs
9
- - Generate Self‑Signed & Use as Key + Cert (writes files, selects key/cert mode)
10
- - Generate & Enable Self‑Signed Mode (enables runtime self-signed mode)
11
-
12
- See the updated mockup: `screenshots/ssl-upload-mock.svg`.
13
-
14
- ## Target branch
15
-
16
- Per repo guidelines, this PR targets the current beta branch: `beta-5.8.1`.
17
-
18
- ## Backend (NestJS)
19
-
20
- New/updated endpoints under Server module:
21
-
22
- - POST `/server/ssl/keycert` — multipart upload for `key.pem` + `cert.pem`
23
- - Validates key↔cert pair via Node.js X509/tls before persisting
24
- - Saves to `{storagePath}/ssl-certs/ui-ssl.key` and `ui-ssl.crt`
25
- - Updates `config.json` → `ui.ssl` to key/cert mode; clears pfx/selfSigned
26
- - POST `/server/ssl/pfx` — multipart upload for `ui-ssl.pfx` with optional `passphrase`
27
- - Validates by creating a SecureContext
28
- - Saves to `{storagePath}/ssl-certs/ui-ssl.pfx`
29
- - Updates `config.json` → `ui.ssl` to pfx mode; clears key/cert/selfSigned
30
- - POST `/server/ssl/validate` — validates the current HTTPS configuration
31
- - Handles `off`, `selfsigned`, `keycert`, and `pfx` modes; returns status/details
32
- - POST `/server/ssl/selfsigned/generate` — generates a self-signed cert
33
- - Body: `{ hostnames?: string[], mode?: 'keycert'|'selfsigned' }`
34
- - Uses existing SSL generator service
35
- - If `mode='keycert'`: writes `private-key.pem`/`certificate.pem`, sets key/cert mode
36
- - If `mode='selfsigned'`: enables runtime self-signed mode and records hostnames
37
-
38
- Security: endpoints are admin-only and write under `{storagePath}/ssl-certs`.
39
-
40
- ## Frontend (Angular)
41
-
42
- Settings → Security → HTTPS additions:
43
-
44
- - HTTPS mode selector: Off, Self-Signed, Key+Cert, PFX
45
- - “Validate SSL” button next to the selector
46
- - Self-signed section:
47
- - Hostnames/SANs input (e.g. `localhost, 127.0.0.1, homebridge.local`)
48
- - Two actions:
49
- - “Generate Self‑Signed & Use as Key + Cert”
50
- - “Generate & Enable Self‑Signed Mode”
51
- - Key/Cert upload (with unified “Upload” button) and PFX upload with passphrase field
52
- - Toastr notifications and restart prompt after changes
53
- - i18n keys added in `ui/src/i18n/en.json` for new labels and toasts
54
-
55
- ## Storage layout
56
-
57
- All artifacts are saved under `{storagePath}/ssl-certs`:
58
-
59
- - `ui-ssl.key` / `ui-ssl.crt` (file-based key/cert mode)
60
- - `ui-ssl.pfx` (pfx mode)
61
- - `private-key.pem` / `certificate.pem` (generated self-signed files)
62
-
63
- ## Manual validation
64
-
65
- Follow the project’s validation steps:
66
-
67
- 1. Build and test:
68
- - `npm run build`
69
- - `npm run lint`
70
- - `npm run test`
71
- 2. Start the app (`npm run watch` for UI + backend) and open Settings → Security → HTTPS
72
- 3. Try each flow:
73
- - Upload Key+Cert and validate
74
- - Upload PFX (with/without passphrase) and validate
75
- - Generate self-signed with custom hostnames and select one of the two buttons
76
- - Use “Validate SSL” to verify the mode
77
-
78
- Backend-only check (optional):
79
-
80
- - POST `/server/ssl/validate` should return OK plus details of the active mode
81
-
82
- ## Notes
83
-
84
- - Raspbian image: the self-signed UI option is hidden/disabled since nginx terminates TLS
85
- - Admin-only scope maintained for all write endpoints
86
-
87
- ## Quality gates
88
-
89
- - Build: PASS
90
- - Lint: PASS
91
- - Tests: PASS (310 e2e tests)
92
-
93
- ---
94
-
95
- Compare URL (after pushing this branch):
96
-
97
- https://github.com/homebridge/homebridge-config-ui-x/compare/beta-5.8.1...ssl-upload
98
-
99
- Suggested PR title:
100
-
101
- feat(settings/https): upload + validate SSL (PEM/PFX) and generate self-signed from UI
102
-
103
- Suggested labels: `feature`, `settings`, `security`, `beta`
@@ -1,8 +0,0 @@
1
- <svg height="512px" width="512px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
2
- <g transform="translate(256, 280) scale(1.37) translate(-256, -256)">
3
- <path
4
- fill="currentColor"
5
- d="M256 212.26666666666665c-21.333333333333332 0 -41.421866666666666 -3.8218666666666667 -60.266666666666666 -11.466666666666665 -18.8448 -7.6448 -35.733333333333334 -18.0448 -50.666666666666664 -31.199999999999996l29.333333333333332 -17.599999999999998c8.533333333333333 6.3999999999999995 18.311466666666664 12 29.333333333333332 16.799999999999997 11.021866666666668 4.8 23.111466666666665 8.266666666666666 36.266666666666666 10.399999999999999V62.93333333333334L256 53.33333333333333l16 9.6v116.26666666666667c12.799999999999999 -2.1333333333333333 24.8 -5.6 36 -10.399999999999999 11.2 -4.8 21.066666666666666 -10.399999999999999 29.599999999999998 -16.799999999999997l29.333333333333332 17.599999999999998c-14.933333333333332 13.1552 -31.821866666666665 23.5552 -50.666666666666664 31.199999999999996C297.42186666666663 208.4448 277.3333333333333 212.26666666666665 256 212.26666666666665Zm-35.199999999999996 211.73333333333335 -29.866666666666664 -16c0.3552 -2.8447999999999998 0.6218666666666666 -5.511466666666667 0.7999999999999999 -8 0.1781333333333333 -2.4885333333333333 0.26666666666666666 -5.1552 0.26666666666666666 -8 0 -8.533333333333333 -0.9781333333333333 -17.511466666666664 -2.9333333333333336 -26.93333333333333 -1.9551999999999998 -9.421866666666666 -4.7114666666666665 -18.7552 -8.266666666666666 -28l-100.26666666666667 60.8L64 388.8V370.1333333333333l99.73333333333332 -60.266666666666666c-8.178133333333333 -9.6 -17.1552 -18.0448 -26.93333333333333 -25.333333333333332 -9.778133333333333 -7.2885333333333335 -19.821866666666665 -12.888533333333331 -30.133333333333333 -16.799999999999997v-34.13333333333333c34.13333333333333 10.311466666666666 62.22186666666667 29.955199999999998 84.26666666666667 58.93333333333334 22.0448 28.978133333333332 33.06666666666666 62.13333333333333 33.06666666666666 99.46666666666665 0 5.688533333333333 -0.26666666666666666 11.2 -0.7999999999999999 16.53333333333333 -0.5333333333333333 5.333333333333333 -1.3333333333333333 10.488533333333333 -2.4 15.466666666666665Zm70.39999999999999 0c-1.0666666666666667 -4.978133333333333 -1.8666666666666665 -10.133333333333333 -2.4 -15.466666666666665 -0.5333333333333333 -5.333333333333333 -0.7999999999999999 -10.8448 -0.7999999999999999 -16.53333333333333 0 -37.33333333333333 11.021866666666668 -70.48853333333332 33.06666666666666 -99.46666666666665 22.0448 -28.978133333333332 50.13333333333333 -48.62186666666666 84.26666666666667 -58.93333333333334v34.13333333333333c-10.311466666666666 3.9114666666666666 -20.3552 9.511466666666667 -30.133333333333333 16.799999999999997 -9.778133333333333 7.2885333333333335 -18.7552 15.733333333333334 -26.93333333333333 25.333333333333332L448 370.1333333333333v18.666666666666664l-16.53333333333333 9.066666666666666 -100.26666666666667 -60.8c-3.5551999999999997 9.2448 -6.311466666666666 18.578133333333334 -8.266666666666666 28 -1.9551999999999998 9.421866666666666 -2.9333333333333336 18.4 -2.9333333333333336 26.93333333333333 0 2.8447999999999998 0.08853333333333332 5.511466666666667 0.26666666666666666 8 0.1781333333333333 2.4885333333333333 0.4448 5.1552 0.7999999999999999 8l-29.866666666666664 16Z"
6
- />
7
- </g>
8
- </svg>
@@ -1 +0,0 @@
1
- import{a as Ce}from"./chunk-MDHWQ5V2.js";import{a as we}from"./chunk-WVG4A2SW.js";import{n as R}from"./chunk-PRGOUVRO.js";import{g as ie,m as F,n as xe}from"./chunk-OF2SRCQW.js";import{c as be}from"./chunk-EWS4VSZB.js";import{a as fe}from"./chunk-Z5PUNNUZ.js";import{b as K}from"./chunk-KTQBVBY4.js";import{B as ve,C as G,D as z,b as W,c as N,d as g,e as j,f as X,g as P,j as E,m as Y,q as Z,r as ee,s as te}from"./chunk-TPUA4UIN.js";import{a as Te,b as _e}from"./chunk-OBV66CW4.js";import{E as D,F as U,H as I,K as V}from"./chunk-J7UDRE66.js";import{Ab as h,Cb as oe,Db as se,Dc as o,Eb as le,Ec as s,Fb as y,Fc as ue,Gb as a,Hb as i,Ib as c,Jb as $,Kb as k,Lb as q,Rb as A,Sb as H,Xb as _,Yb as L,Za as e,Zb as f,aa as p,ea as ae,ga as B,ha as M,ic as O,jc as me,kc as m,lc as d,ma as re,mb as Q,mc as v,nb as S,nc as de,sa as T,xc as pe,yb as u,yc as ce,zb as w}from"./chunk-HUTYOGRH.js";import{g as Ue,h as C}from"./chunk-B4AJQJMI.js";function ke(n,x){n&1&&(a(0,"ngb-alert",13)(1,"p",20),m(2),o(3,"translate"),i()()),n&2&&(y("dismissible",!1),e(2),d(s(3,2,"login.invalid_password")))}var he=(()=>{class n{$activeModal=p(F);$api=p(V);$toastr=p(I);$translate=p(D);invalidCredentials=T(!1,{});formGroup=new P({password:new E("",[g.required])});disable2fa(){return C(this,null,function*(){this.invalidCredentials.set(!1);try{yield this.$api.post("/users/otp/deactivate",this.formGroup.value),this.$activeModal.close(),this.$toastr.success(this.$translate.instant("users.setup_2fa_disable_success"),this.$translate.instant("toast.title_success"))}catch{this.formGroup.setValue({password:""}),this.invalidCredentials.set(!0)}})}dismissModal(){this.$activeModal.dismiss("Dismiss")}static \u0275fac=function(l){return new(l||n)};static \u0275cmp=S({type:n,selectors:[["ng-component"]],decls:34,vars:27,consts:[[1,"modal-content",2,"min-height","300px"],[1,"modal-header"],[1,"modal-title"],["type","button","data-bs-dismiss","modal",1,"btn-close",3,"click"],[1,"modal-body"],[1,"text-center","mb-3"],[1,"fas","fa-key","primary-text",2,"font-size","75px"],[1,"mb-3"],[1,"list-group","list-group-box","mb-0"],[1,"list-group-item","d-flex","flex-column","flex-md-row","align-items-center"],[1,"mb-2","mb-md-0","w-100","w-md-50"],[1,"text-start","text-md-end","w-100","w-md-50"],["type","password","autocomplete","current-password",1,"form-control","custom-input",3,"formControl","placeholder"],["type","error",1,"mt-3","mb-0",3,"dismissible"],[1,"modal-footer","justify-content-between"],[1,"text-start"],["type","button","data-bs-dismiss","modal",1,"btn","btn-elegant",3,"click"],[1,"text-center"],[1,"text-end"],["type","button","data-bs-dismiss","modal",1,"btn","btn-danger",3,"click","disabled"],[1,"mb-0"]],template:function(l,r){l&1&&(a(0,"div",0)(1,"div",1)(2,"h5",2),m(3),o(4,"translate"),i(),a(5,"button",3),o(6,"translate"),_("click",function(){return r.dismissModal()}),i()(),a(7,"div",4)(8,"div",5),c(9,"i",6),i(),a(10,"ul",7)(11,"li"),m(12),o(13,"translate"),i()(),a(14,"ul",8)(15,"li",9)(16,"label",10),m(17),o(18,"translate"),i(),a(19,"div",11),c(20,"input",12),o(21,"translate"),i()()(),w(22,ke,4,4,"ngb-alert",13),i(),a(23,"div",14)(24,"div",15)(25,"button",16),o(26,"translate"),_("click",function(){return r.dismissModal()}),m(27),o(28,"translate"),i()(),c(29,"div",17),a(30,"div",18)(31,"button",19),_("click",function(){return r.disable2fa()}),m(32),o(33,"translate"),i()()()()),l&2&&(e(3),d(s(4,11,"users.setup_2fa_disable")),e(2),u("aria-label",s(6,13,"form.button_close")),e(7),d(s(13,15,"users.setup_2fa_disable_current_password")),e(5),d(s(18,17,"users.label_password")),e(3),y("formControl",r.formGroup.controls.password)("placeholder",s(21,19,"users.label_password")),e(2),h(r.invalidCredentials()&&!r.formGroup.controls.password.value?22:-1),e(3),u("aria-label",s(26,21,"form.button_close")),e(2),v(" ",s(28,23,"form.button_close")," "),e(4),y("disabled",r.formGroup.invalid),e(),v(" ",s(33,25,"form.button_disable")," "))},dependencies:[G,N,j,z,Z,ie,U],encapsulation:2})}return n})();var ge=Ue(Te(),1);var Be=n=>({timeDiffError:n});function Me(n,x){n&1&&(a(0,"li"),m(1),o(2,"translate"),i()),n&2&&(e(),d(s(2,1,"users.setup_2fa_scan_qr_code")))}function De(n,x){if(n&1&&(a(0,"ngb-alert",8)(1,"p",16),m(2),o(3,"translate"),i(),a(4,"p",17),m(5),o(6,"translate"),i()()),n&2){let t=f();y("dismissible",!1),e(2),d(s(3,3,"users.setup_2fa_cannot_setup_2fa")),e(3),d(ue(6,5,"users.setup_2fa_server_time_out",pe(8,Be,t.timeDiffError())))}}function Ie(n,x){n&1&&c(0,"i",27)}function Ve(n,x){n&1&&c(0,"i",28)}function Fe(n,x){if(n&1){let t=A();a(0,"div",21),m(1),o(2,"translate"),c(3,"br"),m(4),a(5,"a",26),_("click",function(){B(t);let r=f(2);return M(r.copySecretToClipboard())}),w(6,Ie,1,0,"i",27)(7,Ve,1,0,"i",28),i()()}if(n&2){let t=f(2);e(),v(" ",s(2,3,"users.setup_2fa_scan_qr_manual")),e(3),v(" ",t.otpSecret()," "),e(2),h(t.secretCopied()?6:7)}}function Ae(n,x){if(n&1&&(a(0,"ul",9)(1,"li",18)(2,"div",19),c(3,"app-qrcode",20),i(),w(4,Fe,8,5,"div",21),i(),a(5,"li",22)(6,"label",23),m(7),o(8,"translate"),i(),a(9,"div",24),c(10,"input",25),i()()()),n&2){let t=f();e(3),y("data",t.otpString()),e(),h(t.otpSecret()?4:-1),e(3),d(s(8,4,"users.setup_2fa_enter_code")),e(3),y("formControl",t.formGroup.controls.code)}}function Ne(n,x){if(n&1){let t=A();a(0,"button",29),o(1,"translate"),_("click",function(){B(t);let r=f();return M(r.dismissModal())}),m(2),o(3,"translate"),i()}n&2&&(u("aria-label",s(1,2,"form.button_close")),e(2),v(" ",s(3,4,"form.button_close")," "))}function je(n,x){if(n&1){let t=A();a(0,"button",29),o(1,"translate"),_("click",function(){B(t);let r=f();return M(r.dismissModal())}),m(2),o(3,"translate"),i()}n&2&&(u("aria-label",s(1,2,"form.button_close")),e(2),v(" ",s(3,4,"form.button_close")," "))}function Pe(n,x){if(n&1){let t=A();a(0,"button",30),_("click",function(){B(t);let r=f();return M(r.enable2fa())}),m(1),o(2,"translate"),i()}if(n&2){let t=f();y("disabled",t.formGroup.invalid),e(),v(" ",s(2,2,"form.button_enable")," ")}}var Ee=(()=>{class n{$activeModal=p(F);$api=p(V);$toastr=p(I);$translate=p(D);modalData=p(R);user=this.modalData.user;timeDiffError=T(null,{});otpString=T(void 0,{});otpSecret=T(void 0,{});secretCopied=T(!1,{});copyTimeout=null;formGroup=new P({code:new E("",[g.required,g.minLength(6),g.maxLength(6)])});ngOnInit(){this.initialize()}initialize(){return C(this,null,function*(){try{let t=yield this.$api.post("/users/otp/setup",{});this.checkTimeDiff(t.timestamp),this.timeDiffError()||(this.otpString.set(t.otpauth),this.otpSecret.set(new URL(t.otpauth).searchParams.get("secret")||""))}catch(t){this.$activeModal.dismiss(),console.error(t),this.$toastr.error(this.$translate.instant("users.setup_2fa_enable_error"),this.$translate.instant("toast.title_error"))}})}enable2fa(){return C(this,null,function*(){try{yield this.$api.post("/users/otp/activate",this.formGroup.value),this.$toastr.success(this.$translate.instant("users.setup_2fa_enabled_success"),this.$translate.instant("toast.title_success")),this.$activeModal.close()}catch(t){console.error(t),this.$toastr.error(this.$translate.instant("users.setup_2fa_activate_error"),this.$translate.instant("toast.title_error"))}})}copySecretToClipboard(){return C(this,null,function*(){let t=this.otpSecret();t&&(yield navigator.clipboard.writeText(t),this.secretCopied.set(!0),this.copyTimeout&&clearTimeout(this.copyTimeout),this.copyTimeout=setTimeout(()=>{this.secretCopied.set(!1)},3e3))})}dismissModal(){this.$activeModal.dismiss("Dismiss")}checkTimeDiff(t){let l=(0,ge.default)(t).diff(new Date,"millisecond");l<-5e3||l>5e3?this.timeDiffError.set(l):this.timeDiffError.set(null)}static \u0275fac=function(l){return new(l||n)};static \u0275cmp=S({type:n,selectors:[["ng-component"]],decls:24,vars:15,consts:[[1,"modal-content","setup2fa"],[1,"modal-header"],[1,"modal-title"],["type","button","data-bs-dismiss","modal",1,"btn-close",3,"click"],[1,"modal-body"],[1,"text-center","mb-3"],[1,"fas","fa-key","primary-text",2,"font-size","75px"],[1,"mb-3"],["type","error",1,"mb-0",3,"dismissible"],[1,"list-group","list-group-box","mb-0"],[1,"modal-footer","justify-content-between"],[1,"text-start"],["type","button","data-bs-dismiss","modal",1,"btn","btn-elegant"],[1,"text-center"],[1,"text-end"],["type","button","data-bs-dismiss","modal",1,"btn","btn-primary",3,"disabled"],[1,"fw-bold","mb-1"],[1,"mb-0"],[1,"list-group-item","text-center"],[1,"text-center","w-100","d-flex","justify-content-center","my-2"],[1,"mx-auto",2,"width","175px","height","175px",3,"data"],[1,"grey-text","small","mt-0","mb-1"],[1,"list-group-item","d-flex","flex-column","flex-md-row","align-items-center"],[1,"mb-2","mb-md-0","w-100","w-md-50"],[1,"text-start","text-md-end","w-100","w-md-50"],["type","text","placeholder","eg. 123456","autocomplete","one-time-code","autocapitalize","none","inputmode","numeric","pattern","[0-9]*",1,"form-control","custom-input",3,"formControl"],["href","javascript:void(0)",1,"ms-1","text-primary",3,"click"],[1,"fas","fa-check","green-text"],[1,"fas","fa-copy"],["type","button","data-bs-dismiss","modal",1,"btn","btn-elegant",3,"click"],["type","button","data-bs-dismiss","modal",1,"btn","btn-primary",3,"click","disabled"]],template:function(l,r){l&1&&(a(0,"div",0)(1,"div",1)(2,"h5",2),m(3),o(4,"translate"),i(),a(5,"button",3),o(6,"translate"),_("click",function(){return r.dismissModal()}),i()(),a(7,"div",4)(8,"div",5),c(9,"i",6),i(),a(10,"ul",7)(11,"li"),m(12),o(13,"translate"),i(),w(14,Me,3,3,"li"),i(),w(15,De,7,10,"ngb-alert",8),w(16,Ae,11,6,"ul",9),i(),a(17,"div",10)(18,"div",11),w(19,Ne,4,6,"button",12),i(),a(20,"div",13),w(21,je,4,6,"button",12),i(),a(22,"div",14),w(23,Pe,3,4,"button",15),i()()()),l&2&&(e(3),d(s(4,9,"users.setup_2fa")),e(2),u("aria-label",s(6,11,"form.button_close")),e(7),d(s(13,13,"users.setup_2fa_warning")),e(2),h(r.timeDiffError()?-1:14),e(),h(r.timeDiffError()?15:-1),e(),h(r.timeDiffError()?-1:16),e(3),h(r.timeDiffError()?-1:19),e(2),h(r.timeDiffError()?21:-1),e(2),h(r.timeDiffError()?-1:23))},dependencies:[ie,Ce,G,N,j,ve,z,Z,U],encapsulation:2})}return n})();var ye=(()=>{class n{$activeModal=p(F);$api=p(V);$toastr=p(I);$translate=p(D);form=new P({username:new E("",[g.required]),name:new E("",[g.required]),password:new E("",[g.compose([g.required,g.minLength(4)])]),passwordConfirm:new E("",[g.required]),admin:new E(!0)},this.matchPassword);onSubmit(l){return C(this,arguments,function*({value:t}){try{yield this.$api.post("/users",t),this.$activeModal.close(),this.$toastr.success(this.$translate.instant("users.toast_added_new_user"),this.$translate.instant("toast.title_success"))}catch(r){this.$toastr.error(r.error.message||this.$translate.instant("users.toast_failed_to_add_user"),this.$translate.instant("toast.title_error"))}})}dismissModal(){this.$activeModal.dismiss("Dismiss")}matchPassword(t){let l=t.get("password")?.value,r=t.get("passwordConfirm")?.value;return l!==r?(t.get("passwordConfirm")?.setErrors({matchPassword:!0}),{matchPassword:!0}):null}static \u0275fac=function(l){return new(l||n)};static \u0275cmp=S({type:n,selectors:[["ng-component"]],decls:58,vars:48,consts:[[1,"modal-content"],["novalidate","",3,"ngSubmit","formGroup"],[1,"modal-header"],[1,"modal-title"],["type","button","data-bs-dismiss","modal",1,"btn-close",3,"click"],[1,"modal-body"],[1,"text-center","mb-3"],[1,"fas","fa-user-plus","primary-text",2,"font-size","75px"],[1,"list-group","list-group-box","mb-0"],[1,"list-group-item","d-flex","flex-column","flex-md-row","align-items-center"],["for","form-username",1,"mb-2","mb-md-0","w-100","w-md-50"],[1,"text-start","text-md-end","w-100","w-md-50"],["formControlName","username","type","text","id","form-username","autocomplete","username","autocapitalize","none",1,"form-control","custom-input"],["for","form-name",1,"mb-2","mb-md-0","w-100","w-md-50"],["formControlName","name","type","text","id","form-name","autocomplete","name",1,"form-control","custom-input"],["for","form-pass",1,"mb-2","mb-md-0","w-100","w-md-50"],["formControlName","password","type","password","autocomplete","new-password","id","form-pass",1,"form-control","custom-input"],["for","form-pass-confirm",1,"mb-2","mb-md-0","w-100","w-md-50"],["formControlName","passwordConfirm","type","password","autocomplete","new-password","id","form-pass-confirm",1,"form-control","custom-input"],[1,"list-group-item","d-flex","justify-content-between","align-items-center","flex-row","pb-2"],[1,"text-start"],[1,"text-end","grey-text","d-flex","align-items-center"],["formControlName","admin","type","checkbox","id","isAdmin",1,"rendux-input"],["for","isAdmin",1,"rendux-label","ms-3"],[1,"modal-footer","justify-content-between"],["type","button","data-bs-dismiss","modal",1,"btn","btn-elegant",3,"click"],[1,"text-center"],[1,"text-end"],["type","submit",1,"btn","btn-primary",3,"disabled"]],template:function(l,r){l&1&&(a(0,"div",0)(1,"form",1),_("ngSubmit",function(){return r.onSubmit(r.form)}),a(2,"div",2)(3,"h5",3),m(4),o(5,"translate"),i(),a(6,"button",4),o(7,"translate"),_("click",function(){return r.dismissModal()}),i()(),a(8,"div",5)(9,"div",6),c(10,"i",7),i(),a(11,"ul",8)(12,"li",9)(13,"label",10),m(14),o(15,"translate"),i(),a(16,"div",11),c(17,"input",12),o(18,"translate"),i()(),a(19,"li",9)(20,"label",13),m(21),o(22,"translate"),i(),a(23,"div",11),c(24,"input",14),o(25,"translate"),i()(),a(26,"li",9)(27,"label",15),m(28),o(29,"translate"),i(),a(30,"div",11),c(31,"input",16),o(32,"translate"),i()(),a(33,"li",9)(34,"label",17),m(35),o(36,"translate"),i(),a(37,"div",11),c(38,"input",18),o(39,"translate"),i()(),a(40,"li",19)(41,"span",20),m(42),o(43,"translate"),i(),a(44,"div",21),c(45,"input",22),o(46,"translate"),c(47,"label",23),i()()()(),a(48,"div",24)(49,"div",20)(50,"button",25),_("click",function(){return r.dismissModal()}),m(51),o(52,"translate"),i()(),c(53,"div",26),a(54,"div",27)(55,"button",28),m(56),o(57,"translate"),i()()()()()),l&2&&(e(),y("formGroup",r.form),e(3),d(s(5,20,"users.title_add_user")),e(2),u("aria-label",s(7,22,"form.button_close")),e(8),d(s(15,24,"users.label_username")),e(3),u("aria-label",s(18,26,"users.label_username")),e(4),d(s(22,28,"users.label_full_name")),e(3),u("aria-label",s(25,30,"users.label_full_name")),e(4),d(s(29,32,"users.label_password")),e(3),O("is-invalid",r.form.controls.password.dirty&&r.form.controls.password.errors),u("aria-label",s(32,34,"users.label_password")),e(4),d(s(36,36,"users.label_confirm_password")),e(3),O("is-invalid",r.form.controls.passwordConfirm.dirty&&r.form.controls.passwordConfirm.errors),u("aria-label",s(39,38,"users.label_confirm_password")),e(4),d(s(43,40,"users.label_admin_user")),e(3),u("aria-label",s(46,42,"users.label_admin_user")),e(6),v(" ",s(52,44,"form.button_close")," "),e(4),y("disabled",!r.form.valid),e(),v(" ",s(57,46,"form.button_save")," "))},dependencies:[G,Y,N,W,j,X,z,te,ee,U],encapsulation:2})}return n})();function Ge(n,x){if(n&1&&(a(0,"li",9)(1,"label",27),m(2),o(3,"translate"),i(),a(4,"div",11),c(5,"input",28),o(6,"translate"),i()()),n&2){let t=f();e(2),d(s(3,4,"users.label_confirm_password")),e(3),O("is-invalid",t.form.controls.passwordConfirm.dirty&&t.form.controls.passwordConfirm.errors),u("aria-label",s(6,6,"users.label_confirm_password"))}}var Se=(()=>{class n{$activeModal=p(F);$api=p(V);$auth=p(K);$toastr=p(I);$translate=p(D);modalData=p(R);user=this.modalData.user;isCurrentUser=T(!1,{});initialFormValue={};form=new P({username:new E("",[g.required]),name:new E("",[g.required]),password:new E(""),passwordConfirm:new E(""),admin:new E(!0)},this.matchPassword);ngOnInit(){this.user&&(this.isCurrentUser.set(this.$auth.user.username===this.user.username),this.form.patchValue(this.user),this.initialFormValue=this.form.getRawValue())}onSubmit(l){return C(this,arguments,function*({value:t}){if(this.user)try{yield this.$api.patch(`/users/${this.user.id}`,t),this.$activeModal.close(),this.$toastr.success(this.$translate.instant("users.toast_updated_user"),this.$translate.instant("toast.title_success")),this.isCurrentUser()&&t.username!==this.$auth.user.username&&this.$auth.logout()}catch(r){console.error(r),this.$toastr.error(r.error?.message||this.$translate.instant("users.toast_failed_to_add_user"),this.$translate.instant("toast.title_error"))}})}isFormUnchanged(){return this.form.controls.password.value?!1:JSON.stringify(this.form.getRawValue())===JSON.stringify(this.initialFormValue)}dismissModal(){this.$activeModal.dismiss("Dismiss")}matchPassword(t){let l=t.get("password")?.value,r=t.get("passwordConfirm")?.value;return l!==r?(t.get("passwordConfirm")?.setErrors({matchPassword:!0}),{matchPassword:!0}):null}static \u0275fac=function(l){return new(l||n)};static \u0275cmp=S({type:n,selectors:[["ng-component"]],decls:52,vars:41,consts:[[1,"modal-content"],["novalidate","",3,"ngSubmit","formGroup"],[1,"modal-header"],[1,"modal-title"],["type","button","data-bs-dismiss","modal",1,"btn-close",3,"click"],[1,"modal-body"],[1,"text-center","mb-3"],[1,"fas","fa-user-pen","primary-text",2,"font-size","75px"],[1,"list-group","list-group-box","mb-0"],[1,"list-group-item","d-flex","flex-column","flex-md-row","align-items-center"],["for","form-username",1,"mb-2","mb-md-0","w-100","w-md-50"],[1,"text-start","text-md-end","w-100","w-md-50"],["formControlName","username","type","text","id","form-username","autocomplete","off","autocapitalize","none",1,"form-control","custom-input"],["for","form-name",1,"mb-2","mb-md-0","w-100","w-md-50"],["formControlName","name","type","text","id","form-name","autocomplete","name",1,"form-control","custom-input"],["for","form-pass",1,"mb-2","mb-md-0","w-100","w-md-50"],["formControlName","password","type","password","autocomplete","new-password","id","form-pass",1,"form-control","custom-input"],[1,"list-group-item","d-flex","justify-content-between","align-items-center","flex-row","pb-2"],[1,"text-start"],[1,"text-end","grey-text","d-flex","align-items-center"],["type","checkbox","formControlName","admin","id","isAdmin",1,"rendux-input"],["for","isAdmin",1,"rendux-label","ms-3"],[1,"modal-footer","justify-content-between"],["type","button","data-bs-dismiss","modal",1,"btn","btn-elegant",3,"click"],[1,"text-center"],[1,"text-end"],["type","submit",1,"btn","btn-primary",3,"disabled"],["for","form-pass-confirm",1,"mb-2","mb-md-0","w-100","w-md-50"],["formControlName","passwordConfirm","type","password","autocomplete","new-password","id","form-pass-confirm",1,"form-control","custom-input"]],template:function(l,r){l&1&&(a(0,"div",0)(1,"form",1),_("ngSubmit",function(){return r.onSubmit(r.form)}),a(2,"div",2)(3,"h5",3),m(4),o(5,"translate"),i(),a(6,"button",4),o(7,"translate"),_("click",function(){return r.dismissModal()}),i()(),a(8,"div",5)(9,"div",6),c(10,"i",7),i(),a(11,"ul",8)(12,"li",9)(13,"label",10),m(14),o(15,"translate"),i(),a(16,"div",11),c(17,"input",12),o(18,"translate"),i()(),a(19,"li",9)(20,"label",13),m(21),o(22,"translate"),i(),a(23,"div",11),c(24,"input",14),o(25,"translate"),i()(),a(26,"li",9)(27,"label",15),m(28),o(29,"translate"),i(),a(30,"div",11),c(31,"input",16),o(32,"translate"),i()(),w(33,Ge,7,8,"li",9),a(34,"li",17)(35,"span",18),m(36),o(37,"translate"),i(),a(38,"div",19),c(39,"input",20),o(40,"translate"),c(41,"label",21),i()()()(),a(42,"div",22)(43,"div",18)(44,"button",23),_("click",function(){return r.dismissModal()}),m(45),o(46,"translate"),i()(),c(47,"div",24),a(48,"div",25)(49,"button",26),m(50),o(51,"translate"),i()()()()()),l&2&&(e(),y("formGroup",r.form),e(3),d(s(5,17,"users.title_edit_user")),e(2),u("aria-label",s(7,19,"form.button_close")),e(8),d(s(15,21,"users.label_username")),e(3),u("aria-label",s(18,23,"users.label_username")),e(4),d(s(22,25,"users.label_full_name")),e(3),u("aria-label",s(25,27,"users.label_full_name")),e(4),d(s(29,29,"users.label_new_password")),e(3),O("is-invalid",r.form.controls.password.dirty&&r.form.controls.password.errors),u("aria-label",s(32,31,"users.label_new_password")),e(2),h(r.form.controls.password.value?33:-1),e(3),d(s(37,33,"users.label_admin_user")),e(3),u("aria-label",s(40,35,"users.label_admin_user")),e(6),v(" ",s(46,37,"form.button_close")," "),e(4),y("disabled",!r.form.valid||r.isFormUnchanged()),e(),v(" ",s(51,39,"form.button_save")," "))},dependencies:[G,Y,N,W,j,X,z,te,ee,U],encapsulation:2})}return n})();var $e=(()=>{class n{$activeModal=p(F);dismissModal(){this.$activeModal.dismiss("Dismiss")}static \u0275fac=function(l){return new(l||n)};static \u0275cmp=S({type:n,selectors:[["ng-component"]],decls:46,vars:36,consts:[[1,"modal-content"],[1,"modal-header"],[1,"modal-title"],["type","button","data-bs-dismiss","modal",1,"btn-close",3,"click"],[1,"modal-body"],[1,"text-center","mb-3"],[1,"fa","fa-question-circle-o","primary-text",2,"font-size","75px"],[1,"ms-2"],[1,"mb-0"],[1,"mb-2","grey-text"],[1,"modal-footer","justify-content-between"],[1,"text-start"],[1,"text-center"],["type","button","data-bs-dismiss","modal",1,"btn","btn-elegant",3,"click"],[1,"text-end"]],template:function(l,r){l&1&&(a(0,"div",0)(1,"form")(2,"div",1)(3,"h5",2),m(4),o(5,"translate"),i(),a(6,"button",3),o(7,"translate"),_("click",function(){return r.dismissModal()}),i()(),a(8,"div",4)(9,"div",5),c(10,"i",6),i(),a(11,"h5",7),m(12),o(13,"translate"),i(),a(14,"ul",8)(15,"li"),m(16),o(17,"translate"),i(),a(18,"ul",9)(19,"li"),m(20),o(21,"translate"),i(),a(22,"li"),m(23),o(24,"translate"),i(),a(25,"li"),m(26),o(27,"translate"),o(28,"translate"),i(),a(29,"li"),m(30),o(31,"translate"),i(),a(32,"li"),m(33),o(34,"translate"),i()(),a(35,"li"),m(36),o(37,"translate"),i()(),c(38,"app-support-banner"),i(),a(39,"div",10),c(40,"div",11),a(41,"div",12)(42,"button",13),_("click",function(){return r.dismissModal()}),m(43),o(44,"translate"),i()(),c(45,"div",14),i()()()),l&2&&(e(4),d(s(5,12,"support.title")),e(2),u("aria-label",s(7,14,"form.button_close")),e(6),d(s(13,16,"users.title_users")),e(4),d(s(17,18,"users.support.acc_1")),e(4),d(s(21,20,"menu.label_status")),e(3),d(s(24,22,"menu.label_plugins")),e(3),de("",s(27,24,"menu.label_accessories")," (",s(28,26,"users.support.control"),")"),e(4),d(s(31,28,"menu.linux.label_logs")),e(3),d(s(34,30,"support.title")),e(3),d(s(37,32,"users.support.acc_2")),e(7),v(" ",s(44,34,"form.button_close")," "))},dependencies:[we,U],encapsulation:2})}return n})();var ze=(n,x)=>({"fa-user-secret":n,"fa-user":x});function Re(n,x){if(n&1){let t=A();$(0,"button",23),L("click",function(){B(t);let r=f(2).$implicit,b=f();return M(b.disable2fa(r))}),m(1),o(2,"translate"),k()}if(n&2){let t=f(2).$implicit,l=f();H("disabled",t.username!==l.username),e(),v(" ",s(2,2,"users.setup_2fa_disable")," ")}}function qe(n,x){if(n&1){let t=A();$(0,"button",24),L("click",function(){B(t);let r=f(2).$implicit,b=f();return M(b.setup2fa(r))}),m(1),o(2,"translate"),k()}if(n&2){let t=f(2).$implicit,l=f();H("disabled",t.username!==l.username),e(),v(" ",s(2,2,"users.setup_2fa")," ")}}function Le(n,x){if(n&1&&w(0,Re,3,4,"button",21)(1,qe,3,4,"button",22),n&2){let t=f().$implicit;h(t.otpActive?0:1)}}function Oe(n,x){n&1&&q(0,"div")}function Je(n,x){if(n&1){let t=A();$(0,"div",9)(1,"div",10)(2,"div",11)(3,"div",12)(4,"span",13)(5,"h4"),m(6),k(),$(7,"h5",14),q(8,"i",15),m(9),k()()(),$(10,"div",16),w(11,Le,2,1)(12,Oe,1,0,"div"),$(13,"div")(14,"button",17),o(15,"translate"),L("click",function(){let r=B(t).$implicit,b=f();return M(b.openEditUser(r))}),q(16,"i",18),k(),$(17,"button",19),o(18,"translate"),L("click",function(){let r=B(t).$implicit,b=f();return M(b.deleteUser(r.id))}),q(19,"i",20),k()()()()()()}if(n&2){let t=x.$implicit,l=f();e(6),d(t.name),e(2),me(ce(12,ze,t.admin,!t.admin)),e(),v(" ",t.username," "),e(2),h(t.admin?11:12),e(3),u("aria-label",s(15,8,"form.button_edit")),e(3),H("disabled",l.username===t.username),u("aria-label",s(18,10,"form.button_delete"))}}var ti=(()=>{class n{injector=p(ae);destroyRef=p(re);$api=p(V);$auth=p(K);$modal=p(xe);$route=p(be);$settings=p(_e);$toastr=p(I);$translate=p(D);homebridgeUsers=T([],{});username=this.$auth.user.username;isAdmin=this.$auth.user.admin;ngOnInit(){let t=this.$translate.instant("users.title_users");this.$settings.setPageTitle(t),this.$route.data.pipe(fe(this.destroyRef)).subscribe(l=>{this.homebridgeUsers.set(l.homebridgeUsers)})}reloadUsers(){return C(this,null,function*(){let t=yield this.$api.get("/users");this.homebridgeUsers.set(t)})}openAddNewUser(){return C(this,null,function*(){let t=this.$modal.open(ye,{size:"lg",backdrop:"static"});try{yield t.result,this.reloadUsers()}catch{}})}openEditUser(t){return C(this,null,function*(){let l=Q([{provide:R,useValue:{user:t}}],this.injector),r=this.$modal.open(Se,{size:"lg",backdrop:"static",injector:l});try{yield r.result,this.reloadUsers()}catch{}})}deleteUser(t){return C(this,null,function*(){try{yield this.$api.delete(`/users/${t}`),this.$toastr.success(this.$translate.instant("users.toast_user_deleted"),this.$translate.instant("toast.title_success")),this.reloadUsers()}catch(l){console.error(l),this.$toastr.error(l.error?.message||this.$translate.instant("users.toast_failed_to_delete_user"),this.$translate.instant("toast.title_error"))}})}setup2fa(t){return C(this,null,function*(){let l=Q([{provide:R,useValue:{user:t}}],this.injector),r=this.$modal.open(Ee,{size:"lg",backdrop:"static",injector:l});try{yield r.result,this.reloadUsers()}catch{}})}disable2fa(t){return C(this,null,function*(){let l=Q([{provide:R,useValue:{user:t}}],this.injector),r=this.$modal.open(he,{size:"lg",backdrop:"static",injector:l});try{yield r.result,this.reloadUsers()}catch{}})}openSupport(){this.$modal.open($e,{size:"lg",backdrop:"static"})}static \u0275fac=function(l){return new(l||n)};static \u0275cmp=S({type:n,selectors:[["app-users"]],decls:15,vars:9,consts:[[1,"row","mb-3"],[1,"col-6"],[1,"primary-text","m-0"],[1,"col-6","text-end"],[1,"btn","btn-elegant","waves-effect","m-0","me-2",3,"click"],[1,"fas","fa-user-plus"],["type","button",1,"btn","btn-elegant","my-0","me-0",3,"click"],[1,"fa","fa-question-circle-o"],[1,"row"],[1,"col-md-6","mb-4"],[1,"card","card-body"],[1,"d-flex","flex-column"],[1,"d-flex","flex-row","mb-3"],[1,"me-auto","my-0"],[1,"small","text-truncate","grey-text"],[1,"fas"],[1,"d-flex","flex-row","justify-content-between"],[1,"btn","btn-elegant","m-0",3,"click"],[1,"fas","fa-user-pen"],[1,"btn","btn-danger","m-0","ms-2",3,"click","disabled"],[1,"fas","fa-trash"],[1,"btn","btn-elegant","m-0",3,"disabled"],[1,"btn","btn-primary","m-0",3,"disabled"],[1,"btn","btn-elegant","m-0",3,"click","disabled"],[1,"btn","btn-primary","m-0",3,"click","disabled"]],template:function(l,r){l&1&&($(0,"div",0)(1,"div",1)(2,"h3",2),m(3),o(4,"translate"),k()(),$(5,"div",3)(6,"button",4),o(7,"translate"),L("click",function(){return r.openAddNewUser()}),q(8,"i",5),k(),$(9,"button",6),o(10,"translate"),L("click",function(){return r.openSupport()}),q(11,"i",7),k()()(),$(12,"div",8),se(13,Je,20,15,"div",9,oe),k()),l&2&&(e(3),d(s(4,3,"users.title_users")),e(3),u("aria-label",s(7,5,"users.button_add_user")),e(3),u("aria-label",s(10,7,"support.title")),e(4),le(r.homebridgeUsers()))},dependencies:[U],encapsulation:2})}return n})();export{ti as UsersComponent};