| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var async = require('async'), | 
					
						
							| 
									
										
										
										
											2014-04-15 00:17:35 -04:00
										 |  |  | 	db = require('../database'), | 
					
						
							|  |  |  | 	utils = require('../../public/src/utils'), | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 	validator = require('validator'), | 
					
						
							| 
									
										
										
										
											2014-04-15 00:17:35 -04:00
										 |  |  | 	plugins = require('../plugins'), | 
					
						
							|  |  |  | 	groups = require('../groups'), | 
					
						
							| 
									
										
										
										
											2014-05-22 10:21:01 -04:00
										 |  |  | 	meta = require('../meta'), | 
					
						
							| 
									
										
										
										
											2014-04-15 00:17:35 -04:00
										 |  |  | 	notifications = require('../notifications'), | 
					
						
							|  |  |  | 	translator = require('../../public/src/translator'); | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = function(User) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 18:07:56 -04:00
										 |  |  | 	User.create = function(data, callback) { | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		data.username = data.username.trim(); | 
					
						
							|  |  |  | 		data.userslug = utils.slugify(data.username); | 
					
						
							|  |  |  | 		if (data.email !== undefined) { | 
					
						
							|  |  |  | 			data.email = validator.escape(data.email.trim()); | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 		isDataValid(data, function(err) { | 
					
						
							|  |  |  | 			if (err)  { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			var gravatar = User.createGravatarURLFromEmail(data.email); | 
					
						
							|  |  |  | 			var timestamp = Date.now(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var userData = { | 
					
						
							| 
									
										
										
										
											2014-10-28 18:41:34 -04:00
										 |  |  | 				'username': data.username, | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 				'userslug': data.userslug, | 
					
						
							|  |  |  | 				'email': data.email, | 
					
						
							|  |  |  | 				'joindate': timestamp, | 
					
						
							|  |  |  | 				'picture': gravatar, | 
					
						
							|  |  |  | 				'gravatarpicture': gravatar, | 
					
						
							|  |  |  | 				'fullname': '', | 
					
						
							|  |  |  | 				'location': '', | 
					
						
							|  |  |  | 				'birthday': '', | 
					
						
							|  |  |  | 				'website': '', | 
					
						
							|  |  |  | 				'signature': '', | 
					
						
							|  |  |  | 				'uploadedpicture': '', | 
					
						
							|  |  |  | 				'profileviews': 0, | 
					
						
							|  |  |  | 				'reputation': 0, | 
					
						
							|  |  |  | 				'postcount': 0, | 
					
						
							|  |  |  | 				'lastposttime': 0, | 
					
						
							|  |  |  | 				'banned': 0, | 
					
						
							|  |  |  | 				'status': 'online' | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			async.parallel({ | 
					
						
							|  |  |  | 				renamedUsername: function(next) { | 
					
						
							|  |  |  | 					renameUsername(userData, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				customFields: function(next) { | 
					
						
							|  |  |  | 					plugins.fireHook('filter:user.custom_fields', [], next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				userData: function(next) { | 
					
						
							|  |  |  | 					plugins.fireHook('filter:user.create', userData, next); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}, function(err, results) { | 
					
						
							|  |  |  | 				if (err) { | 
					
						
							|  |  |  | 					return callback(err); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var customData = {}; | 
					
						
							|  |  |  | 				results.customFields.forEach(function(customField) { | 
					
						
							|  |  |  | 					if (data[customField]) { | 
					
						
							|  |  |  | 						customData[customField] = data[customField]; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				userData = utils.merge(results.userData, customData); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var userNameChanged = !!results.renamedUsername; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (userNameChanged) { | 
					
						
							|  |  |  | 					userData.username = results.renamedUsername; | 
					
						
							|  |  |  | 					userData.userslug = utils.slugify(results.renamedUsername); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				async.waterfall([ | 
					
						
							|  |  |  | 					function(next) { | 
					
						
							|  |  |  | 						db.incrObjectField('global', 'nextUid', next); | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					function(uid, next) { | 
					
						
							|  |  |  | 						userData.uid = uid; | 
					
						
							|  |  |  | 						db.setObject('user:' + uid, userData, next); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				], function(err) { | 
					
						
							|  |  |  | 					if (err) { | 
					
						
							|  |  |  | 						return callback(err); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					async.parallel([ | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							|  |  |  | 							db.incrObjectField('global', 'userCount', next); | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							|  |  |  | 							db.setObjectField('username:uid', userData.username, userData.uid, next); | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							|  |  |  | 							db.setObjectField('userslug:uid', userData.userslug, userData.uid, next); | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							|  |  |  | 							db.sortedSetAdd('users:joindate', timestamp, userData.uid, next); | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							|  |  |  | 							db.sortedSetsAdd(['users:postcount', 'users:reputation'], 0, userData.uid, next); | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							|  |  |  | 							groups.join('registered-users', userData.uid, next); | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							| 
									
										
										
										
											2014-12-08 16:28:30 -05:00
										 |  |  | 							if (userData.email) { | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 								db.setObjectField('email:uid', userData.email.toLowerCase(), userData.uid, next); | 
					
						
							|  |  |  | 								if (parseInt(userData.uid, 10) !== 1 && parseInt(meta.config.requireEmailConfirmation, 10) === 1) { | 
					
						
							|  |  |  | 									User.email.verify(userData.uid, userData.email); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								next(); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						function(next) { | 
					
						
							|  |  |  | 							if (!data.password) { | 
					
						
							|  |  |  | 								return next(); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							User.hashPassword(data.password, function(err, hash) { | 
					
						
							|  |  |  | 								if (err) { | 
					
						
							|  |  |  | 									return next(err); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								User.setUserField(userData.uid, 'password', hash, next); | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					], function(err) { | 
					
						
							|  |  |  | 						if (err) { | 
					
						
							|  |  |  | 							return callback(err); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (userNameChanged) { | 
					
						
							|  |  |  | 							User.notifications.sendNameChangeNotification(userData.uid, userData.username); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						plugins.fireHook('action:user.create', userData); | 
					
						
							|  |  |  | 						callback(null, userData.uid); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function isDataValid(userData, callback) { | 
					
						
							| 
									
										
										
										
											2014-07-23 16:49:32 -04:00
										 |  |  | 		async.parallel({ | 
					
						
							|  |  |  | 			emailValid: function(next) { | 
					
						
							| 
									
										
										
										
											2014-04-07 20:19:40 -04:00
										 |  |  | 				if (userData.email) { | 
					
						
							| 
									
										
										
										
											2014-04-09 22:26:23 -04:00
										 |  |  | 					next(!utils.isEmailValid(userData.email) ? new Error('[[error:invalid-email]]') : null); | 
					
						
							| 
									
										
										
										
											2014-04-07 20:19:40 -04:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					next(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2014-07-23 16:49:32 -04:00
										 |  |  | 			userNameValid: function(next) { | 
					
						
							| 
									
										
										
										
											2014-04-09 22:26:23 -04:00
										 |  |  | 				next((!utils.isUserNameValid(userData.username) || !userData.userslug) ? new Error('[[error:invalid-username]]') : null); | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2014-07-23 16:49:32 -04:00
										 |  |  | 			passwordValid: function(next) { | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 				if (userData.password) { | 
					
						
							|  |  |  | 					next(!utils.isPasswordValid(userData.password) ? new Error('[[error:invalid-password]]') : null); | 
					
						
							| 
									
										
										
										
											2014-03-18 20:21:24 -04:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					next(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2014-07-23 16:49:32 -04:00
										 |  |  | 			emailAvailable: function(next) { | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 				if (userData.email) { | 
					
						
							|  |  |  | 					User.email.available(userData.email, function(err, available) { | 
					
						
							|  |  |  | 						if (err) { | 
					
						
							|  |  |  | 							return next(err); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-04-09 22:26:23 -04:00
										 |  |  | 						next(!available ? new Error('[[error:email-taken]]') : null); | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 					}); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					next(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 		}, callback); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 	function renameUsername(userData, callback) { | 
					
						
							|  |  |  | 		meta.userOrGroupExists(userData.userslug, function(err, exists) { | 
					
						
							|  |  |  | 			if (err || !exists) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							| 
									
										
										
										
											2014-04-15 00:17:35 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 			var	newUsername = ''; | 
					
						
							|  |  |  | 			async.forever(function(next) { | 
					
						
							|  |  |  | 				newUsername = userData.username + (Math.floor(Math.random() * 255) + 1); | 
					
						
							|  |  |  | 				User.exists(newUsername, function(err, exists) { | 
					
						
							| 
									
										
										
										
											2014-08-11 16:26:20 -04:00
										 |  |  | 					if (err) { | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 						return callback(err); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 					if (!exists) { | 
					
						
							|  |  |  | 						next(newUsername); | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 						next(); | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 			}, function(username) { | 
					
						
							|  |  |  | 				callback(null, username); | 
					
						
							| 
									
										
										
										
											2014-03-17 21:47:37 -04:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-10-28 18:28:26 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 20:31:57 +01:00
										 |  |  | }; |