@push.rocks/smartproxy 12.0.0 → 13.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/certificate/acme/acme-factory.d.ts +17 -0
  3. package/dist_ts/certificate/acme/acme-factory.js +40 -0
  4. package/dist_ts/certificate/acme/challenge-handler.d.ts +44 -0
  5. package/dist_ts/certificate/acme/challenge-handler.js +92 -0
  6. package/dist_ts/certificate/acme/index.d.ts +4 -0
  7. package/dist_ts/certificate/acme/index.js +5 -0
  8. package/dist_ts/certificate/events/certificate-events.d.ts +33 -0
  9. package/dist_ts/certificate/events/certificate-events.js +38 -0
  10. package/dist_ts/certificate/index.d.ts +24 -0
  11. package/dist_ts/certificate/index.js +39 -0
  12. package/dist_ts/certificate/models/certificate-types.d.ts +77 -0
  13. package/dist_ts/certificate/models/certificate-types.js +2 -0
  14. package/dist_ts/certificate/providers/cert-provisioner.d.ts +93 -0
  15. package/dist_ts/certificate/providers/cert-provisioner.js +262 -0
  16. package/dist_ts/certificate/providers/index.d.ts +4 -0
  17. package/dist_ts/certificate/providers/index.js +5 -0
  18. package/dist_ts/certificate/storage/file-storage.d.ts +66 -0
  19. package/dist_ts/certificate/storage/file-storage.js +194 -0
  20. package/dist_ts/certificate/storage/index.d.ts +4 -0
  21. package/dist_ts/certificate/storage/index.js +5 -0
  22. package/dist_ts/certificate/utils/certificate-helpers.d.ts +17 -0
  23. package/dist_ts/certificate/utils/certificate-helpers.js +45 -0
  24. package/dist_ts/common/eventUtils.d.ts +1 -1
  25. package/dist_ts/common/port80-adapter.d.ts +1 -1
  26. package/dist_ts/core/events/index.d.ts +4 -0
  27. package/dist_ts/core/events/index.js +5 -0
  28. package/dist_ts/core/index.d.ts +6 -0
  29. package/dist_ts/core/index.js +8 -0
  30. package/dist_ts/core/models/common-types.d.ts +82 -0
  31. package/dist_ts/core/models/common-types.js +15 -0
  32. package/dist_ts/core/models/index.d.ts +4 -0
  33. package/dist_ts/core/models/index.js +5 -0
  34. package/dist_ts/core/utils/event-utils.d.ts +15 -0
  35. package/dist_ts/core/utils/event-utils.js +19 -0
  36. package/dist_ts/core/utils/index.d.ts +6 -0
  37. package/dist_ts/core/utils/index.js +7 -0
  38. package/dist_ts/core/utils/ip-utils.d.ts +53 -0
  39. package/dist_ts/core/utils/ip-utils.js +153 -0
  40. package/dist_ts/core/utils/validation-utils.d.ts +61 -0
  41. package/dist_ts/core/utils/validation-utils.js +149 -0
  42. package/dist_ts/forwarding/config/domain-config.d.ts +12 -0
  43. package/dist_ts/forwarding/config/domain-config.js +12 -0
  44. package/dist_ts/forwarding/config/domain-manager.d.ts +86 -0
  45. package/dist_ts/forwarding/config/domain-manager.js +242 -0
  46. package/dist_ts/forwarding/config/forwarding-types.d.ts +104 -0
  47. package/dist_ts/forwarding/config/forwarding-types.js +50 -0
  48. package/dist_ts/forwarding/config/index.d.ts +6 -0
  49. package/dist_ts/forwarding/config/index.js +7 -0
  50. package/dist_ts/forwarding/factory/forwarding-factory.d.ts +25 -0
  51. package/dist_ts/forwarding/factory/forwarding-factory.js +138 -0
  52. package/dist_ts/forwarding/factory/index.d.ts +4 -0
  53. package/dist_ts/forwarding/factory/index.js +5 -0
  54. package/dist_ts/forwarding/handlers/base-handler.d.ts +55 -0
  55. package/dist_ts/forwarding/handlers/base-handler.js +94 -0
  56. package/dist_ts/forwarding/handlers/http-handler.d.ts +30 -0
  57. package/dist_ts/forwarding/handlers/http-handler.js +131 -0
  58. package/dist_ts/forwarding/handlers/https-passthrough-handler.d.ts +29 -0
  59. package/dist_ts/forwarding/handlers/https-passthrough-handler.js +162 -0
  60. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.d.ts +36 -0
  61. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +229 -0
  62. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.d.ts +35 -0
  63. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +254 -0
  64. package/dist_ts/forwarding/handlers/index.d.ts +8 -0
  65. package/dist_ts/forwarding/handlers/index.js +9 -0
  66. package/dist_ts/forwarding/index.d.ts +19 -0
  67. package/dist_ts/forwarding/index.js +25 -0
  68. package/dist_ts/http/index.d.ts +15 -0
  69. package/dist_ts/http/index.js +20 -0
  70. package/dist_ts/http/models/http-types.d.ts +81 -0
  71. package/dist_ts/http/models/http-types.js +62 -0
  72. package/dist_ts/http/port80/acme-interfaces.d.ts +78 -0
  73. package/dist_ts/http/port80/acme-interfaces.js +6 -0
  74. package/dist_ts/http/port80/challenge-responder.d.ts +53 -0
  75. package/dist_ts/http/port80/challenge-responder.js +203 -0
  76. package/dist_ts/http/port80/index.d.ts +6 -0
  77. package/dist_ts/http/port80/index.js +9 -0
  78. package/dist_ts/http/port80/port80-handler.d.ts +121 -0
  79. package/dist_ts/http/port80/port80-handler.js +554 -0
  80. package/dist_ts/http/redirects/index.d.ts +4 -0
  81. package/dist_ts/http/redirects/index.js +5 -0
  82. package/dist_ts/http/router/index.d.ts +4 -0
  83. package/dist_ts/http/router/index.js +5 -0
  84. package/dist_ts/http/router/proxy-router.d.ts +115 -0
  85. package/dist_ts/http/router/proxy-router.js +325 -0
  86. package/dist_ts/index.d.ts +15 -8
  87. package/dist_ts/index.js +26 -10
  88. package/dist_ts/networkproxy/classes.np.certificatemanager.js +2 -2
  89. package/dist_ts/networkproxy/index.d.ts +1 -6
  90. package/dist_ts/networkproxy/index.js +4 -8
  91. package/dist_ts/plugins.d.ts +2 -1
  92. package/dist_ts/plugins.js +3 -2
  93. package/dist_ts/port80handler/classes.port80handler.d.ts +8 -136
  94. package/dist_ts/port80handler/classes.port80handler.js +14 -567
  95. package/dist_ts/proxies/index.d.ts +6 -0
  96. package/dist_ts/proxies/index.js +8 -0
  97. package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +77 -0
  98. package/dist_ts/proxies/network-proxy/certificate-manager.js +373 -0
  99. package/dist_ts/proxies/network-proxy/connection-pool.d.ts +47 -0
  100. package/dist_ts/proxies/network-proxy/connection-pool.js +210 -0
  101. package/dist_ts/proxies/network-proxy/index.d.ts +10 -0
  102. package/dist_ts/proxies/network-proxy/index.js +12 -0
  103. package/dist_ts/proxies/network-proxy/models/index.d.ts +4 -0
  104. package/dist_ts/proxies/network-proxy/models/index.js +5 -0
  105. package/dist_ts/proxies/network-proxy/models/types.d.ts +80 -0
  106. package/dist_ts/proxies/network-proxy/models/types.js +35 -0
  107. package/dist_ts/proxies/network-proxy/network-proxy.d.ts +118 -0
  108. package/dist_ts/proxies/network-proxy/network-proxy.js +387 -0
  109. package/dist_ts/proxies/network-proxy/request-handler.d.ts +57 -0
  110. package/dist_ts/proxies/network-proxy/request-handler.js +394 -0
  111. package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +38 -0
  112. package/dist_ts/proxies/network-proxy/websocket-handler.js +188 -0
  113. package/dist_ts/proxies/nftables-proxy/index.d.ts +5 -0
  114. package/dist_ts/proxies/nftables-proxy/index.js +6 -0
  115. package/dist_ts/proxies/nftables-proxy/models/errors.d.ts +15 -0
  116. package/dist_ts/proxies/nftables-proxy/models/errors.js +28 -0
  117. package/dist_ts/proxies/nftables-proxy/models/index.d.ts +5 -0
  118. package/dist_ts/proxies/nftables-proxy/models/index.js +6 -0
  119. package/dist_ts/proxies/nftables-proxy/models/interfaces.d.ts +75 -0
  120. package/dist_ts/proxies/nftables-proxy/models/interfaces.js +5 -0
  121. package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +136 -0
  122. package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +1516 -0
  123. package/dist_ts/proxies/smart-proxy/connection-handler.d.ts +39 -0
  124. package/dist_ts/proxies/smart-proxy/connection-handler.js +894 -0
  125. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +78 -0
  126. package/dist_ts/proxies/smart-proxy/connection-manager.js +378 -0
  127. package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +95 -0
  128. package/dist_ts/proxies/smart-proxy/domain-config-manager.js +255 -0
  129. package/dist_ts/proxies/smart-proxy/index.d.ts +13 -0
  130. package/dist_ts/proxies/smart-proxy/index.js +17 -0
  131. package/dist_ts/proxies/smart-proxy/models/index.d.ts +4 -0
  132. package/dist_ts/proxies/smart-proxy/models/index.js +5 -0
  133. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +107 -0
  134. package/dist_ts/proxies/smart-proxy/models/interfaces.js +2 -0
  135. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +62 -0
  136. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +316 -0
  137. package/dist_ts/proxies/smart-proxy/port-range-manager.d.ts +56 -0
  138. package/dist_ts/proxies/smart-proxy/port-range-manager.js +176 -0
  139. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +64 -0
  140. package/dist_ts/proxies/smart-proxy/security-manager.js +149 -0
  141. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +63 -0
  142. package/dist_ts/proxies/smart-proxy/smart-proxy.js +523 -0
  143. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +47 -0
  144. package/dist_ts/proxies/smart-proxy/timeout-manager.js +154 -0
  145. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +57 -0
  146. package/dist_ts/proxies/smart-proxy/tls-manager.js +132 -0
  147. package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +2 -2
  148. package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +1 -1
  149. package/dist_ts/smartproxy/classes.pp.tlsmanager.js +2 -2
  150. package/dist_ts/smartproxy/classes.smartproxy.js +3 -3
  151. package/dist_ts/tls/alerts/index.d.ts +4 -0
  152. package/dist_ts/tls/alerts/index.js +5 -0
  153. package/dist_ts/tls/alerts/tls-alert.d.ts +150 -0
  154. package/dist_ts/tls/alerts/tls-alert.js +226 -0
  155. package/dist_ts/tls/index.d.ts +18 -0
  156. package/dist_ts/tls/index.js +27 -0
  157. package/dist_ts/tls/sni/client-hello-parser.d.ts +100 -0
  158. package/dist_ts/tls/sni/client-hello-parser.js +463 -0
  159. package/dist_ts/tls/sni/index.d.ts +4 -0
  160. package/dist_ts/tls/sni/index.js +5 -0
  161. package/dist_ts/tls/sni/sni-extraction.d.ts +58 -0
  162. package/dist_ts/tls/sni/sni-extraction.js +275 -0
  163. package/dist_ts/tls/sni/sni-handler.d.ts +154 -0
  164. package/dist_ts/tls/sni/sni-handler.js +191 -0
  165. package/dist_ts/tls/utils/index.d.ts +4 -0
  166. package/dist_ts/tls/utils/index.js +5 -0
  167. package/dist_ts/tls/utils/tls-utils.d.ts +158 -0
  168. package/dist_ts/tls/utils/tls-utils.js +187 -0
  169. package/package.json +1 -1
  170. package/readme.md +89 -21
  171. package/readme.plan.md +253 -469
  172. package/ts/00_commitinfo_data.ts +1 -1
  173. package/ts/certificate/acme/acme-factory.ts +48 -0
  174. package/ts/certificate/acme/challenge-handler.ts +110 -0
  175. package/ts/certificate/acme/index.ts +3 -0
  176. package/ts/certificate/events/certificate-events.ts +36 -0
  177. package/ts/certificate/index.ts +67 -0
  178. package/ts/certificate/models/certificate-types.ts +88 -0
  179. package/ts/certificate/providers/cert-provisioner.ts +326 -0
  180. package/ts/certificate/providers/index.ts +3 -0
  181. package/ts/certificate/storage/file-storage.ts +234 -0
  182. package/ts/certificate/storage/index.ts +3 -0
  183. package/ts/certificate/utils/certificate-helpers.ts +50 -0
  184. package/ts/common/eventUtils.ts +1 -1
  185. package/ts/common/port80-adapter.ts +1 -1
  186. package/ts/core/events/index.ts +3 -0
  187. package/ts/core/index.ts +8 -0
  188. package/ts/core/models/common-types.ts +91 -0
  189. package/ts/core/models/index.ts +5 -0
  190. package/ts/core/utils/event-utils.ts +34 -0
  191. package/ts/core/utils/index.ts +7 -0
  192. package/ts/core/utils/ip-utils.ts +175 -0
  193. package/ts/core/utils/validation-utils.ts +177 -0
  194. package/ts/{smartproxy/forwarding → forwarding/config}/domain-config.ts +1 -1
  195. package/ts/{smartproxy/forwarding → forwarding/config}/domain-manager.ts +8 -8
  196. package/ts/{smartproxy/types/forwarding.types.ts → forwarding/config/forwarding-types.ts} +6 -6
  197. package/ts/forwarding/config/index.ts +7 -0
  198. package/ts/{smartproxy/forwarding/forwarding.factory.ts → forwarding/factory/forwarding-factory.ts} +12 -11
  199. package/ts/forwarding/factory/index.ts +5 -0
  200. package/ts/{smartproxy/forwarding/forwarding.handler.ts → forwarding/handlers/base-handler.ts} +2 -2
  201. package/ts/{smartproxy/forwarding/http.handler.ts → forwarding/handlers/http-handler.ts} +13 -4
  202. package/ts/{smartproxy/forwarding/https-passthrough.handler.ts → forwarding/handlers/https-passthrough-handler.ts} +13 -4
  203. package/ts/{smartproxy/forwarding/https-terminate-to-http.handler.ts → forwarding/handlers/https-terminate-to-http-handler.ts} +3 -3
  204. package/ts/{smartproxy/forwarding/https-terminate-to-https.handler.ts → forwarding/handlers/https-terminate-to-https-handler.ts} +3 -3
  205. package/ts/forwarding/handlers/index.ts +9 -0
  206. package/ts/forwarding/index.ts +34 -0
  207. package/ts/http/index.ts +23 -0
  208. package/ts/http/models/http-types.ts +105 -0
  209. package/ts/http/port80/acme-interfaces.ts +85 -0
  210. package/ts/http/port80/challenge-responder.ts +246 -0
  211. package/ts/http/port80/index.ts +13 -0
  212. package/ts/{port80handler/classes.port80handler.ts → http/port80/port80-handler.ts} +164 -161
  213. package/ts/http/redirects/index.ts +3 -0
  214. package/ts/http/router/index.ts +5 -0
  215. package/ts/{classes.router.ts → http/router/proxy-router.ts} +27 -20
  216. package/ts/index.ts +32 -9
  217. package/ts/plugins.ts +2 -1
  218. package/ts/proxies/index.ts +8 -0
  219. package/ts/{networkproxy/classes.np.certificatemanager.ts → proxies/network-proxy/certificate-manager.ts} +17 -16
  220. package/ts/{networkproxy/classes.np.connectionpool.ts → proxies/network-proxy/connection-pool.ts} +3 -3
  221. package/ts/proxies/network-proxy/index.ts +13 -0
  222. package/ts/proxies/network-proxy/models/index.ts +4 -0
  223. package/ts/{networkproxy/classes.np.types.ts → proxies/network-proxy/models/types.ts} +7 -11
  224. package/ts/{networkproxy/classes.np.networkproxy.ts → proxies/network-proxy/network-proxy.ts} +31 -24
  225. package/ts/{networkproxy/classes.np.requesthandler.ts → proxies/network-proxy/request-handler.ts} +12 -7
  226. package/ts/{networkproxy/classes.np.websockethandler.ts → proxies/network-proxy/websocket-handler.ts} +6 -6
  227. package/ts/proxies/nftables-proxy/index.ts +5 -0
  228. package/ts/proxies/nftables-proxy/models/errors.ts +30 -0
  229. package/ts/proxies/nftables-proxy/models/index.ts +5 -0
  230. package/ts/proxies/nftables-proxy/models/interfaces.ts +94 -0
  231. package/ts/{nfttablesproxy/classes.nftablesproxy.ts → proxies/nftables-proxy/nftables-proxy.ts} +24 -126
  232. package/ts/{smartproxy/classes.pp.connectionhandler.ts → proxies/smart-proxy/connection-handler.ts} +12 -12
  233. package/ts/{smartproxy/classes.pp.connectionmanager.ts → proxies/smart-proxy/connection-manager.ts} +8 -8
  234. package/ts/{smartproxy/classes.pp.domainconfigmanager.ts → proxies/smart-proxy/domain-config-manager.ts} +15 -14
  235. package/ts/proxies/smart-proxy/index.ts +18 -0
  236. package/ts/proxies/smart-proxy/models/index.ts +4 -0
  237. package/ts/{smartproxy/classes.pp.interfaces.ts → proxies/smart-proxy/models/interfaces.ts} +12 -8
  238. package/ts/{smartproxy/classes.pp.networkproxybridge.ts → proxies/smart-proxy/network-proxy-bridge.ts} +14 -14
  239. package/ts/{smartproxy/classes.pp.portrangemanager.ts → proxies/smart-proxy/port-range-manager.ts} +1 -1
  240. package/ts/{smartproxy/classes.pp.securitymanager.ts → proxies/smart-proxy/security-manager.ts} +3 -3
  241. package/ts/{smartproxy/classes.smartproxy.ts → proxies/smart-proxy/smart-proxy.ts} +29 -24
  242. package/ts/{smartproxy/classes.pp.timeoutmanager.ts → proxies/smart-proxy/timeout-manager.ts} +3 -3
  243. package/ts/{smartproxy/classes.pp.tlsmanager.ts → proxies/smart-proxy/tls-manager.ts} +3 -3
  244. package/ts/tls/alerts/index.ts +3 -0
  245. package/ts/{smartproxy/classes.pp.tlsalert.ts → tls/alerts/tls-alert.ts} +44 -43
  246. package/ts/tls/index.ts +33 -0
  247. package/ts/tls/sni/client-hello-parser.ts +629 -0
  248. package/ts/tls/sni/index.ts +3 -0
  249. package/ts/tls/sni/sni-extraction.ts +353 -0
  250. package/ts/tls/sni/sni-handler.ts +264 -0
  251. package/ts/tls/utils/index.ts +3 -0
  252. package/ts/tls/utils/tls-utils.ts +201 -0
  253. package/ts/common/acmeFactory.ts +0 -23
  254. package/ts/helpers.certificates.ts +0 -30
  255. package/ts/networkproxy/index.ts +0 -7
  256. package/ts/smartproxy/classes.pp.certprovisioner.ts +0 -200
  257. package/ts/smartproxy/classes.pp.snihandler.ts +0 -1281
  258. package/ts/smartproxy/forwarding/index.ts +0 -52
