@serve.zone/dcrouter 2.12.4

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 (737) hide show
  1. package/.dockerignore +1 -0
  2. package/.gitea/workflows/docker_nottags.yaml +71 -0
  3. package/.gitea/workflows/docker_tags.yaml +106 -0
  4. package/.vscode/launch.json +11 -0
  5. package/.vscode/settings.json +26 -0
  6. package/Dockerfile +46 -0
  7. package/changelog.md +247 -0
  8. package/cli.child.js +4 -0
  9. package/cli.child.ts +4 -0
  10. package/cli.js +4 -0
  11. package/cli.ts.js +5 -0
  12. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  13. package/dist_ts/00_commitinfo_data.js +9 -0
  14. package/dist_ts/classes.dcrouter.d.ts +238 -0
  15. package/dist_ts/classes.dcrouter.js +1008 -0
  16. package/dist_ts/config/index.d.ts +1 -0
  17. package/dist_ts/config/index.js +3 -0
  18. package/dist_ts/config/validator.d.ts +104 -0
  19. package/dist_ts/config/validator.js +152 -0
  20. package/dist_ts/deliverability/classes.ipwarmupmanager.d.ts +253 -0
  21. package/dist_ts/deliverability/classes.ipwarmupmanager.js +639 -0
  22. package/dist_ts/deliverability/classes.senderreputationmonitor.d.ts +300 -0
  23. package/dist_ts/deliverability/classes.senderreputationmonitor.js +961 -0
  24. package/dist_ts/deliverability/index.d.ts +2 -0
  25. package/dist_ts/deliverability/index.js +3 -0
  26. package/dist_ts/errors/base.errors.d.ts +224 -0
  27. package/dist_ts/errors/base.errors.js +310 -0
  28. package/dist_ts/errors/email.errors.d.ts +175 -0
  29. package/dist_ts/errors/email.errors.js +265 -0
  30. package/dist_ts/errors/error-handler.d.ts +98 -0
  31. package/dist_ts/errors/error-handler.js +282 -0
  32. package/dist_ts/errors/error.codes.d.ts +115 -0
  33. package/dist_ts/errors/error.codes.js +136 -0
  34. package/dist_ts/errors/index.d.ts +56 -0
  35. package/dist_ts/errors/index.js +138 -0
  36. package/dist_ts/errors/mta.errors.d.ts +259 -0
  37. package/dist_ts/errors/mta.errors.js +472 -0
  38. package/dist_ts/errors/reputation.errors.d.ts +183 -0
  39. package/dist_ts/errors/reputation.errors.js +292 -0
  40. package/dist_ts/index.d.ts +4 -0
  41. package/dist_ts/index.js +6 -0
  42. package/dist_ts/logger.d.ts +17 -0
  43. package/dist_ts/logger.js +77 -0
  44. package/dist_ts/mail/core/classes.bouncemanager.d.ts +200 -0
  45. package/dist_ts/mail/core/classes.bouncemanager.js +778 -0
  46. package/dist_ts/mail/core/classes.email.d.ts +291 -0
  47. package/dist_ts/mail/core/classes.email.js +780 -0
  48. package/dist_ts/mail/core/classes.emailvalidator.d.ts +61 -0
  49. package/dist_ts/mail/core/classes.emailvalidator.js +182 -0
  50. package/dist_ts/mail/core/classes.templatemanager.d.ts +95 -0
  51. package/dist_ts/mail/core/classes.templatemanager.js +239 -0
  52. package/dist_ts/mail/core/index.d.ts +4 -0
  53. package/dist_ts/mail/core/index.js +6 -0
  54. package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
  55. package/dist_ts/mail/delivery/classes.delivery.queue.js +485 -0
  56. package/dist_ts/mail/delivery/classes.delivery.system.d.ts +186 -0
  57. package/dist_ts/mail/delivery/classes.delivery.system.js +846 -0
  58. package/dist_ts/mail/delivery/classes.emailsendjob.d.ts +84 -0
  59. package/dist_ts/mail/delivery/classes.emailsendjob.js +362 -0
  60. package/dist_ts/mail/delivery/classes.emailsignjob.d.ts +18 -0
  61. package/dist_ts/mail/delivery/classes.emailsignjob.js +44 -0
  62. package/dist_ts/mail/delivery/classes.mta.config.d.ts +22 -0
  63. package/dist_ts/mail/delivery/classes.mta.config.js +51 -0
  64. package/dist_ts/mail/delivery/classes.ratelimiter.d.ts +98 -0
  65. package/dist_ts/mail/delivery/classes.ratelimiter.js +205 -0
  66. package/dist_ts/mail/delivery/classes.smtp.client.legacy.d.ts +275 -0
  67. package/dist_ts/mail/delivery/classes.smtp.client.legacy.js +973 -0
  68. package/dist_ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
  69. package/dist_ts/mail/delivery/classes.unified.rate.limiter.js +817 -0
  70. package/dist_ts/mail/delivery/index.d.ts +12 -0
  71. package/dist_ts/mail/delivery/index.js +18 -0
  72. package/dist_ts/mail/delivery/interfaces.d.ts +243 -0
  73. package/dist_ts/mail/delivery/interfaces.js +17 -0
  74. package/dist_ts/mail/delivery/smtpclient/auth-handler.d.ts +43 -0
  75. package/dist_ts/mail/delivery/smtpclient/auth-handler.js +188 -0
  76. package/dist_ts/mail/delivery/smtpclient/command-handler.d.ts +67 -0
  77. package/dist_ts/mail/delivery/smtpclient/command-handler.js +276 -0
  78. package/dist_ts/mail/delivery/smtpclient/connection-manager.d.ts +48 -0
  79. package/dist_ts/mail/delivery/smtpclient/connection-manager.js +238 -0
  80. package/dist_ts/mail/delivery/smtpclient/constants.d.ts +129 -0
  81. package/dist_ts/mail/delivery/smtpclient/constants.js +135 -0
  82. package/dist_ts/mail/delivery/smtpclient/create-client.d.ts +22 -0
  83. package/dist_ts/mail/delivery/smtpclient/create-client.js +86 -0
  84. package/dist_ts/mail/delivery/smtpclient/error-handler.d.ts +28 -0
  85. package/dist_ts/mail/delivery/smtpclient/error-handler.js +110 -0
  86. package/dist_ts/mail/delivery/smtpclient/index.d.ts +16 -0
  87. package/dist_ts/mail/delivery/smtpclient/index.js +21 -0
  88. package/dist_ts/mail/delivery/smtpclient/interfaces.d.ts +183 -0
  89. package/dist_ts/mail/delivery/smtpclient/interfaces.js +19 -0
  90. package/dist_ts/mail/delivery/smtpclient/smtp-client.d.ts +58 -0
  91. package/dist_ts/mail/delivery/smtpclient/smtp-client.js +279 -0
  92. package/dist_ts/mail/delivery/smtpclient/tls-handler.d.ts +33 -0
  93. package/dist_ts/mail/delivery/smtpclient/tls-handler.js +202 -0
  94. package/dist_ts/mail/delivery/smtpclient/utils/helpers.d.ts +77 -0
  95. package/dist_ts/mail/delivery/smtpclient/utils/helpers.js +196 -0
  96. package/dist_ts/mail/delivery/smtpclient/utils/logging.d.ts +46 -0
  97. package/dist_ts/mail/delivery/smtpclient/utils/logging.js +153 -0
  98. package/dist_ts/mail/delivery/smtpclient/utils/validation.d.ts +38 -0
  99. package/dist_ts/mail/delivery/smtpclient/utils/validation.js +139 -0
  100. package/dist_ts/mail/delivery/smtpserver/certificate-utils.d.ts +45 -0
  101. package/dist_ts/mail/delivery/smtpserver/certificate-utils.js +345 -0
  102. package/dist_ts/mail/delivery/smtpserver/command-handler.d.ts +156 -0
  103. package/dist_ts/mail/delivery/smtpserver/command-handler.js +1159 -0
  104. package/dist_ts/mail/delivery/smtpserver/connection-manager.d.ts +159 -0
  105. package/dist_ts/mail/delivery/smtpserver/connection-manager.js +894 -0
  106. package/dist_ts/mail/delivery/smtpserver/constants.d.ts +130 -0
  107. package/dist_ts/mail/delivery/smtpserver/constants.js +162 -0
  108. package/dist_ts/mail/delivery/smtpserver/create-server.d.ts +14 -0
  109. package/dist_ts/mail/delivery/smtpserver/create-server.js +28 -0
  110. package/dist_ts/mail/delivery/smtpserver/data-handler.d.ts +123 -0
  111. package/dist_ts/mail/delivery/smtpserver/data-handler.js +1148 -0
  112. package/dist_ts/mail/delivery/smtpserver/index.d.ts +20 -0
  113. package/dist_ts/mail/delivery/smtpserver/index.js +27 -0
  114. package/dist_ts/mail/delivery/smtpserver/interfaces.d.ts +530 -0
  115. package/dist_ts/mail/delivery/smtpserver/interfaces.js +10 -0
  116. package/dist_ts/mail/delivery/smtpserver/secure-server.d.ts +15 -0
  117. package/dist_ts/mail/delivery/smtpserver/secure-server.js +79 -0
  118. package/dist_ts/mail/delivery/smtpserver/security-handler.d.ts +86 -0
  119. package/dist_ts/mail/delivery/smtpserver/security-handler.js +234 -0
  120. package/dist_ts/mail/delivery/smtpserver/session-manager.d.ts +140 -0
  121. package/dist_ts/mail/delivery/smtpserver/session-manager.js +469 -0
  122. package/dist_ts/mail/delivery/smtpserver/smtp-server.d.ts +137 -0
  123. package/dist_ts/mail/delivery/smtpserver/smtp-server.js +666 -0
  124. package/dist_ts/mail/delivery/smtpserver/starttls-handler.d.ts +21 -0
  125. package/dist_ts/mail/delivery/smtpserver/starttls-handler.js +207 -0
  126. package/dist_ts/mail/delivery/smtpserver/tls-handler.d.ts +66 -0
  127. package/dist_ts/mail/delivery/smtpserver/tls-handler.js +261 -0
  128. package/dist_ts/mail/delivery/smtpserver/utils/adaptive-logging.d.ts +117 -0
  129. package/dist_ts/mail/delivery/smtpserver/utils/adaptive-logging.js +411 -0
  130. package/dist_ts/mail/delivery/smtpserver/utils/helpers.d.ts +78 -0
  131. package/dist_ts/mail/delivery/smtpserver/utils/helpers.js +208 -0
  132. package/dist_ts/mail/delivery/smtpserver/utils/logging.d.ts +106 -0
  133. package/dist_ts/mail/delivery/smtpserver/utils/logging.js +181 -0
  134. package/dist_ts/mail/delivery/smtpserver/utils/validation.d.ts +69 -0
  135. package/dist_ts/mail/delivery/smtpserver/utils/validation.js +360 -0
  136. package/dist_ts/mail/index.d.ts +8 -0
  137. package/dist_ts/mail/index.js +13 -0
  138. package/dist_ts/mail/routing/classes.dns.manager.d.ts +65 -0
  139. package/dist_ts/mail/routing/classes.dns.manager.js +413 -0
  140. package/dist_ts/mail/routing/classes.dnsmanager.d.ts +165 -0
  141. package/dist_ts/mail/routing/classes.dnsmanager.js +430 -0
  142. package/dist_ts/mail/routing/classes.domain.registry.d.ts +54 -0
  143. package/dist_ts/mail/routing/classes.domain.registry.js +118 -0
  144. package/dist_ts/mail/routing/classes.email.config.d.ts +64 -0
  145. package/dist_ts/mail/routing/classes.email.config.js +2 -0
  146. package/dist_ts/mail/routing/classes.email.router.d.ts +171 -0
  147. package/dist_ts/mail/routing/classes.email.router.js +491 -0
  148. package/dist_ts/mail/routing/classes.unified.email.server.d.ts +426 -0
  149. package/dist_ts/mail/routing/classes.unified.email.server.js +1454 -0
  150. package/dist_ts/mail/routing/index.d.ts +5 -0
  151. package/dist_ts/mail/routing/index.js +7 -0
  152. package/dist_ts/mail/routing/interfaces.d.ts +187 -0
  153. package/dist_ts/mail/routing/interfaces.js +2 -0
  154. package/dist_ts/mail/security/classes.dkimcreator.d.ts +68 -0
  155. package/dist_ts/mail/security/classes.dkimcreator.js +346 -0
  156. package/dist_ts/mail/security/classes.dkimverifier.d.ts +46 -0
  157. package/dist_ts/mail/security/classes.dkimverifier.js +317 -0
  158. package/dist_ts/mail/security/classes.dmarcverifier.d.ts +123 -0
  159. package/dist_ts/mail/security/classes.dmarcverifier.js +365 -0
  160. package/dist_ts/mail/security/classes.spfverifier.d.ts +103 -0
  161. package/dist_ts/mail/security/classes.spfverifier.js +492 -0
  162. package/dist_ts/mail/security/index.d.ts +4 -0
  163. package/dist_ts/mail/security/index.js +6 -0
  164. package/dist_ts/opsserver/classes.opsserver.d.ts +14 -0
  165. package/dist_ts/opsserver/classes.opsserver.js +37 -0
  166. package/dist_ts/opsserver/index.d.ts +1 -0
  167. package/dist_ts/opsserver/index.js +2 -0
  168. package/dist_ts/paths.d.ts +14 -0
  169. package/dist_ts/paths.js +39 -0
  170. package/dist_ts/plugins.d.ts +43 -0
  171. package/dist_ts/plugins.js +50 -0
  172. package/dist_ts/security/classes.contentscanner.d.ts +160 -0
  173. package/dist_ts/security/classes.contentscanner.js +634 -0
  174. package/dist_ts/security/classes.ipreputationchecker.d.ts +150 -0
  175. package/dist_ts/security/classes.ipreputationchecker.js +508 -0
  176. package/dist_ts/security/classes.securitylogger.d.ts +140 -0
  177. package/dist_ts/security/classes.securitylogger.js +232 -0
  178. package/dist_ts/security/index.d.ts +3 -0
  179. package/dist_ts/security/index.js +4 -0
  180. package/dist_ts/sms/classes.smsservice.d.ts +15 -0
  181. package/dist_ts/sms/classes.smsservice.js +72 -0
  182. package/dist_ts/sms/config/sms.config.d.ts +93 -0
  183. package/dist_ts/sms/config/sms.config.js +2 -0
  184. package/dist_ts/sms/config/sms.schema.d.ts +5 -0
  185. package/dist_ts/sms/config/sms.schema.js +121 -0
  186. package/dist_ts/sms/index.d.ts +1 -0
  187. package/dist_ts/sms/index.js +2 -0
  188. package/dist_ts/storage/classes.storagemanager.d.ts +82 -0
  189. package/dist_ts/storage/classes.storagemanager.js +341 -0
  190. package/dist_ts/storage/index.d.ts +1 -0
  191. package/dist_ts/storage/index.js +3 -0
  192. package/dist_ts/ts/00_commitinfo_data.d.ts +8 -0
  193. package/dist_ts/ts/00_commitinfo_data.js +9 -0
  194. package/dist_ts/ts/classes.dcrouter.d.ts +238 -0
  195. package/dist_ts/ts/classes.dcrouter.js +1008 -0
  196. package/dist_ts/ts/config/index.d.ts +1 -0
  197. package/dist_ts/ts/config/index.js +3 -0
  198. package/dist_ts/ts/config/validator.d.ts +104 -0
  199. package/dist_ts/ts/config/validator.js +152 -0
  200. package/dist_ts/ts/deliverability/classes.ipwarmupmanager.d.ts +253 -0
  201. package/dist_ts/ts/deliverability/classes.ipwarmupmanager.js +639 -0
  202. package/dist_ts/ts/deliverability/classes.senderreputationmonitor.d.ts +300 -0
  203. package/dist_ts/ts/deliverability/classes.senderreputationmonitor.js +961 -0
  204. package/dist_ts/ts/deliverability/index.d.ts +2 -0
  205. package/dist_ts/ts/deliverability/index.js +3 -0
  206. package/dist_ts/ts/errors/base.errors.d.ts +224 -0
  207. package/dist_ts/ts/errors/base.errors.js +310 -0
  208. package/dist_ts/ts/errors/email.errors.d.ts +175 -0
  209. package/dist_ts/ts/errors/email.errors.js +265 -0
  210. package/dist_ts/ts/errors/error-handler.d.ts +98 -0
  211. package/dist_ts/ts/errors/error-handler.js +282 -0
  212. package/dist_ts/ts/errors/error.codes.d.ts +115 -0
  213. package/dist_ts/ts/errors/error.codes.js +136 -0
  214. package/dist_ts/ts/errors/index.d.ts +56 -0
  215. package/dist_ts/ts/errors/index.js +138 -0
  216. package/dist_ts/ts/errors/mta.errors.d.ts +259 -0
  217. package/dist_ts/ts/errors/mta.errors.js +472 -0
  218. package/dist_ts/ts/errors/reputation.errors.d.ts +183 -0
  219. package/dist_ts/ts/errors/reputation.errors.js +292 -0
  220. package/dist_ts/ts/index.d.ts +4 -0
  221. package/dist_ts/ts/index.js +6 -0
  222. package/dist_ts/ts/logger.d.ts +17 -0
  223. package/dist_ts/ts/logger.js +77 -0
  224. package/dist_ts/ts/mail/core/classes.bouncemanager.d.ts +200 -0
  225. package/dist_ts/ts/mail/core/classes.bouncemanager.js +778 -0
  226. package/dist_ts/ts/mail/core/classes.email.d.ts +291 -0
  227. package/dist_ts/ts/mail/core/classes.email.js +780 -0
  228. package/dist_ts/ts/mail/core/classes.emailvalidator.d.ts +61 -0
  229. package/dist_ts/ts/mail/core/classes.emailvalidator.js +182 -0
  230. package/dist_ts/ts/mail/core/classes.templatemanager.d.ts +95 -0
  231. package/dist_ts/ts/mail/core/classes.templatemanager.js +239 -0
  232. package/dist_ts/ts/mail/core/index.d.ts +4 -0
  233. package/dist_ts/ts/mail/core/index.js +6 -0
  234. package/dist_ts/ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
  235. package/dist_ts/ts/mail/delivery/classes.delivery.queue.js +485 -0
  236. package/dist_ts/ts/mail/delivery/classes.delivery.system.d.ts +186 -0
  237. package/dist_ts/ts/mail/delivery/classes.delivery.system.js +846 -0
  238. package/dist_ts/ts/mail/delivery/classes.emailsendjob.d.ts +84 -0
  239. package/dist_ts/ts/mail/delivery/classes.emailsendjob.js +362 -0
  240. package/dist_ts/ts/mail/delivery/classes.emailsignjob.d.ts +18 -0
  241. package/dist_ts/ts/mail/delivery/classes.emailsignjob.js +44 -0
  242. package/dist_ts/ts/mail/delivery/classes.mta.config.d.ts +22 -0
  243. package/dist_ts/ts/mail/delivery/classes.mta.config.js +51 -0
  244. package/dist_ts/ts/mail/delivery/classes.ratelimiter.d.ts +98 -0
  245. package/dist_ts/ts/mail/delivery/classes.ratelimiter.js +205 -0
  246. package/dist_ts/ts/mail/delivery/classes.smtp.client.legacy.d.ts +275 -0
  247. package/dist_ts/ts/mail/delivery/classes.smtp.client.legacy.js +973 -0
  248. package/dist_ts/ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
  249. package/dist_ts/ts/mail/delivery/classes.unified.rate.limiter.js +817 -0
  250. package/dist_ts/ts/mail/delivery/index.d.ts +12 -0
  251. package/dist_ts/ts/mail/delivery/index.js +18 -0
  252. package/dist_ts/ts/mail/delivery/interfaces.d.ts +243 -0
  253. package/dist_ts/ts/mail/delivery/interfaces.js +17 -0
  254. package/dist_ts/ts/mail/delivery/smtpclient/auth-handler.d.ts +43 -0
  255. package/dist_ts/ts/mail/delivery/smtpclient/auth-handler.js +188 -0
  256. package/dist_ts/ts/mail/delivery/smtpclient/command-handler.d.ts +67 -0
  257. package/dist_ts/ts/mail/delivery/smtpclient/command-handler.js +276 -0
  258. package/dist_ts/ts/mail/delivery/smtpclient/connection-manager.d.ts +48 -0
  259. package/dist_ts/ts/mail/delivery/smtpclient/connection-manager.js +238 -0
  260. package/dist_ts/ts/mail/delivery/smtpclient/constants.d.ts +129 -0
  261. package/dist_ts/ts/mail/delivery/smtpclient/constants.js +135 -0
  262. package/dist_ts/ts/mail/delivery/smtpclient/create-client.d.ts +22 -0
  263. package/dist_ts/ts/mail/delivery/smtpclient/create-client.js +86 -0
  264. package/dist_ts/ts/mail/delivery/smtpclient/error-handler.d.ts +28 -0
  265. package/dist_ts/ts/mail/delivery/smtpclient/error-handler.js +110 -0
  266. package/dist_ts/ts/mail/delivery/smtpclient/index.d.ts +16 -0
  267. package/dist_ts/ts/mail/delivery/smtpclient/index.js +21 -0
  268. package/dist_ts/ts/mail/delivery/smtpclient/interfaces.d.ts +183 -0
  269. package/dist_ts/ts/mail/delivery/smtpclient/interfaces.js +19 -0
  270. package/dist_ts/ts/mail/delivery/smtpclient/smtp-client.d.ts +58 -0
  271. package/dist_ts/ts/mail/delivery/smtpclient/smtp-client.js +279 -0
  272. package/dist_ts/ts/mail/delivery/smtpclient/tls-handler.d.ts +33 -0
  273. package/dist_ts/ts/mail/delivery/smtpclient/tls-handler.js +202 -0
  274. package/dist_ts/ts/mail/delivery/smtpclient/utils/helpers.d.ts +77 -0
  275. package/dist_ts/ts/mail/delivery/smtpclient/utils/helpers.js +196 -0
  276. package/dist_ts/ts/mail/delivery/smtpclient/utils/logging.d.ts +46 -0
  277. package/dist_ts/ts/mail/delivery/smtpclient/utils/logging.js +153 -0
  278. package/dist_ts/ts/mail/delivery/smtpclient/utils/validation.d.ts +38 -0
  279. package/dist_ts/ts/mail/delivery/smtpclient/utils/validation.js +139 -0
  280. package/dist_ts/ts/mail/delivery/smtpserver/certificate-utils.d.ts +45 -0
  281. package/dist_ts/ts/mail/delivery/smtpserver/certificate-utils.js +345 -0
  282. package/dist_ts/ts/mail/delivery/smtpserver/command-handler.d.ts +156 -0
  283. package/dist_ts/ts/mail/delivery/smtpserver/command-handler.js +1159 -0
  284. package/dist_ts/ts/mail/delivery/smtpserver/connection-manager.d.ts +159 -0
  285. package/dist_ts/ts/mail/delivery/smtpserver/connection-manager.js +894 -0
  286. package/dist_ts/ts/mail/delivery/smtpserver/constants.d.ts +130 -0
  287. package/dist_ts/ts/mail/delivery/smtpserver/constants.js +162 -0
  288. package/dist_ts/ts/mail/delivery/smtpserver/create-server.d.ts +14 -0
  289. package/dist_ts/ts/mail/delivery/smtpserver/create-server.js +28 -0
  290. package/dist_ts/ts/mail/delivery/smtpserver/data-handler.d.ts +123 -0
  291. package/dist_ts/ts/mail/delivery/smtpserver/data-handler.js +1148 -0
  292. package/dist_ts/ts/mail/delivery/smtpserver/index.d.ts +20 -0
  293. package/dist_ts/ts/mail/delivery/smtpserver/index.js +27 -0
  294. package/dist_ts/ts/mail/delivery/smtpserver/interfaces.d.ts +530 -0
  295. package/dist_ts/ts/mail/delivery/smtpserver/interfaces.js +10 -0
  296. package/dist_ts/ts/mail/delivery/smtpserver/secure-server.d.ts +15 -0
  297. package/dist_ts/ts/mail/delivery/smtpserver/secure-server.js +79 -0
  298. package/dist_ts/ts/mail/delivery/smtpserver/security-handler.d.ts +86 -0
  299. package/dist_ts/ts/mail/delivery/smtpserver/security-handler.js +234 -0
  300. package/dist_ts/ts/mail/delivery/smtpserver/session-manager.d.ts +140 -0
  301. package/dist_ts/ts/mail/delivery/smtpserver/session-manager.js +469 -0
  302. package/dist_ts/ts/mail/delivery/smtpserver/smtp-server.d.ts +137 -0
  303. package/dist_ts/ts/mail/delivery/smtpserver/smtp-server.js +666 -0
  304. package/dist_ts/ts/mail/delivery/smtpserver/starttls-handler.d.ts +21 -0
  305. package/dist_ts/ts/mail/delivery/smtpserver/starttls-handler.js +207 -0
  306. package/dist_ts/ts/mail/delivery/smtpserver/tls-handler.d.ts +66 -0
  307. package/dist_ts/ts/mail/delivery/smtpserver/tls-handler.js +261 -0
  308. package/dist_ts/ts/mail/delivery/smtpserver/utils/adaptive-logging.d.ts +117 -0
  309. package/dist_ts/ts/mail/delivery/smtpserver/utils/adaptive-logging.js +411 -0
  310. package/dist_ts/ts/mail/delivery/smtpserver/utils/helpers.d.ts +78 -0
  311. package/dist_ts/ts/mail/delivery/smtpserver/utils/helpers.js +208 -0
  312. package/dist_ts/ts/mail/delivery/smtpserver/utils/logging.d.ts +106 -0
  313. package/dist_ts/ts/mail/delivery/smtpserver/utils/logging.js +181 -0
  314. package/dist_ts/ts/mail/delivery/smtpserver/utils/validation.d.ts +69 -0
  315. package/dist_ts/ts/mail/delivery/smtpserver/utils/validation.js +360 -0
  316. package/dist_ts/ts/mail/index.d.ts +8 -0
  317. package/dist_ts/ts/mail/index.js +13 -0
  318. package/dist_ts/ts/mail/routing/classes.dns.manager.d.ts +65 -0
  319. package/dist_ts/ts/mail/routing/classes.dns.manager.js +413 -0
  320. package/dist_ts/ts/mail/routing/classes.dnsmanager.d.ts +165 -0
  321. package/dist_ts/ts/mail/routing/classes.dnsmanager.js +430 -0
  322. package/dist_ts/ts/mail/routing/classes.domain.registry.d.ts +54 -0
  323. package/dist_ts/ts/mail/routing/classes.domain.registry.js +118 -0
  324. package/dist_ts/ts/mail/routing/classes.email.config.d.ts +64 -0
  325. package/dist_ts/ts/mail/routing/classes.email.config.js +2 -0
  326. package/dist_ts/ts/mail/routing/classes.email.router.d.ts +171 -0
  327. package/dist_ts/ts/mail/routing/classes.email.router.js +491 -0
  328. package/dist_ts/ts/mail/routing/classes.unified.email.server.d.ts +426 -0
  329. package/dist_ts/ts/mail/routing/classes.unified.email.server.js +1454 -0
  330. package/dist_ts/ts/mail/routing/index.d.ts +5 -0
  331. package/dist_ts/ts/mail/routing/index.js +7 -0
  332. package/dist_ts/ts/mail/routing/interfaces.d.ts +187 -0
  333. package/dist_ts/ts/mail/routing/interfaces.js +2 -0
  334. package/dist_ts/ts/mail/security/classes.dkimcreator.d.ts +68 -0
  335. package/dist_ts/ts/mail/security/classes.dkimcreator.js +346 -0
  336. package/dist_ts/ts/mail/security/classes.dkimverifier.d.ts +46 -0
  337. package/dist_ts/ts/mail/security/classes.dkimverifier.js +317 -0
  338. package/dist_ts/ts/mail/security/classes.dmarcverifier.d.ts +123 -0
  339. package/dist_ts/ts/mail/security/classes.dmarcverifier.js +365 -0
  340. package/dist_ts/ts/mail/security/classes.spfverifier.d.ts +103 -0
  341. package/dist_ts/ts/mail/security/classes.spfverifier.js +492 -0
  342. package/dist_ts/ts/mail/security/index.d.ts +4 -0
  343. package/dist_ts/ts/mail/security/index.js +6 -0
  344. package/dist_ts/ts/opsserver/classes.opsserver.d.ts +20 -0
  345. package/dist_ts/ts/opsserver/classes.opsserver.js +44 -0
  346. package/dist_ts/ts/opsserver/handlers/admin.handler.d.ts +31 -0
  347. package/dist_ts/ts/opsserver/handlers/admin.handler.js +177 -0
  348. package/dist_ts/ts/opsserver/handlers/config.handler.d.ts +10 -0
  349. package/dist_ts/ts/opsserver/handlers/config.handler.js +100 -0
  350. package/dist_ts/ts/opsserver/handlers/index.d.ts +5 -0
  351. package/dist_ts/ts/opsserver/handlers/index.js +6 -0
  352. package/dist_ts/ts/opsserver/handlers/logs.handler.d.ts +10 -0
  353. package/dist_ts/ts/opsserver/handlers/logs.handler.js +121 -0
  354. package/dist_ts/ts/opsserver/handlers/security.handler.d.ts +11 -0
  355. package/dist_ts/ts/opsserver/handlers/security.handler.js +118 -0
  356. package/dist_ts/ts/opsserver/handlers/stats.handler.d.ts +13 -0
  357. package/dist_ts/ts/opsserver/handlers/stats.handler.js +233 -0
  358. package/dist_ts/ts/opsserver/helpers/guards.d.ts +25 -0
  359. package/dist_ts/ts/opsserver/helpers/guards.js +41 -0
  360. package/dist_ts/ts/opsserver/index.d.ts +1 -0
  361. package/dist_ts/ts/opsserver/index.js +2 -0
  362. package/dist_ts/ts/paths.d.ts +14 -0
  363. package/dist_ts/ts/paths.js +39 -0
  364. package/dist_ts/ts/plugins.d.ts +46 -0
  365. package/dist_ts/ts/plugins.js +53 -0
  366. package/dist_ts/ts/security/classes.contentscanner.d.ts +160 -0
  367. package/dist_ts/ts/security/classes.contentscanner.js +634 -0
  368. package/dist_ts/ts/security/classes.ipreputationchecker.d.ts +150 -0
  369. package/dist_ts/ts/security/classes.ipreputationchecker.js +508 -0
  370. package/dist_ts/ts/security/classes.securitylogger.d.ts +140 -0
  371. package/dist_ts/ts/security/classes.securitylogger.js +232 -0
  372. package/dist_ts/ts/security/index.d.ts +3 -0
  373. package/dist_ts/ts/security/index.js +4 -0
  374. package/dist_ts/ts/sms/classes.smsservice.d.ts +15 -0
  375. package/dist_ts/ts/sms/classes.smsservice.js +72 -0
  376. package/dist_ts/ts/sms/config/sms.config.d.ts +93 -0
  377. package/dist_ts/ts/sms/config/sms.config.js +2 -0
  378. package/dist_ts/ts/sms/config/sms.schema.d.ts +5 -0
  379. package/dist_ts/ts/sms/config/sms.schema.js +121 -0
  380. package/dist_ts/ts/sms/index.d.ts +1 -0
  381. package/dist_ts/ts/sms/index.js +2 -0
  382. package/dist_ts/ts/storage/classes.storagemanager.d.ts +82 -0
  383. package/dist_ts/ts/storage/classes.storagemanager.js +341 -0
  384. package/dist_ts/ts/storage/index.d.ts +1 -0
  385. package/dist_ts/ts/storage/index.js +3 -0
  386. package/dist_ts/ts_interfaces/data/auth.d.ts +8 -0
  387. package/dist_ts/ts_interfaces/data/auth.js +2 -0
  388. package/dist_ts/ts_interfaces/data/index.d.ts +2 -0
  389. package/dist_ts/ts_interfaces/data/index.js +3 -0
  390. package/dist_ts/ts_interfaces/data/stats.d.ts +93 -0
  391. package/dist_ts/ts_interfaces/data/stats.js +2 -0
  392. package/dist_ts/ts_interfaces/index.d.ts +5 -0
  393. package/dist_ts/ts_interfaces/index.js +8 -0
  394. package/dist_ts/ts_interfaces/plugins.d.ts +2 -0
  395. package/dist_ts/ts_interfaces/plugins.js +4 -0
  396. package/dist_ts/ts_interfaces/requests/admin.d.ts +31 -0
  397. package/dist_ts/ts_interfaces/requests/admin.js +3 -0
  398. package/dist_ts/ts_interfaces/requests/config.d.ts +25 -0
  399. package/dist_ts/ts_interfaces/requests/config.js +3 -0
  400. package/dist_ts/ts_interfaces/requests/index.d.ts +4 -0
  401. package/dist_ts/ts_interfaces/requests/index.js +5 -0
  402. package/dist_ts/ts_interfaces/requests/logs.d.ts +34 -0
  403. package/dist_ts/ts_interfaces/requests/logs.js +4 -0
  404. package/dist_ts/ts_interfaces/requests/stats.d.ts +131 -0
  405. package/dist_ts/ts_interfaces/requests/stats.js +4 -0
  406. package/html/index.html +121 -0
  407. package/npmextra.json +45 -0
  408. package/package.json +83 -0
  409. package/readme.hints.md +906 -0
  410. package/readme.md +1253 -0
  411. package/readme.opsserver.md +351 -0
  412. package/test/helpers/server.loader.ts +347 -0
  413. package/test/helpers/smtp.client.ts +209 -0
  414. package/test/helpers/utils.ts +311 -0
  415. package/test/readme.md +443 -0
  416. package/test/suite/smtpclient_commands/test.ccmd-01.ehlo-helo-sending.ts +168 -0
  417. package/test/suite/smtpclient_commands/test.ccmd-02.mail-from-parameters.ts +277 -0
  418. package/test/suite/smtpclient_commands/test.ccmd-03.rcpt-to-multiple.ts +283 -0
  419. package/test/suite/smtpclient_commands/test.ccmd-04.data-transmission.ts +274 -0
  420. package/test/suite/smtpclient_commands/test.ccmd-05.auth-mechanisms.ts +306 -0
  421. package/test/suite/smtpclient_commands/test.ccmd-06.command-pipelining.ts +233 -0
  422. package/test/suite/smtpclient_commands/test.ccmd-07.response-parsing.ts +243 -0
  423. package/test/suite/smtpclient_commands/test.ccmd-08.rset-command.ts +333 -0
  424. package/test/suite/smtpclient_commands/test.ccmd-09.noop-command.ts +339 -0
  425. package/test/suite/smtpclient_commands/test.ccmd-10.vrfy-expn.ts +457 -0
  426. package/test/suite/smtpclient_commands/test.ccmd-11.help-command.ts +409 -0
  427. package/test/suite/smtpclient_connection/test.ccm-01.basic-tcp-connection.ts +150 -0
  428. package/test/suite/smtpclient_connection/test.ccm-02.tls-connection.ts +140 -0
  429. package/test/suite/smtpclient_connection/test.ccm-03.starttls-upgrade.ts +208 -0
  430. package/test/suite/smtpclient_connection/test.ccm-04.connection-pooling.ts +250 -0
  431. package/test/suite/smtpclient_connection/test.ccm-05.connection-reuse.ts +288 -0
  432. package/test/suite/smtpclient_connection/test.ccm-06.connection-timeout.ts +267 -0
  433. package/test/suite/smtpclient_connection/test.ccm-07.automatic-reconnection.ts +324 -0
  434. package/test/suite/smtpclient_connection/test.ccm-08.dns-resolution.ts +139 -0
  435. package/test/suite/smtpclient_connection/test.ccm-09.ipv6-dual-stack.ts +167 -0
  436. package/test/suite/smtpclient_connection/test.ccm-10.proxy-support.ts +305 -0
  437. package/test/suite/smtpclient_connection/test.ccm-11.keepalive.ts +299 -0
  438. package/test/suite/smtpclient_edge-cases/test.cedge-01.unusual-server-responses.ts +529 -0
  439. package/test/suite/smtpclient_edge-cases/test.cedge-02.malformed-commands.ts +438 -0
  440. package/test/suite/smtpclient_edge-cases/test.cedge-03.protocol-violations.ts +446 -0
  441. package/test/suite/smtpclient_edge-cases/test.cedge-04.resource-constraints.ts +530 -0
  442. package/test/suite/smtpclient_edge-cases/test.cedge-05.encoding-issues.ts +145 -0
  443. package/test/suite/smtpclient_edge-cases/test.cedge-06.large-headers.ts +180 -0
  444. package/test/suite/smtpclient_edge-cases/test.cedge-07.concurrent-operations.ts +204 -0
  445. package/test/suite/smtpclient_email-composition/test.cep-01.basic-headers.ts +245 -0
  446. package/test/suite/smtpclient_email-composition/test.cep-02.mime-multipart.ts +321 -0
  447. package/test/suite/smtpclient_email-composition/test.cep-03.attachment-encoding.ts +334 -0
  448. package/test/suite/smtpclient_email-composition/test.cep-04.bcc-handling.ts +187 -0
  449. package/test/suite/smtpclient_email-composition/test.cep-05.reply-to-return-path.ts +277 -0
  450. package/test/suite/smtpclient_email-composition/test.cep-06.utf8-international.ts +235 -0
  451. package/test/suite/smtpclient_email-composition/test.cep-07.html-inline-images.ts +489 -0
  452. package/test/suite/smtpclient_email-composition/test.cep-08.custom-headers.ts +293 -0
  453. package/test/suite/smtpclient_email-composition/test.cep-09.priority-importance.ts +314 -0
  454. package/test/suite/smtpclient_email-composition/test.cep-10.receipts-dsn.ts +411 -0
  455. package/test/suite/smtpclient_error-handling/test.cerr-01.4xx-errors.ts +232 -0
  456. package/test/suite/smtpclient_error-handling/test.cerr-02.5xx-errors.ts +309 -0
  457. package/test/suite/smtpclient_error-handling/test.cerr-03.network-failures.ts +299 -0
  458. package/test/suite/smtpclient_error-handling/test.cerr-04.greylisting-handling.ts +255 -0
  459. package/test/suite/smtpclient_error-handling/test.cerr-05.quota-exceeded.ts +273 -0
  460. package/test/suite/smtpclient_error-handling/test.cerr-06.invalid-recipients.ts +320 -0
  461. package/test/suite/smtpclient_error-handling/test.cerr-07.message-size-limits.ts +320 -0
  462. package/test/suite/smtpclient_error-handling/test.cerr-08.rate-limiting.ts +261 -0
  463. package/test/suite/smtpclient_error-handling/test.cerr-09.connection-pool-errors.ts +299 -0
  464. package/test/suite/smtpclient_error-handling/test.cerr-10.partial-failure.ts +373 -0
  465. package/test/suite/smtpclient_performance/test.cperf-01.bulk-sending.ts +332 -0
  466. package/test/suite/smtpclient_performance/test.cperf-02.message-throughput.ts +304 -0
  467. package/test/suite/smtpclient_performance/test.cperf-03.memory-usage.ts +332 -0
  468. package/test/suite/smtpclient_performance/test.cperf-04.cpu-utilization.ts +373 -0
  469. package/test/suite/smtpclient_performance/test.cperf-05.network-efficiency.ts +181 -0
  470. package/test/suite/smtpclient_performance/test.cperf-06.caching-strategies.ts +190 -0
  471. package/test/suite/smtpclient_performance/test.cperf-07.queue-management.ts +171 -0
  472. package/test/suite/smtpclient_performance/test.cperf-08.dns-caching.ts +50 -0
  473. package/test/suite/smtpclient_reliability/test.crel-01.reconnection-logic.ts +305 -0
  474. package/test/suite/smtpclient_reliability/test.crel-02.network-interruption.ts +207 -0
  475. package/test/suite/smtpclient_reliability/test.crel-03.queue-persistence.ts +469 -0
  476. package/test/suite/smtpclient_reliability/test.crel-04.crash-recovery.ts +520 -0
  477. package/test/suite/smtpclient_reliability/test.crel-05.memory-leaks.ts +503 -0
  478. package/test/suite/smtpclient_reliability/test.crel-06.concurrency-safety.ts +558 -0
  479. package/test/suite/smtpclient_reliability/test.crel-07.resource-cleanup.ts +52 -0
  480. package/test/suite/smtpclient_rfc-compliance/test.crfc-01.rfc5321-client.ts +283 -0
  481. package/test/suite/smtpclient_rfc-compliance/test.crfc-02.esmtp-compliance.ts +77 -0
  482. package/test/suite/smtpclient_rfc-compliance/test.crfc-03.command-syntax.ts +67 -0
  483. package/test/suite/smtpclient_rfc-compliance/test.crfc-04.response-codes.ts +54 -0
  484. package/test/suite/smtpclient_rfc-compliance/test.crfc-05.state-machine.ts +703 -0
  485. package/test/suite/smtpclient_rfc-compliance/test.crfc-06.protocol-negotiation.ts +688 -0
  486. package/test/suite/smtpclient_rfc-compliance/test.crfc-07.interoperability.ts +728 -0
  487. package/test/suite/smtpclient_rfc-compliance/test.crfc-08.smtp-extensions.ts +656 -0
  488. package/test/suite/smtpclient_security/test.csec-01.tls-verification.ts +88 -0
  489. package/test/suite/smtpclient_security/test.csec-02.oauth2-authentication.ts +132 -0
  490. package/test/suite/smtpclient_security/test.csec-03.dkim-signing.ts +138 -0
  491. package/test/suite/smtpclient_security/test.csec-04.spf-compliance.ts +163 -0
  492. package/test/suite/smtpclient_security/test.csec-05.dmarc-policy.ts +200 -0
  493. package/test/suite/smtpclient_security/test.csec-06.certificate-validation.ts +145 -0
  494. package/test/suite/smtpclient_security/test.csec-07.cipher-suites.ts +153 -0
  495. package/test/suite/smtpclient_security/test.csec-08.authentication-fallback.ts +154 -0
  496. package/test/suite/smtpclient_security/test.csec-09.relay-restrictions.ts +166 -0
  497. package/test/suite/smtpclient_security/test.csec-10.anti-spam-measures.ts +196 -0
  498. package/test/suite/smtpserver_commands/test.cmd-01.ehlo-command.ts +193 -0
  499. package/test/suite/smtpserver_commands/test.cmd-02.mail-from.ts +330 -0
  500. package/test/suite/smtpserver_commands/test.cmd-03.rcpt-to.ts +296 -0
  501. package/test/suite/smtpserver_commands/test.cmd-04.data-command.ts +395 -0
  502. package/test/suite/smtpserver_commands/test.cmd-05.noop-command.ts +320 -0
  503. package/test/suite/smtpserver_commands/test.cmd-06.rset-command.ts +399 -0
  504. package/test/suite/smtpserver_commands/test.cmd-07.vrfy-command.ts +391 -0
  505. package/test/suite/smtpserver_commands/test.cmd-08.expn-command.ts +450 -0
  506. package/test/suite/smtpserver_commands/test.cmd-09.size-extension.ts +465 -0
  507. package/test/suite/smtpserver_commands/test.cmd-10.help-command.ts +454 -0
  508. package/test/suite/smtpserver_commands/test.cmd-11.command-pipelining.ts +334 -0
  509. package/test/suite/smtpserver_commands/test.cmd-12.helo-command.ts +420 -0
  510. package/test/suite/smtpserver_commands/test.cmd-13.quit-command.ts +384 -0
  511. package/test/suite/smtpserver_connection/test.cm-01.tls-connection.ts +61 -0
  512. package/test/suite/smtpserver_connection/test.cm-02.multiple-connections.ts +112 -0
  513. package/test/suite/smtpserver_connection/test.cm-03.connection-timeout.ts +134 -0
  514. package/test/suite/smtpserver_connection/test.cm-04.connection-limits.ts +374 -0
  515. package/test/suite/smtpserver_connection/test.cm-05.connection-rejection.ts +296 -0
  516. package/test/suite/smtpserver_connection/test.cm-06.starttls-upgrade.ts +468 -0
  517. package/test/suite/smtpserver_connection/test.cm-07.abrupt-disconnection.ts +321 -0
  518. package/test/suite/smtpserver_connection/test.cm-08.tls-versions.ts +361 -0
  519. package/test/suite/smtpserver_connection/test.cm-09.tls-ciphers.ts +556 -0
  520. package/test/suite/smtpserver_connection/test.cm-10.plain-connection.ts +293 -0
  521. package/test/suite/smtpserver_connection/test.cm-11.keepalive.ts +382 -0
  522. package/test/suite/smtpserver_edge-cases/test.edge-01.very-large-email.ts +239 -0
  523. package/test/suite/smtpserver_edge-cases/test.edge-02.very-small-email.ts +389 -0
  524. package/test/suite/smtpserver_edge-cases/test.edge-03.invalid-character-handling.ts +479 -0
  525. package/test/suite/smtpserver_edge-cases/test.edge-04.empty-commands.ts +430 -0
  526. package/test/suite/smtpserver_edge-cases/test.edge-05.extremely-long-lines.ts +425 -0
  527. package/test/suite/smtpserver_edge-cases/test.edge-06.extremely-long-headers.ts +404 -0
  528. package/test/suite/smtpserver_edge-cases/test.edge-07.unusual-mime-types.ts +333 -0
  529. package/test/suite/smtpserver_edge-cases/test.edge-08.nested-mime-structures.ts +379 -0
  530. package/test/suite/smtpserver_email-processing/test.ep-01.basic-email-sending.ts +338 -0
  531. package/test/suite/smtpserver_email-processing/test.ep-02.invalid-email-addresses.ts +315 -0
  532. package/test/suite/smtpserver_email-processing/test.ep-03.multiple-recipients.ts +493 -0
  533. package/test/suite/smtpserver_email-processing/test.ep-04.large-email.ts +528 -0
  534. package/test/suite/smtpserver_email-processing/test.ep-05.mime-handling.ts +515 -0
  535. package/test/suite/smtpserver_email-processing/test.ep-06.attachment-handling.ts +629 -0
  536. package/test/suite/smtpserver_email-processing/test.ep-07.special-character-handling.ts +462 -0
  537. package/test/suite/smtpserver_email-processing/test.ep-08.email-routing.ts +527 -0
  538. package/test/suite/smtpserver_email-processing/test.ep-09.delivery-status-notifications.ts +486 -0
  539. package/test/suite/smtpserver_error-handling/test.err-01.syntax-errors.ts +475 -0
  540. package/test/suite/smtpserver_error-handling/test.err-02.invalid-sequence.ts +450 -0
  541. package/test/suite/smtpserver_error-handling/test.err-03.temporary-failures.ts +453 -0
  542. package/test/suite/smtpserver_error-handling/test.err-04.permanent-failures.ts +325 -0
  543. package/test/suite/smtpserver_error-handling/test.err-05.resource-exhaustion.ts +302 -0
  544. package/test/suite/smtpserver_error-handling/test.err-06.malformed-mime.ts +374 -0
  545. package/test/suite/smtpserver_error-handling/test.err-07.exception-handling.ts +333 -0
  546. package/test/suite/smtpserver_error-handling/test.err-08.error-logging.ts +324 -0
  547. package/test/suite/smtpserver_performance/test.perf-01.throughput.ts +183 -0
  548. package/test/suite/smtpserver_performance/test.perf-02.concurrency.ts +388 -0
  549. package/test/suite/smtpserver_performance/test.perf-03.cpu-utilization.ts +245 -0
  550. package/test/suite/smtpserver_performance/test.perf-04.memory-usage.ts +238 -0
  551. package/test/suite/smtpserver_performance/test.perf-05.connection-processing-time.ts +363 -0
  552. package/test/suite/smtpserver_performance/test.perf-06.message-processing-time.ts +252 -0
  553. package/test/suite/smtpserver_performance/test.perf-07.resource-cleanup.ts +317 -0
  554. package/test/suite/smtpserver_reliability/test.rel-01.long-running-operation.ts +344 -0
  555. package/test/suite/smtpserver_reliability/test.rel-02.restart-recovery.ts +328 -0
  556. package/test/suite/smtpserver_reliability/test.rel-03.resource-leak-detection.ts +394 -0
  557. package/test/suite/smtpserver_reliability/test.rel-04.error-recovery.ts +401 -0
  558. package/test/suite/smtpserver_reliability/test.rel-05.dns-resolution-failure.ts +335 -0
  559. package/test/suite/smtpserver_reliability/test.rel-06.network-interruption.ts +410 -0
  560. package/test/suite/smtpserver_rfc-compliance/test.rfc-01.rfc5321-compliance.ts +382 -0
  561. package/test/suite/smtpserver_rfc-compliance/test.rfc-02.rfc5322-compliance.ts +428 -0
  562. package/test/suite/smtpserver_rfc-compliance/test.rfc-03.rfc7208-spf-compliance.ts +330 -0
  563. package/test/suite/smtpserver_rfc-compliance/test.rfc-04.rfc6376-dkim-compliance.ts +450 -0
  564. package/test/suite/smtpserver_rfc-compliance/test.rfc-05.rfc7489-dmarc-compliance.ts +408 -0
  565. package/test/suite/smtpserver_rfc-compliance/test.rfc-06.rfc8314-tls-compliance.ts +366 -0
  566. package/test/suite/smtpserver_rfc-compliance/test.rfc-07.rfc3461-dsn-compliance.ts +399 -0
  567. package/test/suite/smtpserver_security/test.sec-01.authentication.ts +218 -0
  568. package/test/suite/smtpserver_security/test.sec-02.authorization.ts +286 -0
  569. package/test/suite/smtpserver_security/test.sec-03.dkim-processing.ts +414 -0
  570. package/test/suite/smtpserver_security/test.sec-04.spf-checking.ts +280 -0
  571. package/test/suite/smtpserver_security/test.sec-05.dmarc-policy.ts +374 -0
  572. package/test/suite/smtpserver_security/test.sec-06.ip-reputation.ts +303 -0
  573. package/test/suite/smtpserver_security/test.sec-07.content-scanning.ts +409 -0
  574. package/test/suite/smtpserver_security/test.sec-08.rate-limiting.ts +324 -0
  575. package/test/suite/smtpserver_security/test.sec-09.tls-certificate-validation.ts +312 -0
  576. package/test/suite/smtpserver_security/test.sec-10.header-injection-prevention.ts +332 -0
  577. package/test/suite/smtpserver_security/test.sec-11.bounce-management.ts +363 -0
  578. package/test/test.base.ts +65 -0
  579. package/test/test.bouncemanager.ts +196 -0
  580. package/test/test.config.md +175 -0
  581. package/test/test.contentscanner.ts +265 -0
  582. package/test/test.dcrouter.email.ts +201 -0
  583. package/test/test.deliverability.ts +55 -0
  584. package/test/test.dns-manager-creation.ts +141 -0
  585. package/test/test.dns-mode-switching.ts +257 -0
  586. package/test/test.dns-server-config.ts +140 -0
  587. package/test/test.dns-socket-handler.ts +169 -0
  588. package/test/test.dns-validation.ts +283 -0
  589. package/test/test.email-socket-handler.ts +228 -0
  590. package/test/test.email.integration.ts +377 -0
  591. package/test/test.email.router.ts +283 -0
  592. package/test/test.emailauth.ts +195 -0
  593. package/test/test.errors.ts +408 -0
  594. package/test/test.integration.storage.ts +313 -0
  595. package/test/test.integration.ts +75 -0
  596. package/test/test.ipreputationchecker.ts +179 -0
  597. package/test/test.ipwarmupmanager.ts +323 -0
  598. package/test/test.jwt-auth.ts +130 -0
  599. package/test/test.minimal.ts +66 -0
  600. package/test/test.opsserver-api.ts +83 -0
  601. package/test/test.protected-endpoint.ts +115 -0
  602. package/test/test.rate-limiting-integration.ts +236 -0
  603. package/test/test.ratelimiter.ts +141 -0
  604. package/test/test.reputationmonitor.ts +262 -0
  605. package/test/test.smartmail.ts +248 -0
  606. package/test/test.smtp.client.compatibility.ts +154 -0
  607. package/test/test.smtp.client.ts +191 -0
  608. package/test/test.smtp.server.ts +180 -0
  609. package/test/test.socket-handler-integration.ts +240 -0
  610. package/test/test.socket-handler-unit.ts +198 -0
  611. package/test/test.storagemanager.ts +289 -0
  612. package/ts/00_commitinfo_data.ts +8 -0
  613. package/ts/classes.dcrouter.ts +1310 -0
  614. package/ts/config/index.ts +2 -0
  615. package/ts/config/validator.ts +266 -0
  616. package/ts/deliverability/classes.ipwarmupmanager.ts +896 -0
  617. package/ts/deliverability/classes.senderreputationmonitor.ts +1244 -0
  618. package/ts/deliverability/index.ts +13 -0
  619. package/ts/errors/base.errors.ts +525 -0
  620. package/ts/errors/email.errors.ts +383 -0
  621. package/ts/errors/error-handler.ts +412 -0
  622. package/ts/errors/error.codes.ts +165 -0
  623. package/ts/errors/index.ts +195 -0
  624. package/ts/errors/mta.errors.ts +681 -0
  625. package/ts/errors/reputation.errors.ts +422 -0
  626. package/ts/index.ts +7 -0
  627. package/ts/logger.ts +91 -0
  628. package/ts/mail/core/classes.bouncemanager.ts +965 -0
  629. package/ts/mail/core/classes.email.ts +941 -0
  630. package/ts/mail/core/classes.emailvalidator.ts +239 -0
  631. package/ts/mail/core/classes.templatemanager.ts +320 -0
  632. package/ts/mail/core/index.ts +5 -0
  633. package/ts/mail/delivery/classes.delivery.queue.ts +645 -0
  634. package/ts/mail/delivery/classes.delivery.system.ts +1089 -0
  635. package/ts/mail/delivery/classes.emailsendjob.ts +447 -0
  636. package/ts/mail/delivery/classes.emailsendjob.ts.backup +691 -0
  637. package/ts/mail/delivery/classes.emailsignjob.ts +67 -0
  638. package/ts/mail/delivery/classes.mta.config.ts +73 -0
  639. package/ts/mail/delivery/classes.ratelimiter.ts +281 -0
  640. package/ts/mail/delivery/classes.smtp.client.legacy.ts +1422 -0
  641. package/ts/mail/delivery/classes.unified.rate.limiter.ts +1053 -0
  642. package/ts/mail/delivery/index.ts +24 -0
  643. package/ts/mail/delivery/interfaces.ts +291 -0
  644. package/ts/mail/delivery/smtpclient/auth-handler.ts +232 -0
  645. package/ts/mail/delivery/smtpclient/command-handler.ts +343 -0
  646. package/ts/mail/delivery/smtpclient/connection-manager.ts +289 -0
  647. package/ts/mail/delivery/smtpclient/constants.ts +145 -0
  648. package/ts/mail/delivery/smtpclient/create-client.ts +94 -0
  649. package/ts/mail/delivery/smtpclient/error-handler.ts +141 -0
  650. package/ts/mail/delivery/smtpclient/index.ts +24 -0
  651. package/ts/mail/delivery/smtpclient/interfaces.ts +242 -0
  652. package/ts/mail/delivery/smtpclient/smtp-client.ts +357 -0
  653. package/ts/mail/delivery/smtpclient/tls-handler.ts +254 -0
  654. package/ts/mail/delivery/smtpclient/utils/helpers.ts +224 -0
  655. package/ts/mail/delivery/smtpclient/utils/logging.ts +212 -0
  656. package/ts/mail/delivery/smtpclient/utils/validation.ts +170 -0
  657. package/ts/mail/delivery/smtpserver/certificate-utils.ts +398 -0
  658. package/ts/mail/delivery/smtpserver/command-handler.ts +1340 -0
  659. package/ts/mail/delivery/smtpserver/connection-manager.ts +1045 -0
  660. package/ts/mail/delivery/smtpserver/constants.ts +181 -0
  661. package/ts/mail/delivery/smtpserver/create-server.ts +31 -0
  662. package/ts/mail/delivery/smtpserver/data-handler.ts +1283 -0
  663. package/ts/mail/delivery/smtpserver/index.ts +32 -0
  664. package/ts/mail/delivery/smtpserver/interfaces.ts +655 -0
  665. package/ts/mail/delivery/smtpserver/secure-server.ts +97 -0
  666. package/ts/mail/delivery/smtpserver/security-handler.ts +345 -0
  667. package/ts/mail/delivery/smtpserver/session-manager.ts +557 -0
  668. package/ts/mail/delivery/smtpserver/smtp-server.ts +804 -0
  669. package/ts/mail/delivery/smtpserver/starttls-handler.ts +262 -0
  670. package/ts/mail/delivery/smtpserver/tls-handler.ts +346 -0
  671. package/ts/mail/delivery/smtpserver/utils/adaptive-logging.ts +514 -0
  672. package/ts/mail/delivery/smtpserver/utils/helpers.ts +246 -0
  673. package/ts/mail/delivery/smtpserver/utils/logging.ts +246 -0
  674. package/ts/mail/delivery/smtpserver/utils/validation.ts +436 -0
  675. package/ts/mail/index.ts +19 -0
  676. package/ts/mail/routing/classes.dns.manager.ts +563 -0
  677. package/ts/mail/routing/classes.dnsmanager.ts +559 -0
  678. package/ts/mail/routing/classes.domain.registry.ts +139 -0
  679. package/ts/mail/routing/classes.email.config.ts +82 -0
  680. package/ts/mail/routing/classes.email.router.ts +575 -0
  681. package/ts/mail/routing/classes.unified.email.server.ts +1873 -0
  682. package/ts/mail/routing/index.ts +6 -0
  683. package/ts/mail/routing/interfaces.ts +202 -0
  684. package/ts/mail/security/classes.dkimcreator.ts +431 -0
  685. package/ts/mail/security/classes.dkimverifier.ts +382 -0
  686. package/ts/mail/security/classes.dmarcverifier.ts +478 -0
  687. package/ts/mail/security/classes.spfverifier.ts +606 -0
  688. package/ts/mail/security/index.ts +5 -0
  689. package/ts/opsserver/classes.opsserver.ts +65 -0
  690. package/ts/opsserver/handlers/admin.handler.ts +240 -0
  691. package/ts/opsserver/handlers/config.handler.ts +150 -0
  692. package/ts/opsserver/handlers/index.ts +5 -0
  693. package/ts/opsserver/handlers/logs.handler.ts +195 -0
  694. package/ts/opsserver/handlers/security.handler.ts +208 -0
  695. package/ts/opsserver/handlers/stats.handler.ts +344 -0
  696. package/ts/opsserver/helpers/guards.ts +56 -0
  697. package/ts/opsserver/index.ts +1 -0
  698. package/ts/paths.ts +48 -0
  699. package/ts/plugins.ts +94 -0
  700. package/ts/security/classes.contentscanner.ts +739 -0
  701. package/ts/security/classes.ipreputationchecker.ts +592 -0
  702. package/ts/security/classes.securitylogger.ts +299 -0
  703. package/ts/security/index.ts +21 -0
  704. package/ts/sms/classes.smsservice.ts +98 -0
  705. package/ts/sms/config/sms.config.ts +109 -0
  706. package/ts/sms/config/sms.schema.ts +122 -0
  707. package/ts/sms/index.ts +1 -0
  708. package/ts/storage/classes.storagemanager.ts +400 -0
  709. package/ts/storage/index.ts +2 -0
  710. package/ts/tspublish.json +3 -0
  711. package/ts_interfaces/data/auth.ts +8 -0
  712. package/ts_interfaces/data/index.ts +2 -0
  713. package/ts_interfaces/data/stats.ts +101 -0
  714. package/ts_interfaces/index.ts +9 -0
  715. package/ts_interfaces/plugins.ts +6 -0
  716. package/ts_interfaces/requests/admin.ts +46 -0
  717. package/ts_interfaces/requests/config.ts +35 -0
  718. package/ts_interfaces/requests/index.ts +4 -0
  719. package/ts_interfaces/requests/logs.ts +44 -0
  720. package/ts_interfaces/requests/stats.ts +162 -0
  721. package/ts_interfaces/tspublish.json +3 -0
  722. package/ts_web/00_commitinfo_data.ts +8 -0
  723. package/ts_web/appstate.ts +361 -0
  724. package/ts_web/elements/index.ts +7 -0
  725. package/ts_web/elements/ops-dashboard.ts +165 -0
  726. package/ts_web/elements/ops-view-config.ts +268 -0
  727. package/ts_web/elements/ops-view-logs.ts +207 -0
  728. package/ts_web/elements/ops-view-overview.ts +222 -0
  729. package/ts_web/elements/ops-view-security.ts +471 -0
  730. package/ts_web/elements/ops-view-stats.ts +299 -0
  731. package/ts_web/elements/shared/css.ts +10 -0
  732. package/ts_web/elements/shared/index.ts +2 -0
  733. package/ts_web/elements/shared/ops-sectionheading.ts +42 -0
  734. package/ts_web/index.ts +9 -0
  735. package/ts_web/plugins.ts +11 -0
  736. package/ts_web/tspublish.json +3 -0
  737. package/tsconfig.json +15 -0
