resolve-email 4.0.33 → 4.0.37
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/CHANGELOG.md +43 -1
- package/disposable.json +378 -1
- package/eslint.config.d.ts +1 -1
- package/package.json +21 -19
- package/.github/dependabot.yml +0 -22
- package/.github/funding.yml +0 -4
- package/.github/workflows/release.yml +0 -54
- package/.github/workflows/tests.yml +0 -43
- package/.gitmodules +0 -3
- package/CONTRIBUTING.md +0 -34
- package/allow-list.json +0 -13
- package/build-throwaway-domain-list.cjs +0 -142
- package/build-throwaway-domain-list.d.cts +0 -2
- package/build-throwaway-domain-list.d.cts.map +0 -1
- package/declaration.tsconfig.json +0 -9
- package/deny-list.json +0 -23
- package/disposable.d.cts +0 -2
- package/disposable.d.cts.map +0 -1
- package/eslint.config.js +0 -8
- package/fuzz-test.js +0 -259
- package/index.test.js +0 -71
- package/tsconfig.json +0 -19
- package/wildcard-disposable.d.cts +0 -2
- package/wildcard-disposable.d.cts.map +0 -1
package/fuzz-test.js
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import test from 'node:test'
|
|
2
|
-
import assert from 'node:assert'
|
|
3
|
-
import { resolveEmail } from './index.js'
|
|
4
|
-
|
|
5
|
-
// Regular disposable domains to test
|
|
6
|
-
const regularDomains = [
|
|
7
|
-
'0-mail.com',
|
|
8
|
-
'0clickemail.com',
|
|
9
|
-
'mailinator.com',
|
|
10
|
-
'guerrillamail.com'
|
|
11
|
-
// Note: tempmail.com is not in our block list
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
// Wildcard domains to test
|
|
15
|
-
const wildcardDomains = [
|
|
16
|
-
'spambog.com',
|
|
17
|
-
'spambog.net',
|
|
18
|
-
'spambog.org',
|
|
19
|
-
'discardmail.com',
|
|
20
|
-
'discardmail.net',
|
|
21
|
-
'mailcatch.com'
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
// Fuzzing variations to test
|
|
25
|
-
const variations = [
|
|
26
|
-
// Subdomains
|
|
27
|
-
(/** @type {string} */ domain) => `sub.${domain}`,
|
|
28
|
-
(/** @type {string} */ domain) => `random.${domain}`,
|
|
29
|
-
(/** @type {string} */ domain) => `mail.${domain}`,
|
|
30
|
-
(/** @type {string} */ domain) => `smtp.${domain}`,
|
|
31
|
-
(/** @type {string} */ domain) => `a.b.c.${domain}`,
|
|
32
|
-
|
|
33
|
-
// Case variations
|
|
34
|
-
(/** @type {string} */ domain) => domain.toUpperCase(),
|
|
35
|
-
(/** @type {string} */ domain) => domain.charAt(0).toUpperCase() + domain.slice(1),
|
|
36
|
-
(/** @type {string} */ domain) => domain.split('').map((c, i) => i % 2 ? c.toUpperCase() : c).join(''),
|
|
37
|
-
|
|
38
|
-
// Ports and weird formatting
|
|
39
|
-
(/** @type {string} */ domain) => `${domain}:25`,
|
|
40
|
-
(/** @type {string} */ domain) => `${domain}:587`,
|
|
41
|
-
(/** @type {string} */ domain) => `${domain}:invalid`,
|
|
42
|
-
|
|
43
|
-
// Domain modifications
|
|
44
|
-
(/** @type {string} */ domain) => domain.replace('.', '-'),
|
|
45
|
-
(/** @type {string} */ domain) => domain.replace('.', '_'),
|
|
46
|
-
(/** @type {string} */ domain) => `${domain}.extra`,
|
|
47
|
-
|
|
48
|
-
// Brackets
|
|
49
|
-
(/** @type {string} */ domain) => `[${domain}]`,
|
|
50
|
-
(/** @type {string} */ domain) => `[ipv4:${domain}]`
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
// Generate a test user for each domain and variation
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
* @param {string[]} domainList
|
|
57
|
-
* @returns
|
|
58
|
-
*/
|
|
59
|
-
function generateTestCases (domainList) {
|
|
60
|
-
const testCases = []
|
|
61
|
-
|
|
62
|
-
for (const domain of domainList) {
|
|
63
|
-
// Add the original domain
|
|
64
|
-
testCases.push(`test@${domain}`)
|
|
65
|
-
|
|
66
|
-
// Add all variations
|
|
67
|
-
for (const variation of variations) {
|
|
68
|
-
try {
|
|
69
|
-
testCases.push(`test@${variation(domain)}`)
|
|
70
|
-
} catch (err) {
|
|
71
|
-
const error = err instanceof Error ? err : new Error('Unknown error', { cause: err })
|
|
72
|
-
// Skip if variation throws an error
|
|
73
|
-
console.warn(`Skipping invalid variation for ${domain}:`, error.message)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return testCases
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Create all the test cases
|
|
82
|
-
const disposableTestCases = [
|
|
83
|
-
...generateTestCases(regularDomains),
|
|
84
|
-
...generateTestCases(wildcardDomains)
|
|
85
|
-
]
|
|
86
|
-
|
|
87
|
-
// Also add some hand-crafted edge cases
|
|
88
|
-
const edgeCases = [
|
|
89
|
-
// Strange username parts
|
|
90
|
-
'user.name@mailinator.com',
|
|
91
|
-
'user+tag@guerrillamail.com',
|
|
92
|
-
'very.unusual."@".unusual.com@spambog.com',
|
|
93
|
-
'"very.(),:;<>[]".VERY."very@\\ "very".unusual"@discardmail.com',
|
|
94
|
-
|
|
95
|
-
// IP addresses in domain part (should be rejected by isIP check)
|
|
96
|
-
'test@[127.0.0.1]',
|
|
97
|
-
'test@[ipv6:2001:db8::1]',
|
|
98
|
-
|
|
99
|
-
// Unicode/IDN domains
|
|
100
|
-
'test@mаіlіnаtоr.com', // cyrillic characters that look like latin
|
|
101
|
-
'test@xn--80aacd1bhkfed3a8a5b.xn--p1ai', // Punycode
|
|
102
|
-
|
|
103
|
-
// Port and parameters
|
|
104
|
-
'test@mailinator.com:25',
|
|
105
|
-
'test@guerrillamail.com:587',
|
|
106
|
-
'test@mailinator.com?param=value',
|
|
107
|
-
|
|
108
|
-
// Path-like elements
|
|
109
|
-
'test@mailinator.com/path',
|
|
110
|
-
'test@guerrillamail.com/path/to/resource',
|
|
111
|
-
|
|
112
|
-
// Mixed case
|
|
113
|
-
'test@MaIlInAtOr.CoM',
|
|
114
|
-
'test@SPAMBOG.COM',
|
|
115
|
-
|
|
116
|
-
// Excess whitespace
|
|
117
|
-
'test@ mailinator.com',
|
|
118
|
-
'test@mailinator.com ',
|
|
119
|
-
' test@guerrillamail.com',
|
|
120
|
-
|
|
121
|
-
// URL-encoded characters
|
|
122
|
-
'test@mailinator%2Ecom',
|
|
123
|
-
'test@guerrillamail%2Ecom',
|
|
124
|
-
|
|
125
|
-
// Protocol prefixes
|
|
126
|
-
'test@http://mailinator.com',
|
|
127
|
-
'test@https://guerrillamail.com',
|
|
128
|
-
|
|
129
|
-
// Random gibberish that might be missed
|
|
130
|
-
'test@mailinatorcom',
|
|
131
|
-
'test@guerrillamailcom',
|
|
132
|
-
'test@spambogcom',
|
|
133
|
-
|
|
134
|
-
// Likely typos that should still be caught
|
|
135
|
-
'test@mailinat0r.com', // with number 0
|
|
136
|
-
]
|
|
137
|
-
|
|
138
|
-
disposableTestCases.push(...edgeCases)
|
|
139
|
-
|
|
140
|
-
// Run tests for each case
|
|
141
|
-
for (const testEmail of disposableTestCases) {
|
|
142
|
-
test(`Disposable domain should be rejected: ${testEmail}`, async (_t) => {
|
|
143
|
-
try {
|
|
144
|
-
const result = await resolveEmail(testEmail)
|
|
145
|
-
assert.ok(!result.emailResolves, `Email ${testEmail} should not resolve`)
|
|
146
|
-
assert.ok(result.error, `Email ${testEmail} should have an error`)
|
|
147
|
-
} catch (err) {
|
|
148
|
-
const error = err instanceof Error ? err : new Error('Unknown error', { cause: err })
|
|
149
|
-
// If the test throws (rather than returning a result with error),
|
|
150
|
-
// it's likely a syntax error or similar - log it but don't fail
|
|
151
|
-
console.log(`Exception testing ${testEmail}: ${error.message}`)
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Strict testing for specific cases that should fail as disposable
|
|
157
|
-
// but might be slipping through
|
|
158
|
-
const strictTestCases = [
|
|
159
|
-
// This domain is in our list but might not be getting caught
|
|
160
|
-
// Test these actual domains that should be caught
|
|
161
|
-
'test@mailinator.com',
|
|
162
|
-
'test@sub.mailinator.com',
|
|
163
|
-
'test@mail.mailinator.com',
|
|
164
|
-
'test@MAILINATOR.COM',
|
|
165
|
-
'test@mAiLiNaToR.CoM',
|
|
166
|
-
|
|
167
|
-
// Edge cases that might slip through
|
|
168
|
-
'test@mailinatorcom',
|
|
169
|
-
'test@guerrillamailcom',
|
|
170
|
-
'test@spambogcom',
|
|
171
|
-
|
|
172
|
-
// Malformed but should still be caught as disposable
|
|
173
|
-
'test@.mailinator.com',
|
|
174
|
-
'test@mailinator.com.',
|
|
175
|
-
'test@mailinator..com'
|
|
176
|
-
]
|
|
177
|
-
|
|
178
|
-
// Run strict tests that must always be rejected as disposable
|
|
179
|
-
for (const testEmail of strictTestCases) {
|
|
180
|
-
test(`STRICT: ${testEmail} must be rejected`, async (_t) => {
|
|
181
|
-
const result = await resolveEmail(testEmail)
|
|
182
|
-
|
|
183
|
-
// Must not resolve
|
|
184
|
-
assert.strictEqual(result.emailResolves, false, `Email ${testEmail} should not resolve`)
|
|
185
|
-
|
|
186
|
-
// Must have an error
|
|
187
|
-
assert.ok(result.error, `Email ${testEmail} should have an error`)
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Also add some legitimate domains that should pass
|
|
192
|
-
const legitimateDomains = [
|
|
193
|
-
// Common email providers
|
|
194
|
-
'test@gmail.com',
|
|
195
|
-
'user.name+tag@gmail.com', // Gmail with tag
|
|
196
|
-
'test@googlemail.com', // Gmail alias
|
|
197
|
-
'user.name@yahoo.com',
|
|
198
|
-
'test@outlook.com',
|
|
199
|
-
'test@hotmail.com',
|
|
200
|
-
'test@live.com',
|
|
201
|
-
'test@icloud.com',
|
|
202
|
-
'test@protonmail.com',
|
|
203
|
-
'test@aol.com',
|
|
204
|
-
'test@mail.ru',
|
|
205
|
-
'test@yandex.ru',
|
|
206
|
-
|
|
207
|
-
// Organizations
|
|
208
|
-
'someone@example.org',
|
|
209
|
-
'info@microsoft.com',
|
|
210
|
-
'support@apple.com',
|
|
211
|
-
'contact@amazon.com',
|
|
212
|
-
'help@twitter.com',
|
|
213
|
-
'business@facebook.com',
|
|
214
|
-
'developer@github.com',
|
|
215
|
-
'admin@gitlab.com',
|
|
216
|
-
'hello@stripe.com',
|
|
217
|
-
'noreply@zoom.us',
|
|
218
|
-
'webmaster@cloudflare.com',
|
|
219
|
-
'careers@netflix.com',
|
|
220
|
-
'team@slack.com',
|
|
221
|
-
'feedback@spotify.com',
|
|
222
|
-
'sales@salesforce.com',
|
|
223
|
-
'hello@digitalocean.com',
|
|
224
|
-
'support@dropbox.com',
|
|
225
|
-
'info@ibm.com',
|
|
226
|
-
|
|
227
|
-
// Educational and government domains
|
|
228
|
-
'student@harvard.edu',
|
|
229
|
-
'faculty@mit.edu',
|
|
230
|
-
'staff@stanford.edu',
|
|
231
|
-
'contact@nasa.gov',
|
|
232
|
-
'info@whitehouse.gov',
|
|
233
|
-
|
|
234
|
-
// Country-specific TLDs
|
|
235
|
-
'support@google.com', // Google - US tech giant
|
|
236
|
-
'info@microsoft.com', // Microsoft - US tech giant
|
|
237
|
-
'contact@amazon.co.uk', // Amazon UK
|
|
238
|
-
'support@apple.com', // Apple - US tech giant
|
|
239
|
-
'info@yahoo.co.jp', // Yahoo Japan
|
|
240
|
-
'contact@bbc.co.uk', // BBC - British Broadcasting Corporation
|
|
241
|
-
'info@sap.de', // SAP - German software company
|
|
242
|
-
'support@adobe.com', // Adobe - US software company
|
|
243
|
-
'contact@telstra.com.au', // Telstra - Australian telecom
|
|
244
|
-
'info@shopify.ca', // Shopify - Canadian e-commerce
|
|
245
|
-
'contact@alibaba.com', // Alibaba - Chinese e-commerce
|
|
246
|
-
'support@dropbox.com', // Dropbox - US cloud storage
|
|
247
|
-
'info@sony.jp', // Sony - Japanese electronics company
|
|
248
|
-
'contact@samsung.com', // Samsung - Korean electronics company
|
|
249
|
-
'support@spotify.com' // Spotify - Swedish streaming service
|
|
250
|
-
]
|
|
251
|
-
|
|
252
|
-
for (const testEmail of legitimateDomains) {
|
|
253
|
-
// Generate variations of legitimate domains with unusualr (const testEmail of legitimateDomains) {
|
|
254
|
-
test(`Legitimate domain should be accepted: ${testEmail}`, async (_t) => {
|
|
255
|
-
const result = await resolveEmail(testEmail)
|
|
256
|
-
assert.deepStrictEqual(result.error, undefined, `Email ${testEmail} should not have an error`)
|
|
257
|
-
assert.ok(result.emailResolves, `All of these should resolve ${testEmail}`)
|
|
258
|
-
})
|
|
259
|
-
}
|
package/index.test.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @import {TestContext} from 'node:test'
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import test from 'node:test'
|
|
6
|
-
import assert from 'node:assert'
|
|
7
|
-
import { resolveEmail } from './index.js'
|
|
8
|
-
|
|
9
|
-
const inputs = [
|
|
10
|
-
{
|
|
11
|
-
in: 'bcomnes@gmail.com',
|
|
12
|
-
expect: true,
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
in: 'bcomnes@gmailc.om',
|
|
16
|
-
expect: false,
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
in: 'afastmail@fastmail.com',
|
|
20
|
-
expect: true,
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
in: 'fofegoj914@naymedia.com',
|
|
24
|
-
expect: false,
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
in: 'test@rocketmail.com',
|
|
28
|
-
expect: true,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
in: 'example@Cock.li',
|
|
32
|
-
expect: false,
|
|
33
|
-
},
|
|
34
|
-
// Test wildcard domain patterns
|
|
35
|
-
{
|
|
36
|
-
in: 'test@spambog.com',
|
|
37
|
-
expect: false,
|
|
38
|
-
description: 'should match wildcard pattern spambog.*'
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
in: 'test@spambog.net',
|
|
42
|
-
expect: false,
|
|
43
|
-
description: 'should match wildcard pattern spambog.*'
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
in: 'test@discardmail.org',
|
|
47
|
-
expect: false,
|
|
48
|
-
description: 'should match wildcard pattern discardmail.*'
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
in: 'test@mailcatch.xyz',
|
|
52
|
-
expect: false,
|
|
53
|
-
description: 'should match wildcard pattern mailcatch.*'
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
|
|
57
|
-
for (const i of inputs) {
|
|
58
|
-
const testName = i.description
|
|
59
|
-
? `${i.in} ${i.expect ? 'resolves' : 'does not resolve'} (${i.description})`
|
|
60
|
-
: `${i.in} ${i.expect ? 'resolves' : 'does not resolve'}`
|
|
61
|
-
|
|
62
|
-
test(testName, async (/** @type {TestContext} */ _t) => {
|
|
63
|
-
const results = await resolveEmail(i.in)
|
|
64
|
-
|
|
65
|
-
assert.strictEqual(
|
|
66
|
-
results.emailResolves,
|
|
67
|
-
i.expect,
|
|
68
|
-
`${i.in} ${i.expect ? 'resolves' : 'does not resolve'}`
|
|
69
|
-
)
|
|
70
|
-
})
|
|
71
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "@voxpelli/tsconfig/node20.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"skipLibCheck": true,
|
|
5
|
-
"erasableSyntaxOnly": true,
|
|
6
|
-
"allowImportingTsExtensions": true,
|
|
7
|
-
"rewriteRelativeImportExtensions": true,
|
|
8
|
-
"verbatimModuleSyntax": true,
|
|
9
|
-
"module": "nodenext"
|
|
10
|
-
},
|
|
11
|
-
"include": [
|
|
12
|
-
"./**/*"
|
|
13
|
-
],
|
|
14
|
-
"exclude": [
|
|
15
|
-
"node_modules",
|
|
16
|
-
"disposable-email-domains",
|
|
17
|
-
"coverage"
|
|
18
|
-
]
|
|
19
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wildcard-disposable.d.cts","sourceRoot":"","sources":["wildcard-disposable.cjs"],"names":[],"mappings":""}
|