Skip to content

Commit f52566e

Browse files
committed
feat(normalizeEmail): add support for 7 new email providers
Integrate email provider data from canonical-email library: New providers: - Comcast (comcast.com, comcast.net) - FastMail (~20 domains, with dot removal support) - GMX (~10 domains, uses - for subaddress like Yahoo) - Mailfence (mailfence.com) - Proton (proton.me, protonmail.com) - Skiff (skiff.com, with dot removal support) - Zoho (zohomail.com) Other changes: - Add Yandex subaddress removal (yandex_remove_subaddress) - Add missing Yahoo domains (cox.net, sbcglobal.net) - Update README with documentation for all new options
1 parent 6531047 commit f52566e

File tree

3 files changed

+434
-9
lines changed

3 files changed

+434
-9
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ Sanitizer | Description
184184
**blacklist(input, chars)** | remove characters that appear in the blacklist. The characters are used in a RegExp and so you will need to escape some chars, e.g. `blacklist(input, '\\[\\]')`.
185185
**escape(input)** | replace `<`, `>`, `&`, `'`, `"`, `` ` ``, `\` and `/` with HTML entities.
186186
**ltrim(input [, chars])** | trim characters from the left-side of the input.
187-
**normalizeEmail(email [, options])** | canonicalize an email address. (This doesn't validate that the input is an email, if you want to validate the email use isEmail beforehand).<br/><br/>`options` is an object with the following keys and default values:<br/><ul><li>*all_lowercase: true* - Transforms the local part (before the @ symbol) of all email addresses to lowercase. Please note that this may violate RFC 5321, which gives providers the possibility to treat the local part of email addresses in a case sensitive way (although in practice most - yet not all - providers don't). The domain part of the email address is always lowercased, as it is case insensitive per RFC 1035.</li><li>*gmail_lowercase: true* - Gmail addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Gmail addresses are lowercased regardless of the value of this setting.</li><li>*gmail_remove_dots: true*: Removes dots from the local part of the email address, as Gmail ignores them (e.g. "john.doe" and "johndoe" are considered equal).</li><li>*gmail_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@gmail.com" becomes "foo@gmail.com").</li><li>*gmail_convert_googlemaildotcom: true*: Converts addresses with domain @googlemail.com to @gmail.com, as they're equivalent.</li><li>*outlookdotcom_lowercase: true* - Outlook.com addresses (including Windows Live and Hotmail) are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Outlook.com addresses are lowercased regardless of the value of this setting.</li><li>*outlookdotcom_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@outlook.com" becomes "foo@outlook.com").</li><li>*yahoo_lowercase: true* - Yahoo Mail addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Yahoo Mail addresses are lowercased regardless of the value of this setting.</li><li>*yahoo_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "-" sign (e.g. "foo-bar@yahoo.com" becomes "foo@yahoo.com").</li><li>*icloud_lowercase: true* - iCloud addresses (including MobileMe) are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, iCloud addresses are lowercased regardless of the value of this setting.</li><li>*icloud_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@icloud.com" becomes "foo@icloud.com").</li></ul>
187+
**normalizeEmail(email [, options])** | canonicalize an email address. (This doesn't validate that the input is an email, if you want to validate the email use isEmail beforehand).<br/><br/>`options` is an object with the following keys and default values:<br/><ul><li>*all_lowercase: true* - Transforms the local part (before the @ symbol) of all email addresses to lowercase. Please note that this may violate RFC 5321, which gives providers the possibility to treat the local part of email addresses in a case sensitive way (although in practice most - yet not all - providers don't). The domain part of the email address is always lowercased, as it is case insensitive per RFC 1035.</li><li>*gmail_lowercase: true* - Gmail addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Gmail addresses are lowercased regardless of the value of this setting.</li><li>*gmail_remove_dots: true*: Removes dots from the local part of the email address, as Gmail ignores them (e.g. "john.doe" and "johndoe" are considered equal).</li><li>*gmail_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@gmail.com" becomes "foo@gmail.com").</li><li>*gmail_convert_googlemaildotcom: true*: Converts addresses with domain @googlemail.com to @gmail.com, as they're equivalent.</li><li>*outlookdotcom_lowercase: true* - Outlook.com addresses (including Windows Live and Hotmail) are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Outlook.com addresses are lowercased regardless of the value of this setting.</li><li>*outlookdotcom_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@outlook.com" becomes "foo@outlook.com").</li><li>*yahoo_lowercase: true* - Yahoo Mail addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Yahoo Mail addresses are lowercased regardless of the value of this setting.</li><li>*yahoo_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "-" sign (e.g. "foo-bar@yahoo.com" becomes "foo@yahoo.com").</li><li>*icloud_lowercase: true* - iCloud addresses (including MobileMe) are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, iCloud addresses are lowercased regardless of the value of this setting.</li><li>*icloud_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@icloud.com" becomes "foo@icloud.com").</li><li>*yandex_lowercase: true* - Yandex addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Yandex addresses are lowercased regardless of the value of this setting.</li><li>*yandex_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@yandex.ru" becomes "foo@yandex.ru").</li><li>*comcast_lowercase: true* - Comcast addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Comcast addresses are lowercased regardless of the value of this setting.</li><li>*comcast_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@comcast.net" becomes "foo@comcast.net").</li><li>*fastmail_lowercase: true* - FastMail addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, FastMail addresses are lowercased regardless of the value of this setting.</li><li>*fastmail_remove_dots: true*: Removes dots from the local part of the email address, as FastMail ignores them.</li><li>*fastmail_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@fastmail.com" becomes "foo@fastmail.com").</li><li>*gmx_lowercase: true* - GMX addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, GMX addresses are lowercased regardless of the value of this setting.</li><li>*gmx_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "-" sign (e.g. "foo-bar@gmx.com" becomes "foo@gmx.com").</li><li>*mailfence_lowercase: true* - Mailfence addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Mailfence addresses are lowercased regardless of the value of this setting.</li><li>*mailfence_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@mailfence.com" becomes "foo@mailfence.com").</li><li>*proton_lowercase: true* - Proton (ProtonMail) addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Proton addresses are lowercased regardless of the value of this setting.</li><li>*proton_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@proton.me" becomes "foo@proton.me").</li><li>*skiff_lowercase: true* - Skiff addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Skiff addresses are lowercased regardless of the value of this setting.</li><li>*skiff_remove_dots: true*: Removes dots from the local part of the email address, as Skiff ignores them.</li><li>*skiff_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@skiff.com" becomes "foo@skiff.com").</li><li>*zoho_lowercase: true* - Zoho addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Zoho addresses are lowercased regardless of the value of this setting.</li><li>*zoho_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@zohomail.com" becomes "foo@zohomail.com").</li></ul>
188188
**rtrim(input [, chars])** | trim characters from the right-side of the input.
189189
**stripLow(input [, keep_new_lines])** | remove characters with a numerical value < 32 and 127, mostly control characters. If `keep_new_lines` is `true`, newline characters are preserved (`\n` and `\r`, hex `0xA` and `0xD`). Unicode-safe in JavaScript.
190190
**toBoolean(input [, strict])** | convert the input string to a boolean. Everything except for `'0'`, `'false'` and `''` returns `true`. In strict mode only `'1'` and `'true'` return `true`.

src/lib/normalizeEmail.js

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ const default_normalize_email_options = {
3232
// The following conversions are specific to Yandex
3333
// Lowercases the local part of the Yandex address (known to be case-insensitive)
3434
yandex_lowercase: true,
35+
// Removes the subaddress (e.g. "+foo") from the email address
36+
yandex_remove_subaddress: true,
3537
// all yandex domains are equal, this explicitly sets the domain to 'yandex.ru'
3638
yandex_convert_yandexru: true,
3739

@@ -40,6 +42,52 @@ const default_normalize_email_options = {
4042
icloud_lowercase: true,
4143
// Removes the subaddress (e.g. "+foo") from the email address
4244
icloud_remove_subaddress: true,
45+
46+
// The following conversions are specific to Comcast
47+
// Lowercases the local part of the Comcast address (known to be case-insensitive)
48+
comcast_lowercase: true,
49+
// Removes the subaddress (e.g. "+foo") from the email address
50+
comcast_remove_subaddress: true,
51+
52+
// The following conversions are specific to FastMail
53+
// Lowercases the local part of the FastMail address (known to be case-insensitive)
54+
fastmail_lowercase: true,
55+
// Removes dots from the local part of the email address, as that's ignored by FastMail
56+
fastmail_remove_dots: true,
57+
// Removes the subaddress (e.g. "+foo") from the email address
58+
fastmail_remove_subaddress: true,
59+
60+
// The following conversions are specific to GMX
61+
// Lowercases the local part of the GMX address (known to be case-insensitive)
62+
gmx_lowercase: true,
63+
// Removes the subaddress (e.g. "-foo") from the email address
64+
gmx_remove_subaddress: true,
65+
66+
// The following conversions are specific to Mailfence
67+
// Lowercases the local part of the Mailfence address (known to be case-insensitive)
68+
mailfence_lowercase: true,
69+
// Removes the subaddress (e.g. "+foo") from the email address
70+
mailfence_remove_subaddress: true,
71+
72+
// The following conversions are specific to Proton
73+
// Lowercases the local part of the Proton address (known to be case-insensitive)
74+
proton_lowercase: true,
75+
// Removes the subaddress (e.g. "+foo") from the email address
76+
proton_remove_subaddress: true,
77+
78+
// The following conversions are specific to Skiff
79+
// Lowercases the local part of the Skiff address (known to be case-insensitive)
80+
skiff_lowercase: true,
81+
// Removes dots from the local part of the email address, as that's ignored by Skiff
82+
skiff_remove_dots: true,
83+
// Removes the subaddress (e.g. "+foo") from the email address
84+
skiff_remove_subaddress: true,
85+
86+
// The following conversions are specific to Zoho
87+
// Lowercases the local part of the Zoho address (known to be case-insensitive)
88+
zoho_lowercase: true,
89+
// Removes the subaddress (e.g. "+foo") from the email address
90+
zoho_remove_subaddress: true,
4391
};
4492

4593
// List of domains used by iCloud
@@ -149,6 +197,8 @@ const yahoo_domains = [
149197
'yahoo.in',
150198
'yahoo.it',
151199
'ymail.com',
200+
'cox.net',
201+
'sbcglobal.net',
152202
];
153203

154204
// List of domains used by yandex.ru
@@ -161,6 +211,72 @@ const yandex_domains = [
161211
'ya.ru',
162212
];
163213

214+
// List of domains used by Comcast
215+
const comcast_domains = [
216+
'comcast.com',
217+
'comcast.net',
218+
];
219+
220+
// List of domains used by FastMail
221+
const fastmail_domains = [
222+
'fastmail.com',
223+
'fastmail.cn',
224+
'fastmail.co.uk',
225+
'fastmail.com.au',
226+
'fastmail.de',
227+
'fastmail.es',
228+
'fastmail.fm',
229+
'fastmail.fr',
230+
'fastmail.im',
231+
'fastmail.in',
232+
'fastmail.jp',
233+
'fastmail.mx',
234+
'fastmail.net',
235+
'fastmail.nl',
236+
'fastmail.org',
237+
'fastmail.se',
238+
'fastmail.to',
239+
'fastmail.tw',
240+
'fastmail.uk',
241+
'fastmail.us',
242+
'sent.com',
243+
];
244+
245+
// List of domains used by GMX
246+
const gmx_domains = [
247+
'gmx.at',
248+
'gmx.ca',
249+
'gmx.ch',
250+
'gmx.co.uk',
251+
'gmx.com',
252+
'gmx.de',
253+
'gmx.es',
254+
'gmx.fr',
255+
'gmx.net',
256+
'gmx.us',
257+
];
258+
259+
// List of domains used by Mailfence
260+
const mailfence_domains = [
261+
'mailfence.com',
262+
];
263+
264+
// List of domains used by Proton
265+
const proton_domains = [
266+
'proton.me',
267+
'protonmail.com',
268+
];
269+
270+
// List of domains used by Skiff
271+
const skiff_domains = [
272+
'skiff.com',
273+
];
274+
275+
// List of domains used by Zoho
276+
const zoho_domains = [
277+
'zohomail.com',
278+
];
279+
164280
// replace single dots, but not multiple consecutive dots
165281
function dotsReplacer(match) {
166282
if (match.length > 1) {
@@ -231,10 +347,101 @@ export default function normalizeEmail(email, options) {
231347
parts[0] = parts[0].toLowerCase();
232348
}
233349
} else if (yandex_domains.indexOf(parts[1]) >= 0) {
350+
// Address is Yandex
351+
if (options.yandex_remove_subaddress) {
352+
parts[0] = parts[0].split('+')[0];
353+
}
354+
if (!parts[0].length) {
355+
return false;
356+
}
234357
if (options.all_lowercase || options.yandex_lowercase) {
235358
parts[0] = parts[0].toLowerCase();
236359
}
237360
parts[1] = options.yandex_convert_yandexru ? 'yandex.ru' : parts[1];
361+
} else if (comcast_domains.indexOf(parts[1]) >= 0) {
362+
// Address is Comcast
363+
if (options.comcast_remove_subaddress) {
364+
parts[0] = parts[0].split('+')[0];
365+
}
366+
if (!parts[0].length) {
367+
return false;
368+
}
369+
if (options.all_lowercase || options.comcast_lowercase) {
370+
parts[0] = parts[0].toLowerCase();
371+
}
372+
} else if (fastmail_domains.indexOf(parts[1]) >= 0) {
373+
// Address is FastMail
374+
if (options.fastmail_remove_subaddress) {
375+
parts[0] = parts[0].split('+')[0];
376+
}
377+
if (options.fastmail_remove_dots) {
378+
parts[0] = parts[0].replace(/\.+/g, dotsReplacer);
379+
}
380+
if (!parts[0].length) {
381+
return false;
382+
}
383+
if (options.all_lowercase || options.fastmail_lowercase) {
384+
parts[0] = parts[0].toLowerCase();
385+
}
386+
} else if (gmx_domains.indexOf(parts[1]) >= 0) {
387+
// Address is GMX (uses - for subaddress like Yahoo)
388+
if (options.gmx_remove_subaddress) {
389+
let components = parts[0].split('-');
390+
parts[0] = (components.length > 1) ? components.slice(0, -1).join('-') : components[0];
391+
}
392+
if (!parts[0].length) {
393+
return false;
394+
}
395+
if (options.all_lowercase || options.gmx_lowercase) {
396+
parts[0] = parts[0].toLowerCase();
397+
}
398+
} else if (mailfence_domains.indexOf(parts[1]) >= 0) {
399+
// Address is Mailfence
400+
if (options.mailfence_remove_subaddress) {
401+
parts[0] = parts[0].split('+')[0];
402+
}
403+
if (!parts[0].length) {
404+
return false;
405+
}
406+
if (options.all_lowercase || options.mailfence_lowercase) {
407+
parts[0] = parts[0].toLowerCase();
408+
}
409+
} else if (proton_domains.indexOf(parts[1]) >= 0) {
410+
// Address is Proton
411+
if (options.proton_remove_subaddress) {
412+
parts[0] = parts[0].split('+')[0];
413+
}
414+
if (!parts[0].length) {
415+
return false;
416+
}
417+
if (options.all_lowercase || options.proton_lowercase) {
418+
parts[0] = parts[0].toLowerCase();
419+
}
420+
} else if (skiff_domains.indexOf(parts[1]) >= 0) {
421+
// Address is Skiff
422+
if (options.skiff_remove_subaddress) {
423+
parts[0] = parts[0].split('+')[0];
424+
}
425+
if (options.skiff_remove_dots) {
426+
parts[0] = parts[0].replace(/\.+/g, dotsReplacer);
427+
}
428+
if (!parts[0].length) {
429+
return false;
430+
}
431+
if (options.all_lowercase || options.skiff_lowercase) {
432+
parts[0] = parts[0].toLowerCase();
433+
}
434+
} else if (zoho_domains.indexOf(parts[1]) >= 0) {
435+
// Address is Zoho
436+
if (options.zoho_remove_subaddress) {
437+
parts[0] = parts[0].split('+')[0];
438+
}
439+
if (!parts[0].length) {
440+
return false;
441+
}
442+
if (options.all_lowercase || options.zoho_lowercase) {
443+
parts[0] = parts[0].toLowerCase();
444+
}
238445
} else if (options.all_lowercase) {
239446
// Any other address
240447
parts[0] = parts[0].toLowerCase();

0 commit comments

Comments
 (0)