Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gmail validation to isEmail #832

Merged
merged 5 commits into from
May 16, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/isEmail.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var default_email_options = {
/* eslint-disable no-control-regex */
var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\,\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i;
var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
var gmailUserPart = /^[a-z\d](\.?[a-z\d])+$/;
Copy link
Collaborator

@chriso chriso May 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably vulnerable to ReDoS. To sidestep this, we split the user part by . and then test each part individually. Could you set the pattern we use to /^[a-z\d]+$/i when it's a gmail domain?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, i did put length checking before and not inside the regex to try to avoid ReDoS but testing each part individually is a better idea since i have found that dots don't count in length checking

var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;
var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i;
Expand Down Expand Up @@ -68,6 +69,17 @@ function isEmail(str, options) {
should be done in normalizeEmail
*/
user = user.toLowerCase();

// Removing sub-address from username before gmail validation
var username = user.split('+')[0];

if (!(0, _isByteLength2.default)(username, { min: 6, max: 30 })) {
return false;
}

if (!gmailUserPart.test(username)) {
return false;
}
}

if (!(0, _isByteLength2.default)(user, { max: 64 }) || !(0, _isByteLength2.default)(domain, { max: 254 })) {
Expand Down
12 changes: 12 additions & 0 deletions src/lib/isEmail.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const default_email_options = {
/* eslint-disable no-control-regex */
const displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\,\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i;
const emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
const gmailUserPart = /^[a-z\d](\.?[a-z\d])+$/;
const quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;
const emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
const quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i;
Expand Down Expand Up @@ -49,6 +50,17 @@ export default function isEmail(str, options) {
should be done in normalizeEmail
*/
user = user.toLowerCase();

// Removing sub-address from username before gmail validation
const username = user.split('+')[0];

if (!isByteLength(username, { min: 6, max: 30 })) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a source for the [6, 30] length restriction? and the alphanumeric char restriction?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find a link in google/gmail support except for G-suite users but both length and characters restrictions can be found in Gmail sign-up page

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

K, confirmed:

screen shot 2018-05-16 at 8 37 52 pm

screen shot 2018-05-16 at 8 37 42 pm

return false;
}

if (!gmailUserPart.test(username)) {
return false;
}
}

if (!isByteLength(user, { max: 64 }) ||
Expand Down
42 changes: 23 additions & 19 deletions test/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ describe('Validators', function () {
'hans.m端ller@test.com',
'hans@m端ller.com',
'test|123@m端ller.com',
'test+ext@gmail.com',
'some.name.midd.leNa.me.+extension@GoogleMail.com',
'test123+ext@gmail.com',
'some.name.midd.leNa.me+extension@GoogleMail.com',
'"foobar"@example.com',
'" foo m端ller "@example.com',
'"foo\\@bar"@example.com',
Expand All @@ -73,6 +73,7 @@ describe('Validators', function () {
`${repeat('a', 64)}@${repeat('a', 251)}.com`,
`${repeat('a', 65)}@${repeat('a', 250)}.com`,
`${repeat('a', 64)}@${repeat('a', 64)}.com`,
`${repeat('a', 31)}@gmail.com`,
'test1@invalid.co m',
'test2@invalid.co m',
'test3@invalid.co m',
Expand All @@ -87,6 +88,8 @@ describe('Validators', function () {
'test12@invalid.co m',
'test13@invalid.co m',
'gmail...ignores...dots...@gmail.com',
'test@gmail.com',
'ends.with.dot.@gmail.com',
'multiple..dots@gmail.com',
'multiple..dots@stillinvalid.com',
],
Expand All @@ -104,8 +107,8 @@ describe('Validators', function () {
'foo+bar@bar.com',
'hans@m端ller.com',
'test|123@m端ller.com',
'test+ext@gmail.com',
'some.name.midd.leNa.me.+extension@GoogleMail.com',
'test123+ext@gmail.com',
'some.name.midd.leNa.me+extension@GoogleMail.com',
'"foobar"@example.com',
'"foo\\@bar"@example.com',
'" foo bar "@example.com',
Expand Down Expand Up @@ -136,21 +139,21 @@ describe('Validators', function () {
'hans.m端ller@test.com',
'hans@m端ller.com',
'test|123@m端ller.com',
'test+ext@gmail.com',
'some.name.midd.leNa.me.+extension@GoogleMail.com',
'test123+ext@gmail.com',
'some.name.midd.leNa.me+extension@GoogleMail.com',
'Some Name <foo@bar.com>',
'Some Name <x@x.au>',
'Some Name <foo@bar.com.au>',
'Some Name <foo+bar@bar.com>',
'Some Name <hans.m端ller@test.com>',
'Some Name <hans@m端ller.com>',
'Some Name <test|123@m端ller.com>',
'Some Name <test+ext@gmail.com>',
'Some Name <test123+ext@gmail.com>',
'\'Foo Bar, Esq\'<foo@bar.com>',
'Some Name <some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Some Middle Name <some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Name <some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Name<some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Some Name <some.name.midd.leNa.me+extension@GoogleMail.com>',
'Some Middle Name <some.name.midd.leNa.me+extension@GoogleMail.com>',
'Name <some.name.midd.leNa.me+extension@GoogleMail.com>',
'Name<some.name.midd.leNa.me+extension@GoogleMail.com>',
],
invalid: [
'invalidemail@',
Expand All @@ -168,6 +171,7 @@ describe('Validators', function () {
'Some Name < foo@bar.co.uk >',
'Name foo@bar.co.uk',
'Some Name <some..name@gmail.com>',
'Some Name <foo@gmail.com>',
],
});
});
Expand All @@ -184,22 +188,22 @@ describe('Validators', function () {
'Some Name <hans.m端ller@test.com>',
'Some Name <hans@m端ller.com>',
'Some Name <test|123@m端ller.com>',
'Some Name <test+ext@gmail.com>',
'Some Name <some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Some Middle Name <some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Name <some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Name<some.name.midd.leNa.me.+extension@GoogleMail.com>',
'Some Name <test123+ext@gmail.com>',
'Some Name <some.name.midd.leNa.me+extension@GoogleMail.com>',
'Some Middle Name <some.name.midd.leNa.me+extension@GoogleMail.com>',
'Name <some.name.midd.leNa.me+extension@GoogleMail.com>',
'Name<some.name.midd.leNa.me+extension@GoogleMail.com>',
],
invalid: [
'some.name.midd.leNa.me.+extension@GoogleMail.com',
'some.name.midd.leNa.me+extension@GoogleMail.com',
'foo@bar.com',
'x@x.au',
'foo@bar.com.au',
'foo+bar@bar.com',
'hans.m端ller@test.com',
'hans@m端ller.com',
'test|123@m端ller.com',
'test+ext@gmail.com',
'test123+ext@gmail.com',
'invalidemail@',
'invalid.com',
'@invalid.com',
Expand Down Expand Up @@ -3016,7 +3020,7 @@ describe('Validators', function () {
});
for (var i = 0, str = '', encoded; i < 1000; i++) {
str += String.fromCharCode(Math.random() * 26 | 97);
encoded = new Buffer(str).toString('base64');
encoded = Buffer.from(str).toString('base64');
if (!validator.isBase64(encoded)) {
var msg = format('validator.isBase64() failed with "%s"', encoded);
throw new Error(msg);
Expand Down
12 changes: 12 additions & 0 deletions validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ var default_email_options = {
/* eslint-disable no-control-regex */
var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\,\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i;
var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
var gmailUserPart = /^[a-z\d](\.?[a-z\d])+$/;
var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;
var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i;
Expand Down Expand Up @@ -218,6 +219,17 @@ function isEmail(str, options) {
should be done in normalizeEmail
*/
user = user.toLowerCase();

// Removing sub-address from username before gmail validation
var username = user.split('+')[0];

if (!isByteLength(username, { min: 6, max: 30 })) {
return false;
}

if (!gmailUserPart.test(username)) {
return false;
}
}

if (!isByteLength(user, { max: 64 }) || !isByteLength(domain, { max: 254 })) {
Expand Down
2 changes: 1 addition & 1 deletion validator.min.js

Large diffs are not rendered by default.