tons more changes

v1.18.x
Baris Soner Usakli 11 years ago
parent e32d230974
commit 3775c8e50a

@ -1,4 +1,4 @@
var RDB = require('./../redis'), var db = require('./../database'),
utils = require('./../../public/src/utils'), utils = require('./../../public/src/utils'),
categories = require('./../categories'); categories = require('./../categories');
@ -11,12 +11,12 @@ var RDB = require('./../redis'),
var category = modified[cid]; var category = modified[cid];
for (var key in category) { for (var key in category) {
RDB.hset('category:' + cid, key, category[key]); db.setObjectField('category:' + cid, key, category[key]);
if (key == 'name') { if (key == 'name') {
// reset slugs if name is updated // reset slugs if name is updated
var slug = cid + '/' + utils.slugify(category[key]); var slug = cid + '/' + utils.slugify(category[key]);
RDB.hset('category:' + cid, 'slug', slug); db.setObjectField('category:' + cid, 'slug', slug);
} }
} }

@ -68,13 +68,26 @@
}); });
} }
// key
module.exists = function(key, callback) {
redisClient.exists(key, function(err, exists) {
callback(err, exists === 1);
});
}
module.delete = function(key, callback) {
redisClient.del(key, callback);
}
//hashes
module.setObject = function(key, data, callback) { module.setObject = function(key, data, callback) {
redisClient.hmset(key, data, callback); redisClient.hmset(key, data, callback);
} }
module.setObjectField = function(key, field, callback) { module.setObjectField = function(key, field, value, callback) {
redisClient.hset(key, field, callback) redisClient.hset(key, field, value, callback)
} }
module.getObject = function(key, callback) { module.getObject = function(key, callback) {
@ -107,6 +120,16 @@
}); });
} }
module.getObjectValues = function(key, callback) {
redisClient.hvals(key, callback);
}
module.isObjectField = function(key, field, callback) {
redisClient.hexists(key, field, function(err, exists) {
callback(err, exists === 1);
});
}
module.deleteObjectField = function(key, field, callback) { module.deleteObjectField = function(key, field, callback) {
redisClient.hdel(key, field, callback); redisClient.hdel(key, field, callback);
} }
@ -119,6 +142,9 @@
redisClient.hincrby(key, field, value, callback); redisClient.hincrby(key, field, value, callback);
} }
// sets
module.setAdd = function(key, value, callback) { module.setAdd = function(key, value, callback) {
redisClient.sadd(key, value, callback); redisClient.sadd(key, value, callback);
} }
@ -135,6 +161,12 @@
redisClient.smembers(key, callback); redisClient.smembers(key, callback);
} }
module.setCount = function(key, callback) {
redisClient.scard(key, callback);
}
// sorted sets
module.sortedSetAdd = function(key, score, value, callback) { module.sortedSetAdd = function(key, score, value, callback) {
redisClient.zadd(key, score, value, callback); redisClient.zadd(key, score, value, callback);
} }
@ -143,9 +175,30 @@
redisClient.zrem(key, value, callback); redisClient.zrem(key, value, callback);
} }
module.getSortedSetRange = function(key, start, stop, callback) {
redisClient.zrange(set, start, stop, callback);
}
module.getSortedSetRevRange = function(key, start, stop, callback) {
redisClient.zrevrange(set, start, stop, callback);
}
module.sortedSetCount = function(key, min, max, callback) {
redisClient.zcount(key, min, max, callback);
}
// lists
module.listPrepend = function(key, value, callback) {
redisClient.lpush(key, value, callback);
}
module.listAppend = function(key, value, callback) {
redisClient.rpush(key, value, callback);
}
module.getListRange = function(key, start, stop, callback) {
redisClient.lrange(key, start, stop, callback);
}
}(exports)); }(exports));

