@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,896 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as paths from '../paths.js';
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
import { LRUCache } from 'lru-cache';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents a single stage in the warmup process
|
|
8
|
+
*/
|
|
9
|
+
export interface IWarmupStage {
|
|
10
|
+
/** Stage number (1-based) */
|
|
11
|
+
stage: number;
|
|
12
|
+
/** Maximum daily email volume for this stage */
|
|
13
|
+
maxDailyVolume: number;
|
|
14
|
+
/** Duration of this stage in days */
|
|
15
|
+
durationDays: number;
|
|
16
|
+
/** Target engagement metrics for this stage */
|
|
17
|
+
targetMetrics?: {
|
|
18
|
+
/** Minimum open rate (percentage) */
|
|
19
|
+
minOpenRate?: number;
|
|
20
|
+
/** Maximum bounce rate (percentage) */
|
|
21
|
+
maxBounceRate?: number;
|
|
22
|
+
/** Maximum spam complaint rate (percentage) */
|
|
23
|
+
maxComplaintRate?: number;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Configuration for IP warmup process
|
|
29
|
+
*/
|
|
30
|
+
export interface IIPWarmupConfig {
|
|
31
|
+
/** Whether the warmup is enabled */
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
/** List of IP addresses to warm up */
|
|
34
|
+
ipAddresses?: string[];
|
|
35
|
+
/** Target domains to warm up (e.g. your sending domains) */
|
|
36
|
+
targetDomains?: string[];
|
|
37
|
+
/** Warmup stages defining volume and duration */
|
|
38
|
+
stages?: IWarmupStage[];
|
|
39
|
+
/** Date when warmup process started */
|
|
40
|
+
startDate?: Date;
|
|
41
|
+
/** Default hourly distribution for sending (percentage of daily volume per hour) */
|
|
42
|
+
hourlyDistribution?: number[];
|
|
43
|
+
/** Whether to automatically advance stages based on metrics */
|
|
44
|
+
autoAdvanceStages?: boolean;
|
|
45
|
+
/** Whether to suspend warmup if metrics decline */
|
|
46
|
+
suspendOnMetricDecline?: boolean;
|
|
47
|
+
/** Percentage of traffic to send through fallback provider during warmup */
|
|
48
|
+
fallbackPercentage?: number;
|
|
49
|
+
/** Whether to prioritize engaged subscribers during warmup */
|
|
50
|
+
prioritizeEngagedSubscribers?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Status for a specific IP's warmup process
|
|
55
|
+
*/
|
|
56
|
+
export interface IIPWarmupStatus {
|
|
57
|
+
/** IP address being warmed up */
|
|
58
|
+
ipAddress: string;
|
|
59
|
+
/** Current warmup stage */
|
|
60
|
+
currentStage: number;
|
|
61
|
+
/** Start date of the warmup process */
|
|
62
|
+
startDate: Date;
|
|
63
|
+
/** Start date of the current stage */
|
|
64
|
+
currentStageStartDate: Date;
|
|
65
|
+
/** Target completion date for entire warmup */
|
|
66
|
+
targetCompletionDate: Date;
|
|
67
|
+
/** Daily volume allocation for current stage */
|
|
68
|
+
currentDailyAllocation: number;
|
|
69
|
+
/** Emails sent in current stage */
|
|
70
|
+
sentInCurrentStage: number;
|
|
71
|
+
/** Total emails sent during warmup process */
|
|
72
|
+
totalSent: number;
|
|
73
|
+
/** Whether the warmup is currently active */
|
|
74
|
+
isActive: boolean;
|
|
75
|
+
/** Daily statistics for the past week */
|
|
76
|
+
dailyStats: Array<{
|
|
77
|
+
/** Date of the statistics */
|
|
78
|
+
date: string;
|
|
79
|
+
/** Number of emails sent */
|
|
80
|
+
sent: number;
|
|
81
|
+
/** Number of emails opened */
|
|
82
|
+
opened: number;
|
|
83
|
+
/** Number of bounces */
|
|
84
|
+
bounces: number;
|
|
85
|
+
/** Number of spam complaints */
|
|
86
|
+
complaints: number;
|
|
87
|
+
}>;
|
|
88
|
+
/** Current metrics */
|
|
89
|
+
metrics: {
|
|
90
|
+
/** Open rate percentage */
|
|
91
|
+
openRate: number;
|
|
92
|
+
/** Bounce rate percentage */
|
|
93
|
+
bounceRate: number;
|
|
94
|
+
/** Complaint rate percentage */
|
|
95
|
+
complaintRate: number;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Defines methods for a policy used to allocate emails to different IPs
|
|
101
|
+
*/
|
|
102
|
+
export interface IIPAllocationPolicy {
|
|
103
|
+
/** Name of the policy */
|
|
104
|
+
name: string;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Allocate an IP address for sending an email
|
|
108
|
+
* @param availableIPs List of available IP addresses
|
|
109
|
+
* @param emailInfo Information about the email being sent
|
|
110
|
+
* @returns The IP to use, or null if no IP is available
|
|
111
|
+
*/
|
|
112
|
+
allocateIP(
|
|
113
|
+
availableIPs: Array<{ ip: string; priority: number; capacity: number }>,
|
|
114
|
+
emailInfo: {
|
|
115
|
+
from: string;
|
|
116
|
+
to: string[];
|
|
117
|
+
domain: string;
|
|
118
|
+
isTransactional: boolean;
|
|
119
|
+
isWarmup: boolean;
|
|
120
|
+
}
|
|
121
|
+
): string | null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Default IP warmup configuration with industry standard stages
|
|
126
|
+
*/
|
|
127
|
+
const DEFAULT_WARMUP_CONFIG: Required<IIPWarmupConfig> = {
|
|
128
|
+
enabled: true,
|
|
129
|
+
ipAddresses: [],
|
|
130
|
+
targetDomains: [],
|
|
131
|
+
stages: [
|
|
132
|
+
{ stage: 1, maxDailyVolume: 50, durationDays: 2, targetMetrics: { maxBounceRate: 8, minOpenRate: 15 } },
|
|
133
|
+
{ stage: 2, maxDailyVolume: 100, durationDays: 2, targetMetrics: { maxBounceRate: 7, minOpenRate: 18 } },
|
|
134
|
+
{ stage: 3, maxDailyVolume: 500, durationDays: 3, targetMetrics: { maxBounceRate: 6, minOpenRate: 20 } },
|
|
135
|
+
{ stage: 4, maxDailyVolume: 1000, durationDays: 3, targetMetrics: { maxBounceRate: 5, minOpenRate: 20 } },
|
|
136
|
+
{ stage: 5, maxDailyVolume: 5000, durationDays: 5, targetMetrics: { maxBounceRate: 3, minOpenRate: 22 } },
|
|
137
|
+
{ stage: 6, maxDailyVolume: 10000, durationDays: 5, targetMetrics: { maxBounceRate: 2, minOpenRate: 25 } },
|
|
138
|
+
{ stage: 7, maxDailyVolume: 20000, durationDays: 5, targetMetrics: { maxBounceRate: 1, minOpenRate: 25 } },
|
|
139
|
+
{ stage: 8, maxDailyVolume: 50000, durationDays: 5, targetMetrics: { maxBounceRate: 1, minOpenRate: 25 } },
|
|
140
|
+
],
|
|
141
|
+
startDate: new Date(),
|
|
142
|
+
// Default hourly distribution (percentage per hour, sums to 100%)
|
|
143
|
+
hourlyDistribution: [
|
|
144
|
+
1, 1, 1, 1, 1, 2, 3, 5, 7, 8, 10, 11,
|
|
145
|
+
10, 9, 8, 6, 5, 4, 3, 2, 1, 1, 1, 0
|
|
146
|
+
],
|
|
147
|
+
autoAdvanceStages: true,
|
|
148
|
+
suspendOnMetricDecline: true,
|
|
149
|
+
fallbackPercentage: 50,
|
|
150
|
+
prioritizeEngagedSubscribers: true
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Manages the IP warming process for new sending IPs
|
|
155
|
+
*/
|
|
156
|
+
export class IPWarmupManager {
|
|
157
|
+
private static instance: IPWarmupManager;
|
|
158
|
+
private config: Required<IIPWarmupConfig>;
|
|
159
|
+
private warmupStatuses: Map<string, IIPWarmupStatus> = new Map();
|
|
160
|
+
private dailySendCounts: Map<string, number> = new Map();
|
|
161
|
+
private hourlySendCounts: Map<string, number[]> = new Map();
|
|
162
|
+
private isInitialized: boolean = false;
|
|
163
|
+
private allocationPolicies: Map<string, IIPAllocationPolicy> = new Map();
|
|
164
|
+
private activePolicy: string = 'balanced';
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Constructor for IPWarmupManager
|
|
168
|
+
* @param config Warmup configuration
|
|
169
|
+
*/
|
|
170
|
+
constructor(config: IIPWarmupConfig = {}) {
|
|
171
|
+
this.config = {
|
|
172
|
+
...DEFAULT_WARMUP_CONFIG,
|
|
173
|
+
...config,
|
|
174
|
+
stages: config.stages || [...DEFAULT_WARMUP_CONFIG.stages]
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Register default allocation policies
|
|
178
|
+
this.registerAllocationPolicy('balanced', new BalancedAllocationPolicy());
|
|
179
|
+
this.registerAllocationPolicy('roundRobin', new RoundRobinAllocationPolicy());
|
|
180
|
+
this.registerAllocationPolicy('dedicated', new DedicatedDomainPolicy());
|
|
181
|
+
|
|
182
|
+
this.initialize();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get the singleton instance of IPWarmupManager
|
|
187
|
+
* @param config Warmup configuration
|
|
188
|
+
* @returns Singleton instance
|
|
189
|
+
*/
|
|
190
|
+
public static getInstance(config: IIPWarmupConfig = {}): IPWarmupManager {
|
|
191
|
+
if (!IPWarmupManager.instance) {
|
|
192
|
+
IPWarmupManager.instance = new IPWarmupManager(config);
|
|
193
|
+
}
|
|
194
|
+
return IPWarmupManager.instance;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Initialize the warmup manager
|
|
199
|
+
*/
|
|
200
|
+
private initialize(): void {
|
|
201
|
+
if (this.isInitialized) return;
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
// Load warmup statuses from storage
|
|
205
|
+
this.loadWarmupStatuses();
|
|
206
|
+
|
|
207
|
+
// Initialize any new IPs that might have been added to config
|
|
208
|
+
for (const ip of this.config.ipAddresses) {
|
|
209
|
+
if (!this.warmupStatuses.has(ip)) {
|
|
210
|
+
this.initializeIPWarmup(ip);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Initialize daily and hourly counters
|
|
215
|
+
const today = new Date().toISOString().split('T')[0];
|
|
216
|
+
for (const ip of this.config.ipAddresses) {
|
|
217
|
+
this.dailySendCounts.set(ip, 0);
|
|
218
|
+
this.hourlySendCounts.set(ip, Array(24).fill(0));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Schedule daily reset of counters
|
|
222
|
+
this.scheduleDailyReset();
|
|
223
|
+
|
|
224
|
+
// Schedule daily evaluation of warmup progress
|
|
225
|
+
this.scheduleDailyEvaluation();
|
|
226
|
+
|
|
227
|
+
this.isInitialized = true;
|
|
228
|
+
logger.log('info', `IP Warmup Manager initialized with ${this.config.ipAddresses.length} IPs`);
|
|
229
|
+
} catch (error) {
|
|
230
|
+
logger.log('error', `Failed to initialize IP Warmup Manager: ${error.message}`, {
|
|
231
|
+
stack: error.stack
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Initialize warmup status for a new IP address
|
|
238
|
+
* @param ipAddress IP address to initialize
|
|
239
|
+
*/
|
|
240
|
+
private initializeIPWarmup(ipAddress: string): void {
|
|
241
|
+
const startDate = new Date();
|
|
242
|
+
let targetCompletionDate = new Date(startDate);
|
|
243
|
+
|
|
244
|
+
// Calculate target completion date based on stages
|
|
245
|
+
let totalDays = 0;
|
|
246
|
+
for (const stage of this.config.stages) {
|
|
247
|
+
totalDays += stage.durationDays;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
targetCompletionDate.setDate(targetCompletionDate.getDate() + totalDays);
|
|
251
|
+
|
|
252
|
+
const warmupStatus: IIPWarmupStatus = {
|
|
253
|
+
ipAddress,
|
|
254
|
+
currentStage: 1,
|
|
255
|
+
startDate,
|
|
256
|
+
currentStageStartDate: new Date(),
|
|
257
|
+
targetCompletionDate,
|
|
258
|
+
currentDailyAllocation: this.config.stages[0].maxDailyVolume,
|
|
259
|
+
sentInCurrentStage: 0,
|
|
260
|
+
totalSent: 0,
|
|
261
|
+
isActive: true,
|
|
262
|
+
dailyStats: [],
|
|
263
|
+
metrics: {
|
|
264
|
+
openRate: 0,
|
|
265
|
+
bounceRate: 0,
|
|
266
|
+
complaintRate: 0
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
this.warmupStatuses.set(ipAddress, warmupStatus);
|
|
271
|
+
this.saveWarmupStatuses();
|
|
272
|
+
|
|
273
|
+
logger.log('info', `Initialized warmup for IP ${ipAddress}`, {
|
|
274
|
+
currentStage: 1,
|
|
275
|
+
targetCompletion: targetCompletionDate.toISOString().split('T')[0]
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Schedule daily reset of send counters
|
|
281
|
+
*/
|
|
282
|
+
private scheduleDailyReset(): void {
|
|
283
|
+
// Calculate time until midnight
|
|
284
|
+
const now = new Date();
|
|
285
|
+
const tomorrow = new Date(now);
|
|
286
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
287
|
+
tomorrow.setHours(0, 0, 0, 0);
|
|
288
|
+
|
|
289
|
+
const timeUntilMidnight = tomorrow.getTime() - now.getTime();
|
|
290
|
+
|
|
291
|
+
// Schedule reset
|
|
292
|
+
setTimeout(() => {
|
|
293
|
+
this.resetDailyCounts();
|
|
294
|
+
// Reschedule for next day
|
|
295
|
+
this.scheduleDailyReset();
|
|
296
|
+
}, timeUntilMidnight);
|
|
297
|
+
|
|
298
|
+
logger.log('info', `Scheduled daily counter reset in ${Math.floor(timeUntilMidnight / 60000)} minutes`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Reset daily send counters
|
|
303
|
+
*/
|
|
304
|
+
private resetDailyCounts(): void {
|
|
305
|
+
for (const ip of this.config.ipAddresses) {
|
|
306
|
+
// Save yesterday's count to history before resetting
|
|
307
|
+
const status = this.warmupStatuses.get(ip);
|
|
308
|
+
if (status) {
|
|
309
|
+
const yesterday = new Date();
|
|
310
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
311
|
+
|
|
312
|
+
// Update daily stats with yesterday's data
|
|
313
|
+
const sentCount = this.dailySendCounts.get(ip) || 0;
|
|
314
|
+
status.dailyStats.push({
|
|
315
|
+
date: yesterday.toISOString().split('T')[0],
|
|
316
|
+
sent: sentCount,
|
|
317
|
+
opened: Math.floor(sentCount * status.metrics.openRate / 100),
|
|
318
|
+
bounces: Math.floor(sentCount * status.metrics.bounceRate / 100),
|
|
319
|
+
complaints: Math.floor(sentCount * status.metrics.complaintRate / 100)
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Keep only the last 7 days of stats
|
|
323
|
+
if (status.dailyStats.length > 7) {
|
|
324
|
+
status.dailyStats.shift();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Reset counters for today
|
|
329
|
+
this.dailySendCounts.set(ip, 0);
|
|
330
|
+
this.hourlySendCounts.set(ip, Array(24).fill(0));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Save updated statuses
|
|
334
|
+
this.saveWarmupStatuses();
|
|
335
|
+
|
|
336
|
+
logger.log('info', 'Daily send counters reset');
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Schedule daily evaluation of warmup progress
|
|
341
|
+
*/
|
|
342
|
+
private scheduleDailyEvaluation(): void {
|
|
343
|
+
// Calculate time until 1 AM (do evaluation after midnight)
|
|
344
|
+
const now = new Date();
|
|
345
|
+
const evaluationTime = new Date(now);
|
|
346
|
+
evaluationTime.setDate(evaluationTime.getDate() + 1);
|
|
347
|
+
evaluationTime.setHours(1, 0, 0, 0);
|
|
348
|
+
|
|
349
|
+
const timeUntilEvaluation = evaluationTime.getTime() - now.getTime();
|
|
350
|
+
|
|
351
|
+
// Schedule evaluation
|
|
352
|
+
setTimeout(() => {
|
|
353
|
+
this.evaluateWarmupProgress();
|
|
354
|
+
// Reschedule for next day
|
|
355
|
+
this.scheduleDailyEvaluation();
|
|
356
|
+
}, timeUntilEvaluation);
|
|
357
|
+
|
|
358
|
+
logger.log('info', `Scheduled daily warmup evaluation in ${Math.floor(timeUntilEvaluation / 60000)} minutes`);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Evaluate warmup progress and possibly advance stages
|
|
363
|
+
*/
|
|
364
|
+
private evaluateWarmupProgress(): void {
|
|
365
|
+
if (!this.config.autoAdvanceStages) {
|
|
366
|
+
logger.log('info', 'Auto-advance stages is disabled, skipping evaluation');
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Convert entries to array for compatibility with older JS versions
|
|
371
|
+
Array.from(this.warmupStatuses.entries()).forEach(([ip, status]) => {
|
|
372
|
+
if (!status.isActive) return;
|
|
373
|
+
|
|
374
|
+
// Check if current stage duration has elapsed
|
|
375
|
+
const currentStage = this.config.stages[status.currentStage - 1];
|
|
376
|
+
const now = new Date();
|
|
377
|
+
const daysSinceStageStart = Math.floor(
|
|
378
|
+
(now.getTime() - status.currentStageStartDate.getTime()) / (24 * 60 * 60 * 1000)
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
if (daysSinceStageStart >= currentStage.durationDays) {
|
|
382
|
+
// Check if metrics meet requirements for advancing
|
|
383
|
+
const metricsOK = this.checkStageMetrics(status, currentStage);
|
|
384
|
+
|
|
385
|
+
if (metricsOK) {
|
|
386
|
+
// Advance to next stage if not at the final stage
|
|
387
|
+
if (status.currentStage < this.config.stages.length) {
|
|
388
|
+
this.advanceToNextStage(ip);
|
|
389
|
+
} else {
|
|
390
|
+
logger.log('info', `IP ${ip} has completed the warmup process`);
|
|
391
|
+
}
|
|
392
|
+
} else if (this.config.suspendOnMetricDecline) {
|
|
393
|
+
// Suspend warmup if metrics don't meet requirements
|
|
394
|
+
status.isActive = false;
|
|
395
|
+
logger.log('warn', `Suspended warmup for IP ${ip} due to poor metrics`, {
|
|
396
|
+
openRate: status.metrics.openRate,
|
|
397
|
+
bounceRate: status.metrics.bounceRate,
|
|
398
|
+
complaintRate: status.metrics.complaintRate
|
|
399
|
+
});
|
|
400
|
+
} else {
|
|
401
|
+
// Extend current stage if metrics don't meet requirements
|
|
402
|
+
logger.log('info', `Extending stage ${status.currentStage} for IP ${ip} due to metrics not meeting requirements`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Save updated statuses
|
|
408
|
+
this.saveWarmupStatuses();
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Check if the current metrics meet the requirements for the stage
|
|
413
|
+
* @param status Warmup status to check
|
|
414
|
+
* @param stage Stage to check against
|
|
415
|
+
* @returns Whether metrics meet requirements
|
|
416
|
+
*/
|
|
417
|
+
private checkStageMetrics(status: IIPWarmupStatus, stage: IWarmupStage): boolean {
|
|
418
|
+
// If no target metrics specified, assume met
|
|
419
|
+
if (!stage.targetMetrics) return true;
|
|
420
|
+
|
|
421
|
+
const metrics = status.metrics;
|
|
422
|
+
let meetsRequirements = true;
|
|
423
|
+
|
|
424
|
+
// Check each metric against requirements
|
|
425
|
+
if (stage.targetMetrics.minOpenRate !== undefined &&
|
|
426
|
+
metrics.openRate < stage.targetMetrics.minOpenRate) {
|
|
427
|
+
meetsRequirements = false;
|
|
428
|
+
logger.log('info', `Open rate ${metrics.openRate}% below target ${stage.targetMetrics.minOpenRate}% for IP ${status.ipAddress}`);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (stage.targetMetrics.maxBounceRate !== undefined &&
|
|
432
|
+
metrics.bounceRate > stage.targetMetrics.maxBounceRate) {
|
|
433
|
+
meetsRequirements = false;
|
|
434
|
+
logger.log('info', `Bounce rate ${metrics.bounceRate}% above target ${stage.targetMetrics.maxBounceRate}% for IP ${status.ipAddress}`);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (stage.targetMetrics.maxComplaintRate !== undefined &&
|
|
438
|
+
metrics.complaintRate > stage.targetMetrics.maxComplaintRate) {
|
|
439
|
+
meetsRequirements = false;
|
|
440
|
+
logger.log('info', `Complaint rate ${metrics.complaintRate}% above target ${stage.targetMetrics.maxComplaintRate}% for IP ${status.ipAddress}`);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return meetsRequirements;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Advance IP to the next warmup stage
|
|
448
|
+
* @param ipAddress IP address to advance
|
|
449
|
+
*/
|
|
450
|
+
private advanceToNextStage(ipAddress: string): void {
|
|
451
|
+
const status = this.warmupStatuses.get(ipAddress);
|
|
452
|
+
if (!status) return;
|
|
453
|
+
|
|
454
|
+
// Store metrics for the completed stage
|
|
455
|
+
const completedStage = status.currentStage;
|
|
456
|
+
|
|
457
|
+
// Advance to next stage
|
|
458
|
+
status.currentStage++;
|
|
459
|
+
status.currentStageStartDate = new Date();
|
|
460
|
+
status.sentInCurrentStage = 0;
|
|
461
|
+
|
|
462
|
+
// Update allocation
|
|
463
|
+
const newStage = this.config.stages[status.currentStage - 1];
|
|
464
|
+
status.currentDailyAllocation = newStage.maxDailyVolume;
|
|
465
|
+
|
|
466
|
+
logger.log('info', `Advanced IP ${ipAddress} to warmup stage ${status.currentStage}`, {
|
|
467
|
+
previousStage: completedStage,
|
|
468
|
+
newDailyLimit: status.currentDailyAllocation,
|
|
469
|
+
durationDays: newStage.durationDays
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Get warmup status for all IPs or a specific IP
|
|
475
|
+
* @param ipAddress Optional specific IP to get status for
|
|
476
|
+
* @returns Warmup status information
|
|
477
|
+
*/
|
|
478
|
+
public getWarmupStatus(ipAddress?: string): IIPWarmupStatus | Map<string, IIPWarmupStatus> {
|
|
479
|
+
if (ipAddress) {
|
|
480
|
+
return this.warmupStatuses.get(ipAddress);
|
|
481
|
+
}
|
|
482
|
+
return this.warmupStatuses;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Add a new IP address to the warmup process
|
|
487
|
+
* @param ipAddress IP address to add
|
|
488
|
+
*/
|
|
489
|
+
public addIPToWarmup(ipAddress: string): void {
|
|
490
|
+
if (this.config.ipAddresses.includes(ipAddress)) {
|
|
491
|
+
logger.log('info', `IP ${ipAddress} is already in warmup`);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// Add to configuration
|
|
496
|
+
this.config.ipAddresses.push(ipAddress);
|
|
497
|
+
|
|
498
|
+
// Initialize warmup
|
|
499
|
+
this.initializeIPWarmup(ipAddress);
|
|
500
|
+
|
|
501
|
+
// Initialize counters
|
|
502
|
+
this.dailySendCounts.set(ipAddress, 0);
|
|
503
|
+
this.hourlySendCounts.set(ipAddress, Array(24).fill(0));
|
|
504
|
+
|
|
505
|
+
logger.log('info', `Added IP ${ipAddress} to warmup process`);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Remove an IP address from the warmup process
|
|
510
|
+
* @param ipAddress IP address to remove
|
|
511
|
+
*/
|
|
512
|
+
public removeIPFromWarmup(ipAddress: string): void {
|
|
513
|
+
const index = this.config.ipAddresses.indexOf(ipAddress);
|
|
514
|
+
if (index === -1) {
|
|
515
|
+
logger.log('info', `IP ${ipAddress} is not in warmup`);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Remove from configuration
|
|
520
|
+
this.config.ipAddresses.splice(index, 1);
|
|
521
|
+
|
|
522
|
+
// Remove from statuses and counters
|
|
523
|
+
this.warmupStatuses.delete(ipAddress);
|
|
524
|
+
this.dailySendCounts.delete(ipAddress);
|
|
525
|
+
this.hourlySendCounts.delete(ipAddress);
|
|
526
|
+
|
|
527
|
+
this.saveWarmupStatuses();
|
|
528
|
+
|
|
529
|
+
logger.log('info', `Removed IP ${ipAddress} from warmup process`);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Update metrics for an IP address
|
|
534
|
+
* @param ipAddress IP address to update
|
|
535
|
+
* @param metrics New metrics
|
|
536
|
+
*/
|
|
537
|
+
public updateMetrics(
|
|
538
|
+
ipAddress: string,
|
|
539
|
+
metrics: { openRate?: number; bounceRate?: number; complaintRate?: number }
|
|
540
|
+
): void {
|
|
541
|
+
const status = this.warmupStatuses.get(ipAddress);
|
|
542
|
+
if (!status) {
|
|
543
|
+
logger.log('warn', `Cannot update metrics for IP ${ipAddress} - not in warmup`);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Update metrics
|
|
548
|
+
if (metrics.openRate !== undefined) {
|
|
549
|
+
status.metrics.openRate = metrics.openRate;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (metrics.bounceRate !== undefined) {
|
|
553
|
+
status.metrics.bounceRate = metrics.bounceRate;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (metrics.complaintRate !== undefined) {
|
|
557
|
+
status.metrics.complaintRate = metrics.complaintRate;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
this.saveWarmupStatuses();
|
|
561
|
+
|
|
562
|
+
logger.log('info', `Updated metrics for IP ${ipAddress}`, {
|
|
563
|
+
openRate: status.metrics.openRate,
|
|
564
|
+
bounceRate: status.metrics.bounceRate,
|
|
565
|
+
complaintRate: status.metrics.complaintRate
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Record a send event for an IP address
|
|
571
|
+
* @param ipAddress IP address used for sending
|
|
572
|
+
*/
|
|
573
|
+
public recordSend(ipAddress: string): void {
|
|
574
|
+
if (!this.config.ipAddresses.includes(ipAddress)) {
|
|
575
|
+
logger.log('warn', `Cannot record send for IP ${ipAddress} - not in warmup`);
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Increment daily counter
|
|
580
|
+
const currentCount = this.dailySendCounts.get(ipAddress) || 0;
|
|
581
|
+
this.dailySendCounts.set(ipAddress, currentCount + 1);
|
|
582
|
+
|
|
583
|
+
// Increment hourly counter
|
|
584
|
+
const hourlyCount = this.hourlySendCounts.get(ipAddress) || Array(24).fill(0);
|
|
585
|
+
const currentHour = new Date().getHours();
|
|
586
|
+
hourlyCount[currentHour]++;
|
|
587
|
+
this.hourlySendCounts.set(ipAddress, hourlyCount);
|
|
588
|
+
|
|
589
|
+
// Update warmup status
|
|
590
|
+
const status = this.warmupStatuses.get(ipAddress);
|
|
591
|
+
if (status) {
|
|
592
|
+
status.sentInCurrentStage++;
|
|
593
|
+
status.totalSent++;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Check if an IP can send more emails today
|
|
599
|
+
* @param ipAddress IP address to check
|
|
600
|
+
* @returns Whether the IP can send more emails
|
|
601
|
+
*/
|
|
602
|
+
public canSendMoreToday(ipAddress: string): boolean {
|
|
603
|
+
if (!this.config.enabled) return true;
|
|
604
|
+
|
|
605
|
+
if (!this.config.ipAddresses.includes(ipAddress)) {
|
|
606
|
+
// If not in warmup, assume it can send
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const status = this.warmupStatuses.get(ipAddress);
|
|
611
|
+
if (!status || !status.isActive) {
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const currentCount = this.dailySendCounts.get(ipAddress) || 0;
|
|
616
|
+
return currentCount < status.currentDailyAllocation;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Check if an IP can send more emails in the current hour
|
|
621
|
+
* @param ipAddress IP address to check
|
|
622
|
+
* @returns Whether the IP can send more emails this hour
|
|
623
|
+
*/
|
|
624
|
+
public canSendMoreThisHour(ipAddress: string): boolean {
|
|
625
|
+
if (!this.config.enabled) return true;
|
|
626
|
+
|
|
627
|
+
if (!this.config.ipAddresses.includes(ipAddress)) {
|
|
628
|
+
// If not in warmup, assume it can send
|
|
629
|
+
return true;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const status = this.warmupStatuses.get(ipAddress);
|
|
633
|
+
if (!status || !status.isActive) {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const currentDailyLimit = status.currentDailyAllocation;
|
|
638
|
+
const currentHour = new Date().getHours();
|
|
639
|
+
const hourlyAllocation = Math.ceil((currentDailyLimit * this.config.hourlyDistribution[currentHour]) / 100);
|
|
640
|
+
|
|
641
|
+
const hourlyCount = this.hourlySendCounts.get(ipAddress) || Array(24).fill(0);
|
|
642
|
+
const currentHourCount = hourlyCount[currentHour];
|
|
643
|
+
|
|
644
|
+
return currentHourCount < hourlyAllocation;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Get the best IP to use for sending an email
|
|
649
|
+
* @param emailInfo Information about the email being sent
|
|
650
|
+
* @returns The best IP to use, or null if no suitable IP is available
|
|
651
|
+
*/
|
|
652
|
+
public getBestIPForSending(emailInfo: {
|
|
653
|
+
from: string;
|
|
654
|
+
to: string[];
|
|
655
|
+
domain: string;
|
|
656
|
+
isTransactional?: boolean;
|
|
657
|
+
}): string | null {
|
|
658
|
+
// If warmup is disabled, return null (caller will use default IP)
|
|
659
|
+
if (!this.config.enabled || this.config.ipAddresses.length === 0) {
|
|
660
|
+
return null;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Prepare information for allocation policy
|
|
664
|
+
const availableIPs = this.config.ipAddresses
|
|
665
|
+
.filter(ip => this.canSendMoreToday(ip) && this.canSendMoreThisHour(ip))
|
|
666
|
+
.map(ip => {
|
|
667
|
+
const status = this.warmupStatuses.get(ip);
|
|
668
|
+
return {
|
|
669
|
+
ip,
|
|
670
|
+
priority: status ? status.currentStage : 1,
|
|
671
|
+
capacity: status ? (status.currentDailyAllocation - (this.dailySendCounts.get(ip) || 0)) : 0
|
|
672
|
+
};
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
// Use the active allocation policy to determine the best IP
|
|
676
|
+
const policy = this.allocationPolicies.get(this.activePolicy);
|
|
677
|
+
if (!policy) {
|
|
678
|
+
logger.log('warn', `No allocation policy named ${this.activePolicy} found`);
|
|
679
|
+
return null;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
return policy.allocateIP(availableIPs, {
|
|
683
|
+
...emailInfo,
|
|
684
|
+
isTransactional: emailInfo.isTransactional || false,
|
|
685
|
+
isWarmup: true
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Register a new IP allocation policy
|
|
691
|
+
* @param name Policy name
|
|
692
|
+
* @param policy Policy implementation
|
|
693
|
+
*/
|
|
694
|
+
public registerAllocationPolicy(name: string, policy: IIPAllocationPolicy): void {
|
|
695
|
+
this.allocationPolicies.set(name, policy);
|
|
696
|
+
logger.log('info', `Registered IP allocation policy: ${name}`);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Set the active IP allocation policy
|
|
701
|
+
* @param name Policy name
|
|
702
|
+
*/
|
|
703
|
+
public setActiveAllocationPolicy(name: string): void {
|
|
704
|
+
if (!this.allocationPolicies.has(name)) {
|
|
705
|
+
logger.log('warn', `No allocation policy named ${name} found`);
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
this.activePolicy = name;
|
|
710
|
+
logger.log('info', `Set active IP allocation policy to ${name}`);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Get the total number of stages in the warmup process
|
|
715
|
+
* @returns Number of stages
|
|
716
|
+
*/
|
|
717
|
+
public getStageCount(): number {
|
|
718
|
+
return this.config.stages.length;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Load warmup statuses from storage
|
|
723
|
+
*/
|
|
724
|
+
private loadWarmupStatuses(): void {
|
|
725
|
+
try {
|
|
726
|
+
const warmupDir = plugins.path.join(paths.dataDir, 'warmup');
|
|
727
|
+
plugins.smartfile.fs.ensureDirSync(warmupDir);
|
|
728
|
+
|
|
729
|
+
const statusFile = plugins.path.join(warmupDir, 'ip_warmup_status.json');
|
|
730
|
+
|
|
731
|
+
if (plugins.fs.existsSync(statusFile)) {
|
|
732
|
+
const data = plugins.fs.readFileSync(statusFile, 'utf8');
|
|
733
|
+
const statuses = JSON.parse(data);
|
|
734
|
+
|
|
735
|
+
for (const status of statuses) {
|
|
736
|
+
// Restore date objects
|
|
737
|
+
status.startDate = new Date(status.startDate);
|
|
738
|
+
status.currentStageStartDate = new Date(status.currentStageStartDate);
|
|
739
|
+
status.targetCompletionDate = new Date(status.targetCompletionDate);
|
|
740
|
+
|
|
741
|
+
this.warmupStatuses.set(status.ipAddress, status);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
logger.log('info', `Loaded ${this.warmupStatuses.size} IP warmup statuses from storage`);
|
|
745
|
+
}
|
|
746
|
+
} catch (error) {
|
|
747
|
+
logger.log('error', `Failed to load warmup statuses: ${error.message}`, {
|
|
748
|
+
stack: error.stack
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Save warmup statuses to storage
|
|
755
|
+
*/
|
|
756
|
+
private saveWarmupStatuses(): void {
|
|
757
|
+
try {
|
|
758
|
+
const warmupDir = plugins.path.join(paths.dataDir, 'warmup');
|
|
759
|
+
plugins.smartfile.fs.ensureDirSync(warmupDir);
|
|
760
|
+
|
|
761
|
+
const statusFile = plugins.path.join(warmupDir, 'ip_warmup_status.json');
|
|
762
|
+
const statuses = Array.from(this.warmupStatuses.values());
|
|
763
|
+
|
|
764
|
+
plugins.smartfile.memory.toFsSync(
|
|
765
|
+
JSON.stringify(statuses, null, 2),
|
|
766
|
+
statusFile
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
logger.log('debug', `Saved ${statuses.length} IP warmup statuses to storage`);
|
|
770
|
+
} catch (error) {
|
|
771
|
+
logger.log('error', `Failed to save warmup statuses: ${error.message}`, {
|
|
772
|
+
stack: error.stack
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Policy that balances traffic across IPs based on stage and capacity
|
|
780
|
+
*/
|
|
781
|
+
class BalancedAllocationPolicy implements IIPAllocationPolicy {
|
|
782
|
+
name = 'balanced';
|
|
783
|
+
|
|
784
|
+
allocateIP(
|
|
785
|
+
availableIPs: Array<{ ip: string; priority: number; capacity: number }>,
|
|
786
|
+
emailInfo: {
|
|
787
|
+
from: string;
|
|
788
|
+
to: string[];
|
|
789
|
+
domain: string;
|
|
790
|
+
isTransactional: boolean;
|
|
791
|
+
isWarmup: boolean;
|
|
792
|
+
}
|
|
793
|
+
): string | null {
|
|
794
|
+
if (availableIPs.length === 0) return null;
|
|
795
|
+
|
|
796
|
+
// Sort IPs by priority (prefer higher stage IPs) and capacity
|
|
797
|
+
const sortedIPs = [...availableIPs].sort((a, b) => {
|
|
798
|
+
// First by priority (descending)
|
|
799
|
+
if (b.priority !== a.priority) {
|
|
800
|
+
return b.priority - a.priority;
|
|
801
|
+
}
|
|
802
|
+
// Then by remaining capacity (descending)
|
|
803
|
+
return b.capacity - a.capacity;
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
// Prioritize higher-stage IPs for transactional emails
|
|
807
|
+
if (emailInfo.isTransactional) {
|
|
808
|
+
return sortedIPs[0].ip;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// For marketing emails, spread across IPs with preference for higher stages
|
|
812
|
+
// Use weighted random selection based on stage
|
|
813
|
+
const totalWeight = sortedIPs.reduce((sum, ip) => sum + ip.priority, 0);
|
|
814
|
+
let randomPoint = Math.random() * totalWeight;
|
|
815
|
+
|
|
816
|
+
for (const ip of sortedIPs) {
|
|
817
|
+
randomPoint -= ip.priority;
|
|
818
|
+
if (randomPoint <= 0) {
|
|
819
|
+
return ip.ip;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Fallback to the highest priority IP
|
|
824
|
+
return sortedIPs[0].ip;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Policy that rotates through IPs in a round-robin fashion
|
|
830
|
+
*/
|
|
831
|
+
class RoundRobinAllocationPolicy implements IIPAllocationPolicy {
|
|
832
|
+
name = 'roundRobin';
|
|
833
|
+
private lastIndex = -1;
|
|
834
|
+
|
|
835
|
+
allocateIP(
|
|
836
|
+
availableIPs: Array<{ ip: string; priority: number; capacity: number }>,
|
|
837
|
+
emailInfo: {
|
|
838
|
+
from: string;
|
|
839
|
+
to: string[];
|
|
840
|
+
domain: string;
|
|
841
|
+
isTransactional: boolean;
|
|
842
|
+
isWarmup: boolean;
|
|
843
|
+
}
|
|
844
|
+
): string | null {
|
|
845
|
+
if (availableIPs.length === 0) return null;
|
|
846
|
+
|
|
847
|
+
// Sort by capacity to ensure even distribution
|
|
848
|
+
const sortedIPs = [...availableIPs].sort((a, b) => b.capacity - a.capacity);
|
|
849
|
+
|
|
850
|
+
// Move to next IP
|
|
851
|
+
this.lastIndex = (this.lastIndex + 1) % sortedIPs.length;
|
|
852
|
+
|
|
853
|
+
return sortedIPs[this.lastIndex].ip;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Policy that dedicates specific IPs to specific domains
|
|
859
|
+
*/
|
|
860
|
+
class DedicatedDomainPolicy implements IIPAllocationPolicy {
|
|
861
|
+
name = 'dedicated';
|
|
862
|
+
private domainAssignments: Map<string, string> = new Map();
|
|
863
|
+
|
|
864
|
+
allocateIP(
|
|
865
|
+
availableIPs: Array<{ ip: string; priority: number; capacity: number }>,
|
|
866
|
+
emailInfo: {
|
|
867
|
+
from: string;
|
|
868
|
+
to: string[];
|
|
869
|
+
domain: string;
|
|
870
|
+
isTransactional: boolean;
|
|
871
|
+
isWarmup: boolean;
|
|
872
|
+
}
|
|
873
|
+
): string | null {
|
|
874
|
+
if (availableIPs.length === 0) return null;
|
|
875
|
+
|
|
876
|
+
// Check if we have a dedicated IP for this domain
|
|
877
|
+
if (this.domainAssignments.has(emailInfo.domain)) {
|
|
878
|
+
const dedicatedIP = this.domainAssignments.get(emailInfo.domain);
|
|
879
|
+
|
|
880
|
+
// Check if the dedicated IP is in the available list
|
|
881
|
+
const isAvailable = availableIPs.some(ip => ip.ip === dedicatedIP);
|
|
882
|
+
|
|
883
|
+
if (isAvailable) {
|
|
884
|
+
return dedicatedIP;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// If not, assign one and save the assignment
|
|
889
|
+
const sortedIPs = [...availableIPs].sort((a, b) => b.capacity - a.capacity);
|
|
890
|
+
const assignedIP = sortedIPs[0].ip;
|
|
891
|
+
|
|
892
|
+
this.domainAssignments.set(emailInfo.domain, assignedIP);
|
|
893
|
+
|
|
894
|
+
return assignedIP;
|
|
895
|
+
}
|
|
896
|
+
}
|