diff --git a/src/util.js b/src/util.js index 0a1c721d..0535c25a 100644 --- a/src/util.js +++ b/src/util.js @@ -457,11 +457,16 @@ const util = { return os.cpus().length; }, + /** + * Test email format based on W3C HTML5 specification. + * This check is not exaustive, and includes a willful violation of RFC5322 + * (see https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)) + */ isEmailAddress: function(data) { if (!util.isString(data)) { return false; } - const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+([a-zA-Z]{2,}[0-9]*|xn--[a-zA-Z\-0-9]+)))$/; + 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])?)*$/; return re.test(data); }, diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 008cc713..73146a47 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -958,7 +958,7 @@ export default () => describe('OpenPGP.js public api tests', function() { await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); }); - it('should fail for invalid user email address', async function() { + it('should fail for invalid user email address (missing @)', async function() { const opt = { userIDs: [{ name: 'Test User', email: 'textexample.com' }] }; @@ -966,14 +966,6 @@ export default () => describe('OpenPGP.js public api tests', function() { await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); }); - it('should fail for invalid user email address', async function() { - const opt = { - userIDs: [{ name: 'Test User', email: 'text@examplecom' }] - }; - const test = openpgp.generateKey(opt); - await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); - }); - it('should fail for string user ID', async function() { const opt = { userIDs: 'Test User ' diff --git a/test/general/util.js b/test/general/util.js index 25dab192..5bf765c9 100644 --- a/test/general/util.js +++ b/test/general/util.js @@ -108,19 +108,23 @@ export default () => describe('Util unit tests', function() { const data = 'test@example.com'; expect(util.isEmailAddress(data)).to.be.true; }); - it('should return true for valid email address', function() { + it('should return true for valid email address (-- in domain part)', function() { const data = 'test@xn--wgv.xn--q9jyb4c'; expect(util.isEmailAddress(data)).to.be.true; }); - it('should return false for invalid email address', function() { + it('should return true for valid email address (trailing numbers in domain)', function() { + const data = 'test1@com.com09'; + expect(util.isEmailAddress(data)).to.be.true; + }); + it('should return false for invalid email address (no . in domain part)', function() { + const data = 'test@examplecom'; + 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; }); - it('should return false for invalid email address', function() { - const data = 'test@examplecom'; - expect(util.isEmailAddress(data)).to.be.false; - }); - it('should return false for invalid email address', function() { + it('should return false for invalid email address (missing @)', function() { const data = 'testexamplecom'; expect(util.isEmailAddress(data)).to.be.false; });