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 @@
+
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;