@@ -1,6 +1,6 @@
1
- import * as plugins from '../plugins.js';
1
+ import * as plugins from '../../plugins.js';
2
2
  import { IncomingMessage, ServerResponse } from 'http';
3
- import { Port80HandlerEvents } from '../common/types.js';
3
+ import { CertificateEvents } from '../../certificate/events/certificate-events.js';
4
4
  import type {
5
5
  IForwardConfig,
6
6
  IDomainOptions,
@@ -8,50 +8,26 @@ import type {
8
8
  ICertificateFailure,
9
9
  ICertificateExpiring,
10
10
  IAcmeOptions
11
- } from '../common/types.js';
12
- // (fs and path I/O moved to CertProvisioner)
11
+ } from '../../certificate/models/certificate-types.js';
12
+ import {
13
+ HttpEvents,
14
+ HttpStatus,
15
+ HttpError,
16
+ CertificateError,
17
+ ServerError,
18
+ } from '../models/http-types.js';
19
+ import type { IDomainCertificate } from '../models/http-types.js';
20
+ import { ChallengeResponder } from './challenge-responder.js';
13
21
 
14
- /**
15
- * Custom error classes for better error handling
16
- */
17
- export class Port80HandlerError extends Error {
18
- constructor(message: string) {
19
- super(message);
20
- this.name = 'Port80HandlerError';
21
- }
22
- }
23
-
24
- export class CertificateError extends Port80HandlerError {
25
- constructor(
26
- message: string,
27
- public readonly domain: string,
28
- public readonly isRenewal: boolean = false
29
- ) {
30
- super(`${message} for domain ${domain}${isRenewal ? ' (renewal)' : ''}`);
31
- this.name = 'CertificateError';
32
- }
33
- }
34
-
35
- export class ServerError extends Port80HandlerError {
36
- constructor(message: string, public readonly code?: string) {
37
- super(message);
38
- this.name = 'ServerError';
39
- }
22
+ // Re-export for backward compatibility
23
+ export {
24
+ HttpError as Port80HandlerError,
25
+ CertificateError,
26
+ ServerError
40
27
  }
41
28
 
42
-
43
- /**
44
- * Represents a domain configuration with certificate status information
45
- */
46
- interface IDomainCertificate {
47
- options: IDomainOptions;
48
- certObtained: boolean;
49
- obtainingInProgress: boolean;
50
- certificate?: string;
51
- privateKey?: string;
52
- expiryDate?: Date;
53
- lastRenewalAttempt?: Date;
54
- }
29
+ // Port80Handler events enum for backward compatibility
30
+ export const Port80HandlerEvents = CertificateEvents;
55
31
 
56
32
  /**
57
33
  * Configuration options for the Port80Handler
@@ -65,13 +41,10 @@ interface IDomainCertificate {
65
41
  */
66
42
  export class Port80Handler extends plugins.EventEmitter {
67
43
  private domainCertificates: Map<string, IDomainCertificate>;
68
- // SmartAcme instance for certificate management
69
- private smartAcme: plugins.smartacme.SmartAcme | null = null;
70
- private smartAcmeHttp01Handler!: plugins.smartacme.handlers.Http01MemoryHandler;
44
+ private challengeResponder: ChallengeResponder | null = null;
71
45
  private server: plugins.http.Server | null = null;
72
-
46
+
73
47
  // Renewal scheduling is handled externally by SmartProxy
74
- // (Removed internal renewal timer)
75
48
  private isShuttingDown: boolean = false;
76
49
  private options: Required<IAcmeOptions>;
77
50
 
@@ -82,7 +55,7 @@ export class Port80Handler extends plugins.EventEmitter {
82
55
  constructor(options: IAcmeOptions = {}) {
83
56
  super();
84
57
  this.domainCertificates = new Map<string, IDomainCertificate>();
85
-
58
+
86
59
  // Default options
87
60
  this.options = {
88
61
  port: options.port ?? 80,
@@ -97,6 +70,32 @@ export class Port80Handler extends plugins.EventEmitter {
97
70
  autoRenew: options.autoRenew ?? true,
98
71
  domainForwards: options.domainForwards ?? []
99
72
  };
73
+
74
+ // Initialize challenge responder
75
+ if (this.options.enabled) {
76
+ this.challengeResponder = new ChallengeResponder(
77
+ this.options.useProduction,
78
+ this.options.accountEmail,
79
+ this.options.certificateStore
80
+ );
81
+
82
+ // Forward certificate events from the challenge responder
83
+ this.challengeResponder.on(CertificateEvents.CERTIFICATE_ISSUED, (data: ICertificateData) => {
84
+ this.emit(CertificateEvents.CERTIFICATE_ISSUED, data);
85
+ });
86
+
87
+ this.challengeResponder.on(CertificateEvents.CERTIFICATE_RENEWED, (data: ICertificateData) => {
88
+ this.emit(CertificateEvents.CERTIFICATE_RENEWED, data);
89
+ });
90
+
91
+ this.challengeResponder.on(CertificateEvents.CERTIFICATE_FAILED, (error: ICertificateFailure) => {
92
+ this.emit(CertificateEvents.CERTIFICATE_FAILED, error);
93
+ });
94
+
95
+ this.challengeResponder.on(CertificateEvents.CERTIFICATE_EXPIRING, (expiry: ICertificateExpiring) => {
96
+ this.emit(CertificateEvents.CERTIFICATE_EXPIRING, expiry);
97
+ });
98
+ }
100
99
  }
101
100
 
102
101
  /**
@@ -106,7 +105,7 @@ export class Port80Handler extends plugins.EventEmitter {
106
105
  if (this.server) {
107
106
  throw new ServerError('Server is already running');
108
107
  }
109
-
108
+
110
109
  if (this.isShuttingDown) {
111
110
  throw new ServerError('Server is shutting down');
112
111
  }
@@ -116,24 +115,22 @@ export class Port80Handler extends plugins.EventEmitter {
116
115
  console.log('Port80Handler is disabled, skipping start');
117
116
  return;
118
117
  }
119
- // Initialize SmartAcme with in-memory HTTP-01 challenge handler
120
- if (this.options.enabled) {
121
- this.smartAcmeHttp01Handler = new plugins.smartacme.handlers.Http01MemoryHandler();
122
- this.smartAcme = new plugins.smartacme.SmartAcme({
123
- accountEmail: this.options.accountEmail,
124
- certManager: new plugins.smartacme.certmanagers.MemoryCertManager(),
125
- environment: this.options.useProduction ? 'production' : 'integration',
126
- challengeHandlers: [ this.smartAcmeHttp01Handler ],
127
- challengePriority: ['http-01'],
128
- });
129
- await this.smartAcme.start();
118
+
119
+ // Initialize the challenge responder if enabled
120
+ if (this.options.enabled && this.challengeResponder) {
121
+ try {
122
+ await this.challengeResponder.initialize();
123
+ } catch (error) {
124
+ throw new ServerError(`Failed to initialize challenge responder: ${
125
+ error instanceof Error ? error.message : String(error)
126
+ }`);
127
+ }
130
128
  }
131
129
 
132
130
  return new Promise((resolve, reject) => {
133
131
  try {
134
-
135
132
  this.server = plugins.http.createServer((req, res) => this.handleRequest(req, res));
136
-
133
+
137
134
  this.server.on('error', (error: NodeJS.ErrnoException) => {
138
135
  if (error.code === 'EACCES') {
139
136
  reject(new ServerError(`Permission denied to bind to port ${this.options.port}. Try running with elevated privileges or use a port > 1024.`, error.code));
@@ -143,11 +140,11 @@ export class Port80Handler extends plugins.EventEmitter {
143
140
  reject(new ServerError(error.message, error.code));
144
141
  }
145
142
  });
146
-
143
+
147
144
  this.server.listen(this.options.port, () => {
148
145
  console.log(`Port80Handler is listening on port ${this.options.port}`);
149
- this.emit(Port80HandlerEvents.MANAGER_STARTED, this.options.port);
150
-
146
+ this.emit(CertificateEvents.MANAGER_STARTED, this.options.port);
147
+
151
148
  // Start certificate process for domains with acmeMaintenance enabled
152
149
  for (const [domain, domainInfo] of this.domainCertificates.entries()) {
153
150
  // Skip glob patterns for certificate issuance
@@ -155,14 +152,14 @@ export class Port80Handler extends plugins.EventEmitter {
155
152
  console.log(`Skipping initial certificate for glob pattern: ${domain}`);
156
153
  continue;
157
154
  }
158
-
155
+
159
156
  if (domainInfo.options.acmeMaintenance && !domainInfo.certObtained && !domainInfo.obtainingInProgress) {
160
157
  this.obtainCertificate(domain).catch(err => {
161
158
  console.error(`Error obtaining initial certificate for ${domain}:`, err);
162
159
  });
163
160
  }
164
161
  }
165
-
162
+
166
163
  resolve();
167
164
  });
168
165
  } catch (error) {
@@ -173,22 +170,21 @@ export class Port80Handler extends plugins.EventEmitter {
173
170
  }
174
171
 
175
172
  /**
176
- * Stops the HTTP server and renewal timer
173
+ * Stops the HTTP server and cleanup resources
177
174
  */
178
175
  public async stop(): Promise<void> {
179
176
  if (!this.server) {
180
177
  return;
181
178
  }
182
-
179
+
183
180
  this.isShuttingDown = true;
184
-
185
181
 
186
182
  return new Promise<void>((resolve) => {
187
183
  if (this.server) {
188
184
  this.server.close(() => {
189
185
  this.server = null;
190
186
  this.isShuttingDown = false;
191
- this.emit(Port80HandlerEvents.MANAGER_STOPPED);
187
+ this.emit(CertificateEvents.MANAGER_STOPPED);
192
188
  resolve();
193
189
  });
194
190
  } else {
@@ -204,25 +200,25 @@ export class Port80Handler extends plugins.EventEmitter {
204
200
  */
205
201
  public addDomain(options: IDomainOptions): void {
206
202
  if (!options.domainName || typeof options.domainName !== 'string') {
207
- throw new Port80HandlerError('Invalid domain name');
203
+ throw new HttpError('Invalid domain name');
208
204
  }
209
-
205
+
210
206
  const domainName = options.domainName;
211
-
207
+
212
208
  if (!this.domainCertificates.has(domainName)) {
213
209
  this.domainCertificates.set(domainName, {
214
210
  options,
215
211
  certObtained: false,
216
212
  obtainingInProgress: false
217
213
  });
218
-
214
+
219
215
  console.log(`Domain added: ${domainName} with configuration:`, {
220
216
  sslRedirect: options.sslRedirect,
221
217
  acmeMaintenance: options.acmeMaintenance,
222
218
  hasForward: !!options.forward,
223
219
  hasAcmeForward: !!options.acmeForward
224
220
  });
225
-
221
+
226
222
  // If acmeMaintenance is enabled and not a glob pattern, start certificate process immediately
227
223
  if (options.acmeMaintenance && this.server && !this.isGlobPattern(domainName)) {
228
224
  this.obtainCertificate(domainName).catch(err => {
@@ -256,13 +252,13 @@ export class Port80Handler extends plugins.EventEmitter {
256
252
  if (this.isGlobPattern(domain)) {
257
253
  return null;
258
254
  }
259
-
255
+
260
256
  const domainInfo = this.domainCertificates.get(domain);
261
-
257
+
262
258
  if (!domainInfo || !domainInfo.certObtained || !domainInfo.certificate || !domainInfo.privateKey) {
263
259
  return null;
264
260
  }
265
-
261
+
266
262
  return {
267
263
  domain,
268
264
  certificate: domainInfo.certificate,
@@ -295,14 +291,14 @@ export class Port80Handler extends plugins.EventEmitter {
295
291
  pattern: requestDomain
296
292
  };
297
293
  }
298
-
294
+
299
295
  // Then try glob patterns
300
296
  for (const [pattern, domainInfo] of this.domainCertificates.entries()) {
301
297
  if (this.isGlobPattern(pattern) && this.domainMatchesPattern(requestDomain, pattern)) {
302
298
  return { domainInfo, pattern };
303
299
  }
304
300
  }
305
-
301
+
306
302
  return null;
307
303
  }
308
304
 
@@ -339,16 +335,45 @@ export class Port80Handler extends plugins.EventEmitter {
339
335
  * @param res The HTTP response
340
336
  */
341
337
  private handleRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void {
338
+ // Emit request received event with basic info
339
+ this.emit(HttpEvents.REQUEST_RECEIVED, {
340
+ url: req.url,
341
+ method: req.method,
342
+ headers: req.headers
343
+ });
344
+
342
345
  const hostHeader = req.headers.host;
343
346
  if (!hostHeader) {
344
- res.statusCode = 400;
347
+ res.statusCode = HttpStatus.BAD_REQUEST;
345
348
  res.end('Bad Request: Host header is missing');
346
349
  return;
347
350
  }
348
-
351
+
349
352
  // Extract domain (ignoring any port in the Host header)
350
353
  const domain = hostHeader.split(':')[0];
351
354
 
355
+ // Check if this is an ACME challenge request that our ChallengeResponder can handle
356
+ if (this.challengeResponder && req.url?.startsWith('/.well-known/acme-challenge/')) {
357
+ // Handle ACME HTTP-01 challenge with the challenge responder
358
+ const domainMatch = this.getDomainInfoForRequest(domain);
359
+
360
+ // If there's a specific ACME forwarding config for this domain, use that instead
361
+ if (domainMatch?.domainInfo.options.acmeForward) {
362
+ this.forwardRequest(req, res, domainMatch.domainInfo.options.acmeForward, 'ACME challenge');
363
+ return;
364
+ }
365
+
366
+ // If domain exists and has acmeMaintenance enabled, or we don't have the domain yet
367
+ // (for auto-provisioning), try to handle the ACME challenge
368
+ if (!domainMatch || domainMatch.domainInfo.options.acmeMaintenance) {
369
+ // Let the challenge responder try to handle this request
370
+ if (this.challengeResponder.handleRequest(req, res)) {
371
+ // Challenge was handled
372
+ return;
373
+ }
374
+ }
375
+ }
376
+
352
377
  // Dynamic provisioning: if domain not yet managed, register for ACME and return 503
353
378
  if (!this.domainCertificates.has(domain)) {
354
379
  try {
@@ -356,14 +381,15 @@ export class Port80Handler extends plugins.EventEmitter {
356
381
  } catch (err) {
357
382
  console.error(`Error registering domain for on-demand provisioning: ${err}`);
358
383
  }
359
- res.statusCode = 503;
384
+ res.statusCode = HttpStatus.SERVICE_UNAVAILABLE;
360
385
  res.end('Certificate issuance in progress');
361
386
  return;
362
387
  }
388
+
363
389
  // Get domain config, using glob pattern matching if needed
364
390
  const domainMatch = this.getDomainInfoForRequest(domain);
365
391
  if (!domainMatch) {
366
- res.statusCode = 404;
392
+ res.statusCode = HttpStatus.NOT_FOUND;
367
393
  res.end('Domain not configured');
368
394
  return;
369
395
  }
@@ -371,29 +397,6 @@ export class Port80Handler extends plugins.EventEmitter {
371
397
  const { domainInfo, pattern } = domainMatch;
372
398
  const options = domainInfo.options;
373
399
 
374
- // Handle ACME HTTP-01 challenge requests or forwarding
375
- if (req.url && req.url.startsWith('/.well-known/acme-challenge/')) {
376
- // Forward ACME requests if configured
377
- if (options.acmeForward) {
378
- this.forwardRequest(req, res, options.acmeForward, 'ACME challenge');
379
- return;
380
- }
381
- // If not managing ACME for this domain, return 404
382
- if (!options.acmeMaintenance) {
383
- res.statusCode = 404;
384
- res.end('Not found');
385
- return;
386
- }
387
- // Delegate to Http01MemoryHandler
388
- if (this.smartAcmeHttp01Handler) {
389
- this.smartAcmeHttp01Handler.handleRequest(req, res);
390
- } else {
391
- res.statusCode = 500;
392
- res.end('ACME HTTP-01 handler not initialized');
393
- }
394
- return;
395
- }
396
-
397
400
  // Check if we should forward non-ACME requests
398
401
  if (options.forward) {
399
402
  this.forwardRequest(req, res, options.forward, 'HTTP');
@@ -406,13 +409,13 @@ export class Port80Handler extends plugins.EventEmitter {
406
409
  const httpsPort = this.options.httpsRedirectPort;
407
410
  const portSuffix = httpsPort === 443 ? '' : `:${httpsPort}`;
408
411
  const redirectUrl = `https://${domain}${portSuffix}${req.url || '/'}`;
409
-
410
- res.statusCode = 301;
412
+
413
+ res.statusCode = HttpStatus.MOVED_PERMANENTLY;
411
414
  res.setHeader('Location', redirectUrl);
412
415
  res.end(`Redirecting to ${redirectUrl}`);
413
416
  return;
414
417
  }
415
-
418
+
416
419
  // Handle case where certificate maintenance is enabled but not yet obtained
417
420
  // (Skip for glob patterns as they can't have certificates)
418
421
  if (!this.isGlobPattern(pattern) && options.acmeMaintenance && !domainInfo.certObtained) {
@@ -420,7 +423,7 @@ export class Port80Handler extends plugins.EventEmitter {
420
423
  if (!domainInfo.obtainingInProgress) {
421
424
  this.obtainCertificate(domain).catch(err => {
422
425
  const errorMessage = err instanceof Error ? err.message : 'Unknown error';
423
- this.emit(Port80HandlerEvents.CERTIFICATE_FAILED, {
426
+ this.emit(CertificateEvents.CERTIFICATE_FAILED, {
424
427
  domain,
425
428
  error: errorMessage,
426
429
  isRenewal: false
@@ -428,15 +431,22 @@ export class Port80Handler extends plugins.EventEmitter {
428
431
  console.error(`Error obtaining certificate for ${domain}:`, err);
429
432
  });
430
433
  }
431
-
432
- res.statusCode = 503;
434
+
435
+ res.statusCode = HttpStatus.SERVICE_UNAVAILABLE;
433
436
  res.end('Certificate issuance in progress, please try again later.');
434
437
  return;
435
438
  }
436
-
439
+
437
440
  // Default response for unhandled request
438
- res.statusCode = 404;
441
+ res.statusCode = HttpStatus.NOT_FOUND;
439
442
  res.end('No handlers configured for this request');
443
+
444
+ // Emit request handled event
445
+ this.emit(HttpEvents.REQUEST_HANDLED, {
446
+ domain,
447
+ url: req.url,
448
+ statusCode: res.statusCode
449
+ });
440
450
  }
441
451
 
442
452
  /**
@@ -447,7 +457,7 @@ export class Port80Handler extends plugins.EventEmitter {
447
457
  * @param requestType Type of request for logging
448
458
  */
449
459
  private forwardRequest(
450
- req: plugins.http.IncomingMessage,
460
+ req: plugins.http.IncomingMessage,
451
461
  res: plugins.http.ServerResponse,
452
462
  target: IForwardConfig,
453
463
  requestType: string
@@ -459,40 +469,47 @@ export class Port80Handler extends plugins.EventEmitter {
459
469
  method: req.method,
460
470
  headers: { ...req.headers }
461
471
  };
462
-
472
+
463
473
  const domain = req.headers.host?.split(':')[0] || 'unknown';
464
474
  console.log(`Forwarding ${requestType} request for ${domain} to ${target.ip}:${target.port}`);
465
-
475
+
466
476
  const proxyReq = plugins.http.request(options, (proxyRes) => {
467
477
  // Copy status code
468
- res.statusCode = proxyRes.statusCode || 500;
469
-
478
+ res.statusCode = proxyRes.statusCode || HttpStatus.INTERNAL_SERVER_ERROR;
479
+
470
480
  // Copy headers
471
481
  for (const [key, value] of Object.entries(proxyRes.headers)) {
472
482
  if (value) res.setHeader(key, value);
473
483
  }
474
-
484
+
475
485
  // Pipe response data
476
486
  proxyRes.pipe(res);
477
-
478
- this.emit(Port80HandlerEvents.REQUEST_FORWARDED, {
487
+
488
+ this.emit(HttpEvents.REQUEST_FORWARDED, {
479
489
  domain,
480
490
  requestType,
481
491
  target: `${target.ip}:${target.port}`,
482
492
  statusCode: proxyRes.statusCode
483
493
  });
484
494
  });
485
-
495
+
486
496
  proxyReq.on('error', (error) => {
487
497
  console.error(`Error forwarding request to ${target.ip}:${target.port}:`, error);
498
+
499
+ this.emit(HttpEvents.REQUEST_ERROR, {
500
+ domain,
501
+ error: error.message,
502
+ target: `${target.ip}:${target.port}`
503
+ });
504
+
488
505
  if (!res.headersSent) {
489
- res.statusCode = 502;
506
+ res.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
490
507
  res.end(`Proxy error: ${error.message}`);
491
508
  } else {
492
509
  res.end();
493
510
  }
494
511
  });
495
-
512
+
496
513
  // Pipe original request to proxy request
497
514
  if (req.readable) {
498
515
  req.pipe(proxyReq);
@@ -507,59 +524,45 @@ export class Port80Handler extends plugins.EventEmitter {
507
524
  * @param domain The domain to obtain a certificate for
508
525
  * @param isRenewal Whether this is a renewal attempt
509
526
  */
510
- /**
511
- * Obtains a certificate for a domain using SmartAcme HTTP-01 challenges
512
- * @param domain The domain to obtain a certificate for
513
- * @param isRenewal Whether this is a renewal attempt
514
- */
515
527
  private async obtainCertificate(domain: string, isRenewal: boolean = false): Promise<void> {
516
528
  if (this.isGlobPattern(domain)) {
517
529
  throw new CertificateError('Cannot obtain certificates for glob pattern domains', domain, isRenewal);
518
530
  }
531
+
519
532
  const domainInfo = this.domainCertificates.get(domain)!;
533
+
520
534
  if (!domainInfo.options.acmeMaintenance) {
521
535
  console.log(`Skipping certificate issuance for ${domain} - acmeMaintenance is disabled`);
522
536
  return;
523
537
  }
538
+
524
539
  if (domainInfo.obtainingInProgress) {
525
540
  console.log(`Certificate issuance already in progress for ${domain}`);
526
541
  return;
527
542
  }
528
- if (!this.smartAcme) {
529
- throw new Port80HandlerError('SmartAcme is not initialized');
543
+
544
+ if (!this.challengeResponder) {
545
+ throw new HttpError('Challenge responder is not initialized');
530
546
  }
547
+
531
548
  domainInfo.obtainingInProgress = true;
532
549
  domainInfo.lastRenewalAttempt = new Date();
550
+
533
551
  try {
534
- // Request certificate via SmartAcme
535
- const certObj = await this.smartAcme.getCertificateForDomain(domain);
536
- const certificate = certObj.publicKey;
537
- const privateKey = certObj.privateKey;
538
- const expiryDate = new Date(certObj.validUntil);
539
- domainInfo.certificate = certificate;
540
- domainInfo.privateKey = privateKey;
552
+ // Request certificate via ChallengeResponder
553
+ // The ChallengeResponder handles all ACME client interactions and will emit events
554
+ const certData = await this.challengeResponder.requestCertificate(domain, isRenewal);
555
+
556
+ // Update domain info with certificate data
557
+ domainInfo.certificate = certData.certificate;
558
+ domainInfo.privateKey = certData.privateKey;
541
559
  domainInfo.certObtained = true;
542
- domainInfo.expiryDate = expiryDate;
560
+ domainInfo.expiryDate = certData.expiryDate;
543
561
 
544
562
  console.log(`Certificate ${isRenewal ? 'renewed' : 'obtained'} for ${domain}`);
545
- // Persistence moved to CertProvisioner
546
- const eventType = isRenewal
547
- ? Port80HandlerEvents.CERTIFICATE_RENEWED
548
- : Port80HandlerEvents.CERTIFICATE_ISSUED;
549
- this.emitCertificateEvent(eventType, {
550
- domain,
551
- certificate,
552
- privateKey,
553
- expiryDate: expiryDate || this.getDefaultExpiryDate()
554
- });
555
563
  } catch (error: any) {
556
- const errorMsg = error?.message || 'Unknown error';
564
+ const errorMsg = error instanceof Error ? error.message : String(error);
557
565
  console.error(`Error during certificate issuance for ${domain}:`, error);
558
- this.emit(Port80HandlerEvents.CERTIFICATE_FAILED, {
559
- domain,
560
- error: errorMsg,
561
- isRenewal
562
- } as ICertificateFailure);
563
566
  throw new CertificateError(errorMsg, domain, isRenewal);
564
567
  } finally {
565
568
  domainInfo.obtainingInProgress = false;
@@ -609,7 +612,7 @@ export class Port80Handler extends plugins.EventEmitter {
609
612
  * @param eventType The event type to emit
610
613
  * @param data The certificate data
611
614
  */
612
- private emitCertificateEvent(eventType: Port80HandlerEvents, data: ICertificateData): void {
615
+ private emitCertificateEvent(eventType: CertificateEvents, data: ICertificateData): void {
613
616
  this.emit(eventType, data);
614
617
  }
615
618
 
@@ -671,7 +674,7 @@ export class Port80Handler extends plugins.EventEmitter {
671
674
  */
672
675
  public async renewCertificate(domain: string): Promise<void> {
673
676
  if (!this.domainCertificates.has(domain)) {
674
- throw new Port80HandlerError(`Domain not managed: ${domain}`);
677
+ throw new HttpError(`Domain not managed: ${domain}`);
675
678
  }
676
679
  // Trigger renewal via ACME
677
680
  await this.obtainCertificate(domain, true);
@@ -0,0 +1,3 @@
1
+ /**
2
+ * HTTP redirects
3
+ */
@@ -0,0 +1,5 @@
1
+ /**
2
+ * HTTP routing
3
+ */
4
+
5
+ export * from './proxy-router.js';