@ -2,11 +2,11 @@
"use strict"; "use strict";
var async = require('async'), var async = require('async'),
User = require('./user'), user = require('./user'),
RDB = RDB || require('./redis'); db = require('./database');
Groups.list = function(options, callback) { Groups.list = function(options, callback) {
RDB.hvals('group:gid', function (err, gids) { db.getObjectValues('group:gid', function (err, gids) {
if (gids.length > 0) { if (gids.length > 0) {
async.map(gids, function (gid, next) { async.map(gids, function (gid, next) {
Groups.get(gid, { Groups.get(gid, {
@ -31,17 +31,17 @@
Groups.get = function(gid, options, callback) { Groups.get = function(gid, options, callback) {
async.parallel({ async.parallel({
base: function (next) { base: function (next) {
RDB.hgetall('gid:' + gid, next); db.getObject('gid:' + gid, next);
}, },
users: function (next) { users: function (next) {
RDB.smembers('gid:' + gid + ':members', function (err, uids) { db.getSetMembers('gid:' + gid + ':members', function (err, uids) {
if (options.expand) { if (options.expand) {
if (err) { if (err) {
return next(err); return next(err);
} }
async.map(uids, function (uid, next) { async.map(uids, function (uid, next) {
User.getUserData(uid, next); user.getUserData(uid, next);
}, function (err, users) { }, function (err, users) {
next(err, users); next(err, users);
}); });
@ -75,19 +75,19 @@
}; };
Groups.isDeleted = function(gid, callback) { Groups.isDeleted = function(gid, callback) {
RDB.hget('gid:' + gid, 'deleted', function(err, deleted) { db.getObjectField('gid:' + gid, 'deleted', function(err, deleted) {
callback(err, deleted === '1'); callback(err, deleted === '1');
}); });
}; };
Groups.getGidFromName = function(name, callback) { Groups.getGidFromName = function(name, callback) {
RDB.hget('group:gid', name, callback); db.getObjectField('group:gid', name, callback);
}; };
Groups.isMember = function(uid, gid, callback) { Groups.isMember = function(uid, gid, callback) {
Groups.isDeleted(gid, function(err, deleted) { Groups.isDeleted(gid, function(err, deleted) {
if (!deleted) { if (!deleted) {
RDB.sismember('gid:' + gid + ':members', uid, callback); db.isSetMember('gid:' + gid + ':members', uid, callback);
} else { } else {
callback(err, false); callback(err, false);
} }
@ -107,7 +107,7 @@
}; };
Groups.isEmpty = function(gid, callback) { Groups.isEmpty = function(gid, callback) {
RDB.scard('gid:' + gid + ':members', function(err, numMembers) { db.setCount('gid:' + gid + ':members', function(err, numMembers) {
callback(err, numMembers === 0); callback(err, numMembers === 0);
}); });
}; };
@ -125,7 +125,7 @@
Groups.exists = function(name, callback) { Groups.exists = function(name, callback) {
async.parallel({ async.parallel({
exists: function(next) { exists: function(next) {
RDB.hexists('group:gid', name, next); db.isObjectField('group:gid', name, next);
}, },
deleted: function(next) { deleted: function(next) {
Groups.getGidFromName(name, function(err, gid) { Groups.getGidFromName(name, function(err, gid) {
@ -144,18 +144,13 @@
Groups.exists(name, function (err, exists) { Groups.exists(name, function (err, exists) {
if (!exists) { if (!exists) {
RDB.incr('next_gid', function (err, gid) { db.incrObjectField('global', 'nextGid', function (err, gid) {
RDB.multi() db.setObjectField('group:gid', name, gid, function(err) {
.hset('group:gid', name, gid) db.setObject('gid:' + gid, {}, function(err) {
.hmset('gid:' + gid, {
gid: gid,
name: name,
description: description,
deleted: '0',
hidden: '0'
})
.exec(function (err) {
Groups.get(gid, {}, callback); Groups.get(gid, {}, callback);
});
}); });
}); });
} else { } else {
@ -171,22 +166,24 @@
}; };
Groups.update = function(gid, values, callback) { Groups.update = function(gid, values, callback) {
RDB.exists('gid:' + gid, function (err, exists) { db.exists('gid:' + gid, function (err, exists) {
console.log('exists?', gid, exists, values); console.log('exists?', gid, exists, values);
if (!err && exists) { if (!err && exists) {
RDB.hmset('gid:' + gid, values, callback); db.setObject('gid:' + gid, values, callback);
} else { } else {
if (callback) callback(new Error('gid-not-found')); if (callback) {
callback(new Error('gid-not-found'));
}
} }
}); });
}; };
Groups.destroy = function(gid, callback) { Groups.destroy = function(gid, callback) {
RDB.hset('gid:' + gid, 'deleted', '1', callback); db.setObjectField('gid:' + gid, 'deleted', '1', callback);
}; };
Groups.join = function(gid, uid, callback) { Groups.join = function(gid, uid, callback) {
RDB.sadd('gid:' + gid + ':members', uid, callback); db.setAdd('gid:' + gid + ':members', uid, callback);
}; };
Groups.joinByGroupName = function(groupName, uid, callback) { Groups.joinByGroupName = function(groupName, uid, callback) {
@ -210,7 +207,7 @@
}; };
Groups.leave = function(gid, uid, callback) { Groups.leave = function(gid, uid, callback) {
RDB.srem('gid:' + gid + ':members', uid, callback); db.setRemove('gid:' + gid + ':members', uid, callback);
}; };
Groups.leaveByGroupName = function(groupName, uid, callback) { Groups.leaveByGroupName = function(groupName, uid, callback) {
@ -225,22 +222,29 @@
Groups.prune = function(callback) { Groups.prune = function(callback) {
// Actually deletes groups (with the deleted flag) from the redis database // Actually deletes groups (with the deleted flag) from the redis database
RDB.hvals('group:gid', function (err, gids) { db.getObjectValues('group:gid', function (err, gids) {
var multi = RDB.multi(), var groupsDeleted = 0;
groupsDeleted = 0;
async.each(gids, function(gid, next) { async.each(gids, function(gid, next) {
Groups.get(gid, {}, function(err, groupObj) { Groups.get(gid, {}, function(err, groupObj) {
if (!err && groupObj.deleted === '1') { if(err) {
multi.hdel('group:gid', groupObj.name); return next(err);
multi.del('gid:' + gid);
groupsDeleted++;
} }
if (groupObj.deleted === '1') {
db.deleteObjectField('group:gid', groupObj.name, function(err) {
db.delete('gid:' + gid, function(err) {
groupsDeleted++;
next(null);
});
});
} else {
next(null); next(null);
}
}); });
}, function(err) { }, function(err) {
multi.exec(function(err) {
if (!err && process.env.NODE_ENV === 'development') { if (!err && process.env.NODE_ENV === 'development') {
winston.info('[groups.prune] Pruned ' + groupsDeleted + ' deleted groups from Redis'); winston.info('[groups.prune] Pruned ' + groupsDeleted + ' deleted groups from Redis');
} }
@ -248,7 +252,6 @@
callback(err); callback(err);
}); });
}); });
});
}; };
}(module.exports)); }(module.exports));

@ -58,7 +58,11 @@ var user = require('./user.js'),
} }
Login.loginViaTwitter = function(twid, handle, photos, callback) { Login.loginViaTwitter = function(twid, handle, photos, callback) {
user.getUidByTwitterId(twid, function(uid) { user.getUidByTwitterId(twid, function(err, uid) {
if(err) {
return callback(err);
}
if (uid !== null) { if (uid !== null) {
// Existing User // Existing User
callback(null, { callback(null, {
@ -67,9 +71,10 @@ var user = require('./user.js'),
} else { } else {
// New User // New User
user.create(handle, undefined, undefined, function(err, uid) { user.create(handle, undefined, undefined, function(err, uid) {
if (err !== null) { if(err) {
callback(err); return callback(err);
} else { }
// Save twitter-specific information to the user // Save twitter-specific information to the user
user.setUserField(uid, 'twid', twid); user.setUserField(uid, 'twid', twid);
RDB.hset('twid:uid', twid, uid); RDB.hset('twid:uid', twid, uid);
@ -85,14 +90,17 @@ var user = require('./user.js'),
callback(null, { callback(null, {
uid: uid uid: uid
}); });
}
}); });
} }
}); });
} }
Login.loginViaGoogle = function(gplusid, handle, email, callback) { Login.loginViaGoogle = function(gplusid, handle, email, callback) {
user.getUidByGoogleId(gplusid, function(uid) { user.getUidByGoogleId(gplusid, function(err, uid) {
if(err) {
return callback(err);
}
if (uid !== null) { if (uid !== null) {
// Existing User // Existing User
callback(null, { callback(null, {
@ -109,21 +117,33 @@ var user = require('./user.js'),
}); });
} }
user.getUidByEmail(email, function(uid) { user.getUidByEmail(email, function(err, uid) {
if(err) {
return callback(err);
}
if (!uid) { if (!uid) {
user.create(handle, undefined, email, function(err, uid) { user.create(handle, undefined, email, function(err, uid) {
if (err !== null) { if(err) {
callback(err); return callback(err);
} else success(uid); }
success(uid);
}); });
} else success(uid); // Existing account -- merge } else {
success(uid); // Existing account -- merge
}
}); });
} }
}); });
} }
Login.loginViaFacebook = function(fbid, name, email, callback) { Login.loginViaFacebook = function(fbid, name, email, callback) {
user.getUidByFbid(fbid, function(uid) { user.getUidByFbid(fbid, function(err, uid) {
if(err) {
return callback(err);
}
if (uid !== null) { if (uid !== null) {
// Existing User // Existing User
callback(null, { callback(null, {
@ -140,14 +160,22 @@ var user = require('./user.js'),
}); });
} }
user.getUidByEmail(email, function(uid) { user.getUidByEmail(email, function(err, uid) {
if(err) {
return callback(err);
}
if (!uid) { if (!uid) {
user.create(name, undefined, email, function(err, uid) { user.create(name, undefined, email, function(err, uid) {
if (err !== null) { if(err) {
callback(err); return callback(err);
} else success(uid); }
success(uid);
}); });
} else success(uid); // Existing account -- merge } else {
success(uid); // Existing account -- merge
}
}); });
} }
}); });

@ -13,7 +13,7 @@ var bcrypt = require('bcrypt'),
db = require('./database'), db = require('./database'),
meta = require('./meta'), meta = require('./meta'),
emailjsServer = emailjs.server.connect(meta.config['email:smtp:host'] || '127.0.0.1'), emailjsServer = emailjs.server.connect(meta.config['email:smtp:host'] || '127.0.0.1'),
Groups = require('./groups'), groups = require('./groups'),
notifications = require('./notifications'), notifications = require('./notifications'),
topics = require('./topics'); topics = require('./topics');
@ -287,7 +287,7 @@ var bcrypt = require('bcrypt'),
}; };
User.isEmailAvailable = function(email, callback) { User.isEmailAvailable = function(email, callback) {
RDB.hexists('email:uid', email, function(err, exists) { db.isObjectField('email:uid', email, function(err, exists) {
callback(err, !exists); callback(err, !exists);
}); });
}; };
@ -321,25 +321,25 @@ var bcrypt = require('bcrypt'),
}; };
User.setUserField = function(uid, field, value, callback) { User.setUserField = function(uid, field, value, callback) {
RDB.hset('user:' + uid, field, value, callback); db.setObjectField('user:' + uid, field, value, callback);
}; };
User.setUserFields = function(uid, data, callback) { User.setUserFields = function(uid, data, callback) {
RDB.hmset('user:' + uid, data, callback); db.setObject('user:' + uid, data, callback);
}; };
User.incrementUserFieldBy = function(uid, field, value, callback) { User.incrementUserFieldBy = function(uid, field, value, callback) {
RDB.hincrby('user:' + uid, field, value, callback); db.incrObjectFieldBy('user:' + uid, field, value, callback);
}; };
User.decrementUserFieldBy = function(uid, field, value, callback) { User.decrementUserFieldBy = function(uid, field, value, callback) {
RDB.hincrby('user:' + uid, field, -value, callback); db.incrObjectFieldBy('user:' + uid, field, -value, callback);
}; };
User.getUsers = function(set, start, stop, callback) { User.getUsers = function(set, start, stop, callback) {
var data = []; var data = [];
RDB.zrevrange(set, start, stop, function(err, uids) { db.getSortedSetRevRange(set, start, stop, function(err, uids) {
if (err) { if (err) {
return callback(err, null); return callback(err, null);
} }
@ -360,7 +360,6 @@ var bcrypt = require('bcrypt'),
callback(err, data); callback(err, data);
}); });
}); });
}; };
User.createGravatarURLFromEmail = function(email) { User.createGravatarURLFromEmail = function(email) {
@ -433,7 +432,7 @@ var bcrypt = require('bcrypt'),
User.addPostIdToUser(uid, pid); User.addPostIdToUser(uid, pid);
User.incrementUserFieldBy(uid, 'postcount', 1, function(err, newpostcount) { User.incrementUserFieldBy(uid, 'postcount', 1, function(err, newpostcount) {
RDB.zadd('users:postcount', newpostcount, uid); db.sortedSetAdd('users:postcount', newpostcount, uid);
}); });
User.setUserField(uid, 'lastposttime', timestamp); User.setUserField(uid, 'lastposttime', timestamp);
@ -442,15 +441,15 @@ var bcrypt = require('bcrypt'),
}; };
User.addPostIdToUser = function(uid, pid) { User.addPostIdToUser = function(uid, pid) {
RDB.lpush('uid:' + uid + ':posts', pid); db.listPrepend('uid:' + uid + ':posts', pid);
}; };
User.addTopicIdToUser = function(uid, tid) { User.addTopicIdToUser = function(uid, tid) {
RDB.lpush('uid:' + uid + ':topics', tid); db.listPrepend('uid:' + uid + ':topics', tid);
}; };
User.getPostIds = function(uid, start, end, callback) { User.getPostIds = function(uid, start, stop, callback) {
RDB.lrange('uid:' + uid + ':posts', start, end, function(err, pids) { db.getListRange('uid:' + uid + ':posts', start, stop, function(err, pids) {
if (!err) { if (!err) {
if (pids && pids.length) { if (pids && pids.length) {
callback(pids); callback(pids);
@ -464,51 +463,12 @@ var bcrypt = require('bcrypt'),
}); });
}; };
User.sendConfirmationEmail = function(email) {
if (meta.config['email:smtp:host'] && meta.config['email:smtp:port'] && meta.config['email:from']) {
var confirm_code = utils.generateUUID(),
confirm_link = nconf.get('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
});
// Email confirmation code
var expiry_time = 60 * 60 * 2, // Expire after 2 hours
email_key = 'email:' + email + ':confirm',
confirm_key = 'confirm:' + confirm_code + ':email';
RDB.set(email_key, confirm_code);
RDB.expire(email_key, expiry_time);
RDB.set(confirm_key, email);
RDB.expire(confirm_key, expiry_time);
// Send intro email w/ confirm code
var message = emailjs.message.create({
text: confirm_email_plaintext,
from: meta.config['email:from'] || 'localhost@example.org',
to: email,
subject: '[NodeBB] Registration Email Verification',
attachment: [{
data: confirm_email,
alternative: true
}]
});
emailjsServer.send(message, function(err, success) {
if (err) {
console.log(err);
}
});
}
};
User.follow = function(uid, followid, callback) { User.follow = function(uid, followid, callback) {
RDB.sadd('following:' + uid, followid, function(err, data) { db.setAdd('following:' + uid, followid, function(err, data) {
if (!err) { if (!err) {
RDB.sadd('followers:' + followid, uid, function(err, data) { db.setAdd('followers:' + followid, uid, function(err, data) {
if (!err) { if (!err) {
callback(true); callback(true);
} else { } else {
@ -524,7 +484,7 @@ var bcrypt = require('bcrypt'),
}; };
User.unfollow = function(uid, unfollowid, callback) { User.unfollow = function(uid, unfollowid, callback) {
RDB.srem('following:' + uid, unfollowid, function(err, data) { db.setRemove('following:' + uid, unfollowid, function(err, data) {
if (!err) { if (!err) {
RDB.srem('followers:' + unfollowid, uid, function(err, data) { RDB.srem('followers:' + unfollowid, uid, function(err, data) {
callback(data); callback(data);
@ -536,7 +496,7 @@ var bcrypt = require('bcrypt'),
}; };
User.getFollowing = function(uid, callback) { User.getFollowing = function(uid, callback) {
RDB.smembers('following:' + uid, function(err, userIds) { db.getSetMembers('following:' + uid, function(err, userIds) {
if (!err) { if (!err) {
User.getDataForUsers(userIds, callback); User.getDataForUsers(userIds, callback);
} else { } else {
@ -546,7 +506,7 @@ var bcrypt = require('bcrypt'),
}; };
User.getFollowers = function(uid, callback) { User.getFollowers = function(uid, callback) {
RDB.smembers('followers:' + uid, function(err, userIds) { db.getSetMembers('followers:' + uid, function(err, userIds) {
if (!err) { if (!err) {
User.getDataForUsers(userIds, callback); User.getDataForUsers(userIds, callback);
} else { } else {
@ -556,7 +516,7 @@ var bcrypt = require('bcrypt'),
}; };
User.getFollowingCount = function(uid, callback) { User.getFollowingCount = function(uid, callback) {
RDB.smembers('following:' + uid, function(err, userIds) { db.getSetMembers('following:' + uid, function(err, userIds) {
if (err) { if (err) {
console.log(err); console.log(err);
} else { } else {
@ -569,7 +529,7 @@ var bcrypt = require('bcrypt'),
}; };
User.getFollowerCount = function(uid, callback) { User.getFollowerCount = function(uid, callback) {
RDB.smembers('followers:' + uid, function(err, userIds) { db.getSetMembers('followers:' + uid, function(err, userIds) {
if(err) { if(err) {
console.log(err); console.log(err);
} else { } else {
@ -608,7 +568,7 @@ var bcrypt = require('bcrypt'),
User.sendPostNotificationToFollowers = function(uid, tid, pid) { User.sendPostNotificationToFollowers = function(uid, tid, pid) {
User.getUserField(uid, 'username', function(err, username) { User.getUserField(uid, 'username', function(err, username) {
RDB.smembers('followers:' + uid, function(err, followers) { db.getSetMembers('followers:' + uid, function(err, followers) {
topics.getTopicField(tid, 'slug', function(err, slug) { topics.getTopicField(tid, 'slug', function(err, slug) {
var message = '<strong>' + username + '</strong> made a new post'; var message = '<strong>' + username + '</strong> made a new post';
@ -621,7 +581,7 @@ var bcrypt = require('bcrypt'),
}; };
User.isFollowing = function(uid, theirid, callback) { User.isFollowing = function(uid, theirid, callback) {
RDB.sismember('following:' + uid, theirid, function(err, data) { db.isSetMember('following:' + uid, theirid, function(err, data) {
if (!err) { if (!err) {
callback(data === 1); callback(data === 1);
} else { } else {
@ -637,8 +597,10 @@ var bcrypt = require('bcrypt'),
}; };
User.count = function(socket) { User.count = function(socket) {
RDB.get('usercount', function(err, count) { db.getObjectField('global', 'usercount', function(err, count) {
RDB.handle(err); if(err) {
return;
}
socket.emit('user.count', { socket.emit('user.count', {
count: count ? count : 0 count: count ? count : 0
@ -647,11 +609,11 @@ var bcrypt = require('bcrypt'),
}; };
User.getUidByUsername = function(username, callback) { User.getUidByUsername = function(username, callback) {
RDB.hget('username:uid', username, callback); db.getObjectField('username:uid', username, callback);
}; };
User.getUidByUserslug = function(userslug, callback) { User.getUidByUserslug = function(userslug, callback) {
RDB.hget('userslug:uid', userslug, callback); db.getObjectField('userslug:uid', userslug, callback);
}; };
User.getUsernamesByUids = function(uids, callback) { User.getUsernamesByUids = function(uids, callback) {
@ -693,51 +655,53 @@ var bcrypt = require('bcrypt'),
}; };
User.getUidByEmail = function(email, callback) { User.getUidByEmail = function(email, callback) {
RDB.hget('email:uid', email, function(err, data) { db.getObjectField('email:uid', email, function(err, data) {
if (err) { if (err) {
RDB.handle(err); return callback(err);
} }
callback(data); callback(null, data);
}); });
}; };
User.getUidByTwitterId = function(twid, callback) { User.getUidByTwitterId = function(twid, callback) {
RDB.hget('twid:uid', twid, function(err, uid) { db.getObjectField('twid:uid', twid, function(err, uid) {
if (err) { if (err) {
RDB.handle(err); return callback(err);
} }
callback(uid); callback(null, uid);
}); });
}; };
User.getUidByGoogleId = function(gplusid, callback) { User.getUidByGoogleId = function(gplusid, callback) {
RDB.hget('gplusid:uid', gplusid, function(err, uid) { db.getObjectField('gplusid:uid', gplusid, function(err, uid) {
if (err) { if (err) {
RDB.handle(err); return callback(err);
} }
callback(uid); callback(null, uid);
}); });
}; };
User.getUidByFbid = function(fbid, callback) { User.getUidByFbid = function(fbid, callback) {
RDB.hget('fbid:uid', fbid, function(err, uid) { db.getObjectField('fbid:uid', fbid, function(err, uid) {
if (err) { if (err) {
RDB.handle(err); return callback(err);
} }
callback(uid); callback(null, uid);
}); });
}; };
User.isModerator = function(uid, cid, callback) { User.isModerator = function(uid, cid, callback) {
RDB.sismember('cid:' + cid + ':moderators', uid, function(err, exists) { db.isSetMember('cid:' + cid + ':moderators', uid, function(err, exists) {
RDB.handle(err); if(err) {
return calback(err);
}
callback(err, !! exists); callback(err, !! exists);
}); });
}; };
User.isAdministrator = function(uid, callback) { User.isAdministrator = function(uid, callback) {
Groups.getGidFromName('Administrators', function(err, gid) { groups.getGidFromName('Administrators', function(err, gid) {
Groups.isMember(uid, gid, function(err, isAdmin) { groups.isMember(uid, gid, function(err, isAdmin) {
callback(err, !! isAdmin); callback(err, !! isAdmin);
}); });
}); });
@ -750,15 +714,15 @@ var bcrypt = require('bcrypt'),
callback = null; callback = null;
} }
RDB.hget('reset:uid', code, function(err, uid) { db.getObjectField('reset:uid', code, function(err, uid) {
if (err) { if (err) {
RDB.handle(err); return callback(false);
} }
if (uid !== null) { if (uid !== null) {
RDB.hget('reset:expiry', code, function(err, expiry) { db.getObjectField('reset:expiry', code, function(err, expiry) {
if (err) { if (err) {
RDB.handle(err); return callback(false);
} }
if (expiry >= +Date.now() / 1000 | 0) { if (expiry >= +Date.now() / 1000 | 0) {
@ -771,8 +735,8 @@ var bcrypt = require('bcrypt'),
} }
} else { } else {
// Expired, delete from db // Expired, delete from db
RDB.hdel('reset:uid', code); db.deleteObjectField('reset:uid', code);
RDB.hdel('reset:expiry', code); db.deleteObjectField('reset:expiry', code);
if (!callback) { if (!callback) {
socket.emit('user:reset.valid', { socket.emit('user:reset.valid', {
valid: false valid: false
@ -794,12 +758,12 @@ var bcrypt = require('bcrypt'),
}); });
}, },
send: function(socket, email) { send: function(socket, email) {
User.getUidByEmail(email, function(uid) { User.getUidByEmail(email, function(err, uid) {
if (uid !== null) { if (uid !== null) {
// Generate a new reset code // Generate a new reset code
var reset_code = utils.generateUUID(); var reset_code = utils.generateUUID();
RDB.hset('reset:uid', reset_code, uid); db.setObjectField('reset:uid', reset_code, uid);
RDB.hset('reset:expiry', reset_code, (60 * 60) + new Date() / 1000 | 0); // Active for one hour db.setobjectField('reset:expiry', reset_code, (60 * 60) + new Date() / 1000 | 0); // Active for one hour
var reset_link = nconf.get('url') + 'reset/' + reset_code, var reset_link = nconf.get('url') + 'reset/' + reset_code,
reset_email = global.templates['emails/reset'].parse({ reset_email = global.templates['emails/reset'].parse({
@ -847,17 +811,17 @@ var bcrypt = require('bcrypt'),
commit: function(socket, code, password) { commit: function(socket, code, password) {
this.validate(socket, code, function(validated) { this.validate(socket, code, function(validated) {
if (validated) { if (validated) {
RDB.hget('reset:uid', code, function(err, uid) { db.getObjectField('reset:uid', code, function(err, uid) {
if (err) { if (err) {
RDB.handle(err); return;
} }
User.hashPassword(password, function(err, hash) { User.hashPassword(password, function(err, hash) {
User.setUserField(uid, 'password', hash); User.setUserField(uid, 'password', hash);
}); });
RDB.hdel('reset:uid', code); db.deleteObjectField('reset:uid', code);
RDB.hdel('reset:expiry', code); db.deleteObjectField('reset:expiry', code);
socket.emit('user:reset.commit', { socket.emit('user:reset.commit', {
status: 'ok' status: 'ok'
@ -868,9 +832,48 @@ var bcrypt = require('bcrypt'),
} }
}; };
User.sendConfirmationEmail = function(email) {
if (meta.config['email:smtp:host'] && meta.config['email:smtp:port'] && meta.config['email:from']) {
var confirm_code = utils.generateUUID(),
confirm_link = nconf.get('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
});
// Email confirmation code
var expiry_time = Date.now() / 1000 + 60 * 60 * 2;
db.setObjectField('email:confirm', email, confirm_code);
db.setObjectField('confirm:email', confirm_code, email);
db.setObjectField('confirm:email', confirm_code + ':expire', expiry_time);
// Send intro email w/ confirm code
var message = emailjs.message.create({
text: confirm_email_plaintext,
from: meta.config['email:from'] || 'localhost@example.org',
to: email,
subject: '[NodeBB] Registration Email Verification',
attachment: [{
data: confirm_email,
alternative: true
}]
});
emailjsServer.send(message, function(err, success) {
if (err) {
console.log(err);
}
});
}
};
User.email = { User.email = {
exists: function(socket, email, callback) { exists: function(socket, email, callback) {
User.getUidByEmail(email, function(exists) { User.getUidByEmail(email, function(err, exists) {
exists = !! exists; exists = !! exists;
if (typeof callback !== 'function') { if (typeof callback !== 'function') {
socket.emit('user.email.exists', { socket.emit('user.email.exists', {
@ -882,14 +885,30 @@ var bcrypt = require('bcrypt'),
}); });
}, },
confirm: function(code, callback) { confirm: function(code, callback) {
RDB.get('confirm:' + code + ':email', function(err, email) { db.getObjectFields('confirm:email', [code, code + ':expire'], function(err, data) {
if (err) { if (err) {
RDB.handle(err); return callback({
status:'error'
});
}
var email = data.email;
var expiry = data[code + ':expire'];
if (parseInt(expiry, 10) >= Date.now() / 1000) {
db.deleteObjectField('confirm:email', code);
db.deleteObjectField('confirm:email', code + ':expire');
return callback({
status: 'expired'
});
} }
if (email !== null) { if (email !== null) {
RDB.set('email:' + email + ':confirm', true); db.setObjectField('email:confirm', email, true);
RDB.del('confirm:' + code + ':email');
db.deleteObjectField('confirm:email', code);
db.deleteObjectField('confirm:email', code + ':expire');
callback({ callback({
status: 'ok' status: 'ok'
}); });
@ -908,7 +927,7 @@ var bcrypt = require('bcrypt'),
async.parallel({ async.parallel({
unread: function(next) { unread: function(next) {
RDB.zrevrange('uid:' + uid + ':notifications:unread', 0, 10, function(err, nids) { db.getSortedSetRevRange('uid:' + uid + ':notifications:unread', 0, 10, function(err, nids) {
// @todo handle err // @todo handle err
var unread = []; var unread = [];
@ -924,7 +943,7 @@ var bcrypt = require('bcrypt'),
if (notif_data) { if (notif_data) {
unread.push(notif_data); unread.push(notif_data);
} else { } else {
RDB.zrem('uid:' + uid + ':notifications:unread', nid); db.sortedSetRemove('uid:' + uid + ':notifications:unread', nid);
} }
next(); next();
@ -938,7 +957,7 @@ var bcrypt = require('bcrypt'),
}); });
}, },
read: function(next) { read: function(next) {
RDB.zrevrange('uid:' + uid + ':notifications:read', 0, 10, function(err, nids) { db.getSortedSetRevRange('uid:' + uid + ':notifications:read', 0, 10, function(err, nids) {
// @todo handle err // @todo handle err
var read = []; var read = [];
@ -954,7 +973,7 @@ var bcrypt = require('bcrypt'),
if (notif_data) { if (notif_data) {
read.push(notif_data); read.push(notif_data);
} else { } else {
RDB.zrem('uid:' + uid + ':notifications:read', nid); db.sortedSetRemove('uid:' + uid + ':notifications:read', nid);
} }
next(); next();
@ -986,6 +1005,7 @@ var bcrypt = require('bcrypt'),
before = new Date(parseInt(before, 10)); before = new Date(parseInt(before, 10));
} }
// TODO : figure out how to do this with dbal
RDB.multi() RDB.multi()
.zrevrangebyscore('uid:' + uid + ':notifications:read', before ? before.getTime(): now.getTime(), -Infinity, 'LIMIT', 0, limit) .zrevrangebyscore('uid:' + uid + ':notifications:read', before ? before.getTime(): now.getTime(), -Infinity, 'LIMIT', 0, limit)
.zrevrangebyscore('uid:' + uid + ':notifications:unread', before ? before.getTime(): now.getTime(), -Infinity, 'LIMIT', 0, limit) .zrevrangebyscore('uid:' + uid + ':notifications:unread', before ? before.getTime(): now.getTime(), -Infinity, 'LIMIT', 0, limit)
@ -1014,10 +1034,10 @@ var bcrypt = require('bcrypt'),
}); });
}, },
getUnreadCount: function(uid, callback) { getUnreadCount: function(uid, callback) {
RDB.zcount('uid:' + uid + ':notifications:unread', 0, 10, callback); db.sortedSetCount('uid:' + uid + ':notifications:unread', 0, 10, callback);
}, },
getUnreadByUniqueId: function(uid, uniqueId, callback) { getUnreadByUniqueId: function(uid, uniqueId, callback) {
RDB.zrange('uid:' + uid + ':notifications:unread', 0, -1, function(err, nids) { db.getSortedSetRange('uid:' + uid + ':notifications:unread', 0, -1, function(err, nids) {
async.filter(nids, function(nid, next) { async.filter(nids, function(nid, next) {
notifications.get(nid, uid, function(notifObj) { notifications.get(nid, uid, function(notifObj) {
if (notifObj.uniqueId === uniqueId) { if (notifObj.uniqueId === uniqueId) {

Loading…
Cancel
Save