diff --git a/src/util.js b/src/util.js index 47363c97..45db97e8 100644 --- a/src/util.js +++ b/src/util.js @@ -465,16 +465,19 @@ const util = { }, /** - * Test email format based on W3C HTML5 specification. - * This check is not exaustive, and does not match RFC 5322 exactly - * (see https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)), - * but is commonly used for email address validation. + * Test email format to ensure basic compliance: + * - must include a single @ + * - no control or space unicode chars allowed + * - no backslash and square brackets (as the latter can mess with the userID parsing) + * - cannot end with a punctuation char + * These checks are not meant to be exhaustive; applications are strongly encouraged to implement stricter validation, + * e.g. based on the W3C HTML spec (https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)). */ isEmailAddress: function(data) { if (!util.isString(data)) { return false; } - const re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; + const re = /^[^\p{C}\p{Z}@<>\\]+@[^\p{C}\p{Z}@<>\\]+[^\p{C}\p{Z}\p{P}]$/u; return re.test(data); }, diff --git a/test/general/util.js b/test/general/util.js index c17b88c8..5ba9b290 100644 --- a/test/general/util.js +++ b/test/general/util.js @@ -120,6 +120,10 @@ export default () => describe('Util unit tests', function() { const data = 'test@localhost'; expect(util.isEmailAddress(data)).to.be.true; }); + it('should return true for valid email address (unicode chars)', function() { + const data = '🙂@localhost'; + expect(util.isEmailAddress(data)).to.be.true; + }); it('should return false for invalid email address (full userID)', function() { const data = 'Test User '; expect(util.isEmailAddress(data)).to.be.false; @@ -128,6 +132,18 @@ export default () => describe('Util unit tests', function() { const data = 'testexamplecom'; expect(util.isEmailAddress(data)).to.be.false; }); + it('should return false for invalid email address (invisible unicode control char)', function() { + const data = 'test\u{feff}ctrl@email.it'; + expect(util.isEmailAddress(data)).to.be.false; + }); + it('should return false for invalid email address (trailing punctuation)', function() { + const data = 'test@localhost.'; + expect(util.isEmailAddress(data)).to.be.false; + }); + it('should return false for invalid email address (including whitespace)', function() { + const data = 'test space@email.it'; + expect(util.isEmailAddress(data)).to.be.false; + }); it('should return false for empty string', function() { const data = ''; expect(util.isEmailAddress(data)).to.be.false;