@@ -34,17 +34,207 @@ export default class Email implements EmailProps {
3434
3535 private static readonly typoDomains : { [ key : string ] : string } = {
3636 // gmail.com
37- '35gmai.com' : 'gmail.com' ,
38- '636gmail.com' : 'gmail.com' ,
37+ 'gmai.com' : 'gmail.com' ,
3938 'gamil.com' : 'gmail.com' ,
40- 'gmail.comu ' : 'gmail.com' ,
39+ 'gmali.com ' : 'gmail.com' ,
4140 'gmial.com' : 'gmail.com' ,
4241 'gmil.com' : 'gmail.com' ,
42+ 'gmaill.com' : 'gmail.com' ,
43+ 'gmailm.com' : 'gmail.com' ,
44+ 'gmailo.com' : 'gmail.com' ,
45+ 'gmailyhoo.com' : 'gmail.com' ,
4346 'yahoogmail.com' : 'gmail.com' ,
4447 // outlook.com
4548 'putlook.com' : 'outlook.com' ,
4649 } ;
4750
51+ private static readonly equivalentDomains : { [ key : string ] : string } = {
52+ 'googlemail.com' : 'gmail.com' ,
53+ 'pm.me' : 'protonmail.com' ,
54+ 'proton.me' : 'protonmail.com' ,
55+ 'yandex.by' : 'yandex.ru' ,
56+ 'yandex.com' : 'yandex.ru' ,
57+ 'yandex.kz' : 'yandex.ru' ,
58+ 'yandex.ua' : 'yandex.ru' ,
59+ 'ya.ru' : 'yandex.ru' ,
60+ } ;
61+
62+ private static readonly fastmailDomains : { [ key : string ] : boolean } = {
63+ '123mail.org' : true ,
64+ '150mail.com' : true ,
65+ '150ml.com' : true ,
66+ '16mail.com' : true ,
67+ '2-mail.com' : true ,
68+ '4email.net' : true ,
69+ '50mail.com' : true ,
70+ 'airpost.net' : true ,
71+ 'allmail.net' : true ,
72+ 'bestmail.us' : true ,
73+ 'cluemail.com' : true ,
74+ 'elitemail.org' : true ,
75+ 'emailcorner.net' : true ,
76+ 'emailengine.net' : true ,
77+ 'emailengine.org' : true ,
78+ 'emailgroups.net' : true ,
79+ 'emailplus.org' : true ,
80+ 'emailuser.net' : true ,
81+ 'eml.cc' : true ,
82+ 'f-m.fm' : true ,
83+ 'fast-email.com' : true ,
84+ 'fast-mail.org' : true ,
85+ 'fastem.com' : true ,
86+ 'fastemail.us' : true ,
87+ 'fastemailer.com' : true ,
88+ 'fastest.cc' : true ,
89+ 'fastimap.com' : true ,
90+ 'fastmail.cn' : true ,
91+ 'fastmail.co.uk' : true ,
92+ 'fastmail.com' : true ,
93+ 'fastmail.com.au' : true ,
94+ 'fastmail.de' : true ,
95+ 'fastmail.es' : true ,
96+ 'fastmail.fm' : true ,
97+ 'fastmail.fr' : true ,
98+ 'fastmail.im' : true ,
99+ 'fastmail.in' : true ,
100+ 'fastmail.jp' : true ,
101+ 'fastmail.mx' : true ,
102+ 'fastmail.net' : true ,
103+ 'fastmail.nl' : true ,
104+ 'fastmail.org' : true ,
105+ 'fastmail.se' : true ,
106+ 'fastmail.to' : true ,
107+ 'fastmail.tw' : true ,
108+ 'fastmail.uk' : true ,
109+ 'fastmail.us' : true ,
110+ 'fastmailbox.net' : true ,
111+ 'fastmessaging.com' : true ,
112+ 'fea.st' : true ,
113+ 'fmail.co.uk' : true ,
114+ 'fmailbox.com' : true ,
115+ 'fmgirl.com' : true ,
116+ 'fmguy.com' : true ,
117+ 'ftml.net' : true ,
118+ 'h-mail.us' : true ,
119+ 'hailmail.net' : true ,
120+ 'imap-mail.com' : true ,
121+ 'imap.cc' : true ,
122+ 'imapmail.org' : true ,
123+ 'inoutbox.com' : true ,
124+ 'internet-e-mail.com' : true ,
125+ 'internet-mail.org' : true ,
126+ 'internetemails.net' : true ,
127+ 'internetmailing.net' : true ,
128+ 'jetemail.net' : true ,
129+ 'justemail.net' : true ,
130+ 'letterboxes.org' : true ,
131+ 'mail-central.com' : true ,
132+ 'mail-page.com' : true ,
133+ 'mailandftp.com' : true ,
134+ 'mailas.com' : true ,
135+ 'mailbolt.com' : true ,
136+ 'mailc.net' : true ,
137+ 'mailcan.com' : true ,
138+ 'mailforce.net' : true ,
139+ 'mailftp.com' : true ,
140+ 'mailhaven.com' : true ,
141+ 'mailingaddress.org' : true ,
142+ 'mailite.com' : true ,
143+ 'mailmight.com' : true ,
144+ 'mailnew.com' : true ,
145+ 'mailsent.net' : true ,
146+ 'mailservice.ms' : true ,
147+ 'mailup.net' : true ,
148+ 'mailworks.org' : true ,
149+ 'ml1.net' : true ,
150+ 'mm.st' : true ,
151+ 'myfastmail.com' : true ,
152+ 'mymacmail.com' : true ,
153+ 'nospammail.net' : true ,
154+ 'ownmail.net' : true ,
155+ 'petml.com' : true ,
156+ 'postinbox.com' : true ,
157+ 'postpro.net' : true ,
158+ 'proinbox.com' : true ,
159+ 'promessage.com' : true ,
160+ 'realemail.net' : true ,
161+ 'reallyfast.biz' : true ,
162+ 'reallyfast.info' : true ,
163+ 'rushpost.com' : true ,
164+ 'sent.as' : true ,
165+ 'sent.at' : true ,
166+ 'sent.com' : true ,
167+ 'speedpost.net' : true ,
168+ 'speedymail.org' : true ,
169+ 'ssl-mail.com' : true ,
170+ 'swift-mail.com' : true ,
171+ 'the-fastest.net' : true ,
172+ 'the-quickest.com' : true ,
173+ 'theinternetemail.com' : true ,
174+ 'veryfast.biz' : true ,
175+ 'veryspeedy.net' : true ,
176+ 'warpmail.net' : true ,
177+ 'xsmail.com' : true ,
178+ 'yepmail.net' : true ,
179+ 'your-mail.com' : true ,
180+ } ;
181+
182+ private static readonly yahooDomains : { [ key : string ] : boolean } = {
183+ 'y7mail.com' : true ,
184+ 'yahoo.at' : true ,
185+ 'yahoo.be' : true ,
186+ 'yahoo.bg' : true ,
187+ 'yahoo.ca' : true ,
188+ 'yahoo.cl' : true ,
189+ 'yahoo.co.id' : true ,
190+ 'yahoo.co.il' : true ,
191+ 'yahoo.co.in' : true ,
192+ 'yahoo.co.kr' : true ,
193+ 'yahoo.co.nz' : true ,
194+ 'yahoo.co.th' : true ,
195+ 'yahoo.co.uk' : true ,
196+ 'yahoo.co.za' : true ,
197+ 'yahoo.com' : true ,
198+ 'yahoo.com.ar' : true ,
199+ 'yahoo.com.au' : true ,
200+ 'yahoo.com.br' : true ,
201+ 'yahoo.com.co' : true ,
202+ 'yahoo.com.hk' : true ,
203+ 'yahoo.com.hr' : true ,
204+ 'yahoo.com.mx' : true ,
205+ 'yahoo.com.my' : true ,
206+ 'yahoo.com.pe' : true ,
207+ 'yahoo.com.ph' : true ,
208+ 'yahoo.com.sg' : true ,
209+ 'yahoo.com.tr' : true ,
210+ 'yahoo.com.tw' : true ,
211+ 'yahoo.com.ua' : true ,
212+ 'yahoo.com.ve' : true ,
213+ 'yahoo.com.vn' : true ,
214+ 'yahoo.cz' : true ,
215+ 'yahoo.de' : true ,
216+ 'yahoo.dk' : true ,
217+ 'yahoo.ee' : true ,
218+ 'yahoo.es' : true ,
219+ 'yahoo.fi' : true ,
220+ 'yahoo.fr' : true ,
221+ 'yahoo.gr' : true ,
222+ 'yahoo.hu' : true ,
223+ 'yahoo.ie' : true ,
224+ 'yahoo.in' : true ,
225+ 'yahoo.it' : true ,
226+ 'yahoo.lt' : true ,
227+ 'yahoo.lv' : true ,
228+ 'yahoo.nl' : true ,
229+ 'yahoo.no' : true ,
230+ 'yahoo.pl' : true ,
231+ 'yahoo.pt' : true ,
232+ 'yahoo.ro' : true ,
233+ 'yahoo.se' : true ,
234+ 'yahoo.sk' : true ,
235+ 'ymail.com' : true ,
236+ } ;
237+
48238 public constructor ( email : EmailProps ) {
49239 if ( email . address != null && ! isEmail ( email . address ) ) {
50240 throw new ArgumentError ( '`email.address` is an invalid email address' ) ;
@@ -85,28 +275,64 @@ export default class Email implements EmailProps {
85275
86276 domain = this . cleanDomain ( domain ) ;
87277
88- const separator = domain === 'yahoo.com' ? '-' : '+' ;
278+ let separator = '+' ;
279+ if ( Object . prototype . hasOwnProperty . call ( Email . yahooDomains , domain ) ) {
280+ separator = '-' ;
281+ }
282+
89283 const separatorIndex = localPart . indexOf ( separator ) ;
90284 if ( separatorIndex > 0 ) {
91285 localPart = localPart . substring ( 0 , separatorIndex ) ;
92286 }
93287
288+ if ( domain === 'gmail.com' ) {
289+ localPart = localPart . replace ( / \. / g, '' ) ;
290+ }
291+
292+ const domainParts = domain . split ( '.' ) ;
293+ if ( domainParts . length > 2 ) {
294+ const possibleDomain = domainParts . slice ( 1 ) . join ( '.' ) ;
295+ if (
296+ Object . prototype . hasOwnProperty . call (
297+ Email . fastmailDomains ,
298+ possibleDomain
299+ )
300+ ) {
301+ domain = possibleDomain ;
302+ if ( localPart !== '' ) {
303+ localPart = domainParts [ 0 ] ;
304+ }
305+ }
306+ }
307+
94308 return localPart + '@' + domain ;
95309 }
96310
97311 private cleanDomain ( domain : string ) {
98312 // We don't need to trim the domain as if it has any leading whitespace
99- // validation rejects it as invalid.
313+ // validation (isEmail()) rejects it as invalid.
100314
101- // We don't need to strip a trailing '.' because validation rejects domains
102- // that have it.
315+ // We don't need to strip a trailing '.' because validation (isEmail())
316+ // rejects domains that have it.
103317
104318 domain = punycode . toASCII ( domain ) ;
105319
320+ domain = domain . replace ( / (?: \. c o m ) { 2 , } $ / , '.com' ) ;
321+ domain = domain . replace ( / \. c o m [ ^ . ] + $ / , '.com' ) ;
322+ domain = domain . replace (
323+ / (?: \. (?: c o m | c [ a - z ] { 1 , 2 } m | c o [ l n ] | [ d s v x ] o [ m n ] | ) ) $ / ,
324+ '.com'
325+ ) ;
326+ domain = domain . replace ( / ^ \d + (?: g m a i l ? \. c o m ) $ / , 'gmail.com' ) ;
327+
106328 if ( Object . prototype . hasOwnProperty . call ( Email . typoDomains , domain ) ) {
107329 domain = Email . typoDomains [ domain ] ;
108330 }
109331
332+ if ( Object . prototype . hasOwnProperty . call ( Email . equivalentDomains , domain ) ) {
333+ domain = Email . equivalentDomains [ domain ] ;
334+ }
335+
110336 return domain ;
111337 }
112338}
0 commit comments