@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,1422 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { logger } from '../../logger.js';
3
+ import {
4
+ SecurityLogger,
5
+ SecurityLogLevel,
6
+ SecurityEventType
7
+ } from '../../security/index.js';
8
+
9
+ import {
10
+ MtaConnectionError,
11
+ MtaAuthenticationError,
12
+ MtaDeliveryError,
13
+ MtaConfigurationError,
14
+ MtaTimeoutError,
15
+ MtaProtocolError
16
+ } from '../../errors/index.js';
17
+
18
+ import { Email } from '../core/classes.email.js';
19
+ import type { EmailProcessingMode } from './interfaces.js';
20
+
21
+ // Custom error type extension
22
+ interface NodeNetworkError extends Error {
23
+ code?: string;
24
+ }
25
+
26
+ /**
27
+ * SMTP client connection options
28
+ */
29
+ export type ISmtpClientOptions = {
30
+ /**
31
+ * Hostname of the SMTP server
32
+ */
33
+ host: string;
34
+
35
+ /**
36
+ * Port to connect to
37
+ */
38
+ port: number;
39
+
40
+ /**
41
+ * Whether to use TLS for the connection
42
+ */
43
+ secure?: boolean;
44
+
45
+ /**
46
+ * Connection timeout in milliseconds
47
+ */
48
+ connectionTimeout?: number;
49
+
50
+ /**
51
+ * Socket timeout in milliseconds
52
+ */
53
+ socketTimeout?: number;
54
+
55
+ /**
56
+ * Command timeout in milliseconds
57
+ */
58
+ commandTimeout?: number;
59
+
60
+ /**
61
+ * TLS options
62
+ */
63
+ tls?: {
64
+ /**
65
+ * Whether to verify certificates
66
+ */
67
+ rejectUnauthorized?: boolean;
68
+
69
+ /**
70
+ * Minimum TLS version
71
+ */
72
+ minVersion?: string;
73
+
74
+ /**
75
+ * CA certificate path
76
+ */
77
+ ca?: string;
78
+ };
79
+
80
+ /**
81
+ * Authentication options
82
+ */
83
+ auth?: {
84
+ /**
85
+ * Authentication user
86
+ */
87
+ user: string;
88
+
89
+ /**
90
+ * Authentication password
91
+ */
92
+ pass: string;
93
+
94
+ /**
95
+ * Authentication method
96
+ */
97
+ method?: 'PLAIN' | 'LOGIN' | 'OAUTH2';
98
+ };
99
+
100
+ /**
101
+ * Domain name for EHLO
102
+ */
103
+ domain?: string;
104
+
105
+ /**
106
+ * DKIM options for signing outgoing emails
107
+ */
108
+ dkim?: {
109
+ /**
110
+ * Whether to sign emails with DKIM
111
+ */
112
+ enabled: boolean;
113
+
114
+ /**
115
+ * Domain name for DKIM
116
+ */
117
+ domain: string;
118
+
119
+ /**
120
+ * Selector for DKIM
121
+ */
122
+ selector: string;
123
+
124
+ /**
125
+ * Private key for DKIM signing
126
+ */
127
+ privateKey: string;
128
+
129
+ /**
130
+ * Headers to sign
131
+ */
132
+ headers?: string[];
133
+ };
134
+ };
135
+
136
+ /**
137
+ * SMTP delivery result
138
+ */
139
+ export type ISmtpDeliveryResult = {
140
+ /**
141
+ * Whether the delivery was successful
142
+ */
143
+ success: boolean;
144
+
145
+ /**
146
+ * Message ID if successful
147
+ */
148
+ messageId?: string;
149
+
150
+ /**
151
+ * Error message if failed
152
+ */
153
+ error?: string;
154
+
155
+ /**
156
+ * SMTP response code
157
+ */
158
+ responseCode?: string;
159
+
160
+ /**
161
+ * Recipients successfully delivered to
162
+ */
163
+ acceptedRecipients: string[];
164
+
165
+ /**
166
+ * Recipients rejected during delivery
167
+ */
168
+ rejectedRecipients: string[];
169
+
170
+ /**
171
+ * Server response
172
+ */
173
+ response?: string;
174
+
175
+ /**
176
+ * Timestamp of the delivery attempt
177
+ */
178
+ timestamp: number;
179
+
180
+ /**
181
+ * Whether DKIM signing was applied
182
+ */
183
+ dkimSigned?: boolean;
184
+
185
+ /**
186
+ * Whether this was a TLS secured delivery
187
+ */
188
+ secure?: boolean;
189
+
190
+ /**
191
+ * Whether authentication was used
192
+ */
193
+ authenticated?: boolean;
194
+ };
195
+
196
+ /**
197
+ * SMTP client for sending emails to remote mail servers
198
+ */
199
+ export class SmtpClient {
200
+ private options: ISmtpClientOptions;
201
+ private connected: boolean = false;
202
+ private socket?: plugins.net.Socket | plugins.tls.TLSSocket;
203
+ private supportedExtensions: Set<string> = new Set();
204
+
205
+ /**
206
+ * Create a new SMTP client instance
207
+ * @param options SMTP client connection options
208
+ */
209
+ constructor(options: ISmtpClientOptions) {
210
+ // Set default options
211
+ this.options = {
212
+ ...options,
213
+ connectionTimeout: options.connectionTimeout || 30000, // 30 seconds
214
+ socketTimeout: options.socketTimeout || 60000, // 60 seconds
215
+ commandTimeout: options.commandTimeout || 30000, // 30 seconds
216
+ secure: options.secure || false,
217
+ domain: options.domain || 'localhost',
218
+ tls: {
219
+ rejectUnauthorized: options.tls?.rejectUnauthorized !== false, // Default to true
220
+ minVersion: options.tls?.minVersion || 'TLSv1.2'
221
+ }
222
+ };
223
+ }
224
+
225
+ /**
226
+ * Connect to the SMTP server
227
+ */
228
+ public async connect(): Promise<void> {
229
+ if (this.connected && this.socket) {
230
+ return;
231
+ }
232
+
233
+ try {
234
+ logger.log('info', `Connecting to SMTP server ${this.options.host}:${this.options.port}`);
235
+
236
+ // Create socket
237
+ const socket = new plugins.net.Socket();
238
+
239
+ // Set timeouts
240
+ socket.setTimeout(this.options.socketTimeout);
241
+
242
+ // Connect to the server
243
+ await new Promise<void>((resolve, reject) => {
244
+ // Handle connection events
245
+ socket.once('connect', () => {
246
+ logger.log('debug', `Connected to ${this.options.host}:${this.options.port}`);
247
+ resolve();
248
+ });
249
+
250
+ socket.once('timeout', () => {
251
+ reject(MtaConnectionError.timeout(
252
+ this.options.host,
253
+ this.options.port,
254
+ this.options.connectionTimeout
255
+ ));
256
+ });
257
+
258
+ socket.once('error', (err: NodeNetworkError) => {
259
+ if (err.code === 'ECONNREFUSED') {
260
+ reject(MtaConnectionError.refused(
261
+ this.options.host,
262
+ this.options.port
263
+ ));
264
+ } else if (err.code === 'ENOTFOUND') {
265
+ reject(MtaConnectionError.dnsError(
266
+ this.options.host,
267
+ err
268
+ ));
269
+ } else {
270
+ reject(new MtaConnectionError(
271
+ `Connection error to ${this.options.host}:${this.options.port}: ${err.message}`,
272
+ {
273
+ data: {
274
+ host: this.options.host,
275
+ port: this.options.port,
276
+ error: err.message,
277
+ code: err.code
278
+ }
279
+ }
280
+ ));
281
+ }
282
+ });
283
+
284
+ // Connect to the server
285
+ const connectOptions = {
286
+ host: this.options.host,
287
+ port: this.options.port
288
+ };
289
+
290
+ // For direct TLS connections
291
+ if (this.options.secure) {
292
+ const tlsSocket = plugins.tls.connect({
293
+ ...connectOptions,
294
+ rejectUnauthorized: this.options.tls.rejectUnauthorized,
295
+ minVersion: this.options.tls.minVersion as any,
296
+ ca: this.options.tls.ca ? [this.options.tls.ca] : undefined
297
+ } as plugins.tls.ConnectionOptions);
298
+
299
+ tlsSocket.once('secureConnect', () => {
300
+ logger.log('debug', `Secure connection established to ${this.options.host}:${this.options.port}`);
301
+ this.socket = tlsSocket;
302
+ resolve();
303
+ });
304
+
305
+ tlsSocket.once('error', (err: NodeNetworkError) => {
306
+ reject(new MtaConnectionError(
307
+ `TLS connection error to ${this.options.host}:${this.options.port}: ${err.message}`,
308
+ {
309
+ data: {
310
+ host: this.options.host,
311
+ port: this.options.port,
312
+ error: err.message,
313
+ code: err.code
314
+ }
315
+ }
316
+ ));
317
+ });
318
+
319
+ tlsSocket.setTimeout(this.options.socketTimeout);
320
+
321
+ tlsSocket.once('timeout', () => {
322
+ reject(MtaConnectionError.timeout(
323
+ this.options.host,
324
+ this.options.port,
325
+ this.options.connectionTimeout
326
+ ));
327
+ });
328
+ } else {
329
+ socket.connect(connectOptions);
330
+ this.socket = socket;
331
+ }
332
+ });
333
+
334
+ // Wait for server greeting
335
+ const greeting = await this.readResponse();
336
+
337
+ if (!greeting.startsWith('220')) {
338
+ throw new MtaConnectionError(
339
+ `Unexpected greeting from server: ${greeting}`,
340
+ {
341
+ data: {
342
+ host: this.options.host,
343
+ port: this.options.port,
344
+ greeting
345
+ }
346
+ }
347
+ );
348
+ }
349
+
350
+ // Send EHLO
351
+ await this.sendEhlo();
352
+
353
+ // Start TLS if not secure and supported
354
+ if (!this.options.secure && this.supportedExtensions.has('STARTTLS')) {
355
+ await this.startTls();
356
+
357
+ // Send EHLO again after STARTTLS
358
+ await this.sendEhlo();
359
+ }
360
+
361
+ // Authenticate if credentials provided
362
+ if (this.options.auth) {
363
+ await this.authenticate();
364
+ }
365
+
366
+ this.connected = true;
367
+ logger.log('info', `Successfully connected to SMTP server ${this.options.host}:${this.options.port}`);
368
+
369
+ // Set up error handling for the socket
370
+ this.socket.on('error', (err) => {
371
+ logger.log('error', `Socket error: ${err.message}`);
372
+ this.connected = false;
373
+ this.socket = undefined;
374
+ });
375
+
376
+ this.socket.on('close', () => {
377
+ logger.log('debug', 'Socket closed');
378
+ this.connected = false;
379
+ this.socket = undefined;
380
+ });
381
+
382
+ this.socket.on('timeout', () => {
383
+ logger.log('error', 'Socket timeout');
384
+ this.connected = false;
385
+ if (this.socket) {
386
+ this.socket.destroy();
387
+ this.socket = undefined;
388
+ }
389
+ });
390
+
391
+ } catch (error) {
392
+ // Clean up socket if connection failed
393
+ if (this.socket) {
394
+ this.socket.destroy();
395
+ this.socket = undefined;
396
+ }
397
+
398
+ logger.log('error', `Failed to connect to SMTP server: ${error.message}`);
399
+ throw error;
400
+ }
401
+ }
402
+
403
+ /**
404
+ * Send EHLO command to the server
405
+ */
406
+ private async sendEhlo(): Promise<void> {
407
+ // Clear previous extensions
408
+ this.supportedExtensions.clear();
409
+
410
+ // Send EHLO - don't allow pipelining for this command
411
+ const response = await this.sendCommand(`EHLO ${this.options.domain}`, false);
412
+
413
+ // Parse supported extensions
414
+ const lines = response.split('\r\n');
415
+ for (let i = 1; i < lines.length; i++) {
416
+ const line = lines[i];
417
+ if (line.startsWith('250-') || line.startsWith('250 ')) {
418
+ const extension = line.substring(4).split(' ')[0];
419
+ this.supportedExtensions.add(extension);
420
+ }
421
+ }
422
+
423
+ // Check if server supports pipelining
424
+ this.supportsPipelining = this.supportedExtensions.has('PIPELINING');
425
+
426
+ logger.log('debug', `Server supports extensions: ${Array.from(this.supportedExtensions).join(', ')}`);
427
+ if (this.supportsPipelining) {
428
+ logger.log('info', 'Server supports PIPELINING - will use for improved performance');
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Start TLS negotiation
434
+ */
435
+ private async startTls(): Promise<void> {
436
+ logger.log('debug', 'Starting TLS negotiation');
437
+
438
+ // Send STARTTLS command
439
+ const response = await this.sendCommand('STARTTLS');
440
+
441
+ if (!response.startsWith('220')) {
442
+ throw new MtaConnectionError(
443
+ `Failed to start TLS: ${response}`,
444
+ {
445
+ data: {
446
+ host: this.options.host,
447
+ port: this.options.port,
448
+ response
449
+ }
450
+ }
451
+ );
452
+ }
453
+
454
+ if (!this.socket) {
455
+ throw new MtaConnectionError(
456
+ 'No socket available for TLS upgrade',
457
+ {
458
+ data: {
459
+ host: this.options.host,
460
+ port: this.options.port
461
+ }
462
+ }
463
+ );
464
+ }
465
+
466
+ // Upgrade socket to TLS
467
+ const currentSocket = this.socket;
468
+ this.socket = await this.upgradeTls(currentSocket);
469
+ }
470
+
471
+ /**
472
+ * Upgrade socket to TLS
473
+ * @param socket Original socket
474
+ */
475
+ private async upgradeTls(socket: plugins.net.Socket): Promise<plugins.tls.TLSSocket> {
476
+ return new Promise<plugins.tls.TLSSocket>((resolve, reject) => {
477
+ const tlsOptions: plugins.tls.ConnectionOptions = {
478
+ socket,
479
+ servername: this.options.host,
480
+ rejectUnauthorized: this.options.tls.rejectUnauthorized,
481
+ minVersion: this.options.tls.minVersion as any,
482
+ ca: this.options.tls.ca ? [this.options.tls.ca] : undefined
483
+ };
484
+
485
+ const tlsSocket = plugins.tls.connect(tlsOptions);
486
+
487
+ tlsSocket.once('secureConnect', () => {
488
+ logger.log('debug', 'TLS negotiation successful');
489
+ resolve(tlsSocket);
490
+ });
491
+
492
+ tlsSocket.once('error', (err: NodeNetworkError) => {
493
+ reject(new MtaConnectionError(
494
+ `TLS error: ${err.message}`,
495
+ {
496
+ data: {
497
+ host: this.options.host,
498
+ port: this.options.port,
499
+ error: err.message,
500
+ code: err.code
501
+ }
502
+ }
503
+ ));
504
+ });
505
+
506
+ tlsSocket.setTimeout(this.options.socketTimeout);
507
+
508
+ tlsSocket.once('timeout', () => {
509
+ reject(MtaTimeoutError.commandTimeout(
510
+ 'STARTTLS',
511
+ this.options.host,
512
+ this.options.socketTimeout
513
+ ));
514
+ });
515
+ });
516
+ }
517
+
518
+ /**
519
+ * Authenticate with the server
520
+ */
521
+ private async authenticate(): Promise<void> {
522
+ if (!this.options.auth) {
523
+ return;
524
+ }
525
+
526
+ const { user, pass, method = 'LOGIN' } = this.options.auth;
527
+
528
+ logger.log('debug', `Authenticating as ${user} using ${method}`);
529
+
530
+ try {
531
+ switch (method) {
532
+ case 'PLAIN':
533
+ await this.authPlain(user, pass);
534
+ break;
535
+
536
+ case 'LOGIN':
537
+ await this.authLogin(user, pass);
538
+ break;
539
+
540
+ case 'OAUTH2':
541
+ await this.authOAuth2(user, pass);
542
+ break;
543
+
544
+ default:
545
+ throw new MtaAuthenticationError(
546
+ `Authentication method ${method} not supported by client`,
547
+ {
548
+ data: {
549
+ method
550
+ }
551
+ }
552
+ );
553
+ }
554
+
555
+ logger.log('info', `Successfully authenticated as ${user}`);
556
+ } catch (error) {
557
+ logger.log('error', `Authentication failed: ${error.message}`);
558
+ throw error;
559
+ }
560
+ }
561
+
562
+ /**
563
+ * Authenticate using PLAIN method
564
+ * @param user Username
565
+ * @param pass Password
566
+ */
567
+ private async authPlain(user: string, pass: string): Promise<void> {
568
+ // PLAIN authentication format: \0username\0password
569
+ const authString = Buffer.from(`\0${user}\0${pass}`).toString('base64');
570
+ const response = await this.sendCommand(`AUTH PLAIN ${authString}`);
571
+
572
+ if (!response.startsWith('235')) {
573
+ throw MtaAuthenticationError.invalidCredentials(
574
+ this.options.host,
575
+ user
576
+ );
577
+ }
578
+ }
579
+
580
+ /**
581
+ * Authenticate using LOGIN method
582
+ * @param user Username
583
+ * @param pass Password
584
+ */
585
+ private async authLogin(user: string, pass: string): Promise<void> {
586
+ // Start LOGIN authentication
587
+ const response = await this.sendCommand('AUTH LOGIN');
588
+
589
+ if (!response.startsWith('334')) {
590
+ throw new MtaAuthenticationError(
591
+ `Server did not accept AUTH LOGIN: ${response}`,
592
+ {
593
+ data: {
594
+ host: this.options.host,
595
+ response
596
+ }
597
+ }
598
+ );
599
+ }
600
+
601
+ // Send username (base64)
602
+ const userResponse = await this.sendCommand(Buffer.from(user).toString('base64'));
603
+
604
+ if (!userResponse.startsWith('334')) {
605
+ throw MtaAuthenticationError.invalidCredentials(
606
+ this.options.host,
607
+ user
608
+ );
609
+ }
610
+
611
+ // Send password (base64)
612
+ const passResponse = await this.sendCommand(Buffer.from(pass).toString('base64'));
613
+
614
+ if (!passResponse.startsWith('235')) {
615
+ throw MtaAuthenticationError.invalidCredentials(
616
+ this.options.host,
617
+ user
618
+ );
619
+ }
620
+ }
621
+
622
+ /**
623
+ * Authenticate using OAuth2 method
624
+ * @param user Username
625
+ * @param token OAuth2 token
626
+ */
627
+ private async authOAuth2(user: string, token: string): Promise<void> {
628
+ // XOAUTH2 format
629
+ const authString = `user=${user}\x01auth=Bearer ${token}\x01\x01`;
630
+ const response = await this.sendCommand(`AUTH XOAUTH2 ${Buffer.from(authString).toString('base64')}`);
631
+
632
+ if (!response.startsWith('235')) {
633
+ throw MtaAuthenticationError.invalidCredentials(
634
+ this.options.host,
635
+ user
636
+ );
637
+ }
638
+ }
639
+
640
+ /**
641
+ * Send an email through the SMTP client
642
+ * @param email Email to send
643
+ * @param processingMode Optional processing mode
644
+ */
645
+ public async sendMail(email: Email, processingMode?: EmailProcessingMode): Promise<ISmtpDeliveryResult> {
646
+ // Ensure we're connected
647
+ if (!this.connected || !this.socket) {
648
+ await this.connect();
649
+ }
650
+
651
+ const startTime = Date.now();
652
+ const result: ISmtpDeliveryResult = {
653
+ success: false,
654
+ acceptedRecipients: [],
655
+ rejectedRecipients: [],
656
+ timestamp: startTime,
657
+ secure: this.options.secure || this.socket instanceof plugins.tls.TLSSocket,
658
+ authenticated: !!this.options.auth
659
+ };
660
+
661
+ try {
662
+ logger.log('info', `Sending email to ${email.getAllRecipients().join(', ')}`);
663
+
664
+ // Apply DKIM signing if configured
665
+ if (this.options.dkim?.enabled) {
666
+ await this.applyDkimSignature(email);
667
+ result.dkimSigned = true;
668
+ }
669
+
670
+ // Get envelope and recipients
671
+ const envelope_from = email.getEnvelopeFrom() || email.from;
672
+ const recipients = email.getAllRecipients();
673
+
674
+ // Check if we can use pipelining for MAIL FROM and RCPT TO commands
675
+ if (this.supportsPipelining && recipients.length > 0) {
676
+ logger.log('debug', 'Using SMTP pipelining for sending');
677
+
678
+ // Send MAIL FROM command first (always needed)
679
+ const mailFromCmd = `MAIL FROM:<${envelope_from}> SIZE=${this.getEmailSize(email)}`;
680
+ let mailFromResponse: string;
681
+
682
+ try {
683
+ mailFromResponse = await this.sendCommand(mailFromCmd);
684
+
685
+ if (!mailFromResponse.startsWith('250')) {
686
+ throw new MtaDeliveryError(
687
+ `MAIL FROM command failed: ${mailFromResponse}`,
688
+ {
689
+ data: {
690
+ command: mailFromCmd,
691
+ response: mailFromResponse
692
+ }
693
+ }
694
+ );
695
+ }
696
+ } catch (error) {
697
+ logger.log('error', `MAIL FROM failed: ${error.message}`);
698
+ throw error;
699
+ }
700
+
701
+ // Pipeline all RCPT TO commands
702
+ const rcptPromises = recipients.map(recipient => {
703
+ return this.sendCommand(`RCPT TO:<${recipient}>`)
704
+ .then(response => {
705
+ if (response.startsWith('250')) {
706
+ result.acceptedRecipients.push(recipient);
707
+ return { recipient, accepted: true, response };
708
+ } else {
709
+ result.rejectedRecipients.push(recipient);
710
+ logger.log('warn', `Recipient ${recipient} rejected: ${response}`);
711
+ return { recipient, accepted: false, response };
712
+ }
713
+ })
714
+ .catch(error => {
715
+ result.rejectedRecipients.push(recipient);
716
+ logger.log('warn', `Recipient ${recipient} rejected with error: ${error.message}`);
717
+ return { recipient, accepted: false, error: error.message };
718
+ });
719
+ });
720
+
721
+ // Wait for all RCPT TO commands to complete
722
+ await Promise.all(rcptPromises);
723
+ } else {
724
+ // Fall back to sequential commands if pipelining not supported
725
+ logger.log('debug', 'Using sequential SMTP commands for sending');
726
+
727
+ // Send MAIL FROM
728
+ await this.sendCommand(`MAIL FROM:<${envelope_from}> SIZE=${this.getEmailSize(email)}`);
729
+
730
+ // Send RCPT TO for each recipient
731
+ for (const recipient of recipients) {
732
+ try {
733
+ await this.sendCommand(`RCPT TO:<${recipient}>`);
734
+ result.acceptedRecipients.push(recipient);
735
+ } catch (error) {
736
+ logger.log('warn', `Recipient ${recipient} rejected: ${error.message}`);
737
+ result.rejectedRecipients.push(recipient);
738
+ }
739
+ }
740
+ }
741
+
742
+ // Check if at least one recipient was accepted
743
+ if (result.acceptedRecipients.length === 0) {
744
+ throw new MtaDeliveryError(
745
+ 'All recipients were rejected',
746
+ {
747
+ data: {
748
+ recipients,
749
+ rejectedRecipients: result.rejectedRecipients
750
+ }
751
+ }
752
+ );
753
+ }
754
+
755
+ // Send DATA
756
+ const dataResponse = await this.sendCommand('DATA');
757
+
758
+ if (!dataResponse.startsWith('354')) {
759
+ throw new MtaProtocolError(
760
+ `Failed to start DATA phase: ${dataResponse}`,
761
+ {
762
+ data: {
763
+ response: dataResponse
764
+ }
765
+ }
766
+ );
767
+ }
768
+
769
+ // Format email content efficiently
770
+ const emailContent = await this.getFormattedEmail(email);
771
+
772
+ // Send email content
773
+ const finalResponse = await this.sendCommand(emailContent + '\r\n.');
774
+
775
+ // Extract message ID if available
776
+ const messageIdMatch = finalResponse.match(/\[(.*?)\]/);
777
+ if (messageIdMatch) {
778
+ result.messageId = messageIdMatch[1];
779
+ }
780
+
781
+ result.success = true;
782
+ result.response = finalResponse;
783
+
784
+ logger.log('info', `Email sent successfully to ${result.acceptedRecipients.join(', ')}`);
785
+
786
+ // Log security event
787
+ SecurityLogger.getInstance().logEvent({
788
+ level: SecurityLogLevel.INFO,
789
+ type: SecurityEventType.EMAIL_DELIVERY,
790
+ message: 'Email sent successfully',
791
+ details: {
792
+ recipients: result.acceptedRecipients,
793
+ rejectedRecipients: result.rejectedRecipients,
794
+ messageId: result.messageId,
795
+ secure: result.secure,
796
+ authenticated: result.authenticated,
797
+ server: `${this.options.host}:${this.options.port}`,
798
+ dkimSigned: result.dkimSigned
799
+ },
800
+ success: true
801
+ });
802
+
803
+ return result;
804
+ } catch (error) {
805
+ logger.log('error', `Failed to send email: ${error.message}`);
806
+
807
+ // Format error for result
808
+ result.error = error.message;
809
+
810
+ // Extract SMTP code if available
811
+ if (error.context?.data?.statusCode) {
812
+ result.responseCode = error.context.data.statusCode;
813
+ }
814
+
815
+ // Log security event
816
+ SecurityLogger.getInstance().logEvent({
817
+ level: SecurityLogLevel.ERROR,
818
+ type: SecurityEventType.EMAIL_DELIVERY,
819
+ message: 'Email delivery failed',
820
+ details: {
821
+ error: error.message,
822
+ server: `${this.options.host}:${this.options.port}`,
823
+ recipients: email.getAllRecipients(),
824
+ acceptedRecipients: result.acceptedRecipients,
825
+ rejectedRecipients: result.rejectedRecipients,
826
+ secure: result.secure,
827
+ authenticated: result.authenticated
828
+ },
829
+ success: false
830
+ });
831
+
832
+ return result;
833
+ }
834
+ }
835
+
836
+ /**
837
+ * Apply DKIM signature to email
838
+ * @param email Email to sign
839
+ */
840
+ private async applyDkimSignature(email: Email): Promise<void> {
841
+ if (!this.options.dkim?.enabled || !this.options.dkim?.privateKey) {
842
+ return;
843
+ }
844
+
845
+ try {
846
+ logger.log('debug', `Signing email with DKIM for domain ${this.options.dkim.domain}`);
847
+
848
+ // Format email for DKIM signing
849
+ const { dkimSign } = plugins;
850
+ const emailContent = await this.getFormattedEmail(email);
851
+
852
+ // Sign email
853
+ const signOptions = {
854
+ domainName: this.options.dkim.domain,
855
+ keySelector: this.options.dkim.selector,
856
+ privateKey: this.options.dkim.privateKey,
857
+ headerFieldNames: this.options.dkim.headers || [
858
+ 'from', 'to', 'subject', 'date', 'message-id'
859
+ ]
860
+ };
861
+
862
+ const signedEmail = await dkimSign(emailContent, signOptions);
863
+
864
+ // Replace headers in original email
865
+ const dkimHeader = signedEmail.substring(0, signedEmail.indexOf('\r\n\r\n')).split('\r\n')
866
+ .find(line => line.startsWith('DKIM-Signature: '));
867
+
868
+ if (dkimHeader) {
869
+ email.addHeader('DKIM-Signature', dkimHeader.substring('DKIM-Signature: '.length));
870
+ }
871
+
872
+ logger.log('debug', 'DKIM signature applied successfully');
873
+ } catch (error) {
874
+ logger.log('error', `Failed to apply DKIM signature: ${error.message}`);
875
+ throw error;
876
+ }
877
+ }
878
+
879
+ /**
880
+ * Format email for SMTP transmission
881
+ * @param email Email to format
882
+ */
883
+ private async getFormattedEmail(email: Email): Promise<string> {
884
+ // This is a simplified implementation
885
+ // In a full implementation, this would use proper MIME formatting
886
+
887
+ let content = '';
888
+
889
+ // Add headers
890
+ content += `From: ${email.from}\r\n`;
891
+ content += `To: ${email.to.join(', ')}\r\n`;
892
+ content += `Subject: ${email.subject}\r\n`;
893
+ content += `Date: ${new Date().toUTCString()}\r\n`;
894
+ content += `Message-ID: <${plugins.uuid.v4()}@${this.options.domain}>\r\n`;
895
+
896
+ // Add additional headers
897
+ for (const [name, value] of Object.entries(email.headers || {})) {
898
+ content += `${name}: ${value}\r\n`;
899
+ }
900
+
901
+ // Add content type for multipart
902
+ if (email.attachments && email.attachments.length > 0) {
903
+ const boundary = `----_=_NextPart_${Math.random().toString(36).substr(2)}`;
904
+ content += `MIME-Version: 1.0\r\n`;
905
+ content += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n`;
906
+ content += `\r\n`;
907
+
908
+ // Add text part
909
+ content += `--${boundary}\r\n`;
910
+ content += `Content-Type: text/plain; charset="UTF-8"\r\n`;
911
+ content += `\r\n`;
912
+ content += `${email.text}\r\n`;
913
+
914
+ // Add HTML part if present
915
+ if (email.html) {
916
+ content += `--${boundary}\r\n`;
917
+ content += `Content-Type: text/html; charset="UTF-8"\r\n`;
918
+ content += `\r\n`;
919
+ content += `${email.html}\r\n`;
920
+ }
921
+
922
+ // Add attachments
923
+ for (const attachment of email.attachments) {
924
+ content += `--${boundary}\r\n`;
925
+ content += `Content-Type: ${attachment.contentType || 'application/octet-stream'}; name="${attachment.filename}"\r\n`;
926
+ content += `Content-Disposition: attachment; filename="${attachment.filename}"\r\n`;
927
+ content += `Content-Transfer-Encoding: base64\r\n`;
928
+ content += `\r\n`;
929
+
930
+ // Add base64 encoded content
931
+ const base64Content = attachment.content.toString('base64');
932
+
933
+ // Split into lines of 76 characters
934
+ for (let i = 0; i < base64Content.length; i += 76) {
935
+ content += base64Content.substring(i, i + 76) + '\r\n';
936
+ }
937
+ }
938
+
939
+ // End boundary
940
+ content += `--${boundary}--\r\n`;
941
+ } else {
942
+ // Simple email with just text
943
+ content += `Content-Type: text/plain; charset="UTF-8"\r\n`;
944
+ content += `\r\n`;
945
+ content += `${email.text}\r\n`;
946
+ }
947
+
948
+ return content;
949
+ }
950
+
951
+ /**
952
+ * Get size of email in bytes
953
+ * @param email Email to measure
954
+ */
955
+ private getEmailSize(email: Email): number {
956
+ // Simplified size estimation
957
+ let size = 0;
958
+
959
+ // Headers
960
+ size += `From: ${email.from}\r\n`.length;
961
+ size += `To: ${email.to.join(', ')}\r\n`.length;
962
+ size += `Subject: ${email.subject}\r\n`.length;
963
+
964
+ // Body
965
+ size += (email.text?.length || 0) + 2; // +2 for CRLF
966
+
967
+ // HTML part if present
968
+ if (email.html) {
969
+ size += email.html.length + 2;
970
+ }
971
+
972
+ // Attachments
973
+ for (const attachment of email.attachments || []) {
974
+ size += attachment.content.length;
975
+ }
976
+
977
+ // Add overhead for MIME boundaries and headers
978
+ const overhead = email.attachments?.length ? 1000 + (email.attachments.length * 200) : 200;
979
+
980
+ return size + overhead;
981
+ }
982
+
983
+ /**
984
+ * Send SMTP command and wait for response
985
+ * @param command SMTP command to send
986
+ */
987
+ // Queue for command pipelining
988
+ private commandQueue: Array<{
989
+ command: string;
990
+ resolve: (response: string) => void;
991
+ reject: (error: any) => void;
992
+ timeout: NodeJS.Timeout;
993
+ }> = [];
994
+
995
+ // Flag to indicate if we're currently processing commands
996
+ private processingCommands = false;
997
+
998
+ // Flag to indicate if server supports pipelining
999
+ private supportsPipelining = false;
1000
+
1001
+ /**
1002
+ * Send an SMTP command and wait for response
1003
+ * @param command SMTP command to send
1004
+ * @param allowPipelining Whether this command can be pipelined
1005
+ */
1006
+ private async sendCommand(command: string, allowPipelining = true): Promise<string> {
1007
+ if (!this.socket) {
1008
+ throw new MtaConnectionError(
1009
+ 'Not connected to server',
1010
+ {
1011
+ data: {
1012
+ host: this.options.host,
1013
+ port: this.options.port
1014
+ }
1015
+ }
1016
+ );
1017
+ }
1018
+
1019
+ // Log command if not sensitive
1020
+ if (!command.startsWith('AUTH')) {
1021
+ logger.log('debug', `> ${command}`);
1022
+ } else {
1023
+ logger.log('debug', '> AUTH ***');
1024
+ }
1025
+
1026
+ return new Promise<string>((resolve, reject) => {
1027
+ // Set up timeout for command
1028
+ const timeout = setTimeout(() => {
1029
+ // Remove this command from the queue if it times out
1030
+ const index = this.commandQueue.findIndex(item => item.command === command);
1031
+ if (index !== -1) {
1032
+ this.commandQueue.splice(index, 1);
1033
+ }
1034
+
1035
+ reject(MtaTimeoutError.commandTimeout(
1036
+ command.split(' ')[0],
1037
+ this.options.host,
1038
+ this.options.commandTimeout
1039
+ ));
1040
+ }, this.options.commandTimeout);
1041
+
1042
+ // Add command to the queue
1043
+ this.commandQueue.push({
1044
+ command,
1045
+ resolve,
1046
+ reject,
1047
+ timeout
1048
+ });
1049
+
1050
+ // Process command queue if we can pipeline or if not currently processing commands
1051
+ if ((this.supportsPipelining && allowPipelining) || !this.processingCommands) {
1052
+ this.processCommandQueue();
1053
+ }
1054
+ });
1055
+ }
1056
+
1057
+ /**
1058
+ * Process the command queue - either one by one or pipelined if supported
1059
+ */
1060
+ private processCommandQueue(): void {
1061
+ if (this.processingCommands || this.commandQueue.length === 0 || !this.socket) {
1062
+ return;
1063
+ }
1064
+
1065
+ this.processingCommands = true;
1066
+
1067
+ try {
1068
+ // If pipelining is supported, send all commands at once
1069
+ if (this.supportsPipelining) {
1070
+ // Send all commands in queue at once
1071
+ const commands = this.commandQueue.map(item => item.command).join('\r\n') + '\r\n';
1072
+
1073
+ this.socket.write(commands, (err) => {
1074
+ if (err) {
1075
+ // Handle write error for all commands
1076
+ const error = new MtaConnectionError(
1077
+ `Failed to send commands: ${err.message}`,
1078
+ {
1079
+ data: {
1080
+ error: err.message
1081
+ }
1082
+ }
1083
+ );
1084
+
1085
+ // Fail all pending commands
1086
+ while (this.commandQueue.length > 0) {
1087
+ const item = this.commandQueue.shift();
1088
+ clearTimeout(item.timeout);
1089
+ item.reject(error);
1090
+ }
1091
+
1092
+ this.processingCommands = false;
1093
+ }
1094
+ });
1095
+
1096
+ // Process responses one by one in order
1097
+ this.processResponses();
1098
+ } else {
1099
+ // Process commands one by one if pipelining not supported
1100
+ this.processNextCommand();
1101
+ }
1102
+ } catch (error) {
1103
+ logger.log('error', `Error processing command queue: ${error.message}`);
1104
+ this.processingCommands = false;
1105
+ }
1106
+ }
1107
+
1108
+ /**
1109
+ * Process the next command in the queue (non-pipelined mode)
1110
+ */
1111
+ private processNextCommand(): void {
1112
+ if (this.commandQueue.length === 0 || !this.socket) {
1113
+ this.processingCommands = false;
1114
+ return;
1115
+ }
1116
+
1117
+ const currentCommand = this.commandQueue[0];
1118
+
1119
+ this.socket.write(currentCommand.command + '\r\n', (err) => {
1120
+ if (err) {
1121
+ // Handle write error
1122
+ const error = new MtaConnectionError(
1123
+ `Failed to send command: ${err.message}`,
1124
+ {
1125
+ data: {
1126
+ command: currentCommand.command.split(' ')[0],
1127
+ error: err.message
1128
+ }
1129
+ }
1130
+ );
1131
+
1132
+ // Remove from queue
1133
+ this.commandQueue.shift();
1134
+ clearTimeout(currentCommand.timeout);
1135
+ currentCommand.reject(error);
1136
+
1137
+ // Continue with next command
1138
+ this.processNextCommand();
1139
+ return;
1140
+ }
1141
+
1142
+ // Read response
1143
+ this.readResponse()
1144
+ .then((response) => {
1145
+ // Remove from queue and resolve
1146
+ this.commandQueue.shift();
1147
+ clearTimeout(currentCommand.timeout);
1148
+ currentCommand.resolve(response);
1149
+
1150
+ // Process next command
1151
+ this.processNextCommand();
1152
+ })
1153
+ .catch((err) => {
1154
+ // Remove from queue and reject
1155
+ this.commandQueue.shift();
1156
+ clearTimeout(currentCommand.timeout);
1157
+ currentCommand.reject(err);
1158
+
1159
+ // Process next command
1160
+ this.processNextCommand();
1161
+ });
1162
+ });
1163
+ }
1164
+
1165
+ /**
1166
+ * Process responses for pipelined commands
1167
+ */
1168
+ private async processResponses(): Promise<void> {
1169
+ try {
1170
+ // Process responses for each command in order
1171
+ while (this.commandQueue.length > 0) {
1172
+ const currentCommand = this.commandQueue[0];
1173
+
1174
+ try {
1175
+ // Wait for response
1176
+ const response = await this.readResponse();
1177
+
1178
+ // Remove from queue and resolve
1179
+ this.commandQueue.shift();
1180
+ clearTimeout(currentCommand.timeout);
1181
+ currentCommand.resolve(response);
1182
+ } catch (error) {
1183
+ // Remove from queue and reject
1184
+ this.commandQueue.shift();
1185
+ clearTimeout(currentCommand.timeout);
1186
+ currentCommand.reject(error);
1187
+
1188
+ // Stop processing if this is a critical error
1189
+ if (
1190
+ error instanceof MtaConnectionError &&
1191
+ (error.message.includes('Connection closed') || error.message.includes('Not connected'))
1192
+ ) {
1193
+ break;
1194
+ }
1195
+ }
1196
+ }
1197
+ } catch (error) {
1198
+ logger.log('error', `Error processing responses: ${error.message}`);
1199
+ } finally {
1200
+ this.processingCommands = false;
1201
+ }
1202
+ }
1203
+
1204
+ /**
1205
+ * Read response from the server
1206
+ */
1207
+ private async readResponse(): Promise<string> {
1208
+ if (!this.socket) {
1209
+ throw new MtaConnectionError(
1210
+ 'Not connected to server',
1211
+ {
1212
+ data: {
1213
+ host: this.options.host,
1214
+ port: this.options.port
1215
+ }
1216
+ }
1217
+ );
1218
+ }
1219
+
1220
+ return new Promise<string>((resolve, reject) => {
1221
+ // Use an array to collect response chunks instead of string concatenation
1222
+ const responseChunks: Buffer[] = [];
1223
+
1224
+ // Single function to clean up all listeners
1225
+ const cleanupListeners = () => {
1226
+ if (!this.socket) return;
1227
+ this.socket.removeListener('data', onData);
1228
+ this.socket.removeListener('error', onError);
1229
+ this.socket.removeListener('close', onClose);
1230
+ this.socket.removeListener('end', onEnd);
1231
+ };
1232
+
1233
+ const onData = (data: Buffer) => {
1234
+ // Store buffer directly, avoiding unnecessary string conversion
1235
+ responseChunks.push(data);
1236
+
1237
+ // Convert to string only for response checking
1238
+ const responseData = Buffer.concat(responseChunks).toString();
1239
+
1240
+ // Check if this is a complete response
1241
+ if (this.isCompleteResponse(responseData)) {
1242
+ // Clean up listeners
1243
+ cleanupListeners();
1244
+
1245
+ const trimmedResponse = responseData.trim();
1246
+ logger.log('debug', `< ${trimmedResponse}`);
1247
+
1248
+ // Check if this is an error response
1249
+ if (this.isErrorResponse(responseData)) {
1250
+ const code = responseData.substring(0, 3);
1251
+ reject(this.createErrorFromResponse(trimmedResponse, code));
1252
+ } else {
1253
+ resolve(trimmedResponse);
1254
+ }
1255
+ }
1256
+ };
1257
+
1258
+ const onError = (err: Error) => {
1259
+ cleanupListeners();
1260
+
1261
+ reject(new MtaConnectionError(
1262
+ `Socket error while waiting for response: ${err.message}`,
1263
+ {
1264
+ data: {
1265
+ error: err.message
1266
+ }
1267
+ }
1268
+ ));
1269
+ };
1270
+
1271
+ const onClose = () => {
1272
+ cleanupListeners();
1273
+
1274
+ const responseData = Buffer.concat(responseChunks).toString();
1275
+ reject(new MtaConnectionError(
1276
+ 'Connection closed while waiting for response',
1277
+ {
1278
+ data: {
1279
+ partialResponse: responseData
1280
+ }
1281
+ }
1282
+ ));
1283
+ };
1284
+
1285
+ const onEnd = () => {
1286
+ cleanupListeners();
1287
+
1288
+ const responseData = Buffer.concat(responseChunks).toString();
1289
+ reject(new MtaConnectionError(
1290
+ 'Connection ended while waiting for response',
1291
+ {
1292
+ data: {
1293
+ partialResponse: responseData
1294
+ }
1295
+ }
1296
+ ));
1297
+ };
1298
+
1299
+ // Set up listeners
1300
+ this.socket.on('data', onData);
1301
+ this.socket.once('error', onError);
1302
+ this.socket.once('close', onClose);
1303
+ this.socket.once('end', onEnd);
1304
+ });
1305
+ }
1306
+
1307
+ /**
1308
+ * Check if the response is complete
1309
+ * @param response Response to check
1310
+ */
1311
+ private isCompleteResponse(response: string): boolean {
1312
+ // Check if it's a multi-line response
1313
+ const lines = response.split('\r\n');
1314
+ const lastLine = lines[lines.length - 2]; // Second to last because of the trailing CRLF
1315
+
1316
+ // Check if the last line starts with a code followed by a space
1317
+ // If it does, this is a complete response
1318
+ if (lastLine && /^\d{3} /.test(lastLine)) {
1319
+ return true;
1320
+ }
1321
+
1322
+ // For single line responses
1323
+ if (lines.length === 2 && lines[0].length >= 3 && /^\d{3} /.test(lines[0])) {
1324
+ return true;
1325
+ }
1326
+
1327
+ return false;
1328
+ }
1329
+
1330
+ /**
1331
+ * Check if the response is an error
1332
+ * @param response Response to check
1333
+ */
1334
+ private isErrorResponse(response: string): boolean {
1335
+ // Get the status code (first 3 characters)
1336
+ const code = response.substring(0, 3);
1337
+
1338
+ // 4xx and 5xx are error codes
1339
+ return code.startsWith('4') || code.startsWith('5');
1340
+ }
1341
+
1342
+ /**
1343
+ * Create appropriate error from response
1344
+ * @param response Error response
1345
+ * @param code SMTP status code
1346
+ */
1347
+ private createErrorFromResponse(response: string, code: string): Error {
1348
+ // Extract message part
1349
+ const message = response.substring(4).trim();
1350
+
1351
+ switch (code.charAt(0)) {
1352
+ case '4': // Temporary errors
1353
+ return MtaDeliveryError.temporary(
1354
+ message,
1355
+ 'recipient',
1356
+ code,
1357
+ response
1358
+ );
1359
+
1360
+ case '5': // Permanent errors
1361
+ return MtaDeliveryError.permanent(
1362
+ message,
1363
+ 'recipient',
1364
+ code,
1365
+ response
1366
+ );
1367
+
1368
+ default:
1369
+ return new MtaDeliveryError(
1370
+ `Unexpected error response: ${response}`,
1371
+ {
1372
+ data: {
1373
+ response,
1374
+ code
1375
+ }
1376
+ }
1377
+ );
1378
+ }
1379
+ }
1380
+
1381
+ /**
1382
+ * Close the connection to the server
1383
+ */
1384
+ public async close(): Promise<void> {
1385
+ if (!this.connected || !this.socket) {
1386
+ return;
1387
+ }
1388
+
1389
+ try {
1390
+ // Send QUIT
1391
+ await this.sendCommand('QUIT');
1392
+ } catch (error) {
1393
+ logger.log('warn', `Error sending QUIT command: ${error.message}`);
1394
+ } finally {
1395
+ // Close socket
1396
+ this.socket.destroy();
1397
+ this.socket = undefined;
1398
+ this.connected = false;
1399
+ logger.log('info', 'SMTP connection closed');
1400
+ }
1401
+ }
1402
+
1403
+ /**
1404
+ * Checks if the connection is active
1405
+ */
1406
+ public isConnected(): boolean {
1407
+ return this.connected && !!this.socket;
1408
+ }
1409
+
1410
+ /**
1411
+ * Update SMTP client options
1412
+ * @param options New options
1413
+ */
1414
+ public updateOptions(options: Partial<ISmtpClientOptions>): void {
1415
+ this.options = {
1416
+ ...this.options,
1417
+ ...options
1418
+ };
1419
+
1420
+ logger.log('info', 'SMTP client options updated');
1421
+ }
1422
+ }