diff --git a/public/src/templates.js b/public/src/templates.js index e476f429ca..8ab24d7fc9 100644 --- a/public/src/templates.js +++ b/public/src/templates.js @@ -49,10 +49,11 @@ var templates = {}; function init() { loadTemplates([ - 'header', 'footer', 'register', 'home', 'topic', - 'login', 'reset', 'reset_code', - 'emails/reset', 'emails/reset_plaintext' - ]); + 'header', 'footer', 'register', 'home', 'topic', + 'login', 'reset', 'reset_code', 'account', + 'confirm', + 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext' + ]); } diff --git a/public/templates/confirm.tpl b/public/templates/confirm.tpl new file mode 100644 index 0000000000..41f6363398 --- /dev/null +++ b/public/templates/confirm.tpl @@ -0,0 +1,7 @@ +
+ {title} +

{text}

+

+ NodeBB Home +

+
diff --git a/public/templates/emails/email_confirm.tpl b/public/templates/emails/email_confirm.tpl new file mode 100644 index 0000000000..2f3159c613 --- /dev/null +++ b/public/templates/emails/email_confirm.tpl @@ -0,0 +1,7 @@ + +

Hello,

+

Thank you for registering with NodeBB!

+

To fully activate your account, we need to verify that you own the email address you registered with.

+

Please click on the following link:

+
{CONFIRM_LINK}
+

Thanks!
NodeBB \ No newline at end of file diff --git a/public/templates/emails/email_confirm_plaintext.tpl b/public/templates/emails/email_confirm_plaintext.tpl new file mode 100644 index 0000000000..a01d7c90cc --- /dev/null +++ b/public/templates/emails/email_confirm_plaintext.tpl @@ -0,0 +1,12 @@ +Hello, + +Thank you for registering with NodeBB! + +To fully activate your account, we need to verify that you own the email address you registered with. + +Please click on the following link: + + {CONFIRM_LINK} + +Thanks! +NodeBB \ No newline at end of file diff --git a/public/templates/emails/footer.tpl b/public/templates/emails/footer.tpl new file mode 100644 index 0000000000..5fd5205487 --- /dev/null +++ b/public/templates/emails/footer.tpl @@ -0,0 +1,10 @@ + + +


+

+ This email was sent by NodeBB. If it does not apply to you, please ignore it. +

+ \ No newline at end of file diff --git a/public/templates/emails/header.tpl b/public/templates/emails/header.tpl new file mode 100644 index 0000000000..9c3bf39b76 --- /dev/null +++ b/public/templates/emails/header.tpl @@ -0,0 +1,26 @@ +
+

+ NodeBB +

+
diff --git a/src/templates.js b/src/templates.js index 17b41592d7..5e93378333 100644 --- a/src/templates.js +++ b/src/templates.js @@ -28,7 +28,8 @@ 'header', 'footer', 'register', 'home', 'topic', 'account', 'login', 'reset', 'reset_code', 'logout', '403', - 'emails/reset', 'emails/reset_plaintext' + 'emails/header', 'emails/footer', + 'emails/reset', 'emails/reset_plaintext', 'emails/email_confirm', 'emails/email_confirm_plaintext' ]); } diff --git a/src/user.js b/src/user.js index 0bb52ce1a4..fd979933ae 100644 --- a/src/user.js +++ b/src/user.js @@ -277,8 +277,35 @@ var config = require('../config.js'), } if (email) { + var confirm_code = utils.generateUUID(), + confirm_link = config.url + 'confirm/' + confirm_code, + confirm_email = global.templates['emails/header'] + global.templates['emails/email_confirm'].parse({'CONFIRM_LINK': confirm_link}) + global.templates['emails/footer'], + confirm_email_plaintext = global.templates['emails/email_confirm_plaintext'].parse({ 'CONFIRM_LINK': confirm_link }); + RDB.set('uid:' + uid + ':email', email); RDB.set('email:' + email, uid); + + // Email confirmation code + RDB.set('email:' + email + ':confirm', confirm_code, 60*60*2); + RDB.set('confirm:' + confirm_code + ':email', email, 60*60*2); // Expire after 2 hours + + // Send intro email w/ confirm code + var message = emailjs.message.create({ + text: confirm_email_plaintext, + from: config.mailer.from, + to: email, + subject: '[NodeBB] Registration Email Verification', + attachment: [ + { + data: confirm_email, + alternative: true + } + ] + }); + + emailjsServer.send(message, function(err, success) { + if (err) console.log(err); + }); } RDB.set('uid:' + uid + ':joindate', new Date().getTime()); @@ -485,6 +512,21 @@ var config = require('../config.js'), if (typeof callback !== 'function') socket.emit('user.email.exists', { exists: exists }); else callback(exists); }); + }, + confirm: function(code, callback) { + RDB.get('confirm:' + code + ':email', function(email) { + if (email !== null) { + RDB.set('email:' + email + ':confirm', true); + RDB.del('confirm:' + code + ':email'); + callback({ + status: 'ok' + }); + } else { + callback({ + status: 'not_ok' + }); + } + }); } } diff --git a/src/webserver.js b/src/webserver.js index 8fc6c4b687..e1cf20d051 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -140,7 +140,9 @@ passport.deserializeUser(function(uid, done) { res.send(templates['header'] + '' + templates['footer']); }); - + app.get('/confirm/:code', function(req, res) { + res.send(templates['header'] + '' + templates['footer']); + }); // These functions are called via ajax once the initial page is loaded to populate templates with data function api_method(req, res) { @@ -176,6 +178,23 @@ passport.deserializeUser(function(uid, done) { res.send(JSON.stringify(data)); }, req.params.id, (req.user) ? req.user.uid : 0); break; + case 'confirm': + global.modules.user.email.confirm(req.params.id, function(data) { + if (data.status === 'ok') { + res.send(JSON.stringify({ + 'alert-class': 'alert-success', + title: 'Email Confirmed', + text: 'Thank you for vaidating your email. Your account is now fully activated.' + })); + } else { + res.send(JSON.stringify({ + 'alert-class': 'alert-error', + title: 'An error occurred...', + text: 'There was a problem validating your email address. Perhaps the code was invalid or has expired.' + })); + } + }); + break; default : res.send('{}'); break;