Rework email validation to use isemail

Drop hand-crafted RegExp in favour of a 3rd-party module that supports
RFC5321, RFC5322 and other relevant standards.
This commit is contained in:
Miroslav Bajtoš 2016-09-06 12:50:03 +02:00
parent 6220d1f986
commit 9a75ee6f30
3 changed files with 28 additions and 9 deletions

View File

@ -9,6 +9,7 @@
var g = require('strong-globalize')(); var g = require('strong-globalize')();
var isEmail = require('isemail');
var loopback = require('../../lib/loopback'); var loopback = require('../../lib/loopback');
var utils = require('../../lib/utils'); var utils = require('../../lib/utils');
var path = require('path'); var path = require('path');
@ -752,10 +753,9 @@ module.exports = function(User) {
assert(loopback.AccessToken, 'AccessToken model must be defined before User model'); assert(loopback.AccessToken, 'AccessToken model must be defined before User model');
UserModel.accessToken = loopback.AccessToken; UserModel.accessToken = loopback.AccessToken;
// email validation regex UserModel.validate('email', emailValidator, {
var 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,}))$/; message: g.f('Must provide a valid email'),
});
UserModel.validatesFormatOf('email', { with: re, message: g.f('Must provide a valid email') });
// FIXME: We need to add support for uniqueness of composite keys in juggler // FIXME: We need to add support for uniqueness of composite keys in juggler
if (!(UserModel.settings.realmRequired || UserModel.settings.realmDelimiter)) { if (!(UserModel.settings.realmRequired || UserModel.settings.realmDelimiter)) {
@ -772,3 +772,14 @@ module.exports = function(User) {
User.setup(); User.setup();
}; };
function emailValidator(err, done) {
var value = this.email;
if (value == null)
return;
if (typeof value !== 'string')
return err('string');
if (value === '') return;
if (!isEmail(value))
return err('email');
}

View File

@ -48,6 +48,7 @@
"inflection": "^1.6.0", "inflection": "^1.6.0",
"loopback-connector-remote": "^2.0.0-alpha.1", "loopback-connector-remote": "^2.0.0-alpha.1",
"loopback-datasource-juggler": "^3.0.0-alpha.7", "loopback-datasource-juggler": "^3.0.0-alpha.7",
"isemail": "^1.2.0",
"loopback-phase": "^1.2.0", "loopback-phase": "^1.2.0",
"nodemailer": "^2.5.0", "nodemailer": "^2.5.0",
"nodemailer-stub-transport": "^1.0.0", "nodemailer-stub-transport": "^1.0.0",

View File

@ -120,10 +120,7 @@ describe('User', function() {
assert.equal(err.name, 'ValidationError'); assert.equal(err.name, 'ValidationError');
assert.equal(err.statusCode, 422); assert.equal(err.statusCode, 422);
assert.equal(err.details.context, User.modelName); assert.equal(err.details.context, User.modelName);
assert.deepEqual(err.details.codes.email, [ assert.deepEqual(err.details.codes.email, ['presence']);
'presence',
'format.null',
]);
done(); done();
}); });
@ -143,11 +140,21 @@ describe('User', function() {
it('Requires a valid email', function(done) { it('Requires a valid email', function(done) {
User.create({ email: 'foo@', password: '123' }, function(err) { User.create({ email: 'foo@', password: '123' }, function(err) {
assert(err); assert(err);
assert.equal(err.name, 'ValidationError');
assert.equal(err.statusCode, 422);
assert.equal(err.details.context, User.modelName);
assert.deepEqual(err.details.codes.email, ['custom.email']);
done(); done();
}); });
}); });
it('allows TLD domains in email', function() {
return User.create({
email: 'local@com',
password: '123',
});
});
it('Requires a unique email', function(done) { it('Requires a unique email', function(done) {
User.create({ email: 'a@b.com', password: 'foobar' }, function() { User.create({ email: 'a@b.com', password: 'foobar' }, function() {
User.create({ email: 'a@b.com', password: 'batbaz' }, function(err) { User.create({ email: 'a@b.com', password: 'batbaz' }, function(err) {