diff --git a/app/public/js/controllers/activatedController.js b/app/public/js/controllers/activatedController.js new file mode 100644 index 00000000..f0493dd4 --- /dev/null +++ b/app/public/js/controllers/activatedController.js @@ -0,0 +1,7 @@ + +function ActivatedController() +{ + +// redirect to homepage on account activation, add short delay so user can read alert window // + $('.modal-alert #ok').click(function(){ setTimeout(function(){window.location.href = '/';}, 300)}); +} \ No newline at end of file diff --git a/app/public/js/form-validators/accountValidator.js b/app/public/js/form-validators/accountValidator.js index 6de2dfcf..62e99528 100644 --- a/app/public/js/form-validators/accountValidator.js +++ b/app/public/js/form-validators/accountValidator.js @@ -3,8 +3,8 @@ function AccountValidator(){ // build array maps of the form inputs & control groups // - this.formFields = [$('#name-tf'), $('#email-tf'), $('#user-tf'), $('#pass-tf')]; - this.controlGroups = [$('#name-cg'), $('#email-cg'), $('#user-cg'), $('#pass-cg')]; + this.formFields = [$('#name-tf'), $('#email-tf'), $('#user-tf'), $('#pass-tf'), $('#pass-confirm-tf')]; + this.controlGroups = [$('#name-cg'), $('#email-cg'), $('#user-cg'), $('#pass-cg'), $('#pass-confirm-cg')]; // bind the form-error modal window to this controller to display any errors // @@ -73,6 +73,10 @@ AccountValidator.prototype.validateForm = function() this.controlGroups[3].addClass('error'); e.push('Password Should Be At Least 6 Characters'); } + if (this.formFields[4].val() != this.formFields[3].val()) { + this.controlGroups[4].addClass('error'); + e.push('Passwords don\'t match'); + } if (e.length) this.showErrors(e); return e.length === 0; } diff --git a/app/public/js/views/activated.js b/app/public/js/views/activated.js new file mode 100644 index 00000000..19c4bcef --- /dev/null +++ b/app/public/js/views/activated.js @@ -0,0 +1,13 @@ + +$(document).ready(function(){ + + var ac = new ActivatedController(); + + $('.modal-alert').modal('show'); +// setup the alert that displays when an account has been activated // + + $('.modal-alert').modal({ show : false, keyboard : false, backdrop : 'static' }); + $('.modal-alert .modal-header h3').text('Activated!'); + $('.modal-alert .modal-body p').html('Your account has been activated.Click OK to return to the login page.'); + +}) \ No newline at end of file diff --git a/app/public/js/views/activation-failed.js b/app/public/js/views/activation-failed.js new file mode 100644 index 00000000..4e201674 --- /dev/null +++ b/app/public/js/views/activation-failed.js @@ -0,0 +1,13 @@ + +$(document).ready(function(){ + + var ac = new ActivatedController(); + + $('.modal-alert').modal('show'); +// setup the alert that displays when an account has not been activated // + + $('.modal-alert').modal({ show : false, keyboard : false, backdrop : 'static' }); + $('.modal-alert .modal-header h3').text('Activation Failed.'); + $('.modal-alert .modal-body p').html('The activation code provided was invalid.Click OK to return to the login page.'); + +}) \ No newline at end of file diff --git a/app/public/js/views/signup.js b/app/public/js/views/signup.js index 52de1978..25ace8fb 100644 --- a/app/public/js/views/signup.js +++ b/app/public/js/views/signup.js @@ -34,6 +34,6 @@ $(document).ready(function(){ $('.modal-alert').modal({ show : false, keyboard : false, backdrop : 'static' }); $('.modal-alert .modal-header h3').text('Success!'); - $('.modal-alert .modal-body p').html('Your account has been created.Click OK to return to the login page.'); + $('.modal-alert .modal-body p').html('Please check your email for a verification link which will confirm your email address.Click OK to return to the login page.'); }) \ No newline at end of file diff --git a/app/server/modules/account-manager.js b/app/server/modules/account-manager.js index 71ea3f8d..0f1b9792 100644 --- a/app/server/modules/account-manager.js +++ b/app/server/modules/account-manager.js @@ -24,7 +24,7 @@ var accounts = db.collection('accounts'); exports.autoLogin = function(user, pass, callback) { - accounts.findOne({user:user}, function(e, o) { + accounts.findOne({user:user, activated:true}, function(e, o) { if (o){ o.pass == pass ? callback(o) : callback(null); } else{ @@ -35,7 +35,7 @@ exports.autoLogin = function(user, pass, callback) exports.manualLogin = function(user, pass, callback) { - accounts.findOne({user:user}, function(e, o) { + accounts.findOne({user:user, activated:true}, function(e, o) { if (o == null){ callback('user-not-found'); } else{ @@ -64,9 +64,19 @@ exports.addNewAccount = function(newData, callback) } else{ saltAndHash(newData.pass, function(hash){ newData.pass = hash; - // append date stamp when record was created // - newData.date = moment().format('MMMM Do YYYY, h:mm:ss a'); - accounts.insert(newData, {safe: true}, callback); + saltAndHash(newData.user, function(hash){ + newData.activationCode = hash; + newData.activated = false; + // append date stamp when record was created // + newData.date = moment().format('MMMM Do YYYY, h:mm:ss a'); + accounts.insert(newData, {safe: true}, function(e,o){ + if (o.length > 0){ + callback(e,o[0]); + } else{ + callback(e, null); + } + }); + }); }); } }); @@ -74,9 +84,23 @@ exports.addNewAccount = function(newData, callback) }); } +exports.activateAccount = function(activationCode, callback) +{ + accounts.findOne({activationCode:activationCode, activated:false}, function(e, o) { + if(!o){ + callback('invalid-activation-code', null); + } else{ + o.activated = true; + accounts.save(o, {safe: true}, function(err, o){ + callback(err, o); + }); + } + }); +} + exports.updateAccount = function(newData, callback) { - accounts.findOne({user:newData.user}, function(e, o){ + accounts.findOne({user:newData.user, activated:true}, function(e, o){ o.name = newData.name; o.email = newData.email; o.country = newData.country; @@ -151,10 +175,10 @@ var md5 = function(str) { return crypto.createHash('md5').update(str).digest('hex'); } -var saltAndHash = function(pass, callback) +var saltAndHash = function(data, callback) { var salt = generateSalt(); - callback(salt + md5(pass + salt)); + callback(salt + md5(data + salt)); } var validatePassword = function(plainPass, hashedPass, callback) diff --git a/app/server/modules/email-dispatcher.js b/app/server/modules/email-dispatcher.js index 3918d0bb..ca5ab5bc 100644 --- a/app/server/modules/email-dispatcher.js +++ b/app/server/modules/email-dispatcher.js @@ -19,11 +19,11 @@ EM.dispatchResetPasswordLink = function(account, callback) to : account.email, subject : 'Password Reset', text : 'something went wrong... :(', - attachment : EM.composeEmail(account) + attachment : EM.composePasswordResetEmail(account) }, callback ); } -EM.composeEmail = function(o) +EM.composePasswordResetEmail = function(o) { var link = 'http://node-login.braitsch.io/reset-password?e='+o.email+'&p='+o.pass; var html = "
"; @@ -34,4 +34,28 @@ EM.composeEmail = function(o) html += "braitsch