diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index 3aa389802a..26e0c23690 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -9,6 +9,7 @@ var plugins = require('../plugins'); var widgets = require('../widgets'); var user = require('../user'); var userDigest = require('../user/digest'); +var userEmail = require('../user/email'); var logger = require('../logger'); var events = require('../events'); var emailer = require('../emailer'); @@ -230,6 +231,12 @@ SocketAdmin.email.test = function (socket, data, callback) { emailer.send(data.template, socket.uid, payload, callback); break; + case 'welcome': + userEmail.sendValidationEmail(socket.uid, { + force: 1, + }); + break; + default: emailer.send(data.template, socket.uid, payload, callback); break; diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index de2ccfc299..3fb4dfb9ff 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -101,20 +101,9 @@ User.sendValidationEmail = function (socket, uids, callback) { return callback(new Error('[[error:email-confirmations-are-disabled]]')); } - async.waterfall([ - function (next) { - user.getUsersFields(uids, ['uid', 'email'], next); - }, - function (usersData, next) { - async.eachLimit(usersData, 50, function (userData, next) { - if (userData.email && userData.uid) { - user.email.sendValidationEmail(userData.uid, userData.email, next); - } else { - next(); - } - }, next); - }, - ], callback); + async.eachLimit(uids, 50, function (uid, next) { + user.email.sendValidationEmail(uid, next); + }, callback); }; User.sendPasswordResetEmail = function (socket, uids, callback) { diff --git a/src/socket.io/user.js b/src/socket.io/user.js index f14e0c0c89..b9cd70552b 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -75,18 +75,7 @@ SocketUser.emailConfirm = function (socket, data, callback) { return callback(new Error('[[error:email-confirmations-are-disabled]]')); } - async.waterfall([ - function (next) { - user.getUserField(socket.uid, 'email', next); - }, - function (email, next) { - if (!email) { - return callback(); - } - - user.email.sendValidationEmail(socket.uid, email, next); - }, - ], callback); + user.email.sendValidationEmail(socket.uid, next); }; diff --git a/src/user/create.js b/src/user/create.js index 812e3c0a4a..8b684cdacb 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -103,7 +103,9 @@ module.exports = function (User) { ], next); if (parseInt(userData.uid, 10) !== 1 && parseInt(meta.config.requireEmailConfirmation, 10) === 1) { - User.email.sendValidationEmail(userData.uid, userData.email); + User.email.sendValidationEmail(userData.uid, { + email: userData.email, + }); } } else { next(); diff --git a/src/user/email.js b/src/user/email.js index 30d8340e8a..9dafee3fa7 100644 --- a/src/user/email.js +++ b/src/user/email.js @@ -26,7 +26,26 @@ UserEmail.available = function (email, callback) { }); }; -UserEmail.sendValidationEmail = function (uid, email, callback) { +UserEmail.sendValidationEmail = function (uid, options, callback) { + /* + * Options: + * - email, overrides email retrieval + * - force, sends email even if it is too soon to send another + */ + + // Handling for 2 arguments + if (arguments.length === 2 && typeof options === 'function') { + callback = options; + options = {}; + } + + // Fallback behaviour (email passed in as second argument) + if (typeof options === 'string') { + options = { + email: options, + }; + } + callback = callback || function () {}; var confirm_code = utils.generateUUID(); var confirm_link = nconf.get('url') + '/confirm/' + confirm_code; @@ -35,6 +54,25 @@ UserEmail.sendValidationEmail = function (uid, email, callback) { async.waterfall([ function (next) { + // If no email passed in (default), retrieve email from uid + if (options.email && options.email.length) { + return setImmediate(next); + } + + user.getUserField(uid, 'email', function (err, email) { + if (err) { + return next(err); + } + + options.email = email; + next(); + }); + }, + function (next) { + if (options.force) { + return setImmediate(next, null, false); + } + db.get('uid:' + uid + ':confirm:email:sent', next); }, function (sent, next) { @@ -52,7 +90,7 @@ UserEmail.sendValidationEmail = function (uid, email, callback) { function (_confirm_code, next) { confirm_code = _confirm_code; db.setObject('confirm:' + confirm_code, { - email: email.toLowerCase(), + email: options.email.toLowerCase(), uid: uid, }, next); }, diff --git a/src/user/profile.js b/src/user/profile.js index 91956e9bf4..d6f7ac5a4b 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -176,7 +176,9 @@ module.exports = function (User) { }, function (next) { if (parseInt(meta.config.requireEmailConfirmation, 10) === 1 && newEmail) { - User.email.sendValidationEmail(uid, newEmail); + User.email.sendValidationEmail(uid, { + email: newEmail, + }); } User.setUserField(uid, 'email:confirmed', 0, next); },