Skip to content

Commit 69feafe

Browse files
committed
fix(email): split two fused domain entries in the vendored list
Upstream joins mail2moldova.com/mail2molly.com and smileyface.com/smithemail.net into one entry each, a CSV line-join artifact that made all four read as work addresses. Splitting them keeps the list sorted and adds a guard against a naive refresh.
1 parent a604e95 commit 69feafe

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

apps/sim/lib/messaging/email/free-email-domains.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2590,7 +2590,8 @@
25902590
"mail2missouri.com",
25912591
"mail2mitch.com",
25922592
"mail2model.com",
2593-
"mail2moldova.commail2molly.com",
2593+
"mail2moldova.com",
2594+
"mail2molly.com",
25942595
"mail2mom.com",
25952596
"mail2monaco.com",
25962597
"mail2money.com",
@@ -3974,7 +3975,8 @@
39743975
"smapxsmap.net",
39753976
"smashmail.de",
39763977
"smellrear.com",
3977-
"smileyface.comsmithemail.net",
3978+
"smileyface.com",
3979+
"smithemail.net",
39783980
"smoothmail.com",
39793981
"sms.at",
39803982
"snail-mail.net",

apps/sim/lib/messaging/email/free-email.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* @vitest-environment node
33
*/
44
import { describe, expect, it } from 'vitest'
5+
import freeEmailDomains from '@/lib/messaging/email/free-email-domains.json'
56
import { isFreeEmailDomain } from './free-email'
67

78
describe('isFreeEmailDomain', () => {
@@ -24,4 +25,28 @@ describe('isFreeEmailDomain', () => {
2425
expect(isFreeEmailDomain('jane')).toBe(false)
2526
expect(isFreeEmailDomain('')).toBe(false)
2627
})
28+
29+
/**
30+
* Upstream joins each of these pairs into one entry, which made all four read as work
31+
* addresses. They are split in the vendored list, so this guards against a naive refresh.
32+
*/
33+
it('returns true for the providers upstream fuses into a single entry', () => {
34+
expect(isFreeEmailDomain('jane@mail2moldova.com')).toBe(true)
35+
expect(isFreeEmailDomain('jane@mail2molly.com')).toBe(true)
36+
expect(isFreeEmailDomain('jane@smileyface.com')).toBe(true)
37+
expect(isFreeEmailDomain('jane@smithemail.net')).toBe(true)
38+
})
39+
40+
it('carries no entry that is two domains concatenated', () => {
41+
const suffixes = ['.com', '.net', '.org', '.info', '.biz']
42+
const fused = freeEmailDomains.filter((entry) =>
43+
suffixes.some((suffix) => {
44+
const at = entry.indexOf(suffix)
45+
if (at === -1 || at + suffix.length >= entry.length) return false
46+
const rest = entry.slice(at + suffix.length)
47+
return rest.includes('.') && rest.split('.')[0].length >= 3
48+
})
49+
)
50+
expect(fused).toEqual(['cable.comcast.com'])
51+
})
2752
})

apps/sim/lib/messaging/email/free-email.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ const FREE_EMAIL_DOMAINS = new Set<string>(freeEmailDomains)
1515
* downloads a CDN CSV and overwrites its own `domains.json` — so the lockfile hash covers
1616
* the tarball but not the installed data. Refresh from
1717
* https://github.com/Kikobeats/free-email-domains (MIT) and review the diff.
18+
*
19+
* The vendored list deviates from upstream in one place: upstream fuses two pairs of
20+
* domains into single entries (`mail2moldova.com`/`mail2molly.com` and
21+
* `smileyface.com`/`smithemail.net`), a CSV line-join artifact that made all four read as
22+
* work addresses. They are split here, so re-apply that split after any refresh.
1823
*/
1924
export function isFreeEmailDomain(email: string): boolean {
2025
const domain = email.split('@')[1]?.toLowerCase()

0 commit comments

Comments
 (0)