@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.
- package/.dockerignore +1 -0
- package/.gitea/workflows/docker_nottags.yaml +71 -0
- package/.gitea/workflows/docker_tags.yaml +106 -0
- package/.vscode/launch.json +11 -0
- package/.vscode/settings.json +26 -0
- package/Dockerfile +46 -0
- package/changelog.md +247 -0
- package/cli.child.js +4 -0
- package/cli.child.ts +4 -0
- package/cli.js +4 -0
- package/cli.ts.js +5 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.dcrouter.d.ts +238 -0
- package/dist_ts/classes.dcrouter.js +1008 -0
- package/dist_ts/config/index.d.ts +1 -0
- package/dist_ts/config/index.js +3 -0
- package/dist_ts/config/validator.d.ts +104 -0
- package/dist_ts/config/validator.js +152 -0
- package/dist_ts/deliverability/classes.ipwarmupmanager.d.ts +253 -0
- package/dist_ts/deliverability/classes.ipwarmupmanager.js +639 -0
- package/dist_ts/deliverability/classes.senderreputationmonitor.d.ts +300 -0
- package/dist_ts/deliverability/classes.senderreputationmonitor.js +961 -0
- package/dist_ts/deliverability/index.d.ts +2 -0
- package/dist_ts/deliverability/index.js +3 -0
- package/dist_ts/errors/base.errors.d.ts +224 -0
- package/dist_ts/errors/base.errors.js +310 -0
- package/dist_ts/errors/email.errors.d.ts +175 -0
- package/dist_ts/errors/email.errors.js +265 -0
- package/dist_ts/errors/error-handler.d.ts +98 -0
- package/dist_ts/errors/error-handler.js +282 -0
- package/dist_ts/errors/error.codes.d.ts +115 -0
- package/dist_ts/errors/error.codes.js +136 -0
- package/dist_ts/errors/index.d.ts +56 -0
- package/dist_ts/errors/index.js +138 -0
- package/dist_ts/errors/mta.errors.d.ts +259 -0
- package/dist_ts/errors/mta.errors.js +472 -0
- package/dist_ts/errors/reputation.errors.d.ts +183 -0
- package/dist_ts/errors/reputation.errors.js +292 -0
- package/dist_ts/index.d.ts +4 -0
- package/dist_ts/index.js +6 -0
- package/dist_ts/logger.d.ts +17 -0
- package/dist_ts/logger.js +77 -0
- package/dist_ts/mail/core/classes.bouncemanager.d.ts +200 -0
- package/dist_ts/mail/core/classes.bouncemanager.js +778 -0
- package/dist_ts/mail/core/classes.email.d.ts +291 -0
- package/dist_ts/mail/core/classes.email.js +780 -0
- package/dist_ts/mail/core/classes.emailvalidator.d.ts +61 -0
- package/dist_ts/mail/core/classes.emailvalidator.js +182 -0
- package/dist_ts/mail/core/classes.templatemanager.d.ts +95 -0
- package/dist_ts/mail/core/classes.templatemanager.js +239 -0
- package/dist_ts/mail/core/index.d.ts +4 -0
- package/dist_ts/mail/core/index.js +6 -0
- package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
- package/dist_ts/mail/delivery/classes.delivery.queue.js +485 -0
- package/dist_ts/mail/delivery/classes.delivery.system.d.ts +186 -0
- package/dist_ts/mail/delivery/classes.delivery.system.js +846 -0
- package/dist_ts/mail/delivery/classes.emailsendjob.d.ts +84 -0
- package/dist_ts/mail/delivery/classes.emailsendjob.js +362 -0
- package/dist_ts/mail/delivery/classes.emailsignjob.d.ts +18 -0
- package/dist_ts/mail/delivery/classes.emailsignjob.js +44 -0
- package/dist_ts/mail/delivery/classes.mta.config.d.ts +22 -0
- package/dist_ts/mail/delivery/classes.mta.config.js +51 -0
- package/dist_ts/mail/delivery/classes.ratelimiter.d.ts +98 -0
- package/dist_ts/mail/delivery/classes.ratelimiter.js +205 -0
- package/dist_ts/mail/delivery/classes.smtp.client.legacy.d.ts +275 -0
- package/dist_ts/mail/delivery/classes.smtp.client.legacy.js +973 -0
- package/dist_ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
- package/dist_ts/mail/delivery/classes.unified.rate.limiter.js +817 -0
- package/dist_ts/mail/delivery/index.d.ts +12 -0
- package/dist_ts/mail/delivery/index.js +18 -0
- package/dist_ts/mail/delivery/interfaces.d.ts +243 -0
- package/dist_ts/mail/delivery/interfaces.js +17 -0
- package/dist_ts/mail/delivery/smtpclient/auth-handler.d.ts +43 -0
- package/dist_ts/mail/delivery/smtpclient/auth-handler.js +188 -0
- package/dist_ts/mail/delivery/smtpclient/command-handler.d.ts +67 -0
- package/dist_ts/mail/delivery/smtpclient/command-handler.js +276 -0
- package/dist_ts/mail/delivery/smtpclient/connection-manager.d.ts +48 -0
- package/dist_ts/mail/delivery/smtpclient/connection-manager.js +238 -0
- package/dist_ts/mail/delivery/smtpclient/constants.d.ts +129 -0
- package/dist_ts/mail/delivery/smtpclient/constants.js +135 -0
- package/dist_ts/mail/delivery/smtpclient/create-client.d.ts +22 -0
- package/dist_ts/mail/delivery/smtpclient/create-client.js +86 -0
- package/dist_ts/mail/delivery/smtpclient/error-handler.d.ts +28 -0
- package/dist_ts/mail/delivery/smtpclient/error-handler.js +110 -0
- package/dist_ts/mail/delivery/smtpclient/index.d.ts +16 -0
- package/dist_ts/mail/delivery/smtpclient/index.js +21 -0
- package/dist_ts/mail/delivery/smtpclient/interfaces.d.ts +183 -0
- package/dist_ts/mail/delivery/smtpclient/interfaces.js +19 -0
- package/dist_ts/mail/delivery/smtpclient/smtp-client.d.ts +58 -0
- package/dist_ts/mail/delivery/smtpclient/smtp-client.js +279 -0
- package/dist_ts/mail/delivery/smtpclient/tls-handler.d.ts +33 -0
- package/dist_ts/mail/delivery/smtpclient/tls-handler.js +202 -0
- package/dist_ts/mail/delivery/smtpclient/utils/helpers.d.ts +77 -0
- package/dist_ts/mail/delivery/smtpclient/utils/helpers.js +196 -0
- package/dist_ts/mail/delivery/smtpclient/utils/logging.d.ts +46 -0
- package/dist_ts/mail/delivery/smtpclient/utils/logging.js +153 -0
- package/dist_ts/mail/delivery/smtpclient/utils/validation.d.ts +38 -0
- package/dist_ts/mail/delivery/smtpclient/utils/validation.js +139 -0
- package/dist_ts/mail/delivery/smtpserver/certificate-utils.d.ts +45 -0
- package/dist_ts/mail/delivery/smtpserver/certificate-utils.js +345 -0
- package/dist_ts/mail/delivery/smtpserver/command-handler.d.ts +156 -0
- package/dist_ts/mail/delivery/smtpserver/command-handler.js +1159 -0
- package/dist_ts/mail/delivery/smtpserver/connection-manager.d.ts +159 -0
- package/dist_ts/mail/delivery/smtpserver/connection-manager.js +894 -0
- package/dist_ts/mail/delivery/smtpserver/constants.d.ts +130 -0
- package/dist_ts/mail/delivery/smtpserver/constants.js +162 -0
- package/dist_ts/mail/delivery/smtpserver/create-server.d.ts +14 -0
- package/dist_ts/mail/delivery/smtpserver/create-server.js +28 -0
- package/dist_ts/mail/delivery/smtpserver/data-handler.d.ts +123 -0
- package/dist_ts/mail/delivery/smtpserver/data-handler.js +1148 -0
- package/dist_ts/mail/delivery/smtpserver/index.d.ts +20 -0
- package/dist_ts/mail/delivery/smtpserver/index.js +27 -0
- package/dist_ts/mail/delivery/smtpserver/interfaces.d.ts +530 -0
- package/dist_ts/mail/delivery/smtpserver/interfaces.js +10 -0
- package/dist_ts/mail/delivery/smtpserver/secure-server.d.ts +15 -0
- package/dist_ts/mail/delivery/smtpserver/secure-server.js +79 -0
- package/dist_ts/mail/delivery/smtpserver/security-handler.d.ts +86 -0
- package/dist_ts/mail/delivery/smtpserver/security-handler.js +234 -0
- package/dist_ts/mail/delivery/smtpserver/session-manager.d.ts +140 -0
- package/dist_ts/mail/delivery/smtpserver/session-manager.js +469 -0
- package/dist_ts/mail/delivery/smtpserver/smtp-server.d.ts +137 -0
- package/dist_ts/mail/delivery/smtpserver/smtp-server.js +666 -0
- package/dist_ts/mail/delivery/smtpserver/starttls-handler.d.ts +21 -0
- package/dist_ts/mail/delivery/smtpserver/starttls-handler.js +207 -0
- package/dist_ts/mail/delivery/smtpserver/tls-handler.d.ts +66 -0
- package/dist_ts/mail/delivery/smtpserver/tls-handler.js +261 -0
- package/dist_ts/mail/delivery/smtpserver/utils/adaptive-logging.d.ts +117 -0
- package/dist_ts/mail/delivery/smtpserver/utils/adaptive-logging.js +411 -0
- package/dist_ts/mail/delivery/smtpserver/utils/helpers.d.ts +78 -0
- package/dist_ts/mail/delivery/smtpserver/utils/helpers.js +208 -0
- package/dist_ts/mail/delivery/smtpserver/utils/logging.d.ts +106 -0
- package/dist_ts/mail/delivery/smtpserver/utils/logging.js +181 -0
- package/dist_ts/mail/delivery/smtpserver/utils/validation.d.ts +69 -0
- package/dist_ts/mail/delivery/smtpserver/utils/validation.js +360 -0
- package/dist_ts/mail/index.d.ts +8 -0
- package/dist_ts/mail/index.js +13 -0
- package/dist_ts/mail/routing/classes.dns.manager.d.ts +65 -0
- package/dist_ts/mail/routing/classes.dns.manager.js +413 -0
- package/dist_ts/mail/routing/classes.dnsmanager.d.ts +165 -0
- package/dist_ts/mail/routing/classes.dnsmanager.js +430 -0
- package/dist_ts/mail/routing/classes.domain.registry.d.ts +54 -0
- package/dist_ts/mail/routing/classes.domain.registry.js +118 -0
- package/dist_ts/mail/routing/classes.email.config.d.ts +64 -0
- package/dist_ts/mail/routing/classes.email.config.js +2 -0
- package/dist_ts/mail/routing/classes.email.router.d.ts +171 -0
- package/dist_ts/mail/routing/classes.email.router.js +491 -0
- package/dist_ts/mail/routing/classes.unified.email.server.d.ts +426 -0
- package/dist_ts/mail/routing/classes.unified.email.server.js +1454 -0
- package/dist_ts/mail/routing/index.d.ts +5 -0
- package/dist_ts/mail/routing/index.js +7 -0
- package/dist_ts/mail/routing/interfaces.d.ts +187 -0
- package/dist_ts/mail/routing/interfaces.js +2 -0
- package/dist_ts/mail/security/classes.dkimcreator.d.ts +68 -0
- package/dist_ts/mail/security/classes.dkimcreator.js +346 -0
- package/dist_ts/mail/security/classes.dkimverifier.d.ts +46 -0
- package/dist_ts/mail/security/classes.dkimverifier.js +317 -0
- package/dist_ts/mail/security/classes.dmarcverifier.d.ts +123 -0
- package/dist_ts/mail/security/classes.dmarcverifier.js +365 -0
- package/dist_ts/mail/security/classes.spfverifier.d.ts +103 -0
- package/dist_ts/mail/security/classes.spfverifier.js +492 -0
- package/dist_ts/mail/security/index.d.ts +4 -0
- package/dist_ts/mail/security/index.js +6 -0
- package/dist_ts/opsserver/classes.opsserver.d.ts +14 -0
- package/dist_ts/opsserver/classes.opsserver.js +37 -0
- package/dist_ts/opsserver/index.d.ts +1 -0
- package/dist_ts/opsserver/index.js +2 -0
- package/dist_ts/paths.d.ts +14 -0
- package/dist_ts/paths.js +39 -0
- package/dist_ts/plugins.d.ts +43 -0
- package/dist_ts/plugins.js +50 -0
- package/dist_ts/security/classes.contentscanner.d.ts +160 -0
- package/dist_ts/security/classes.contentscanner.js +634 -0
- package/dist_ts/security/classes.ipreputationchecker.d.ts +150 -0
- package/dist_ts/security/classes.ipreputationchecker.js +508 -0
- package/dist_ts/security/classes.securitylogger.d.ts +140 -0
- package/dist_ts/security/classes.securitylogger.js +232 -0
- package/dist_ts/security/index.d.ts +3 -0
- package/dist_ts/security/index.js +4 -0
- package/dist_ts/sms/classes.smsservice.d.ts +15 -0
- package/dist_ts/sms/classes.smsservice.js +72 -0
- package/dist_ts/sms/config/sms.config.d.ts +93 -0
- package/dist_ts/sms/config/sms.config.js +2 -0
- package/dist_ts/sms/config/sms.schema.d.ts +5 -0
- package/dist_ts/sms/config/sms.schema.js +121 -0
- package/dist_ts/sms/index.d.ts +1 -0
- package/dist_ts/sms/index.js +2 -0
- package/dist_ts/storage/classes.storagemanager.d.ts +82 -0
- package/dist_ts/storage/classes.storagemanager.js +341 -0
- package/dist_ts/storage/index.d.ts +1 -0
- package/dist_ts/storage/index.js +3 -0
- package/dist_ts/ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/ts/00_commitinfo_data.js +9 -0
- package/dist_ts/ts/classes.dcrouter.d.ts +238 -0
- package/dist_ts/ts/classes.dcrouter.js +1008 -0
- package/dist_ts/ts/config/index.d.ts +1 -0
- package/dist_ts/ts/config/index.js +3 -0
- package/dist_ts/ts/config/validator.d.ts +104 -0
- package/dist_ts/ts/config/validator.js +152 -0
- package/dist_ts/ts/deliverability/classes.ipwarmupmanager.d.ts +253 -0
- package/dist_ts/ts/deliverability/classes.ipwarmupmanager.js +639 -0
- package/dist_ts/ts/deliverability/classes.senderreputationmonitor.d.ts +300 -0
- package/dist_ts/ts/deliverability/classes.senderreputationmonitor.js +961 -0
- package/dist_ts/ts/deliverability/index.d.ts +2 -0
- package/dist_ts/ts/deliverability/index.js +3 -0
- package/dist_ts/ts/errors/base.errors.d.ts +224 -0
- package/dist_ts/ts/errors/base.errors.js +310 -0
- package/dist_ts/ts/errors/email.errors.d.ts +175 -0
- package/dist_ts/ts/errors/email.errors.js +265 -0
- package/dist_ts/ts/errors/error-handler.d.ts +98 -0
- package/dist_ts/ts/errors/error-handler.js +282 -0
- package/dist_ts/ts/errors/error.codes.d.ts +115 -0
- package/dist_ts/ts/errors/error.codes.js +136 -0
- package/dist_ts/ts/errors/index.d.ts +56 -0
- package/dist_ts/ts/errors/index.js +138 -0
- package/dist_ts/ts/errors/mta.errors.d.ts +259 -0
- package/dist_ts/ts/errors/mta.errors.js +472 -0
- package/dist_ts/ts/errors/reputation.errors.d.ts +183 -0
- package/dist_ts/ts/errors/reputation.errors.js +292 -0
- package/dist_ts/ts/index.d.ts +4 -0
- package/dist_ts/ts/index.js +6 -0
- package/dist_ts/ts/logger.d.ts +17 -0
- package/dist_ts/ts/logger.js +77 -0
- package/dist_ts/ts/mail/core/classes.bouncemanager.d.ts +200 -0
- package/dist_ts/ts/mail/core/classes.bouncemanager.js +778 -0
- package/dist_ts/ts/mail/core/classes.email.d.ts +291 -0
- package/dist_ts/ts/mail/core/classes.email.js +780 -0
- package/dist_ts/ts/mail/core/classes.emailvalidator.d.ts +61 -0
- package/dist_ts/ts/mail/core/classes.emailvalidator.js +182 -0
- package/dist_ts/ts/mail/core/classes.templatemanager.d.ts +95 -0
- package/dist_ts/ts/mail/core/classes.templatemanager.js +239 -0
- package/dist_ts/ts/mail/core/index.d.ts +4 -0
- package/dist_ts/ts/mail/core/index.js +6 -0
- package/dist_ts/ts/mail/delivery/classes.delivery.queue.d.ts +163 -0
- package/dist_ts/ts/mail/delivery/classes.delivery.queue.js +485 -0
- package/dist_ts/ts/mail/delivery/classes.delivery.system.d.ts +186 -0
- package/dist_ts/ts/mail/delivery/classes.delivery.system.js +846 -0
- package/dist_ts/ts/mail/delivery/classes.emailsendjob.d.ts +84 -0
- package/dist_ts/ts/mail/delivery/classes.emailsendjob.js +362 -0
- package/dist_ts/ts/mail/delivery/classes.emailsignjob.d.ts +18 -0
- package/dist_ts/ts/mail/delivery/classes.emailsignjob.js +44 -0
- package/dist_ts/ts/mail/delivery/classes.mta.config.d.ts +22 -0
- package/dist_ts/ts/mail/delivery/classes.mta.config.js +51 -0
- package/dist_ts/ts/mail/delivery/classes.ratelimiter.d.ts +98 -0
- package/dist_ts/ts/mail/delivery/classes.ratelimiter.js +205 -0
- package/dist_ts/ts/mail/delivery/classes.smtp.client.legacy.d.ts +275 -0
- package/dist_ts/ts/mail/delivery/classes.smtp.client.legacy.js +973 -0
- package/dist_ts/ts/mail/delivery/classes.unified.rate.limiter.d.ts +200 -0
- package/dist_ts/ts/mail/delivery/classes.unified.rate.limiter.js +817 -0
- package/dist_ts/ts/mail/delivery/index.d.ts +12 -0
- package/dist_ts/ts/mail/delivery/index.js +18 -0
- package/dist_ts/ts/mail/delivery/interfaces.d.ts +243 -0
- package/dist_ts/ts/mail/delivery/interfaces.js +17 -0
- package/dist_ts/ts/mail/delivery/smtpclient/auth-handler.d.ts +43 -0
- package/dist_ts/ts/mail/delivery/smtpclient/auth-handler.js +188 -0
- package/dist_ts/ts/mail/delivery/smtpclient/command-handler.d.ts +67 -0
- package/dist_ts/ts/mail/delivery/smtpclient/command-handler.js +276 -0
- package/dist_ts/ts/mail/delivery/smtpclient/connection-manager.d.ts +48 -0
- package/dist_ts/ts/mail/delivery/smtpclient/connection-manager.js +238 -0
- package/dist_ts/ts/mail/delivery/smtpclient/constants.d.ts +129 -0
- package/dist_ts/ts/mail/delivery/smtpclient/constants.js +135 -0
- package/dist_ts/ts/mail/delivery/smtpclient/create-client.d.ts +22 -0
- package/dist_ts/ts/mail/delivery/smtpclient/create-client.js +86 -0
- package/dist_ts/ts/mail/delivery/smtpclient/error-handler.d.ts +28 -0
- package/dist_ts/ts/mail/delivery/smtpclient/error-handler.js +110 -0
- package/dist_ts/ts/mail/delivery/smtpclient/index.d.ts +16 -0
- package/dist_ts/ts/mail/delivery/smtpclient/index.js +21 -0
- package/dist_ts/ts/mail/delivery/smtpclient/interfaces.d.ts +183 -0
- package/dist_ts/ts/mail/delivery/smtpclient/interfaces.js +19 -0
- package/dist_ts/ts/mail/delivery/smtpclient/smtp-client.d.ts +58 -0
- package/dist_ts/ts/mail/delivery/smtpclient/smtp-client.js +279 -0
- package/dist_ts/ts/mail/delivery/smtpclient/tls-handler.d.ts +33 -0
- package/dist_ts/ts/mail/delivery/smtpclient/tls-handler.js +202 -0
- package/dist_ts/ts/mail/delivery/smtpclient/utils/helpers.d.ts +77 -0
- package/dist_ts/ts/mail/delivery/smtpclient/utils/helpers.js +196 -0
- package/dist_ts/ts/mail/delivery/smtpclient/utils/logging.d.ts +46 -0
- package/dist_ts/ts/mail/delivery/smtpclient/utils/logging.js +153 -0
- package/dist_ts/ts/mail/delivery/smtpclient/utils/validation.d.ts +38 -0
- package/dist_ts/ts/mail/delivery/smtpclient/utils/validation.js +139 -0
- package/dist_ts/ts/mail/delivery/smtpserver/certificate-utils.d.ts +45 -0
- package/dist_ts/ts/mail/delivery/smtpserver/certificate-utils.js +345 -0
- package/dist_ts/ts/mail/delivery/smtpserver/command-handler.d.ts +156 -0
- package/dist_ts/ts/mail/delivery/smtpserver/command-handler.js +1159 -0
- package/dist_ts/ts/mail/delivery/smtpserver/connection-manager.d.ts +159 -0
- package/dist_ts/ts/mail/delivery/smtpserver/connection-manager.js +894 -0
- package/dist_ts/ts/mail/delivery/smtpserver/constants.d.ts +130 -0
- package/dist_ts/ts/mail/delivery/smtpserver/constants.js +162 -0
- package/dist_ts/ts/mail/delivery/smtpserver/create-server.d.ts +14 -0
- package/dist_ts/ts/mail/delivery/smtpserver/create-server.js +28 -0
- package/dist_ts/ts/mail/delivery/smtpserver/data-handler.d.ts +123 -0
- package/dist_ts/ts/mail/delivery/smtpserver/data-handler.js +1148 -0
- package/dist_ts/ts/mail/delivery/smtpserver/index.d.ts +20 -0
- package/dist_ts/ts/mail/delivery/smtpserver/index.js +27 -0
- package/dist_ts/ts/mail/delivery/smtpserver/interfaces.d.ts +530 -0
- package/dist_ts/ts/mail/delivery/smtpserver/interfaces.js +10 -0
- package/dist_ts/ts/mail/delivery/smtpserver/secure-server.d.ts +15 -0
- package/dist_ts/ts/mail/delivery/smtpserver/secure-server.js +79 -0
- package/dist_ts/ts/mail/delivery/smtpserver/security-handler.d.ts +86 -0
- package/dist_ts/ts/mail/delivery/smtpserver/security-handler.js +234 -0
- package/dist_ts/ts/mail/delivery/smtpserver/session-manager.d.ts +140 -0
- package/dist_ts/ts/mail/delivery/smtpserver/session-manager.js +469 -0
- package/dist_ts/ts/mail/delivery/smtpserver/smtp-server.d.ts +137 -0
- package/dist_ts/ts/mail/delivery/smtpserver/smtp-server.js +666 -0
- package/dist_ts/ts/mail/delivery/smtpserver/starttls-handler.d.ts +21 -0
- package/dist_ts/ts/mail/delivery/smtpserver/starttls-handler.js +207 -0
- package/dist_ts/ts/mail/delivery/smtpserver/tls-handler.d.ts +66 -0
- package/dist_ts/ts/mail/delivery/smtpserver/tls-handler.js +261 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/adaptive-logging.d.ts +117 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/adaptive-logging.js +411 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/helpers.d.ts +78 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/helpers.js +208 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/logging.d.ts +106 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/logging.js +181 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/validation.d.ts +69 -0
- package/dist_ts/ts/mail/delivery/smtpserver/utils/validation.js +360 -0
- package/dist_ts/ts/mail/index.d.ts +8 -0
- package/dist_ts/ts/mail/index.js +13 -0
- package/dist_ts/ts/mail/routing/classes.dns.manager.d.ts +65 -0
- package/dist_ts/ts/mail/routing/classes.dns.manager.js +413 -0
- package/dist_ts/ts/mail/routing/classes.dnsmanager.d.ts +165 -0
- package/dist_ts/ts/mail/routing/classes.dnsmanager.js +430 -0
- package/dist_ts/ts/mail/routing/classes.domain.registry.d.ts +54 -0
- package/dist_ts/ts/mail/routing/classes.domain.registry.js +118 -0
- package/dist_ts/ts/mail/routing/classes.email.config.d.ts +64 -0
- package/dist_ts/ts/mail/routing/classes.email.config.js +2 -0
- package/dist_ts/ts/mail/routing/classes.email.router.d.ts +171 -0
- package/dist_ts/ts/mail/routing/classes.email.router.js +491 -0
- package/dist_ts/ts/mail/routing/classes.unified.email.server.d.ts +426 -0
- package/dist_ts/ts/mail/routing/classes.unified.email.server.js +1454 -0
- package/dist_ts/ts/mail/routing/index.d.ts +5 -0
- package/dist_ts/ts/mail/routing/index.js +7 -0
- package/dist_ts/ts/mail/routing/interfaces.d.ts +187 -0
- package/dist_ts/ts/mail/routing/interfaces.js +2 -0
- package/dist_ts/ts/mail/security/classes.dkimcreator.d.ts +68 -0
- package/dist_ts/ts/mail/security/classes.dkimcreator.js +346 -0
- package/dist_ts/ts/mail/security/classes.dkimverifier.d.ts +46 -0
- package/dist_ts/ts/mail/security/classes.dkimverifier.js +317 -0
- package/dist_ts/ts/mail/security/classes.dmarcverifier.d.ts +123 -0
- package/dist_ts/ts/mail/security/classes.dmarcverifier.js +365 -0
- package/dist_ts/ts/mail/security/classes.spfverifier.d.ts +103 -0
- package/dist_ts/ts/mail/security/classes.spfverifier.js +492 -0
- package/dist_ts/ts/mail/security/index.d.ts +4 -0
- package/dist_ts/ts/mail/security/index.js +6 -0
- package/dist_ts/ts/opsserver/classes.opsserver.d.ts +20 -0
- package/dist_ts/ts/opsserver/classes.opsserver.js +44 -0
- package/dist_ts/ts/opsserver/handlers/admin.handler.d.ts +31 -0
- package/dist_ts/ts/opsserver/handlers/admin.handler.js +177 -0
- package/dist_ts/ts/opsserver/handlers/config.handler.d.ts +10 -0
- package/dist_ts/ts/opsserver/handlers/config.handler.js +100 -0
- package/dist_ts/ts/opsserver/handlers/index.d.ts +5 -0
- package/dist_ts/ts/opsserver/handlers/index.js +6 -0
- package/dist_ts/ts/opsserver/handlers/logs.handler.d.ts +10 -0
- package/dist_ts/ts/opsserver/handlers/logs.handler.js +121 -0
- package/dist_ts/ts/opsserver/handlers/security.handler.d.ts +11 -0
- package/dist_ts/ts/opsserver/handlers/security.handler.js +118 -0
- package/dist_ts/ts/opsserver/handlers/stats.handler.d.ts +13 -0
- package/dist_ts/ts/opsserver/handlers/stats.handler.js +233 -0
- package/dist_ts/ts/opsserver/helpers/guards.d.ts +25 -0
- package/dist_ts/ts/opsserver/helpers/guards.js +41 -0
- package/dist_ts/ts/opsserver/index.d.ts +1 -0
- package/dist_ts/ts/opsserver/index.js +2 -0
- package/dist_ts/ts/paths.d.ts +14 -0
- package/dist_ts/ts/paths.js +39 -0
- package/dist_ts/ts/plugins.d.ts +46 -0
- package/dist_ts/ts/plugins.js +53 -0
- package/dist_ts/ts/security/classes.contentscanner.d.ts +160 -0
- package/dist_ts/ts/security/classes.contentscanner.js +634 -0
- package/dist_ts/ts/security/classes.ipreputationchecker.d.ts +150 -0
- package/dist_ts/ts/security/classes.ipreputationchecker.js +508 -0
- package/dist_ts/ts/security/classes.securitylogger.d.ts +140 -0
- package/dist_ts/ts/security/classes.securitylogger.js +232 -0
- package/dist_ts/ts/security/index.d.ts +3 -0
- package/dist_ts/ts/security/index.js +4 -0
- package/dist_ts/ts/sms/classes.smsservice.d.ts +15 -0
- package/dist_ts/ts/sms/classes.smsservice.js +72 -0
- package/dist_ts/ts/sms/config/sms.config.d.ts +93 -0
- package/dist_ts/ts/sms/config/sms.config.js +2 -0
- package/dist_ts/ts/sms/config/sms.schema.d.ts +5 -0
- package/dist_ts/ts/sms/config/sms.schema.js +121 -0
- package/dist_ts/ts/sms/index.d.ts +1 -0
- package/dist_ts/ts/sms/index.js +2 -0
- package/dist_ts/ts/storage/classes.storagemanager.d.ts +82 -0
- package/dist_ts/ts/storage/classes.storagemanager.js +341 -0
- package/dist_ts/ts/storage/index.d.ts +1 -0
- package/dist_ts/ts/storage/index.js +3 -0
- package/dist_ts/ts_interfaces/data/auth.d.ts +8 -0
- package/dist_ts/ts_interfaces/data/auth.js +2 -0
- package/dist_ts/ts_interfaces/data/index.d.ts +2 -0
- package/dist_ts/ts_interfaces/data/index.js +3 -0
- package/dist_ts/ts_interfaces/data/stats.d.ts +93 -0
- package/dist_ts/ts_interfaces/data/stats.js +2 -0
- package/dist_ts/ts_interfaces/index.d.ts +5 -0
- package/dist_ts/ts_interfaces/index.js +8 -0
- package/dist_ts/ts_interfaces/plugins.d.ts +2 -0
- package/dist_ts/ts_interfaces/plugins.js +4 -0
- package/dist_ts/ts_interfaces/requests/admin.d.ts +31 -0
- package/dist_ts/ts_interfaces/requests/admin.js +3 -0
- package/dist_ts/ts_interfaces/requests/config.d.ts +25 -0
- package/dist_ts/ts_interfaces/requests/config.js +3 -0
- package/dist_ts/ts_interfaces/requests/index.d.ts +4 -0
- package/dist_ts/ts_interfaces/requests/index.js +5 -0
- package/dist_ts/ts_interfaces/requests/logs.d.ts +34 -0
- package/dist_ts/ts_interfaces/requests/logs.js +4 -0
- package/dist_ts/ts_interfaces/requests/stats.d.ts +131 -0
- package/dist_ts/ts_interfaces/requests/stats.js +4 -0
- package/html/index.html +121 -0
- package/npmextra.json +45 -0
- package/package.json +83 -0
- package/readme.hints.md +906 -0
- package/readme.md +1253 -0
- package/readme.opsserver.md +351 -0
- package/test/helpers/server.loader.ts +347 -0
- package/test/helpers/smtp.client.ts +209 -0
- package/test/helpers/utils.ts +311 -0
- package/test/readme.md +443 -0
- package/test/suite/smtpclient_commands/test.ccmd-01.ehlo-helo-sending.ts +168 -0
- package/test/suite/smtpclient_commands/test.ccmd-02.mail-from-parameters.ts +277 -0
- package/test/suite/smtpclient_commands/test.ccmd-03.rcpt-to-multiple.ts +283 -0
- package/test/suite/smtpclient_commands/test.ccmd-04.data-transmission.ts +274 -0
- package/test/suite/smtpclient_commands/test.ccmd-05.auth-mechanisms.ts +306 -0
- package/test/suite/smtpclient_commands/test.ccmd-06.command-pipelining.ts +233 -0
- package/test/suite/smtpclient_commands/test.ccmd-07.response-parsing.ts +243 -0
- package/test/suite/smtpclient_commands/test.ccmd-08.rset-command.ts +333 -0
- package/test/suite/smtpclient_commands/test.ccmd-09.noop-command.ts +339 -0
- package/test/suite/smtpclient_commands/test.ccmd-10.vrfy-expn.ts +457 -0
- package/test/suite/smtpclient_commands/test.ccmd-11.help-command.ts +409 -0
- package/test/suite/smtpclient_connection/test.ccm-01.basic-tcp-connection.ts +150 -0
- package/test/suite/smtpclient_connection/test.ccm-02.tls-connection.ts +140 -0
- package/test/suite/smtpclient_connection/test.ccm-03.starttls-upgrade.ts +208 -0
- package/test/suite/smtpclient_connection/test.ccm-04.connection-pooling.ts +250 -0
- package/test/suite/smtpclient_connection/test.ccm-05.connection-reuse.ts +288 -0
- package/test/suite/smtpclient_connection/test.ccm-06.connection-timeout.ts +267 -0
- package/test/suite/smtpclient_connection/test.ccm-07.automatic-reconnection.ts +324 -0
- package/test/suite/smtpclient_connection/test.ccm-08.dns-resolution.ts +139 -0
- package/test/suite/smtpclient_connection/test.ccm-09.ipv6-dual-stack.ts +167 -0
- package/test/suite/smtpclient_connection/test.ccm-10.proxy-support.ts +305 -0
- package/test/suite/smtpclient_connection/test.ccm-11.keepalive.ts +299 -0
- package/test/suite/smtpclient_edge-cases/test.cedge-01.unusual-server-responses.ts +529 -0
- package/test/suite/smtpclient_edge-cases/test.cedge-02.malformed-commands.ts +438 -0
- package/test/suite/smtpclient_edge-cases/test.cedge-03.protocol-violations.ts +446 -0
- package/test/suite/smtpclient_edge-cases/test.cedge-04.resource-constraints.ts +530 -0
- package/test/suite/smtpclient_edge-cases/test.cedge-05.encoding-issues.ts +145 -0
- package/test/suite/smtpclient_edge-cases/test.cedge-06.large-headers.ts +180 -0
- package/test/suite/smtpclient_edge-cases/test.cedge-07.concurrent-operations.ts +204 -0
- package/test/suite/smtpclient_email-composition/test.cep-01.basic-headers.ts +245 -0
- package/test/suite/smtpclient_email-composition/test.cep-02.mime-multipart.ts +321 -0
- package/test/suite/smtpclient_email-composition/test.cep-03.attachment-encoding.ts +334 -0
- package/test/suite/smtpclient_email-composition/test.cep-04.bcc-handling.ts +187 -0
- package/test/suite/smtpclient_email-composition/test.cep-05.reply-to-return-path.ts +277 -0
- package/test/suite/smtpclient_email-composition/test.cep-06.utf8-international.ts +235 -0
- package/test/suite/smtpclient_email-composition/test.cep-07.html-inline-images.ts +489 -0
- package/test/suite/smtpclient_email-composition/test.cep-08.custom-headers.ts +293 -0
- package/test/suite/smtpclient_email-composition/test.cep-09.priority-importance.ts +314 -0
- package/test/suite/smtpclient_email-composition/test.cep-10.receipts-dsn.ts +411 -0
- package/test/suite/smtpclient_error-handling/test.cerr-01.4xx-errors.ts +232 -0
- package/test/suite/smtpclient_error-handling/test.cerr-02.5xx-errors.ts +309 -0
- package/test/suite/smtpclient_error-handling/test.cerr-03.network-failures.ts +299 -0
- package/test/suite/smtpclient_error-handling/test.cerr-04.greylisting-handling.ts +255 -0
- package/test/suite/smtpclient_error-handling/test.cerr-05.quota-exceeded.ts +273 -0
- package/test/suite/smtpclient_error-handling/test.cerr-06.invalid-recipients.ts +320 -0
- package/test/suite/smtpclient_error-handling/test.cerr-07.message-size-limits.ts +320 -0
- package/test/suite/smtpclient_error-handling/test.cerr-08.rate-limiting.ts +261 -0
- package/test/suite/smtpclient_error-handling/test.cerr-09.connection-pool-errors.ts +299 -0
- package/test/suite/smtpclient_error-handling/test.cerr-10.partial-failure.ts +373 -0
- package/test/suite/smtpclient_performance/test.cperf-01.bulk-sending.ts +332 -0
- package/test/suite/smtpclient_performance/test.cperf-02.message-throughput.ts +304 -0
- package/test/suite/smtpclient_performance/test.cperf-03.memory-usage.ts +332 -0
- package/test/suite/smtpclient_performance/test.cperf-04.cpu-utilization.ts +373 -0
- package/test/suite/smtpclient_performance/test.cperf-05.network-efficiency.ts +181 -0
- package/test/suite/smtpclient_performance/test.cperf-06.caching-strategies.ts +190 -0
- package/test/suite/smtpclient_performance/test.cperf-07.queue-management.ts +171 -0
- package/test/suite/smtpclient_performance/test.cperf-08.dns-caching.ts +50 -0
- package/test/suite/smtpclient_reliability/test.crel-01.reconnection-logic.ts +305 -0
- package/test/suite/smtpclient_reliability/test.crel-02.network-interruption.ts +207 -0
- package/test/suite/smtpclient_reliability/test.crel-03.queue-persistence.ts +469 -0
- package/test/suite/smtpclient_reliability/test.crel-04.crash-recovery.ts +520 -0
- package/test/suite/smtpclient_reliability/test.crel-05.memory-leaks.ts +503 -0
- package/test/suite/smtpclient_reliability/test.crel-06.concurrency-safety.ts +558 -0
- package/test/suite/smtpclient_reliability/test.crel-07.resource-cleanup.ts +52 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-01.rfc5321-client.ts +283 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-02.esmtp-compliance.ts +77 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-03.command-syntax.ts +67 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-04.response-codes.ts +54 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-05.state-machine.ts +703 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-06.protocol-negotiation.ts +688 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-07.interoperability.ts +728 -0
- package/test/suite/smtpclient_rfc-compliance/test.crfc-08.smtp-extensions.ts +656 -0
- package/test/suite/smtpclient_security/test.csec-01.tls-verification.ts +88 -0
- package/test/suite/smtpclient_security/test.csec-02.oauth2-authentication.ts +132 -0
- package/test/suite/smtpclient_security/test.csec-03.dkim-signing.ts +138 -0
- package/test/suite/smtpclient_security/test.csec-04.spf-compliance.ts +163 -0
- package/test/suite/smtpclient_security/test.csec-05.dmarc-policy.ts +200 -0
- package/test/suite/smtpclient_security/test.csec-06.certificate-validation.ts +145 -0
- package/test/suite/smtpclient_security/test.csec-07.cipher-suites.ts +153 -0
- package/test/suite/smtpclient_security/test.csec-08.authentication-fallback.ts +154 -0
- package/test/suite/smtpclient_security/test.csec-09.relay-restrictions.ts +166 -0
- package/test/suite/smtpclient_security/test.csec-10.anti-spam-measures.ts +196 -0
- package/test/suite/smtpserver_commands/test.cmd-01.ehlo-command.ts +193 -0
- package/test/suite/smtpserver_commands/test.cmd-02.mail-from.ts +330 -0
- package/test/suite/smtpserver_commands/test.cmd-03.rcpt-to.ts +296 -0
- package/test/suite/smtpserver_commands/test.cmd-04.data-command.ts +395 -0
- package/test/suite/smtpserver_commands/test.cmd-05.noop-command.ts +320 -0
- package/test/suite/smtpserver_commands/test.cmd-06.rset-command.ts +399 -0
- package/test/suite/smtpserver_commands/test.cmd-07.vrfy-command.ts +391 -0
- package/test/suite/smtpserver_commands/test.cmd-08.expn-command.ts +450 -0
- package/test/suite/smtpserver_commands/test.cmd-09.size-extension.ts +465 -0
- package/test/suite/smtpserver_commands/test.cmd-10.help-command.ts +454 -0
- package/test/suite/smtpserver_commands/test.cmd-11.command-pipelining.ts +334 -0
- package/test/suite/smtpserver_commands/test.cmd-12.helo-command.ts +420 -0
- package/test/suite/smtpserver_commands/test.cmd-13.quit-command.ts +384 -0
- package/test/suite/smtpserver_connection/test.cm-01.tls-connection.ts +61 -0
- package/test/suite/smtpserver_connection/test.cm-02.multiple-connections.ts +112 -0
- package/test/suite/smtpserver_connection/test.cm-03.connection-timeout.ts +134 -0
- package/test/suite/smtpserver_connection/test.cm-04.connection-limits.ts +374 -0
- package/test/suite/smtpserver_connection/test.cm-05.connection-rejection.ts +296 -0
- package/test/suite/smtpserver_connection/test.cm-06.starttls-upgrade.ts +468 -0
- package/test/suite/smtpserver_connection/test.cm-07.abrupt-disconnection.ts +321 -0
- package/test/suite/smtpserver_connection/test.cm-08.tls-versions.ts +361 -0
- package/test/suite/smtpserver_connection/test.cm-09.tls-ciphers.ts +556 -0
- package/test/suite/smtpserver_connection/test.cm-10.plain-connection.ts +293 -0
- package/test/suite/smtpserver_connection/test.cm-11.keepalive.ts +382 -0
- package/test/suite/smtpserver_edge-cases/test.edge-01.very-large-email.ts +239 -0
- package/test/suite/smtpserver_edge-cases/test.edge-02.very-small-email.ts +389 -0
- package/test/suite/smtpserver_edge-cases/test.edge-03.invalid-character-handling.ts +479 -0
- package/test/suite/smtpserver_edge-cases/test.edge-04.empty-commands.ts +430 -0
- package/test/suite/smtpserver_edge-cases/test.edge-05.extremely-long-lines.ts +425 -0
- package/test/suite/smtpserver_edge-cases/test.edge-06.extremely-long-headers.ts +404 -0
- package/test/suite/smtpserver_edge-cases/test.edge-07.unusual-mime-types.ts +333 -0
- package/test/suite/smtpserver_edge-cases/test.edge-08.nested-mime-structures.ts +379 -0
- package/test/suite/smtpserver_email-processing/test.ep-01.basic-email-sending.ts +338 -0
- package/test/suite/smtpserver_email-processing/test.ep-02.invalid-email-addresses.ts +315 -0
- package/test/suite/smtpserver_email-processing/test.ep-03.multiple-recipients.ts +493 -0
- package/test/suite/smtpserver_email-processing/test.ep-04.large-email.ts +528 -0
- package/test/suite/smtpserver_email-processing/test.ep-05.mime-handling.ts +515 -0
- package/test/suite/smtpserver_email-processing/test.ep-06.attachment-handling.ts +629 -0
- package/test/suite/smtpserver_email-processing/test.ep-07.special-character-handling.ts +462 -0
- package/test/suite/smtpserver_email-processing/test.ep-08.email-routing.ts +527 -0
- package/test/suite/smtpserver_email-processing/test.ep-09.delivery-status-notifications.ts +486 -0
- package/test/suite/smtpserver_error-handling/test.err-01.syntax-errors.ts +475 -0
- package/test/suite/smtpserver_error-handling/test.err-02.invalid-sequence.ts +450 -0
- package/test/suite/smtpserver_error-handling/test.err-03.temporary-failures.ts +453 -0
- package/test/suite/smtpserver_error-handling/test.err-04.permanent-failures.ts +325 -0
- package/test/suite/smtpserver_error-handling/test.err-05.resource-exhaustion.ts +302 -0
- package/test/suite/smtpserver_error-handling/test.err-06.malformed-mime.ts +374 -0
- package/test/suite/smtpserver_error-handling/test.err-07.exception-handling.ts +333 -0
- package/test/suite/smtpserver_error-handling/test.err-08.error-logging.ts +324 -0
- package/test/suite/smtpserver_performance/test.perf-01.throughput.ts +183 -0
- package/test/suite/smtpserver_performance/test.perf-02.concurrency.ts +388 -0
- package/test/suite/smtpserver_performance/test.perf-03.cpu-utilization.ts +245 -0
- package/test/suite/smtpserver_performance/test.perf-04.memory-usage.ts +238 -0
- package/test/suite/smtpserver_performance/test.perf-05.connection-processing-time.ts +363 -0
- package/test/suite/smtpserver_performance/test.perf-06.message-processing-time.ts +252 -0
- package/test/suite/smtpserver_performance/test.perf-07.resource-cleanup.ts +317 -0
- package/test/suite/smtpserver_reliability/test.rel-01.long-running-operation.ts +344 -0
- package/test/suite/smtpserver_reliability/test.rel-02.restart-recovery.ts +328 -0
- package/test/suite/smtpserver_reliability/test.rel-03.resource-leak-detection.ts +394 -0
- package/test/suite/smtpserver_reliability/test.rel-04.error-recovery.ts +401 -0
- package/test/suite/smtpserver_reliability/test.rel-05.dns-resolution-failure.ts +335 -0
- package/test/suite/smtpserver_reliability/test.rel-06.network-interruption.ts +410 -0
- package/test/suite/smtpserver_rfc-compliance/test.rfc-01.rfc5321-compliance.ts +382 -0
- package/test/suite/smtpserver_rfc-compliance/test.rfc-02.rfc5322-compliance.ts +428 -0
- package/test/suite/smtpserver_rfc-compliance/test.rfc-03.rfc7208-spf-compliance.ts +330 -0
- package/test/suite/smtpserver_rfc-compliance/test.rfc-04.rfc6376-dkim-compliance.ts +450 -0
- package/test/suite/smtpserver_rfc-compliance/test.rfc-05.rfc7489-dmarc-compliance.ts +408 -0
- package/test/suite/smtpserver_rfc-compliance/test.rfc-06.rfc8314-tls-compliance.ts +366 -0
- package/test/suite/smtpserver_rfc-compliance/test.rfc-07.rfc3461-dsn-compliance.ts +399 -0
- package/test/suite/smtpserver_security/test.sec-01.authentication.ts +218 -0
- package/test/suite/smtpserver_security/test.sec-02.authorization.ts +286 -0
- package/test/suite/smtpserver_security/test.sec-03.dkim-processing.ts +414 -0
- package/test/suite/smtpserver_security/test.sec-04.spf-checking.ts +280 -0
- package/test/suite/smtpserver_security/test.sec-05.dmarc-policy.ts +374 -0
- package/test/suite/smtpserver_security/test.sec-06.ip-reputation.ts +303 -0
- package/test/suite/smtpserver_security/test.sec-07.content-scanning.ts +409 -0
- package/test/suite/smtpserver_security/test.sec-08.rate-limiting.ts +324 -0
- package/test/suite/smtpserver_security/test.sec-09.tls-certificate-validation.ts +312 -0
- package/test/suite/smtpserver_security/test.sec-10.header-injection-prevention.ts +332 -0
- package/test/suite/smtpserver_security/test.sec-11.bounce-management.ts +363 -0
- package/test/test.base.ts +65 -0
- package/test/test.bouncemanager.ts +196 -0
- package/test/test.config.md +175 -0
- package/test/test.contentscanner.ts +265 -0
- package/test/test.dcrouter.email.ts +201 -0
- package/test/test.deliverability.ts +55 -0
- package/test/test.dns-manager-creation.ts +141 -0
- package/test/test.dns-mode-switching.ts +257 -0
- package/test/test.dns-server-config.ts +140 -0
- package/test/test.dns-socket-handler.ts +169 -0
- package/test/test.dns-validation.ts +283 -0
- package/test/test.email-socket-handler.ts +228 -0
- package/test/test.email.integration.ts +377 -0
- package/test/test.email.router.ts +283 -0
- package/test/test.emailauth.ts +195 -0
- package/test/test.errors.ts +408 -0
- package/test/test.integration.storage.ts +313 -0
- package/test/test.integration.ts +75 -0
- package/test/test.ipreputationchecker.ts +179 -0
- package/test/test.ipwarmupmanager.ts +323 -0
- package/test/test.jwt-auth.ts +130 -0
- package/test/test.minimal.ts +66 -0
- package/test/test.opsserver-api.ts +83 -0
- package/test/test.protected-endpoint.ts +115 -0
- package/test/test.rate-limiting-integration.ts +236 -0
- package/test/test.ratelimiter.ts +141 -0
- package/test/test.reputationmonitor.ts +262 -0
- package/test/test.smartmail.ts +248 -0
- package/test/test.smtp.client.compatibility.ts +154 -0
- package/test/test.smtp.client.ts +191 -0
- package/test/test.smtp.server.ts +180 -0
- package/test/test.socket-handler-integration.ts +240 -0
- package/test/test.socket-handler-unit.ts +198 -0
- package/test/test.storagemanager.ts +289 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.dcrouter.ts +1310 -0
- package/ts/config/index.ts +2 -0
- package/ts/config/validator.ts +266 -0
- package/ts/deliverability/classes.ipwarmupmanager.ts +896 -0
- package/ts/deliverability/classes.senderreputationmonitor.ts +1244 -0
- package/ts/deliverability/index.ts +13 -0
- package/ts/errors/base.errors.ts +525 -0
- package/ts/errors/email.errors.ts +383 -0
- package/ts/errors/error-handler.ts +412 -0
- package/ts/errors/error.codes.ts +165 -0
- package/ts/errors/index.ts +195 -0
- package/ts/errors/mta.errors.ts +681 -0
- package/ts/errors/reputation.errors.ts +422 -0
- package/ts/index.ts +7 -0
- package/ts/logger.ts +91 -0
- package/ts/mail/core/classes.bouncemanager.ts +965 -0
- package/ts/mail/core/classes.email.ts +941 -0
- package/ts/mail/core/classes.emailvalidator.ts +239 -0
- package/ts/mail/core/classes.templatemanager.ts +320 -0
- package/ts/mail/core/index.ts +5 -0
- package/ts/mail/delivery/classes.delivery.queue.ts +645 -0
- package/ts/mail/delivery/classes.delivery.system.ts +1089 -0
- package/ts/mail/delivery/classes.emailsendjob.ts +447 -0
- package/ts/mail/delivery/classes.emailsendjob.ts.backup +691 -0
- package/ts/mail/delivery/classes.emailsignjob.ts +67 -0
- package/ts/mail/delivery/classes.mta.config.ts +73 -0
- package/ts/mail/delivery/classes.ratelimiter.ts +281 -0
- package/ts/mail/delivery/classes.smtp.client.legacy.ts +1422 -0
- package/ts/mail/delivery/classes.unified.rate.limiter.ts +1053 -0
- package/ts/mail/delivery/index.ts +24 -0
- package/ts/mail/delivery/interfaces.ts +291 -0
- package/ts/mail/delivery/smtpclient/auth-handler.ts +232 -0
- package/ts/mail/delivery/smtpclient/command-handler.ts +343 -0
- package/ts/mail/delivery/smtpclient/connection-manager.ts +289 -0
- package/ts/mail/delivery/smtpclient/constants.ts +145 -0
- package/ts/mail/delivery/smtpclient/create-client.ts +94 -0
- package/ts/mail/delivery/smtpclient/error-handler.ts +141 -0
- package/ts/mail/delivery/smtpclient/index.ts +24 -0
- package/ts/mail/delivery/smtpclient/interfaces.ts +242 -0
- package/ts/mail/delivery/smtpclient/smtp-client.ts +357 -0
- package/ts/mail/delivery/smtpclient/tls-handler.ts +254 -0
- package/ts/mail/delivery/smtpclient/utils/helpers.ts +224 -0
- package/ts/mail/delivery/smtpclient/utils/logging.ts +212 -0
- package/ts/mail/delivery/smtpclient/utils/validation.ts +170 -0
- package/ts/mail/delivery/smtpserver/certificate-utils.ts +398 -0
- package/ts/mail/delivery/smtpserver/command-handler.ts +1340 -0
- package/ts/mail/delivery/smtpserver/connection-manager.ts +1045 -0
- package/ts/mail/delivery/smtpserver/constants.ts +181 -0
- package/ts/mail/delivery/smtpserver/create-server.ts +31 -0
- package/ts/mail/delivery/smtpserver/data-handler.ts +1283 -0
- package/ts/mail/delivery/smtpserver/index.ts +32 -0
- package/ts/mail/delivery/smtpserver/interfaces.ts +655 -0
- package/ts/mail/delivery/smtpserver/secure-server.ts +97 -0
- package/ts/mail/delivery/smtpserver/security-handler.ts +345 -0
- package/ts/mail/delivery/smtpserver/session-manager.ts +557 -0
- package/ts/mail/delivery/smtpserver/smtp-server.ts +804 -0
- package/ts/mail/delivery/smtpserver/starttls-handler.ts +262 -0
- package/ts/mail/delivery/smtpserver/tls-handler.ts +346 -0
- package/ts/mail/delivery/smtpserver/utils/adaptive-logging.ts +514 -0
- package/ts/mail/delivery/smtpserver/utils/helpers.ts +246 -0
- package/ts/mail/delivery/smtpserver/utils/logging.ts +246 -0
- package/ts/mail/delivery/smtpserver/utils/validation.ts +436 -0
- package/ts/mail/index.ts +19 -0
- package/ts/mail/routing/classes.dns.manager.ts +563 -0
- package/ts/mail/routing/classes.dnsmanager.ts +559 -0
- package/ts/mail/routing/classes.domain.registry.ts +139 -0
- package/ts/mail/routing/classes.email.config.ts +82 -0
- package/ts/mail/routing/classes.email.router.ts +575 -0
- package/ts/mail/routing/classes.unified.email.server.ts +1873 -0
- package/ts/mail/routing/index.ts +6 -0
- package/ts/mail/routing/interfaces.ts +202 -0
- package/ts/mail/security/classes.dkimcreator.ts +431 -0
- package/ts/mail/security/classes.dkimverifier.ts +382 -0
- package/ts/mail/security/classes.dmarcverifier.ts +478 -0
- package/ts/mail/security/classes.spfverifier.ts +606 -0
- package/ts/mail/security/index.ts +5 -0
- package/ts/opsserver/classes.opsserver.ts +65 -0
- package/ts/opsserver/handlers/admin.handler.ts +240 -0
- package/ts/opsserver/handlers/config.handler.ts +150 -0
- package/ts/opsserver/handlers/index.ts +5 -0
- package/ts/opsserver/handlers/logs.handler.ts +195 -0
- package/ts/opsserver/handlers/security.handler.ts +208 -0
- package/ts/opsserver/handlers/stats.handler.ts +344 -0
- package/ts/opsserver/helpers/guards.ts +56 -0
- package/ts/opsserver/index.ts +1 -0
- package/ts/paths.ts +48 -0
- package/ts/plugins.ts +94 -0
- package/ts/security/classes.contentscanner.ts +739 -0
- package/ts/security/classes.ipreputationchecker.ts +592 -0
- package/ts/security/classes.securitylogger.ts +299 -0
- package/ts/security/index.ts +21 -0
- package/ts/sms/classes.smsservice.ts +98 -0
- package/ts/sms/config/sms.config.ts +109 -0
- package/ts/sms/config/sms.schema.ts +122 -0
- package/ts/sms/index.ts +1 -0
- package/ts/storage/classes.storagemanager.ts +400 -0
- package/ts/storage/index.ts +2 -0
- package/ts/tspublish.json +3 -0
- package/ts_interfaces/data/auth.ts +8 -0
- package/ts_interfaces/data/index.ts +2 -0
- package/ts_interfaces/data/stats.ts +101 -0
- package/ts_interfaces/index.ts +9 -0
- package/ts_interfaces/plugins.ts +6 -0
- package/ts_interfaces/requests/admin.ts +46 -0
- package/ts_interfaces/requests/config.ts +35 -0
- package/ts_interfaces/requests/index.ts +4 -0
- package/ts_interfaces/requests/logs.ts +44 -0
- package/ts_interfaces/requests/stats.ts +162 -0
- package/ts_interfaces/tspublish.json +3 -0
- package/ts_web/00_commitinfo_data.ts +8 -0
- package/ts_web/appstate.ts +361 -0
- package/ts_web/elements/index.ts +7 -0
- package/ts_web/elements/ops-dashboard.ts +165 -0
- package/ts_web/elements/ops-view-config.ts +268 -0
- package/ts_web/elements/ops-view-logs.ts +207 -0
- package/ts_web/elements/ops-view-overview.ts +222 -0
- package/ts_web/elements/ops-view-security.ts +471 -0
- package/ts_web/elements/ops-view-stats.ts +299 -0
- package/ts_web/elements/shared/css.ts +10 -0
- package/ts_web/elements/shared/index.ts +2 -0
- package/ts_web/elements/shared/ops-sectionheading.ts +42 -0
- package/ts_web/index.ts +9 -0
- package/ts_web/plugins.ts +11 -0
- package/ts_web/tspublish.json +3 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,1089 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import * as net from 'node:net';
|
|
4
|
+
import * as tls from 'node:tls';
|
|
5
|
+
import { logger } from '../../logger.js';
|
|
6
|
+
import {
|
|
7
|
+
SecurityLogger,
|
|
8
|
+
SecurityLogLevel,
|
|
9
|
+
SecurityEventType
|
|
10
|
+
} from '../../security/index.js';
|
|
11
|
+
import { UnifiedDeliveryQueue, type IQueueItem } from './classes.delivery.queue.js';
|
|
12
|
+
import type { Email } from '../core/classes.email.js';
|
|
13
|
+
import type { UnifiedEmailServer } from '../routing/classes.unified.email.server.js';
|
|
14
|
+
import type { SmtpClient } from './smtpclient/smtp-client.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Delivery status enumeration
|
|
18
|
+
*/
|
|
19
|
+
export enum DeliveryStatus {
|
|
20
|
+
PENDING = 'pending',
|
|
21
|
+
DELIVERING = 'delivering',
|
|
22
|
+
DELIVERED = 'delivered',
|
|
23
|
+
DEFERRED = 'deferred',
|
|
24
|
+
FAILED = 'failed'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Delivery handler interface
|
|
29
|
+
*/
|
|
30
|
+
export interface IDeliveryHandler {
|
|
31
|
+
deliver(item: IQueueItem): Promise<any>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Delivery options
|
|
36
|
+
*/
|
|
37
|
+
export interface IMultiModeDeliveryOptions {
|
|
38
|
+
// Connection options
|
|
39
|
+
connectionPoolSize?: number;
|
|
40
|
+
socketTimeout?: number;
|
|
41
|
+
|
|
42
|
+
// Delivery behavior
|
|
43
|
+
concurrentDeliveries?: number;
|
|
44
|
+
sendTimeout?: number;
|
|
45
|
+
|
|
46
|
+
// TLS options
|
|
47
|
+
verifyCertificates?: boolean;
|
|
48
|
+
tlsMinVersion?: string;
|
|
49
|
+
|
|
50
|
+
// Mode-specific handlers
|
|
51
|
+
forwardHandler?: IDeliveryHandler;
|
|
52
|
+
deliveryHandler?: IDeliveryHandler;
|
|
53
|
+
processHandler?: IDeliveryHandler;
|
|
54
|
+
|
|
55
|
+
// Rate limiting
|
|
56
|
+
globalRateLimit?: number;
|
|
57
|
+
perPatternRateLimit?: Record<string, number>;
|
|
58
|
+
|
|
59
|
+
// Bounce handling
|
|
60
|
+
processBounces?: boolean;
|
|
61
|
+
bounceHandler?: {
|
|
62
|
+
processSmtpFailure: (recipient: string, smtpResponse: string, options: any) => Promise<any>;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Event hooks
|
|
66
|
+
onDeliveryStart?: (item: IQueueItem) => Promise<void>;
|
|
67
|
+
onDeliverySuccess?: (item: IQueueItem, result: any) => Promise<void>;
|
|
68
|
+
onDeliveryFailed?: (item: IQueueItem, error: string) => Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Delivery system statistics
|
|
73
|
+
*/
|
|
74
|
+
export interface IDeliveryStats {
|
|
75
|
+
activeDeliveries: number;
|
|
76
|
+
totalSuccessful: number;
|
|
77
|
+
totalFailed: number;
|
|
78
|
+
avgDeliveryTime: number;
|
|
79
|
+
byMode: {
|
|
80
|
+
forward: {
|
|
81
|
+
successful: number;
|
|
82
|
+
failed: number;
|
|
83
|
+
};
|
|
84
|
+
mta: {
|
|
85
|
+
successful: number;
|
|
86
|
+
failed: number;
|
|
87
|
+
};
|
|
88
|
+
process: {
|
|
89
|
+
successful: number;
|
|
90
|
+
failed: number;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
rateLimiting: {
|
|
94
|
+
currentRate: number;
|
|
95
|
+
globalLimit: number;
|
|
96
|
+
throttled: number;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Handles delivery for all email processing modes
|
|
102
|
+
*/
|
|
103
|
+
export class MultiModeDeliverySystem extends EventEmitter {
|
|
104
|
+
private queue: UnifiedDeliveryQueue;
|
|
105
|
+
private options: Required<IMultiModeDeliveryOptions>;
|
|
106
|
+
private stats: IDeliveryStats;
|
|
107
|
+
private deliveryTimes: number[] = [];
|
|
108
|
+
private activeDeliveries: Set<string> = new Set();
|
|
109
|
+
private running: boolean = false;
|
|
110
|
+
private throttled: boolean = false;
|
|
111
|
+
private rateLimitLastCheck: number = Date.now();
|
|
112
|
+
private rateLimitCounter: number = 0;
|
|
113
|
+
private emailServer?: UnifiedEmailServer;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Create a new multi-mode delivery system
|
|
117
|
+
* @param queue Unified delivery queue
|
|
118
|
+
* @param options Delivery options
|
|
119
|
+
* @param emailServer Optional reference to unified email server for SmtpClient access
|
|
120
|
+
*/
|
|
121
|
+
constructor(queue: UnifiedDeliveryQueue, options: IMultiModeDeliveryOptions, emailServer?: UnifiedEmailServer) {
|
|
122
|
+
super();
|
|
123
|
+
|
|
124
|
+
this.queue = queue;
|
|
125
|
+
this.emailServer = emailServer;
|
|
126
|
+
|
|
127
|
+
// Set default options
|
|
128
|
+
this.options = {
|
|
129
|
+
connectionPoolSize: options.connectionPoolSize || 10,
|
|
130
|
+
socketTimeout: options.socketTimeout || 30000, // 30 seconds
|
|
131
|
+
concurrentDeliveries: options.concurrentDeliveries || 10,
|
|
132
|
+
sendTimeout: options.sendTimeout || 60000, // 1 minute
|
|
133
|
+
verifyCertificates: options.verifyCertificates !== false, // Default to true
|
|
134
|
+
tlsMinVersion: options.tlsMinVersion || 'TLSv1.2',
|
|
135
|
+
forwardHandler: options.forwardHandler || {
|
|
136
|
+
deliver: this.handleForwardDelivery.bind(this)
|
|
137
|
+
},
|
|
138
|
+
deliveryHandler: options.deliveryHandler || {
|
|
139
|
+
deliver: this.handleMtaDelivery.bind(this)
|
|
140
|
+
},
|
|
141
|
+
processHandler: options.processHandler || {
|
|
142
|
+
deliver: this.handleProcessDelivery.bind(this)
|
|
143
|
+
},
|
|
144
|
+
globalRateLimit: options.globalRateLimit || 100, // 100 emails per minute
|
|
145
|
+
perPatternRateLimit: options.perPatternRateLimit || {},
|
|
146
|
+
processBounces: options.processBounces !== false, // Default to true
|
|
147
|
+
bounceHandler: options.bounceHandler || null,
|
|
148
|
+
onDeliveryStart: options.onDeliveryStart || (async () => {}),
|
|
149
|
+
onDeliverySuccess: options.onDeliverySuccess || (async () => {}),
|
|
150
|
+
onDeliveryFailed: options.onDeliveryFailed || (async () => {})
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Initialize statistics
|
|
154
|
+
this.stats = {
|
|
155
|
+
activeDeliveries: 0,
|
|
156
|
+
totalSuccessful: 0,
|
|
157
|
+
totalFailed: 0,
|
|
158
|
+
avgDeliveryTime: 0,
|
|
159
|
+
byMode: {
|
|
160
|
+
forward: {
|
|
161
|
+
successful: 0,
|
|
162
|
+
failed: 0
|
|
163
|
+
},
|
|
164
|
+
mta: {
|
|
165
|
+
successful: 0,
|
|
166
|
+
failed: 0
|
|
167
|
+
},
|
|
168
|
+
process: {
|
|
169
|
+
successful: 0,
|
|
170
|
+
failed: 0
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
rateLimiting: {
|
|
174
|
+
currentRate: 0,
|
|
175
|
+
globalLimit: this.options.globalRateLimit,
|
|
176
|
+
throttled: 0
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Set up event listeners
|
|
181
|
+
this.queue.on('itemsReady', this.processItems.bind(this));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Start the delivery system
|
|
186
|
+
*/
|
|
187
|
+
public async start(): Promise<void> {
|
|
188
|
+
logger.log('info', 'Starting MultiModeDeliverySystem');
|
|
189
|
+
|
|
190
|
+
if (this.running) {
|
|
191
|
+
logger.log('warn', 'MultiModeDeliverySystem is already running');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
this.running = true;
|
|
196
|
+
|
|
197
|
+
// Emit started event
|
|
198
|
+
this.emit('started');
|
|
199
|
+
logger.log('info', 'MultiModeDeliverySystem started successfully');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Stop the delivery system
|
|
204
|
+
*/
|
|
205
|
+
public async stop(): Promise<void> {
|
|
206
|
+
logger.log('info', 'Stopping MultiModeDeliverySystem');
|
|
207
|
+
|
|
208
|
+
if (!this.running) {
|
|
209
|
+
logger.log('warn', 'MultiModeDeliverySystem is already stopped');
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
this.running = false;
|
|
214
|
+
|
|
215
|
+
// Wait for active deliveries to complete
|
|
216
|
+
if (this.activeDeliveries.size > 0) {
|
|
217
|
+
logger.log('info', `Waiting for ${this.activeDeliveries.size} active deliveries to complete`);
|
|
218
|
+
|
|
219
|
+
// Wait for a maximum of 30 seconds
|
|
220
|
+
await new Promise<void>(resolve => {
|
|
221
|
+
const checkInterval = setInterval(() => {
|
|
222
|
+
if (this.activeDeliveries.size === 0) {
|
|
223
|
+
clearInterval(checkInterval);
|
|
224
|
+
resolve();
|
|
225
|
+
}
|
|
226
|
+
}, 1000);
|
|
227
|
+
|
|
228
|
+
// Force resolve after 30 seconds
|
|
229
|
+
setTimeout(() => {
|
|
230
|
+
clearInterval(checkInterval);
|
|
231
|
+
resolve();
|
|
232
|
+
}, 30000);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Emit stopped event
|
|
237
|
+
this.emit('stopped');
|
|
238
|
+
logger.log('info', 'MultiModeDeliverySystem stopped successfully');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Process ready items from the queue
|
|
243
|
+
* @param items Queue items ready for processing
|
|
244
|
+
*/
|
|
245
|
+
private async processItems(items: IQueueItem[]): Promise<void> {
|
|
246
|
+
if (!this.running) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Check if we're already at max concurrent deliveries
|
|
251
|
+
if (this.activeDeliveries.size >= this.options.concurrentDeliveries) {
|
|
252
|
+
logger.log('debug', `Already at max concurrent deliveries (${this.activeDeliveries.size})`);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Check rate limiting
|
|
257
|
+
if (this.checkRateLimit()) {
|
|
258
|
+
logger.log('debug', 'Rate limit exceeded, throttling deliveries');
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Calculate how many more deliveries we can start
|
|
263
|
+
const availableSlots = this.options.concurrentDeliveries - this.activeDeliveries.size;
|
|
264
|
+
const itemsToProcess = items.slice(0, availableSlots);
|
|
265
|
+
|
|
266
|
+
if (itemsToProcess.length === 0) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
logger.log('info', `Processing ${itemsToProcess.length} items for delivery`);
|
|
271
|
+
|
|
272
|
+
// Process each item
|
|
273
|
+
for (const item of itemsToProcess) {
|
|
274
|
+
// Mark as processing
|
|
275
|
+
await this.queue.markProcessing(item.id);
|
|
276
|
+
|
|
277
|
+
// Add to active deliveries
|
|
278
|
+
this.activeDeliveries.add(item.id);
|
|
279
|
+
this.stats.activeDeliveries = this.activeDeliveries.size;
|
|
280
|
+
|
|
281
|
+
// Deliver asynchronously
|
|
282
|
+
this.deliverItem(item).catch(err => {
|
|
283
|
+
logger.log('error', `Unhandled error in delivery: ${err.message}`);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Update statistics
|
|
288
|
+
this.emit('statsUpdated', this.stats);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Deliver an item from the queue
|
|
293
|
+
* @param item Queue item to deliver
|
|
294
|
+
*/
|
|
295
|
+
private async deliverItem(item: IQueueItem): Promise<void> {
|
|
296
|
+
const startTime = Date.now();
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
// Call delivery start hook
|
|
300
|
+
await this.options.onDeliveryStart(item);
|
|
301
|
+
|
|
302
|
+
// Emit delivery start event
|
|
303
|
+
this.emit('deliveryStart', item);
|
|
304
|
+
logger.log('info', `Starting delivery of item ${item.id}, mode: ${item.processingMode}`);
|
|
305
|
+
|
|
306
|
+
// Choose the appropriate handler based on mode
|
|
307
|
+
let result: any;
|
|
308
|
+
|
|
309
|
+
switch (item.processingMode) {
|
|
310
|
+
case 'forward':
|
|
311
|
+
result = await this.options.forwardHandler.deliver(item);
|
|
312
|
+
break;
|
|
313
|
+
|
|
314
|
+
case 'mta':
|
|
315
|
+
result = await this.options.deliveryHandler.deliver(item);
|
|
316
|
+
break;
|
|
317
|
+
|
|
318
|
+
case 'process':
|
|
319
|
+
result = await this.options.processHandler.deliver(item);
|
|
320
|
+
break;
|
|
321
|
+
|
|
322
|
+
default:
|
|
323
|
+
throw new Error(`Unknown processing mode: ${item.processingMode}`);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Mark as delivered
|
|
327
|
+
await this.queue.markDelivered(item.id);
|
|
328
|
+
|
|
329
|
+
// Update statistics
|
|
330
|
+
this.stats.totalSuccessful++;
|
|
331
|
+
this.stats.byMode[item.processingMode].successful++;
|
|
332
|
+
|
|
333
|
+
// Calculate delivery time
|
|
334
|
+
const deliveryTime = Date.now() - startTime;
|
|
335
|
+
this.deliveryTimes.push(deliveryTime);
|
|
336
|
+
this.updateDeliveryTimeStats();
|
|
337
|
+
|
|
338
|
+
// Call delivery success hook
|
|
339
|
+
await this.options.onDeliverySuccess(item, result);
|
|
340
|
+
|
|
341
|
+
// Emit delivery success event
|
|
342
|
+
this.emit('deliverySuccess', item, result);
|
|
343
|
+
logger.log('info', `Item ${item.id} delivered successfully in ${deliveryTime}ms`);
|
|
344
|
+
|
|
345
|
+
SecurityLogger.getInstance().logEvent({
|
|
346
|
+
level: SecurityLogLevel.INFO,
|
|
347
|
+
type: SecurityEventType.EMAIL_DELIVERY,
|
|
348
|
+
message: 'Email delivery successful',
|
|
349
|
+
details: {
|
|
350
|
+
itemId: item.id,
|
|
351
|
+
mode: item.processingMode,
|
|
352
|
+
routeName: item.route?.name || 'unknown',
|
|
353
|
+
deliveryTime
|
|
354
|
+
},
|
|
355
|
+
success: true
|
|
356
|
+
});
|
|
357
|
+
} catch (error: any) {
|
|
358
|
+
// Calculate delivery attempt time even for failures
|
|
359
|
+
const deliveryTime = Date.now() - startTime;
|
|
360
|
+
|
|
361
|
+
// Mark as failed
|
|
362
|
+
await this.queue.markFailed(item.id, error.message);
|
|
363
|
+
|
|
364
|
+
// Update statistics
|
|
365
|
+
this.stats.totalFailed++;
|
|
366
|
+
this.stats.byMode[item.processingMode].failed++;
|
|
367
|
+
|
|
368
|
+
// Call delivery failed hook
|
|
369
|
+
await this.options.onDeliveryFailed(item, error.message);
|
|
370
|
+
|
|
371
|
+
// Process as bounce if enabled and we have a bounce handler
|
|
372
|
+
if (this.options.processBounces && this.options.bounceHandler) {
|
|
373
|
+
try {
|
|
374
|
+
const email = item.processingResult as Email;
|
|
375
|
+
|
|
376
|
+
// Extract recipient and error message
|
|
377
|
+
// For multiple recipients, we'd need more sophisticated parsing
|
|
378
|
+
const recipient = email.to.length > 0 ? email.to[0] : '';
|
|
379
|
+
|
|
380
|
+
if (recipient) {
|
|
381
|
+
logger.log('info', `Processing delivery failure as bounce for recipient ${recipient}`);
|
|
382
|
+
|
|
383
|
+
// Process SMTP failure through bounce handler
|
|
384
|
+
await this.options.bounceHandler.processSmtpFailure(
|
|
385
|
+
recipient,
|
|
386
|
+
error.message,
|
|
387
|
+
{
|
|
388
|
+
sender: email.from,
|
|
389
|
+
originalEmailId: item.id,
|
|
390
|
+
headers: email.headers
|
|
391
|
+
}
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
logger.log('info', `Bounce record created for failed delivery to ${recipient}`);
|
|
395
|
+
}
|
|
396
|
+
} catch (bounceError) {
|
|
397
|
+
logger.log('error', `Failed to process bounce: ${bounceError.message}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Emit delivery failed event
|
|
402
|
+
this.emit('deliveryFailed', item, error);
|
|
403
|
+
logger.log('error', `Item ${item.id} delivery failed: ${error.message}`);
|
|
404
|
+
|
|
405
|
+
SecurityLogger.getInstance().logEvent({
|
|
406
|
+
level: SecurityLogLevel.ERROR,
|
|
407
|
+
type: SecurityEventType.EMAIL_DELIVERY,
|
|
408
|
+
message: 'Email delivery failed',
|
|
409
|
+
details: {
|
|
410
|
+
itemId: item.id,
|
|
411
|
+
mode: item.processingMode,
|
|
412
|
+
routeName: item.route?.name || 'unknown',
|
|
413
|
+
error: error.message,
|
|
414
|
+
deliveryTime
|
|
415
|
+
},
|
|
416
|
+
success: false
|
|
417
|
+
});
|
|
418
|
+
} finally {
|
|
419
|
+
// Remove from active deliveries
|
|
420
|
+
this.activeDeliveries.delete(item.id);
|
|
421
|
+
this.stats.activeDeliveries = this.activeDeliveries.size;
|
|
422
|
+
|
|
423
|
+
// Update statistics
|
|
424
|
+
this.emit('statsUpdated', this.stats);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Default handler for forward mode delivery
|
|
430
|
+
* @param item Queue item
|
|
431
|
+
*/
|
|
432
|
+
private async handleForwardDelivery(item: IQueueItem): Promise<any> {
|
|
433
|
+
logger.log('info', `Forward delivery for item ${item.id}`);
|
|
434
|
+
|
|
435
|
+
const email = item.processingResult as Email;
|
|
436
|
+
const route = item.route;
|
|
437
|
+
|
|
438
|
+
// Get target server information
|
|
439
|
+
const targetServer = route?.action.forward?.host;
|
|
440
|
+
const targetPort = route?.action.forward?.port || 25;
|
|
441
|
+
const useTls = false; // TLS configuration can be enhanced later
|
|
442
|
+
|
|
443
|
+
if (!targetServer) {
|
|
444
|
+
throw new Error('No target server configured for forward mode');
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
logger.log('info', `Forwarding email to ${targetServer}:${targetPort}, TLS: ${useTls}`);
|
|
448
|
+
|
|
449
|
+
try {
|
|
450
|
+
// Get SMTP client from email server if available
|
|
451
|
+
if (!this.emailServer) {
|
|
452
|
+
// Fall back to raw socket implementation if no email server
|
|
453
|
+
logger.log('warn', 'No email server available, falling back to raw socket implementation');
|
|
454
|
+
return this.handleForwardDeliveryLegacy(item);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Get SMTP client from UnifiedEmailServer
|
|
458
|
+
const smtpClient = this.emailServer.getSmtpClient(targetServer, targetPort);
|
|
459
|
+
|
|
460
|
+
// Apply DKIM signing if configured in the route
|
|
461
|
+
if (item.route?.action.options?.mtaOptions?.dkimSign) {
|
|
462
|
+
await this.applyDkimSigning(email, item.route.action.options.mtaOptions);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Send the email using SmtpClient
|
|
466
|
+
const result = await smtpClient.sendMail(email);
|
|
467
|
+
|
|
468
|
+
if (result.success) {
|
|
469
|
+
logger.log('info', `Email forwarded successfully to ${targetServer}:${targetPort}`);
|
|
470
|
+
|
|
471
|
+
return {
|
|
472
|
+
targetServer: targetServer,
|
|
473
|
+
targetPort: targetPort,
|
|
474
|
+
recipients: result.acceptedRecipients.length,
|
|
475
|
+
messageId: result.messageId,
|
|
476
|
+
rejectedRecipients: result.rejectedRecipients
|
|
477
|
+
};
|
|
478
|
+
} else {
|
|
479
|
+
throw new Error(result.error?.message || 'Failed to forward email');
|
|
480
|
+
}
|
|
481
|
+
} catch (error: any) {
|
|
482
|
+
logger.log('error', `Failed to forward email: ${error.message}`);
|
|
483
|
+
throw error;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Legacy forward delivery using raw sockets (fallback)
|
|
489
|
+
* @param item Queue item
|
|
490
|
+
*/
|
|
491
|
+
private async handleForwardDeliveryLegacy(item: IQueueItem): Promise<any> {
|
|
492
|
+
const email = item.processingResult as Email;
|
|
493
|
+
const route = item.route;
|
|
494
|
+
|
|
495
|
+
// Get target server information
|
|
496
|
+
const targetServer = route?.action.forward?.host;
|
|
497
|
+
const targetPort = route?.action.forward?.port || 25;
|
|
498
|
+
const useTls = false; // TLS configuration can be enhanced later
|
|
499
|
+
|
|
500
|
+
if (!targetServer) {
|
|
501
|
+
throw new Error('No target server configured for forward mode');
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Create a socket connection to the target server
|
|
505
|
+
const socket = new net.Socket();
|
|
506
|
+
|
|
507
|
+
// Set timeout
|
|
508
|
+
socket.setTimeout(this.options.socketTimeout);
|
|
509
|
+
|
|
510
|
+
try {
|
|
511
|
+
// Connect to the target server
|
|
512
|
+
await new Promise<void>((resolve, reject) => {
|
|
513
|
+
// Handle connection events
|
|
514
|
+
socket.on('connect', () => {
|
|
515
|
+
logger.log('debug', `Connected to ${targetServer}:${targetPort}`);
|
|
516
|
+
resolve();
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
socket.on('timeout', () => {
|
|
520
|
+
reject(new Error(`Connection timeout to ${targetServer}:${targetPort}`));
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
socket.on('error', (err) => {
|
|
524
|
+
reject(new Error(`Connection error to ${targetServer}:${targetPort}: ${err.message}`));
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
// Connect to the server
|
|
528
|
+
socket.connect({
|
|
529
|
+
host: targetServer,
|
|
530
|
+
port: targetPort
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
// Send EHLO
|
|
535
|
+
await this.smtpCommand(socket, `EHLO ${route?.action.options?.mtaOptions?.domain || 'localhost'}`);
|
|
536
|
+
|
|
537
|
+
// Start TLS if required
|
|
538
|
+
if (useTls) {
|
|
539
|
+
await this.smtpCommand(socket, 'STARTTLS');
|
|
540
|
+
|
|
541
|
+
// Upgrade to TLS
|
|
542
|
+
const tlsSocket = await this.upgradeTls(socket, targetServer);
|
|
543
|
+
|
|
544
|
+
// Send EHLO again after STARTTLS
|
|
545
|
+
await this.smtpCommand(tlsSocket, `EHLO ${route?.action.options?.mtaOptions?.domain || 'localhost'}`);
|
|
546
|
+
|
|
547
|
+
// Use tlsSocket for remaining commands
|
|
548
|
+
return this.completeSMTPExchange(tlsSocket, email, route);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Complete the SMTP exchange
|
|
552
|
+
return this.completeSMTPExchange(socket, email, route);
|
|
553
|
+
} catch (error: any) {
|
|
554
|
+
logger.log('error', `Failed to forward email: ${error.message}`);
|
|
555
|
+
|
|
556
|
+
// Close the connection
|
|
557
|
+
socket.destroy();
|
|
558
|
+
|
|
559
|
+
throw error;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Complete the SMTP exchange after connection and initial setup
|
|
565
|
+
* @param socket Network socket
|
|
566
|
+
* @param email Email to send
|
|
567
|
+
* @param rule Domain rule
|
|
568
|
+
*/
|
|
569
|
+
private async completeSMTPExchange(socket: net.Socket | tls.TLSSocket, email: Email, route: any): Promise<any> {
|
|
570
|
+
try {
|
|
571
|
+
// Authenticate if credentials provided
|
|
572
|
+
if (route?.action?.forward?.auth?.user && route?.action?.forward?.auth?.pass) {
|
|
573
|
+
// Send AUTH LOGIN
|
|
574
|
+
await this.smtpCommand(socket, 'AUTH LOGIN');
|
|
575
|
+
|
|
576
|
+
// Send username (base64)
|
|
577
|
+
const username = Buffer.from(route.action.forward.auth.user).toString('base64');
|
|
578
|
+
await this.smtpCommand(socket, username);
|
|
579
|
+
|
|
580
|
+
// Send password (base64)
|
|
581
|
+
const password = Buffer.from(route.action.forward.auth.pass).toString('base64');
|
|
582
|
+
await this.smtpCommand(socket, password);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Send MAIL FROM
|
|
586
|
+
await this.smtpCommand(socket, `MAIL FROM:<${email.from}>`);
|
|
587
|
+
|
|
588
|
+
// Send RCPT TO for each recipient
|
|
589
|
+
for (const recipient of email.getAllRecipients()) {
|
|
590
|
+
await this.smtpCommand(socket, `RCPT TO:<${recipient}>`);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// Send DATA
|
|
594
|
+
await this.smtpCommand(socket, 'DATA');
|
|
595
|
+
|
|
596
|
+
// Send email content (simplified)
|
|
597
|
+
const emailContent = await this.getFormattedEmail(email);
|
|
598
|
+
await this.smtpData(socket, emailContent);
|
|
599
|
+
|
|
600
|
+
// Send QUIT
|
|
601
|
+
await this.smtpCommand(socket, 'QUIT');
|
|
602
|
+
|
|
603
|
+
// Close the connection
|
|
604
|
+
socket.end();
|
|
605
|
+
|
|
606
|
+
logger.log('info', `Email forwarded successfully to ${route?.action?.forward?.host}:${route?.action?.forward?.port || 25}`);
|
|
607
|
+
|
|
608
|
+
return {
|
|
609
|
+
targetServer: route?.action?.forward?.host,
|
|
610
|
+
targetPort: route?.action?.forward?.port || 25,
|
|
611
|
+
recipients: email.getAllRecipients().length
|
|
612
|
+
};
|
|
613
|
+
} catch (error: any) {
|
|
614
|
+
logger.log('error', `Failed to forward email: ${error.message}`);
|
|
615
|
+
|
|
616
|
+
// Close the connection
|
|
617
|
+
socket.destroy();
|
|
618
|
+
|
|
619
|
+
throw error;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Default handler for MTA mode delivery
|
|
625
|
+
* @param item Queue item
|
|
626
|
+
*/
|
|
627
|
+
private async handleMtaDelivery(item: IQueueItem): Promise<any> {
|
|
628
|
+
logger.log('info', `MTA delivery for item ${item.id}`);
|
|
629
|
+
|
|
630
|
+
const email = item.processingResult as Email;
|
|
631
|
+
const route = item.route;
|
|
632
|
+
|
|
633
|
+
try {
|
|
634
|
+
// Apply DKIM signing if configured in the route
|
|
635
|
+
if (item.route?.action.options?.mtaOptions?.dkimSign) {
|
|
636
|
+
await this.applyDkimSigning(email, item.route.action.options.mtaOptions);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// In a full implementation, this would use the MTA service
|
|
640
|
+
// For now, we'll simulate a successful delivery
|
|
641
|
+
|
|
642
|
+
logger.log('info', `Email processed by MTA: ${email.subject} to ${email.getAllRecipients().join(', ')}`);
|
|
643
|
+
|
|
644
|
+
// Note: The MTA implementation would handle actual local delivery
|
|
645
|
+
|
|
646
|
+
// Simulate successful delivery
|
|
647
|
+
return {
|
|
648
|
+
recipients: email.getAllRecipients().length,
|
|
649
|
+
subject: email.subject,
|
|
650
|
+
dkimSigned: !!item.route?.action.options?.mtaOptions?.dkimSign
|
|
651
|
+
};
|
|
652
|
+
} catch (error: any) {
|
|
653
|
+
logger.log('error', `Failed to process email in MTA mode: ${error.message}`);
|
|
654
|
+
throw error;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Default handler for process mode delivery
|
|
660
|
+
* @param item Queue item
|
|
661
|
+
*/
|
|
662
|
+
private async handleProcessDelivery(item: IQueueItem): Promise<any> {
|
|
663
|
+
logger.log('info', `Process delivery for item ${item.id}`);
|
|
664
|
+
|
|
665
|
+
const email = item.processingResult as Email;
|
|
666
|
+
const route = item.route;
|
|
667
|
+
|
|
668
|
+
try {
|
|
669
|
+
// Apply content scanning if enabled
|
|
670
|
+
if (route?.action.options?.contentScanning && route?.action.options?.scanners && route.action.options.scanners.length > 0) {
|
|
671
|
+
logger.log('info', 'Performing content scanning');
|
|
672
|
+
|
|
673
|
+
// Apply each scanner
|
|
674
|
+
for (const scanner of route.action.options.scanners) {
|
|
675
|
+
switch (scanner.type) {
|
|
676
|
+
case 'spam':
|
|
677
|
+
logger.log('info', 'Scanning for spam content');
|
|
678
|
+
// Implement spam scanning
|
|
679
|
+
break;
|
|
680
|
+
|
|
681
|
+
case 'virus':
|
|
682
|
+
logger.log('info', 'Scanning for virus content');
|
|
683
|
+
// Implement virus scanning
|
|
684
|
+
break;
|
|
685
|
+
|
|
686
|
+
case 'attachment':
|
|
687
|
+
logger.log('info', 'Scanning attachments');
|
|
688
|
+
|
|
689
|
+
// Check for blocked extensions
|
|
690
|
+
if (scanner.blockedExtensions && scanner.blockedExtensions.length > 0) {
|
|
691
|
+
for (const attachment of email.attachments) {
|
|
692
|
+
const ext = this.getFileExtension(attachment.filename);
|
|
693
|
+
if (scanner.blockedExtensions.includes(ext)) {
|
|
694
|
+
if (scanner.action === 'reject') {
|
|
695
|
+
throw new Error(`Blocked attachment type: ${ext}`);
|
|
696
|
+
} else { // tag
|
|
697
|
+
email.addHeader('X-Attachment-Warning', `Potentially unsafe attachment: ${attachment.filename}`);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
break;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// Apply transformations if defined
|
|
708
|
+
if (route?.action.options?.transformations && route?.action.options?.transformations.length > 0) {
|
|
709
|
+
logger.log('info', 'Applying email transformations');
|
|
710
|
+
|
|
711
|
+
for (const transform of route.action.options.transformations) {
|
|
712
|
+
switch (transform.type) {
|
|
713
|
+
case 'addHeader':
|
|
714
|
+
if (transform.header && transform.value) {
|
|
715
|
+
email.addHeader(transform.header, transform.value);
|
|
716
|
+
}
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// Apply DKIM signing if configured (after all transformations)
|
|
723
|
+
if (item.route?.action.options?.mtaOptions?.dkimSign || item.route?.action.process?.dkim) {
|
|
724
|
+
await this.applyDkimSigning(email, item.route.action.options?.mtaOptions || {});
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
logger.log('info', `Email successfully processed in store-and-forward mode`);
|
|
728
|
+
|
|
729
|
+
// Simulate successful delivery
|
|
730
|
+
return {
|
|
731
|
+
recipients: email.getAllRecipients().length,
|
|
732
|
+
subject: email.subject,
|
|
733
|
+
scanned: !!route?.action.options?.contentScanning,
|
|
734
|
+
transformed: !!(route?.action.options?.transformations && route?.action.options?.transformations.length > 0),
|
|
735
|
+
dkimSigned: !!(item.route?.action.options?.mtaOptions?.dkimSign || item.route?.action.process?.dkim)
|
|
736
|
+
};
|
|
737
|
+
} catch (error: any) {
|
|
738
|
+
logger.log('error', `Failed to process email: ${error.message}`);
|
|
739
|
+
throw error;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Get file extension from filename
|
|
745
|
+
*/
|
|
746
|
+
private getFileExtension(filename: string): string {
|
|
747
|
+
return filename.substring(filename.lastIndexOf('.')).toLowerCase();
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Apply DKIM signing to an email
|
|
752
|
+
*/
|
|
753
|
+
private async applyDkimSigning(email: Email, mtaOptions: any): Promise<void> {
|
|
754
|
+
if (!this.emailServer) {
|
|
755
|
+
logger.log('warn', 'Cannot apply DKIM signing without email server reference');
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const domainName = mtaOptions.dkimOptions?.domainName || email.from.split('@')[1];
|
|
760
|
+
const keySelector = mtaOptions.dkimOptions?.keySelector || 'default';
|
|
761
|
+
|
|
762
|
+
try {
|
|
763
|
+
// Ensure DKIM keys exist for the domain
|
|
764
|
+
await this.emailServer.dkimCreator.handleDKIMKeysForDomain(domainName);
|
|
765
|
+
|
|
766
|
+
// Convert Email to raw format for signing
|
|
767
|
+
const rawEmail = email.toRFC822String();
|
|
768
|
+
|
|
769
|
+
// Sign the email
|
|
770
|
+
const signResult = await plugins.dkimSign(rawEmail, {
|
|
771
|
+
canonicalization: 'relaxed/relaxed',
|
|
772
|
+
algorithm: 'rsa-sha256',
|
|
773
|
+
signTime: new Date(),
|
|
774
|
+
signatureData: [
|
|
775
|
+
{
|
|
776
|
+
signingDomain: domainName,
|
|
777
|
+
selector: keySelector,
|
|
778
|
+
privateKey: (await this.emailServer.dkimCreator.readDKIMKeys(domainName)).privateKey,
|
|
779
|
+
algorithm: 'rsa-sha256',
|
|
780
|
+
canonicalization: 'relaxed/relaxed'
|
|
781
|
+
}
|
|
782
|
+
]
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
// Add the DKIM-Signature header to the email
|
|
786
|
+
if (signResult.signatures) {
|
|
787
|
+
email.addHeader('DKIM-Signature', signResult.signatures);
|
|
788
|
+
logger.log('info', `Successfully added DKIM signature for ${domainName}`);
|
|
789
|
+
}
|
|
790
|
+
} catch (error) {
|
|
791
|
+
logger.log('error', `Failed to apply DKIM signature: ${error.message}`);
|
|
792
|
+
// Don't throw - allow email to be sent without DKIM if signing fails
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Format email for SMTP transmission
|
|
798
|
+
* @param email Email to format
|
|
799
|
+
*/
|
|
800
|
+
private async getFormattedEmail(email: Email): Promise<string> {
|
|
801
|
+
// This is a simplified implementation
|
|
802
|
+
// In a full implementation, this would use proper MIME formatting
|
|
803
|
+
|
|
804
|
+
let content = '';
|
|
805
|
+
|
|
806
|
+
// Add headers
|
|
807
|
+
content += `From: ${email.from}\r\n`;
|
|
808
|
+
content += `To: ${email.to.join(', ')}\r\n`;
|
|
809
|
+
content += `Subject: ${email.subject}\r\n`;
|
|
810
|
+
|
|
811
|
+
// Add additional headers
|
|
812
|
+
for (const [name, value] of Object.entries(email.headers || {})) {
|
|
813
|
+
content += `${name}: ${value}\r\n`;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// Add content type for multipart
|
|
817
|
+
if (email.attachments && email.attachments.length > 0) {
|
|
818
|
+
const boundary = `----_=_NextPart_${Math.random().toString(36).substr(2)}`;
|
|
819
|
+
content += `MIME-Version: 1.0\r\n`;
|
|
820
|
+
content += `Content-Type: multipart/mixed; boundary="${boundary}"\r\n`;
|
|
821
|
+
content += `\r\n`;
|
|
822
|
+
|
|
823
|
+
// Add text part
|
|
824
|
+
content += `--${boundary}\r\n`;
|
|
825
|
+
content += `Content-Type: text/plain; charset="UTF-8"\r\n`;
|
|
826
|
+
content += `\r\n`;
|
|
827
|
+
content += `${email.text}\r\n`;
|
|
828
|
+
|
|
829
|
+
// Add HTML part if present
|
|
830
|
+
if (email.html) {
|
|
831
|
+
content += `--${boundary}\r\n`;
|
|
832
|
+
content += `Content-Type: text/html; charset="UTF-8"\r\n`;
|
|
833
|
+
content += `\r\n`;
|
|
834
|
+
content += `${email.html}\r\n`;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// Add attachments
|
|
838
|
+
for (const attachment of email.attachments) {
|
|
839
|
+
content += `--${boundary}\r\n`;
|
|
840
|
+
content += `Content-Type: ${attachment.contentType || 'application/octet-stream'}; name="${attachment.filename}"\r\n`;
|
|
841
|
+
content += `Content-Disposition: attachment; filename="${attachment.filename}"\r\n`;
|
|
842
|
+
content += `Content-Transfer-Encoding: base64\r\n`;
|
|
843
|
+
content += `\r\n`;
|
|
844
|
+
|
|
845
|
+
// Add base64 encoded content
|
|
846
|
+
const base64Content = attachment.content.toString('base64');
|
|
847
|
+
|
|
848
|
+
// Split into lines of 76 characters
|
|
849
|
+
for (let i = 0; i < base64Content.length; i += 76) {
|
|
850
|
+
content += base64Content.substring(i, i + 76) + '\r\n';
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// End boundary
|
|
855
|
+
content += `--${boundary}--\r\n`;
|
|
856
|
+
} else {
|
|
857
|
+
// Simple email with just text
|
|
858
|
+
content += `Content-Type: text/plain; charset="UTF-8"\r\n`;
|
|
859
|
+
content += `\r\n`;
|
|
860
|
+
content += `${email.text}\r\n`;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
return content;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Send SMTP command and wait for response
|
|
868
|
+
* @param socket Socket connection
|
|
869
|
+
* @param command SMTP command to send
|
|
870
|
+
*/
|
|
871
|
+
private async smtpCommand(socket: net.Socket, command: string): Promise<string> {
|
|
872
|
+
return new Promise<string>((resolve, reject) => {
|
|
873
|
+
const onData = (data: Buffer) => {
|
|
874
|
+
const response = data.toString().trim();
|
|
875
|
+
|
|
876
|
+
// Clean up listeners
|
|
877
|
+
socket.removeListener('data', onData);
|
|
878
|
+
socket.removeListener('error', onError);
|
|
879
|
+
socket.removeListener('timeout', onTimeout);
|
|
880
|
+
|
|
881
|
+
// Check response code
|
|
882
|
+
if (response.charAt(0) === '2' || response.charAt(0) === '3') {
|
|
883
|
+
resolve(response);
|
|
884
|
+
} else {
|
|
885
|
+
reject(new Error(`SMTP error: ${response}`));
|
|
886
|
+
}
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
const onError = (err: Error) => {
|
|
890
|
+
// Clean up listeners
|
|
891
|
+
socket.removeListener('data', onData);
|
|
892
|
+
socket.removeListener('error', onError);
|
|
893
|
+
socket.removeListener('timeout', onTimeout);
|
|
894
|
+
|
|
895
|
+
reject(err);
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
const onTimeout = () => {
|
|
899
|
+
// Clean up listeners
|
|
900
|
+
socket.removeListener('data', onData);
|
|
901
|
+
socket.removeListener('error', onError);
|
|
902
|
+
socket.removeListener('timeout', onTimeout);
|
|
903
|
+
|
|
904
|
+
reject(new Error('SMTP command timeout'));
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
// Set up listeners
|
|
908
|
+
socket.once('data', onData);
|
|
909
|
+
socket.once('error', onError);
|
|
910
|
+
socket.once('timeout', onTimeout);
|
|
911
|
+
|
|
912
|
+
// Send command
|
|
913
|
+
socket.write(command + '\r\n');
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* Send SMTP DATA command with content
|
|
919
|
+
* @param socket Socket connection
|
|
920
|
+
* @param data Email content to send
|
|
921
|
+
*/
|
|
922
|
+
private async smtpData(socket: net.Socket, data: string): Promise<string> {
|
|
923
|
+
return new Promise<string>((resolve, reject) => {
|
|
924
|
+
const onData = (responseData: Buffer) => {
|
|
925
|
+
const response = responseData.toString().trim();
|
|
926
|
+
|
|
927
|
+
// Clean up listeners
|
|
928
|
+
socket.removeListener('data', onData);
|
|
929
|
+
socket.removeListener('error', onError);
|
|
930
|
+
socket.removeListener('timeout', onTimeout);
|
|
931
|
+
|
|
932
|
+
// Check response code
|
|
933
|
+
if (response.charAt(0) === '2') {
|
|
934
|
+
resolve(response);
|
|
935
|
+
} else {
|
|
936
|
+
reject(new Error(`SMTP error: ${response}`));
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
|
|
940
|
+
const onError = (err: Error) => {
|
|
941
|
+
// Clean up listeners
|
|
942
|
+
socket.removeListener('data', onData);
|
|
943
|
+
socket.removeListener('error', onError);
|
|
944
|
+
socket.removeListener('timeout', onTimeout);
|
|
945
|
+
|
|
946
|
+
reject(err);
|
|
947
|
+
};
|
|
948
|
+
|
|
949
|
+
const onTimeout = () => {
|
|
950
|
+
// Clean up listeners
|
|
951
|
+
socket.removeListener('data', onData);
|
|
952
|
+
socket.removeListener('error', onError);
|
|
953
|
+
socket.removeListener('timeout', onTimeout);
|
|
954
|
+
|
|
955
|
+
reject(new Error('SMTP data timeout'));
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
// Set up listeners
|
|
959
|
+
socket.once('data', onData);
|
|
960
|
+
socket.once('error', onError);
|
|
961
|
+
socket.once('timeout', onTimeout);
|
|
962
|
+
|
|
963
|
+
// Send data and end with CRLF.CRLF
|
|
964
|
+
socket.write(data + '\r\n.\r\n');
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Upgrade socket to TLS
|
|
970
|
+
* @param socket Socket connection
|
|
971
|
+
* @param hostname Target hostname for TLS
|
|
972
|
+
*/
|
|
973
|
+
private async upgradeTls(socket: net.Socket, hostname: string): Promise<tls.TLSSocket> {
|
|
974
|
+
return new Promise<tls.TLSSocket>((resolve, reject) => {
|
|
975
|
+
const tlsOptions: tls.ConnectionOptions = {
|
|
976
|
+
socket,
|
|
977
|
+
servername: hostname,
|
|
978
|
+
rejectUnauthorized: this.options.verifyCertificates,
|
|
979
|
+
minVersion: this.options.tlsMinVersion as tls.SecureVersion
|
|
980
|
+
};
|
|
981
|
+
|
|
982
|
+
const tlsSocket = tls.connect(tlsOptions);
|
|
983
|
+
|
|
984
|
+
tlsSocket.once('secureConnect', () => {
|
|
985
|
+
resolve(tlsSocket);
|
|
986
|
+
});
|
|
987
|
+
|
|
988
|
+
tlsSocket.once('error', (err) => {
|
|
989
|
+
reject(new Error(`TLS error: ${err.message}`));
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
tlsSocket.setTimeout(this.options.socketTimeout);
|
|
993
|
+
|
|
994
|
+
tlsSocket.once('timeout', () => {
|
|
995
|
+
reject(new Error('TLS connection timeout'));
|
|
996
|
+
});
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Update delivery time statistics
|
|
1002
|
+
*/
|
|
1003
|
+
private updateDeliveryTimeStats(): void {
|
|
1004
|
+
if (this.deliveryTimes.length === 0) return;
|
|
1005
|
+
|
|
1006
|
+
// Keep only the last 1000 delivery times
|
|
1007
|
+
if (this.deliveryTimes.length > 1000) {
|
|
1008
|
+
this.deliveryTimes = this.deliveryTimes.slice(-1000);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
// Calculate average
|
|
1012
|
+
const sum = this.deliveryTimes.reduce((acc, time) => acc + time, 0);
|
|
1013
|
+
this.stats.avgDeliveryTime = sum / this.deliveryTimes.length;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* Check if rate limit is exceeded
|
|
1018
|
+
* @returns True if rate limited, false otherwise
|
|
1019
|
+
*/
|
|
1020
|
+
private checkRateLimit(): boolean {
|
|
1021
|
+
const now = Date.now();
|
|
1022
|
+
const elapsed = now - this.rateLimitLastCheck;
|
|
1023
|
+
|
|
1024
|
+
// Reset counter if more than a minute has passed
|
|
1025
|
+
if (elapsed >= 60000) {
|
|
1026
|
+
this.rateLimitLastCheck = now;
|
|
1027
|
+
this.rateLimitCounter = 0;
|
|
1028
|
+
this.throttled = false;
|
|
1029
|
+
this.stats.rateLimiting.currentRate = 0;
|
|
1030
|
+
return false;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// Check if we're already throttled
|
|
1034
|
+
if (this.throttled) {
|
|
1035
|
+
return true;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// Increment counter
|
|
1039
|
+
this.rateLimitCounter++;
|
|
1040
|
+
|
|
1041
|
+
// Calculate current rate (emails per minute)
|
|
1042
|
+
const rate = (this.rateLimitCounter / elapsed) * 60000;
|
|
1043
|
+
this.stats.rateLimiting.currentRate = rate;
|
|
1044
|
+
|
|
1045
|
+
// Check if rate limit is exceeded
|
|
1046
|
+
if (rate > this.options.globalRateLimit) {
|
|
1047
|
+
this.throttled = true;
|
|
1048
|
+
this.stats.rateLimiting.throttled++;
|
|
1049
|
+
|
|
1050
|
+
// Schedule throttle reset
|
|
1051
|
+
const resetDelay = 60000 - elapsed;
|
|
1052
|
+
setTimeout(() => {
|
|
1053
|
+
this.throttled = false;
|
|
1054
|
+
this.rateLimitLastCheck = Date.now();
|
|
1055
|
+
this.rateLimitCounter = 0;
|
|
1056
|
+
this.stats.rateLimiting.currentRate = 0;
|
|
1057
|
+
}, resetDelay);
|
|
1058
|
+
|
|
1059
|
+
return true;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
return false;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* Update delivery options
|
|
1067
|
+
* @param options New options
|
|
1068
|
+
*/
|
|
1069
|
+
public updateOptions(options: Partial<IMultiModeDeliveryOptions>): void {
|
|
1070
|
+
this.options = {
|
|
1071
|
+
...this.options,
|
|
1072
|
+
...options
|
|
1073
|
+
};
|
|
1074
|
+
|
|
1075
|
+
// Update rate limit statistics
|
|
1076
|
+
if (options.globalRateLimit) {
|
|
1077
|
+
this.stats.rateLimiting.globalLimit = options.globalRateLimit;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
logger.log('info', 'MultiModeDeliverySystem options updated');
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* Get delivery statistics
|
|
1085
|
+
*/
|
|
1086
|
+
public getStats(): IDeliveryStats {
|
|
1087
|
+
return { ...this.stats };
|
|
1088
|
+
}
|
|
1089
|
+
}
|