@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
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '12.0.0',
6
+ version: '13.1.2',
7
7
  description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
8
8
  }
@@ -0,0 +1,48 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import type { IAcmeOptions } from '../models/certificate-types.js';
4
+ import { ensureCertificateDirectory } from '../utils/certificate-helpers.js';
5
+ // We'll need to update this import when we move the Port80Handler
6
+ import { Port80Handler } from '../../http/port80/port80-handler.js';
7
+
8
+ /**
9
+ * Factory to create a Port80Handler with common setup.
10
+ * Ensures the certificate store directory exists and instantiates the handler.
11
+ * @param options Port80Handler configuration options
12
+ * @returns A new Port80Handler instance
13
+ */
14
+ export function buildPort80Handler(
15
+ options: IAcmeOptions
16
+ ): Port80Handler {
17
+ if (options.certificateStore) {
18
+ ensureCertificateDirectory(options.certificateStore);
19
+ console.log(`Ensured certificate store directory: ${options.certificateStore}`);
20
+ }
21
+ return new Port80Handler(options);
22
+ }
23
+
24
+ /**
25
+ * Creates default ACME options with sensible defaults
26
+ * @param email Account email for ACME provider
27
+ * @param certificateStore Path to store certificates
28
+ * @param useProduction Whether to use production ACME servers
29
+ * @returns Configured ACME options
30
+ */
31
+ export function createDefaultAcmeOptions(
32
+ email: string,
33
+ certificateStore: string,
34
+ useProduction: boolean = false
35
+ ): IAcmeOptions {
36
+ return {
37
+ accountEmail: email,
38
+ enabled: true,
39
+ port: 80,
40
+ useProduction,
41
+ httpsRedirectPort: 443,
42
+ renewThresholdDays: 30,
43
+ renewCheckIntervalHours: 24,
44
+ autoRenew: true,
45
+ certificateStore,
46
+ skipConfiguredCerts: false
47
+ };
48
+ }
@@ -0,0 +1,110 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import type { IAcmeOptions, ICertificateData } from '../models/certificate-types.js';
3
+ import { CertificateEvents } from '../events/certificate-events.js';
4
+
5
+ /**
6
+ * Manages ACME challenges and certificate validation
7
+ */
8
+ export class AcmeChallengeHandler extends plugins.EventEmitter {
9
+ private options: IAcmeOptions;
10
+ private client: any; // ACME client from plugins
11
+ private pendingChallenges: Map<string, any>;
12
+
13
+ /**
14
+ * Creates a new ACME challenge handler
15
+ * @param options ACME configuration options
16
+ */
17
+ constructor(options: IAcmeOptions) {
18
+ super();
19
+ this.options = options;
20
+ this.pendingChallenges = new Map();
21
+
22
+ // Initialize ACME client if needed
23
+ // This is just a placeholder implementation since we don't use the actual
24
+ // client directly in this implementation - it's handled by Port80Handler
25
+ this.client = null;
26
+ console.log('Created challenge handler with options:',
27
+ options.accountEmail,
28
+ options.useProduction ? 'production' : 'staging'
29
+ );
30
+ }
31
+
32
+ /**
33
+ * Gets or creates the ACME account key
34
+ */
35
+ private getAccountKey(): Buffer {
36
+ // Implementation details would depend on plugin requirements
37
+ // This is a simplified version
38
+ if (!this.options.certificateStore) {
39
+ throw new Error('Certificate store is required for ACME challenges');
40
+ }
41
+
42
+ // This is just a placeholder - actual implementation would check for
43
+ // existing account key and create one if needed
44
+ return Buffer.from('account-key-placeholder');
45
+ }
46
+
47
+ /**
48
+ * Validates a domain using HTTP-01 challenge
49
+ * @param domain Domain to validate
50
+ * @param challengeToken ACME challenge token
51
+ * @param keyAuthorization Key authorization for the challenge
52
+ */
53
+ public async handleHttpChallenge(
54
+ domain: string,
55
+ challengeToken: string,
56
+ keyAuthorization: string
57
+ ): Promise<void> {
58
+ // Store challenge for response
59
+ this.pendingChallenges.set(challengeToken, keyAuthorization);
60
+
61
+ try {
62
+ // Wait for challenge validation - this would normally be handled by the ACME client
63
+ await new Promise(resolve => setTimeout(resolve, 1000));
64
+ this.emit(CertificateEvents.CERTIFICATE_ISSUED, {
65
+ domain,
66
+ success: true
67
+ });
68
+ } catch (error) {
69
+ this.emit(CertificateEvents.CERTIFICATE_FAILED, {
70
+ domain,
71
+ error: error instanceof Error ? error.message : String(error),
72
+ isRenewal: false
73
+ });
74
+ throw error;
75
+ } finally {
76
+ // Clean up the challenge
77
+ this.pendingChallenges.delete(challengeToken);
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Responds to an HTTP-01 challenge request
83
+ * @param token Challenge token from the request path
84
+ * @returns The key authorization if found
85
+ */
86
+ public getChallengeResponse(token: string): string | null {
87
+ return this.pendingChallenges.get(token) || null;
88
+ }
89
+
90
+ /**
91
+ * Checks if a request path is an ACME challenge
92
+ * @param path Request path
93
+ * @returns True if this is an ACME challenge request
94
+ */
95
+ public isAcmeChallenge(path: string): boolean {
96
+ return path.startsWith('/.well-known/acme-challenge/');
97
+ }
98
+
99
+ /**
100
+ * Extracts the challenge token from an ACME challenge path
101
+ * @param path Request path
102
+ * @returns The challenge token if valid
103
+ */
104
+ public extractChallengeToken(path: string): string | null {
105
+ if (!this.isAcmeChallenge(path)) return null;
106
+
107
+ const parts = path.split('/');
108
+ return parts[parts.length - 1] || null;
109
+ }
110
+ }
@@ -0,0 +1,3 @@
1
+ /**
2
+ * ACME certificate provisioning
3
+ */
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Certificate-related events emitted by certificate management components
3
+ */
4
+ export enum CertificateEvents {
5
+ CERTIFICATE_ISSUED = 'certificate-issued',
6
+ CERTIFICATE_RENEWED = 'certificate-renewed',
7
+ CERTIFICATE_FAILED = 'certificate-failed',
8
+ CERTIFICATE_EXPIRING = 'certificate-expiring',
9
+ CERTIFICATE_APPLIED = 'certificate-applied',
10
+ // Events moved from Port80Handler for compatibility
11
+ MANAGER_STARTED = 'manager-started',
12
+ MANAGER_STOPPED = 'manager-stopped',
13
+ }
14
+
15
+ /**
16
+ * Port80Handler-specific events including certificate-related ones
17
+ * @deprecated Use CertificateEvents and HttpEvents instead
18
+ */
19
+ export enum Port80HandlerEvents {
20
+ CERTIFICATE_ISSUED = 'certificate-issued',
21
+ CERTIFICATE_RENEWED = 'certificate-renewed',
22
+ CERTIFICATE_FAILED = 'certificate-failed',
23
+ CERTIFICATE_EXPIRING = 'certificate-expiring',
24
+ MANAGER_STARTED = 'manager-started',
25
+ MANAGER_STOPPED = 'manager-stopped',
26
+ REQUEST_FORWARDED = 'request-forwarded',
27
+ }
28
+
29
+ /**
30
+ * Certificate provider events
31
+ */
32
+ export enum CertProvisionerEvents {
33
+ CERTIFICATE_ISSUED = 'certificate',
34
+ CERTIFICATE_RENEWED = 'certificate',
35
+ CERTIFICATE_FAILED = 'certificate-failed'
36
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Certificate management module for SmartProxy
3
+ * Provides certificate provisioning, storage, and management capabilities
4
+ */
5
+
6
+ // Certificate types and models
7
+ export * from './models/certificate-types.js';
8
+
9
+ // Certificate events
10
+ export * from './events/certificate-events.js';
11
+
12
+ // Certificate providers
13
+ export * from './providers/cert-provisioner.js';
14
+
15
+ // ACME related exports
16
+ export * from './acme/acme-factory.js';
17
+ export * from './acme/challenge-handler.js';
18
+
19
+ // Certificate utilities
20
+ export * from './utils/certificate-helpers.js';
21
+
22
+ // Certificate storage
23
+ export * from './storage/file-storage.js';
24
+
25
+ // Convenience function to create a certificate provisioner with common settings
26
+ import { CertProvisioner } from './providers/cert-provisioner.js';
27
+ import { buildPort80Handler } from './acme/acme-factory.js';
28
+ import type { IAcmeOptions, IDomainForwardConfig } from './models/certificate-types.js';
29
+ import type { IDomainConfig } from '../forwarding/config/domain-config.js';
30
+
31
+ /**
32
+ * Creates a complete certificate provisioning system with default settings
33
+ * @param domainConfigs Domain configurations
34
+ * @param acmeOptions ACME options for certificate provisioning
35
+ * @param networkProxyBridge Bridge to apply certificates to network proxy
36
+ * @param certProvider Optional custom certificate provider
37
+ * @returns Configured CertProvisioner
38
+ */
39
+ export function createCertificateProvisioner(
40
+ domainConfigs: IDomainConfig[],
41
+ acmeOptions: IAcmeOptions,
42
+ networkProxyBridge: any, // Placeholder until NetworkProxyBridge is migrated
43
+ certProvider?: any // Placeholder until cert provider type is properly defined
44
+ ): CertProvisioner {
45
+ // Build the Port80Handler for ACME challenges
46
+ const port80Handler = buildPort80Handler(acmeOptions);
47
+
48
+ // Extract ACME-specific configuration
49
+ const {
50
+ renewThresholdDays = 30,
51
+ renewCheckIntervalHours = 24,
52
+ autoRenew = true,
53
+ domainForwards = []
54
+ } = acmeOptions;
55
+
56
+ // Create and return the certificate provisioner
57
+ return new CertProvisioner(
58
+ domainConfigs,
59
+ port80Handler,
60
+ networkProxyBridge,
61
+ certProvider,
62
+ renewThresholdDays,
63
+ renewCheckIntervalHours,
64
+ autoRenew,
65
+ domainForwards
66
+ );
67
+ }
@@ -0,0 +1,88 @@
1
+ import * as plugins from '../../plugins.js';
2
+
3
+ /**
4
+ * Certificate data structure containing all necessary information
5
+ * about a certificate
6
+ */
7
+ export interface ICertificateData {
8
+ domain: string;
9
+ certificate: string;
10
+ privateKey: string;
11
+ expiryDate: Date;
12
+ // Optional source and renewal information for event emissions
13
+ source?: 'static' | 'http01' | 'dns01';
14
+ isRenewal?: boolean;
15
+ }
16
+
17
+ /**
18
+ * Certificates pair (private and public keys)
19
+ */
20
+ export interface ICertificates {
21
+ privateKey: string;
22
+ publicKey: string;
23
+ }
24
+
25
+ /**
26
+ * Certificate failure payload type
27
+ */
28
+ export interface ICertificateFailure {
29
+ domain: string;
30
+ error: string;
31
+ isRenewal: boolean;
32
+ }
33
+
34
+ /**
35
+ * Certificate expiry payload type
36
+ */
37
+ export interface ICertificateExpiring {
38
+ domain: string;
39
+ expiryDate: Date;
40
+ daysRemaining: number;
41
+ }
42
+
43
+ /**
44
+ * Domain forwarding configuration
45
+ */
46
+ export interface IForwardConfig {
47
+ ip: string;
48
+ port: number;
49
+ }
50
+
51
+ /**
52
+ * Domain-specific forwarding configuration for ACME challenges
53
+ */
54
+ export interface IDomainForwardConfig {
55
+ domain: string;
56
+ forwardConfig?: IForwardConfig;
57
+ acmeForwardConfig?: IForwardConfig;
58
+ sslRedirect?: boolean;
59
+ }
60
+
61
+ /**
62
+ * Domain configuration options
63
+ */
64
+ export interface IDomainOptions {
65
+ domainName: string;
66
+ sslRedirect: boolean; // if true redirects the request to port 443
67
+ acmeMaintenance: boolean; // tries to always have a valid cert for this domain
68
+ forward?: IForwardConfig; // forwards all http requests to that target
69
+ acmeForward?: IForwardConfig; // forwards letsencrypt requests to this config
70
+ }
71
+
72
+ /**
73
+ * Unified ACME configuration options used across proxies and handlers
74
+ */
75
+ export interface IAcmeOptions {
76
+ accountEmail?: string; // Email for Let's Encrypt account
77
+ enabled?: boolean; // Whether ACME is enabled
78
+ port?: number; // Port to listen on for ACME challenges (default: 80)
79
+ useProduction?: boolean; // Use production environment (default: staging)
80
+ httpsRedirectPort?: number; // Port to redirect HTTP requests to HTTPS (default: 443)
81
+ renewThresholdDays?: number; // Days before expiry to renew certificates
82
+ renewCheckIntervalHours?: number; // How often to check for renewals (in hours)
83
+ autoRenew?: boolean; // Whether to automatically renew certificates
84
+ certificateStore?: string; // Directory to store certificates
85
+ skipConfiguredCerts?: boolean; // Skip domains with existing certificates
86
+ domainForwards?: IDomainForwardConfig[]; // Domain-specific forwarding configs
87
+ }
88
+
@@ -0,0 +1,326 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import type { IDomainConfig } from '../../forwarding/config/domain-config.js';
3
+ import type { ICertificateData, IDomainForwardConfig, IDomainOptions } from '../models/certificate-types.js';
4
+ import { Port80HandlerEvents, CertProvisionerEvents } from '../events/certificate-events.js';
5
+ import { Port80Handler } from '../../http/port80/port80-handler.js';
6
+ // We need to define this interface until we migrate NetworkProxyBridge
7
+ interface INetworkProxyBridge {
8
+ applyExternalCertificate(certData: ICertificateData): void;
9
+ }
10
+
11
+ // This will be imported after NetworkProxyBridge is migrated
12
+ // import type { NetworkProxyBridge } from '../../proxies/smart-proxy/network-proxy-bridge.js';
13
+
14
+ // For backward compatibility
15
+ export type TSmartProxyCertProvisionObject = plugins.tsclass.network.ICert | 'http01';
16
+
17
+ /**
18
+ * Type for static certificate provisioning
19
+ */
20
+ export type TCertProvisionObject = plugins.tsclass.network.ICert | 'http01' | 'dns01';
21
+
22
+ /**
23
+ * CertProvisioner manages certificate provisioning and renewal workflows,
24
+ * unifying static certificates and HTTP-01 challenges via Port80Handler.
25
+ */
26
+ export class CertProvisioner extends plugins.EventEmitter {
27
+ private domainConfigs: IDomainConfig[];
28
+ private port80Handler: Port80Handler;
29
+ private networkProxyBridge: INetworkProxyBridge;
30
+ private certProvisionFunction?: (domain: string) => Promise<TCertProvisionObject>;
31
+ private forwardConfigs: IDomainForwardConfig[];
32
+ private renewThresholdDays: number;
33
+ private renewCheckIntervalHours: number;
34
+ private autoRenew: boolean;
35
+ private renewManager?: plugins.taskbuffer.TaskManager;
36
+ // Track provisioning type per domain
37
+ private provisionMap: Map<string, 'http01' | 'dns01' | 'static'>;
38
+
39
+ /**
40
+ * @param domainConfigs Array of domain configuration objects
41
+ * @param port80Handler HTTP-01 challenge handler instance
42
+ * @param networkProxyBridge Bridge for applying external certificates
43
+ * @param certProvider Optional callback returning a static cert or 'http01'
44
+ * @param renewThresholdDays Days before expiry to trigger renewals
45
+ * @param renewCheckIntervalHours Interval in hours to check for renewals
46
+ * @param autoRenew Whether to automatically schedule renewals
47
+ * @param forwardConfigs Domain forwarding configurations for ACME challenges
48
+ */
49
+ constructor(
50
+ domainConfigs: IDomainConfig[],
51
+ port80Handler: Port80Handler,
52
+ networkProxyBridge: INetworkProxyBridge,
53
+ certProvider?: (domain: string) => Promise<TCertProvisionObject>,
54
+ renewThresholdDays: number = 30,
55
+ renewCheckIntervalHours: number = 24,
56
+ autoRenew: boolean = true,
57
+ forwardConfigs: IDomainForwardConfig[] = []
58
+ ) {
59
+ super();
60
+ this.domainConfigs = domainConfigs;
61
+ this.port80Handler = port80Handler;
62
+ this.networkProxyBridge = networkProxyBridge;
63
+ this.certProvisionFunction = certProvider;
64
+ this.renewThresholdDays = renewThresholdDays;
65
+ this.renewCheckIntervalHours = renewCheckIntervalHours;
66
+ this.autoRenew = autoRenew;
67
+ this.provisionMap = new Map();
68
+ this.forwardConfigs = forwardConfigs;
69
+ }
70
+
71
+ /**
72
+ * Start initial provisioning and schedule renewals.
73
+ */
74
+ public async start(): Promise<void> {
75
+ // Subscribe to Port80Handler certificate events
76
+ this.setupEventSubscriptions();
77
+
78
+ // Apply external forwarding for ACME challenges
79
+ this.setupForwardingConfigs();
80
+
81
+ // Initial provisioning for all domains
82
+ await this.provisionAllDomains();
83
+
84
+ // Schedule renewals if enabled
85
+ if (this.autoRenew) {
86
+ this.scheduleRenewals();
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Set up event subscriptions for certificate events
92
+ */
93
+ private setupEventSubscriptions(): void {
94
+ // We need to reimplement subscribeToPort80Handler here
95
+ this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, (data: ICertificateData) => {
96
+ this.emit(CertProvisionerEvents.CERTIFICATE_ISSUED, { ...data, source: 'http01', isRenewal: false });
97
+ });
98
+
99
+ this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, (data: ICertificateData) => {
100
+ this.emit(CertProvisionerEvents.CERTIFICATE_RENEWED, { ...data, source: 'http01', isRenewal: true });
101
+ });
102
+
103
+ this.port80Handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, (error) => {
104
+ this.emit(CertProvisionerEvents.CERTIFICATE_FAILED, error);
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Set up forwarding configurations for the Port80Handler
110
+ */
111
+ private setupForwardingConfigs(): void {
112
+ for (const config of this.forwardConfigs) {
113
+ const domainOptions: IDomainOptions = {
114
+ domainName: config.domain,
115
+ sslRedirect: config.sslRedirect || false,
116
+ acmeMaintenance: false,
117
+ forward: config.forwardConfig,
118
+ acmeForward: config.acmeForwardConfig
119
+ };
120
+ this.port80Handler.addDomain(domainOptions);
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Provision certificates for all configured domains
126
+ */
127
+ private async provisionAllDomains(): Promise<void> {
128
+ const domains = this.domainConfigs.flatMap(cfg => cfg.domains);
129
+
130
+ for (const domain of domains) {
131
+ await this.provisionDomain(domain);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Provision a certificate for a single domain
137
+ * @param domain Domain to provision
138
+ */
139
+ private async provisionDomain(domain: string): Promise<void> {
140
+ const isWildcard = domain.includes('*');
141
+ let provision: TCertProvisionObject = 'http01';
142
+
143
+ // Try to get a certificate from the provision function
144
+ if (this.certProvisionFunction) {
145
+ try {
146
+ provision = await this.certProvisionFunction(domain);
147
+ } catch (err) {
148
+ console.error(`certProvider error for ${domain}:`, err);
149
+ }
150
+ } else if (isWildcard) {
151
+ // No certProvider: cannot handle wildcard without DNS-01 support
152
+ console.warn(`Skipping wildcard domain without certProvisionFunction: ${domain}`);
153
+ return;
154
+ }
155
+
156
+ // Handle different provisioning methods
157
+ if (provision === 'http01') {
158
+ if (isWildcard) {
159
+ console.warn(`Skipping HTTP-01 for wildcard domain: ${domain}`);
160
+ return;
161
+ }
162
+
163
+ this.provisionMap.set(domain, 'http01');
164
+ this.port80Handler.addDomain({
165
+ domainName: domain,
166
+ sslRedirect: true,
167
+ acmeMaintenance: true
168
+ });
169
+ } else if (provision === 'dns01') {
170
+ // DNS-01 challenges would be handled by the certProvisionFunction
171
+ this.provisionMap.set(domain, 'dns01');
172
+ // DNS-01 handling would go here if implemented
173
+ } else {
174
+ // Static certificate (e.g., DNS-01 provisioned or user-provided)
175
+ this.provisionMap.set(domain, 'static');
176
+ const certObj = provision as plugins.tsclass.network.ICert;
177
+ const certData: ICertificateData = {
178
+ domain: certObj.domainName,
179
+ certificate: certObj.publicKey,
180
+ privateKey: certObj.privateKey,
181
+ expiryDate: new Date(certObj.validUntil),
182
+ source: 'static',
183
+ isRenewal: false
184
+ };
185
+
186
+ this.networkProxyBridge.applyExternalCertificate(certData);
187
+ this.emit(CertProvisionerEvents.CERTIFICATE_ISSUED, certData);
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Schedule certificate renewals using a task manager
193
+ */
194
+ private scheduleRenewals(): void {
195
+ this.renewManager = new plugins.taskbuffer.TaskManager();
196
+
197
+ const renewTask = new plugins.taskbuffer.Task({
198
+ name: 'CertificateRenewals',
199
+ taskFunction: async () => await this.performRenewals()
200
+ });
201
+
202
+ const hours = this.renewCheckIntervalHours;
203
+ const cronExpr = `0 0 */${hours} * * *`;
204
+
205
+ this.renewManager.addAndScheduleTask(renewTask, cronExpr);
206
+ this.renewManager.start();
207
+ }
208
+
209
+ /**
210
+ * Perform renewals for all domains that need it
211
+ */
212
+ private async performRenewals(): Promise<void> {
213
+ for (const [domain, type] of this.provisionMap.entries()) {
214
+ // Skip wildcard domains for HTTP-01 challenges
215
+ if (domain.includes('*') && type === 'http01') continue;
216
+
217
+ try {
218
+ await this.renewDomain(domain, type);
219
+ } catch (err) {
220
+ console.error(`Renewal error for ${domain}:`, err);
221
+ }
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Renew a certificate for a specific domain
227
+ * @param domain Domain to renew
228
+ * @param provisionType Type of provisioning for this domain
229
+ */
230
+ private async renewDomain(domain: string, provisionType: 'http01' | 'dns01' | 'static'): Promise<void> {
231
+ if (provisionType === 'http01') {
232
+ await this.port80Handler.renewCertificate(domain);
233
+ } else if ((provisionType === 'static' || provisionType === 'dns01') && this.certProvisionFunction) {
234
+ const provision = await this.certProvisionFunction(domain);
235
+
236
+ if (provision !== 'http01' && provision !== 'dns01') {
237
+ const certObj = provision as plugins.tsclass.network.ICert;
238
+ const certData: ICertificateData = {
239
+ domain: certObj.domainName,
240
+ certificate: certObj.publicKey,
241
+ privateKey: certObj.privateKey,
242
+ expiryDate: new Date(certObj.validUntil),
243
+ source: 'static',
244
+ isRenewal: true
245
+ };
246
+
247
+ this.networkProxyBridge.applyExternalCertificate(certData);
248
+ this.emit(CertProvisionerEvents.CERTIFICATE_RENEWED, certData);
249
+ }
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Stop all scheduled renewal tasks.
255
+ */
256
+ public async stop(): Promise<void> {
257
+ if (this.renewManager) {
258
+ this.renewManager.stop();
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Request a certificate on-demand for the given domain.
264
+ * @param domain Domain name to provision
265
+ */
266
+ public async requestCertificate(domain: string): Promise<void> {
267
+ const isWildcard = domain.includes('*');
268
+
269
+ // Determine provisioning method
270
+ let provision: TCertProvisionObject = 'http01';
271
+
272
+ if (this.certProvisionFunction) {
273
+ provision = await this.certProvisionFunction(domain);
274
+ } else if (isWildcard) {
275
+ // Cannot perform HTTP-01 on wildcard without certProvider
276
+ throw new Error(`Cannot request certificate for wildcard domain without certProvisionFunction: ${domain}`);
277
+ }
278
+
279
+ if (provision === 'http01') {
280
+ if (isWildcard) {
281
+ throw new Error(`Cannot request HTTP-01 certificate for wildcard domain: ${domain}`);
282
+ }
283
+ await this.port80Handler.renewCertificate(domain);
284
+ } else if (provision === 'dns01') {
285
+ // DNS-01 challenges would be handled by external mechanisms
286
+ // This is a placeholder for future implementation
287
+ console.log(`DNS-01 challenge requested for ${domain}`);
288
+ } else {
289
+ // Static certificate (e.g., DNS-01 provisioned) supports wildcards
290
+ const certObj = provision as plugins.tsclass.network.ICert;
291
+ const certData: ICertificateData = {
292
+ domain: certObj.domainName,
293
+ certificate: certObj.publicKey,
294
+ privateKey: certObj.privateKey,
295
+ expiryDate: new Date(certObj.validUntil),
296
+ source: 'static',
297
+ isRenewal: false
298
+ };
299
+
300
+ this.networkProxyBridge.applyExternalCertificate(certData);
301
+ this.emit(CertProvisionerEvents.CERTIFICATE_ISSUED, certData);
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Add a new domain for certificate provisioning
307
+ * @param domain Domain to add
308
+ * @param options Domain configuration options
309
+ */
310
+ public async addDomain(domain: string, options?: {
311
+ sslRedirect?: boolean;
312
+ acmeMaintenance?: boolean;
313
+ }): Promise<void> {
314
+ const domainOptions: IDomainOptions = {
315
+ domainName: domain,
316
+ sslRedirect: options?.sslRedirect || true,
317
+ acmeMaintenance: options?.acmeMaintenance || true
318
+ };
319
+
320
+ this.port80Handler.addDomain(domainOptions);
321
+ await this.provisionDomain(domain);
322
+ }
323
+ }
324
+
325
+ // For backward compatibility
326
+ export { CertProvisioner as CertificateProvisioner }
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Certificate providers
3
+ */