@serve.zone/dcrouter 13.16.1 → 13.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/dist_serve/bundle.js +729 -721
  2. package/package.json +2 -2
  3. package/ts/00_commitinfo_data.ts +1 -1
  4. package/ts/monitoring/classes.metricsmanager.ts +43 -34
  5. package/ts_web/00_commitinfo_data.ts +1 -1
  6. package/ts_web/elements/network/ops-view-network-activity.ts +2 -1
  7. package/ts_web/elements/network/ops-view-routes.ts +24 -8
  8. package/dist_ts/00_commitinfo_data.d.ts +0 -8
  9. package/dist_ts/00_commitinfo_data.js +0 -9
  10. package/dist_ts/acme/index.d.ts +0 -1
  11. package/dist_ts/acme/index.js +0 -2
  12. package/dist_ts/acme/manager.acme-config.d.ts +0 -48
  13. package/dist_ts/acme/manager.acme-config.js +0 -156
  14. package/dist_ts/classes.cert-provision-scheduler.d.ts +0 -52
  15. package/dist_ts/classes.cert-provision-scheduler.js +0 -138
  16. package/dist_ts/classes.dcrouter.d.ts +0 -401
  17. package/dist_ts/classes.dcrouter.js +0 -1852
  18. package/dist_ts/classes.storage-cert-manager.d.ts +0 -15
  19. package/dist_ts/classes.storage-cert-manager.js +0 -53
  20. package/dist_ts/config/classes.api-token-manager.d.ts +0 -44
  21. package/dist_ts/config/classes.api-token-manager.js +0 -180
  22. package/dist_ts/config/classes.db-seeder.d.ts +0 -25
  23. package/dist_ts/config/classes.db-seeder.js +0 -69
  24. package/dist_ts/config/classes.reference-resolver.d.ts +0 -80
  25. package/dist_ts/config/classes.reference-resolver.js +0 -483
  26. package/dist_ts/config/classes.route-config-manager.d.ts +0 -54
  27. package/dist_ts/config/classes.route-config-manager.js +0 -370
  28. package/dist_ts/config/classes.target-profile-manager.d.ts +0 -82
  29. package/dist_ts/config/classes.target-profile-manager.js +0 -349
  30. package/dist_ts/config/index.d.ts +0 -6
  31. package/dist_ts/config/index.js +0 -8
  32. package/dist_ts/config/validator.d.ts +0 -104
  33. package/dist_ts/config/validator.js +0 -152
  34. package/dist_ts/db/classes.cache.cleaner.d.ts +0 -47
  35. package/dist_ts/db/classes.cache.cleaner.js +0 -130
  36. package/dist_ts/db/classes.cached.document.d.ts +0 -76
  37. package/dist_ts/db/classes.cached.document.js +0 -100
  38. package/dist_ts/db/classes.dcrouter-db.d.ts +0 -70
  39. package/dist_ts/db/classes.dcrouter-db.js +0 -146
  40. package/dist_ts/db/documents/classes.accounting-session.doc.d.ts +0 -32
  41. package/dist_ts/db/documents/classes.accounting-session.doc.js +0 -214
  42. package/dist_ts/db/documents/classes.acme-cert.doc.d.ts +0 -13
  43. package/dist_ts/db/documents/classes.acme-cert.doc.js +0 -109
  44. package/dist_ts/db/documents/classes.acme-config.doc.d.ts +0 -22
  45. package/dist_ts/db/documents/classes.acme-config.doc.js +0 -121
  46. package/dist_ts/db/documents/classes.api-token.doc.d.ts +0 -18
  47. package/dist_ts/db/documents/classes.api-token.doc.js +0 -127
  48. package/dist_ts/db/documents/classes.cached.email.d.ts +0 -125
  49. package/dist_ts/db/documents/classes.cached.email.js +0 -337
  50. package/dist_ts/db/documents/classes.cached.ip.reputation.d.ts +0 -119
  51. package/dist_ts/db/documents/classes.cached.ip.reputation.js +0 -323
  52. package/dist_ts/db/documents/classes.cert-backoff.doc.d.ts +0 -11
  53. package/dist_ts/db/documents/classes.cert-backoff.doc.js +0 -97
  54. package/dist_ts/db/documents/classes.dns-provider.doc.d.ts +0 -22
  55. package/dist_ts/db/documents/classes.dns-provider.doc.js +0 -134
  56. package/dist_ts/db/documents/classes.dns-record.doc.d.ts +0 -21
  57. package/dist_ts/db/documents/classes.dns-record.doc.js +0 -143
  58. package/dist_ts/db/documents/classes.domain.doc.d.ts +0 -22
  59. package/dist_ts/db/documents/classes.domain.doc.js +0 -146
  60. package/dist_ts/db/documents/classes.email-domain.doc.d.ts +0 -17
  61. package/dist_ts/db/documents/classes.email-domain.doc.js +0 -124
  62. package/dist_ts/db/documents/classes.network-target.doc.d.ts +0 -15
  63. package/dist_ts/db/documents/classes.network-target.doc.js +0 -118
  64. package/dist_ts/db/documents/classes.proxy-cert.doc.d.ts +0 -12
  65. package/dist_ts/db/documents/classes.proxy-cert.doc.js +0 -103
  66. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.d.ts +0 -17
  67. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.js +0 -130
  68. package/dist_ts/db/documents/classes.route.doc.d.ts +0 -18
  69. package/dist_ts/db/documents/classes.route.doc.js +0 -121
  70. package/dist_ts/db/documents/classes.source-profile.doc.d.ts +0 -15
  71. package/dist_ts/db/documents/classes.source-profile.doc.js +0 -115
  72. package/dist_ts/db/documents/classes.target-profile.doc.d.ts +0 -16
  73. package/dist_ts/db/documents/classes.target-profile.doc.js +0 -121
  74. package/dist_ts/db/documents/classes.vlan-mappings.doc.d.ts +0 -15
  75. package/dist_ts/db/documents/classes.vlan-mappings.doc.js +0 -77
  76. package/dist_ts/db/documents/classes.vpn-client.doc.d.ts +0 -23
  77. package/dist_ts/db/documents/classes.vpn-client.doc.js +0 -172
  78. package/dist_ts/db/documents/classes.vpn-server-keys.doc.d.ts +0 -10
  79. package/dist_ts/db/documents/classes.vpn-server-keys.doc.js +0 -94
  80. package/dist_ts/db/documents/index.d.ts +0 -20
  81. package/dist_ts/db/documents/index.js +0 -30
  82. package/dist_ts/db/index.d.ts +0 -4
  83. package/dist_ts/db/index.js +0 -9
  84. package/dist_ts/dns/index.d.ts +0 -2
  85. package/dist_ts/dns/index.js +0 -3
  86. package/dist_ts/dns/manager.dns.d.ts +0 -267
  87. package/dist_ts/dns/manager.dns.js +0 -906
  88. package/dist_ts/dns/providers/cloudflare.provider.d.ts +0 -21
  89. package/dist_ts/dns/providers/cloudflare.provider.js +0 -106
  90. package/dist_ts/dns/providers/factory.d.ts +0 -23
  91. package/dist_ts/dns/providers/factory.js +0 -47
  92. package/dist_ts/dns/providers/index.d.ts +0 -3
  93. package/dist_ts/dns/providers/index.js +0 -4
  94. package/dist_ts/dns/providers/interfaces.d.ts +0 -54
  95. package/dist_ts/dns/providers/interfaces.js +0 -2
  96. package/dist_ts/email/classes.email-domain.manager.d.ts +0 -46
  97. package/dist_ts/email/classes.email-domain.manager.js +0 -276
  98. package/dist_ts/email/index.d.ts +0 -1
  99. package/dist_ts/email/index.js +0 -2
  100. package/dist_ts/errors/base.errors.d.ts +0 -224
  101. package/dist_ts/errors/base.errors.js +0 -320
  102. package/dist_ts/errors/error-handler.d.ts +0 -98
  103. package/dist_ts/errors/error-handler.js +0 -282
  104. package/dist_ts/errors/error.codes.d.ts +0 -115
  105. package/dist_ts/errors/error.codes.js +0 -136
  106. package/dist_ts/errors/index.d.ts +0 -54
  107. package/dist_ts/errors/index.js +0 -136
  108. package/dist_ts/errors/reputation.errors.d.ts +0 -183
  109. package/dist_ts/errors/reputation.errors.js +0 -292
  110. package/dist_ts/http3/http3-route-augmentation.d.ts +0 -50
  111. package/dist_ts/http3/http3-route-augmentation.js +0 -98
  112. package/dist_ts/http3/index.d.ts +0 -1
  113. package/dist_ts/http3/index.js +0 -2
  114. package/dist_ts/index.d.ts +0 -8
  115. package/dist_ts/index.js +0 -29
  116. package/dist_ts/logger.d.ts +0 -21
  117. package/dist_ts/logger.js +0 -81
  118. package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
  119. package/dist_ts/monitoring/classes.metricscache.js +0 -63
  120. package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -233
  121. package/dist_ts/monitoring/classes.metricsmanager.js +0 -897
  122. package/dist_ts/monitoring/index.d.ts +0 -1
  123. package/dist_ts/monitoring/index.js +0 -2
  124. package/dist_ts/opsserver/classes.opsserver.d.ts +0 -47
  125. package/dist_ts/opsserver/classes.opsserver.js +0 -105
  126. package/dist_ts/opsserver/handlers/acme-config.handler.d.ts +0 -16
  127. package/dist_ts/opsserver/handlers/acme-config.handler.js +0 -77
  128. package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -40
  129. package/dist_ts/opsserver/handlers/admin.handler.js +0 -191
  130. package/dist_ts/opsserver/handlers/api-token.handler.d.ts +0 -6
  131. package/dist_ts/opsserver/handlers/api-token.handler.js +0 -62
  132. package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -77
  133. package/dist_ts/opsserver/handlers/certificate.handler.js +0 -574
  134. package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -7
  135. package/dist_ts/opsserver/handlers/config.handler.js +0 -200
  136. package/dist_ts/opsserver/handlers/dns-provider.handler.d.ts +0 -16
  137. package/dist_ts/opsserver/handlers/dns-provider.handler.js +0 -156
  138. package/dist_ts/opsserver/handlers/dns-record.handler.d.ts +0 -13
  139. package/dist_ts/opsserver/handlers/dns-record.handler.js +0 -98
  140. package/dist_ts/opsserver/handlers/domain.handler.d.ts +0 -13
  141. package/dist_ts/opsserver/handlers/domain.handler.js +0 -137
  142. package/dist_ts/opsserver/handlers/email-domain.handler.d.ts +0 -16
  143. package/dist_ts/opsserver/handlers/email-domain.handler.js +0 -150
  144. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +0 -30
  145. package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -227
  146. package/dist_ts/opsserver/handlers/index.d.ts +0 -21
  147. package/dist_ts/opsserver/handlers/index.js +0 -22
  148. package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -25
  149. package/dist_ts/opsserver/handlers/logs.handler.js +0 -264
  150. package/dist_ts/opsserver/handlers/network-target.handler.d.ts +0 -10
  151. package/dist_ts/opsserver/handlers/network-target.handler.js +0 -117
  152. package/dist_ts/opsserver/handlers/radius.handler.d.ts +0 -6
  153. package/dist_ts/opsserver/handlers/radius.handler.js +0 -295
  154. package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -6
  155. package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -156
  156. package/dist_ts/opsserver/handlers/route-management.handler.d.ts +0 -14
  157. package/dist_ts/opsserver/handlers/route-management.handler.js +0 -98
  158. package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -9
  159. package/dist_ts/opsserver/handlers/security.handler.js +0 -237
  160. package/dist_ts/opsserver/handlers/source-profile.handler.d.ts +0 -10
  161. package/dist_ts/opsserver/handlers/source-profile.handler.js +0 -119
  162. package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -11
  163. package/dist_ts/opsserver/handlers/stats.handler.js +0 -461
  164. package/dist_ts/opsserver/handlers/target-profile.handler.d.ts +0 -10
  165. package/dist_ts/opsserver/handlers/target-profile.handler.js +0 -117
  166. package/dist_ts/opsserver/handlers/users.handler.d.ts +0 -12
  167. package/dist_ts/opsserver/handlers/users.handler.js +0 -24
  168. package/dist_ts/opsserver/handlers/vpn.handler.d.ts +0 -6
  169. package/dist_ts/opsserver/handlers/vpn.handler.js +0 -262
  170. package/dist_ts/opsserver/helpers/guards.d.ts +0 -27
  171. package/dist_ts/opsserver/helpers/guards.js +0 -43
  172. package/dist_ts/opsserver/index.d.ts +0 -1
  173. package/dist_ts/opsserver/index.js +0 -2
  174. package/dist_ts/paths.d.ts +0 -25
  175. package/dist_ts/paths.js +0 -44
  176. package/dist_ts/plugins.d.ts +0 -81
  177. package/dist_ts/plugins.js +0 -115
  178. package/dist_ts/radius/classes.accounting.manager.d.ts +0 -223
  179. package/dist_ts/radius/classes.accounting.manager.js +0 -449
  180. package/dist_ts/radius/classes.radius.server.d.ts +0 -169
  181. package/dist_ts/radius/classes.radius.server.js +0 -384
  182. package/dist_ts/radius/classes.vlan.manager.d.ts +0 -124
  183. package/dist_ts/radius/classes.vlan.manager.js +0 -272
  184. package/dist_ts/radius/index.d.ts +0 -13
  185. package/dist_ts/radius/index.js +0 -14
  186. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +0 -92
  187. package/dist_ts/remoteingress/classes.remoteingress-manager.js +0 -291
  188. package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +0 -59
  189. package/dist_ts/remoteingress/classes.tunnel-manager.js +0 -165
  190. package/dist_ts/remoteingress/index.d.ts +0 -2
  191. package/dist_ts/remoteingress/index.js +0 -3
  192. package/dist_ts/security/classes.contentscanner.d.ts +0 -164
  193. package/dist_ts/security/classes.contentscanner.js +0 -642
  194. package/dist_ts/security/classes.ipreputationchecker.d.ts +0 -145
  195. package/dist_ts/security/classes.ipreputationchecker.js +0 -458
  196. package/dist_ts/security/classes.securitylogger.d.ts +0 -144
  197. package/dist_ts/security/classes.securitylogger.js +0 -235
  198. package/dist_ts/security/index.d.ts +0 -3
  199. package/dist_ts/security/index.js +0 -4
  200. package/dist_ts/sms/classes.smsservice.d.ts +0 -15
  201. package/dist_ts/sms/classes.smsservice.js +0 -72
  202. package/dist_ts/sms/config/sms.config.d.ts +0 -93
  203. package/dist_ts/sms/config/sms.config.js +0 -2
  204. package/dist_ts/sms/config/sms.schema.d.ts +0 -5
  205. package/dist_ts/sms/config/sms.schema.js +0 -121
  206. package/dist_ts/sms/index.d.ts +0 -1
  207. package/dist_ts/sms/index.js +0 -2
  208. package/dist_ts/vpn/classes.vpn-manager.d.ts +0 -159
  209. package/dist_ts/vpn/classes.vpn-manager.js +0 -459
  210. package/dist_ts/vpn/index.d.ts +0 -1
  211. package/dist_ts/vpn/index.js +0 -2
  212. package/dist_ts_apiclient/classes.apitoken.d.ts +0 -41
  213. package/dist_ts_apiclient/classes.apitoken.js +0 -115
  214. package/dist_ts_apiclient/classes.certificate.d.ts +0 -57
  215. package/dist_ts_apiclient/classes.certificate.js +0 -69
  216. package/dist_ts_apiclient/classes.config.d.ts +0 -7
  217. package/dist_ts_apiclient/classes.config.js +0 -11
  218. package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +0 -41
  219. package/dist_ts_apiclient/classes.dcrouterapiclient.js +0 -81
  220. package/dist_ts_apiclient/classes.email.d.ts +0 -30
  221. package/dist_ts_apiclient/classes.email.js +0 -52
  222. package/dist_ts_apiclient/classes.logs.d.ts +0 -21
  223. package/dist_ts_apiclient/classes.logs.js +0 -14
  224. package/dist_ts_apiclient/classes.radius.d.ts +0 -59
  225. package/dist_ts_apiclient/classes.radius.js +0 -95
  226. package/dist_ts_apiclient/classes.remoteingress.d.ts +0 -54
  227. package/dist_ts_apiclient/classes.remoteingress.js +0 -136
  228. package/dist_ts_apiclient/classes.route.d.ts +0 -39
  229. package/dist_ts_apiclient/classes.route.js +0 -125
  230. package/dist_ts_apiclient/classes.stats.d.ts +0 -47
  231. package/dist_ts_apiclient/classes.stats.js +0 -38
  232. package/dist_ts_apiclient/index.d.ts +0 -10
  233. package/dist_ts_apiclient/index.js +0 -14
  234. package/dist_ts_apiclient/plugins.d.ts +0 -3
  235. package/dist_ts_apiclient/plugins.js +0 -5
  236. package/dist_ts_interfaces/data/acme-config.d.ts +0 -25
  237. package/dist_ts_interfaces/data/acme-config.js +0 -2
  238. package/dist_ts_interfaces/data/auth.d.ts +0 -8
  239. package/dist_ts_interfaces/data/auth.js +0 -2
  240. package/dist_ts_interfaces/data/dns-provider.d.ts +0 -136
  241. package/dist_ts_interfaces/data/dns-provider.js +0 -41
  242. package/dist_ts_interfaces/data/dns-record.d.ts +0 -42
  243. package/dist_ts_interfaces/data/dns-record.js +0 -2
  244. package/dist_ts_interfaces/data/domain.d.ts +0 -35
  245. package/dist_ts_interfaces/data/domain.js +0 -2
  246. package/dist_ts_interfaces/data/email-domain.d.ts +0 -70
  247. package/dist_ts_interfaces/data/email-domain.js +0 -2
  248. package/dist_ts_interfaces/data/index.d.ts +0 -11
  249. package/dist_ts_interfaces/data/index.js +0 -12
  250. package/dist_ts_interfaces/data/remoteingress.d.ts +0 -60
  251. package/dist_ts_interfaces/data/remoteingress.js +0 -2
  252. package/dist_ts_interfaces/data/route-management.d.ts +0 -110
  253. package/dist_ts_interfaces/data/route-management.js +0 -2
  254. package/dist_ts_interfaces/data/stats.d.ts +0 -238
  255. package/dist_ts_interfaces/data/stats.js +0 -2
  256. package/dist_ts_interfaces/data/target-profile.d.ts +0 -28
  257. package/dist_ts_interfaces/data/target-profile.js +0 -2
  258. package/dist_ts_interfaces/data/vpn.d.ts +0 -61
  259. package/dist_ts_interfaces/data/vpn.js +0 -2
  260. package/dist_ts_interfaces/index.d.ts +0 -5
  261. package/dist_ts_interfaces/index.js +0 -8
  262. package/dist_ts_interfaces/plugins.d.ts +0 -2
  263. package/dist_ts_interfaces/plugins.js +0 -4
  264. package/dist_ts_interfaces/requests/acme-config.d.ts +0 -42
  265. package/dist_ts_interfaces/requests/acme-config.js +0 -2
  266. package/dist_ts_interfaces/requests/admin.d.ts +0 -31
  267. package/dist_ts_interfaces/requests/admin.js +0 -3
  268. package/dist_ts_interfaces/requests/api-tokens.d.ts +0 -79
  269. package/dist_ts_interfaces/requests/api-tokens.js +0 -2
  270. package/dist_ts_interfaces/requests/certificate.d.ts +0 -111
  271. package/dist_ts_interfaces/requests/certificate.js +0 -3
  272. package/dist_ts_interfaces/requests/combined.stats.d.ts +0 -28
  273. package/dist_ts_interfaces/requests/combined.stats.js +0 -2
  274. package/dist_ts_interfaces/requests/config.d.ts +0 -90
  275. package/dist_ts_interfaces/requests/config.js +0 -3
  276. package/dist_ts_interfaces/requests/dns-providers.d.ts +0 -117
  277. package/dist_ts_interfaces/requests/dns-providers.js +0 -2
  278. package/dist_ts_interfaces/requests/dns-records.d.ts +0 -89
  279. package/dist_ts_interfaces/requests/dns-records.js +0 -2
  280. package/dist_ts_interfaces/requests/domains.d.ts +0 -142
  281. package/dist_ts_interfaces/requests/domains.js +0 -2
  282. package/dist_ts_interfaces/requests/email-domains.d.ts +0 -142
  283. package/dist_ts_interfaces/requests/email-domains.js +0 -2
  284. package/dist_ts_interfaces/requests/email-ops.d.ts +0 -82
  285. package/dist_ts_interfaces/requests/email-ops.js +0 -3
  286. package/dist_ts_interfaces/requests/index.d.ts +0 -21
  287. package/dist_ts_interfaces/requests/index.js +0 -22
  288. package/dist_ts_interfaces/requests/logs.d.ts +0 -41
  289. package/dist_ts_interfaces/requests/logs.js +0 -4
  290. package/dist_ts_interfaces/requests/network-targets.d.ts +0 -102
  291. package/dist_ts_interfaces/requests/network-targets.js +0 -2
  292. package/dist_ts_interfaces/requests/radius.d.ts +0 -268
  293. package/dist_ts_interfaces/requests/radius.js +0 -3
  294. package/dist_ts_interfaces/requests/remoteingress.d.ts +0 -108
  295. package/dist_ts_interfaces/requests/remoteingress.js +0 -3
  296. package/dist_ts_interfaces/requests/route-management.d.ts +0 -85
  297. package/dist_ts_interfaces/requests/route-management.js +0 -2
  298. package/dist_ts_interfaces/requests/source-profiles.d.ts +0 -102
  299. package/dist_ts_interfaces/requests/source-profiles.js +0 -2
  300. package/dist_ts_interfaces/requests/stats.d.ts +0 -177
  301. package/dist_ts_interfaces/requests/stats.js +0 -4
  302. package/dist_ts_interfaces/requests/target-profiles.d.ts +0 -103
  303. package/dist_ts_interfaces/requests/target-profiles.js +0 -2
  304. package/dist_ts_interfaces/requests/users.d.ts +0 -19
  305. package/dist_ts_interfaces/requests/users.js +0 -3
  306. package/dist_ts_interfaces/requests/vpn.d.ts +0 -177
  307. package/dist_ts_interfaces/requests/vpn.js +0 -3
  308. package/dist_ts_migrations/index.d.ts +0 -28
  309. package/dist_ts_migrations/index.js +0 -82
  310. package/dist_ts_oci_container/index.d.ts +0 -8
  311. package/dist_ts_oci_container/index.js +0 -110
  312. package/dist_ts_oci_container/plugins.d.ts +0 -3
  313. package/dist_ts_oci_container/plugins.js +0 -4
  314. package/dist_ts_web/00_commitinfo_data.d.ts +0 -8
  315. package/dist_ts_web/00_commitinfo_data.js +0 -9
  316. package/dist_ts_web/appstate.d.ts +0 -478
  317. package/dist_ts_web/appstate.js +0 -1968
  318. package/dist_ts_web/elements/access/index.d.ts +0 -2
  319. package/dist_ts_web/elements/access/index.js +0 -3
  320. package/dist_ts_web/elements/access/ops-view-apitokens.d.ts +0 -13
  321. package/dist_ts_web/elements/access/ops-view-apitokens.js +0 -372
  322. package/dist_ts_web/elements/access/ops-view-users.d.ts +0 -11
  323. package/dist_ts_web/elements/access/ops-view-users.js +0 -190
  324. package/dist_ts_web/elements/domains/dns-provider-form.d.ts +0 -60
  325. package/dist_ts_web/elements/domains/dns-provider-form.js +0 -259
  326. package/dist_ts_web/elements/domains/index.d.ts +0 -5
  327. package/dist_ts_web/elements/domains/index.js +0 -6
  328. package/dist_ts_web/elements/domains/ops-view-certificates.d.ts +0 -25
  329. package/dist_ts_web/elements/domains/ops-view-certificates.js +0 -669
  330. package/dist_ts_web/elements/domains/ops-view-dns.d.ts +0 -17
  331. package/dist_ts_web/elements/domains/ops-view-dns.js +0 -305
  332. package/dist_ts_web/elements/domains/ops-view-domains.d.ts +0 -19
  333. package/dist_ts_web/elements/domains/ops-view-domains.js +0 -456
  334. package/dist_ts_web/elements/domains/ops-view-providers.d.ts +0 -21
  335. package/dist_ts_web/elements/domains/ops-view-providers.js +0 -330
  336. package/dist_ts_web/elements/email/index.d.ts +0 -3
  337. package/dist_ts_web/elements/email/index.js +0 -4
  338. package/dist_ts_web/elements/email/ops-view-email-domains.d.ts +0 -19
  339. package/dist_ts_web/elements/email/ops-view-email-domains.js +0 -410
  340. package/dist_ts_web/elements/email/ops-view-email-security.d.ts +0 -14
  341. package/dist_ts_web/elements/email/ops-view-email-security.js +0 -178
  342. package/dist_ts_web/elements/email/ops-view-emails.d.ts +0 -21
  343. package/dist_ts_web/elements/email/ops-view-emails.js +0 -165
  344. package/dist_ts_web/elements/index.d.ts +0 -9
  345. package/dist_ts_web/elements/index.js +0 -10
  346. package/dist_ts_web/elements/network/index.d.ts +0 -7
  347. package/dist_ts_web/elements/network/index.js +0 -8
  348. package/dist_ts_web/elements/network/ops-view-network-activity.d.ts +0 -60
  349. package/dist_ts_web/elements/network/ops-view-network-activity.js +0 -753
  350. package/dist_ts_web/elements/network/ops-view-networktargets.d.ts +0 -17
  351. package/dist_ts_web/elements/network/ops-view-networktargets.js +0 -255
  352. package/dist_ts_web/elements/network/ops-view-remoteingress.d.ts +0 -20
  353. package/dist_ts_web/elements/network/ops-view-remoteingress.js +0 -497
  354. package/dist_ts_web/elements/network/ops-view-routes.d.ts +0 -16
  355. package/dist_ts_web/elements/network/ops-view-routes.js +0 -674
  356. package/dist_ts_web/elements/network/ops-view-sourceprofiles.d.ts +0 -17
  357. package/dist_ts_web/elements/network/ops-view-sourceprofiles.js +0 -278
  358. package/dist_ts_web/elements/network/ops-view-targetprofiles.d.ts +0 -21
  359. package/dist_ts_web/elements/network/ops-view-targetprofiles.js +0 -420
  360. package/dist_ts_web/elements/network/ops-view-vpn.d.ts +0 -31
  361. package/dist_ts_web/elements/network/ops-view-vpn.js +0 -873
  362. package/dist_ts_web/elements/ops-dashboard.d.ts +0 -31
  363. package/dist_ts_web/elements/ops-dashboard.js +0 -405
  364. package/dist_ts_web/elements/ops-view-logs.d.ts +0 -13
  365. package/dist_ts_web/elements/ops-view-logs.js +0 -159
  366. package/dist_ts_web/elements/overview/index.d.ts +0 -2
  367. package/dist_ts_web/elements/overview/index.js +0 -3
  368. package/dist_ts_web/elements/overview/ops-view-config.d.ts +0 -19
  369. package/dist_ts_web/elements/overview/ops-view-config.js +0 -339
  370. package/dist_ts_web/elements/overview/ops-view-overview.d.ts +0 -24
  371. package/dist_ts_web/elements/overview/ops-view-overview.js +0 -545
  372. package/dist_ts_web/elements/security/index.d.ts +0 -3
  373. package/dist_ts_web/elements/security/index.js +0 -4
  374. package/dist_ts_web/elements/security/ops-view-security-authentication.d.ts +0 -13
  375. package/dist_ts_web/elements/security/ops-view-security-authentication.js +0 -157
  376. package/dist_ts_web/elements/security/ops-view-security-blocked.d.ts +0 -15
  377. package/dist_ts_web/elements/security/ops-view-security-blocked.js +0 -153
  378. package/dist_ts_web/elements/security/ops-view-security-overview.d.ts +0 -16
  379. package/dist_ts_web/elements/security/ops-view-security-overview.js +0 -205
  380. package/dist_ts_web/elements/shared/css.d.ts +0 -1
  381. package/dist_ts_web/elements/shared/css.js +0 -10
  382. package/dist_ts_web/elements/shared/index.d.ts +0 -1
  383. package/dist_ts_web/elements/shared/index.js +0 -2
  384. package/dist_ts_web/index.d.ts +0 -1
  385. package/dist_ts_web/index.js +0 -10
  386. package/dist_ts_web/plugins.d.ts +0 -7
  387. package/dist_ts_web/plugins.js +0 -13
  388. package/dist_ts_web/router.d.ts +0 -21
  389. package/dist_ts_web/router.js +0 -151
