nolimit-x 1.0.59 → 1.0.61
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/package.json +1 -1
- package/src/email-validator.js +26 -12
- package/src/sender.js +2 -2
package/package.json
CHANGED
package/src/email-validator.js
CHANGED
|
@@ -26,44 +26,58 @@ const {
|
|
|
26
26
|
// ═══════════════════════════════════════════════════════════
|
|
27
27
|
const domainCache = new Map();
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Retry wrapper with exponential backoff for DNS queries.
|
|
31
|
+
* Retries up to `maxRetries` times on transient failures.
|
|
32
|
+
*/
|
|
33
|
+
async function withRetry(fn, maxRetries = 3, baseDelay = 300) {
|
|
34
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
35
|
+
try {
|
|
36
|
+
return await fn();
|
|
37
|
+
} catch (e) {
|
|
38
|
+
// ENOTFOUND / ENODATA = domain genuinely doesn't exist, no point retrying
|
|
39
|
+
if (e.code === 'ENOTFOUND' || e.code === 'ENODATA') return null;
|
|
40
|
+
if (attempt === maxRetries) return null;
|
|
41
|
+
// Exponential backoff with jitter
|
|
42
|
+
const delay = baseDelay * Math.pow(2, attempt) + Math.random() * 100;
|
|
43
|
+
await new Promise(r => setTimeout(r, delay));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
/**
|
|
30
50
|
* Resolve MX records for a domain.
|
|
31
51
|
* Returns the lowest-priority MX hostname (primary).
|
|
32
52
|
*/
|
|
33
53
|
async function getMX(domain) {
|
|
34
|
-
|
|
54
|
+
return withRetry(async () => {
|
|
35
55
|
const records = await dns.resolveMx(domain);
|
|
36
56
|
if (!records || records.length === 0) return null;
|
|
37
57
|
// Sort by priority (lowest = primary)
|
|
38
58
|
records.sort((a, b) => a.priority - b.priority);
|
|
39
59
|
return records[0].exchange.toLowerCase().replace(/\.$/, '');
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
60
|
+
});
|
|
43
61
|
}
|
|
44
62
|
|
|
45
63
|
/**
|
|
46
64
|
* Resolve A record (hostname → IP).
|
|
47
65
|
*/
|
|
48
66
|
async function getA(hostname) {
|
|
49
|
-
|
|
67
|
+
return withRetry(async () => {
|
|
50
68
|
const addrs = await dns.resolve4(hostname);
|
|
51
69
|
return addrs && addrs.length > 0 ? addrs[0] : null;
|
|
52
|
-
}
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
70
|
+
});
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
/**
|
|
58
74
|
* Reverse PTR lookup (IP → hostname).
|
|
59
75
|
*/
|
|
60
76
|
async function getPTR(ip) {
|
|
61
|
-
|
|
77
|
+
return withRetry(async () => {
|
|
62
78
|
const names = await dns.reverse(ip);
|
|
63
79
|
return names && names.length > 0 ? names[0].toLowerCase() : null;
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
80
|
+
});
|
|
67
81
|
}
|
|
68
82
|
|
|
69
83
|
/**
|
package/src/sender.js
CHANGED
|
@@ -492,6 +492,8 @@ async function send(options) {
|
|
|
492
492
|
try { senderIntel.recordSuccessfulSend(campaignId, sender, email, result); } catch (e) { }
|
|
493
493
|
} else {
|
|
494
494
|
campaign.failedSends++;
|
|
495
|
+
const errMsg = result.error || result.message || 'unknown error';
|
|
496
|
+
console.log(`${RED}✗${RESET} ${WHITE}${email}${RESET} — ${RED}${errMsg}${RESET}`);
|
|
495
497
|
try { senderIntel.recordFailedSend(campaignId, sender, email, result); } catch (e) { }
|
|
496
498
|
}
|
|
497
499
|
campaign.processedEmails++;
|
|
@@ -1152,13 +1154,11 @@ function buildBasicRustJob(config, recipient, messageHtml, configManager) {
|
|
|
1152
1154
|
// Scenario 2: Use config from_email
|
|
1153
1155
|
fromEmail = conf.from_email;
|
|
1154
1156
|
envelopeSender = conf.from_email;
|
|
1155
|
-
console.log(`[SENDER] Using config from_email: ${fromEmail}`);
|
|
1156
1157
|
} else {
|
|
1157
1158
|
// Scenario 3: Use SMTP user email
|
|
1158
1159
|
const smtpConfig = Array.isArray(config.smtp) ? config.smtp[0] : config.smtp;
|
|
1159
1160
|
fromEmail = smtpConfig.user;
|
|
1160
1161
|
envelopeSender = smtpConfig.user;
|
|
1161
|
-
console.log(`[SENDER] Using SMTP user email: ${fromEmail}`);
|
|
1162
1162
|
}
|
|
1163
1163
|
}
|
|
1164
1164
|
|