Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/public/js/controllers/activatedController.js
Original file line number Diff line number Diff line change
@@ -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)});
}
8 changes: 6 additions & 2 deletions app/public/js/form-validators/accountValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 //

Expand Down Expand Up @@ -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;
}
Expand Down
13 changes: 13 additions & 0 deletions app/public/js/views/activated.js
Original file line number Diff line number Diff line change
@@ -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.</br>Click OK to return to the login page.');

})
13 changes: 13 additions & 0 deletions app/public/js/views/activation-failed.js
Original file line number Diff line number Diff line change
@@ -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.</br>Click OK to return to the login page.');

})
2 changes: 1 addition & 1 deletion app/public/js/views/signup.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.</br>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.</br>Click OK to return to the login page.');

})
40 changes: 32 additions & 8 deletions app/server/modules/account-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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{
Expand Down Expand Up @@ -64,19 +64,43 @@ 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);
}
});
});
});
}
});
}
});
}

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;
Expand Down Expand Up @@ -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)
Expand Down
28 changes: 26 additions & 2 deletions app/server/modules/email-dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "<html><body>";
Expand All @@ -34,4 +34,28 @@ EM.composeEmail = function(o)
html += "<a href='http://twitter.com/braitsch'>braitsch</a><br><br>";
html += "</body></html>";
return [{data:html, alternative:true}];
}

EM.dispatchActivationLink = function(account, callback)
{
EM.server.send({
from : ES.sender,
to : account.email,
subject : 'Account Activation',
text : 'something went wrong... :(',
attachment : EM.composeActivationEmail(account)
}, callback );
}

EM.composeActivationEmail = function(o)
{
var link = 'http://node-login.braitsch.io/activation?c='+o.activationCode;
var html = "<html><body>";
html += "Hi "+o.name+",<br><br>";
html += "Your username is :: <b>"+o.user+"</b><br><br>";
html += "<a href='"+link+"'>Please click here to activate your account</a><br><br>";
html += "Cheers,<br>";
html += "<a href='http://twitter.com/braitsch'>braitsch</a><br><br>";
html += "</body></html>";
return [{data:html, alternative:true}];
}
29 changes: 28 additions & 1 deletion app/server/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,42 @@ module.exports = function(app) {
user : req.param('user'),
pass : req.param('pass'),
country : req.param('country')
}, function(e){
}, function(e,o){
if (e){
res.send(e, 400);
} else{
res.send('ok', 200);
EM.dispatchActivationLink(o, function(e, m){
// this callback takes a moment to return //
// should add an ajax loader to give user feedback //
if (!e) {
// res.send('ok', 200);
} else{
res.send('email-server-error', 400);
for (k in e) console.log('error : ', k, e[k]);
}
});
}
});
});

// activating account //

app.get('/activation', function(req, res) {
if (req.param('c', null))
{
AM.activateAccount(req.param('c'),function(e, o){
if (o){
res.render('activated', { title: 'Activation'});
} else{
res.render('activation-failed', { title: 'Activation' });
}
});
} else{
res.send("activation code required", 400);
}
});

// password reset //

app.post('/lost-password', function(req, res){
Expand Down
4 changes: 4 additions & 0 deletions app/server/views/account.jade
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ input(type='hidden', value= user._id)#userId
label.control-label(for='pass-tf') Password
.controls
input#pass-tf.input-xlarge(type='password', name='pass', value='')
#pass-confirm-cg.control-group
label.control-label(for='pass-confirm-tf') Confirm
.controls
input#pass-confirm-tf.input-xlarge(type='password', name='pass-confirm', value='')
.form-actions
button(type='button')#account-form-btn1.btn
button(type='submit')#account-form-btn2.btn
Expand Down
13 changes: 13 additions & 0 deletions app/server/views/activated.jade
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

extends layout

block content
include modals/alert

block scripts
script(src='/vendor/jquery.min.js')
script(src='/vendor/jquery.form.js')
script(src='/vendor/bootstrap-modal.js')
script(src='/vendor/bootstrap-transition.js')
script(src='/js/views/activated.js')
script(src='/js/controllers/activatedController.js')
13 changes: 13 additions & 0 deletions app/server/views/activation-failed.jade
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

extends layout

block content
include modals/alert

block scripts
script(src='/vendor/jquery.min.js')
script(src='/vendor/jquery.form.js')
script(src='/vendor/bootstrap-modal.js')
script(src='/vendor/bootstrap-transition.js')
script(src='/js/views/activation-failed.js')
script(src='/js/controllers/activatedController.js')