@@ -1,906 +0,0 @@
1
- import * as plugins from '../plugins.js';
2
- import { logger } from '../logger.js';
3
- import { DnsProviderDoc, DomainDoc, DnsRecordDoc, } from '../db/documents/index.js';
4
- import { createDnsProvider } from './providers/factory.js';
5
- /**
6
- * DnsManager — owns runtime DNS state on top of the embedded DnsServer.
7
- *
8
- * Responsibilities:
9
- * - Load Domain/DnsRecord docs from the DB on start
10
- * - First-boot seeding from legacy constructor config (dnsScopes/dnsRecords/dnsNsDomains)
11
- * - Register dcrouter-hosted domain records with smartdns.DnsServer at startup
12
- * - Provide CRUD methods used by OpsServer handlers (dcrouter-hosted domains hit
13
- * smartdns, provider domains hit the provider API)
14
- * - Expose a provider lookup used by the ACME DNS-01 wiring in setupSmartProxy()
15
- *
16
- * Provider-managed domains are NEVER served from the embedded DnsServer — the
17
- * provider stays authoritative. We only mirror their records locally for the UI
18
- * and to track providerRecordIds for updates / deletes.
19
- */
20
- export class DnsManager {
21
- options;
22
- /**
23
- * Reference to the active smartdns DnsServer (set by DcRouter once it exists).
24
- * May be undefined if dnsScopes/dnsNsDomains aren't configured.
25
- */
26
- dnsServer;
27
- /**
28
- * Cached provider clients, keyed by DnsProviderDoc.id.
29
- * Created lazily when a provider is first needed.
30
- */
31
- providerClients = new Map();
32
- constructor(options) {
33
- this.options = options;
34
- }
35
- // ==========================================================================
36
- // Lifecycle
37
- // ==========================================================================
38
- /**
39
- * Called from DcRouter after DcRouterDb is up. Performs first-boot seeding
40
- * from legacy constructor config if (and only if) the DB is empty.
41
- */
42
- async start() {
43
- logger.log('info', 'DnsManager: starting');
44
- await this.seedFromConstructorConfigIfEmpty();
45
- }
46
- async stop() {
47
- this.providerClients.clear();
48
- this.dnsServer = undefined;
49
- }
50
- /**
51
- * Wire the embedded DnsServer instance after it has been created by
52
- * DcRouter.setupDnsWithSocketHandler(). After this, local records on
53
- * dcrouter-hosted domains loaded from the DB are registered with the server.
54
- */
55
- async attachDnsServer(dnsServer) {
56
- this.dnsServer = dnsServer;
57
- await this.applyDcrouterDomainsToDnsServer();
58
- }
59
- // ==========================================================================
60
- // First-boot seeding
61
- // ==========================================================================
62
- /**
63
- * If no DomainDocs exist yet but the constructor has legacy DNS fields,
64
- * seed them as dcrouter-hosted (`domain.source: 'dcrouter'`) zones with
65
- * local (`record.source: 'local'`) records. On subsequent boots (DB has
66
- * entries), constructor config is ignored with a warning.
67
- */
68
- async seedFromConstructorConfigIfEmpty() {
69
- const existingDomains = await DomainDoc.findAll();
70
- const hasLegacyConfig = (this.options.dnsScopes && this.options.dnsScopes.length > 0) ||
71
- (this.options.dnsRecords && this.options.dnsRecords.length > 0);
72
- if (existingDomains.length > 0) {
73
- if (hasLegacyConfig) {
74
- logger.log('warn', 'DnsManager: DB has DomainDoc entries — ignoring legacy dnsScopes/dnsRecords/dnsNsDomains constructor config. ' +
75
- 'Manage DNS via the Domains UI instead.');
76
- }
77
- return;
78
- }
79
- if (!hasLegacyConfig) {
80
- return;
81
- }
82
- logger.log('info', 'DnsManager: seeding DB from legacy constructor DNS config');
83
- const now = Date.now();
84
- const seededDomains = new Map();
85
- // Create one DomainDoc per dnsScope (these are the authoritative zones)
86
- for (const scope of this.options.dnsScopes ?? []) {
87
- const domain = new DomainDoc();
88
- domain.id = plugins.uuid.v4();
89
- domain.name = scope.toLowerCase();
90
- domain.source = 'dcrouter';
91
- domain.authoritative = true;
92
- domain.createdAt = now;
93
- domain.updatedAt = now;
94
- domain.createdBy = 'seed';
95
- await domain.save();
96
- seededDomains.set(domain.name, domain);
97
- logger.log('info', `DnsManager: seeded DomainDoc for ${domain.name}`);
98
- }
99
- // Map each legacy dnsRecord to its parent DomainDoc
100
- for (const rec of this.options.dnsRecords ?? []) {
101
- const parent = this.findParentDomain(rec.name, seededDomains);
102
- if (!parent) {
103
- logger.log('warn', `DnsManager: legacy dnsRecord '${rec.name}' has no matching dnsScope — skipping seed`);
104
- continue;
105
- }
106
- const record = new DnsRecordDoc();
107
- record.id = plugins.uuid.v4();
108
- record.domainId = parent.id;
109
- record.name = rec.name.toLowerCase();
110
- record.type = rec.type;
111
- record.value = rec.value;
112
- record.ttl = rec.ttl ?? 300;
113
- record.source = 'local';
114
- record.createdAt = now;
115
- record.updatedAt = now;
116
- record.createdBy = 'seed';
117
- await record.save();
118
- }
119
- logger.log('info', `DnsManager: seeded ${seededDomains.size} domain(s) and ${this.options.dnsRecords?.length ?? 0} record(s) from legacy config`);
120
- }
121
- findParentDomain(recordName, domains) {
122
- const lower = recordName.toLowerCase().replace(/^\*\./, '');
123
- let candidate = null;
124
- for (const [name, doc] of domains) {
125
- if (lower === name || lower.endsWith(`.${name}`)) {
126
- if (!candidate || name.length > candidate.name.length) {
127
- candidate = doc;
128
- }
129
- }
130
- }
131
- return candidate;
132
- }
133
- // ==========================================================================
134
- // DcRouter-hosted domain DnsServer wiring
135
- // ==========================================================================
136
- /**
137
- * Register all records from dcrouter-hosted domains in the DB with the
138
- * embedded DnsServer. Called once after attachDnsServer().
139
- */
140
- async applyDcrouterDomainsToDnsServer() {
141
- if (!this.dnsServer) {
142
- return;
143
- }
144
- const allDomains = await DomainDoc.findAll();
145
- const dcrouterDomains = allDomains.filter((d) => d.source === 'dcrouter');
146
- let registered = 0;
147
- for (const domain of dcrouterDomains) {
148
- const records = await DnsRecordDoc.findByDomainId(domain.id);
149
- for (const rec of records) {
150
- this.registerRecordWithDnsServer(rec);
151
- registered++;
152
- }
153
- }
154
- logger.log('info', `DnsManager: registered ${registered} dcrouter-hosted DNS record(s) from DB`);
155
- }
156
- /**
157
- * Register a single record with the embedded DnsServer. The handler closure
158
- * captures the record fields, so updates require a re-register cycle.
159
- */
160
- registerRecordWithDnsServer(rec) {
161
- if (!this.dnsServer)
162
- return;
163
- this.dnsServer.registerHandler(rec.name, [rec.type], (question) => {
164
- if (question.name === rec.name && question.type === rec.type) {
165
- return {
166
- name: rec.name,
167
- type: rec.type,
168
- class: 'IN',
169
- ttl: rec.ttl,
170
- data: this.parseRecordData(rec.type, rec.value),
171
- };
172
- }
173
- return null;
174
- });
175
- }
176
- parseRecordData(type, value) {
177
- switch (type) {
178
- case 'A':
179
- case 'AAAA':
180
- case 'CNAME':
181
- case 'TXT':
182
- case 'NS':
183
- case 'CAA':
184
- return value;
185
- case 'MX': {
186
- const [priorityStr, exchange] = value.split(' ');
187
- return { priority: parseInt(priorityStr, 10), exchange };
188
- }
189
- case 'SOA': {
190
- const parts = value.split(' ');
191
- return {
192
- mname: parts[0],
193
- rname: parts[1],
194
- serial: parseInt(parts[2], 10),
195
- refresh: parseInt(parts[3], 10),
196
- retry: parseInt(parts[4], 10),
197
- expire: parseInt(parts[5], 10),
198
- minimum: parseInt(parts[6], 10),
199
- };
200
- }
201
- default:
202
- return value;
203
- }
204
- }
205
- // ==========================================================================
206
- // Provider lookup (used by ACME DNS-01 + record CRUD)
207
- // ==========================================================================
208
- /**
209
- * Get the provider client for a given DnsProviderDoc id, instantiating
210
- * (and caching) it on first use.
211
- */
212
- async getProviderClientById(providerId) {
213
- const cached = this.providerClients.get(providerId);
214
- if (cached)
215
- return cached;
216
- const doc = await DnsProviderDoc.findById(providerId);
217
- if (!doc)
218
- return null;
219
- const client = createDnsProvider(doc.type, doc.credentials);
220
- this.providerClients.set(providerId, client);
221
- return client;
222
- }
223
- /**
224
- * Find the IDnsProviderClient that owns the given FQDN (by walking up its
225
- * labels to find a matching DomainDoc with `source === 'provider'`).
226
- * Returns null if no provider claims this FQDN.
227
- *
228
- * Used by:
229
- * - SmartAcme DNS-01 wiring in setupSmartProxy()
230
- * - DnsRecordHandler when creating provider records
231
- */
232
- async getProviderClientForDomain(fqdn) {
233
- const lower = fqdn.toLowerCase().replace(/^\*\./, '').replace(/\.$/, '');
234
- const allDomains = await DomainDoc.findAll();
235
- const providerDomains = allDomains
236
- .filter((d) => d.source === 'provider' && d.providerId)
237
- // longest-match wins
238
- .sort((a, b) => b.name.length - a.name.length);
239
- for (const domain of providerDomains) {
240
- if (lower === domain.name || lower.endsWith(`.${domain.name}`)) {
241
- return this.getProviderClientById(domain.providerId);
242
- }
243
- }
244
- return null;
245
- }
246
- /**
247
- * Find the DomainDoc that covers a given FQDN, regardless of source
248
- * (dcrouter-hosted or provider-managed). Uses longest-suffix match.
249
- */
250
- async findDomainForFqdn(fqdn) {
251
- const lower = fqdn.toLowerCase().replace(/^\*\./, '').replace(/\.$/, '');
252
- const allDomains = await DomainDoc.findAll();
253
- // Sort by name length descending for longest-match-wins
254
- allDomains.sort((a, b) => b.name.length - a.name.length);
255
- for (const domain of allDomains) {
256
- if (lower === domain.name || lower.endsWith(`.${domain.name}`)) {
257
- return domain;
258
- }
259
- }
260
- return null;
261
- }
262
- /**
263
- * Delete all DNS records matching a name and type under a domain.
264
- * Used for ACME challenge cleanup (may have multiple TXT records at the same name).
265
- */
266
- async deleteRecordsByNameAndType(domainId, name, type) {
267
- const records = await DnsRecordDoc.findByDomainId(domainId);
268
- for (const rec of records) {
269
- if (rec.name.toLowerCase() === name.toLowerCase() && rec.type === type) {
270
- await this.deleteRecord(rec.id);
271
- }
272
- }
273
- }
274
- /**
275
- * True if any domain is under management (dcrouter-hosted or provider-managed).
276
- * Used by setupSmartProxy() to decide whether to wire SmartAcme with a DNS-01 handler.
277
- */
278
- async hasAnyManagedDomain() {
279
- const domains = await DomainDoc.findAll();
280
- return domains.length > 0;
281
- }
282
- /**
283
- * Build an IConvenientDnsProvider that routes ACME DNS-01 challenges through
284
- * the DnsManager abstraction. Challenges are dispatched via createRecord() /
285
- * deleteRecord(), which transparently handle both dcrouter-hosted zones
286
- * (embedded DnsServer) and provider-managed zones (e.g. Cloudflare API).
287
- *
288
- * Only domains under management (with a DomainDoc in DB) are supported —
289
- * this acts as the management gate for certificate issuance.
290
- */
291
- buildAcmeConvenientDnsProvider() {
292
- const self = this;
293
- const adapter = {
294
- async acmeSetDnsChallenge(dnsChallenge) {
295
- const domainDoc = await self.findDomainForFqdn(dnsChallenge.hostName);
296
- if (!domainDoc) {
297
- throw new Error(`DnsManager: no managed domain found for ${dnsChallenge.hostName}. ` +
298
- 'Add the domain in Domains before issuing certificates.');
299
- }
300
- // Clean leftover challenge records first to avoid duplicates.
301
- try {
302
- await self.deleteRecordsByNameAndType(domainDoc.id, dnsChallenge.hostName, 'TXT');
303
- }
304
- catch (err) {
305
- logger.log('warn', `DnsManager: failed to clean existing TXT for ${dnsChallenge.hostName}: ${err.message}`);
306
- }
307
- // Create the challenge TXT record via the unified path
308
- await self.createRecord({
309
- domainId: domainDoc.id,
310
- name: dnsChallenge.hostName,
311
- type: 'TXT',
312
- value: dnsChallenge.challenge,
313
- ttl: 120,
314
- createdBy: 'acme-dns01',
315
- });
316
- },
317
- async acmeRemoveDnsChallenge(dnsChallenge) {
318
- const domainDoc = await self.findDomainForFqdn(dnsChallenge.hostName);
319
- if (!domainDoc) {
320
- // The domain may have been removed; nothing to clean up.
321
- return;
322
- }
323
- try {
324
- await self.deleteRecordsByNameAndType(domainDoc.id, dnsChallenge.hostName, 'TXT');
325
- }
326
- catch (err) {
327
- logger.log('warn', `DnsManager: failed to remove TXT for ${dnsChallenge.hostName}: ${err.message}`);
328
- }
329
- },
330
- async isDomainSupported(domain) {
331
- const domainDoc = await self.findDomainForFqdn(domain);
332
- return !!domainDoc;
333
- },
334
- };
335
- return { convenience: adapter };
336
- }
337
- // ==========================================================================
338
- // Provider CRUD (used by DnsProviderHandler)
339
- // ==========================================================================
340
- async listProviders() {
341
- const docs = await DnsProviderDoc.findAll();
342
- return docs.map((d) => this.toPublicProvider(d));
343
- }
344
- async getProvider(id) {
345
- const doc = await DnsProviderDoc.findById(id);
346
- return doc ? this.toPublicProvider(doc) : null;
347
- }
348
- async createProvider(args) {
349
- if (args.type === 'dcrouter') {
350
- throw new Error('createProvider: cannot create a DnsProviderDoc with type "dcrouter" — ' +
351
- 'that type is reserved for the built-in pseudo-provider surfaced at read time.');
352
- }
353
- const now = Date.now();
354
- const doc = new DnsProviderDoc();
355
- doc.id = plugins.uuid.v4();
356
- doc.name = args.name;
357
- doc.type = args.type;
358
- doc.credentials = args.credentials;
359
- doc.status = 'untested';
360
- doc.createdAt = now;
361
- doc.updatedAt = now;
362
- doc.createdBy = args.createdBy;
363
- await doc.save();
364
- return doc.id;
365
- }
366
- async updateProvider(id, args) {
367
- const doc = await DnsProviderDoc.findById(id);
368
- if (!doc)
369
- return false;
370
- if (args.name !== undefined)
371
- doc.name = args.name;
372
- if (args.credentials !== undefined) {
373
- doc.credentials = args.credentials;
374
- doc.status = 'untested';
375
- doc.lastError = undefined;
376
- // Invalidate cached client so the next use re-instantiates with the new credentials.
377
- this.providerClients.delete(id);
378
- }
379
- doc.updatedAt = Date.now();
380
- await doc.save();
381
- return true;
382
- }
383
- async deleteProvider(id, force) {
384
- const doc = await DnsProviderDoc.findById(id);
385
- if (!doc)
386
- return { success: false, message: 'Provider not found' };
387
- const linkedDomains = await DomainDoc.findByProviderId(id);
388
- if (linkedDomains.length > 0 && !force) {
389
- return {
390
- success: false,
391
- message: `Provider is referenced by ${linkedDomains.length} domain(s). Pass force: true to delete anyway.`,
392
- };
393
- }
394
- // If forcing, also delete the linked domains and their records.
395
- if (force) {
396
- for (const domain of linkedDomains) {
397
- await this.deleteDomain(domain.id);
398
- }
399
- }
400
- await doc.delete();
401
- this.providerClients.delete(id);
402
- return { success: true };
403
- }
404
- async testProvider(id) {
405
- const doc = await DnsProviderDoc.findById(id);
406
- if (!doc) {
407
- return { ok: false, error: 'Provider not found', testedAt: Date.now() };
408
- }
409
- const client = createDnsProvider(doc.type, doc.credentials);
410
- const result = await client.testConnection();
411
- doc.status = result.ok ? 'ok' : 'error';
412
- doc.lastTestedAt = Date.now();
413
- doc.lastError = result.ok ? undefined : result.error;
414
- await doc.save();
415
- if (result.ok) {
416
- this.providerClients.set(id, client); // cache the working client
417
- }
418
- return { ok: result.ok, error: result.error, testedAt: doc.lastTestedAt };
419
- }
420
- async listProviderDomains(providerId) {
421
- const client = await this.getProviderClientById(providerId);
422
- if (!client) {
423
- throw new Error('Provider not found');
424
- }
425
- return await client.listDomains();
426
- }
427
- // ==========================================================================
428
- // Domain CRUD (used by DomainHandler)
429
- // ==========================================================================
430
- async listDomains() {
431
- return await DomainDoc.findAll();
432
- }
433
- async getDomain(id) {
434
- return await DomainDoc.findById(id);
435
- }
436
- /**
437
- * Create a dcrouter-hosted (authoritative) domain. dcrouter will serve
438
- * DNS records for this domain via the embedded smartdns.DnsServer.
439
- */
440
- async createDcrouterDomain(args) {
441
- const now = Date.now();
442
- const doc = new DomainDoc();
443
- doc.id = plugins.uuid.v4();
444
- doc.name = args.name.toLowerCase();
445
- doc.source = 'dcrouter';
446
- doc.authoritative = true;
447
- doc.description = args.description;
448
- doc.createdAt = now;
449
- doc.updatedAt = now;
450
- doc.createdBy = args.createdBy;
451
- await doc.save();
452
- return doc.id;
453
- }
454
- /**
455
- * Import one or more domains from a provider, pulling all of their DNS
456
- * records into local DnsRecordDocs.
457
- */
458
- async importDomainsFromProvider(args) {
459
- const provider = await DnsProviderDoc.findById(args.providerId);
460
- if (!provider) {
461
- throw new Error('Provider not found');
462
- }
463
- const client = await this.getProviderClientById(args.providerId);
464
- if (!client) {
465
- throw new Error('Failed to instantiate provider client');
466
- }
467
- const allProviderDomains = await client.listDomains();
468
- const importedIds = [];
469
- const now = Date.now();
470
- for (const wantedName of args.domainNames) {
471
- const lower = wantedName.toLowerCase();
472
- const listing = allProviderDomains.find((d) => d.name.toLowerCase() === lower);
473
- if (!listing) {
474
- logger.log('warn', `DnsManager: import skipped — provider does not list domain ${wantedName}`);
475
- continue;
476
- }
477
- // Skip if already imported
478
- const existing = await DomainDoc.findByName(lower);
479
- if (existing) {
480
- logger.log('warn', `DnsManager: domain ${wantedName} already imported — skipping`);
481
- continue;
482
- }
483
- const domain = new DomainDoc();
484
- domain.id = plugins.uuid.v4();
485
- domain.name = lower;
486
- domain.source = 'provider';
487
- domain.providerId = args.providerId;
488
- domain.authoritative = false;
489
- domain.nameservers = listing.nameservers;
490
- domain.externalZoneId = listing.externalId;
491
- domain.lastSyncedAt = now;
492
- domain.createdAt = now;
493
- domain.updatedAt = now;
494
- domain.createdBy = args.createdBy;
495
- await domain.save();
496
- importedIds.push(domain.id);
497
- // Pull records for the imported domain
498
- try {
499
- const providerRecords = await client.listRecords(lower);
500
- for (const pr of providerRecords) {
501
- await this.createSyncedRecord(domain.id, pr, args.createdBy);
502
- }
503
- logger.log('info', `DnsManager: imported ${providerRecords.length} record(s) for ${lower}`);
504
- }
505
- catch (err) {
506
- logger.log('warn', `DnsManager: failed to import records for ${lower}: ${err.message}`);
507
- }
508
- }
509
- return importedIds;
510
- }
511
- async updateDomain(id, args) {
512
- const doc = await DomainDoc.findById(id);
513
- if (!doc)
514
- return false;
515
- if (args.description !== undefined)
516
- doc.description = args.description;
517
- doc.updatedAt = Date.now();
518
- await doc.save();
519
- return true;
520
- }
521
- /**
522
- * Delete a domain and all of its DNS records. For provider domains, only
523
- * removes the local mirror — does NOT touch the provider.
524
- * For dcrouter-hosted domains, also unregisters records from the embedded
525
- * DnsServer.
526
- *
527
- * Note: smartdns has no public unregister-by-name API in the version pinned
528
- * here, so local record deletes only take effect after a restart. The DB
529
- * is the source of truth and the next start will not register the deleted
530
- * record.
531
- */
532
- async deleteDomain(id) {
533
- const doc = await DomainDoc.findById(id);
534
- if (!doc)
535
- return false;
536
- const records = await DnsRecordDoc.findByDomainId(id);
537
- for (const r of records) {
538
- await r.delete();
539
- }
540
- await doc.delete();
541
- return true;
542
- }
543
- /**
544
- * Force-resync a provider-managed domain: re-pull all records from the
545
- * provider API, replacing the cached DnsRecordDocs.
546
- */
547
- async syncDomain(id) {
548
- const doc = await DomainDoc.findById(id);
549
- if (!doc)
550
- return { success: false, message: 'Domain not found' };
551
- if (doc.source !== 'provider' || !doc.providerId) {
552
- return { success: false, message: 'Domain is not provider-managed' };
553
- }
554
- const client = await this.getProviderClientById(doc.providerId);
555
- if (!client) {
556
- return { success: false, message: 'Provider client unavailable' };
557
- }
558
- const providerRecords = await client.listRecords(doc.name);
559
- // Drop existing records and replace
560
- const existing = await DnsRecordDoc.findByDomainId(id);
561
- for (const r of existing) {
562
- await r.delete();
563
- }
564
- for (const pr of providerRecords) {
565
- await this.createSyncedRecord(id, pr, doc.createdBy);
566
- }
567
- doc.lastSyncedAt = Date.now();
568
- doc.updatedAt = doc.lastSyncedAt;
569
- await doc.save();
570
- return { success: true, recordCount: providerRecords.length };
571
- }
572
- // ==========================================================================
573
- // Record CRUD (used by DnsRecordHandler)
574
- // ==========================================================================
575
- async listRecordsForDomain(domainId) {
576
- return await DnsRecordDoc.findByDomainId(domainId);
577
- }
578
- async getRecord(id) {
579
- return await DnsRecordDoc.findById(id);
580
- }
581
- // ==========================================================================
582
- // Domain migration
583
- // ==========================================================================
584
- /**
585
- * Migrate a domain between dcrouter-hosted and provider-managed.
586
- * Transfers all records to the target and updates domain metadata.
587
- */
588
- async migrateDomain(args) {
589
- const domain = await DomainDoc.findById(args.id);
590
- if (!domain)
591
- return { success: false, message: 'Domain not found' };
592
- if (domain.source === args.targetSource && domain.providerId === args.targetProviderId) {
593
- return { success: false, message: 'Domain is already in the target configuration' };
594
- }
595
- const records = await DnsRecordDoc.findByDomainId(domain.id);
596
- if (args.targetSource === 'provider') {
597
- return this.migrateToDnsProvider(domain, records, args.targetProviderId, args.deleteExistingProviderRecords ?? false);
598
- }
599
- else {
600
- return this.migrateToDcrouter(domain, records);
601
- }
602
- }
603
- /**
604
- * Migrate domain from dcrouter-hosted (or another provider) to an external DNS provider.
605
- */
606
- async migrateToDnsProvider(domain, records, targetProviderId, deleteExistingProviderRecords) {
607
- // Validate the target provider exists
608
- const client = await this.getProviderClientById(targetProviderId);
609
- if (!client) {
610
- return { success: false, message: 'Target DNS provider not found' };
611
- }
612
- // Find the zone at the provider
613
- const providerDomains = await client.listDomains();
614
- const zone = providerDomains.find((z) => z.name.toLowerCase() === domain.name.toLowerCase());
615
- if (!zone) {
616
- return { success: false, message: `Zone "${domain.name}" not found at the target provider` };
617
- }
618
- // Optionally delete existing records at the provider
619
- if (deleteExistingProviderRecords) {
620
- try {
621
- const existingProviderRecords = await client.listRecords(domain.name);
622
- for (const pr of existingProviderRecords) {
623
- await client.deleteRecord(domain.name, pr.providerRecordId).catch(() => { });
624
- }
625
- logger.log('info', `Deleted ${existingProviderRecords.length} existing records at provider for ${domain.name}`);
626
- }
627
- catch (err) {
628
- logger.log('warn', `Failed to clean existing provider records for ${domain.name}: ${err.message}`);
629
- }
630
- }
631
- // Push each local record to the provider
632
- let migrated = 0;
633
- for (const rec of records) {
634
- try {
635
- const providerRecord = await client.createRecord(domain.name, {
636
- name: rec.name,
637
- type: rec.type,
638
- value: rec.value,
639
- ttl: rec.ttl,
640
- });
641
- // Unregister from embedded DnsServer if it was dcrouter-hosted
642
- if (domain.source === 'dcrouter') {
643
- this.unregisterRecordFromDnsServer(rec);
644
- }
645
- // Update the record doc to synced
646
- rec.source = 'synced';
647
- rec.providerRecordId = providerRecord.providerRecordId;
648
- await rec.save();
649
- migrated++;
650
- }
651
- catch (err) {
652
- logger.log('warn', `Failed to migrate record ${rec.name} ${rec.type} to provider: ${err.message}`);
653
- }
654
- }
655
- // Update domain metadata
656
- domain.source = 'provider';
657
- domain.authoritative = false;
658
- domain.providerId = targetProviderId;
659
- domain.externalZoneId = zone.externalId;
660
- domain.nameservers = zone.nameservers;
661
- domain.lastSyncedAt = Date.now();
662
- domain.updatedAt = Date.now();
663
- await domain.save();
664
- logger.log('info', `Domain ${domain.name} migrated to provider (${migrated} records)`);
665
- return { success: true, recordsMigrated: migrated };
666
- }
667
- /**
668
- * Migrate domain from provider-managed to dcrouter-hosted (authoritative).
669
- */
670
- async migrateToDcrouter(domain, records) {
671
- // Register each record with the embedded DnsServer
672
- let migrated = 0;
673
- for (const rec of records) {
674
- try {
675
- this.registerRecordWithDnsServer(rec);
676
- // Update the record doc to local
677
- rec.source = 'local';
678
- rec.providerRecordId = undefined;
679
- await rec.save();
680
- migrated++;
681
- }
682
- catch (err) {
683
- logger.log('warn', `Failed to register record ${rec.name} ${rec.type} with DnsServer: ${err.message}`);
684
- }
685
- }
686
- // Update domain metadata
687
- domain.source = 'dcrouter';
688
- domain.authoritative = true;
689
- domain.providerId = undefined;
690
- domain.externalZoneId = undefined;
691
- domain.nameservers = undefined;
692
- domain.lastSyncedAt = undefined;
693
- domain.updatedAt = Date.now();
694
- await domain.save();
695
- logger.log('info', `Domain ${domain.name} migrated to dcrouter (${migrated} records)`);
696
- return { success: true, recordsMigrated: migrated };
697
- }
698
- // ==========================================================================
699
- // Record CRUD
700
- // ==========================================================================
701
- async createRecord(args) {
702
- const domain = await DomainDoc.findById(args.domainId);
703
- if (!domain)
704
- return { success: false, message: 'Domain not found' };
705
- const now = Date.now();
706
- const doc = new DnsRecordDoc();
707
- doc.id = plugins.uuid.v4();
708
- doc.domainId = args.domainId;
709
- doc.name = args.name.toLowerCase();
710
- doc.type = args.type;
711
- doc.value = args.value;
712
- doc.ttl = args.ttl ?? 300;
713
- if (args.proxied !== undefined)
714
- doc.proxied = args.proxied;
715
- doc.source = 'local';
716
- doc.createdAt = now;
717
- doc.updatedAt = now;
718
- doc.createdBy = args.createdBy;
719
- if (domain.source === 'provider') {
720
- // Push to provider first; only persist locally on success
721
- if (!domain.providerId) {
722
- return { success: false, message: 'Provider domain has no providerId' };
723
- }
724
- const client = await this.getProviderClientById(domain.providerId);
725
- if (!client)
726
- return { success: false, message: 'Provider client unavailable' };
727
- try {
728
- const created = await client.createRecord(domain.name, {
729
- name: doc.name,
730
- type: doc.type,
731
- value: doc.value,
732
- ttl: doc.ttl,
733
- proxied: doc.proxied,
734
- });
735
- doc.providerRecordId = created.providerRecordId;
736
- doc.source = 'synced';
737
- }
738
- catch (err) {
739
- return { success: false, message: `Provider rejected record: ${err.message}` };
740
- }
741
- }
742
- else {
743
- // dcrouter-hosted / authoritative — register with embedded DnsServer immediately
744
- this.registerRecordWithDnsServer(doc);
745
- }
746
- await doc.save();
747
- return { success: true, id: doc.id };
748
- }
749
- async updateRecord(args) {
750
- const doc = await DnsRecordDoc.findById(args.id);
751
- if (!doc)
752
- return { success: false, message: 'Record not found' };
753
- const domain = await DomainDoc.findById(doc.domainId);
754
- if (!domain)
755
- return { success: false, message: 'Parent domain not found' };
756
- if (args.name !== undefined)
757
- doc.name = args.name.toLowerCase();
758
- if (args.value !== undefined)
759
- doc.value = args.value;
760
- if (args.ttl !== undefined)
761
- doc.ttl = args.ttl;
762
- if (args.proxied !== undefined)
763
- doc.proxied = args.proxied;
764
- doc.updatedAt = Date.now();
765
- if (domain.source === 'provider') {
766
- if (!domain.providerId || !doc.providerRecordId) {
767
- return { success: false, message: 'Provider record metadata missing' };
768
- }
769
- const client = await this.getProviderClientById(domain.providerId);
770
- if (!client)
771
- return { success: false, message: 'Provider client unavailable' };
772
- try {
773
- await client.updateRecord(domain.name, doc.providerRecordId, {
774
- name: doc.name,
775
- type: doc.type,
776
- value: doc.value,
777
- ttl: doc.ttl,
778
- proxied: doc.proxied,
779
- });
780
- }
781
- catch (err) {
782
- return { success: false, message: `Provider rejected update: ${err.message}` };
783
- }
784
- }
785
- else {
786
- // Re-register the local record so the new closure picks up the updated fields
787
- this.registerRecordWithDnsServer(doc);
788
- }
789
- await doc.save();
790
- return { success: true };
791
- }
792
- async deleteRecord(id) {
793
- const doc = await DnsRecordDoc.findById(id);
794
- if (!doc)
795
- return { success: false, message: 'Record not found' };
796
- const domain = await DomainDoc.findById(doc.domainId);
797
- if (!domain)
798
- return { success: false, message: 'Parent domain not found' };
799
- if (domain.source === 'provider') {
800
- if (domain.providerId && doc.providerRecordId) {
801
- const client = await this.getProviderClientById(domain.providerId);
802
- if (client) {
803
- try {
804
- await client.deleteRecord(domain.name, doc.providerRecordId);
805
- }
806
- catch (err) {
807
- return { success: false, message: `Provider rejected delete: ${err.message}` };
808
- }
809
- }
810
- }
811
- }
812
- // For dcrouter-hosted records: unregister the handler from the embedded DnsServer
813
- // so the record stops being served immediately (not just after restart).
814
- if (domain.source === 'dcrouter' && this.dnsServer) {
815
- this.unregisterRecordFromDnsServer(doc);
816
- }
817
- await doc.delete();
818
- return { success: true };
819
- }
820
- /**
821
- * Unregister a record's handler from the embedded DnsServer.
822
- */
823
- unregisterRecordFromDnsServer(rec) {
824
- if (!this.dnsServer)
825
- return;
826
- this.dnsServer.unregisterHandler(rec.name, [rec.type]);
827
- }
828
- // ==========================================================================
829
- // Internal helpers
830
- // ==========================================================================
831
- async createSyncedRecord(domainId, pr, createdBy) {
832
- const now = Date.now();
833
- const doc = new DnsRecordDoc();
834
- doc.id = plugins.uuid.v4();
835
- doc.domainId = domainId;
836
- doc.name = pr.name.toLowerCase();
837
- doc.type = pr.type;
838
- doc.value = pr.value;
839
- doc.ttl = pr.ttl;
840
- if (pr.proxied !== undefined)
841
- doc.proxied = pr.proxied;
842
- doc.source = 'synced';
843
- doc.providerRecordId = pr.providerRecordId;
844
- doc.createdAt = now;
845
- doc.updatedAt = now;
846
- doc.createdBy = createdBy;
847
- await doc.save();
848
- }
849
- /**
850
- * Convert a DnsProviderDoc to its public, secret-stripped representation
851
- * for the OpsServer API.
852
- */
853
- toPublicProvider(doc) {
854
- return {
855
- id: doc.id,
856
- name: doc.name,
857
- type: doc.type,
858
- status: doc.status,
859
- lastTestedAt: doc.lastTestedAt,
860
- lastError: doc.lastError,
861
- createdAt: doc.createdAt,
862
- updatedAt: doc.updatedAt,
863
- createdBy: doc.createdBy,
864
- hasCredentials: !!doc.credentials,
865
- };
866
- }
867
- /**
868
- * Convert a DomainDoc to its plain interface representation.
869
- */
870
- toPublicDomain(doc) {
871
- return {
872
- id: doc.id,
873
- name: doc.name,
874
- source: doc.source,
875
- providerId: doc.providerId,
876
- authoritative: doc.authoritative,
877
- nameservers: doc.nameservers,
878
- externalZoneId: doc.externalZoneId,
879
- lastSyncedAt: doc.lastSyncedAt,
880
- description: doc.description,
881
- createdAt: doc.createdAt,
882
- updatedAt: doc.updatedAt,
883
- createdBy: doc.createdBy,
884
- };
885
- }
886
- /**
887
- * Convert a DnsRecordDoc to its plain interface representation.
888
- */
889
- toPublicRecord(doc) {
890
- return {
891
- id: doc.id,
892
- domainId: doc.domainId,
893
- name: doc.name,
894
- type: doc.type,
895
- value: doc.value,
896
- ttl: doc.ttl,
897
- proxied: doc.proxied,
898
- source: doc.source,
899
- providerRecordId: doc.providerRecordId,
900
- createdAt: doc.createdAt,
901
- updatedAt: doc.updatedAt,
902
- createdBy: doc.createdBy,
903
- };
904
- }
905
- }
906
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlci5kbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9kbnMvbWFuYWdlci5kbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN0QyxPQUFPLEVBQ0wsY0FBYyxFQUNkLFNBQVMsRUFDVCxZQUFZLEdBQ2IsTUFBTSwwQkFBMEIsQ0FBQztBQUdsQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVkzRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBYUQ7SUFacEI7OztPQUdHO0lBQ0ksU0FBUyxDQUEyQztJQUUzRDs7O09BR0c7SUFDSyxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7SUFFaEUsWUFBb0IsT0FBeUI7UUFBekIsWUFBTyxHQUFQLE9BQU8sQ0FBa0I7SUFBRyxDQUFDO0lBRWpELDZFQUE2RTtJQUM3RSxZQUFZO0lBQ1osNkVBQTZFO0lBRTdFOzs7T0FHRztJQUNJLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDM0MsTUFBTSxJQUFJLENBQUMsZ0NBQWdDLEVBQUUsQ0FBQztJQUNoRCxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUk7UUFDZixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQzdCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksS0FBSyxDQUFDLGVBQWUsQ0FBQyxTQUFrRDtRQUM3RSxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixNQUFNLElBQUksQ0FBQywrQkFBK0IsRUFBRSxDQUFDO0lBQy9DLENBQUM7SUFFRCw2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