style changes

v1.18.x
Barış Soner Uşaklı 8 years ago
parent 8db193ff55
commit f6ac92111b

@ -36,9 +36,7 @@ rewards.checkConditionAndRewardUser = function (uid, condition, method, callback
return next(null, false);
}
checkCondition(reward, method, function (result) {
next(null, result);
});
checkCondition(reward, method, next);
}, function (err, eligible) {
if (err || !eligible) {
return next(false);
@ -59,29 +57,30 @@ function getIDsByCondition(condition, callback) {
}
function filterCompletedRewards(uid, rewards, callback) {
db.getSortedSetRangeByScoreWithScores('uid:' + uid + ':rewards', 0, -1, 1, '+inf', function (err, data) {
if (err) {
return callback(err);
}
var userRewards = {};
async.waterfall([
function (next) {
db.getSortedSetRangeByScoreWithScores('uid:' + uid + ':rewards', 0, -1, 1, '+inf', next);
},
function (data, next) {
var userRewards = {};
data.forEach(function (obj) {
userRewards[obj.value] = parseInt(obj.score, 10);
});
data.forEach(function (obj) {
userRewards[obj.value] = parseInt(obj.score, 10);
});
rewards = rewards.filter(function (reward) {
if (!reward) {
return false;
}
rewards = rewards.filter(function (reward) {
if (!reward) {
return false;
}
var claimable = parseInt(reward.claimable, 10);
var claimable = parseInt(reward.claimable, 10);
return claimable === 0 || (userRewards[reward.id] < reward.claimable);
});
return claimable === 0 || (userRewards[reward.id] < reward.claimable);
});
callback(null, rewards);
});
next(null, rewards);
},
], callback);
}
function getRewardDataByIDs(ids, callback) {
@ -97,26 +96,29 @@ function getRewardsByRewardData(rewards, callback) {
}
function checkCondition(reward, method, callback) {
method(function (err, value) {
if (err) {
return callback(err);
}
plugins.fireHook('filter:rewards.checkConditional:' + reward.conditional, { left: value, right: reward.value }, function (err, bool) {
callback(err || bool);
});
});
async.waterfall([
function (next) {
method(next);
},
function (value, next) {
plugins.fireHook('filter:rewards.checkConditional:' + reward.conditional, { left: value, right: reward.value }, next);
},
function (bool, next) {
next(null, bool);
},
], callback);
}
function giveRewards(uid, rewards, callback) {
getRewardsByRewardData(rewards, function (err, rewardData) {
if (err) {
return callback(err);
}
async.each(rewards, function (reward, next) {
plugins.fireHook('action:rewards.award:' + reward.rid, { uid: uid, reward: rewardData[rewards.indexOf(reward)] });
db.sortedSetIncrBy('uid:' + uid + ':rewards', 1, reward.id, next);
}, callback);
});
async.waterfall([
function (next) {
getRewardsByRewardData(rewards, next);
},
function (rewardData, next) {
async.each(rewards, function (reward, next) {
plugins.fireHook('action:rewards.award:' + reward.rid, { uid: uid, reward: rewardData[rewards.indexOf(reward)] });
db.sortedSetIncrBy('uid:' + uid + ':rewards', 1, reward.id, next);
}, next);
},
], callback);
}

@ -1,54 +1,55 @@
'use strict';
(function (Auth) {
var passport = require('passport');
var passportLocal = require('passport-local').Strategy;
var nconf = require('nconf');
var winston = require('winston');
var express = require('express');
var async = require('async');
var passport = require('passport');
var passportLocal = require('passport-local').Strategy;
var nconf = require('nconf');
var winston = require('winston');
var express = require('express');
var controllers = require('../controllers');
var plugins = require('../plugins');
var hotswap = require('../hotswap');
var controllers = require('../controllers');
var plugins = require('../plugins');
var hotswap = require('../hotswap');
var loginStrategies = [];
var loginStrategies = [];
Auth.initialize = function (app, middleware) {
app.use(passport.initialize());
app.use(passport.session());
var Auth = module.exports;
app.use(function (req, res, next) {
req.uid = req.user ? parseInt(req.user.uid, 10) : 0;
next();
});
Auth.initialize = function (app, middleware) {
app.use(passport.initialize());
app.use(passport.session());
Auth.app = app;
Auth.middleware = middleware;
};
app.use(function (req, res, next) {
req.uid = req.user ? parseInt(req.user.uid, 10) : 0;
next();
});
Auth.getLoginStrategies = function () {
return loginStrategies;
};
Auth.app = app;
Auth.middleware = middleware;
};
Auth.reloadRoutes = function (callback) {
var router = express.Router();
router.hotswapId = 'auth';
Auth.getLoginStrategies = function () {
return loginStrategies;
};
loginStrategies.length = 0;
Auth.reloadRoutes = function (callback) {
var router = express.Router();
router.hotswapId = 'auth';
if (plugins.hasListeners('action:auth.overrideLogin')) {
winston.warn('[authentication] Login override detected, skipping local login strategy.');
plugins.fireHook('action:auth.overrideLogin');
} else {
passport.use(new passportLocal({ passReqToCallback: true }, controllers.authentication.localLogin));
}
loginStrategies.length = 0;
plugins.fireHook('filter:auth.init', loginStrategies, function (err) {
if (err) {
winston.error('filter:auth.init - plugin failure');
return callback(err);
}
if (plugins.hasListeners('action:auth.overrideLogin')) {
winston.warn('[authentication] Login override detected, skipping local login strategy.');
plugins.fireHook('action:auth.overrideLogin');
} else {
passport.use(new passportLocal({ passReqToCallback: true }, controllers.authentication.localLogin));
}
async.waterfall([
function (next) {
plugins.fireHook('filter:auth.init', loginStrategies, next);
},
function (loginStrategies, next) {
loginStrategies.forEach(function (strategy) {
if (strategy.url) {
router.get(strategy.url, passport.authenticate(strategy.name, {
@ -70,19 +71,17 @@
router.post('/logout', Auth.middleware.applyCSRF, controllers.authentication.logout);
hotswap.replace('auth', router);
if (typeof callback === 'function') {
callback();
}
});
};
passport.serializeUser(function (user, done) {
done(null, user.uid);
});
next();
},
], callback);
};
passport.serializeUser(function (user, done) {
done(null, user.uid);
});
passport.deserializeUser(function (uid, done) {
done(null, {
uid: uid,
});
passport.deserializeUser(function (uid, done) {
done(null, {
uid: uid,
});
}(exports));
});

@ -205,11 +205,11 @@ module.exports = function (app, middleware, hotswapIds, callback) {
async.apply(plugins.reloadRoutes),
async.apply(authRoutes.reloadRoutes),
async.apply(user.addInterstitials),
function (next) {
winston.info('Routes added');
next();
},
], function (err) {
if (err) {
return callback(err);
}
winston.info('Routes added');
callback();
callback(err);
});
};

@ -38,13 +38,18 @@ var SocketAdmin = {
};
SocketAdmin.before = function (socket, method, data, next) {
user.isAdministrator(socket.uid, function (err, isAdmin) {
if (err || isAdmin) {
return next(err);
}
winston.warn('[socket.io] Call to admin method ( ' + method + ' ) blocked (accessed by uid ' + socket.uid + ')');
next(new Error('[[error:no-privileges]]'));
});
async.waterfall([
function (next) {
user.isAdministrator(socket.uid, next);
},
function (isAdmin) {
if (isAdmin) {
return next();
}
winston.warn('[socket.io] Call to admin method ( ' + method + ' ) blocked (accessed by uid ' + socket.uid + ')');
next(new Error('[[error:no-privileges]]'));
},
], next);
};
SocketAdmin.reload = function (socket, data, callback) {
@ -58,26 +63,27 @@ SocketAdmin.reload = function (socket, data, callback) {
};
SocketAdmin.restart = function (socket, data, callback) {
require('../meta/build').buildAll(function (err) {
if (err) {
return callback(err);
}
events.log({
type: 'build',
uid: socket.uid,
ip: socket.ip,
});
events.log({
type: 'restart',
uid: socket.uid,
ip: socket.ip,
});
meta.restart();
callback();
});
async.waterfall([
function (next) {
require('../meta/build').buildAll(next);
},
function (next) {
events.log({
type: 'build',
uid: socket.uid,
ip: socket.ip,
});
events.log({
type: 'restart',
uid: socket.uid,
ip: socket.ip,
});
meta.restart();
next();
},
], callback);
};
SocketAdmin.fireEvent = function (socket, data, callback) {

@ -30,13 +30,7 @@ Categories.getAll = function (socket, data, callback) {
function (result, next) {
next(null, categories.getTree(result.categories, 0));
},
], function (err, categoriesTree) {
if (err) {
return callback(err);
}
callback(null, categoriesTree);
});
], callback);
};
Categories.getNames = function (socket, data, callback) {
@ -93,27 +87,31 @@ Categories.getPrivilegeSettings = function (socket, cid, callback) {
};
Categories.copyPrivilegesToChildren = function (socket, cid, callback) {
categories.getCategories([cid], socket.uid, function (err, categories) {
if (err) {
return callback(err);
}
var category = categories[0];
async.eachSeries(category.children, function (child, next) {
copyPrivilegesToChildrenRecursive(cid, child, next);
}, callback);
});
async.waterfall([
function (next) {
categories.getCategories([cid], socket.uid, next);
},
function (categories, next) {
var category = categories[0];
async.eachSeries(category.children, function (child, next) {
copyPrivilegesToChildrenRecursive(cid, child, next);
}, next);
},
], callback);
};
function copyPrivilegesToChildrenRecursive(parentCid, category, callback) {
categories.copyPrivilegesFrom(parentCid, category.cid, function (err) {
if (err) {
return callback(err);
}
async.eachSeries(category.children, function (child, next) {
copyPrivilegesToChildrenRecursive(parentCid, child, next);
}, callback);
});
async.waterfall([
function (next) {
categories.copyPrivilegesFrom(parentCid, category.cid, next);
},
function (next) {
async.eachSeries(category.children, function (child, next) {
copyPrivilegesToChildrenRecursive(parentCid, child, next);
}, next);
},
], callback);
}
Categories.copySettingsFrom = function (socket, data, callback) {

@ -3,7 +3,7 @@
var async = require('async');
var groups = require('../../groups');
var Groups = {};
var Groups = module.exports;
Groups.create = function (socket, data, callback) {
if (!data) {
@ -66,5 +66,3 @@ Groups.update = function (socket, data, callback) {
groups.update(data.groupName, data.values, callback);
};
module.exports = Groups;

@ -1,10 +1,8 @@
'use strict';
var navigationAdmin = require('../../navigation/admin');
var SocketNavigation = {};
var SocketNavigation = module.exports;
SocketNavigation.save = function (socket, data, callback) {
navigationAdmin.save(data, callback);
};
module.exports = SocketNavigation;

@ -11,11 +11,11 @@ var pubsub = require('../../pubsub');
var stats = {};
var totals = {};
var SocketRooms = {
stats: stats,
totals: totals,
};
var SocketRooms = module.exports;
SocketRooms.stats = stats;
SocketRooms.totals = totals;
pubsub.on('sync:stats:start', function () {
SocketRooms.getLocalStats(function (err, stats) {
@ -181,6 +181,3 @@ SocketRooms.getLocalStats = function (callback) {
callback(null, socketData);
};
module.exports = SocketRooms;

@ -10,28 +10,29 @@ var events = require('../../events');
var meta = require('../../meta');
var plugins = require('../../plugins');
var User = {};
var User = module.exports;
User.makeAdmins = function (socket, uids, callback) {
if (!Array.isArray(uids)) {
return callback(new Error('[[error:invalid-data]]'));
}
user.getUsersFields(uids, ['banned'], function (err, userData) {
if (err) {
return callback(err);
}
for (var i = 0; i < userData.length; i += 1) {
if (userData[i] && parseInt(userData[i].banned, 10) === 1) {
return callback(new Error('[[error:cant-make-banned-users-admin]]'));
async.waterfall([
function (next) {
user.getUsersFields(uids, ['banned'], next);
},
function (userData, next) {
for (var i = 0; i < userData.length; i += 1) {
if (userData[i] && parseInt(userData[i].banned, 10) === 1) {
return callback(new Error('[[error:cant-make-banned-users-admin]]'));
}
}
}
async.each(uids, function (uid, next) {
groups.join('administrators', uid, next);
}, callback);
});
async.each(uids, function (uid, next) {
groups.join('administrators', uid, next);
}, next);
},
], callback);
};
User.removeAdmins = function (socket, uids, callback) {
@ -40,17 +41,18 @@ User.removeAdmins = function (socket, uids, callback) {
}
async.eachSeries(uids, function (uid, next) {
groups.getMemberCount('administrators', function (err, count) {
if (err) {
return next(err);
}
if (count === 1) {
return next(new Error('[[error:cant-remove-last-admin]]'));
}
async.waterfall([
function (next) {
groups.getMemberCount('administrators', next);
},
function (count, next) {
if (count === 1) {
return next(new Error('[[error:cant-remove-last-admin]]'));
}
groups.leave('administrators', uid, next);
});
groups.leave('administrators', uid, next);
},
], next);
}, callback);
};
@ -78,14 +80,16 @@ User.validateEmail = function (socket, uids, callback) {
return parseInt(uid, 10);
});
async.each(uids, function (uid, next) {
user.setUserField(uid, 'email:confirmed', 1, next);
}, function (err) {
if (err) {
return callback(err);
}
db.sortedSetRemove('users:notvalidated', uids, callback);
});
async.waterfall([
function (next) {
async.each(uids, function (uid, next) {
user.setUserField(uid, 'email:confirmed', 1, next);
}, next);
},
function (next) {
db.sortedSetRemove('users:notvalidated', uids, next);
},
], callback);
};
User.sendValidationEmail = function (socket, uids, callback) {
@ -123,15 +127,17 @@ User.sendPasswordResetEmail = function (socket, uids, callback) {
});
async.each(uids, function (uid, next) {
user.getUserFields(uid, ['email', 'username'], function (err, userData) {
if (err) {
return next(err);
}
if (!userData.email) {
return next(new Error('[[error:user-doesnt-have-email, ' + userData.username + ']]'));
}
user.reset.send(userData.email, next);
});
async.waterfall([
function (next) {
user.getUserFields(uid, ['email', 'username'], next);
},
function (userData, next) {
if (!userData.email) {
return next(new Error('[[error:user-doesnt-have-email, ' + userData.username + ']]'));
}
user.reset.send(userData.email, next);
},
], next);
}, callback);
};
@ -257,5 +263,3 @@ User.rejectRegistration = function (socket, data, callback) {
User.restartJobs = function (socket, data, callback) {
user.startJobs(callback);
};
module.exports = User;

@ -1,24 +1,28 @@
'use strict';
var async = require('async');
var user = require('../user');
var meta = require('../meta');
var SocketBlacklist = {};
var SocketBlacklist = module.exports;
SocketBlacklist.validate = function (socket, data, callback) {
meta.blacklist.validate(data.rules, callback);
};
SocketBlacklist.save = function (socket, rules, callback) {
user.isAdminOrGlobalMod(socket.uid, function (err, isAdminOrGlobalMod) {
if (err || !isAdminOrGlobalMod) {
return callback(err || new Error('[[error:no-privileges]]'));
}
meta.blacklist.save(rules, callback);
});
async.waterfall([
function (next) {
user.isAdminOrGlobalMod(socket.uid, next);
},
function (isAdminOrGlobalMod, next) {
if (!isAdminOrGlobalMod) {
return callback(new Error('[[error:no-privileges]]'));
}
meta.blacklist.save(rules, next);
},
], callback);
};
module.exports = SocketBlacklist;

@ -8,133 +8,134 @@ var user = require('../user');
var topics = require('../topics');
var apiController = require('../controllers/api');
var SocketCategories = {};
var SocketCategories = module.exports;
SocketCategories.getRecentReplies = function (socket, cid, callback) {
categories.getRecentReplies(cid, socket.uid, 4, callback);
};
SocketCategories.get = function (socket, data, callback) {
async.parallel({
isAdmin: async.apply(user.isAdministrator, socket.uid),
categories: function (next) {
async.waterfall([
async.apply(db.getSortedSetRange, 'categories:cid', 0, -1),
async.apply(categories.getCategoriesData),
], next);
async.waterfall([
function (next) {
async.parallel({
isAdmin: async.apply(user.isAdministrator, socket.uid),
categories: function (next) {
async.waterfall([
async.apply(db.getSortedSetRange, 'categories:cid', 0, -1),
async.apply(categories.getCategoriesData),
], next);
},
}, next);
},
}, function (err, results) {
if (err) {
return callback(err);
}
results.categories = results.categories.filter(function (category) {
return category && (!category.disabled || results.isAdmin);
});
function (results, next) {
results.categories = results.categories.filter(function (category) {
return category && (!category.disabled || results.isAdmin);
});
callback(null, results.categories);
});
next(null, results.categories);
},
], callback);
};
SocketCategories.getWatchedCategories = function (socket, data, callback) {
async.parallel({
categories: async.apply(categories.getCategoriesByPrivilege, 'cid:0:children', socket.uid, 'find'),
ignoredCids: async.apply(user.getIgnoredCategories, socket.uid),
}, function (err, results) {
if (err) {
return callback(err);
}
var watchedCategories = results.categories.filter(function (category) {
return category && results.ignoredCids.indexOf(category.cid.toString()) === -1;
});
callback(null, watchedCategories);
});
async.waterfall([
function (next) {
async.parallel({
categories: async.apply(categories.getCategoriesByPrivilege, 'cid:0:children', socket.uid, 'find'),
ignoredCids: async.apply(user.getIgnoredCategories, socket.uid),
}, next);
},
function (results, next) {
var watchedCategories = results.categories.filter(function (category) {
return category && results.ignoredCids.indexOf(category.cid.toString()) === -1;
});
next(null, watchedCategories);
},
], callback);
};
SocketCategories.loadMore = function (socket, data, callback) {
if (!data) {
return callback(new Error('[[error:invalid-data]]'));
}
async.parallel({
privileges: function (next) {
privileges.categories.get(data.cid, socket.uid, next);
},
settings: function (next) {
user.getSettings(socket.uid, next);
var userPrivileges;
async.waterfall([
function (next) {
async.parallel({
privileges: function (next) {
privileges.categories.get(data.cid, socket.uid, next);
},
settings: function (next) {
user.getSettings(socket.uid, next);
},
targetUid: function (next) {
if (data.author) {
user.getUidByUserslug(data.author, next);
} else {
next();
}
},
}, next);
},
targetUid: function (next) {
if (data.author) {
user.getUidByUserslug(data.author, next);
} else {
next();
function (results, next) {
userPrivileges = results.privileges;
if (!userPrivileges.read) {
return callback(new Error('[[error:no-privileges]]'));
}
},
}, function (err, results) {
if (err) {
return callback(err);
}
if (!results.privileges.read) {
return callback(new Error('[[error:no-privileges]]'));
}
var infScrollTopicsPerPage = 20;
var set = 'cid:' + data.cid + ':tids';
var reverse = false;
if (data.categoryTopicSort === 'newest_to_oldest') {
reverse = true;
} else if (data.categoryTopicSort === 'most_posts') {
reverse = true;
set = 'cid:' + data.cid + ':tids:posts';
}
var start = Math.max(0, parseInt(data.after, 10));
if (data.direction === -1) {
start -= reverse ? infScrollTopicsPerPage : -infScrollTopicsPerPage;
}
var stop = start + infScrollTopicsPerPage - 1;
start = Math.max(0, start);
stop = Math.max(0, stop);
if (results.targetUid) {
set = 'cid:' + data.cid + ':uid:' + results.targetUid + ':tids';
}
if (data.tag) {
set = [set, 'tag:' + data.tag + ':topics'];
}
categories.getCategoryTopics({
cid: data.cid,
set: set,
reverse: reverse,
start: start,
stop: stop,
uid: socket.uid,
targetUid: results.targetUid,
settings: results.settings,
}, function (err, data) {
if (err) {
return callback(err);
var infScrollTopicsPerPage = 20;
var set = 'cid:' + data.cid + ':tids';
var reverse = false;
if (data.categoryTopicSort === 'newest_to_oldest') {
reverse = true;
} else if (data.categoryTopicSort === 'most_posts') {
reverse = true;
set = 'cid:' + data.cid + ':tids:posts';
}
var start = Math.max(0, parseInt(data.after, 10));
if (data.direction === -1) {
start -= reverse ? infScrollTopicsPerPage : -infScrollTopicsPerPage;
}
var stop = start + infScrollTopicsPerPage - 1;
start = Math.max(0, start);
stop = Math.max(0, stop);
if (results.targetUid) {
set = 'cid:' + data.cid + ':uid:' + results.targetUid + ':tids';
}
if (data.tag) {
set = [set, 'tag:' + data.tag + ':topics'];
}
categories.modifyTopicsByPrivilege(data.topics, results.privileges);
categories.getCategoryTopics({
cid: data.cid,
set: set,
reverse: reverse,
start: start,
stop: stop,
uid: socket.uid,
targetUid: results.targetUid,
settings: results.settings,
}, next);
},
function (data, next) {
categories.modifyTopicsByPrivilege(data.topics, userPrivileges);
data.privileges = results.privileges;
data.privileges = userPrivileges;
data.template = {
category: true,
name: 'category',
};
callback(null, data);
});
});
next(null, data);
},
], callback);
};
SocketCategories.getPageCount = function (socket, cid, callback) {
@ -150,32 +151,33 @@ SocketCategories.getCategoriesByPrivilege = function (socket, privilege, callbac
};
SocketCategories.getMoveCategories = function (socket, data, callback) {
async.parallel({
isAdmin: async.apply(user.isAdministrator, socket.uid),
categories: function (next) {
async.waterfall([
function (next) {
db.getSortedSetRange('cid:0:children', 0, -1, next);
},
function (cids, next) {
privileges.categories.filterCids('read', cids, socket.uid, next);
},
function (cids, next) {
categories.getCategories(cids, socket.uid, next);
async.waterfall([
function (next) {
async.parallel({
isAdmin: async.apply(user.isAdministrator, socket.uid),
categories: function (next) {
async.waterfall([
function (next) {
db.getSortedSetRange('cid:0:children', 0, -1, next);
},
function (cids, next) {
privileges.categories.filterCids('read', cids, socket.uid, next);
},
function (cids, next) {
categories.getCategories(cids, socket.uid, next);
},
], next);
},
], next);
}, next);
},
}, function (err, results) {
if (err) {
return callback(err);
}
results.categories = results.categories.filter(function (category) {
return category && (!category.disabled || results.isAdmin) && !category.link;
});
function (results, next) {
results.categories = results.categories.filter(function (category) {
return category && (!category.disabled || results.isAdmin) && !category.link;
});
callback(null, results.categories);
});
next(null, results.categories);
},
], callback);
};
SocketCategories.watch = function (socket, cid, callback) {
@ -231,5 +233,3 @@ SocketCategories.isModerator = function (socket, cid, callback) {
SocketCategories.getCategory = function (socket, cid, callback) {
apiController.getCategoryData(cid, socket.uid, callback);
};
module.exports = SocketCategories;

@ -26,14 +26,11 @@ SocketFlags.create = function (socket, data, callback) {
// If we got here, then no errors occurred
flags.create(data.type, data.id, socket.uid, data.reason, next);
},
], function (err, flagObj) {
if (err) {
return callback(err);
}
flags.notify(flagObj, socket.uid);
callback(null, flagObj);
});
function (flagObj, next) {
flags.notify(flagObj, socket.uid);
next(null, flagObj);
},
], callback);
};
SocketFlags.update = function (socket, data, callback) {

@ -8,8 +8,7 @@ var user = require('../user');
var utils = require('../utils');
var groupsController = require('../controllers/groups');
var SocketGroups = {};
var SocketGroups = module.exports;
SocketGroups.before = function (socket, method, data, next) {
if (!data) {
@ -304,5 +303,3 @@ SocketGroups.cover.remove = function (socket, data, callback) {
},
], callback);
};
module.exports = SocketGroups;

@ -13,7 +13,7 @@ var utils = require('../utils');
var apiController = require('../controllers/api');
var SocketPosts = {};
var SocketPosts = module.exports;
require('./posts/edit')(SocketPosts);
require('./posts/move')(SocketPosts);
@ -152,6 +152,3 @@ SocketPosts.getReplies = function (socket, pid, callback) {
},
], callback);
};
module.exports = SocketPosts;

@ -60,25 +60,30 @@ module.exports = function (SocketPosts) {
return callback(new Error('[[error:invalid-data]]'));
}
posts.getUpvotedUidsByPids(pids, function (err, data) {
if (err || !Array.isArray(data) || !data.length) {
return callback(err, []);
}
async.map(data, function (uids, next) {
var otherCount = 0;
if (uids.length > 6) {
otherCount = uids.length - 5;
uids = uids.slice(0, 5);
async.waterfall([
function (next) {
posts.getUpvotedUidsByPids(pids, next);
},
function (data, next) {
if (!data.length) {
return callback(null, []);
}
user.getUsernamesByUids(uids, function (err, usernames) {
next(err, {
otherCount: otherCount,
usernames: usernames,
async.map(data, function (uids, next) {
var otherCount = 0;
if (uids.length > 6) {
otherCount = uids.length - 5;
uids = uids.slice(0, 5);
}
user.getUsernamesByUids(uids, function (err, usernames) {
next(err, {
otherCount: otherCount,
usernames: usernames,
});
});
});
}, callback);
});
}, next);
},
], callback);
};
SocketPosts.upvote = function (socket, data, callback) {

@ -197,17 +197,18 @@ SocketUser.unfollow = function (socket, data, callback) {
};
function toggleFollow(method, uid, theiruid, callback) {
user[method](uid, theiruid, function (err) {
if (err) {
return callback(err);
}
plugins.fireHook('action:user.' + method, {
fromUid: uid,
toUid: theiruid,
});
callback();
});
async.waterfall([
function (next) {
user[method](uid, theiruid, next);
},
function (next) {
plugins.fireHook('action:user.' + method, {
fromUid: uid,
toUid: theiruid,
});
next();
},
], callback);
}
SocketUser.saveSettings = function (socket, data, callback) {

@ -121,11 +121,11 @@ module.exports = function (SocketUser) {
function (next) {
if (!reason) {
return translator.translate('[[user:info.banned-no-reason]]', function (translated) {
next(false, translated);
next(null, translated);
});
}
next(false, reason);
next(null, reason);
},
function (_reason, next) {
websockets.in('uid_' + uid).emit('event:banned', {

@ -67,32 +67,34 @@ module.exports = function (SocketUser) {
};
function isAdminOrSelfAndPasswordMatch(uid, data, callback) {
async.parallel({
isAdmin: async.apply(user.isAdministrator, uid),
hasPassword: async.apply(user.hasPassword, data.uid),
passwordMatch: function (next) {
if (data.password) {
user.isPasswordCorrect(data.uid, data.password, next);
} else {
next(null, false);
}
async.waterfall([
function (next) {
async.parallel({
isAdmin: async.apply(user.isAdministrator, uid),
hasPassword: async.apply(user.hasPassword, data.uid),
passwordMatch: function (next) {
if (data.password) {
user.isPasswordCorrect(data.uid, data.password, next);
} else {
next(null, false);
}
},
}, next);
},
}, function (err, results) {
if (err) {
return callback(err);
}
var isSelf = parseInt(uid, 10) === parseInt(data.uid, 10);
function (results, next) {
var isSelf = parseInt(uid, 10) === parseInt(data.uid, 10);
if (!results.isAdmin && !isSelf) {
return callback(new Error('[[error:no-privileges]]'));
}
if (!results.isAdmin && !isSelf) {
return next(new Error('[[error:no-privileges]]'));
}
if (isSelf && results.hasPassword && !results.passwordMatch) {
return callback(new Error('[[error:invalid-password]]'));
}
if (isSelf && results.hasPassword && !results.passwordMatch) {
return next(new Error('[[error:invalid-password]]'));
}
callback();
});
next();
},
], callback);
}
SocketUser.changePassword = function (socket, data, callback) {
@ -103,20 +105,20 @@ module.exports = function (SocketUser) {
if (!data || !data.uid) {
return callback(new Error('[[error:invalid-data]]'));
}
user.changePassword(socket.uid, data, function (err) {
if (err) {
return callback(err);
}
events.log({
type: 'password-change',
uid: socket.uid,
targetUid: data.uid,
ip: socket.ip,
});
callback();
});
async.waterfall([
function (next) {
user.changePassword(socket.uid, data, next);
},
function (next) {
events.log({
type: 'password-change',
uid: socket.uid,
targetUid: data.uid,
ip: socket.ip,
});
next();
},
], callback);
};
SocketUser.updateProfile = function (socket, data, callback) {

@ -1,5 +1,7 @@
'use strict';
var async = require('async');
var user = require('../../user');
var meta = require('../../meta');
var pagination = require('../../pagination');
@ -9,25 +11,29 @@ module.exports = function (SocketUser) {
if (!data) {
return callback(new Error('[[error:invalid-data]]'));
}
if (!socket.uid && parseInt(meta.config.allowGuestUserSearching, 10) !== 1) {
return callback(new Error('[[error:not-logged-in]]'));
}
user.search({
query: data.query,
page: data.page,
searchBy: data.searchBy,
sortBy: data.sortBy,
onlineOnly: data.onlineOnly,
bannedOnly: data.bannedOnly,
flaggedOnly: data.flaggedOnly,
uid: socket.uid,
}, function (err, result) {
if (err) {
return callback(err);
}
result.pagination = pagination.create(data.page, result.pageCount);
result['route_users:' + data.sortBy] = true;
callback(null, result);
});
async.waterfall([
function (next) {
user.search({
query: data.query,
page: data.page,
searchBy: data.searchBy,
sortBy: data.sortBy,
onlineOnly: data.onlineOnly,
bannedOnly: data.bannedOnly,
flaggedOnly: data.flaggedOnly,
uid: socket.uid,
}, next);
},
function (result, next) {
result.pagination = pagination.create(data.page, result.pageCount);
result['route_users:' + data.sortBy] = true;
next(null, result);
},
], callback);
};
};

@ -1,5 +1,6 @@
'use strict';
var async = require('async');
var validator = require('validator');
var db = require('../database');
@ -21,27 +22,29 @@ function escapeTitle(topicData) {
module.exports = function (Topics) {
Topics.getTopicField = function (tid, field, callback) {
db.getObjectField('topic:' + tid, field, function (err, value) {
if (err) {
return callback(err);
}
if (field === 'title') {
value = translator.escape(validator.escape(String(value)));
}
callback(null, value);
});
async.waterfall([
function (next) {
db.getObjectField('topic:' + tid, field, next);
},
function (value, next) {
if (field === 'title') {
value = translator.escape(validator.escape(String(value)));
}
next(null, value);
},
], callback);
};
Topics.getTopicFields = function (tid, fields, callback) {
db.getObjectFields('topic:' + tid, fields, function (err, topic) {
if (err) {
return callback(err);
}
escapeTitle(topic);
callback(null, topic);
});
async.waterfall([
function (next) {
db.getObjectFields('topic:' + tid, fields, next);
},
function (topic, next) {
escapeTitle(topic);
next(null, topic);
},
], callback);
};
Topics.getTopicsFields = function (tids, fields, callback) {
@ -51,42 +54,38 @@ module.exports = function (Topics) {
var keys = tids.map(function (tid) {
return 'topic:' + tid;
});
db.getObjectsFields(keys, fields, function (err, topics) {
if (err) {
return callback(err);
}
topics.forEach(escapeTitle);
callback(null, topics);
});
async.waterfall([
function (next) {
if (fields.length) {
db.getObjectsFields(keys, fields, next);
} else {
db.getObjects(keys, next);
}
},
function (topics, next) {
topics.forEach(modifyTopic);
next(null, topics);
},
], callback);
};
Topics.getTopicData = function (tid, callback) {
db.getObject('topic:' + tid, function (err, topic) {
if (err || !topic) {
return callback(err);
}
modifyTopic(topic);
callback(null, topic);
});
async.waterfall([
function (next) {
db.getObject('topic:' + tid, next);
},
function (topic, next) {
if (!topic) {
return next(null, null);
}
modifyTopic(topic);
next(null, topic);
},
], callback);
};
Topics.getTopicsData = function (tids, callback) {
var keys = [];
for (var i = 0; i < tids.length; i += 1) {
keys.push('topic:' + tids[i]);
}
db.getObjects(keys, function (err, topics) {
if (err) {
return callback(err);
}
topics.forEach(modifyTopic);
callback(null, topics);
});
Topics.getTopicsFields(tids, [], callback);
};
function modifyTopic(topic) {
@ -102,13 +101,14 @@ module.exports = function (Topics) {
}
Topics.getCategoryData = function (tid, callback) {
Topics.getTopicField(tid, 'cid', function (err, cid) {
if (err) {
return callback(err);
}
categories.getCategoryData(cid, callback);
});
async.waterfall([
function (next) {
Topics.getTopicField(tid, 'cid', next);
},
function (cid, next) {
categories.getCategoryData(cid, next);
},
], callback);
};
Topics.setTopicField = function (tid, field, value, callback) {

@ -126,33 +126,35 @@ module.exports = function (Topics) {
async.parallel([
async.apply(updateRecentTopic, tid),
async.apply(updateRecentTopic, postData.tid),
], next);
], function (err) {
next(err);
});
},
], function (err) {
if (err) {
return callback(err);
}
plugins.fireHook('action:post.move', { post: postData, tid: tid });
callback();
});
function (next) {
plugins.fireHook('action:post.move', { post: postData, tid: tid });
next();
},
], callback);
};
function updateCategoryPostCount(oldTid, tid, callback) {
Topics.getTopicsFields([oldTid, tid], ['cid'], function (err, topicData) {
if (err) {
return callback(err);
}
if (!topicData[0].cid || !topicData[1].cid) {
return callback();
}
if (parseInt(topicData[0].cid, 10) === parseInt(topicData[1].cid, 10)) {
return callback();
}
async.parallel([
async.apply(db.incrObjectFieldBy, 'category:' + topicData[0].cid, 'post_count', -1),
async.apply(db.incrObjectFieldBy, 'category:' + topicData[1].cid, 'post_count', 1),
], callback);
});
async.waterfall([
function (next) {
Topics.getTopicsFields([oldTid, tid], ['cid'], next);
},
function (topicData, next) {
if (!topicData[0].cid || !topicData[1].cid) {
return callback();
}
if (parseInt(topicData[0].cid, 10) === parseInt(topicData[1].cid, 10)) {
return callback();
}
async.parallel([
async.apply(db.incrObjectFieldBy, 'category:' + topicData[0].cid, 'post_count', -1),
async.apply(db.incrObjectFieldBy, 'category:' + topicData[1].cid, 'post_count', 1),
], next);
},
], callback);
}
function updateRecentTopic(tid, callback) {

@ -9,33 +9,35 @@ var search = require('../search');
module.exports = function (Topics) {
Topics.getSuggestedTopics = function (tid, uid, start, stop, callback) {
async.parallel({
tagTids: function (next) {
getTidsWithSameTags(tid, next);
},
searchTids: function (next) {
getSearchTids(tid, next);
},
categoryTids: function (next) {
getCategoryTids(tid, next);
async.waterfall([
function (next) {
async.parallel({
tagTids: function (next) {
getTidsWithSameTags(tid, next);
},
searchTids: function (next) {
getSearchTids(tid, next);
},
categoryTids: function (next) {
getCategoryTids(tid, next);
},
}, next);
},
}, function (err, results) {
if (err) {
return callback(err);
}
var tids = results.tagTids.concat(results.searchTids).concat(results.categoryTids);
tids = tids.filter(function (_tid, index, array) {
return parseInt(_tid, 10) !== parseInt(tid, 10) && array.indexOf(_tid) === index;
});
function (results, next) {
var tids = results.tagTids.concat(results.searchTids).concat(results.categoryTids);
tids = tids.filter(function (_tid, index, array) {
return parseInt(_tid, 10) !== parseInt(tid, 10) && array.indexOf(_tid) === index;
});
if (stop === -1) {
tids = tids.slice(start);
} else {
tids = tids.slice(start, stop + 1);
}
if (stop === -1) {
tids = tids.slice(start);
} else {
tids = tids.slice(start, stop + 1);
}
Topics.getTopics(tids, uid, callback);
});
Topics.getTopics(tids, uid, next);
},
], callback);
};
function getTidsWithSameTags(tid, callback) {

@ -13,7 +13,6 @@ module.exports = function (Topics) {
var topicTools = {};
Topics.tools = topicTools;
topicTools.delete = function (tid, uid, callback) {
toggleDelete(tid, uid, true, callback);
};
@ -246,6 +245,7 @@ module.exports = function (Topics) {
topicTools.move = function (tid, cid, uid, callback) {
var topic;
var oldCid;
async.waterfall([
function (next) {
Topics.exists(tid, next);
@ -276,41 +276,41 @@ module.exports = function (Topics) {
topic.postcount = topic.postcount || 0;
db.sortedSetAdd('cid:' + cid + ':tids:posts', topic.postcount, tid, next);
},
], next);
], function (err) {
next(err);
});
}
},
], function (err) {
if (err) {
return callback(err);
}
var oldCid = topic.cid;
categories.moveRecentReplies(tid, oldCid, cid);
async.parallel([
function (next) {
categories.incrementCategoryFieldBy(oldCid, 'topic_count', -1, next);
},
function (next) {
categories.incrementCategoryFieldBy(cid, 'topic_count', 1, next);
},
function (next) {
Topics.setTopicFields(tid, {
cid: cid,
oldCid: oldCid,
}, next);
},
], function (err) {
if (err) {
return callback(err);
}
function (next) {
oldCid = topic.cid;
categories.moveRecentReplies(tid, oldCid, cid);
async.parallel([
function (next) {
categories.incrementCategoryFieldBy(oldCid, 'topic_count', -1, next);
},
function (next) {
categories.incrementCategoryFieldBy(cid, 'topic_count', 1, next);
},
function (next) {
Topics.setTopicFields(tid, {
cid: cid,
oldCid: oldCid,
}, next);
},
], function (err) {
next(err);
});
},
function (next) {
plugins.fireHook('action:topic.move', {
tid: tid,
fromCid: oldCid,
toCid: cid,
uid: uid,
});
callback();
});
});
next();
},
], callback);
};
};

@ -326,30 +326,31 @@ module.exports = function (Topics) {
}));
}
async.parallel({
recentScores: function (next) {
db.sortedSetScores('topics:recent', tids, next);
},
userScores: function (next) {
db.sortedSetScores('uid:' + uid + ':tids_read', tids, next);
},
tids_unread: function (next) {
db.sortedSetScores('uid:' + uid + ':tids_unread', tids, next);
async.waterfall([
function (next) {
async.parallel({
recentScores: function (next) {
db.sortedSetScores('topics:recent', tids, next);
},
userScores: function (next) {
db.sortedSetScores('uid:' + uid + ':tids_read', tids, next);
},
tids_unread: function (next) {
db.sortedSetScores('uid:' + uid + ':tids_unread', tids, next);
},
}, next);
},
}, function (err, results) {
if (err) {
return callback(err);
}
var cutoff = Topics.unreadCutoff();
var result = tids.map(function (tid, index) {
return !results.tids_unread[index] &&
(results.recentScores[index] < cutoff ||
!!(results.userScores[index] && results.userScores[index] >= results.recentScores[index]));
});
function (results, next) {
var cutoff = Topics.unreadCutoff();
var result = tids.map(function (tid, index) {
return !results.tids_unread[index] &&
(results.recentScores[index] < cutoff ||
!!(results.userScores[index] && results.userScores[index] >= results.recentScores[index]));
});
callback(null, result);
});
next(null, result);
},
], callback);
};
Topics.hasReadTopic = function (tid, uid, callback) {

@ -11,23 +11,24 @@ module.exports = function (User) {
};
User.getWatchedCategories = function (uid, callback) {
async.parallel({
ignored: function (next) {
User.getIgnoredCategories(uid, next);
async.waterfall([
function (next) {
async.parallel({
ignored: function (next) {
User.getIgnoredCategories(uid, next);
},
all: function (next) {
db.getSortedSetRange('categories:cid', 0, -1, next);
},
}, next);
},
all: function (next) {
db.getSortedSetRange('categories:cid', 0, -1, next);
function (results, next) {
var watched = results.all.filter(function (cid) {
return cid && results.ignored.indexOf(cid) === -1;
});
next(null, watched);
},
}, function (err, results) {
if (err) {
return callback(err);
}
var watched = results.all.filter(function (cid) {
return cid && results.ignored.indexOf(cid) === -1;
});
callback(null, watched);
});
], callback);
};
User.ignoreCategory = function (uid, cid, callback) {

@ -15,137 +15,129 @@ module.exports = function (User) {
if (data.email !== undefined) {
data.email = validator.escape(String(data.email).trim());
}
var timestamp = data.timestamp || Date.now();
var userData;
var userNameChanged = false;
User.isDataValid(data, function (err) {
if (err) {
return callback(err);
}
var timestamp = data.timestamp || Date.now();
var userData = {
username: data.username,
userslug: data.userslug,
email: data.email || '',
joindate: timestamp,
lastonline: timestamp,
picture: data.picture || '',
fullname: data.fullname || '',
location: data.location || '',
birthday: data.birthday || '',
website: '',
signature: '',
uploadedpicture: '',
profileviews: 0,
reputation: 0,
postcount: 0,
topiccount: 0,
lastposttime: 0,
banned: 0,
status: 'online',
};
async.parallel({
renamedUsername: function (next) {
User.uniqueUsername(userData, next);
},
userData: function (next) {
plugins.fireHook('filter:user.create', { user: userData, data: data }, next);
},
}, function (err, results) {
if (err) {
return callback(err);
}
var userNameChanged = !!results.renamedUsername;
async.waterfall([
function (next) {
User.isDataValid(data, next);
},
function (next) {
userData = {
username: data.username,
userslug: data.userslug,
email: data.email || '',
joindate: timestamp,
lastonline: timestamp,
picture: data.picture || '',
fullname: data.fullname || '',
location: data.location || '',
birthday: data.birthday || '',
website: '',
signature: '',
uploadedpicture: '',
profileviews: 0,
reputation: 0,
postcount: 0,
topiccount: 0,
lastposttime: 0,
banned: 0,
status: 'online',
};
User.uniqueUsername(userData, next);
},
function (renamedUsername, next) {
userNameChanged = !!renamedUsername;
if (userNameChanged) {
userData.username = results.renamedUsername;
userData.userslug = utils.slugify(results.renamedUsername);
userData.username = renamedUsername;
userData.userslug = utils.slugify(renamedUsername);
}
async.waterfall([
plugins.fireHook('filter:user.create', { user: userData, data: data }, next);
},
function (results, next) {
userData = results.user;
db.incrObjectField('global', 'nextUid', next);
},
function (uid, next) {
userData.uid = uid;
db.setObject('user:' + uid, userData, next);
},
function (next) {
async.parallel([
function (next) {
db.incrObjectField('global', 'nextUid', next);
db.incrObjectField('global', 'userCount', next);
},
function (uid, next) {
userData.uid = uid;
db.setObject('user:' + uid, userData, next);
function (next) {
db.sortedSetAdd('username:uid', userData.uid, userData.username, next);
},
function (next) {
async.parallel([
function (next) {
db.incrObjectField('global', 'userCount', next);
},
function (next) {
db.sortedSetAdd('username:uid', userData.uid, userData.username, next);
},
function (next) {
db.sortedSetAdd('username:sorted', 0, userData.username.toLowerCase() + ':' + userData.uid, next);
},
function (next) {
db.sortedSetAdd('userslug:uid', userData.uid, userData.userslug, next);
},
function (next) {
var sets = ['users:joindate', 'users:online'];
if (parseInt(userData.uid, 10) !== 1) {
sets.push('users:notvalidated');
}
db.sortedSetsAdd(sets, timestamp, userData.uid, next);
},
function (next) {
db.sortedSetsAdd(['users:postcount', 'users:reputation'], 0, userData.uid, next);
},
function (next) {
groups.join('registered-users', userData.uid, next);
},
function (next) {
User.notifications.sendWelcomeNotification(userData.uid, next);
},
function (next) {
if (userData.email) {
async.parallel([
async.apply(db.sortedSetAdd, 'email:uid', userData.uid, userData.email.toLowerCase()),
async.apply(db.sortedSetAdd, 'email:sorted', 0, userData.email.toLowerCase() + ':' + userData.uid),
], next);
if (parseInt(userData.uid, 10) !== 1 && parseInt(meta.config.requireEmailConfirmation, 10) === 1) {
User.email.sendValidationEmail(userData.uid, userData.email);
}
} else {
next();
}
},
function (next) {
if (!data.password) {
return next();
}
db.sortedSetAdd('username:sorted', 0, userData.username.toLowerCase() + ':' + userData.uid, next);
},
function (next) {
db.sortedSetAdd('userslug:uid', userData.uid, userData.userslug, next);
},
function (next) {
var sets = ['users:joindate', 'users:online'];
if (parseInt(userData.uid, 10) !== 1) {
sets.push('users:notvalidated');
}
db.sortedSetsAdd(sets, timestamp, userData.uid, next);
},
function (next) {
db.sortedSetsAdd(['users:postcount', 'users:reputation'], 0, userData.uid, next);
},
function (next) {
groups.join('registered-users', userData.uid, next);
},
function (next) {
User.notifications.sendWelcomeNotification(userData.uid, next);
},
function (next) {
if (userData.email) {
async.parallel([
async.apply(db.sortedSetAdd, 'email:uid', userData.uid, userData.email.toLowerCase()),
async.apply(db.sortedSetAdd, 'email:sorted', 0, userData.email.toLowerCase() + ':' + userData.uid),
], next);
if (parseInt(userData.uid, 10) !== 1 && parseInt(meta.config.requireEmailConfirmation, 10) === 1) {
User.email.sendValidationEmail(userData.uid, userData.email);
}
} else {
next();
}
},
function (next) {
if (!data.password) {
return next();
}
User.hashPassword(data.password, function (err, hash) {
if (err) {
return next(err);
}
User.hashPassword(data.password, function (err, hash) {
if (err) {
return next(err);
}
async.parallel([
async.apply(User.setUserField, userData.uid, 'password', hash),
async.apply(User.reset.updateExpiry, userData.uid),
], next);
});
},
function (next) {
User.updateDigestSetting(userData.uid, meta.config.dailyDigestFreq, next);
},
], next);
async.parallel([
async.apply(User.setUserField, userData.uid, 'password', hash),
async.apply(User.reset.updateExpiry, userData.uid),
], next);
});
},
function (results, next) {
if (userNameChanged) {
User.notifications.sendNameChangeNotification(userData.uid, userData.username);
}
plugins.fireHook('action:user.create', { user: userData });
next(null, userData.uid);
function (next) {
User.updateDigestSetting(userData.uid, meta.config.dailyDigestFreq, next);
},
], callback);
});
});
], next);
},
function (results, next) {
if (userNameChanged) {
User.notifications.sendNameChangeNotification(userData.uid, userData.username);
}
plugins.fireHook('action:user.create', { user: userData });
next(null, userData.uid);
},
], callback);
};
User.isDataValid = function (userData, callback) {
@ -201,26 +193,23 @@ module.exports = function (User) {
};
User.uniqueUsername = function (userData, callback) {
meta.userOrGroupExists(userData.userslug, function (err, exists) {
if (err || !exists) {
return callback(err);
}
var num = 0;
function go() {
var username = userData.username + ' ' + num.toString(32);
meta.userOrGroupExists(username, function (err, exists) {
if (err || !exists) {
return callback(err, username);
var numTries = 0;
function go(username) {
async.waterfall([
function (next) {
meta.userOrGroupExists(username, next);
},
function (exists) {
if (!exists) {
return callback(null, numTries ? username : null);
}
username = userData.username + ' ' + numTries.toString(32);
numTries += 1;
go(username);
},
], callback);
}
num += 1;
go();
});
}
go();
});
go(userData.userslug);
};
};

@ -191,7 +191,6 @@ UserNotifications.getUnreadCount = function (uid, callback) {
return callback(null, 0);
}
async.waterfall([
function (next) {
db.getSortedSetRevRange('uid:' + uid + ':notifications:unread', 0, 99, next);

@ -17,22 +17,21 @@ module.exports = function (User) {
User.isPasswordCorrect = function (uid, password, callback) {
password = password || '';
var hashedPassword;
async.waterfall([
function (next) {
db.getObjectField('user:' + uid, 'password', next);
},
function (hashedPassword, next) {
function (_hashedPassword, next) {
hashedPassword = _hashedPassword;
if (!hashedPassword) {
return callback(null, true);
}
User.isPasswordValid(password, function (err) {
if (err) {
return next(err);
}
Password.compare(password, hashedPassword, next);
});
User.isPasswordValid(password, next);
},
function (next) {
Password.compare(password, hashedPassword, next);
},
], callback);
};

@ -183,14 +183,15 @@ module.exports = function (User) {
if (!convertToPNG) {
return setImmediate(callback, null, path);
}
image.normalise(path, extension, function (err, newPath) {
if (err) {
return callback(err);
}
file.delete(path);
callback(null, newPath);
});
async.waterfall([
function (next) {
image.normalise(path, extension, next);
},
function (newPath, next) {
file.delete(path);
next(null, newPath);
},
], callback);
}
function uploadProfileOrCover(filename, image, callback) {

@ -10,55 +10,55 @@ module.exports = function (User) {
if (parseInt(uid, 10) === 0) {
return callback();
}
async.parallel({
userData: function (next) {
User.getUserFields(uid, ['banned', 'lastposttime', 'joindate', 'email', 'email:confirmed', 'reputation'], next);
},
exists: function (next) {
db.exists('user:' + uid, next);
},
isAdminOrMod: function (next) {
privileges.categories.isAdminOrMod(cid, uid, next);
async.waterfall([
function (next) {
async.parallel({
userData: function (next) {
User.getUserFields(uid, ['banned', 'lastposttime', 'joindate', 'email', 'email:confirmed', 'reputation'], next);
},
exists: function (next) {
db.exists('user:' + uid, next);
},
isAdminOrMod: function (next) {
privileges.categories.isAdminOrMod(cid, uid, next);
},
}, next);
},
}, function (err, results) {
if (err) {
return callback(err);
}
function (results, next) {
if (!results.exists) {
return next(new Error('[[error:no-user]]'));
}
if (!results.exists) {
return callback(new Error('[[error:no-user]]'));
}
if (results.isAdminOrMod) {
return next();
}
if (results.isAdminOrMod) {
return callback();
}
var userData = results.userData;
var userData = results.userData;
if (parseInt(userData.banned, 10) === 1) {
return next(new Error('[[error:user-banned]]'));
}
if (parseInt(userData.banned, 10) === 1) {
return callback(new Error('[[error:user-banned]]'));
}
if (parseInt(meta.config.requireEmailConfirmation, 10) === 1 && parseInt(userData['email:confirmed'], 10) !== 1) {
return next(new Error('[[error:email-not-confirmed]]'));
}
if (parseInt(meta.config.requireEmailConfirmation, 10) === 1 && parseInt(userData['email:confirmed'], 10) !== 1) {
return callback(new Error('[[error:email-not-confirmed]]'));
}
var now = Date.now();
if (now - parseInt(userData.joindate, 10) < parseInt(meta.config.initialPostDelay, 10) * 1000) {
return next(new Error('[[error:user-too-new, ' + meta.config.initialPostDelay + ']]'));
}
var now = Date.now();
if (now - parseInt(userData.joindate, 10) < parseInt(meta.config.initialPostDelay, 10) * 1000) {
return callback(new Error('[[error:user-too-new, ' + meta.config.initialPostDelay + ']]'));
}
var lastposttime = userData.lastposttime || 0;
var lastposttime = userData.lastposttime || 0;
if (parseInt(meta.config.newbiePostDelay, 10) > 0 && parseInt(meta.config.newbiePostDelayThreshold, 10) > parseInt(userData.reputation, 10) && now - parseInt(lastposttime, 10) < parseInt(meta.config.newbiePostDelay, 10) * 1000) {
return next(new Error('[[error:too-many-posts-newbie, ' + meta.config.newbiePostDelay + ', ' + meta.config.newbiePostDelayThreshold + ']]'));
} else if (now - parseInt(lastposttime, 10) < parseInt(meta.config.postDelay, 10) * 1000) {
return next(new Error('[[error:too-many-posts, ' + meta.config.postDelay + ']]'));
}
if (parseInt(meta.config.newbiePostDelay, 10) > 0 && parseInt(meta.config.newbiePostDelayThreshold, 10) > parseInt(userData.reputation, 10) && now - parseInt(lastposttime, 10) < parseInt(meta.config.newbiePostDelay, 10) * 1000) {
return callback(new Error('[[error:too-many-posts-newbie, ' + meta.config.newbiePostDelay + ', ' + meta.config.newbiePostDelayThreshold + ']]'));
} else if (now - parseInt(lastposttime, 10) < parseInt(meta.config.postDelay, 10) * 1000) {
return callback(new Error('[[error:too-many-posts, ' + meta.config.postDelay + ']]'));
}
callback();
});
next();
},
], callback);
};
User.onNewPostMade = function (postData, callback) {
@ -84,15 +84,17 @@ module.exports = function (User) {
User.incrementUserPostCountBy = function (uid, value, callback) {
callback = callback || function () {};
User.incrementUserFieldBy(uid, 'postcount', value, function (err, newpostcount) {
if (err) {
return callback(err);
}
if (!parseInt(uid, 10)) {
return callback();
}
db.sortedSetAdd('users:postcount', newpostcount, uid, callback);
});
async.waterfall([
function (next) {
User.incrementUserFieldBy(uid, 'postcount', value, next);
},
function (newpostcount, next) {
if (!parseInt(uid, 10)) {
return next();
}
db.sortedSetAdd('users:postcount', newpostcount, uid, next);
},
], callback);
};
User.getPostIds = function (uid, start, stop, callback) {

@ -63,9 +63,9 @@ module.exports.listen = function (callback) {
helpers.register();
logger.init(app);
next();
initializeNodeBB(next);
},
initializeNodeBB,
function (next) {
winston.info('NodeBB Ready');

@ -69,6 +69,31 @@ describe('User', function () {
done();
});
});
it('should error with invalid password', function (done) {
User.create({ username: 'test', password: '1' }, function (err) {
assert.equal(err.message, '[[user:change_password_error_length]]');
done();
});
});
it('should error with invalid password', function (done) {
User.create({ username: 'test', password: {} }, function (err) {
assert.equal(err.message, '[[error:invalid-password]]');
done();
});
});
it('should error with a too long password', function (done) {
var toolong = '';
for (var i = 0; i < 5000; i++) {
toolong += 'a';
}
User.create({ username: 'test', password: toolong }, function (err) {
assert.equal(err.message, '[[error:password-too-long]]');
done();
});
});
});
describe('.uniqueUsername()', function () {
@ -77,7 +102,6 @@ describe('User', function () {
for (var i = 0; i < 10; i += 1) {
users.push({
username: 'Jane Doe',
password: 'abcdefghi',
email: 'jane.doe' + i + '@example.com',
});
}

Loading…
Cancel
Save