all files / src/user/ email.js

34.04% Statements 16/47
0% Branches 0/20
15% Functions 3/20
34.04% Lines 16/47
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113                                                                                                                                                                                                 
 
'use strict';
 
var async = require('async');
var nconf = require('nconf');
 
var user = require('../user');
var utils = require('../../public/src/utils');
var translator = require('../../public/src/modules/translator');
var plugins = require('../plugins');
var db = require('../database');
var meta = require('../meta');
var emailer = require('../emailer');
 
(function(UserEmail) {
 
	UserEmail.exists = function(email, callback) {
		user.getUidByEmail(email.toLowerCase(), function(err, exists) {
			callback(err, !!exists);
		});
	};
 
	UserEmail.available = function(email, callback) {
		db.isSortedSetMember('email:uid', email.toLowerCase(), function(err, exists) {
			callback(err, !exists);
		});
	};
 
	UserEmail.sendValidationEmail = function(uid, email, callback) {
		callback = callback || function() {};
		var confirm_code = utils.generateUUID(),
			confirm_link = nconf.get('url') + '/confirm/' + confirm_code;
 
		var emailInterval = meta.config.hasOwnProperty('emailConfirmInterval') ? parseInt(meta.config.emailConfirmInterval, 10) : 10;
 
		async.waterfall([
			function(next) {
				db.get('uid:' + uid + ':confirm:email:sent', next);
			},
			function(sent, next) {
				if (sent) {
					return next(new Error('[[error:confirm-email-already-sent, ' + emailInterval + ']]'));
				}
				db.set('uid:' + uid + ':confirm:email:sent', 1, next);
			},
			function(next) {
				db.pexpireAt('uid:' + uid + ':confirm:email:sent', Date.now() + (emailInterval * 60 * 1000), next);
			},
			function(next) {
				plugins.fireHook('filter:user.verify.code', confirm_code, next);
			},
			function(_confirm_code, next) {
				confirm_code = _confirm_code;
				db.setObject('confirm:' + confirm_code, {
					email: email.toLowerCase(),
					uid: uid
				}, next);
			},
			function(next) {
				db.expireAt('confirm:' + confirm_code, Math.floor(Date.now() / 1000 + 60 * 60 * 24), next);
			},
			function(next) {
				user.getUserField(uid, 'username', next);
			},
			function(username, next) {
				var title = meta.config.title || meta.config.browserTitle || 'NodeBB';
				translator.translate('[[email:welcome-to, ' + title + ']]', meta.config.defaultLang, function(subject) {
					var data = {
						site_title: title,
						username: username,
						confirm_link: confirm_link,
						confirm_code: confirm_code,
 
						subject: subject,
						template: 'welcome',
						uid: uid
					};
 
					if (plugins.hasListeners('action:user.verify')) {
						plugins.fireHook('action:user.verify', {uid: uid, data: data});
						next();
					} else {
						emailer.send('welcome', uid, data, next);
					}
				});
			}
		], callback);
	};
 
	UserEmail.confirm = function(code, callback) {
		db.getObject('confirm:' + code, function(err, confirmObj) {
			if (err) {
				return callback(new Error('[[error:parse-error]]'));
			}
 
			if (confirmObj && confirmObj.uid && confirmObj.email) {
				async.series([
					async.apply(user.setUserField, confirmObj.uid, 'email:confirmed', 1),
					async.apply(db.delete, 'confirm:' + code),
					function(next) {
						db.sortedSetRemove('users:notvalidated', confirmObj.uid, next);
					}
				], function(err) {
					callback(err ? new Error('[[error:email-confirm-failed]]') : null);
				});
			} else {
				callback(new Error('[[error:invalid-data]]'));
			}
		});
	};
 
}(exports));