Relax constraints for UserID email address validity (#1641)

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.

Co-authored-by: Daniel Huigens <d.huigens@protonmail.com>
This commit is contained in:
larabr 2024-02-02 15:04:34 +01:00 committed by GitHub
parent 22c2682574
commit 3320eaccb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 19 additions and 17 deletions

View File

@ -457,11 +457,17 @@ const util = {
return os.cpus().length;
},
/**
* 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.
*/
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);
},

View File

@ -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 <text@example.com>'

View File

@ -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 (internationalized domain name)', 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 true for valid email address (no . in domain part)', function() {
const data = 'test@localhost';
expect(util.isEmailAddress(data)).to.be.true;
});
it('should return false for invalid email address (full userID)', function() {
const data = 'Test User <test@example.com>';
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;
});