@push.rocks/smartproxy 19.3.2 → 19.3.3

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 (313) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/forwarding/factory/forwarding-factory.js +29 -1
  3. package/dist_ts/http/index.d.ts +1 -3
  4. package/dist_ts/http/index.js +4 -10
  5. package/dist_ts/http/models/http-types.d.ts +4 -91
  6. package/dist_ts/http/models/http-types.js +5 -60
  7. package/dist_ts/http/router/proxy-router.d.ts +1 -1
  8. package/dist_ts/http/router/route-router.d.ts +1 -1
  9. package/dist_ts/index.d.ts +9 -7
  10. package/dist_ts/index.js +10 -7
  11. package/dist_ts/proxies/{network-proxy → http-proxy}/certificate-manager.d.ts +2 -2
  12. package/dist_ts/proxies/{network-proxy → http-proxy}/certificate-manager.js +1 -1
  13. package/dist_ts/proxies/{network-proxy → http-proxy}/connection-pool.d.ts +2 -2
  14. package/dist_ts/proxies/http-proxy/connection-pool.js +210 -0
  15. package/dist_ts/proxies/http-proxy/context-creator.js +108 -0
  16. package/dist_ts/proxies/{network-proxy → http-proxy}/function-cache.js +1 -1
  17. package/dist_ts/proxies/http-proxy/handlers/index.d.ts +5 -0
  18. package/dist_ts/proxies/http-proxy/handlers/index.js +6 -0
  19. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.d.ts +18 -0
  20. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.js +78 -0
  21. package/dist_ts/proxies/http-proxy/handlers/static-handler.d.ts +19 -0
  22. package/dist_ts/proxies/http-proxy/handlers/static-handler.js +203 -0
  23. package/dist_ts/proxies/{network-proxy/network-proxy.d.ts → http-proxy/http-proxy.d.ts} +10 -9
  24. package/dist_ts/proxies/{network-proxy/network-proxy.js → http-proxy/http-proxy.js} +13 -12
  25. package/dist_ts/proxies/{network-proxy → http-proxy}/http-request-handler.js +1 -1
  26. package/dist_ts/proxies/http-proxy/http2-request-handler.js +201 -0
  27. package/dist_ts/proxies/{network-proxy → http-proxy}/index.d.ts +2 -2
  28. package/dist_ts/proxies/http-proxy/index.js +12 -0
  29. package/dist_ts/proxies/http-proxy/models/http-types.d.ts +119 -0
  30. package/dist_ts/proxies/http-proxy/models/http-types.js +112 -0
  31. package/dist_ts/proxies/http-proxy/models/index.d.ts +5 -0
  32. package/dist_ts/proxies/http-proxy/models/index.js +6 -0
  33. package/dist_ts/proxies/{network-proxy → http-proxy}/models/types.d.ts +2 -2
  34. package/dist_ts/proxies/http-proxy/models/types.js +276 -0
  35. package/dist_ts/proxies/{network-proxy → http-proxy}/request-handler.d.ts +3 -3
  36. package/dist_ts/proxies/{network-proxy → http-proxy}/request-handler.js +2 -2
  37. package/dist_ts/proxies/http-proxy/security-manager.js +255 -0
  38. package/dist_ts/proxies/{network-proxy → http-proxy}/websocket-handler.d.ts +3 -3
  39. package/dist_ts/proxies/{network-proxy → http-proxy}/websocket-handler.js +2 -2
  40. package/dist_ts/proxies/index.d.ts +5 -5
  41. package/dist_ts/proxies/index.js +5 -5
  42. package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +4 -4
  43. package/dist_ts/proxies/smart-proxy/certificate-manager.js +11 -11
  44. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +41 -0
  45. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +121 -0
  46. package/dist_ts/proxies/smart-proxy/index.d.ts +2 -1
  47. package/dist_ts/proxies/smart-proxy/index.js +4 -2
  48. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +2 -2
  49. package/dist_ts/proxies/smart-proxy/port-manager.js +3 -3
  50. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +3 -3
  51. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +24 -265
  52. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +1 -1
  53. package/dist_ts/proxies/smart-proxy/smart-proxy.js +25 -25
  54. package/dist_ts/routing/index.d.ts +5 -0
  55. package/dist_ts/routing/index.js +8 -0
  56. package/dist_ts/routing/models/http-types.d.ts +6 -0
  57. package/dist_ts/routing/models/http-types.js +7 -0
  58. package/dist_ts/routing/router/index.d.ts +8 -0
  59. package/dist_ts/routing/router/index.js +7 -0
  60. package/dist_ts/{classes.router.d.ts → routing/router/proxy-router.d.ts} +14 -11
  61. package/dist_ts/{classes.router.js → routing/router/proxy-router.js} +2 -2
  62. package/dist_ts/routing/router/route-router.d.ts +108 -0
  63. package/dist_ts/routing/router/route-router.js +393 -0
  64. package/package.json +1 -1
  65. package/readme.md +12 -12
  66. package/readme.plan.md +152 -257
  67. package/ts/00_commitinfo_data.ts +1 -1
  68. package/ts/forwarding/factory/forwarding-factory.ts +28 -0
  69. package/ts/index.ts +13 -9
  70. package/ts/proxies/{network-proxy → http-proxy}/certificate-manager.ts +2 -2
  71. package/ts/proxies/{network-proxy → http-proxy}/connection-pool.ts +2 -2
  72. package/ts/proxies/http-proxy/handlers/index.ts +6 -0
  73. package/ts/proxies/http-proxy/handlers/redirect-handler.ts +105 -0
  74. package/ts/proxies/http-proxy/handlers/static-handler.ts +251 -0
  75. package/ts/proxies/{network-proxy/network-proxy.ts → http-proxy/http-proxy.ts} +15 -14
  76. package/ts/proxies/{network-proxy → http-proxy}/index.ts +3 -3
  77. package/ts/proxies/http-proxy/models/http-types.ts +165 -0
  78. package/ts/proxies/http-proxy/models/index.ts +5 -0
  79. package/ts/proxies/{network-proxy → http-proxy}/models/types.ts +2 -2
  80. package/ts/proxies/{network-proxy → http-proxy}/request-handler.ts +3 -3
  81. package/ts/proxies/{network-proxy → http-proxy}/websocket-handler.ts +3 -3
  82. package/ts/proxies/index.ts +7 -7
  83. package/ts/proxies/smart-proxy/certificate-manager.ts +10 -10
  84. package/ts/proxies/smart-proxy/{network-proxy-bridge.ts → http-proxy-bridge.ts} +44 -44
  85. package/ts/proxies/smart-proxy/index.ts +4 -1
  86. package/ts/proxies/smart-proxy/models/interfaces.ts +3 -3
  87. package/ts/proxies/smart-proxy/port-manager.ts +2 -2
  88. package/ts/proxies/smart-proxy/route-connection-handler.ts +23 -307
  89. package/ts/proxies/smart-proxy/smart-proxy.ts +25 -25
  90. package/ts/routing/index.ts +9 -0
  91. package/ts/routing/models/http-types.ts +6 -0
  92. package/ts/{http → routing}/router/proxy-router.ts +1 -1
  93. package/ts/{http → routing}/router/route-router.ts +1 -1
  94. package/dist_ts/certificate/acme/acme-factory.d.ts +0 -17
  95. package/dist_ts/certificate/acme/acme-factory.js +0 -40
  96. package/dist_ts/certificate/acme/challenge-handler.d.ts +0 -44
  97. package/dist_ts/certificate/acme/challenge-handler.js +0 -92
  98. package/dist_ts/certificate/acme/index.d.ts +0 -4
  99. package/dist_ts/certificate/acme/index.js +0 -5
  100. package/dist_ts/certificate/certificate-manager.d.ts +0 -150
  101. package/dist_ts/certificate/certificate-manager.js +0 -505
  102. package/dist_ts/certificate/events/certificate-events.d.ts +0 -33
  103. package/dist_ts/certificate/events/certificate-events.js +0 -38
  104. package/dist_ts/certificate/events/simplified-events.d.ts +0 -56
  105. package/dist_ts/certificate/events/simplified-events.js +0 -13
  106. package/dist_ts/certificate/index.d.ts +0 -30
  107. package/dist_ts/certificate/index.js +0 -37
  108. package/dist_ts/certificate/models/certificate-errors.d.ts +0 -69
  109. package/dist_ts/certificate/models/certificate-errors.js +0 -141
  110. package/dist_ts/certificate/models/certificate-strategy.d.ts +0 -60
  111. package/dist_ts/certificate/models/certificate-strategy.js +0 -73
  112. package/dist_ts/certificate/models/certificate-types.d.ts +0 -97
  113. package/dist_ts/certificate/models/certificate-types.js +0 -2
  114. package/dist_ts/certificate/providers/cert-provisioner.d.ts +0 -119
  115. package/dist_ts/certificate/providers/cert-provisioner.js +0 -422
  116. package/dist_ts/certificate/providers/index.d.ts +0 -4
  117. package/dist_ts/certificate/providers/index.js +0 -5
  118. package/dist_ts/certificate/simplified-certificate-manager.d.ts +0 -150
  119. package/dist_ts/certificate/simplified-certificate-manager.js +0 -501
  120. package/dist_ts/certificate/storage/file-storage.d.ts +0 -66
  121. package/dist_ts/certificate/storage/file-storage.js +0 -194
  122. package/dist_ts/certificate/storage/index.d.ts +0 -4
  123. package/dist_ts/certificate/storage/index.js +0 -5
  124. package/dist_ts/certificate/utils/certificate-helpers.d.ts +0 -17
  125. package/dist_ts/certificate/utils/certificate-helpers.js +0 -45
  126. package/dist_ts/classes.iptablesproxy.d.ts +0 -112
  127. package/dist_ts/classes.iptablesproxy.js +0 -765
  128. package/dist_ts/classes.networkproxy.d.ts +0 -243
  129. package/dist_ts/classes.networkproxy.js +0 -1424
  130. package/dist_ts/classes.nftablesproxy.d.ts +0 -219
  131. package/dist_ts/classes.nftablesproxy.js +0 -1542
  132. package/dist_ts/classes.port80handler.d.ts +0 -215
  133. package/dist_ts/classes.port80handler.js +0 -736
  134. package/dist_ts/classes.portproxy.d.ts +0 -171
  135. package/dist_ts/classes.portproxy.js +0 -1802
  136. package/dist_ts/classes.pp.acmemanager.d.ts +0 -34
  137. package/dist_ts/classes.pp.acmemanager.js +0 -123
  138. package/dist_ts/classes.pp.connectionhandler.d.ts +0 -39
  139. package/dist_ts/classes.pp.connectionhandler.js +0 -754
  140. package/dist_ts/classes.pp.connectionmanager.d.ts +0 -78
  141. package/dist_ts/classes.pp.connectionmanager.js +0 -378
  142. package/dist_ts/classes.pp.domainconfigmanager.d.ts +0 -55
  143. package/dist_ts/classes.pp.domainconfigmanager.js +0 -103
  144. package/dist_ts/classes.pp.interfaces.d.ts +0 -133
  145. package/dist_ts/classes.pp.interfaces.js +0 -2
  146. package/dist_ts/classes.pp.networkproxybridge.d.ts +0 -57
  147. package/dist_ts/classes.pp.networkproxybridge.js +0 -306
  148. package/dist_ts/classes.pp.portproxy.d.ts +0 -64
  149. package/dist_ts/classes.pp.portproxy.js +0 -567
  150. package/dist_ts/classes.pp.portrangemanager.d.ts +0 -56
  151. package/dist_ts/classes.pp.portrangemanager.js +0 -179
  152. package/dist_ts/classes.pp.securitymanager.d.ts +0 -47
  153. package/dist_ts/classes.pp.securitymanager.js +0 -126
  154. package/dist_ts/classes.pp.snihandler.d.ts +0 -153
  155. package/dist_ts/classes.pp.snihandler.js +0 -1053
  156. package/dist_ts/classes.pp.timeoutmanager.d.ts +0 -47
  157. package/dist_ts/classes.pp.timeoutmanager.js +0 -154
  158. package/dist_ts/classes.pp.tlsalert.d.ts +0 -149
  159. package/dist_ts/classes.pp.tlsalert.js +0 -225
  160. package/dist_ts/classes.pp.tlsmanager.d.ts +0 -57
  161. package/dist_ts/classes.pp.tlsmanager.js +0 -132
  162. package/dist_ts/classes.snihandler.d.ts +0 -198
  163. package/dist_ts/classes.snihandler.js +0 -1210
  164. package/dist_ts/classes.sslredirect.d.ts +0 -8
  165. package/dist_ts/classes.sslredirect.js +0 -28
  166. package/dist_ts/common/acmeFactory.d.ts +0 -9
  167. package/dist_ts/common/acmeFactory.js +0 -20
  168. package/dist_ts/common/port80-adapter.d.ts +0 -11
  169. package/dist_ts/common/port80-adapter.js +0 -87
  170. package/dist_ts/examples/forwarding-example.d.ts +0 -1
  171. package/dist_ts/examples/forwarding-example.js +0 -96
  172. package/dist_ts/forwarding/config/domain-config.d.ts +0 -12
  173. package/dist_ts/forwarding/config/domain-config.js +0 -12
  174. package/dist_ts/forwarding/config/domain-manager.d.ts +0 -86
  175. package/dist_ts/forwarding/config/domain-manager.js +0 -242
  176. package/dist_ts/helpers.certificates.d.ts +0 -5
  177. package/dist_ts/helpers.certificates.js +0 -23
  178. package/dist_ts/http/port80/acme-interfaces.d.ts +0 -108
  179. package/dist_ts/http/port80/acme-interfaces.js +0 -51
  180. package/dist_ts/http/port80/challenge-responder.d.ts +0 -53
  181. package/dist_ts/http/port80/challenge-responder.js +0 -203
  182. package/dist_ts/http/port80/index.d.ts +0 -6
  183. package/dist_ts/http/port80/index.js +0 -9
  184. package/dist_ts/http/port80/port80-handler.d.ts +0 -136
  185. package/dist_ts/http/port80/port80-handler.js +0 -592
  186. package/dist_ts/http/redirects/index.d.ts +0 -4
  187. package/dist_ts/http/redirects/index.js +0 -5
  188. package/dist_ts/networkproxy/classes.np.certificatemanager.d.ts +0 -77
  189. package/dist_ts/networkproxy/classes.np.certificatemanager.js +0 -372
  190. package/dist_ts/networkproxy/classes.np.connectionpool.d.ts +0 -47
  191. package/dist_ts/networkproxy/classes.np.connectionpool.js +0 -210
  192. package/dist_ts/networkproxy/classes.np.networkproxy.d.ts +0 -118
  193. package/dist_ts/networkproxy/classes.np.networkproxy.js +0 -387
  194. package/dist_ts/networkproxy/classes.np.requesthandler.d.ts +0 -56
  195. package/dist_ts/networkproxy/classes.np.requesthandler.js +0 -393
  196. package/dist_ts/networkproxy/classes.np.types.d.ts +0 -83
  197. package/dist_ts/networkproxy/classes.np.types.js +0 -35
  198. package/dist_ts/networkproxy/classes.np.websockethandler.d.ts +0 -38
  199. package/dist_ts/networkproxy/classes.np.websockethandler.js +0 -188
  200. package/dist_ts/networkproxy/index.d.ts +0 -1
  201. package/dist_ts/networkproxy/index.js +0 -4
  202. package/dist_ts/nfttablesproxy/classes.nftablesproxy.d.ts +0 -219
  203. package/dist_ts/nfttablesproxy/classes.nftablesproxy.js +0 -1542
  204. package/dist_ts/port80handler/classes.port80handler.d.ts +0 -10
  205. package/dist_ts/port80handler/classes.port80handler.js +0 -16
  206. package/dist_ts/proxies/network-proxy/connection-pool.js +0 -210
  207. package/dist_ts/proxies/network-proxy/context-creator.js +0 -108
  208. package/dist_ts/proxies/network-proxy/http2-request-handler.js +0 -201
  209. package/dist_ts/proxies/network-proxy/index.js +0 -12
  210. package/dist_ts/proxies/network-proxy/models/index.d.ts +0 -4
  211. package/dist_ts/proxies/network-proxy/models/index.js +0 -5
  212. package/dist_ts/proxies/network-proxy/models/types.js +0 -276
  213. package/dist_ts/proxies/network-proxy/security-manager.js +0 -255
  214. package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.d.ts +0 -48
  215. package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.js +0 -76
  216. package/dist_ts/proxies/smart-proxy/connection-handler.d.ts +0 -39
  217. package/dist_ts/proxies/smart-proxy/connection-handler.js +0 -894
  218. package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +0 -110
  219. package/dist_ts/proxies/smart-proxy/domain-config-manager.js +0 -386
  220. package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.d.ts +0 -168
  221. package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.js +0 -642
  222. package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.d.ts +0 -65
  223. package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.js +0 -31
  224. package/dist_ts/proxies/smart-proxy/models/smartproxy-options.d.ts +0 -102
  225. package/dist_ts/proxies/smart-proxy/models/smartproxy-options.js +0 -73
  226. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +0 -41
  227. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +0 -121
  228. package/dist_ts/proxies/smart-proxy/port-range-manager.d.ts +0 -56
  229. package/dist_ts/proxies/smart-proxy/port-range-manager.js +0 -176
  230. package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +0 -9
  231. package/dist_ts/proxies/smart-proxy/route-helpers/index.js +0 -11
  232. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +0 -7
  233. package/dist_ts/proxies/smart-proxy/route-helpers.js +0 -9
  234. package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.d.ts +0 -41
  235. package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.js +0 -132
  236. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.d.ts +0 -51
  237. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.js +0 -124
  238. package/dist_ts/redirect/classes.redirect.d.ts +0 -96
  239. package/dist_ts/redirect/classes.redirect.js +0 -194
  240. package/dist_ts/smartproxy/classes.pp.certprovisioner.d.ts +0 -54
  241. package/dist_ts/smartproxy/classes.pp.certprovisioner.js +0 -179
  242. package/dist_ts/smartproxy/classes.pp.connectionhandler.d.ts +0 -39
  243. package/dist_ts/smartproxy/classes.pp.connectionhandler.js +0 -894
  244. package/dist_ts/smartproxy/classes.pp.connectionmanager.d.ts +0 -78
  245. package/dist_ts/smartproxy/classes.pp.connectionmanager.js +0 -378
  246. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.d.ts +0 -94
  247. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.js +0 -255
  248. package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +0 -103
  249. package/dist_ts/smartproxy/classes.pp.interfaces.js +0 -2
  250. package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +0 -62
  251. package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +0 -316
  252. package/dist_ts/smartproxy/classes.pp.portrangemanager.d.ts +0 -56
  253. package/dist_ts/smartproxy/classes.pp.portrangemanager.js +0 -176
  254. package/dist_ts/smartproxy/classes.pp.securitymanager.d.ts +0 -64
  255. package/dist_ts/smartproxy/classes.pp.securitymanager.js +0 -149
  256. package/dist_ts/smartproxy/classes.pp.snihandler.d.ts +0 -153
  257. package/dist_ts/smartproxy/classes.pp.snihandler.js +0 -1053
  258. package/dist_ts/smartproxy/classes.pp.timeoutmanager.d.ts +0 -47
  259. package/dist_ts/smartproxy/classes.pp.timeoutmanager.js +0 -154
  260. package/dist_ts/smartproxy/classes.pp.tlsalert.d.ts +0 -149
  261. package/dist_ts/smartproxy/classes.pp.tlsalert.js +0 -225
  262. package/dist_ts/smartproxy/classes.pp.tlsmanager.d.ts +0 -57
  263. package/dist_ts/smartproxy/classes.pp.tlsmanager.js +0 -132
  264. package/dist_ts/smartproxy/classes.smartproxy.d.ts +0 -63
  265. package/dist_ts/smartproxy/classes.smartproxy.js +0 -521
  266. package/dist_ts/smartproxy/forwarding/domain-config.d.ts +0 -12
  267. package/dist_ts/smartproxy/forwarding/domain-config.js +0 -12
  268. package/dist_ts/smartproxy/forwarding/domain-manager.d.ts +0 -86
  269. package/dist_ts/smartproxy/forwarding/domain-manager.js +0 -241
  270. package/dist_ts/smartproxy/forwarding/forwarding.factory.d.ts +0 -24
  271. package/dist_ts/smartproxy/forwarding/forwarding.factory.js +0 -137
  272. package/dist_ts/smartproxy/forwarding/forwarding.handler.d.ts +0 -55
  273. package/dist_ts/smartproxy/forwarding/forwarding.handler.js +0 -94
  274. package/dist_ts/smartproxy/forwarding/http.handler.d.ts +0 -25
  275. package/dist_ts/smartproxy/forwarding/http.handler.js +0 -123
  276. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.d.ts +0 -24
  277. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.js +0 -154
  278. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.d.ts +0 -36
  279. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.js +0 -229
  280. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.d.ts +0 -35
  281. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.js +0 -254
  282. package/dist_ts/smartproxy/forwarding/index.d.ts +0 -16
  283. package/dist_ts/smartproxy/forwarding/index.js +0 -23
  284. package/dist_ts/smartproxy/types/forwarding.types.d.ts +0 -104
  285. package/dist_ts/smartproxy/types/forwarding.types.js +0 -50
  286. package/dist_ts/smartproxy.classes.networkproxy.d.ts +0 -31
  287. package/dist_ts/smartproxy.classes.networkproxy.js +0 -305
  288. package/dist_ts/smartproxy.classes.router.d.ts +0 -13
  289. package/dist_ts/smartproxy.classes.router.js +0 -33
  290. package/dist_ts/smartproxy.classes.sslredirect.d.ts +0 -8
  291. package/dist_ts/smartproxy.classes.sslredirect.js +0 -28
  292. package/dist_ts/smartproxy.helpers.certificates.d.ts +0 -5
  293. package/dist_ts/smartproxy.helpers.certificates.js +0 -23
  294. package/dist_ts/smartproxy.plugins.d.ts +0 -18
  295. package/dist_ts/smartproxy.plugins.js +0 -23
  296. package/dist_ts/smartproxy.portproxy.d.ts +0 -26
  297. package/dist_ts/smartproxy.portproxy.js +0 -295
  298. package/ts/http/index.ts +0 -16
  299. package/ts/http/models/http-types.ts +0 -108
  300. package/ts/http/redirects/index.ts +0 -3
  301. package/ts/proxies/network-proxy/models/index.ts +0 -4
  302. package/ts/redirect/classes.redirect.ts +0 -295
  303. /package/dist_ts/proxies/{network-proxy → http-proxy}/context-creator.d.ts +0 -0
  304. /package/dist_ts/proxies/{network-proxy → http-proxy}/function-cache.d.ts +0 -0
  305. /package/dist_ts/proxies/{network-proxy → http-proxy}/http-request-handler.d.ts +0 -0
  306. /package/dist_ts/proxies/{network-proxy → http-proxy}/http2-request-handler.d.ts +0 -0
  307. /package/dist_ts/proxies/{network-proxy → http-proxy}/security-manager.d.ts +0 -0
  308. /package/ts/proxies/{network-proxy → http-proxy}/context-creator.ts +0 -0
  309. /package/ts/proxies/{network-proxy → http-proxy}/function-cache.ts +0 -0
  310. /package/ts/proxies/{network-proxy → http-proxy}/http-request-handler.ts +0 -0
  311. /package/ts/proxies/{network-proxy → http-proxy}/http2-request-handler.ts +0 -0
  312. /package/ts/proxies/{network-proxy → http-proxy}/security-manager.ts +0 -0
  313. /package/ts/{http → routing}/router/index.ts +0 -0
