From 7d7a8dc113c7dceb8b76c03e84d11cd04786ea8c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 15 May 2023 13:28:15 +0200 Subject: [PATCH] Relax constraints for UserID email address validity New checks align with the HTML5 W3C spec and should be more lax than the existing ones (meaning, addresses which passed validation before should continue to be valid). Addresses such as @localhost are now allowed too, since presence of "." is no longer enforced. These checks should not be considered exhaustive: library users are encouraged to implement separate checks for email validity if needed. --- src/util.js | 7 ++++++- test/general/openpgp.js | 10 +--------- test/general/util.js | 18 +++++++++++------- 3 files changed, 18 insertions(+), 17 deletions(-) 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; });