diff --git a/public/src/utils.js b/public/src/utils.js index 44d348b096..34a4224762 100644 --- a/public/src/utils.js +++ b/public/src/utils.js @@ -126,18 +126,17 @@ return str; }, - // from http://stackoverflow.com/questions/46155/validate-email-address-in-javascript + isEmailValid: function(email) { - // var re = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; - return email.indexOf('@') !== -1; + return typeof email === 'string' && email.length && email.indexOf('@') !== -1; }, isUserNameValid: function(name) { - return (name && name !== "" && (/^['"\s\-.*0-9\u00BF-\u1FFF\u2C00-\uD7FF\w]+$/.test(name))); + return (name && name !== '' && (/^['"\s\-.*0-9\u00BF-\u1FFF\u2C00-\uD7FF\w]+$/.test(name))); }, isPasswordValid: function(password) { - return password && password.indexOf(' ') === -1; + return typeof password === 'string' && password.length && password.indexOf(' ') === -1; }, isNumber: function(n) { diff --git a/src/user.js b/src/user.js index 0d1c25c064..32bba3d6ce 100644 --- a/src/user.js +++ b/src/user.js @@ -24,6 +24,7 @@ var bcrypt = require('bcryptjs'), User.notifications = require('./user/notifications'); User.reset = require('./user/reset'); + require('./user/create')(User); require('./user/follow')(User); require('./user/profile')(User); require('./user/admin')(User); @@ -31,136 +32,6 @@ var bcrypt = require('bcryptjs'), require('./user/settings')(User); require('./user/search')(User); - User.create = function(userData, callback) { - userData = userData || {}; - userData.userslug = utils.slugify(userData.username); - - userData.username = userData.username.trim(); - if (userData.email !== undefined) { - userData.email = userData.email.trim(); - userData.email = validator.escape(userData.email); - } - - async.parallel([ - function(next) { - if (userData.email) { - next(!utils.isEmailValid(userData.email) ? new Error('Invalid Email!') : null); - } else { - next(); - } - }, - function(next) { - next((!utils.isUserNameValid(userData.username) || !userData.userslug) ? new Error('Invalid Username!') : null); - }, - function(next) { - if (userData.password) { - next(!utils.isPasswordValid(userData.password) ? new Error('Invalid Password!') : null); - } else { - next(); - } - }, - function(next) { - User.exists(userData.userslug, function(err, exists) { - if (err) { - return next(err); - } - next(exists ? new Error('Username taken!') : null); - }); - }, - function(next) { - if (userData.email) { - User.email.available(userData.email, function(err, available) { - if (err) { - return next(err); - } - next(!available ? new Error('Email taken!') : null); - }); - } else { - next(); - } - }, - function(next) { - plugins.fireHook('filter:user.create', userData, function(err, filteredUserData){ - next(err, utils.merge(userData, filteredUserData)); - }); - } - ], function(err, results) { - if (err) { - return callback(err); - } - userData = results[results.length - 1]; - - db.incrObjectField('global', 'nextUid', function(err, uid) { - if(err) { - return callback(err); - } - - var gravatar = User.createGravatarURLFromEmail(userData.email); - var timestamp = Date.now(); - var password = userData.password; - - userData = { - 'uid': uid, - 'username': userData.username, - 'userslug': userData.userslug, - 'fullname': '', - 'location': '', - 'birthday': '', - 'website': '', - 'email': userData.email || '', - 'signature': '', - 'joindate': timestamp, - 'picture': gravatar, - 'gravatarpicture': gravatar, - 'uploadedpicture': '', - 'profileviews': 0, - 'reputation': 0, - 'postcount': 0, - 'lastposttime': 0, - 'banned': 0, - 'status': 'online' - }; - - db.setObject('user:' + uid, userData, function(err) { - - if(err) { - return callback(err); - } - db.setObjectField('username:uid', userData.username, uid); - db.setObjectField('userslug:uid', userData.userslug, uid); - - if (userData.email !== undefined) { - db.setObjectField('email:uid', userData.email, uid); - if (parseInt(uid, 10) !== 1) { - User.email.verify(uid, userData.email); - } - } - - plugins.fireHook('action:user.create', userData); - db.incrObjectField('global', 'userCount'); - - db.sortedSetAdd('users:joindate', timestamp, uid); - db.sortedSetAdd('users:postcount', 0, uid); - db.sortedSetAdd('users:reputation', 0, uid); - - groups.joinByGroupName('registered-users', uid); - - if (password) { - User.hashPassword(password, function(err, hash) { - if(err) { - return callback(err); - } - - User.setUserField(uid, 'password', hash); - callback(null, uid); - }); - } else { - callback(null, uid); - } - }); - }); - }); - }; User.getUserField = function(uid, field, callback) { db.getObjectField('user:' + uid, field, callback); @@ -329,7 +200,7 @@ var bcrypt = require('bcryptjs'), User.hashPassword = function(password, callback) { if (!password) { - return callback(password); + return callback(null, password); } bcrypt.genSalt(nconf.get('bcrypt_rounds'), function(err, salt) { diff --git a/src/user/create.js b/src/user/create.js new file mode 100644 index 0000000000..6e39ae047a --- /dev/null +++ b/src/user/create.js @@ -0,0 +1,134 @@ +'use strict'; + +var async = require('async'), + db = require('./../database'), + utils = require('./../../public/src/utils'), + validator = require('validator'), + plugins = require('./../plugins'), + groups = require('./../groups'); + +module.exports = function(User) { + + User.create = function(userData, callback) { + userData = userData || {}; + userData.userslug = utils.slugify(userData.username); + + userData.username = userData.username.trim(); + if (userData.email !== undefined) { + userData.email = userData.email.trim(); + userData.email = validator.escape(userData.email); + } + + async.parallel([ + function(next) { + next(!utils.isEmailValid(userData.email) ? new Error('Invalid Email!') : null); + }, + function(next) { + next((!utils.isUserNameValid(userData.username) || !userData.userslug) ? new Error('Invalid Username!') : null); + }, + function(next) { + next(!utils.isPasswordValid(userData.password) ? new Error('Invalid Password!') : null); + }, + function(next) { + User.exists(userData.userslug, function(err, exists) { + if (err) { + return next(err); + } + next(exists ? new Error('Username taken!') : null); + }); + }, + function(next) { + if (userData.email) { + User.email.available(userData.email, function(err, available) { + if (err) { + return next(err); + } + next(!available ? new Error('Email taken!') : null); + }); + } else { + next(); + } + }, + function(next) { + plugins.fireHook('filter:user.create', userData, function(err, filteredUserData){ + next(err, utils.merge(userData, filteredUserData)); + }); + } + ], function(err, results) { + if (err) { + return callback(err); + } + userData = results[results.length - 1]; + + db.incrObjectField('global', 'nextUid', function(err, uid) { + if(err) { + return callback(err); + } + + var gravatar = User.createGravatarURLFromEmail(userData.email); + var timestamp = Date.now(); + var password = userData.password; + + userData = { + 'uid': uid, + 'username': userData.username, + 'userslug': userData.userslug, + 'fullname': '', + 'location': '', + 'birthday': '', + 'website': '', + 'email': userData.email || '', + 'signature': '', + 'joindate': timestamp, + 'picture': gravatar, + 'gravatarpicture': gravatar, + 'uploadedpicture': '', + 'profileviews': 0, + 'reputation': 0, + 'postcount': 0, + 'lastposttime': 0, + 'banned': 0, + 'status': 'online' + }; + + db.setObject('user:' + uid, userData, function(err) { + + if(err) { + return callback(err); + } + db.setObjectField('username:uid', userData.username, uid); + db.setObjectField('userslug:uid', userData.userslug, uid); + + if (userData.email !== undefined) { + db.setObjectField('email:uid', userData.email, uid); + if (parseInt(uid, 10) !== 1) { + User.email.verify(uid, userData.email); + } + } + + plugins.fireHook('action:user.create', userData); + db.incrObjectField('global', 'userCount'); + + db.sortedSetAdd('users:joindate', timestamp, uid); + db.sortedSetAdd('users:postcount', 0, uid); + db.sortedSetAdd('users:reputation', 0, uid); + + groups.joinByGroupName('registered-users', uid); + + if (password) { + User.hashPassword(password, function(err, hash) { + if(err) { + return callback(err); + } + + User.setUserField(uid, 'password', hash); + callback(null, uid); + }); + } else { + callback(null, uid); + } + }); + }); + }); + }; +}; \ No newline at end of file