@@ -0,0 +1,1873 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import * as paths from '../../paths.js';
3
+ import { EventEmitter } from 'events';
4
+ import { logger } from '../../logger.js';
5
+ import {
6
+ SecurityLogger,
7
+ SecurityLogLevel,
8
+ SecurityEventType
9
+ } from '../../security/index.js';
10
+ import { DKIMCreator } from '../security/classes.dkimcreator.js';
11
+ import { IPReputationChecker } from '../../security/classes.ipreputationchecker.js';
12
+ import {
13
+ IPWarmupManager,
14
+ type IIPWarmupConfig,
15
+ SenderReputationMonitor,
16
+ type IReputationMonitorConfig
17
+ } from '../../deliverability/index.js';
18
+ import { EmailRouter } from './classes.email.router.js';
19
+ import type { IEmailRoute, IEmailAction, IEmailContext, IEmailDomainConfig } from './interfaces.js';
20
+ import { Email } from '../core/classes.email.js';
21
+ import { DomainRegistry } from './classes.domain.registry.js';
22
+ import { DnsManager } from './classes.dns.manager.js';
23
+ import { BounceManager, BounceType, BounceCategory } from '../core/classes.bouncemanager.js';
24
+ import { createSmtpServer } from '../delivery/smtpserver/index.js';
25
+ import { createPooledSmtpClient } from '../delivery/smtpclient/create-client.js';
26
+ import type { SmtpClient } from '../delivery/smtpclient/smtp-client.js';
27
+ import { MultiModeDeliverySystem, type IMultiModeDeliveryOptions } from '../delivery/classes.delivery.system.js';
28
+ import { UnifiedDeliveryQueue, type IQueueOptions } from '../delivery/classes.delivery.queue.js';
29
+ import { UnifiedRateLimiter, type IHierarchicalRateLimits } from '../delivery/classes.unified.rate.limiter.js';
30
+ import { SmtpState } from '../delivery/interfaces.js';
31
+ import type { EmailProcessingMode, ISmtpSession as IBaseSmtpSession } from '../delivery/interfaces.js';
32
+ import type { DcRouter } from '../../classes.dcrouter.js';
33
+
34
+ /**
35
+ * Extended SMTP session interface with route information
36
+ */
37
+ export interface IExtendedSmtpSession extends ISmtpSession {
38
+ /**
39
+ * Matched route for this session
40
+ */
41
+ matchedRoute?: IEmailRoute;
42
+ }
43
+
44
+ /**
45
+ * Options for the unified email server
46
+ */
47
+ export interface IUnifiedEmailServerOptions {
48
+ // Base server options
49
+ ports: number[];
50
+ hostname: string;
51
+ domains: IEmailDomainConfig[]; // Domain configurations
52
+ banner?: string;
53
+ debug?: boolean;
54
+ useSocketHandler?: boolean; // Use socket-handler mode instead of port listening
55
+
56
+ // Authentication options
57
+ auth?: {
58
+ required?: boolean;
59
+ methods?: ('PLAIN' | 'LOGIN' | 'OAUTH2')[];
60
+ users?: Array<{username: string, password: string}>;
61
+ };
62
+
63
+ // TLS options
64
+ tls?: {
65
+ certPath?: string;
66
+ keyPath?: string;
67
+ caPath?: string;
68
+ minVersion?: string;
69
+ ciphers?: string;
70
+ };
71
+
72
+ // Limits
73
+ maxMessageSize?: number;
74
+ maxClients?: number;
75
+ maxConnections?: number;
76
+
77
+ // Connection options
78
+ connectionTimeout?: number;
79
+ socketTimeout?: number;
80
+
81
+ // Email routing rules
82
+ routes: IEmailRoute[];
83
+
84
+ // Global defaults for all domains
85
+ defaults?: {
86
+ dnsMode?: 'forward' | 'internal-dns' | 'external-dns';
87
+ dkim?: IEmailDomainConfig['dkim'];
88
+ rateLimits?: IEmailDomainConfig['rateLimits'];
89
+ };
90
+
91
+ // Outbound settings
92
+ outbound?: {
93
+ maxConnections?: number;
94
+ connectionTimeout?: number;
95
+ socketTimeout?: number;
96
+ retryAttempts?: number;
97
+ defaultFrom?: string;
98
+ };
99
+
100
+ // Rate limiting (global limits, can be overridden per domain)
101
+ rateLimits?: IHierarchicalRateLimits;
102
+
103
+ // Deliverability options
104
+ ipWarmupConfig?: IIPWarmupConfig;
105
+ reputationMonitorConfig?: IReputationMonitorConfig;
106
+ }
107
+
108
+
109
+ /**
110
+ * Extended SMTP session interface for UnifiedEmailServer
111
+ */
112
+ export interface ISmtpSession extends IBaseSmtpSession {
113
+ /**
114
+ * User information if authenticated
115
+ */
116
+ user?: {
117
+ username: string;
118
+ [key: string]: any;
119
+ };
120
+
121
+ /**
122
+ * Matched route for this session
123
+ */
124
+ matchedRoute?: IEmailRoute;
125
+ }
126
+
127
+ /**
128
+ * Authentication data for SMTP
129
+ */
130
+ import type { ISmtpAuth } from '../delivery/interfaces.js';
131
+ export type IAuthData = ISmtpAuth;
132
+
133
+ /**
134
+ * Server statistics
135
+ */
136
+ export interface IServerStats {
137
+ startTime: Date;
138
+ connections: {
139
+ current: number;
140
+ total: number;
141
+ };
142
+ messages: {
143
+ processed: number;
144
+ delivered: number;
145
+ failed: number;
146
+ };
147
+ processingTime: {
148
+ avg: number;
149
+ max: number;
150
+ min: number;
151
+ };
152
+ }
153
+
154
+ /**
155
+ * Unified email server that handles all email traffic with pattern-based routing
156
+ */
157
+ export class UnifiedEmailServer extends EventEmitter {
158
+ private dcRouter: DcRouter;
159
+ private options: IUnifiedEmailServerOptions;
160
+ private emailRouter: EmailRouter;
161
+ private domainRegistry: DomainRegistry;
162
+ private servers: any[] = [];
163
+ private stats: IServerStats;
164
+
165
+ // Add components needed for sending and securing emails
166
+ public dkimCreator: DKIMCreator;
167
+ private ipReputationChecker: IPReputationChecker; // TODO: Implement IP reputation checks in processEmailByMode
168
+ private bounceManager: BounceManager;
169
+ private ipWarmupManager: IPWarmupManager;
170
+ private senderReputationMonitor: SenderReputationMonitor;
171
+ public deliveryQueue: UnifiedDeliveryQueue;
172
+ public deliverySystem: MultiModeDeliverySystem;
173
+ private rateLimiter: UnifiedRateLimiter; // TODO: Implement rate limiting in SMTP server handlers
174
+ private dkimKeys: Map<string, string> = new Map(); // domain -> private key
175
+ private smtpClients: Map<string, SmtpClient> = new Map(); // host:port -> client
176
+
177
+ constructor(dcRouter: DcRouter, options: IUnifiedEmailServerOptions) {
178
+ super();
179
+ this.dcRouter = dcRouter;
180
+
181
+ // Set default options
182
+ this.options = {
183
+ ...options,
184
+ banner: options.banner || `${options.hostname} ESMTP UnifiedEmailServer`,
185
+ maxMessageSize: options.maxMessageSize || 10 * 1024 * 1024, // 10MB
186
+ maxClients: options.maxClients || 100,
187
+ maxConnections: options.maxConnections || 1000,
188
+ connectionTimeout: options.connectionTimeout || 60000, // 1 minute
189
+ socketTimeout: options.socketTimeout || 60000 // 1 minute
190
+ };
191
+
192
+ // Initialize DKIM creator with storage manager
193
+ this.dkimCreator = new DKIMCreator(paths.keysDir, dcRouter.storageManager);
194
+
195
+ // Initialize IP reputation checker with storage manager
196
+ this.ipReputationChecker = IPReputationChecker.getInstance({
197
+ enableLocalCache: true,
198
+ enableDNSBL: true,
199
+ enableIPInfo: true
200
+ }, dcRouter.storageManager);
201
+
202
+ // Initialize bounce manager with storage manager
203
+ this.bounceManager = new BounceManager({
204
+ maxCacheSize: 10000,
205
+ cacheTTL: 30 * 24 * 60 * 60 * 1000, // 30 days
206
+ storageManager: dcRouter.storageManager
207
+ });
208
+
209
+ // Initialize IP warmup manager
210
+ this.ipWarmupManager = IPWarmupManager.getInstance(options.ipWarmupConfig || {
211
+ enabled: true,
212
+ ipAddresses: [],
213
+ targetDomains: []
214
+ });
215
+
216
+ // Initialize sender reputation monitor with storage manager
217
+ this.senderReputationMonitor = SenderReputationMonitor.getInstance(
218
+ options.reputationMonitorConfig || {
219
+ enabled: true,
220
+ domains: []
221
+ },
222
+ dcRouter.storageManager
223
+ );
224
+
225
+ // Initialize domain registry
226
+ this.domainRegistry = new DomainRegistry(options.domains, options.defaults);
227
+
228
+ // Initialize email router with routes and storage manager
229
+ this.emailRouter = new EmailRouter(options.routes || [], {
230
+ storageManager: dcRouter.storageManager,
231
+ persistChanges: true
232
+ });
233
+
234
+ // Initialize rate limiter
235
+ this.rateLimiter = new UnifiedRateLimiter(options.rateLimits || {
236
+ global: {
237
+ maxConnectionsPerIP: 10,
238
+ maxMessagesPerMinute: 100,
239
+ maxRecipientsPerMessage: 50,
240
+ maxErrorsPerIP: 10,
241
+ maxAuthFailuresPerIP: 5,
242
+ blockDuration: 300000 // 5 minutes
243
+ }
244
+ });
245
+
246
+ // Initialize delivery components
247
+ const queueOptions: IQueueOptions = {
248
+ storageType: 'memory', // Default to memory storage
249
+ maxRetries: 3,
250
+ baseRetryDelay: 300000, // 5 minutes
251
+ maxRetryDelay: 3600000 // 1 hour
252
+ };
253
+
254
+ this.deliveryQueue = new UnifiedDeliveryQueue(queueOptions);
255
+
256
+ const deliveryOptions: IMultiModeDeliveryOptions = {
257
+ globalRateLimit: 100, // Default to 100 emails per minute
258
+ concurrentDeliveries: 10,
259
+ processBounces: true,
260
+ bounceHandler: {
261
+ processSmtpFailure: this.processSmtpFailure.bind(this)
262
+ },
263
+ onDeliverySuccess: async (item, _result) => {
264
+ // Record delivery success event for reputation monitoring
265
+ const email = item.processingResult as Email;
266
+ const senderDomain = email.from.split('@')[1];
267
+
268
+ if (senderDomain) {
269
+ this.recordReputationEvent(senderDomain, {
270
+ type: 'delivered',
271
+ count: email.to.length
272
+ });
273
+ }
274
+ }
275
+ };
276
+
277
+ this.deliverySystem = new MultiModeDeliverySystem(this.deliveryQueue, deliveryOptions, this);
278
+
279
+ // Initialize statistics
280
+ this.stats = {
281
+ startTime: new Date(),
282
+ connections: {
283
+ current: 0,
284
+ total: 0
285
+ },
286
+ messages: {
287
+ processed: 0,
288
+ delivered: 0,
289
+ failed: 0
290
+ },
291
+ processingTime: {
292
+ avg: 0,
293
+ max: 0,
294
+ min: 0
295
+ }
296
+ };
297
+
298
+ // We'll create the SMTP servers during the start() method
299
+ }
300
+
301
+ /**
302
+ * Get or create an SMTP client for the given host and port
303
+ * Uses connection pooling for efficiency
304
+ */
305
+ public getSmtpClient(host: string, port: number = 25): SmtpClient {
306
+ const clientKey = `${host}:${port}`;
307
+
308
+ // Check if we already have a client for this destination
309
+ let client = this.smtpClients.get(clientKey);
310
+
311
+ if (!client) {
312
+ // Create a new pooled SMTP client
313
+ client = createPooledSmtpClient({
314
+ host,
315
+ port,
316
+ secure: port === 465,
317
+ connectionTimeout: this.options.outbound?.connectionTimeout || 30000,
318
+ socketTimeout: this.options.outbound?.socketTimeout || 120000,
319
+ maxConnections: this.options.outbound?.maxConnections || 10,
320
+ maxMessages: 1000, // Messages per connection before reconnect
321
+ pool: true,
322
+ debug: false
323
+ });
324
+
325
+ this.smtpClients.set(clientKey, client);
326
+ logger.log('info', `Created new SMTP client pool for ${clientKey}`);
327
+ }
328
+
329
+ return client;
330
+ }
331
+
332
+ /**
333
+ * Start the unified email server
334
+ */
335
+ public async start(): Promise<void> {
336
+ logger.log('info', `Starting UnifiedEmailServer on ports: ${(this.options.ports as number[]).join(', ')}`);
337
+
338
+ try {
339
+ // Initialize the delivery queue
340
+ await this.deliveryQueue.initialize();
341
+ logger.log('info', 'Email delivery queue initialized');
342
+
343
+ // Start the delivery system
344
+ await this.deliverySystem.start();
345
+ logger.log('info', 'Email delivery system started');
346
+
347
+ // Set up DKIM for all domains
348
+ await this.setupDkimForDomains();
349
+ logger.log('info', 'DKIM configuration completed for all domains');
350
+
351
+ // Create DNS manager and ensure all DNS records are created
352
+ const dnsManager = new DnsManager(this.dcRouter);
353
+ await dnsManager.ensureDnsRecords(this.domainRegistry.getAllConfigs(), this.dkimCreator);
354
+ logger.log('info', 'DNS records ensured for all configured domains');
355
+
356
+ // Apply per-domain rate limits
357
+ this.applyDomainRateLimits();
358
+ logger.log('info', 'Per-domain rate limits configured');
359
+
360
+ // Check and rotate DKIM keys if needed
361
+ await this.checkAndRotateDkimKeys();
362
+ logger.log('info', 'DKIM key rotation check completed');
363
+
364
+ // Skip server creation in socket-handler mode
365
+ if (this.options.useSocketHandler) {
366
+ logger.log('info', 'UnifiedEmailServer started in socket-handler mode (no port listening)');
367
+ this.emit('started');
368
+ return;
369
+ }
370
+
371
+ // Ensure we have the necessary TLS options
372
+ const hasTlsConfig = this.options.tls?.keyPath && this.options.tls?.certPath;
373
+
374
+ // Prepare the certificate and key if available
375
+ let key: string | undefined;
376
+ let cert: string | undefined;
377
+
378
+ if (hasTlsConfig) {
379
+ try {
380
+ key = plugins.fs.readFileSync(this.options.tls.keyPath!, 'utf8');
381
+ cert = plugins.fs.readFileSync(this.options.tls.certPath!, 'utf8');
382
+ logger.log('info', 'TLS certificates loaded successfully');
383
+ } catch (error) {
384
+ logger.log('warn', `Failed to load TLS certificates: ${error.message}`);
385
+ }
386
+ }
387
+
388
+ // Create a SMTP server for each port
389
+ for (const port of this.options.ports as number[]) {
390
+ // Create a reference object to hold the MTA service during setup
391
+ const mtaRef = {
392
+ config: {
393
+ smtp: {
394
+ hostname: this.options.hostname
395
+ },
396
+ security: {
397
+ checkIPReputation: false,
398
+ verifyDkim: true,
399
+ verifySpf: true,
400
+ verifyDmarc: true
401
+ }
402
+ },
403
+ // These will be implemented in the real integration:
404
+ dkimVerifier: {
405
+ verify: async () => ({ isValid: true, domain: '' })
406
+ },
407
+ spfVerifier: {
408
+ verifyAndApply: async () => true
409
+ },
410
+ dmarcVerifier: {
411
+ verify: async () => ({}),
412
+ applyPolicy: () => true
413
+ },
414
+ processIncomingEmail: async (email: Email) => {
415
+ // Process email using the new route-based system
416
+ await this.processEmailByMode(email, {
417
+ id: 'session-' + Math.random().toString(36).substring(2),
418
+ state: SmtpState.FINISHED,
419
+ mailFrom: email.from,
420
+ rcptTo: email.to,
421
+ emailData: email.toRFC822String(), // Use the proper method to get the full email content
422
+ useTLS: false,
423
+ connectionEnded: true,
424
+ remoteAddress: '127.0.0.1',
425
+ clientHostname: '',
426
+ secure: false,
427
+ authenticated: false,
428
+ envelope: {
429
+ mailFrom: { address: email.from, args: {} },
430
+ rcptTo: email.to.map(recipient => ({ address: recipient, args: {} }))
431
+ }
432
+ });
433
+
434
+ return true;
435
+ }
436
+ };
437
+
438
+ // Create server options
439
+ const serverOptions = {
440
+ port,
441
+ hostname: this.options.hostname,
442
+ key,
443
+ cert
444
+ };
445
+
446
+ // Create and start the SMTP server
447
+ const smtpServer = createSmtpServer(mtaRef as any, serverOptions);
448
+ this.servers.push(smtpServer);
449
+
450
+ // Start the server
451
+ await new Promise<void>((resolve, reject) => {
452
+ try {
453
+ // Leave this empty for now, smtpServer.start() is handled by the SMTPServer class internally
454
+ // The server is started when it's created
455
+ logger.log('info', `UnifiedEmailServer listening on port ${port}`);
456
+
457
+ // Event handlers are managed internally by the SmtpServer class
458
+ // No need to access the private server property
459
+
460
+ resolve();
461
+ } catch (err) {
462
+ if ((err as any).code === 'EADDRINUSE') {
463
+ logger.log('error', `Port ${port} is already in use`);
464
+ reject(new Error(`Port ${port} is already in use`));
465
+ } else {
466
+ logger.log('error', `Error starting server on port ${port}: ${err.message}`);
467
+ reject(err);
468
+ }
469
+ }
470
+ });
471
+ }
472
+
473
+ logger.log('info', 'UnifiedEmailServer started successfully');
474
+ this.emit('started');
475
+ } catch (error) {
476
+ logger.log('error', `Failed to start UnifiedEmailServer: ${error.message}`);
477
+ throw error;
478
+ }
479
+ }
480
+
481
+ /**
482
+ * Handle a socket from smartproxy in socket-handler mode
483
+ * @param socket The socket to handle
484
+ * @param port The port this connection is for (25, 587, 465)
485
+ */
486
+ public async handleSocket(socket: plugins.net.Socket | plugins.tls.TLSSocket, port: number): Promise<void> {
487
+ if (!this.options.useSocketHandler) {
488
+ logger.log('error', 'handleSocket called but useSocketHandler is not enabled');
489
+ socket.destroy();
490
+ return;
491
+ }
492
+
493
+ logger.log('info', `Handling socket for port ${port}`);
494
+
495
+ // Create a temporary SMTP server instance for this connection
496
+ // We need a full server instance because the SMTP protocol handler needs all components
497
+ const smtpServerOptions = {
498
+ port,
499
+ hostname: this.options.hostname,
500
+ key: this.options.tls?.keyPath ? plugins.fs.readFileSync(this.options.tls.keyPath, 'utf8') : undefined,
501
+ cert: this.options.tls?.certPath ? plugins.fs.readFileSync(this.options.tls.certPath, 'utf8') : undefined
502
+ };
503
+
504
+ // Create the SMTP server instance
505
+ const smtpServer = createSmtpServer(this, smtpServerOptions);
506
+
507
+ // Get the connection manager from the server
508
+ const connectionManager = (smtpServer as any).connectionManager;
509
+
510
+ if (!connectionManager) {
511
+ logger.log('error', 'Could not get connection manager from SMTP server');
512
+ socket.destroy();
513
+ return;
514
+ }
515
+
516
+ // Determine if this is a secure connection
517
+ // Port 465 uses implicit TLS, so the socket is already secure
518
+ const isSecure = port === 465 || socket instanceof plugins.tls.TLSSocket;
519
+
520
+ // Pass the socket to the connection manager
521
+ try {
522
+ await connectionManager.handleConnection(socket, isSecure);
523
+ } catch (error) {
524
+ logger.log('error', `Error handling socket connection: ${error.message}`);
525
+ socket.destroy();
526
+ }
527
+ }
528
+
529
+ /**
530
+ * Stop the unified email server
531
+ */
532
+ public async stop(): Promise<void> {
533
+ logger.log('info', 'Stopping UnifiedEmailServer');
534
+
535
+ try {
536
+ // Clear the servers array - servers will be garbage collected
537
+ this.servers = [];
538
+
539
+ // Stop the delivery system
540
+ if (this.deliverySystem) {
541
+ await this.deliverySystem.stop();
542
+ logger.log('info', 'Email delivery system stopped');
543
+ }
544
+
545
+ // Shut down the delivery queue
546
+ if (this.deliveryQueue) {
547
+ await this.deliveryQueue.shutdown();
548
+ logger.log('info', 'Email delivery queue shut down');
549
+ }
550
+
551
+ // Close all SMTP client connections
552
+ for (const [clientKey, client] of this.smtpClients) {
553
+ try {
554
+ await client.close();
555
+ logger.log('info', `Closed SMTP client pool for ${clientKey}`);
556
+ } catch (error) {
557
+ logger.log('warn', `Error closing SMTP client for ${clientKey}: ${error.message}`);
558
+ }
559
+ }
560
+ this.smtpClients.clear();
561
+
562
+ logger.log('info', 'UnifiedEmailServer stopped successfully');
563
+ this.emit('stopped');
564
+ } catch (error) {
565
+ logger.log('error', `Error stopping UnifiedEmailServer: ${error.message}`);
566
+ throw error;
567
+ }
568
+ }
569
+
570
+
571
+
572
+
573
+
574
+ /**
575
+ * Process email based on routing rules
576
+ */
577
+ public async processEmailByMode(emailData: Email | Buffer, session: IExtendedSmtpSession): Promise<Email> {
578
+ // Convert Buffer to Email if needed
579
+ let email: Email;
580
+ if (Buffer.isBuffer(emailData)) {
581
+ // Parse the email data buffer into an Email object
582
+ try {
583
+ const parsed = await plugins.mailparser.simpleParser(emailData);
584
+ email = new Email({
585
+ from: parsed.from?.value[0]?.address || session.envelope.mailFrom.address,
586
+ to: session.envelope.rcptTo[0]?.address || '',
587
+ subject: parsed.subject || '',
588
+ text: parsed.text || '',
589
+ html: parsed.html || undefined,
590
+ attachments: parsed.attachments?.map(att => ({
591
+ filename: att.filename || '',
592
+ content: att.content,
593
+ contentType: att.contentType
594
+ })) || []
595
+ });
596
+ } catch (error) {
597
+ logger.log('error', `Error parsing email data: ${error.message}`);
598
+ throw new Error(`Error parsing email data: ${error.message}`);
599
+ }
600
+ } else {
601
+ email = emailData;
602
+ }
603
+
604
+ // First check if this is a bounce notification email
605
+ // Look for common bounce notification subject patterns
606
+ const subject = email.subject || '';
607
+ const isBounceLike = /mail delivery|delivery (failed|status|notification)|failure notice|returned mail|undeliverable|delivery problem/i.test(subject);
608
+
609
+ if (isBounceLike) {
610
+ logger.log('info', `Email subject matches bounce notification pattern: "${subject}"`);
611
+
612
+ // Try to process as a bounce
613
+ const isBounce = await this.processBounceNotification(email);
614
+
615
+ if (isBounce) {
616
+ logger.log('info', 'Successfully processed as bounce notification, skipping regular processing');
617
+ return email;
618
+ }
619
+
620
+ logger.log('info', 'Not a valid bounce notification, continuing with regular processing');
621
+ }
622
+
623
+ // Find matching route
624
+ const context: IEmailContext = { email, session };
625
+ const route = await this.emailRouter.evaluateRoutes(context);
626
+
627
+ if (!route) {
628
+ // No matching route - reject
629
+ throw new Error('No matching route for email');
630
+ }
631
+
632
+ // Store matched route in session
633
+ session.matchedRoute = route;
634
+
635
+ // Execute action based on route
636
+ await this.executeAction(route.action, email, context);
637
+
638
+ // Return the processed email
639
+ return email;
640
+ }
641
+
642
+ /**
643
+ * Execute action based on route configuration
644
+ */
645
+ private async executeAction(action: IEmailAction, email: Email, context: IEmailContext): Promise<void> {
646
+ switch (action.type) {
647
+ case 'forward':
648
+ await this.handleForwardAction(action, email, context);
649
+ break;
650
+
651
+ case 'process':
652
+ await this.handleProcessAction(action, email, context);
653
+ break;
654
+
655
+ case 'deliver':
656
+ await this.handleDeliverAction(action, email, context);
657
+ break;
658
+
659
+ case 'reject':
660
+ await this.handleRejectAction(action, email, context);
661
+ break;
662
+
663
+ default:
664
+ throw new Error(`Unknown action type: ${(action as any).type}`);
665
+ }
666
+ }
667
+
668
+ /**
669
+ * Handle forward action
670
+ */
671
+ private async handleForwardAction(_action: IEmailAction, email: Email, context: IEmailContext): Promise<void> {
672
+ if (!_action.forward) {
673
+ throw new Error('Forward action requires forward configuration');
674
+ }
675
+
676
+ const { host, port = 25, auth, addHeaders } = _action.forward;
677
+
678
+ logger.log('info', `Forwarding email to ${host}:${port}`);
679
+
680
+ // Add forwarding headers
681
+ if (addHeaders) {
682
+ for (const [key, value] of Object.entries(addHeaders)) {
683
+ email.headers[key] = value;
684
+ }
685
+ }
686
+
687
+ // Add standard forwarding headers
688
+ email.headers['X-Forwarded-For'] = context.session.remoteAddress || 'unknown';
689
+ email.headers['X-Forwarded-To'] = email.to.join(', ');
690
+ email.headers['X-Forwarded-Date'] = new Date().toISOString();
691
+
692
+ // Get SMTP client
693
+ const client = this.getSmtpClient(host, port);
694
+
695
+ try {
696
+ // Send email
697
+ await client.sendMail(email);
698
+
699
+ logger.log('info', `Successfully forwarded email to ${host}:${port}`);
700
+
701
+ SecurityLogger.getInstance().logEvent({
702
+ level: SecurityLogLevel.INFO,
703
+ type: SecurityEventType.EMAIL_FORWARDING,
704
+ message: 'Email forwarded successfully',
705
+ ipAddress: context.session.remoteAddress,
706
+ details: {
707
+ sessionId: context.session.id,
708
+ routeName: context.session.matchedRoute?.name,
709
+ targetHost: host,
710
+ targetPort: port,
711
+ recipients: email.to
712
+ },
713
+ success: true
714
+ });
715
+ } catch (error) {
716
+ logger.log('error', `Failed to forward email: ${error.message}`);
717
+
718
+ SecurityLogger.getInstance().logEvent({
719
+ level: SecurityLogLevel.ERROR,
720
+ type: SecurityEventType.EMAIL_FORWARDING,
721
+ message: 'Email forwarding failed',
722
+ ipAddress: context.session.remoteAddress,
723
+ details: {
724
+ sessionId: context.session.id,
725
+ routeName: context.session.matchedRoute?.name,
726
+ targetHost: host,
727
+ targetPort: port,
728
+ error: error.message
729
+ },
730
+ success: false
731
+ });
732
+
733
+ // Handle as bounce
734
+ for (const recipient of email.getAllRecipients()) {
735
+ await this.bounceManager.processSmtpFailure(recipient, error.message, {
736
+ sender: email.from,
737
+ originalEmailId: email.headers['Message-ID'] as string
738
+ });
739
+ }
740
+ throw error;
741
+ }
742
+ }
743
+
744
+ /**
745
+ * Handle process action
746
+ */
747
+ private async handleProcessAction(action: IEmailAction, email: Email, context: IEmailContext): Promise<void> {
748
+ logger.log('info', `Processing email with action options`);
749
+
750
+ // Apply scanning if requested
751
+ if (action.process?.scan) {
752
+ // Use existing content scanner
753
+ // Note: ContentScanner integration would go here
754
+ logger.log('info', 'Content scanning requested');
755
+ }
756
+
757
+ // Note: DKIM signing will be applied at delivery time to ensure signature validity
758
+
759
+ // Queue for delivery
760
+ const queue = action.process?.queue || 'normal';
761
+ await this.deliveryQueue.enqueue(email, 'process', context.session.matchedRoute!);
762
+
763
+ logger.log('info', `Email queued for delivery in ${queue} queue`);
764
+ }
765
+
766
+ /**
767
+ * Handle deliver action
768
+ */
769
+ private async handleDeliverAction(_action: IEmailAction, email: Email, context: IEmailContext): Promise<void> {
770
+ logger.log('info', `Delivering email locally`);
771
+
772
+ // Queue for local delivery
773
+ await this.deliveryQueue.enqueue(email, 'mta', context.session.matchedRoute!);
774
+
775
+ logger.log('info', 'Email queued for local delivery');
776
+ }
777
+
778
+ /**
779
+ * Handle reject action
780
+ */
781
+ private async handleRejectAction(action: IEmailAction, email: Email, context: IEmailContext): Promise<void> {
782
+ const code = action.reject?.code || 550;
783
+ const message = action.reject?.message || 'Message rejected';
784
+
785
+ logger.log('info', `Rejecting email with code ${code}: ${message}`);
786
+
787
+ SecurityLogger.getInstance().logEvent({
788
+ level: SecurityLogLevel.WARN,
789
+ type: SecurityEventType.EMAIL_PROCESSING,
790
+ message: 'Email rejected by routing rule',
791
+ ipAddress: context.session.remoteAddress,
792
+ details: {
793
+ sessionId: context.session.id,
794
+ routeName: context.session.matchedRoute?.name,
795
+ rejectCode: code,
796
+ rejectMessage: message,
797
+ from: email.from,
798
+ to: email.to
799
+ },
800
+ success: false
801
+ });
802
+
803
+ // Throw error with SMTP code and message
804
+ const error = new Error(message);
805
+ (error as any).responseCode = code;
806
+ throw error;
807
+ }
808
+
809
+ /**
810
+ * Handle email in MTA mode (programmatic processing)
811
+ */
812
+ private async _handleMtaMode(email: Email, session: IExtendedSmtpSession): Promise<void> {
813
+ logger.log('info', `Handling email in MTA mode for session ${session.id}`);
814
+
815
+ try {
816
+ // Apply MTA rule options if provided
817
+ if (session.matchedRoute?.action.options?.mtaOptions) {
818
+ const options = session.matchedRoute.action.options.mtaOptions;
819
+
820
+ // Apply DKIM signing if enabled
821
+ if (options.dkimSign && options.dkimOptions) {
822
+ // Sign the email with DKIM
823
+ logger.log('info', `Signing email with DKIM for domain ${options.dkimOptions.domainName}`);
824
+
825
+ try {
826
+ // Ensure DKIM keys exist for the domain
827
+ await this.dkimCreator.handleDKIMKeysForDomain(options.dkimOptions.domainName);
828
+
829
+ // Convert Email to raw format for signing
830
+ const rawEmail = email.toRFC822String();
831
+
832
+ // Create headers object
833
+ const headers = {};
834
+ for (const [key, value] of Object.entries(email.headers)) {
835
+ headers[key] = value;
836
+ }
837
+
838
+ // Sign the email
839
+ const signResult = await plugins.dkimSign(rawEmail, {
840
+ canonicalization: 'relaxed/relaxed',
841
+ algorithm: 'rsa-sha256',
842
+ signTime: new Date(),
843
+ signatureData: [
844
+ {
845
+ signingDomain: options.dkimOptions.domainName,
846
+ selector: options.dkimOptions.keySelector || 'mta',
847
+ privateKey: (await this.dkimCreator.readDKIMKeys(options.dkimOptions.domainName)).privateKey,
848
+ algorithm: 'rsa-sha256',
849
+ canonicalization: 'relaxed/relaxed'
850
+ }
851
+ ]
852
+ });
853
+
854
+ // Add the DKIM-Signature header to the email
855
+ if (signResult.signatures) {
856
+ email.addHeader('DKIM-Signature', signResult.signatures);
857
+ logger.log('info', `Successfully added DKIM signature for ${options.dkimOptions.domainName}`);
858
+ }
859
+ } catch (error) {
860
+ logger.log('error', `Failed to sign email with DKIM: ${error.message}`);
861
+ }
862
+ }
863
+ }
864
+
865
+ // Get email content for logging/processing
866
+ const subject = email.subject;
867
+ const recipients = email.getAllRecipients().join(', ');
868
+
869
+ logger.log('info', `Email processed by MTA: ${subject} to ${recipients}`);
870
+
871
+ SecurityLogger.getInstance().logEvent({
872
+ level: SecurityLogLevel.INFO,
873
+ type: SecurityEventType.EMAIL_PROCESSING,
874
+ message: 'Email processed by MTA',
875
+ ipAddress: session.remoteAddress,
876
+ details: {
877
+ sessionId: session.id,
878
+ ruleName: session.matchedRoute?.name || 'default',
879
+ subject,
880
+ recipients
881
+ },
882
+ success: true
883
+ });
884
+ } catch (error) {
885
+ logger.log('error', `Failed to process email in MTA mode: ${error.message}`);
886
+
887
+ SecurityLogger.getInstance().logEvent({
888
+ level: SecurityLogLevel.ERROR,
889
+ type: SecurityEventType.EMAIL_PROCESSING,
890
+ message: 'MTA processing failed',
891
+ ipAddress: session.remoteAddress,
892
+ details: {
893
+ sessionId: session.id,
894
+ ruleName: session.matchedRoute?.name || 'default',
895
+ error: error.message
896
+ },
897
+ success: false
898
+ });
899
+
900
+ throw error;
901
+ }
902
+ }
903
+
904
+ /**
905
+ * Handle email in process mode (store-and-forward with scanning)
906
+ */
907
+ private async _handleProcessMode(email: Email, session: IExtendedSmtpSession): Promise<void> {
908
+ logger.log('info', `Handling email in process mode for session ${session.id}`);
909
+
910
+ try {
911
+ const route = session.matchedRoute;
912
+
913
+ // Apply content scanning if enabled
914
+ if (route?.action.options?.contentScanning && route.action.options.scanners && route.action.options.scanners.length > 0) {
915
+ logger.log('info', 'Performing content scanning');
916
+
917
+ // Apply each scanner
918
+ for (const scanner of route.action.options.scanners) {
919
+ switch (scanner.type) {
920
+ case 'spam':
921
+ logger.log('info', 'Scanning for spam content');
922
+ // Implement spam scanning
923
+ break;
924
+
925
+ case 'virus':
926
+ logger.log('info', 'Scanning for virus content');
927
+ // Implement virus scanning
928
+ break;
929
+
930
+ case 'attachment':
931
+ logger.log('info', 'Scanning attachments');
932
+
933
+ // Check for blocked extensions
934
+ if (scanner.blockedExtensions && scanner.blockedExtensions.length > 0) {
935
+ for (const attachment of email.attachments) {
936
+ const ext = this.getFileExtension(attachment.filename);
937
+ if (scanner.blockedExtensions.includes(ext)) {
938
+ if (scanner.action === 'reject') {
939
+ throw new Error(`Blocked attachment type: ${ext}`);
940
+ } else { // tag
941
+ email.addHeader('X-Attachment-Warning', `Potentially unsafe attachment: ${attachment.filename}`);
942
+ }
943
+ }
944
+ }
945
+ }
946
+ break;
947
+ }
948
+ }
949
+ }
950
+
951
+ // Apply transformations if defined
952
+ if (route?.action.options?.transformations && route.action.options.transformations.length > 0) {
953
+ logger.log('info', 'Applying email transformations');
954
+
955
+ for (const transform of route.action.options.transformations) {
956
+ switch (transform.type) {
957
+ case 'addHeader':
958
+ if (transform.header && transform.value) {
959
+ email.addHeader(transform.header, transform.value);
960
+ }
961
+ break;
962
+ }
963
+ }
964
+ }
965
+
966
+ logger.log('info', `Email successfully processed in store-and-forward mode`);
967
+
968
+ SecurityLogger.getInstance().logEvent({
969
+ level: SecurityLogLevel.INFO,
970
+ type: SecurityEventType.EMAIL_PROCESSING,
971
+ message: 'Email processed and queued',
972
+ ipAddress: session.remoteAddress,
973
+ details: {
974
+ sessionId: session.id,
975
+ ruleName: route?.name || 'default',
976
+ contentScanning: route?.action.options?.contentScanning || false,
977
+ subject: email.subject
978
+ },
979
+ success: true
980
+ });
981
+ } catch (error) {
982
+ logger.log('error', `Failed to process email: ${error.message}`);
983
+
984
+ SecurityLogger.getInstance().logEvent({
985
+ level: SecurityLogLevel.ERROR,
986
+ type: SecurityEventType.EMAIL_PROCESSING,
987
+ message: 'Email processing failed',
988
+ ipAddress: session.remoteAddress,
989
+ details: {
990
+ sessionId: session.id,
991
+ ruleName: session.matchedRoute?.name || 'default',
992
+ error: error.message
993
+ },
994
+ success: false
995
+ });
996
+
997
+ throw error;
998
+ }
999
+ }
1000
+
1001
+ /**
1002
+ * Get file extension from filename
1003
+ */
1004
+ private getFileExtension(filename: string): string {
1005
+ return filename.substring(filename.lastIndexOf('.')).toLowerCase();
1006
+ }
1007
+
1008
+
1009
+
1010
+ /**
1011
+ * Set up DKIM configuration for all domains
1012
+ */
1013
+ private async setupDkimForDomains(): Promise<void> {
1014
+ const domainConfigs = this.domainRegistry.getAllConfigs();
1015
+
1016
+ if (domainConfigs.length === 0) {
1017
+ logger.log('warn', 'No domains configured for DKIM');
1018
+ return;
1019
+ }
1020
+
1021
+ for (const domainConfig of domainConfigs) {
1022
+ const domain = domainConfig.domain;
1023
+ const selector = domainConfig.dkim?.selector || 'default';
1024
+
1025
+ try {
1026
+ // Check if DKIM keys already exist for this domain
1027
+ let keyPair: { privateKey: string; publicKey: string };
1028
+
1029
+ try {
1030
+ // Try to read existing keys
1031
+ keyPair = await this.dkimCreator.readDKIMKeys(domain);
1032
+ logger.log('info', `Using existing DKIM keys for domain: ${domain}`);
1033
+ } catch (error) {
1034
+ // Generate new keys if they don't exist
1035
+ keyPair = await this.dkimCreator.createDKIMKeys();
1036
+ // Store them for future use
1037
+ await this.dkimCreator.createAndStoreDKIMKeys(domain);
1038
+ logger.log('info', `Generated new DKIM keys for domain: ${domain}`);
1039
+ }
1040
+
1041
+ // Store the private key for signing
1042
+ this.dkimKeys.set(domain, keyPair.privateKey);
1043
+
1044
+ // DNS record creation is now handled by DnsManager
1045
+ logger.log('info', `DKIM keys loaded for domain: ${domain} with selector: ${selector}`);
1046
+ } catch (error) {
1047
+ logger.log('error', `Failed to set up DKIM for domain ${domain}: ${error.message}`);
1048
+ }
1049
+ }
1050
+ }
1051
+
1052
+
1053
+ /**
1054
+ * Apply per-domain rate limits from domain configurations
1055
+ */
1056
+ private applyDomainRateLimits(): void {
1057
+ const domainConfigs = this.domainRegistry.getAllConfigs();
1058
+
1059
+ for (const domainConfig of domainConfigs) {
1060
+ if (domainConfig.rateLimits) {
1061
+ const domain = domainConfig.domain;
1062
+ const rateLimitConfig: any = {};
1063
+
1064
+ // Convert domain-specific rate limits to the format expected by UnifiedRateLimiter
1065
+ if (domainConfig.rateLimits.outbound) {
1066
+ if (domainConfig.rateLimits.outbound.messagesPerMinute) {
1067
+ rateLimitConfig.maxMessagesPerMinute = domainConfig.rateLimits.outbound.messagesPerMinute;
1068
+ }
1069
+ // Note: messagesPerHour and messagesPerDay would need additional implementation in rate limiter
1070
+ }
1071
+
1072
+ if (domainConfig.rateLimits.inbound) {
1073
+ if (domainConfig.rateLimits.inbound.messagesPerMinute) {
1074
+ rateLimitConfig.maxMessagesPerMinute = domainConfig.rateLimits.inbound.messagesPerMinute;
1075
+ }
1076
+ if (domainConfig.rateLimits.inbound.connectionsPerIp) {
1077
+ rateLimitConfig.maxConnectionsPerIP = domainConfig.rateLimits.inbound.connectionsPerIp;
1078
+ }
1079
+ if (domainConfig.rateLimits.inbound.recipientsPerMessage) {
1080
+ rateLimitConfig.maxRecipientsPerMessage = domainConfig.rateLimits.inbound.recipientsPerMessage;
1081
+ }
1082
+ }
1083
+
1084
+ // Apply the rate limits if we have any
1085
+ if (Object.keys(rateLimitConfig).length > 0) {
1086
+ this.rateLimiter.applyDomainLimits(domain, rateLimitConfig);
1087
+ logger.log('info', `Applied rate limits for domain ${domain}:`, rateLimitConfig);
1088
+ }
1089
+ }
1090
+ }
1091
+ }
1092
+
1093
+ /**
1094
+ * Check and rotate DKIM keys if needed
1095
+ */
1096
+ private async checkAndRotateDkimKeys(): Promise<void> {
1097
+ const domainConfigs = this.domainRegistry.getAllConfigs();
1098
+
1099
+ for (const domainConfig of domainConfigs) {
1100
+ const domain = domainConfig.domain;
1101
+ const selector = domainConfig.dkim?.selector || 'default';
1102
+ const rotateKeys = domainConfig.dkim?.rotateKeys || false;
1103
+ const rotationInterval = domainConfig.dkim?.rotationInterval || 90;
1104
+ const keySize = domainConfig.dkim?.keySize || 2048;
1105
+
1106
+ if (!rotateKeys) {
1107
+ logger.log('debug', `DKIM key rotation disabled for ${domain}`);
1108
+ continue;
1109
+ }
1110
+
1111
+ try {
1112
+ // Check if keys need rotation
1113
+ const needsRotation = await this.dkimCreator.needsRotation(domain, selector, rotationInterval);
1114
+
1115
+ if (needsRotation) {
1116
+ logger.log('info', `DKIM keys need rotation for ${domain} (selector: ${selector})`);
1117
+
1118
+ // Rotate the keys
1119
+ const newSelector = await this.dkimCreator.rotateDkimKeys(domain, selector, keySize);
1120
+
1121
+ // Update the domain config with new selector
1122
+ domainConfig.dkim = {
1123
+ ...domainConfig.dkim,
1124
+ selector: newSelector
1125
+ };
1126
+
1127
+ // Re-register DNS handler for new selector if internal-dns mode
1128
+ if (domainConfig.dnsMode === 'internal-dns' && this.dcRouter.dnsServer) {
1129
+ // Get new public key
1130
+ const keyPair = await this.dkimCreator.readDKIMKeysForSelector(domain, newSelector);
1131
+ const publicKeyBase64 = keyPair.publicKey
1132
+ .replace(/-----BEGIN PUBLIC KEY-----/g, '')
1133
+ .replace(/-----END PUBLIC KEY-----/g, '')
1134
+ .replace(/\s/g, '');
1135
+
1136
+ const ttl = domainConfig.dns?.internal?.ttl || 3600;
1137
+
1138
+ // Register new selector
1139
+ this.dcRouter.dnsServer.registerHandler(
1140
+ `${newSelector}._domainkey.${domain}`,
1141
+ ['TXT'],
1142
+ () => ({
1143
+ name: `${newSelector}._domainkey.${domain}`,
1144
+ type: 'TXT',
1145
+ class: 'IN',
1146
+ ttl: ttl,
1147
+ data: `v=DKIM1; k=rsa; p=${publicKeyBase64}`
1148
+ })
1149
+ );
1150
+
1151
+ logger.log('info', `DKIM DNS handler registered for new selector: ${newSelector}._domainkey.${domain}`);
1152
+
1153
+ // Store the updated public key in storage
1154
+ await this.dcRouter.storageManager.set(
1155
+ `/email/dkim/${domain}/public.key`,
1156
+ keyPair.publicKey
1157
+ );
1158
+ }
1159
+
1160
+ // Clean up old keys after grace period (async, don't wait)
1161
+ this.dkimCreator.cleanupOldKeys(domain, 30).catch(error => {
1162
+ logger.log('warn', `Failed to cleanup old DKIM keys for ${domain}: ${error.message}`);
1163
+ });
1164
+
1165
+ } else {
1166
+ logger.log('debug', `DKIM keys for ${domain} are up to date`);
1167
+ }
1168
+ } catch (error) {
1169
+ logger.log('error', `Failed to check/rotate DKIM keys for ${domain}: ${error.message}`);
1170
+ }
1171
+ }
1172
+ }
1173
+
1174
+
1175
+ /**
1176
+ * Generate SmartProxy routes for email ports
1177
+ */
1178
+ public generateProxyRoutes(portMapping?: Record<number, number>): any[] {
1179
+ const routes: any[] = [];
1180
+ const defaultPortMapping = {
1181
+ 25: 10025,
1182
+ 587: 10587,
1183
+ 465: 10465
1184
+ };
1185
+
1186
+ const actualPortMapping = portMapping || defaultPortMapping;
1187
+
1188
+ // Generate routes for each configured port
1189
+ for (const externalPort of this.options.ports) {
1190
+ const internalPort = actualPortMapping[externalPort] || externalPort + 10000;
1191
+
1192
+ let routeName = 'email-route';
1193
+ let tlsMode = 'passthrough';
1194
+
1195
+ // Configure based on port
1196
+ switch (externalPort) {
1197
+ case 25:
1198
+ routeName = 'smtp-route';
1199
+ tlsMode = 'passthrough'; // STARTTLS
1200
+ break;
1201
+ case 587:
1202
+ routeName = 'submission-route';
1203
+ tlsMode = 'passthrough'; // STARTTLS
1204
+ break;
1205
+ case 465:
1206
+ routeName = 'smtps-route';
1207
+ tlsMode = 'terminate'; // Implicit TLS
1208
+ break;
1209
+ default:
1210
+ routeName = `email-port-${externalPort}-route`;
1211
+ }
1212
+
1213
+ routes.push({
1214
+ name: routeName,
1215
+ match: {
1216
+ ports: [externalPort]
1217
+ },
1218
+ action: {
1219
+ type: 'forward',
1220
+ target: {
1221
+ host: 'localhost',
1222
+ port: internalPort
1223
+ },
1224
+ tls: {
1225
+ mode: tlsMode
1226
+ }
1227
+ }
1228
+ });
1229
+ }
1230
+
1231
+ return routes;
1232
+ }
1233
+
1234
+ /**
1235
+ * Update server configuration
1236
+ */
1237
+ public updateOptions(options: Partial<IUnifiedEmailServerOptions>): void {
1238
+ // Stop the server if changing ports
1239
+ const portsChanged = options.ports &&
1240
+ (!this.options.ports ||
1241
+ JSON.stringify(options.ports) !== JSON.stringify(this.options.ports));
1242
+
1243
+ if (portsChanged) {
1244
+ this.stop().then(() => {
1245
+ this.options = { ...this.options, ...options };
1246
+ this.start();
1247
+ });
1248
+ } else {
1249
+ // Update options without restart
1250
+ this.options = { ...this.options, ...options };
1251
+
1252
+ // Update domain registry if domains changed
1253
+ if (options.domains) {
1254
+ this.domainRegistry = new DomainRegistry(options.domains, options.defaults || this.options.defaults);
1255
+ }
1256
+
1257
+ // Update email router if routes changed
1258
+ if (options.routes) {
1259
+ this.emailRouter.updateRoutes(options.routes);
1260
+ }
1261
+ }
1262
+ }
1263
+
1264
+ /**
1265
+ * Update email routes
1266
+ */
1267
+ public updateEmailRoutes(routes: IEmailRoute[]): void {
1268
+ this.options.routes = routes;
1269
+ this.emailRouter.updateRoutes(routes);
1270
+ }
1271
+
1272
+ /**
1273
+ * Get server statistics
1274
+ */
1275
+ public getStats(): IServerStats {
1276
+ return { ...this.stats };
1277
+ }
1278
+
1279
+ /**
1280
+ * Get domain registry
1281
+ */
1282
+ public getDomainRegistry(): DomainRegistry {
1283
+ return this.domainRegistry;
1284
+ }
1285
+
1286
+ /**
1287
+ * Update email routes dynamically
1288
+ */
1289
+ public updateRoutes(routes: IEmailRoute[]): void {
1290
+ this.emailRouter.setRoutes(routes);
1291
+ logger.log('info', `Updated email routes with ${routes.length} routes`);
1292
+ }
1293
+
1294
+ /**
1295
+ * Send an email through the delivery system
1296
+ * @param email The email to send
1297
+ * @param mode The processing mode to use
1298
+ * @param rule Optional rule to apply
1299
+ * @param options Optional sending options
1300
+ * @returns The ID of the queued email
1301
+ */
1302
+ public async sendEmail(
1303
+ email: Email,
1304
+ mode: EmailProcessingMode = 'mta',
1305
+ route?: IEmailRoute,
1306
+ options?: {
1307
+ skipSuppressionCheck?: boolean;
1308
+ ipAddress?: string;
1309
+ isTransactional?: boolean;
1310
+ }
1311
+ ): Promise<string> {
1312
+ logger.log('info', `Sending email: ${email.subject} to ${email.to.join(', ')}`);
1313
+
1314
+ try {
1315
+ // Validate the email
1316
+ if (!email.from) {
1317
+ throw new Error('Email must have a sender address');
1318
+ }
1319
+
1320
+ if (!email.to || email.to.length === 0) {
1321
+ throw new Error('Email must have at least one recipient');
1322
+ }
1323
+
1324
+ // Check if any recipients are on the suppression list (unless explicitly skipped)
1325
+ if (!options?.skipSuppressionCheck) {
1326
+ const suppressedRecipients = email.to.filter(recipient => this.isEmailSuppressed(recipient));
1327
+
1328
+ if (suppressedRecipients.length > 0) {
1329
+ // Filter out suppressed recipients
1330
+ const originalCount = email.to.length;
1331
+ const suppressed = suppressedRecipients.map(recipient => {
1332
+ const info = this.getSuppressionInfo(recipient);
1333
+ return {
1334
+ email: recipient,
1335
+ reason: info?.reason || 'Unknown',
1336
+ until: info?.expiresAt ? new Date(info.expiresAt).toISOString() : 'permanent'
1337
+ };
1338
+ });
1339
+
1340
+ logger.log('warn', `Filtering out ${suppressedRecipients.length} suppressed recipient(s)`, { suppressed });
1341
+
1342
+ // If all recipients are suppressed, throw an error
1343
+ if (suppressedRecipients.length === originalCount) {
1344
+ throw new Error('All recipients are on the suppression list');
1345
+ }
1346
+
1347
+ // Filter the recipients list to only include non-suppressed addresses
1348
+ email.to = email.to.filter(recipient => !this.isEmailSuppressed(recipient));
1349
+ }
1350
+ }
1351
+
1352
+ // IP warmup handling
1353
+ let ipAddress = options?.ipAddress;
1354
+
1355
+ // If no specific IP was provided, use IP warmup manager to find the best IP
1356
+ if (!ipAddress) {
1357
+ const domain = email.from.split('@')[1];
1358
+
1359
+ ipAddress = this.getBestIPForSending({
1360
+ from: email.from,
1361
+ to: email.to,
1362
+ domain,
1363
+ isTransactional: options?.isTransactional
1364
+ });
1365
+
1366
+ if (ipAddress) {
1367
+ logger.log('info', `Selected IP ${ipAddress} for sending based on warmup status`);
1368
+ }
1369
+ }
1370
+
1371
+ // If an IP is provided or selected by warmup manager, check its capacity
1372
+ if (ipAddress) {
1373
+ // Check if the IP can send more today
1374
+ if (!this.canIPSendMoreToday(ipAddress)) {
1375
+ logger.log('warn', `IP ${ipAddress} has reached its daily sending limit, email will be queued for later delivery`);
1376
+ }
1377
+
1378
+ // Check if the IP can send more this hour
1379
+ if (!this.canIPSendMoreThisHour(ipAddress)) {
1380
+ logger.log('warn', `IP ${ipAddress} has reached its hourly sending limit, email will be queued for later delivery`);
1381
+ }
1382
+
1383
+ // Record the send for IP warmup tracking
1384
+ this.recordIPSend(ipAddress);
1385
+
1386
+ // Add IP header to the email
1387
+ email.addHeader('X-Sending-IP', ipAddress);
1388
+ }
1389
+
1390
+ // Check if the sender domain has DKIM keys and sign the email if needed
1391
+ if (mode === 'mta' && route?.action.options?.mtaOptions?.dkimSign) {
1392
+ const domain = email.from.split('@')[1];
1393
+ await this.handleDkimSigning(email, domain, route.action.options.mtaOptions.dkimOptions?.keySelector || 'mta');
1394
+ }
1395
+
1396
+ // Generate a unique ID for this email
1397
+ const id = plugins.uuid.v4();
1398
+
1399
+ // Queue the email for delivery
1400
+ await this.deliveryQueue.enqueue(email, mode, route);
1401
+
1402
+ // Record 'sent' event for domain reputation monitoring
1403
+ const senderDomain = email.from.split('@')[1];
1404
+ if (senderDomain) {
1405
+ this.recordReputationEvent(senderDomain, {
1406
+ type: 'sent',
1407
+ count: email.to.length
1408
+ });
1409
+ }
1410
+
1411
+ logger.log('info', `Email queued with ID: ${id}`);
1412
+ return id;
1413
+ } catch (error) {
1414
+ logger.log('error', `Failed to send email: ${error.message}`);
1415
+ throw error;
1416
+ }
1417
+ }
1418
+
1419
+ /**
1420
+ * Handle DKIM signing for an email
1421
+ * @param email The email to sign
1422
+ * @param domain The domain to sign with
1423
+ * @param selector The DKIM selector
1424
+ */
1425
+ private async handleDkimSigning(email: Email, domain: string, selector: string): Promise<void> {
1426
+ try {
1427
+ // Ensure we have DKIM keys for this domain
1428
+ await this.dkimCreator.handleDKIMKeysForDomain(domain);
1429
+
1430
+ // Get the private key
1431
+ const { privateKey } = await this.dkimCreator.readDKIMKeys(domain);
1432
+
1433
+ // Convert Email to raw format for signing
1434
+ const rawEmail = email.toRFC822String();
1435
+
1436
+ // Sign the email
1437
+ const signResult = await plugins.dkimSign(rawEmail, {
1438
+ canonicalization: 'relaxed/relaxed',
1439
+ algorithm: 'rsa-sha256',
1440
+ signTime: new Date(),
1441
+ signatureData: [
1442
+ {
1443
+ signingDomain: domain,
1444
+ selector: selector,
1445
+ privateKey: privateKey,
1446
+ algorithm: 'rsa-sha256',
1447
+ canonicalization: 'relaxed/relaxed'
1448
+ }
1449
+ ]
1450
+ });
1451
+
1452
+ // Add the DKIM-Signature header to the email
1453
+ if (signResult.signatures) {
1454
+ email.addHeader('DKIM-Signature', signResult.signatures);
1455
+ logger.log('info', `Successfully added DKIM signature for ${domain}`);
1456
+ }
1457
+ } catch (error) {
1458
+ logger.log('error', `Failed to sign email with DKIM: ${error.message}`);
1459
+ // Continue without DKIM rather than failing the send
1460
+ }
1461
+ }
1462
+
1463
+ /**
1464
+ * Process a bounce notification email
1465
+ * @param bounceEmail The email containing bounce notification information
1466
+ * @returns Processed bounce record or null if not a bounce
1467
+ */
1468
+ public async processBounceNotification(bounceEmail: Email): Promise<boolean> {
1469
+ logger.log('info', 'Processing potential bounce notification email');
1470
+
1471
+ try {
1472
+ // Process as a bounce notification (no conversion needed anymore)
1473
+ const bounceRecord = await this.bounceManager.processBounceEmail(bounceEmail);
1474
+
1475
+ if (bounceRecord) {
1476
+ logger.log('info', `Successfully processed bounce notification for ${bounceRecord.recipient}`, {
1477
+ bounceType: bounceRecord.bounceType,
1478
+ bounceCategory: bounceRecord.bounceCategory
1479
+ });
1480
+
1481
+ // Notify any registered listeners about the bounce
1482
+ this.emit('bounceProcessed', bounceRecord);
1483
+
1484
+ // Record bounce event for domain reputation tracking
1485
+ if (bounceRecord.domain) {
1486
+ this.recordReputationEvent(bounceRecord.domain, {
1487
+ type: 'bounce',
1488
+ hardBounce: bounceRecord.bounceCategory === BounceCategory.HARD,
1489
+ receivingDomain: bounceRecord.recipient.split('@')[1]
1490
+ });
1491
+ }
1492
+
1493
+ // Log security event
1494
+ SecurityLogger.getInstance().logEvent({
1495
+ level: SecurityLogLevel.INFO,
1496
+ type: SecurityEventType.EMAIL_VALIDATION,
1497
+ message: `Bounce notification processed for recipient`,
1498
+ domain: bounceRecord.domain,
1499
+ details: {
1500
+ recipient: bounceRecord.recipient,
1501
+ bounceType: bounceRecord.bounceType,
1502
+ bounceCategory: bounceRecord.bounceCategory
1503
+ },
1504
+ success: true
1505
+ });
1506
+
1507
+ return true;
1508
+ } else {
1509
+ logger.log('info', 'Email not recognized as a bounce notification');
1510
+ return false;
1511
+ }
1512
+ } catch (error) {
1513
+ logger.log('error', `Error processing bounce notification: ${error.message}`);
1514
+
1515
+ SecurityLogger.getInstance().logEvent({
1516
+ level: SecurityLogLevel.ERROR,
1517
+ type: SecurityEventType.EMAIL_VALIDATION,
1518
+ message: 'Failed to process bounce notification',
1519
+ details: {
1520
+ error: error.message,
1521
+ subject: bounceEmail.subject
1522
+ },
1523
+ success: false
1524
+ });
1525
+
1526
+ return false;
1527
+ }
1528
+ }
1529
+
1530
+ /**
1531
+ * Process an SMTP failure as a bounce
1532
+ * @param recipient Recipient email that failed
1533
+ * @param smtpResponse SMTP error response
1534
+ * @param options Additional options for bounce processing
1535
+ * @returns Processed bounce record
1536
+ */
1537
+ public async processSmtpFailure(
1538
+ recipient: string,
1539
+ smtpResponse: string,
1540
+ options: {
1541
+ sender?: string;
1542
+ originalEmailId?: string;
1543
+ statusCode?: string;
1544
+ headers?: Record<string, string>;
1545
+ } = {}
1546
+ ): Promise<boolean> {
1547
+ logger.log('info', `Processing SMTP failure for ${recipient}: ${smtpResponse}`);
1548
+
1549
+ try {
1550
+ // Process the SMTP failure through the bounce manager
1551
+ const bounceRecord = await this.bounceManager.processSmtpFailure(
1552
+ recipient,
1553
+ smtpResponse,
1554
+ options
1555
+ );
1556
+
1557
+ logger.log('info', `Successfully processed SMTP failure for ${recipient} as ${bounceRecord.bounceCategory} bounce`, {
1558
+ bounceType: bounceRecord.bounceType
1559
+ });
1560
+
1561
+ // Notify any registered listeners about the bounce
1562
+ this.emit('bounceProcessed', bounceRecord);
1563
+
1564
+ // Record bounce event for domain reputation tracking
1565
+ if (bounceRecord.domain) {
1566
+ this.recordReputationEvent(bounceRecord.domain, {
1567
+ type: 'bounce',
1568
+ hardBounce: bounceRecord.bounceCategory === BounceCategory.HARD,
1569
+ receivingDomain: bounceRecord.recipient.split('@')[1]
1570
+ });
1571
+ }
1572
+
1573
+ // Log security event
1574
+ SecurityLogger.getInstance().logEvent({
1575
+ level: SecurityLogLevel.INFO,
1576
+ type: SecurityEventType.EMAIL_VALIDATION,
1577
+ message: `SMTP failure processed for recipient`,
1578
+ domain: bounceRecord.domain,
1579
+ details: {
1580
+ recipient: bounceRecord.recipient,
1581
+ bounceType: bounceRecord.bounceType,
1582
+ bounceCategory: bounceRecord.bounceCategory,
1583
+ smtpResponse
1584
+ },
1585
+ success: true
1586
+ });
1587
+
1588
+ return true;
1589
+ } catch (error) {
1590
+ logger.log('error', `Error processing SMTP failure: ${error.message}`);
1591
+
1592
+ SecurityLogger.getInstance().logEvent({
1593
+ level: SecurityLogLevel.ERROR,
1594
+ type: SecurityEventType.EMAIL_VALIDATION,
1595
+ message: 'Failed to process SMTP failure',
1596
+ details: {
1597
+ recipient,
1598
+ smtpResponse,
1599
+ error: error.message
1600
+ },
1601
+ success: false
1602
+ });
1603
+
1604
+ return false;
1605
+ }
1606
+ }
1607
+
1608
+ /**
1609
+ * Check if an email address is suppressed (has bounced previously)
1610
+ * @param email Email address to check
1611
+ * @returns Whether the email is suppressed
1612
+ */
1613
+ public isEmailSuppressed(email: string): boolean {
1614
+ return this.bounceManager.isEmailSuppressed(email);
1615
+ }
1616
+
1617
+ /**
1618
+ * Get suppression information for an email
1619
+ * @param email Email address to check
1620
+ * @returns Suppression information or null if not suppressed
1621
+ */
1622
+ public getSuppressionInfo(email: string): {
1623
+ reason: string;
1624
+ timestamp: number;
1625
+ expiresAt?: number;
1626
+ } | null {
1627
+ return this.bounceManager.getSuppressionInfo(email);
1628
+ }
1629
+
1630
+ /**
1631
+ * Get bounce history information for an email
1632
+ * @param email Email address to check
1633
+ * @returns Bounce history or null if no bounces
1634
+ */
1635
+ public getBounceHistory(email: string): {
1636
+ lastBounce: number;
1637
+ count: number;
1638
+ type: BounceType;
1639
+ category: BounceCategory;
1640
+ } | null {
1641
+ return this.bounceManager.getBounceInfo(email);
1642
+ }
1643
+
1644
+ /**
1645
+ * Get all suppressed email addresses
1646
+ * @returns Array of suppressed email addresses
1647
+ */
1648
+ public getSuppressionList(): string[] {
1649
+ return this.bounceManager.getSuppressionList();
1650
+ }
1651
+
1652
+ /**
1653
+ * Get all hard bounced email addresses
1654
+ * @returns Array of hard bounced email addresses
1655
+ */
1656
+ public getHardBouncedAddresses(): string[] {
1657
+ return this.bounceManager.getHardBouncedAddresses();
1658
+ }
1659
+
1660
+ /**
1661
+ * Add an email to the suppression list
1662
+ * @param email Email address to suppress
1663
+ * @param reason Reason for suppression
1664
+ * @param expiresAt Optional expiration time (undefined for permanent)
1665
+ */
1666
+ public addToSuppressionList(email: string, reason: string, expiresAt?: number): void {
1667
+ this.bounceManager.addToSuppressionList(email, reason, expiresAt);
1668
+ logger.log('info', `Added ${email} to suppression list: ${reason}`);
1669
+ }
1670
+
1671
+ /**
1672
+ * Remove an email from the suppression list
1673
+ * @param email Email address to remove from suppression
1674
+ */
1675
+ public removeFromSuppressionList(email: string): void {
1676
+ this.bounceManager.removeFromSuppressionList(email);
1677
+ logger.log('info', `Removed ${email} from suppression list`);
1678
+ }
1679
+
1680
+ /**
1681
+ * Get the status of IP warmup process
1682
+ * @param ipAddress Optional specific IP to check
1683
+ * @returns Status of IP warmup
1684
+ */
1685
+ public getIPWarmupStatus(ipAddress?: string): any {
1686
+ return this.ipWarmupManager.getWarmupStatus(ipAddress);
1687
+ }
1688
+
1689
+ /**
1690
+ * Add a new IP address to the warmup process
1691
+ * @param ipAddress IP address to add
1692
+ */
1693
+ public addIPToWarmup(ipAddress: string): void {
1694
+ this.ipWarmupManager.addIPToWarmup(ipAddress);
1695
+ }
1696
+
1697
+ /**
1698
+ * Remove an IP address from the warmup process
1699
+ * @param ipAddress IP address to remove
1700
+ */
1701
+ public removeIPFromWarmup(ipAddress: string): void {
1702
+ this.ipWarmupManager.removeIPFromWarmup(ipAddress);
1703
+ }
1704
+
1705
+ /**
1706
+ * Update metrics for an IP in the warmup process
1707
+ * @param ipAddress IP address
1708
+ * @param metrics Metrics to update
1709
+ */
1710
+ public updateIPWarmupMetrics(
1711
+ ipAddress: string,
1712
+ metrics: { openRate?: number; bounceRate?: number; complaintRate?: number }
1713
+ ): void {
1714
+ this.ipWarmupManager.updateMetrics(ipAddress, metrics);
1715
+ }
1716
+
1717
+ /**
1718
+ * Check if an IP can send more emails today
1719
+ * @param ipAddress IP address to check
1720
+ * @returns Whether the IP can send more today
1721
+ */
1722
+ public canIPSendMoreToday(ipAddress: string): boolean {
1723
+ return this.ipWarmupManager.canSendMoreToday(ipAddress);
1724
+ }
1725
+
1726
+ /**
1727
+ * Check if an IP can send more emails in the current hour
1728
+ * @param ipAddress IP address to check
1729
+ * @returns Whether the IP can send more this hour
1730
+ */
1731
+ public canIPSendMoreThisHour(ipAddress: string): boolean {
1732
+ return this.ipWarmupManager.canSendMoreThisHour(ipAddress);
1733
+ }
1734
+
1735
+ /**
1736
+ * Get the best IP to use for sending an email based on warmup status
1737
+ * @param emailInfo Information about the email being sent
1738
+ * @returns Best IP to use or null
1739
+ */
1740
+ public getBestIPForSending(emailInfo: {
1741
+ from: string;
1742
+ to: string[];
1743
+ domain: string;
1744
+ isTransactional?: boolean;
1745
+ }): string | null {
1746
+ return this.ipWarmupManager.getBestIPForSending(emailInfo);
1747
+ }
1748
+
1749
+ /**
1750
+ * Set the active IP allocation policy for warmup
1751
+ * @param policyName Name of the policy to set
1752
+ */
1753
+ public setIPAllocationPolicy(policyName: string): void {
1754
+ this.ipWarmupManager.setActiveAllocationPolicy(policyName);
1755
+ }
1756
+
1757
+ /**
1758
+ * Record that an email was sent using a specific IP
1759
+ * @param ipAddress IP address used for sending
1760
+ */
1761
+ public recordIPSend(ipAddress: string): void {
1762
+ this.ipWarmupManager.recordSend(ipAddress);
1763
+ }
1764
+
1765
+ /**
1766
+ * Get reputation data for a domain
1767
+ * @param domain Domain to get reputation for
1768
+ * @returns Domain reputation metrics
1769
+ */
1770
+ public getDomainReputationData(domain: string): any {
1771
+ return this.senderReputationMonitor.getReputationData(domain);
1772
+ }
1773
+
1774
+ /**
1775
+ * Get summary reputation data for all monitored domains
1776
+ * @returns Summary data for all domains
1777
+ */
1778
+ public getReputationSummary(): any {
1779
+ return this.senderReputationMonitor.getReputationSummary();
1780
+ }
1781
+
1782
+ /**
1783
+ * Add a domain to the reputation monitoring system
1784
+ * @param domain Domain to add
1785
+ */
1786
+ public addDomainToMonitoring(domain: string): void {
1787
+ this.senderReputationMonitor.addDomain(domain);
1788
+ }
1789
+
1790
+ /**
1791
+ * Remove a domain from the reputation monitoring system
1792
+ * @param domain Domain to remove
1793
+ */
1794
+ public removeDomainFromMonitoring(domain: string): void {
1795
+ this.senderReputationMonitor.removeDomain(domain);
1796
+ }
1797
+
1798
+ /**
1799
+ * Record an email event for domain reputation tracking
1800
+ * @param domain Domain sending the email
1801
+ * @param event Event details
1802
+ */
1803
+ public recordReputationEvent(domain: string, event: {
1804
+ type: 'sent' | 'delivered' | 'bounce' | 'complaint' | 'open' | 'click';
1805
+ count?: number;
1806
+ hardBounce?: boolean;
1807
+ receivingDomain?: string;
1808
+ }): void {
1809
+ this.senderReputationMonitor.recordSendEvent(domain, event);
1810
+ }
1811
+
1812
+ /**
1813
+ * Check if DKIM key exists for a domain
1814
+ * @param domain Domain to check
1815
+ */
1816
+ public hasDkimKey(domain: string): boolean {
1817
+ return this.dkimKeys.has(domain);
1818
+ }
1819
+
1820
+ /**
1821
+ * Record successful email delivery
1822
+ * @param domain Sending domain
1823
+ */
1824
+ public recordDelivery(domain: string): void {
1825
+ this.recordReputationEvent(domain, {
1826
+ type: 'delivered',
1827
+ count: 1
1828
+ });
1829
+ }
1830
+
1831
+ /**
1832
+ * Record email bounce
1833
+ * @param domain Sending domain
1834
+ * @param receivingDomain Receiving domain that bounced
1835
+ * @param bounceType Type of bounce (hard/soft)
1836
+ * @param reason Bounce reason
1837
+ */
1838
+ public recordBounce(domain: string, receivingDomain: string, bounceType: 'hard' | 'soft', reason: string): void {
1839
+ // Record bounce in bounce manager
1840
+ const bounceRecord = {
1841
+ id: `bounce_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
1842
+ recipient: `user@${receivingDomain}`,
1843
+ sender: `user@${domain}`,
1844
+ domain: domain,
1845
+ bounceType: bounceType === 'hard' ? BounceType.INVALID_RECIPIENT : BounceType.TEMPORARY_FAILURE,
1846
+ bounceCategory: bounceType === 'hard' ? BounceCategory.HARD : BounceCategory.SOFT,
1847
+ timestamp: Date.now(),
1848
+ smtpResponse: reason,
1849
+ diagnosticCode: reason,
1850
+ statusCode: bounceType === 'hard' ? '550' : '450',
1851
+ processed: false
1852
+ };
1853
+
1854
+ // Process the bounce
1855
+ this.bounceManager.processBounce(bounceRecord);
1856
+
1857
+ // Record reputation event
1858
+ this.recordReputationEvent(domain, {
1859
+ type: 'bounce',
1860
+ count: 1,
1861
+ hardBounce: bounceType === 'hard',
1862
+ receivingDomain
1863
+ });
1864
+ }
1865
+
1866
+ /**
1867
+ * Get the rate limiter instance
1868
+ * @returns The unified rate limiter
1869
+ */
1870
+ public getRateLimiter(): UnifiedRateLimiter {
1871
+ return this.rateLimiter;
1872
+ }
1873
+ }