@@ -1,736 +0,0 @@
1
- import * as plugins from './plugins.js';
2
- import { IncomingMessage, ServerResponse } from 'http';
3
- /**
4
- * Custom error classes for better error handling
5
- */
6
- export class Port80HandlerError extends Error {
7
- constructor(message) {
8
- super(message);
9
- this.name = 'Port80HandlerError';
10
- }
11
- }
12
- export class CertificateError extends Port80HandlerError {
13
- constructor(message, domain, isRenewal = false) {
14
- super(`${message} for domain ${domain}${isRenewal ? ' (renewal)' : ''}`);
15
- this.domain = domain;
16
- this.isRenewal = isRenewal;
17
- this.name = 'CertificateError';
18
- }
19
- }
20
- export class ServerError extends Port80HandlerError {
21
- constructor(message, code) {
22
- super(message);
23
- this.code = code;
24
- this.name = 'ServerError';
25
- }
26
- }
27
- /**
28
- * Events emitted by the Port80Handler
29
- */
30
- export var Port80HandlerEvents;
31
- (function (Port80HandlerEvents) {
32
- Port80HandlerEvents["CERTIFICATE_ISSUED"] = "certificate-issued";
33
- Port80HandlerEvents["CERTIFICATE_RENEWED"] = "certificate-renewed";
34
- Port80HandlerEvents["CERTIFICATE_FAILED"] = "certificate-failed";
35
- Port80HandlerEvents["CERTIFICATE_EXPIRING"] = "certificate-expiring";
36
- Port80HandlerEvents["MANAGER_STARTED"] = "manager-started";
37
- Port80HandlerEvents["MANAGER_STOPPED"] = "manager-stopped";
38
- Port80HandlerEvents["REQUEST_FORWARDED"] = "request-forwarded";
39
- })(Port80HandlerEvents || (Port80HandlerEvents = {}));
40
- /**
41
- * Port80Handler with ACME certificate management and request forwarding capabilities
42
- * Now with glob pattern support for domain matching
43
- */
44
- export class Port80Handler extends plugins.EventEmitter {
45
- /**
46
- * Creates a new Port80Handler
47
- * @param options Configuration options
48
- */
49
- constructor(options = {}) {
50
- super();
51
- this.server = null;
52
- this.acmeClient = null;
53
- this.accountKey = null;
54
- this.renewalTimer = null;
55
- this.isShuttingDown = false;
56
- this.domainCertificates = new Map();
57
- // Default options
58
- this.options = {
59
- port: options.port ?? 80,
60
- contactEmail: options.contactEmail ?? 'admin@example.com',
61
- useProduction: options.useProduction ?? false, // Safer default: staging
62
- renewThresholdDays: options.renewThresholdDays ?? 10, // Changed to 10 days as per requirements
63
- httpsRedirectPort: options.httpsRedirectPort ?? 443,
64
- renewCheckIntervalHours: options.renewCheckIntervalHours ?? 24,
65
- };
66
- }
67
- /**
68
- * Starts the HTTP server for ACME challenges
69
- */
70
- async start() {
71
- if (this.server) {
72
- throw new ServerError('Server is already running');
73
- }
74
- if (this.isShuttingDown) {
75
- throw new ServerError('Server is shutting down');
76
- }
77
- return new Promise((resolve, reject) => {
78
- try {
79
- this.server = plugins.http.createServer((req, res) => this.handleRequest(req, res));
80
- this.server.on('error', (error) => {
81
- if (error.code === 'EACCES') {
82
- reject(new ServerError(`Permission denied to bind to port ${this.options.port}. Try running with elevated privileges or use a port > 1024.`, error.code));
83
- }
84
- else if (error.code === 'EADDRINUSE') {
85
- reject(new ServerError(`Port ${this.options.port} is already in use.`, error.code));
86
- }
87
- else {
88
- reject(new ServerError(error.message, error.code));
89
- }
90
- });
91
- this.server.listen(this.options.port, () => {
92
- console.log(`Port80Handler is listening on port ${this.options.port}`);
93
- this.startRenewalTimer();
94
- this.emit(Port80HandlerEvents.MANAGER_STARTED, this.options.port);
95
- // Start certificate process for domains with acmeMaintenance enabled
96
- for (const [domain, domainInfo] of this.domainCertificates.entries()) {
97
- // Skip glob patterns for certificate issuance
98
- if (this.isGlobPattern(domain)) {
99
- console.log(`Skipping initial certificate for glob pattern: ${domain}`);
100
- continue;
101
- }
102
- if (domainInfo.options.acmeMaintenance && !domainInfo.certObtained && !domainInfo.obtainingInProgress) {
103
- this.obtainCertificate(domain).catch(err => {
104
- console.error(`Error obtaining initial certificate for ${domain}:`, err);
105
- });
106
- }
107
- }
108
- resolve();
109
- });
110
- }
111
- catch (error) {
112
- const message = error instanceof Error ? error.message : 'Unknown error starting server';
113
- reject(new ServerError(message));
114
- }
115
- });
116
- }
117
- /**
118
- * Stops the HTTP server and renewal timer
119
- */
120
- async stop() {
121
- if (!this.server) {
122
- return;
123
- }
124
- this.isShuttingDown = true;
125
- // Stop the renewal timer
126
- if (this.renewalTimer) {
127
- clearInterval(this.renewalTimer);
128
- this.renewalTimer = null;
129
- }
130
- return new Promise((resolve) => {
131
- if (this.server) {
132
- this.server.close(() => {
133
- this.server = null;
134
- this.isShuttingDown = false;
135
- this.emit(Port80HandlerEvents.MANAGER_STOPPED);
136
- resolve();
137
- });
138
- }
139
- else {
140
- this.isShuttingDown = false;
141
- resolve();
142
- }
143
- });
144
- }
145
- /**
146
- * Adds a domain with configuration options
147
- * @param options Domain configuration options
148
- */
149
- addDomain(options) {
150
- if (!options.domainName || typeof options.domainName !== 'string') {
151
- throw new Port80HandlerError('Invalid domain name');
152
- }
153
- const domainName = options.domainName;
154
- if (!this.domainCertificates.has(domainName)) {
155
- this.domainCertificates.set(domainName, {
156
- options,
157
- certObtained: false,
158
- obtainingInProgress: false
159
- });
160
- console.log(`Domain added: ${domainName} with configuration:`, {
161
- sslRedirect: options.sslRedirect,
162
- acmeMaintenance: options.acmeMaintenance,
163
- hasForward: !!options.forward,
164
- hasAcmeForward: !!options.acmeForward
165
- });
166
- // If acmeMaintenance is enabled and not a glob pattern, start certificate process immediately
167
- if (options.acmeMaintenance && this.server && !this.isGlobPattern(domainName)) {
168
- this.obtainCertificate(domainName).catch(err => {
169
- console.error(`Error obtaining initial certificate for ${domainName}:`, err);
170
- });
171
- }
172
- }
173
- else {
174
- // Update existing domain with new options
175
- const existing = this.domainCertificates.get(domainName);
176
- existing.options = options;
177
- console.log(`Domain ${domainName} configuration updated`);
178
- }
179
- }
180
- /**
181
- * Removes a domain from management
182
- * @param domain The domain to remove
183
- */
184
- removeDomain(domain) {
185
- if (this.domainCertificates.delete(domain)) {
186
- console.log(`Domain removed: ${domain}`);
187
- }
188
- }
189
- /**
190
- * Sets a certificate for a domain directly (for externally obtained certificates)
191
- * @param domain The domain for the certificate
192
- * @param certificate The certificate (PEM format)
193
- * @param privateKey The private key (PEM format)
194
- * @param expiryDate Optional expiry date
195
- */
196
- setCertificate(domain, certificate, privateKey, expiryDate) {
197
- if (!domain || !certificate || !privateKey) {
198
- throw new Port80HandlerError('Domain, certificate and privateKey are required');
199
- }
200
- // Don't allow setting certificates for glob patterns
201
- if (this.isGlobPattern(domain)) {
202
- throw new Port80HandlerError('Cannot set certificate for glob pattern domains');
203
- }
204
- let domainInfo = this.domainCertificates.get(domain);
205
- if (!domainInfo) {
206
- // Create default domain options if not already configured
207
- const defaultOptions = {
208
- domainName: domain,
209
- sslRedirect: true,
210
- acmeMaintenance: true
211
- };
212
- domainInfo = {
213
- options: defaultOptions,
214
- certObtained: false,
215
- obtainingInProgress: false
216
- };
217
- this.domainCertificates.set(domain, domainInfo);
218
- }
219
- domainInfo.certificate = certificate;
220
- domainInfo.privateKey = privateKey;
221
- domainInfo.certObtained = true;
222
- domainInfo.obtainingInProgress = false;
223
- if (expiryDate) {
224
- domainInfo.expiryDate = expiryDate;
225
- }
226
- else {
227
- // Extract expiry date from certificate
228
- domainInfo.expiryDate = this.extractExpiryDateFromCertificate(certificate, domain);
229
- }
230
- console.log(`Certificate set for ${domain}`);
231
- // Emit certificate event
232
- this.emitCertificateEvent(Port80HandlerEvents.CERTIFICATE_ISSUED, {
233
- domain,
234
- certificate,
235
- privateKey,
236
- expiryDate: domainInfo.expiryDate || this.getDefaultExpiryDate()
237
- });
238
- }
239
- /**
240
- * Gets the certificate for a domain if it exists
241
- * @param domain The domain to get the certificate for
242
- */
243
- getCertificate(domain) {
244
- // Can't get certificates for glob patterns
245
- if (this.isGlobPattern(domain)) {
246
- return null;
247
- }
248
- const domainInfo = this.domainCertificates.get(domain);
249
- if (!domainInfo || !domainInfo.certObtained || !domainInfo.certificate || !domainInfo.privateKey) {
250
- return null;
251
- }
252
- return {
253
- domain,
254
- certificate: domainInfo.certificate,
255
- privateKey: domainInfo.privateKey,
256
- expiryDate: domainInfo.expiryDate || this.getDefaultExpiryDate()
257
- };
258
- }
259
- /**
260
- * Check if a domain is a glob pattern
261
- * @param domain Domain to check
262
- * @returns True if the domain is a glob pattern
263
- */
264
- isGlobPattern(domain) {
265
- return domain.includes('*');
266
- }
267
- /**
268
- * Get domain info for a specific domain, using glob pattern matching if needed
269
- * @param requestDomain The actual domain from the request
270
- * @returns The domain info or null if not found
271
- */
272
- getDomainInfoForRequest(requestDomain) {
273
- // Try direct match first
274
- if (this.domainCertificates.has(requestDomain)) {
275
- return {
276
- domainInfo: this.domainCertificates.get(requestDomain),
277
- pattern: requestDomain
278
- };
279
- }
280
- // Then try glob patterns
281
- for (const [pattern, domainInfo] of this.domainCertificates.entries()) {
282
- if (this.isGlobPattern(pattern) && this.domainMatchesPattern(requestDomain, pattern)) {
283
- return { domainInfo, pattern };
284
- }
285
- }
286
- return null;
287
- }
288
- /**
289
- * Check if a domain matches a glob pattern
290
- * @param domain The domain to check
291
- * @param pattern The pattern to match against
292
- * @returns True if the domain matches the pattern
293
- */
294
- domainMatchesPattern(domain, pattern) {
295
- // Handle different glob pattern styles
296
- if (pattern.startsWith('*.')) {
297
- // *.example.com matches any subdomain
298
- const suffix = pattern.substring(2);
299
- return domain.endsWith(suffix) && domain.includes('.') && domain !== suffix;
300
- }
301
- else if (pattern.endsWith('.*')) {
302
- // example.* matches any TLD
303
- const prefix = pattern.substring(0, pattern.length - 2);
304
- const domainParts = domain.split('.');
305
- return domain.startsWith(prefix + '.') && domainParts.length >= 2;
306
- }
307
- else if (pattern === '*') {
308
- // Wildcard matches everything
309
- return true;
310
- }
311
- else {
312
- // Exact match (shouldn't reach here as we check exact matches first)
313
- return domain === pattern;
314
- }
315
- }
316
- /**
317
- * Lazy initialization of the ACME client
318
- * @returns An ACME client instance
319
- */
320
- async getAcmeClient() {
321
- if (this.acmeClient) {
322
- return this.acmeClient;
323
- }
324
- try {
325
- // Generate a new account key
326
- this.accountKey = (await plugins.acme.forge.createPrivateKey()).toString();
327
- this.acmeClient = new plugins.acme.Client({
328
- directoryUrl: this.options.useProduction
329
- ? plugins.acme.directory.letsencrypt.production
330
- : plugins.acme.directory.letsencrypt.staging,
331
- accountKey: this.accountKey,
332
- });
333
- // Create a new account
334
- await this.acmeClient.createAccount({
335
- termsOfServiceAgreed: true,
336
- contact: [`mailto:${this.options.contactEmail}`],
337
- });
338
- return this.acmeClient;
339
- }
340
- catch (error) {
341
- const message = error instanceof Error ? error.message : 'Unknown error initializing ACME client';
342
- throw new Port80HandlerError(`Failed to initialize ACME client: ${message}`);
343
- }
344
- }
345
- /**
346
- * Handles incoming HTTP requests
347
- * @param req The HTTP request
348
- * @param res The HTTP response
349
- */
350
- handleRequest(req, res) {
351
- const hostHeader = req.headers.host;
352
- if (!hostHeader) {
353
- res.statusCode = 400;
354
- res.end('Bad Request: Host header is missing');
355
- return;
356
- }
357
- // Extract domain (ignoring any port in the Host header)
358
- const domain = hostHeader.split(':')[0];
359
- // Get domain config, using glob pattern matching if needed
360
- const domainMatch = this.getDomainInfoForRequest(domain);
361
- if (!domainMatch) {
362
- res.statusCode = 404;
363
- res.end('Domain not configured');
364
- return;
365
- }
366
- const { domainInfo, pattern } = domainMatch;
367
- const options = domainInfo.options;
368
- // If the request is for an ACME HTTP-01 challenge, handle it
369
- if (req.url && req.url.startsWith('/.well-known/acme-challenge/') && (options.acmeMaintenance || options.acmeForward)) {
370
- // Check if we should forward ACME requests
371
- if (options.acmeForward) {
372
- this.forwardRequest(req, res, options.acmeForward, 'ACME challenge');
373
- return;
374
- }
375
- // Only handle ACME challenges for non-glob patterns
376
- if (!this.isGlobPattern(pattern)) {
377
- this.handleAcmeChallenge(req, res, domain);
378
- return;
379
- }
380
- }
381
- // Check if we should forward non-ACME requests
382
- if (options.forward) {
383
- this.forwardRequest(req, res, options.forward, 'HTTP');
384
- return;
385
- }
386
- // If certificate exists and sslRedirect is enabled, redirect to HTTPS
387
- // (Skip for glob patterns as they won't have certificates)
388
- if (!this.isGlobPattern(pattern) && domainInfo.certObtained && options.sslRedirect) {
389
- const httpsPort = this.options.httpsRedirectPort;
390
- const portSuffix = httpsPort === 443 ? '' : `:${httpsPort}`;
391
- const redirectUrl = `https://${domain}${portSuffix}${req.url || '/'}`;
392
- res.statusCode = 301;
393
- res.setHeader('Location', redirectUrl);
394
- res.end(`Redirecting to ${redirectUrl}`);
395
- return;
396
- }
397
- // Handle case where certificate maintenance is enabled but not yet obtained
398
- // (Skip for glob patterns as they can't have certificates)
399
- if (!this.isGlobPattern(pattern) && options.acmeMaintenance && !domainInfo.certObtained) {
400
- // Trigger certificate issuance if not already running
401
- if (!domainInfo.obtainingInProgress) {
402
- this.obtainCertificate(domain).catch(err => {
403
- const errorMessage = err instanceof Error ? err.message : 'Unknown error';
404
- this.emit(Port80HandlerEvents.CERTIFICATE_FAILED, {
405
- domain,
406
- error: errorMessage,
407
- isRenewal: false
408
- });
409
- console.error(`Error obtaining certificate for ${domain}:`, err);
410
- });
411
- }
412
- res.statusCode = 503;
413
- res.end('Certificate issuance in progress, please try again later.');
414
- return;
415
- }
416
- // Default response for unhandled request
417
- res.statusCode = 404;
418
- res.end('No handlers configured for this request');
419
- }
420
- /**
421
- * Forwards an HTTP request to the specified target
422
- * @param req The original request
423
- * @param res The response object
424
- * @param target The forwarding target (IP and port)
425
- * @param requestType Type of request for logging
426
- */
427
- forwardRequest(req, res, target, requestType) {
428
- const options = {
429
- hostname: target.ip,
430
- port: target.port,
431
- path: req.url,
432
- method: req.method,
433
- headers: { ...req.headers }
434
- };
435
- const domain = req.headers.host?.split(':')[0] || 'unknown';
436
- console.log(`Forwarding ${requestType} request for ${domain} to ${target.ip}:${target.port}`);
437
- const proxyReq = plugins.http.request(options, (proxyRes) => {
438
- // Copy status code
439
- res.statusCode = proxyRes.statusCode || 500;
440
- // Copy headers
441
- for (const [key, value] of Object.entries(proxyRes.headers)) {
442
- if (value)
443
- res.setHeader(key, value);
444
- }
445
- // Pipe response data
446
- proxyRes.pipe(res);
447
- this.emit(Port80HandlerEvents.REQUEST_FORWARDED, {
448
- domain,
449
- requestType,
450
- target: `${target.ip}:${target.port}`,
451
- statusCode: proxyRes.statusCode
452
- });
453
- });
454
- proxyReq.on('error', (error) => {
455
- console.error(`Error forwarding request to ${target.ip}:${target.port}:`, error);
456
- if (!res.headersSent) {
457
- res.statusCode = 502;
458
- res.end(`Proxy error: ${error.message}`);
459
- }
460
- else {
461
- res.end();
462
- }
463
- });
464
- // Pipe original request to proxy request
465
- if (req.readable) {
466
- req.pipe(proxyReq);
467
- }
468
- else {
469
- proxyReq.end();
470
- }
471
- }
472
- /**
473
- * Serves the ACME HTTP-01 challenge response
474
- * @param req The HTTP request
475
- * @param res The HTTP response
476
- * @param domain The domain for the challenge
477
- */
478
- handleAcmeChallenge(req, res, domain) {
479
- const domainInfo = this.domainCertificates.get(domain);
480
- if (!domainInfo) {
481
- res.statusCode = 404;
482
- res.end('Domain not configured');
483
- return;
484
- }
485
- // The token is the last part of the URL
486
- const urlParts = req.url?.split('/');
487
- const token = urlParts ? urlParts[urlParts.length - 1] : '';
488
- if (domainInfo.challengeToken === token && domainInfo.challengeKeyAuthorization) {
489
- res.statusCode = 200;
490
- res.setHeader('Content-Type', 'text/plain');
491
- res.end(domainInfo.challengeKeyAuthorization);
492
- console.log(`Served ACME challenge response for ${domain}`);
493
- }
494
- else {
495
- res.statusCode = 404;
496
- res.end('Challenge token not found');
497
- }
498
- }
499
- /**
500
- * Obtains a certificate for a domain using ACME HTTP-01 challenge
501
- * @param domain The domain to obtain a certificate for
502
- * @param isRenewal Whether this is a renewal attempt
503
- */
504
- async obtainCertificate(domain, isRenewal = false) {
505
- // Don't allow certificate issuance for glob patterns
506
- if (this.isGlobPattern(domain)) {
507
- throw new CertificateError('Cannot obtain certificates for glob pattern domains', domain, isRenewal);
508
- }
509
- // Get the domain info
510
- const domainInfo = this.domainCertificates.get(domain);
511
- if (!domainInfo) {
512
- throw new CertificateError('Domain not found', domain, isRenewal);
513
- }
514
- // Verify that acmeMaintenance is enabled
515
- if (!domainInfo.options.acmeMaintenance) {
516
- console.log(`Skipping certificate issuance for ${domain} - acmeMaintenance is disabled`);
517
- return;
518
- }
519
- // Prevent concurrent certificate issuance
520
- if (domainInfo.obtainingInProgress) {
521
- console.log(`Certificate issuance already in progress for ${domain}`);
522
- return;
523
- }
524
- domainInfo.obtainingInProgress = true;
525
- domainInfo.lastRenewalAttempt = new Date();
526
- try {
527
- const client = await this.getAcmeClient();
528
- // Create a new order for the domain
529
- const order = await client.createOrder({
530
- identifiers: [{ type: 'dns', value: domain }],
531
- });
532
- // Get the authorizations for the order
533
- const authorizations = await client.getAuthorizations(order);
534
- // Process each authorization
535
- await this.processAuthorizations(client, domain, authorizations);
536
- // Generate a CSR and private key
537
- const [csrBuffer, privateKeyBuffer] = await plugins.acme.forge.createCsr({
538
- commonName: domain,
539
- });
540
- const csr = csrBuffer.toString();
541
- const privateKey = privateKeyBuffer.toString();
542
- // Finalize the order with our CSR
543
- await client.finalizeOrder(order, csr);
544
- // Get the certificate with the full chain
545
- const certificate = await client.getCertificate(order);
546
- // Store the certificate and key
547
- domainInfo.certificate = certificate;
548
- domainInfo.privateKey = privateKey;
549
- domainInfo.certObtained = true;
550
- // Clear challenge data
551
- delete domainInfo.challengeToken;
552
- delete domainInfo.challengeKeyAuthorization;
553
- // Extract expiry date from certificate
554
- domainInfo.expiryDate = this.extractExpiryDateFromCertificate(certificate, domain);
555
- console.log(`Certificate ${isRenewal ? 'renewed' : 'obtained'} for ${domain}`);
556
- // Emit the appropriate event
557
- const eventType = isRenewal
558
- ? Port80HandlerEvents.CERTIFICATE_RENEWED
559
- : Port80HandlerEvents.CERTIFICATE_ISSUED;
560
- this.emitCertificateEvent(eventType, {
561
- domain,
562
- certificate,
563
- privateKey,
564
- expiryDate: domainInfo.expiryDate || this.getDefaultExpiryDate()
565
- });
566
- }
567
- catch (error) {
568
- // Check for rate limit errors
569
- if (error.message && (error.message.includes('rateLimited') ||
570
- error.message.includes('too many certificates') ||
571
- error.message.includes('rate limit'))) {
572
- console.error(`Rate limit reached for ${domain}. Waiting before retry.`);
573
- }
574
- else {
575
- console.error(`Error during certificate issuance for ${domain}:`, error);
576
- }
577
- // Emit failure event
578
- this.emit(Port80HandlerEvents.CERTIFICATE_FAILED, {
579
- domain,
580
- error: error.message || 'Unknown error',
581
- isRenewal
582
- });
583
- throw new CertificateError(error.message || 'Certificate issuance failed', domain, isRenewal);
584
- }
585
- finally {
586
- // Reset flag whether successful or not
587
- domainInfo.obtainingInProgress = false;
588
- }
589
- }
590
- /**
591
- * Process ACME authorizations by verifying and completing challenges
592
- * @param client ACME client
593
- * @param domain Domain name
594
- * @param authorizations Authorizations to process
595
- */
596
- async processAuthorizations(client, domain, authorizations) {
597
- const domainInfo = this.domainCertificates.get(domain);
598
- if (!domainInfo) {
599
- throw new CertificateError('Domain not found during authorization', domain);
600
- }
601
- for (const authz of authorizations) {
602
- const challenge = authz.challenges.find(ch => ch.type === 'http-01');
603
- if (!challenge) {
604
- throw new CertificateError('HTTP-01 challenge not found', domain);
605
- }
606
- // Get the key authorization for the challenge
607
- const keyAuthorization = await client.getChallengeKeyAuthorization(challenge);
608
- // Store the challenge data
609
- domainInfo.challengeToken = challenge.token;
610
- domainInfo.challengeKeyAuthorization = keyAuthorization;
611
- // ACME client type definition workaround - use compatible approach
612
- // First check if challenge verification is needed
613
- const authzUrl = authz.url;
614
- try {
615
- // Check if authzUrl exists and perform verification
616
- if (authzUrl) {
617
- await client.verifyChallenge(authz, challenge);
618
- }
619
- // Complete the challenge
620
- await client.completeChallenge(challenge);
621
- // Wait for validation
622
- await client.waitForValidStatus(challenge);
623
- console.log(`HTTP-01 challenge completed for ${domain}`);
624
- }
625
- catch (error) {
626
- const errorMessage = error instanceof Error ? error.message : 'Unknown challenge error';
627
- console.error(`Challenge error for ${domain}:`, error);
628
- throw new CertificateError(`Challenge verification failed: ${errorMessage}`, domain);
629
- }
630
- }
631
- }
632
- /**
633
- * Starts the certificate renewal timer
634
- */
635
- startRenewalTimer() {
636
- if (this.renewalTimer) {
637
- clearInterval(this.renewalTimer);
638
- }
639
- // Convert hours to milliseconds
640
- const checkInterval = this.options.renewCheckIntervalHours * 60 * 60 * 1000;
641
- this.renewalTimer = setInterval(() => this.checkForRenewals(), checkInterval);
642
- // Prevent the timer from keeping the process alive
643
- if (this.renewalTimer.unref) {
644
- this.renewalTimer.unref();
645
- }
646
- console.log(`Certificate renewal check scheduled every ${this.options.renewCheckIntervalHours} hours`);
647
- }
648
- /**
649
- * Checks for certificates that need renewal
650
- */
651
- checkForRenewals() {
652
- if (this.isShuttingDown) {
653
- return;
654
- }
655
- console.log('Checking for certificates that need renewal...');
656
- const now = new Date();
657
- const renewThresholdMs = this.options.renewThresholdDays * 24 * 60 * 60 * 1000;
658
- for (const [domain, domainInfo] of this.domainCertificates.entries()) {
659
- // Skip glob patterns
660
- if (this.isGlobPattern(domain)) {
661
- continue;
662
- }
663
- // Skip domains with acmeMaintenance disabled
664
- if (!domainInfo.options.acmeMaintenance) {
665
- continue;
666
- }
667
- // Skip domains without certificates or already in renewal
668
- if (!domainInfo.certObtained || domainInfo.obtainingInProgress) {
669
- continue;
670
- }
671
- // Skip domains without expiry dates
672
- if (!domainInfo.expiryDate) {
673
- continue;
674
- }
675
- const timeUntilExpiry = domainInfo.expiryDate.getTime() - now.getTime();
676
- // Check if certificate is near expiry
677
- if (timeUntilExpiry <= renewThresholdMs) {
678
- console.log(`Certificate for ${domain} expires soon, renewing...`);
679
- const daysRemaining = Math.ceil(timeUntilExpiry / (24 * 60 * 60 * 1000));
680
- this.emit(Port80HandlerEvents.CERTIFICATE_EXPIRING, {
681
- domain,
682
- expiryDate: domainInfo.expiryDate,
683
- daysRemaining
684
- });
685
- // Start renewal process
686
- this.obtainCertificate(domain, true).catch(err => {
687
- const errorMessage = err instanceof Error ? err.message : 'Unknown error';
688
- console.error(`Error renewing certificate for ${domain}:`, errorMessage);
689
- });
690
- }
691
- }
692
- }
693
- /**
694
- * Extract expiry date from certificate using a more robust approach
695
- * @param certificate Certificate PEM string
696
- * @param domain Domain for logging
697
- * @returns Extracted expiry date or default
698
- */
699
- extractExpiryDateFromCertificate(certificate, domain) {
700
- try {
701
- // This is still using regex, but in a real implementation you would use
702
- // a library like node-forge or x509 to properly parse the certificate
703
- const matches = certificate.match(/Not After\s*:\s*(.*?)(?:\n|$)/i);
704
- if (matches && matches[1]) {
705
- const expiryDate = new Date(matches[1]);
706
- // Validate that we got a valid date
707
- if (!isNaN(expiryDate.getTime())) {
708
- console.log(`Certificate for ${domain} will expire on ${expiryDate.toISOString()}`);
709
- return expiryDate;
710
- }
711
- }
712
- console.warn(`Could not extract valid expiry date from certificate for ${domain}, using default`);
713
- return this.getDefaultExpiryDate();
714
- }
715
- catch (error) {
716
- console.warn(`Failed to extract expiry date from certificate for ${domain}, using default`);
717
- return this.getDefaultExpiryDate();
718
- }
719
- }
720
- /**
721
- * Get a default expiry date (90 days from now)
722
- * @returns Default expiry date
723
- */
724
- getDefaultExpiryDate() {
725
- return new Date(Date.now() + 90 * 24 * 60 * 60 * 1000); // 90 days default
726
- }
727
- /**
728
- * Emits a certificate event with the certificate data
729
- * @param eventType The event type to emit
730
- * @param data The certificate data
731
- */
732
- emitCertificateEvent(eventType, data) {
733
- this.emit(eventType, data);
734
- }
735
- }
736
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wb3J0ODBoYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5wb3J0ODBoYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXZEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGtCQUFtQixTQUFRLEtBQUs7SUFDM0MsWUFBWSxPQUFlO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsb0JBQW9CLENBQUM7SUFDbkMsQ0FBQztDQUNGO0FBRUQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLGtCQUFrQjtJQUN0RCxZQUNFLE9BQWUsRUFDQyxNQUFjLEVBQ2QsWUFBcUIsS0FBSztRQUUxQyxLQUFLLENBQUMsR0FBRyxPQUFPLGVBQWUsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBSHpELFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxjQUFTLEdBQVQsU0FBUyxDQUFpQjtRQUcxQyxJQUFJLENBQUMsSUFBSSxHQUFHLGtCQUFrQixDQUFDO0lBQ2pDLENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxXQUFZLFNBQVEsa0JBQWtCO0lBQ2pELFlBQVksT0FBZSxFQUFrQixJQUFhO1FBQ3hELEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUQ0QixTQUFJLEdBQUosSUFBSSxDQUFTO1FBRXhELElBQUksQ0FBQyxJQUFJLEdBQUcsYUFBYSxDQUFDO0lBQzVCLENBQUM7Q0FDRjtBQTBERDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLG1CQVFYO0FBUkQsV0FBWSxtQkFBbUI7SUFDN0IsZ0VBQXlDLENBQUE7SUFDekMsa0VBQTJDLENB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