2014-03-31 11:46:28 -04:00
sanitize = require ( ' sanitizer ' )
2014-04-10 09:43:06 -04:00
User = require ( " ../../models/User " ) . User
UserCreator = require ( " ./UserCreator " )
AuthenticationManager = require ( " ../Authentication/AuthenticationManager " )
2014-04-10 17:21:20 -04:00
NewsLetterManager = require ( " ../Newsletter/NewsletterManager " )
2014-04-10 09:43:06 -04:00
async = require ( " async " )
logger = require ( " logger-sharelatex " )
2015-12-11 12:11:13 -05:00
crypto = require ( " crypto " )
EmailHandler = require ( " ../Email/EmailHandler " )
OneTimeTokenHandler = require " ../Security/OneTimeTokenHandler "
2016-08-11 07:29:58 -04:00
Analytics = require " ../Analytics/AnalyticsManager "
2015-12-11 12:11:13 -05:00
settings = require " settings-sharelatex "
2014-02-12 05:23:40 -05:00
2015-12-11 12:11:13 -05:00
module.exports = UserRegistrationHandler =
2014-02-12 05:23:40 -05:00
validateEmail : (email) ->
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,}))$/
return re . test ( email )
hasZeroLengths : (props) ->
hasZeroLength = false
props . forEach (prop) ->
if prop . length == 0
hasZeroLength = true
return hasZeroLength
2014-04-10 09:43:06 -04:00
_registrationRequestIsValid : (body, callback)->
email = sanitize . escape ( body . email ) . trim ( ) . toLowerCase ( )
password = body . password
2014-02-12 05:23:40 -05:00
username = email . match ( /^[^@]*/ )
if @ hasZeroLengths ( [ password , email ] )
2014-04-10 09:43:06 -04:00
return false
2014-02-12 05:23:40 -05:00
else if ! @ validateEmail ( email )
2014-04-10 09:43:06 -04:00
return false
2014-02-12 05:23:40 -05:00
else
2014-04-10 09:43:06 -04:00
return true
2014-04-10 07:39:13 -04:00
2014-04-10 09:43:06 -04:00
_createNewUserIfRequired: (user, userDetails, callback)->
if ! user ?
2016-06-13 08:21:44 -04:00
userDetails.holdingAccount = false
2016-06-13 08:38:17 -04:00
UserCreator . createNewUser { holdingAccount : false , email : userDetails . email , first_name : userDetails . first_name , last_name : userDetails . last_name } , callback
2014-04-10 09:43:06 -04:00
else
callback null , user
2014-04-10 07:39:13 -04:00
registerNewUser: (userDetails, callback)->
2014-04-10 09:43:06 -04:00
self = @
requestIsValid = @ _registrationRequestIsValid userDetails
if ! requestIsValid
2015-03-18 12:19:48 -04:00
return callback ( new Error ( " request is not valid " ) )
2014-04-10 09:43:06 -04:00
userDetails.email = userDetails . email ? . trim ( ) ? . toLowerCase ( )
User . findOne email : userDetails . email , (err, user)->
if err ?
return callback err
if user ? . holdingAccount == false
2015-03-19 10:22:48 -04:00
return callback ( new Error ( " EmailAlreadyRegistered " ) , user )
2014-04-10 09:43:06 -04:00
self . _createNewUserIfRequired user , userDetails , (err, user)->
if err ?
return callback ( err )
async . series [
(cb)-> User . update { _id: user . _id } , { " $set " : { holdingAccount : false } } , cb
(cb)-> AuthenticationManager . setUserPassword user . _id , userDetails . password , cb
2015-02-23 11:03:45 -05:00
(cb)->
NewsLetterManager . subscribe user , ->
cb ( ) #this can be slow, just fire it off
2014-04-10 09:43:06 -04:00
] , (err)->
logger . log user: user , " registered "
2016-08-11 07:29:58 -04:00
Analytics . recordEvent user . _id , " user-registered "
2014-04-10 09:43:06 -04:00
callback ( err , user )
2015-12-11 12:11:13 -05:00
registerNewUserAndSendActivationEmail: ( email , callback = (error, user, setNewPasswordUrl) -> ) ->
logger . log { email } , " registering new user "
UserRegistrationHandler . registerNewUser {
email: email
password: crypto . randomBytes ( 32 ) . toString ( " hex " )
} , (err, user)->
if err ? and err ? . message != " EmailAlreadyRegistered "
2016-02-16 06:12:07 -05:00
return callback ( err )
2015-12-11 12:11:13 -05:00
if err ? . message == " EmailAlreadyRegistered "
logger . log { email } , " user already exists, resending welcome email "
ONE_WEEK = 7 * 24 * 60 * 60 # seconds
OneTimeTokenHandler . getNewToken user . _id , { expiresIn: ONE_WEEK } , (err, token)->
2016-02-16 06:12:07 -05:00
return callback ( err ) if err ?
2015-12-11 12:11:13 -05:00
setNewPasswordUrl = " #{ settings . siteUrl } /user/activate?token= #{ token } &user_id= #{ user . _id } "
EmailHandler . sendEmail " registered " , {
to: user . email
setNewPasswordUrl: setNewPasswordUrl
} , () ->
callback null , user , setNewPasswordUrl
2014-04-10 09:43:06 -04:00
2014-04-10 07:39:13 -04:00