mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 03:26:04 +01:00
style changes
This commit is contained in:
@@ -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);
|
||||
}
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.getSortedSetRangeByScoreWithScores('uid:' + uid + ':rewards', 0, -1, 1, '+inf', next);
|
||||
},
|
||||
function (data, next) {
|
||||
var userRewards = {};
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
};
|
||||
next();
|
||||
},
|
||||
], callback);
|
||||
};
|
||||
|
||||
passport.serializeUser(function (user, done) {
|
||||
done(null, user.uid);
|
||||
});
|
||||
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);
|
||||
}
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
require('../meta/build').buildAll(next);
|
||||
},
|
||||
function (next) {
|
||||
events.log({
|
||||
type: 'build',
|
||||
uid: socket.uid,
|
||||
ip: socket.ip,
|
||||
});
|
||||
|
||||
events.log({
|
||||
type: 'build',
|
||||
uid: socket.uid,
|
||||
ip: socket.ip,
|
||||
});
|
||||
events.log({
|
||||
type: 'restart',
|
||||
uid: socket.uid,
|
||||
ip: socket.ip,
|
||||
});
|
||||
|
||||
events.log({
|
||||
type: 'restart',
|
||||
uid: socket.uid,
|
||||
ip: socket.ip,
|
||||
});
|
||||
|
||||
meta.restart();
|
||||
callback();
|
||||
});
|
||||
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.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);
|
||||
}, callback);
|
||||
});
|
||||
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);
|
||||
}
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
groups.getMemberCount('administrators', next);
|
||||
},
|
||||
function (count, next) {
|
||||
if (count === 1) {
|
||||
return next(new Error('[[error:cant-remove-last-admin]]'));
|
||||
}
|
||||
|
||||
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]]'));
|
||||
}
|
||||
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, callback);
|
||||
});
|
||||
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);
|
||||
}
|
||||
function (results, next) {
|
||||
results.categories = results.categories.filter(function (category) {
|
||||
return category && (!category.disabled || results.isAdmin);
|
||||
});
|
||||
|
||||
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;
|
||||
});
|
||||
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;
|
||||
});
|
||||
|
||||
callback(null, watchedCategories);
|
||||
});
|
||||
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);
|
||||
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);
|
||||
},
|
||||
settings: function (next) {
|
||||
user.getSettings(socket.uid, 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);
|
||||
}
|
||||
var infScrollTopicsPerPage = 20;
|
||||
var set = 'cid:' + data.cid + ':tids';
|
||||
var reverse = false;
|
||||
|
||||
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);
|
||||
if (data.categoryTopicSort === 'newest_to_oldest') {
|
||||
reverse = true;
|
||||
} else if (data.categoryTopicSort === 'most_posts') {
|
||||
reverse = true;
|
||||
set = 'cid:' + data.cid + ':tids:posts';
|
||||
}
|
||||
|
||||
categories.modifyTopicsByPrivilege(data.topics, results.privileges);
|
||||
var start = Math.max(0, parseInt(data.after, 10));
|
||||
|
||||
data.privileges = results.privileges;
|
||||
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,
|
||||
}, next);
|
||||
},
|
||||
function (data, next) {
|
||||
categories.modifyTopicsByPrivilege(data.topics, userPrivileges);
|
||||
|
||||
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);
|
||||
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);
|
||||
},
|
||||
function (cids, next) {
|
||||
privileges.categories.filterCids('read', cids, socket.uid, next);
|
||||
},
|
||||
function (cids, next) {
|
||||
categories.getCategories(cids, socket.uid, next);
|
||||
},
|
||||
], next);
|
||||
}, next);
|
||||
},
|
||||
}, function (err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
function (results, next) {
|
||||
results.categories = results.categories.filter(function (category) {
|
||||
return category && (!category.disabled || results.isAdmin) && !category.link;
|
||||
});
|
||||
|
||||
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);
|
||||
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);
|
||||
},
|
||||
searchTids: function (next) {
|
||||
getSearchTids(tid, next);
|
||||
},
|
||||
categoryTids: function (next) {
|
||||
getCategoryTids(tid, 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);
|
||||
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) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
},
|
||||
userScores: function (next) {
|
||||
db.sortedSetScores('uid:' + uid + ':tids_read', tids, next);
|
||||
},
|
||||
tids_unread: function (next) {
|
||||
db.sortedSetScores('uid:' + uid + ':tids_unread', tids, next);
|
||||
},
|
||||
}, function (err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
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]));
|
||||
});
|
||||
|
||||
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();
|
||||
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',
|
||||
};
|
||||
|
||||
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;
|
||||
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);
|
||||
},
|
||||
function (uid, next) {
|
||||
userData.uid = uid;
|
||||
db.setObject('user:' + uid, userData, next);
|
||||
db.incrObjectField('global', 'userCount', 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();
|
||||
}
|
||||
|
||||
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);
|
||||
db.sortedSetAdd('username:uid', userData.uid, userData.username, next);
|
||||
},
|
||||
function (results, next) {
|
||||
if (userNameChanged) {
|
||||
User.notifications.sendNameChangeNotification(userData.uid, userData.username);
|
||||
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');
|
||||
}
|
||||
plugins.fireHook('action:user.create', { user: userData });
|
||||
next(null, userData.uid);
|
||||
db.sortedSetsAdd(sets, timestamp, userData.uid, next);
|
||||
},
|
||||
], callback);
|
||||
});
|
||||
});
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
},
|
||||
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);
|
||||
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);
|
||||
},
|
||||
exists: function (next) {
|
||||
db.exists('user:' + uid, next);
|
||||
function (results, next) {
|
||||
if (!results.exists) {
|
||||
return next(new Error('[[error:no-user]]'));
|
||||
}
|
||||
|
||||
if (results.isAdminOrMod) {
|
||||
return next();
|
||||
}
|
||||
|
||||
var userData = results.userData;
|
||||
|
||||
if (parseInt(userData.banned, 10) === 1) {
|
||||
return next(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]]'));
|
||||
}
|
||||
|
||||
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 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 + ']]'));
|
||||
}
|
||||
|
||||
next();
|
||||
},
|
||||
isAdminOrMod: function (next) {
|
||||
privileges.categories.isAdminOrMod(cid, uid, next);
|
||||
},
|
||||
}, function (err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (!results.exists) {
|
||||
return callback(new Error('[[error:no-user]]'));
|
||||
}
|
||||
|
||||
if (results.isAdminOrMod) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
var userData = results.userData;
|
||||
|
||||
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 callback(new Error('[[error:email-not-confirmed]]'));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
});
|
||||
], 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');
|
||||
|
||||
|
||||
26
test/user.js
26
test/user.js
@@ -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',
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user