@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
@@ -0,0 +1,234 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as plugins from '../../plugins.js';
4
+ import type { ICertificateData, ICertificates } from '../models/certificate-types.js';
5
+ import { ensureCertificateDirectory } from '../utils/certificate-helpers.js';
6
+
7
+ /**
8
+ * FileStorage provides file system storage for certificates
9
+ */
10
+ export class FileStorage {
11
+ private storageDir: string;
12
+
13
+ /**
14
+ * Creates a new file storage provider
15
+ * @param storageDir Directory to store certificates
16
+ */
17
+ constructor(storageDir: string) {
18
+ this.storageDir = path.resolve(storageDir);
19
+ ensureCertificateDirectory(this.storageDir);
20
+ }
21
+
22
+ /**
23
+ * Save a certificate to the file system
24
+ * @param domain Domain name
25
+ * @param certData Certificate data to save
26
+ */
27
+ public async saveCertificate(domain: string, certData: ICertificateData): Promise<void> {
28
+ const sanitizedDomain = this.sanitizeDomain(domain);
29
+ const certDir = path.join(this.storageDir, sanitizedDomain);
30
+ ensureCertificateDirectory(certDir);
31
+
32
+ const certPath = path.join(certDir, 'fullchain.pem');
33
+ const keyPath = path.join(certDir, 'privkey.pem');
34
+ const metaPath = path.join(certDir, 'metadata.json');
35
+
36
+ // Write certificate and private key
37
+ await fs.promises.writeFile(certPath, certData.certificate, 'utf8');
38
+ await fs.promises.writeFile(keyPath, certData.privateKey, 'utf8');
39
+
40
+ // Write metadata
41
+ const metadata = {
42
+ domain: certData.domain,
43
+ expiryDate: certData.expiryDate.toISOString(),
44
+ source: certData.source || 'unknown',
45
+ issuedAt: new Date().toISOString()
46
+ };
47
+
48
+ await fs.promises.writeFile(
49
+ metaPath,
50
+ JSON.stringify(metadata, null, 2),
51
+ 'utf8'
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Load a certificate from the file system
57
+ * @param domain Domain name
58
+ * @returns Certificate data if found, null otherwise
59
+ */
60
+ public async loadCertificate(domain: string): Promise<ICertificateData | null> {
61
+ const sanitizedDomain = this.sanitizeDomain(domain);
62
+ const certDir = path.join(this.storageDir, sanitizedDomain);
63
+
64
+ if (!fs.existsSync(certDir)) {
65
+ return null;
66
+ }
67
+
68
+ const certPath = path.join(certDir, 'fullchain.pem');
69
+ const keyPath = path.join(certDir, 'privkey.pem');
70
+ const metaPath = path.join(certDir, 'metadata.json');
71
+
72
+ try {
73
+ // Check if all required files exist
74
+ if (!fs.existsSync(certPath) || !fs.existsSync(keyPath)) {
75
+ return null;
76
+ }
77
+
78
+ // Read certificate and private key
79
+ const certificate = await fs.promises.readFile(certPath, 'utf8');
80
+ const privateKey = await fs.promises.readFile(keyPath, 'utf8');
81
+
82
+ // Try to read metadata if available
83
+ let expiryDate = new Date();
84
+ let source: 'static' | 'http01' | 'dns01' | undefined;
85
+
86
+ if (fs.existsSync(metaPath)) {
87
+ const metaContent = await fs.promises.readFile(metaPath, 'utf8');
88
+ const metadata = JSON.parse(metaContent);
89
+
90
+ if (metadata.expiryDate) {
91
+ expiryDate = new Date(metadata.expiryDate);
92
+ }
93
+
94
+ if (metadata.source) {
95
+ source = metadata.source as 'static' | 'http01' | 'dns01';
96
+ }
97
+ }
98
+
99
+ return {
100
+ domain,
101
+ certificate,
102
+ privateKey,
103
+ expiryDate,
104
+ source
105
+ };
106
+ } catch (error) {
107
+ console.error(`Error loading certificate for ${domain}:`, error);
108
+ return null;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Delete a certificate from the file system
114
+ * @param domain Domain name
115
+ */
116
+ public async deleteCertificate(domain: string): Promise<boolean> {
117
+ const sanitizedDomain = this.sanitizeDomain(domain);
118
+ const certDir = path.join(this.storageDir, sanitizedDomain);
119
+
120
+ if (!fs.existsSync(certDir)) {
121
+ return false;
122
+ }
123
+
124
+ try {
125
+ // Recursively delete the certificate directory
126
+ await this.deleteDirectory(certDir);
127
+ return true;
128
+ } catch (error) {
129
+ console.error(`Error deleting certificate for ${domain}:`, error);
130
+ return false;
131
+ }
132
+ }
133
+
134
+ /**
135
+ * List all domains with stored certificates
136
+ * @returns Array of domain names
137
+ */
138
+ public async listCertificates(): Promise<string[]> {
139
+ try {
140
+ const entries = await fs.promises.readdir(this.storageDir, { withFileTypes: true });
141
+ return entries
142
+ .filter(entry => entry.isDirectory())
143
+ .map(entry => entry.name);
144
+ } catch (error) {
145
+ console.error('Error listing certificates:', error);
146
+ return [];
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Check if a certificate is expiring soon
152
+ * @param domain Domain name
153
+ * @param thresholdDays Days threshold to consider expiring
154
+ * @returns Information about expiring certificate or null
155
+ */
156
+ public async isExpiringSoon(
157
+ domain: string,
158
+ thresholdDays: number = 30
159
+ ): Promise<{ domain: string; expiryDate: Date; daysRemaining: number } | null> {
160
+ const certData = await this.loadCertificate(domain);
161
+
162
+ if (!certData) {
163
+ return null;
164
+ }
165
+
166
+ const now = new Date();
167
+ const expiryDate = certData.expiryDate;
168
+ const timeRemaining = expiryDate.getTime() - now.getTime();
169
+ const daysRemaining = Math.floor(timeRemaining / (1000 * 60 * 60 * 24));
170
+
171
+ if (daysRemaining <= thresholdDays) {
172
+ return {
173
+ domain,
174
+ expiryDate,
175
+ daysRemaining
176
+ };
177
+ }
178
+
179
+ return null;
180
+ }
181
+
182
+ /**
183
+ * Check all certificates for expiration
184
+ * @param thresholdDays Days threshold to consider expiring
185
+ * @returns List of expiring certificates
186
+ */
187
+ public async getExpiringCertificates(
188
+ thresholdDays: number = 30
189
+ ): Promise<Array<{ domain: string; expiryDate: Date; daysRemaining: number }>> {
190
+ const domains = await this.listCertificates();
191
+ const expiringCerts = [];
192
+
193
+ for (const domain of domains) {
194
+ const expiring = await this.isExpiringSoon(domain, thresholdDays);
195
+ if (expiring) {
196
+ expiringCerts.push(expiring);
197
+ }
198
+ }
199
+
200
+ return expiringCerts;
201
+ }
202
+
203
+ /**
204
+ * Delete a directory recursively
205
+ * @param directoryPath Directory to delete
206
+ */
207
+ private async deleteDirectory(directoryPath: string): Promise<void> {
208
+ if (fs.existsSync(directoryPath)) {
209
+ const entries = await fs.promises.readdir(directoryPath, { withFileTypes: true });
210
+
211
+ for (const entry of entries) {
212
+ const fullPath = path.join(directoryPath, entry.name);
213
+
214
+ if (entry.isDirectory()) {
215
+ await this.deleteDirectory(fullPath);
216
+ } else {
217
+ await fs.promises.unlink(fullPath);
218
+ }
219
+ }
220
+
221
+ await fs.promises.rmdir(directoryPath);
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Sanitize a domain name for use as a directory name
227
+ * @param domain Domain name
228
+ * @returns Sanitized domain name
229
+ */
230
+ private sanitizeDomain(domain: string): string {
231
+ // Replace wildcard and any invalid filesystem characters
232
+ return domain.replace(/\*/g, '_wildcard_').replace(/[/\\:*?"<>|]/g, '_');
233
+ }
234
+ }
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Certificate storage mechanisms
3
+ */
@@ -0,0 +1,50 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import type { ICertificates } from '../models/certificate-types.js';
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+
8
+ /**
9
+ * Loads the default SSL certificates from the assets directory
10
+ * @returns The certificate key pair
11
+ */
12
+ export function loadDefaultCertificates(): ICertificates {
13
+ try {
14
+ // Need to adjust path from /ts/certificate/utils to /assets/certs
15
+ const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs');
16
+ const privateKey = fs.readFileSync(path.join(certPath, 'key.pem'), 'utf8');
17
+ const publicKey = fs.readFileSync(path.join(certPath, 'cert.pem'), 'utf8');
18
+
19
+ if (!privateKey || !publicKey) {
20
+ throw new Error('Failed to load default certificates');
21
+ }
22
+
23
+ return {
24
+ privateKey,
25
+ publicKey
26
+ };
27
+ } catch (error) {
28
+ console.error('Error loading default certificates:', error);
29
+ throw error;
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Checks if a certificate file exists at the specified path
35
+ * @param certPath Path to check for certificate
36
+ * @returns True if the certificate exists, false otherwise
37
+ */
38
+ export function certificateExists(certPath: string): boolean {
39
+ return fs.existsSync(certPath);
40
+ }
41
+
42
+ /**
43
+ * Ensures the certificate directory exists
44
+ * @param dirPath Path to the certificate directory
45
+ */
46
+ export function ensureCertificateDirectory(dirPath: string): void {
47
+ if (!fs.existsSync(dirPath)) {
48
+ fs.mkdirSync(dirPath, { recursive: true });
49
+ }
50
+ }
@@ -1,4 +1,4 @@
1
- import type { Port80Handler } from '../port80handler/classes.port80handler.js';
1
+ import type { Port80Handler } from '../http/port80/port80-handler.js';
2
2
  import { Port80HandlerEvents } from './types.js';
3
3
  import type { ICertificateData, ICertificateFailure, ICertificateExpiring } from './types.js';
4
4
 
@@ -7,7 +7,7 @@ import type {
7
7
 
8
8
  import type {
9
9
  IForwardConfig
10
- } from '../smartproxy/types/forwarding.types.js';
10
+ } from '../forwarding/config/forwarding-types.js';
11
11
 
12
12
  /**
13
13
  * Converts a forwarding configuration target to the legacy format
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Common event definitions
3
+ */
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Core functionality module
3
+ */
4
+
5
+ // Export submodules
6
+ export * from './models/index.js';
7
+ export * from './utils/index.js';
8
+ export * from './events/index.js';
@@ -0,0 +1,91 @@
1
+ import * as plugins from '../../plugins.js';
2
+
3
+ /**
4
+ * Shared types for certificate management and domain options
5
+ */
6
+
7
+ /**
8
+ * Domain forwarding configuration
9
+ */
10
+ export interface IForwardConfig {
11
+ ip: string;
12
+ port: number;
13
+ }
14
+
15
+ /**
16
+ * Domain configuration options
17
+ */
18
+ export interface IDomainOptions {
19
+ domainName: string;
20
+ sslRedirect: boolean; // if true redirects the request to port 443
21
+ acmeMaintenance: boolean; // tries to always have a valid cert for this domain
22
+ forward?: IForwardConfig; // forwards all http requests to that target
23
+ acmeForward?: IForwardConfig; // forwards letsencrypt requests to this config
24
+ }
25
+
26
+ /**
27
+ * Certificate data that can be emitted via events or set from outside
28
+ */
29
+ export interface ICertificateData {
30
+ domain: string;
31
+ certificate: string;
32
+ privateKey: string;
33
+ expiryDate: Date;
34
+ }
35
+
36
+ /**
37
+ * Events emitted by the Port80Handler
38
+ */
39
+ export enum Port80HandlerEvents {
40
+ CERTIFICATE_ISSUED = 'certificate-issued',
41
+ CERTIFICATE_RENEWED = 'certificate-renewed',
42
+ CERTIFICATE_FAILED = 'certificate-failed',
43
+ CERTIFICATE_EXPIRING = 'certificate-expiring',
44
+ MANAGER_STARTED = 'manager-started',
45
+ MANAGER_STOPPED = 'manager-stopped',
46
+ REQUEST_FORWARDED = 'request-forwarded',
47
+ }
48
+
49
+ /**
50
+ * Certificate failure payload type
51
+ */
52
+ export interface ICertificateFailure {
53
+ domain: string;
54
+ error: string;
55
+ isRenewal: boolean;
56
+ }
57
+
58
+ /**
59
+ * Certificate expiry payload type
60
+ */
61
+ export interface ICertificateExpiring {
62
+ domain: string;
63
+ expiryDate: Date;
64
+ daysRemaining: number;
65
+ }
66
+ /**
67
+ * Forwarding configuration for specific domains in ACME setup
68
+ */
69
+ export interface IDomainForwardConfig {
70
+ domain: string;
71
+ forwardConfig?: IForwardConfig;
72
+ acmeForwardConfig?: IForwardConfig;
73
+ sslRedirect?: boolean;
74
+ }
75
+
76
+ /**
77
+ * Unified ACME configuration options used across proxies and handlers
78
+ */
79
+ export interface IAcmeOptions {
80
+ accountEmail?: string; // Email for Let's Encrypt account
81
+ enabled?: boolean; // Whether ACME is enabled
82
+ port?: number; // Port to listen on for ACME challenges (default: 80)
83
+ useProduction?: boolean; // Use production environment (default: staging)
84
+ httpsRedirectPort?: number; // Port to redirect HTTP requests to HTTPS (default: 443)
85
+ renewThresholdDays?: number; // Days before expiry to renew certificates
86
+ renewCheckIntervalHours?: number; // How often to check for renewals (in hours)
87
+ autoRenew?: boolean; // Whether to automatically renew certificates
88
+ certificateStore?: string; // Directory to store certificates
89
+ skipConfiguredCerts?: boolean; // Skip domains with existing certificates
90
+ domainForwards?: IDomainForwardConfig[]; // Domain-specific forwarding configs
91
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Core data models and interfaces
3
+ */
4
+
5
+ export * from './common-types.js';
@@ -0,0 +1,34 @@
1
+ import type { Port80Handler } from '../../http/port80/port80-handler.js';
2
+ import { Port80HandlerEvents } from '../models/common-types.js';
3
+ import type { ICertificateData, ICertificateFailure, ICertificateExpiring } from '../models/common-types.js';
4
+
5
+ /**
6
+ * Subscribers callback definitions for Port80Handler events
7
+ */
8
+ export interface IPort80HandlerSubscribers {
9
+ onCertificateIssued?: (data: ICertificateData) => void;
10
+ onCertificateRenewed?: (data: ICertificateData) => void;
11
+ onCertificateFailed?: (data: ICertificateFailure) => void;
12
+ onCertificateExpiring?: (data: ICertificateExpiring) => void;
13
+ }
14
+
15
+ /**
16
+ * Subscribes to Port80Handler events based on provided callbacks
17
+ */
18
+ export function subscribeToPort80Handler(
19
+ handler: Port80Handler,
20
+ subscribers: IPort80HandlerSubscribers
21
+ ): void {
22
+ if (subscribers.onCertificateIssued) {
23
+ handler.on(Port80HandlerEvents.CERTIFICATE_ISSUED, subscribers.onCertificateIssued);
24
+ }
25
+ if (subscribers.onCertificateRenewed) {
26
+ handler.on(Port80HandlerEvents.CERTIFICATE_RENEWED, subscribers.onCertificateRenewed);
27
+ }
28
+ if (subscribers.onCertificateFailed) {
29
+ handler.on(Port80HandlerEvents.CERTIFICATE_FAILED, subscribers.onCertificateFailed);
30
+ }
31
+ if (subscribers.onCertificateExpiring) {
32
+ handler.on(Port80HandlerEvents.CERTIFICATE_EXPIRING, subscribers.onCertificateExpiring);
33
+ }
34
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Core utility functions
3
+ */
4
+
5
+ export * from './event-utils.js';
6
+ export * from './validation-utils.js';
7
+ export * from './ip-utils.js';
@@ -0,0 +1,175 @@
1
+ import * as plugins from '../../plugins.js';
2
+
3
+ /**
4
+ * Utility class for IP address operations
5
+ */
6
+ export class IpUtils {
7
+ /**
8
+ * Check if the IP matches any of the glob patterns
9
+ *
10
+ * This method checks IP addresses against glob patterns and handles IPv4/IPv6 normalization.
11
+ * It's used to implement IP filtering based on security configurations.
12
+ *
13
+ * @param ip - The IP address to check
14
+ * @param patterns - Array of glob patterns
15
+ * @returns true if IP matches any pattern, false otherwise
16
+ */
17
+ public static isGlobIPMatch(ip: string, patterns: string[]): boolean {
18
+ if (!ip || !patterns || patterns.length === 0) return false;
19
+
20
+ // Normalize the IP being checked
21
+ const normalizedIPVariants = this.normalizeIP(ip);
22
+ if (normalizedIPVariants.length === 0) return false;
23
+
24
+ // Normalize the pattern IPs for consistent comparison
25
+ const expandedPatterns = patterns.flatMap(pattern => this.normalizeIP(pattern));
26
+
27
+ // Check for any match between normalized IP variants and patterns
28
+ return normalizedIPVariants.some((ipVariant) =>
29
+ expandedPatterns.some((pattern) => plugins.minimatch(ipVariant, pattern))
30
+ );
31
+ }
32
+
33
+ /**
34
+ * Normalize IP addresses for consistent comparison
35
+ *
36
+ * @param ip The IP address to normalize
37
+ * @returns Array of normalized IP forms
38
+ */
39
+ public static normalizeIP(ip: string): string[] {
40
+ if (!ip) return [];
41
+
42
+ // Handle IPv4-mapped IPv6 addresses (::ffff:127.0.0.1)
43
+ if (ip.startsWith('::ffff:')) {
44
+ const ipv4 = ip.slice(7);
45
+ return [ip, ipv4];
46
+ }
47
+
48
+ // Handle IPv4 addresses by also checking IPv4-mapped form
49
+ if (/^\d{1,3}(\.\d{1,3}){3}$/.test(ip)) {
50
+ return [ip, `::ffff:${ip}`];
51
+ }
52
+
53
+ return [ip];
54
+ }
55
+
56
+ /**
57
+ * Check if an IP is authorized using security rules
58
+ *
59
+ * @param ip - The IP address to check
60
+ * @param allowedIPs - Array of allowed IP patterns
61
+ * @param blockedIPs - Array of blocked IP patterns
62
+ * @returns true if IP is authorized, false if blocked
63
+ */
64
+ public static isIPAuthorized(ip: string, allowedIPs: string[] = [], blockedIPs: string[] = []): boolean {
65
+ // Skip IP validation if no rules are defined
66
+ if (!ip || (allowedIPs.length === 0 && blockedIPs.length === 0)) {
67
+ return true;
68
+ }
69
+
70
+ // First check if IP is blocked - blocked IPs take precedence
71
+ if (blockedIPs.length > 0 && this.isGlobIPMatch(ip, blockedIPs)) {
72
+ return false;
73
+ }
74
+
75
+ // Then check if IP is allowed (if no allowed IPs are specified, all non-blocked IPs are allowed)
76
+ return allowedIPs.length === 0 || this.isGlobIPMatch(ip, allowedIPs);
77
+ }
78
+
79
+ /**
80
+ * Check if an IP address is a private network address
81
+ *
82
+ * @param ip The IP address to check
83
+ * @returns true if the IP is a private network address, false otherwise
84
+ */
85
+ public static isPrivateIP(ip: string): boolean {
86
+ if (!ip) return false;
87
+
88
+ // Handle IPv4-mapped IPv6 addresses
89
+ if (ip.startsWith('::ffff:')) {
90
+ ip = ip.slice(7);
91
+ }
92
+
93
+ // Check IPv4 private ranges
94
+ if (/^\d{1,3}(\.\d{1,3}){3}$/.test(ip)) {
95
+ const parts = ip.split('.').map(Number);
96
+
97
+ // Check common private ranges
98
+ // 10.0.0.0/8
99
+ if (parts[0] === 10) return true;
100
+
101
+ // 172.16.0.0/12
102
+ if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) return true;
103
+
104
+ // 192.168.0.0/16
105
+ if (parts[0] === 192 && parts[1] === 168) return true;
106
+
107
+ // 127.0.0.0/8 (localhost)
108
+ if (parts[0] === 127) return true;
109
+
110
+ return false;
111
+ }
112
+
113
+ // IPv6 local addresses
114
+ return ip === '::1' || ip.startsWith('fc00:') || ip.startsWith('fd00:') || ip.startsWith('fe80:');
115
+ }
116
+
117
+ /**
118
+ * Check if an IP address is a public network address
119
+ *
120
+ * @param ip The IP address to check
121
+ * @returns true if the IP is a public network address, false otherwise
122
+ */
123
+ public static isPublicIP(ip: string): boolean {
124
+ return !this.isPrivateIP(ip);
125
+ }
126
+
127
+ /**
128
+ * Convert a subnet CIDR to an IP range for filtering
129
+ *
130
+ * @param cidr The CIDR notation (e.g., "192.168.1.0/24")
131
+ * @returns Array of glob patterns that match the CIDR range
132
+ */
133
+ public static cidrToGlobPatterns(cidr: string): string[] {
134
+ if (!cidr || !cidr.includes('/')) return [];
135
+
136
+ const [ipPart, prefixPart] = cidr.split('/');
137
+ const prefix = parseInt(prefixPart, 10);
138
+
139
+ if (isNaN(prefix) || prefix < 0 || prefix > 32) return [];
140
+
141
+ // For IPv4 only for now
142
+ if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(ipPart)) return [];
143
+
144
+ const ipParts = ipPart.split('.').map(Number);
145
+ const fullMask = Math.pow(2, 32 - prefix) - 1;
146
+
147
+ // Convert IP to a numeric value
148
+ const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
149
+
150
+ // Calculate network address (IP & ~fullMask)
151
+ const networkNum = ipNum & ~fullMask;
152
+
153
+ // For large ranges, return wildcard patterns
154
+ if (prefix <= 8) {
155
+ return [`${(networkNum >>> 24) & 255}.*.*.*`];
156
+ } else if (prefix <= 16) {
157
+ return [`${(networkNum >>> 24) & 255}.${(networkNum >>> 16) & 255}.*.*`];
158
+ } else if (prefix <= 24) {
159
+ return [`${(networkNum >>> 24) & 255}.${(networkNum >>> 16) & 255}.${(networkNum >>> 8) & 255}.*`];
160
+ }
161
+
162
+ // For small ranges, create individual IP patterns
163
+ const patterns = [];
164
+ const maxAddresses = Math.min(256, Math.pow(2, 32 - prefix));
165
+
166
+ for (let i = 0; i < maxAddresses; i++) {
167
+ const currentIpNum = networkNum + i;
168
+ patterns.push(
169
+ `${(currentIpNum >>> 24) & 255}.${(currentIpNum >>> 16) & 255}.${(currentIpNum >>> 8) & 255}.${currentIpNum & 255}`
170
+ );
171
+ }
172
+
173
+ return patterns;
174
+ }
175
+ }