From 1eafc6ba3def4e55b3ff3b125cd7677d900871e5 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 15 Mar 2014 15:09:54 -0400 Subject: [PATCH 1/8] moved user delete to its own file, closes #746 --- src/user.js | 1 + src/user/admin.js | 324 +------------------------------------------- src/user/delete.js | 331 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 333 insertions(+), 323 deletions(-) create mode 100644 src/user/delete.js diff --git a/src/user.js b/src/user.js index ba55215512..5249a9b4e0 100644 --- a/src/user.js +++ b/src/user.js @@ -26,6 +26,7 @@ var bcrypt = require('bcryptjs'), require('./user/follow')(User); require('./user/profile')(User); require('./user/admin')(User); + require('./user/delete')(User); require('./user/settings')(User); require('./user/search')(User); diff --git a/src/user/admin.js b/src/user/admin.js index 3289cb1f90..b6b97b2065 100644 --- a/src/user/admin.js +++ b/src/user/admin.js @@ -2,14 +2,7 @@ 'use strict'; var async = require('async'), - db = require('./../database'), - posts = require('./../posts'), - user = require('./../user'), - topics = require('./../topics'), - categories = require('./../categories'), - plugins = require('./../plugins'), - events = require('./../events'), - groups = require('./../groups'); + db = require('./../database'); module.exports = function(User) { @@ -59,319 +52,4 @@ module.exports = function(User) { User.unban = function(uid, callback) { User.setUserField(uid, 'banned', 0, callback); }; - - User.delete = function(adminUid, uid, callback) { - async.waterfall([ - function(next) { - deletePosts(uid, next); - }, - function(next) { - deleteTopics(uid, next); - }, - function(next) { - events.logAdminUserDelete(adminUid, uid, next); - } - ], function(err) { - if (err) { - return callback(err); - } - - deleteAccount(uid, callback); - }); - }; - - function deletePosts(uid, callback) { - deleteSortedSetElements('uid:' + uid + ':posts', deletePost, callback); - } - - function deletePost(pid, callback) { - async.parallel([ - function(next) { - deletePostFromTopic(pid, next); - }, - function(next) { - deletePostFromCategoryRecentPosts(pid, next); - }, - function(next) { - deletePostFromUsersFavourites(pid, next); - }, - function(next) { - deletePostFromUsersVotes(pid, next); - }, - function(next) { - db.sortedSetRemove('posts:pid', pid, next); - } - ], function(err) { - if (err) { - return callback(err); - } - - plugins.fireHook('action:post.delete', pid); - db.delete('post:' + pid, callback); - }); - } - - function deletePostFromTopic(pid, callback) { - posts.getPostFields(pid, ['tid', 'deleted'], function(err, postData) { - if (err) { - return callback(err); - } - - db.sortedSetRemove('tid:' + postData.tid + ':posts', pid, function(err) { - if (err) { - return callback(err); - } - - if (parseInt(postData.deleted, 10) === 0) { - db.decrObjectField('global', 'postCount', callback); - } else { - callback(); - } - }); - }); - } - - function deletePostFromCategoryRecentPosts(pid, callback) { - db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { - if (err) { - return callback(err); - } - - async.each(cids, function(cid, next) { - db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid, next); - }, callback); - }); - } - - function deletePostFromUsersFavourites(pid, callback) { - db.getSetMembers('pid:' + pid + ':users_favourited', function(err, uids) { - if (err) { - return callback(err); - } - - async.each(uids, function(uid, next) { - db.sortedSetRemove('uid:' + uid + ':favourites', pid, next); - }, function(err) { - if (err) { - return callback(err); - } - - db.delete('pid:' + pid + ':users_favourited', callback); - }); - }); - } - - function deletePostFromUsersVotes(pid, callback) { - async.parallel({ - upvoters: function(next) { - db.getSetMembers('pid:' + pid + ':upvote', next); - }, - downvoters: function(next) { - db.getSetMembers('pid:' + pid + ':downvote', next); - } - }, function(err, results) { - if (err) { - return callback(err); - } - - async.parallel([ - function(next) { - async.each(results.upvoters, function(uid, next) { - db.sortedSetRemove('uid:' + uid + ':upvote', pid, next); - }, next); - }, - function(next) { - async.each(results.downvoters, function(uid, next) { - db.sortedSetRemove('uid:' + uid + ':downvote', pid, next); - }, next); - } - ], callback); - }); - } - - function deleteTopics(uid, callback) { - deleteSortedSetElements('uid:' + uid + ':topics', deleteTopic, callback); - } - - function deleteSortedSetElements(set, deleteMethod, callback) { - db.getSortedSetRange(set, 0, -1, function(err, ids) { - if (err) { - return callback(err); - } - - async.each(ids, deleteMethod, callback); - }); - } - - function deleteTopic(tid, callback) { - - async.parallel([ - function(next) { - db.delete('tid:' + tid + ':followers', next); - }, - function(next) { - db.delete('tid:' + tid + ':read_by_uid', next); - }, - function(next) { - db.sortedSetRemove('topics:tid', tid, next); - }, - function(next) { - db.sortedSetRemove('topics:recent', tid, next); - }, - function(next) { - db.sortedSetRemove('topics:posts', tid, next); - }, - function(next) { - db.sortedSetRemove('topics:views', tid, next); - }, - function(next) { - deleteTopicFromCategory(tid, next); - } - ], function(err) { - if (err) { - return callback(err); - } - plugins.fireHook('action:topic.delete', tid); - db.delete('topic:' + tid, callback); - }); - } - - function deleteTopicFromCategory(tid, callback) { - topics.getTopicFields(tid, ['cid', 'deleted'], function(err, topicData) { - if (err) { - return callback(err); - } - - db.sortedSetRemove('categories:' + topicData.cid + ':tid', tid, function(err) { - if (err) { - return callback(err); - } - - db.decrObjectField('category:' + topicData.cid, 'topic_count', function(err) { - if (err) { - return callback(err); - } - - if (parseInt(topicData.deleted, 10) === 0) { - db.decrObjectField('global', 'topicCount', callback); - } else { - callback(); - } - }); - }); - }); - } - - function deleteAccount(uid, callback) { - user.getUserFields(uid, ['username', 'userslug', 'email'], function(err, userData) { - if (err) { - return callback(err); - } - - async.parallel([ - function(next) { - db.deleteObjectField('username:uid', userData.username, next); - }, - function(next) { - db.deleteObjectField('userslug:uid', userData.userslug, next); - }, - function(next) { - db.deleteObjectField('email:uid', userData.email, next); - }, - function(next) { - db.delete('uid:' + uid + ':notifications:read', next); - }, - function(next) { - db.delete('uid:' + uid + ':notifications:unread', next); - }, - function(next) { - db.sortedSetRemove('users:joindate', uid, next); - }, - function(next) { - db.sortedSetRemove('users:postcount', uid, next); - }, - function(next) { - db.sortedSetRemove('users:reputation', uid, next); - }, - function(next) { - db.delete('uid:' + uid + ':favourites', next); - }, - function(next) { - db.delete('uid:' + uid + ':topics', next); - }, - function(next) { - db.delete('uid:' + uid + ':posts', next); - }, - function(next) { - db.delete('uid:' + uid + ':chats', next); - }, - function(next) { - db.delete('uid:' + uid + ':ip', next); - }, - function(next) { - db.delete('uid:' + uid + ':upvote', next); - }, - function(next) { - db.delete('uid:' + uid + ':downvote', next); - }, - function(next) { - deleteUserFromCategoryActiveUsers(uid, next); - }, - function(next) { - deleteUserFromFollowers(uid, next); - }, - function(next) { - deleteUserFromGroups(uid, next); - } - ], function(err) { - if (err) { - return callback(err); - } - - async.parallel([ - function(next) { - db.delete('followers:' + uid, next); - }, - function(next) { - db.delete('following:' + uid, next); - }, - function(next) { - db.delete('user:' + uid, next); - } - ], callback); - }); - }); - } - - function deleteUserFromCategoryActiveUsers(uid, callback) { - db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { - if (err) { - return callback(err); - } - - async.each(cids, function(cid, next) { - categories.removeActiveUser(cid, uid, next); - }, callback); - }); - } - - function deleteUserFromFollowers(uid, callback) { - db.getSetMembers('followers:' + uid, function(err, uids) { - if (err) { - return callback(err); - } - - async.each(uids, function(theiruid, next) { - db.setRemove('following:' + theiruid, uid, next); - }, callback); - }); - } - - function deleteUserFromGroups(uid, callback) { - groups.getGroupIds(function(err, gids) { - async.each(gids, function(gid, next) { - groups.leave(gid, uid, next); - }, callback); - }); - } }; diff --git a/src/user/delete.js b/src/user/delete.js new file mode 100644 index 0000000000..1a8036e837 --- /dev/null +++ b/src/user/delete.js @@ -0,0 +1,331 @@ + +'use strict'; + +var async = require('async'), + db = require('./../database'), + posts = require('./../posts'), + user = require('./../user'), + topics = require('./../topics'), + categories = require('./../categories'), + plugins = require('./../plugins'), + events = require('./../events'), + groups = require('./../groups'); + + +module.exports = function(User) { + + User.delete = function(adminUid, uid, callback) { + async.waterfall([ + function(next) { + deletePosts(uid, next); + }, + function(next) { + deleteTopics(uid, next); + }, + function(next) { + events.logAdminUserDelete(adminUid, uid, next); + } + ], function(err) { + if (err) { + return callback(err); + } + + deleteAccount(uid, callback); + }); + }; + + function deletePosts(uid, callback) { + deleteSortedSetElements('uid:' + uid + ':posts', deletePost, callback); + } + + function deletePost(pid, callback) { + async.parallel([ + function(next) { + deletePostFromTopic(pid, next); + }, + function(next) { + deletePostFromCategoryRecentPosts(pid, next); + }, + function(next) { + deletePostFromUsersFavourites(pid, next); + }, + function(next) { + deletePostFromUsersVotes(pid, next); + }, + function(next) { + db.sortedSetRemove('posts:pid', pid, next); + } + ], function(err) { + if (err) { + return callback(err); + } + + plugins.fireHook('action:post.delete', pid); + db.delete('post:' + pid, callback); + }); + } + + function deletePostFromTopic(pid, callback) { + posts.getPostFields(pid, ['tid', 'deleted'], function(err, postData) { + if (err) { + return callback(err); + } + + db.sortedSetRemove('tid:' + postData.tid + ':posts', pid, function(err) { + if (err) { + return callback(err); + } + + if (parseInt(postData.deleted, 10) === 0) { + db.decrObjectField('global', 'postCount', callback); + } else { + callback(); + } + }); + }); + } + + function deletePostFromCategoryRecentPosts(pid, callback) { + db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { + if (err) { + return callback(err); + } + + async.each(cids, function(cid, next) { + db.sortedSetRemove('categories:recent_posts:cid:' + cid, pid, next); + }, callback); + }); + } + + function deletePostFromUsersFavourites(pid, callback) { + db.getSetMembers('pid:' + pid + ':users_favourited', function(err, uids) { + if (err) { + return callback(err); + } + + async.each(uids, function(uid, next) { + db.sortedSetRemove('uid:' + uid + ':favourites', pid, next); + }, function(err) { + if (err) { + return callback(err); + } + + db.delete('pid:' + pid + ':users_favourited', callback); + }); + }); + } + + function deletePostFromUsersVotes(pid, callback) { + async.parallel({ + upvoters: function(next) { + db.getSetMembers('pid:' + pid + ':upvote', next); + }, + downvoters: function(next) { + db.getSetMembers('pid:' + pid + ':downvote', next); + } + }, function(err, results) { + if (err) { + return callback(err); + } + + async.parallel([ + function(next) { + async.each(results.upvoters, function(uid, next) { + db.sortedSetRemove('uid:' + uid + ':upvote', pid, next); + }, next); + }, + function(next) { + async.each(results.downvoters, function(uid, next) { + db.sortedSetRemove('uid:' + uid + ':downvote', pid, next); + }, next); + } + ], callback); + }); + } + + function deleteTopics(uid, callback) { + deleteSortedSetElements('uid:' + uid + ':topics', deleteTopic, callback); + } + + function deleteSortedSetElements(set, deleteMethod, callback) { + db.getSortedSetRange(set, 0, -1, function(err, ids) { + if (err) { + return callback(err); + } + + async.each(ids, deleteMethod, callback); + }); + } + + function deleteTopic(tid, callback) { + + async.parallel([ + function(next) { + db.delete('tid:' + tid + ':followers', next); + }, + function(next) { + db.delete('tid:' + tid + ':read_by_uid', next); + }, + function(next) { + db.sortedSetRemove('topics:tid', tid, next); + }, + function(next) { + db.sortedSetRemove('topics:recent', tid, next); + }, + function(next) { + db.sortedSetRemove('topics:posts', tid, next); + }, + function(next) { + db.sortedSetRemove('topics:views', tid, next); + }, + function(next) { + deleteTopicFromCategory(tid, next); + } + ], function(err) { + if (err) { + return callback(err); + } + plugins.fireHook('action:topic.delete', tid); + db.delete('topic:' + tid, callback); + }); + } + + function deleteTopicFromCategory(tid, callback) { + topics.getTopicFields(tid, ['cid', 'deleted'], function(err, topicData) { + if (err) { + return callback(err); + } + + db.sortedSetRemove('categories:' + topicData.cid + ':tid', tid, function(err) { + if (err) { + return callback(err); + } + + db.decrObjectField('category:' + topicData.cid, 'topic_count', function(err) { + if (err) { + return callback(err); + } + + if (parseInt(topicData.deleted, 10) === 0) { + db.decrObjectField('global', 'topicCount', callback); + } else { + callback(); + } + }); + }); + }); + } + + function deleteAccount(uid, callback) { + user.getUserFields(uid, ['username', 'userslug', 'email'], function(err, userData) { + if (err) { + return callback(err); + } + + async.parallel([ + function(next) { + db.deleteObjectField('username:uid', userData.username, next); + }, + function(next) { + db.deleteObjectField('userslug:uid', userData.userslug, next); + }, + function(next) { + db.deleteObjectField('email:uid', userData.email, next); + }, + function(next) { + db.delete('uid:' + uid + ':notifications:read', next); + }, + function(next) { + db.delete('uid:' + uid + ':notifications:unread', next); + }, + function(next) { + db.sortedSetRemove('users:joindate', uid, next); + }, + function(next) { + db.sortedSetRemove('users:postcount', uid, next); + }, + function(next) { + db.sortedSetRemove('users:reputation', uid, next); + }, + function(next) { + db.delete('uid:' + uid + ':favourites', next); + }, + function(next) { + db.delete('uid:' + uid + ':topics', next); + }, + function(next) { + db.delete('uid:' + uid + ':posts', next); + }, + function(next) { + db.delete('uid:' + uid + ':chats', next); + }, + function(next) { + db.delete('uid:' + uid + ':ip', next); + }, + function(next) { + db.delete('uid:' + uid + ':upvote', next); + }, + function(next) { + db.delete('uid:' + uid + ':downvote', next); + }, + function(next) { + deleteUserFromCategoryActiveUsers(uid, next); + }, + function(next) { + deleteUserFromFollowers(uid, next); + }, + function(next) { + deleteUserFromGroups(uid, next); + } + ], function(err) { + if (err) { + return callback(err); + } + + async.parallel([ + function(next) { + db.delete('followers:' + uid, next); + }, + function(next) { + db.delete('following:' + uid, next); + }, + function(next) { + db.delete('user:' + uid, next); + } + ], callback); + }); + }); + } + + function deleteUserFromCategoryActiveUsers(uid, callback) { + db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { + if (err) { + return callback(err); + } + + async.each(cids, function(cid, next) { + categories.removeActiveUser(cid, uid, next); + }, callback); + }); + } + + function deleteUserFromFollowers(uid, callback) { + db.getSetMembers('followers:' + uid, function(err, uids) { + if (err) { + return callback(err); + } + + async.each(uids, function(theiruid, next) { + db.setRemove('following:' + theiruid, uid, next); + }, callback); + }); + } + + function deleteUserFromGroups(uid, callback) { + groups.getGroupIds(function(err, gids) { + async.each(gids, function(gid, next) { + groups.leave(gid, uid, next); + }, callback); + }); + } +}; \ No newline at end of file From 37e8856861cd1618e57a008eab06d5283eb0276d Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 15 Mar 2014 15:29:56 -0400 Subject: [PATCH 2/8] new middleware to add slug to topic and category --- src/controllers/categories.js | 10 ---------- src/controllers/topics.js | 10 ---------- src/middleware/middleware.js | 26 +++++++++++++++++++++++++- src/routes/index.js | 4 ++-- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 4dd9d0e8a5..9d0a1aae49 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -65,16 +65,6 @@ categoriesController.get = function(req, res, next) { page = req.query.page || 1, uid = req.user ? req.user.uid : 0; - if (!req.params.slug && !res.locals.isAPI) { - categories.getCategoryField(cid, 'slug', function(err, slug) { - if (err) { - return next(err); - } - res.redirect('/category/' + slug); - }); - return; - } - async.waterfall([ function(next) { categoryTools.privileges(cid, uid, function(err, categoryPrivileges) { diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 50d3fefa37..15452aaf80 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -18,16 +18,6 @@ topicsController.get = function(req, res, next) { uid = req.user ? req.user.uid : 0, privileges; - if (!req.params.slug && !res.locals.isAPI) { - topics.getTopicField(tid, 'slug', function(err, slug) { - if (err) { - return next(err); - } - res.redirect('/topic/' + slug); - }); - return; - } - async.waterfall([ function(next) { threadTools.privileges(tid, ((req.user) ? req.user.uid || 0 : 0), function(err, userPrivileges) { diff --git a/src/middleware/middleware.js b/src/middleware/middleware.js index c33e4def7d..5807c8361c 100644 --- a/src/middleware/middleware.js +++ b/src/middleware/middleware.js @@ -14,6 +14,8 @@ var app, translator = require('./../../public/src/translator'), user = require('./../user'), db = require('./../database'), + categories = require('./../categories'), + topics = require('./../topics'), controllers = { api: require('./../controllers/api') @@ -49,9 +51,31 @@ middleware.redirectToAccountIfLoggedIn = function(req, res, next) { } else { next(); } - } +middleware.addSlug = function(req, res, next) { + function redirect(method, id, name) { + method(id, 'slug', function(err, slug) { + if (err || !slug) { + return next(err); + } + res.redirect(name + slug); + }); + } + + if (!req.params.slug) { + if (req.params.category_id) { + redirect(categories.getCategoryField, req.params.category_id, '/category/'); + } else if (req.params.topic_id) { + redirect(topics.getTopicField, req.params.topic_id, '/topic/'); + } else { + return next(); + } + return; + } + next(); +}; + middleware.prepareAPI = function(req, res, next) { res.locals.isAPI = true; next(); diff --git a/src/routes/index.js b/src/routes/index.js index 8dc5be4200..377a6d343a 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -48,7 +48,7 @@ function staticRoutes(app, middleware, controllers) { } function topicRoutes(app, middleware, controllers) { - app.get('/topic/:topic_id/:slug?', middleware.buildHeader, controllers.topics.get); + app.get('/topic/:topic_id/:slug?', middleware.buildHeader, middleware.addSlug, controllers.topics.get); app.get('/api/topic/:topic_id/:slug?', controllers.topics.get); } @@ -65,7 +65,7 @@ function categoryRoutes(app, middleware, controllers) { app.get('/unread/total', middleware.buildHeader, middleware.authenticate, controllers.categories.unreadTotal); app.get('/api/unread/total', middleware.authenticate, controllers.categories.unreadTotal); - app.get('/category/:category_id/:slug?', middleware.buildHeader, controllers.categories.get); + app.get('/category/:category_id/:slug?', middleware.buildHeader, middleware.addSlug, controllers.categories.get); app.get('/api/category/:category_id/:slug?', controllers.categories.get); } From 19c2a85bf13cebf02a006d7e6040ba67899b8dfa Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 15 Mar 2014 16:08:31 -0400 Subject: [PATCH 3/8] logger jshint --- src/logger.js | 118 ++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/src/logger.js b/src/logger.js index 1a106e1efc..90926dd5fd 100644 --- a/src/logger.js +++ b/src/logger.js @@ -1,3 +1,5 @@ +'use strict'; + /* * Logger module: ability to dynamically turn on/off logging for http requests & socket.io events */ @@ -34,25 +36,22 @@ var opts = { opts.express.app = app; /* Open log file stream & initialize express logging if meta.config.logger* variables are set */ Logger.setup(); - } + }; Logger.setup = function() { Logger.setup_one('loggerPath', meta.config.loggerPath); - } + }; - Logger.setup_one = function(key,value) { + Logger.setup_one = function(key, value) { /* * 1. Open the logger stream: stdout or file * 2. Re-initialize the express logger hijack */ - switch(key) { - case 'loggerPath': { - Logger.setup_one_log(value); - Logger.express_open(); - } - default: return; + if (key === 'loggerPath') { + Logger.setup_one_log(value); + Logger.express_open(); } - } + }; Logger.setup_one_log = function(value) { /* @@ -61,20 +60,23 @@ var opts = { */ if(meta.config.loggerStatus > 0 || meta.config.loggerIOStatus) { var stream = Logger.open(value); - if(stream) opts.streams.log.f = stream; - else opts.streams.log.f = process.stdout; + if(stream) { + opts.streams.log.f = stream; + } else { + opts.streams.log.f = process.stdout; + } } else { Logger.close(opts.streams.log); } - } + }; Logger.open = function(value) { /* Open the streams to log to: either a path or stdout */ var stream; if(value) { if(fs.existsSync(value)) { - stats = fs.statSync(value); + var stats = fs.statSync(value); if(stats) { if(stats.isDirectory()) { stream = fs.createWriteStream(path.join(value, 'nodebb.log'), {flags: 'a'}); @@ -96,12 +98,14 @@ var opts = { stream = process.stdout; } return stream; - } + }; Logger.close = function(stream) { - if(stream.f != process.stdout && stream.f != null) stream.end(); + if(stream.f !== process.stdout && stream.f) { + stream.end(); + } stream.f = null; - } + }; Logger.monitorConfig = function(socket, data) { /* @@ -110,10 +114,10 @@ var opts = { Logger.setup_one(data.key,data.value); Logger.io_close(socket); Logger.io(socket); - } + }; Logger.express_open = function() { - if(opts.express.set != 1) { + if(opts.express.set !== 1) { opts.express.set = 1; opts.express.app.use(Logger.expressLogger); } @@ -121,7 +125,7 @@ var opts = { * Always initialize "ofn" (original function) with the original logger function */ opts.express.ofn = express.logger({stream : opts.streams.log.f}); - } + }; Logger.expressLogger = function(req,res,next) { /* @@ -134,7 +138,7 @@ var opts = { } else { return next(); } - } + }; Logger.prepare_io_string = function(_type, _uid, _args) { /* @@ -145,82 +149,74 @@ var opts = { try { return 'io: '+_uid+' '+_type+' '+util.inspect(Array.prototype.slice.call(_args))+'\n'; } catch(err) { - winston.info("Logger.prepare_io_string: Failed",err) + winston.info("Logger.prepare_io_string: Failed", err); return "error"; } - } + }; Logger.io_close = function(socket) { /* * Restore all hijacked sockets to their original emit/on functions */ var clients = socket.io.sockets.clients(); - for(var v in clients) { - var client = clients[v]; - - if(client.oEmit != undefined && client.oEmit != client.emit) { + clients.forEach(function(client) { + if(client.oEmit && client.oEmit !== client.emit) { client.emit = client.oEmit; } - if(client.$oEmit != undefined && client.$oEmit != client.$emit) { + if(client.$oEmit && client.$oEmit !== client.$emit) { client.$emit = client.$oEmit; } - } - } + }); + }; Logger.io = function(socket) { /* * Go through all of the currently established sockets & hook their .emit/.on */ - if(socket == undefined && socket.io.sockets == undefined) { + if(!socket && !socket.io.sockets) { return; } var clients = socket.io.sockets.clients(); - for(var v in clients) { - var client = clients[v]; - Logger.io_one(client,client.state.user.uid); - } - } - Logger.io_one = function(socket,uid) { + clients.forEach(function(client) { + Logger.io_one(client, client.uid); + }); + }; + + Logger.io_one = function(socket, uid) { /* * This function replaces a socket's .emit/.on functions in order to intercept events */ - if(socket != undefined && meta.config.loggerIOStatus > 0) { + if(socket && meta.config.loggerIOStatus > 0) { (function() { + function override(method, name, errorMsg) { + return function() { + if(opts.streams.log.f) { + opts.streams.log.f.write(Logger.prepare_io_string(name, uid, arguments)); + } + + try { + method.apply(socket, arguments); + } catch(err) { + winston.info(errorMsg, err); + } + }; + } + // courtesy of: http://stackoverflow.com/a/9674248 - var user = uid - if(!user) user = "?" socket.oEmit = socket.emit; var emit = socket.emit; - socket.emit = function() { - if(opts.streams.log.f != null) { - opts.streams.log.f.write(Logger.prepare_io_string("emit", uid, arguments)); - } + socket.emit = override(emit, 'emit', 'Logger.io_one: emit.apply: Failed'); - try { - emit.apply(socket, arguments); - } catch(err) { - winston.info("Logger.io_one: emit.apply: Failed", err); - } - }; socket.$oEmit = socket.$emit; var $emit = socket.$emit; - socket.$emit = function() { + socket.$emit = override($emit, 'on', 'Logger.io_one: $emit.apply: Failed'); - if(opts.streams.log.f != null) { - opts.streams.log.f.write(Logger.prepare_io_string("on",uid,arguments)); - } - try { - $emit.apply(socket, arguments); - } catch(err) { - winston.info("Logger.io_one: $emit.apply: Failed", err); - } - }; })(); } - } + }; }(exports)); From ea4931fa1d4fc82477fbaa9033c86916f03adc75 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 15 Mar 2014 16:18:03 -0400 Subject: [PATCH 4/8] removed dupe from controllers/user.js --- src/controllers/users.js | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/controllers/users.js b/src/controllers/users.js index 49a61b81cb..ed6e10dbb5 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -60,33 +60,22 @@ usersController.getOnlineUsers = function(req, res, next) { }; usersController.getUsersSortedByPosts = function(req, res, next) { - user.getUsers('users:postcount', 0, 49, function (err, data) { - var userData = { - search_display: 'none', - loadmore_display: 'block', - users: data, - show_anon: 'hide' - }; - - res.render('users', userData); - }); + getUsers('users:postcount', res, next); }; usersController.getUsersSortedByReputation = function(req, res, next) { - user.getUsers('users:reputation', 0, 49, function (err, data) { - var userData = { - search_display: 'none', - loadmore_display: 'block', - users: data, - show_anon: 'hide' - }; - - res.render('users', userData); - }); + getUsers('users:reputation', res, next); }; usersController.getUsersSortedByJoinDate = function(req, res, next) { - user.getUsers('users:joindate', 0, 49, function (err, data) { + getUsers('users:joindate', res, next); +}; + +function getUsers(set, res, next) { + user.getUsers(set, 0, 49, function (err, data) { + if (err) { + return next(err); + } var userData = { search_display: 'none', loadmore_display: 'block', @@ -96,7 +85,7 @@ usersController.getUsersSortedByJoinDate = function(req, res, next) { res.render('users', userData); }); -}; +} usersController.getUsersForSearch = function(req, res, next) { var data = { From 46a475fdde889db9439e803cddadc808ae86a7b2 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 15 Mar 2014 16:28:57 -0400 Subject: [PATCH 5/8] controllers/admin/users cleanup --- src/controllers/admin/users.js | 41 ++++++++++------------------------ src/routes/admin.js | 6 ++--- src/socket.io/index.js | 9 +------- 3 files changed, 16 insertions(+), 40 deletions(-) diff --git a/src/controllers/admin/users.js b/src/controllers/admin/users.js index 6bd64ef23b..4cf53b79bd 100644 --- a/src/controllers/admin/users.js +++ b/src/controllers/admin/users.js @@ -13,48 +13,31 @@ usersController.search = function(req, res, next) { }); }; -usersController.latest = function(req, res, next) { - user.getUsers('users:joindate', 0, 49, function(err, users) { - res.render('admin/users', { - search_display: 'none', - loadmore_display: 'block', - users: users, - yourid: req.user.uid - }); - }); -}; - usersController.sortByPosts = function(req, res, next) { - user.getUsers('users:postcount', 0, 49, function(err, users) { - res.render('admin/users', { - search_display: 'none', - loadmore_display: 'block', - users: users, - yourid: req.user.uid - }); - }); + getUsers('users:postcount', req, res, next); }; usersController.sortByReputation = function(req, res, next) { - user.getUsers('users:reputation', 0, 49, function(err, users) { - res.render('admin/users', { - search_display: 'none', - loadmore_display: 'block', - users: users, - yourid: req.user.uid - }); - }); + getUsers('users:reputation', req, res, next); }; usersController.sortByJoinDate = function(req, res, next) { - user.getUsers('users:joindate', 0, 49, function(err, users) { + getUsers('users:joindate', req, res, next); +}; + +function getUsers(set, req, res, next) { + user.getUsers(set, 0, 49, function(err, users) { + if (err) { + return next(err); + } res.render('admin/users', { search_display: 'none', + loadmore_display: 'block', users: users, yourid: req.user.uid }); }); -}; +} usersController.getCSV = function(req, res, next) { user.getUsersCSV(function(err, data) { diff --git a/src/routes/admin.js b/src/routes/admin.js index a75e7d1d16..647dd5f54e 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -26,8 +26,8 @@ function userRoutes(app, middleware, controllers) { app.get('/admin/users/search', middleware.admin.buildHeader, controllers.admin.users.search); app.get('/api/admin/users/search', controllers.admin.users.search); - app.get('/admin/users/latest', middleware.admin.buildHeader, controllers.admin.users.latest); - app.get('/api/admin/users/latest', controllers.admin.users.latest); + app.get('/admin/users/latest', middleware.admin.buildHeader, controllers.admin.users.sortByJoinDate); + app.get('/api/admin/users/latest', controllers.admin.users.sortByJoinDate); app.get('/admin/users/sort-posts', middleware.admin.buildHeader, controllers.admin.users.sortByPosts); app.get('/api/admin/users/sort-posts', controllers.admin.users.sortByPosts); @@ -76,7 +76,7 @@ module.exports = function(app, middleware, controllers) { app.all('/api/admin/*', middleware.admin.isAdmin, middleware.prepareAPI); app.all('/admin/*', middleware.admin.isAdmin); app.get('/admin', middleware.admin.isAdmin); - + mainRoutes(app, middleware, controllers); userRoutes(app, middleware, controllers); forumRoutes(app, middleware, controllers); diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 9d55c874aa..bdd017a4c3 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -67,15 +67,8 @@ Sockets.init = function(server) { socket.uid = parseInt(uid, 10); - /* Need to save some state for the logger & maybe some other modules later on */ - socket.state = { - user : { - uid : uid - } - }; - /* If meta.config.loggerIOStatus > 0, logger.io_one will hook into this socket */ - logger.io_one(socket,uid); + logger.io_one(socket, uid); if (uid) { From 38d4fd1a59108ff664bb3c9fb30a88a03b85db19 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 15 Mar 2014 17:50:19 -0400 Subject: [PATCH 6/8] took out forking to its own file --- public/src/forum/topic.js | 152 ++++++++------------------------- public/src/forum/topic/fork.js | 115 +++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 116 deletions(-) create mode 100644 public/src/forum/topic/fork.js diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index a86c6d9b71..6084daffaf 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -1,4 +1,9 @@ -define(['composer', 'forum/pagination'], function(composer, pagination) { +'use strict'; + + +/* globals define, app, templates, translator, socket, bootbox, config, ajaxify, RELATIVE_PATH */ + +define(['composer', 'forum/pagination', 'forum/topic/fork'], function(composer, pagination, fork) { var Topic = {}, infiniteLoaderActive = false, scrollingToPost = false, @@ -196,97 +201,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { } }); - $('.fork_thread').on('click', function() { - var pids = []; - var forkModal = $('#fork-thread-modal'), - forkCommit = forkModal.find('#fork_thread_commit'); - forkModal.removeClass('hide'); - forkModal.css('position', 'fixed') - .css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px') - .css('top', '0px') - .css('z-index', '2000'); - - showNoPostsSelected(); - - forkModal.find('.close,#fork_thread_cancel').on('click', closeForkModal); - forkModal.find('#fork-title').on('change', checkForkButtonEnable); - $('#post-container').on('click', 'li', togglePostSelection); - forkCommit.on('click', createTopicFromPosts); - - function createTopicFromPosts() { - socket.emit('topics.createTopicFromPosts', { - title: forkModal.find('#fork-title').val(), - pids: pids - }, function(err) { - if(err) { - return app.alertError(err.message); - } - - translator.get('topic:fork_success', function(translated) { - app.alertSuccess(translated); - }); - - function removePost() { - $(this).remove(); - } - - for(var i=0; i 8) { break; @@ -688,12 +603,13 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { activeEl.append(anonLink); var title = ''; - if(remainingUsers && anonymousCount) + if(remainingUsers && anonymousCount) { title = remainingUsers + ' more user(s) and ' + anonymousCount + ' guest(s)'; - else if(remainingUsers) + } else if(remainingUsers) { title = remainingUsers + ' more user(s)'; - else + } else { title = anonymousCount + ' guest(s)'; + } anonLink.tooltip({ placement: 'top', @@ -884,7 +800,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { socket.on('event:post_deleted', function(data) { if (data.pid) { - toggle_post_delete_state(data.pid); + toggle_post_delete_state(data.pid); } }); @@ -913,7 +829,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { votes.html(currentVotes).attr('data-votes', currentVotes); reputationElements.html(reputation).attr('data-reputation', reputation); - }; + } function adjust_favourites(value, pid, uid) { var favourites = $('li[data-pid="' + pid + '"] .favouriteCount'), @@ -922,7 +838,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { currentFavourites += value; favourites.html(currentFavourites).attr('data-favourites', currentFavourites); - }; + } function set_follow_state(state, alert) { @@ -937,7 +853,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { type: 'success' }); } - }; + } function set_locked_state(locked, alert) { translator.translate(' [[topic:thread_tools.' + (locked ? 'un': '') + 'lock]]', function(translated) { @@ -960,7 +876,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { } thread_state.locked = locked ? '1' : '0'; - }; + } function set_delete_state(deleted) { var threadEl = $('#post-container'); @@ -977,7 +893,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { } else { $('#thread-deleted').remove(); } - }; + } function set_pinned_state(pinned, alert) { translator.translate(' [[topic:thread_tools.' + (pinned ? 'unpin' : 'pin') + ']]', function(translated) { @@ -994,7 +910,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { } thread_state.pinned = pinned ? '1' : '0'; }); - }; + } function toggle_post_delete_state(pid) { var postEl = $('#post-container li[data-pid="' + pid + '"]'); @@ -1006,7 +922,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { updatePostCount(); } - }; + } function toggle_post_tools(pid, isDeleted) { var postEl = $('#post-container li[data-pid="' + pid + '"]'); @@ -1016,7 +932,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { translator.translate(isDeleted ? ' [[topic:restore]]' : ' [[topic:delete]]', function(translated) { postEl.find('.delete').find('span').html(translated); }); - }; + } $(window).on('scroll', updateHeader); $(window).trigger('action:topic.loaded'); @@ -1231,7 +1147,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { } if(after) { - translated.insertAfter(after) + translated.insertAfter(after); } else if(before) { translated.insertBefore(before); } else { @@ -1250,16 +1166,16 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { function parseAndTranslatePosts(data, callback) { templates.preload_template('topic', function() { - templates['topic'].parse({posts: []}); - var html = templates.prepare(templates['topic'].blocks['posts']).parse(data); + templates.topic.parse({posts: []}); + var html = templates.prepare(templates.topic.blocks.posts).parse(data); translator.translate(html, callback); }); } function onNewPostsLoaded(html, posts) { - for (var x = 0, numPosts = posts.length; x < numPosts; x++) { - socket.emit('posts.getPrivileges', posts[x].pid, function(err, privileges) { + function getPostPrivileges(pid) { + socket.emit('posts.getPrivileges', pid, function(err, privileges) { if(err) { return app.alertError(err.message); } @@ -1267,6 +1183,10 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { }); } + for (var x = 0, numPosts = posts.length; x < numPosts; x++) { + getPostPrivileges(posts[x].pid); + } + infiniteLoaderActive = false; app.populateOnlineUsers(); diff --git a/public/src/forum/topic/fork.js b/public/src/forum/topic/fork.js new file mode 100644 index 0000000000..468b708a5a --- /dev/null +++ b/public/src/forum/topic/fork.js @@ -0,0 +1,115 @@ +'use strict'; + +/* globals define, app, translator, socket */ + +define(function() { + + var Fork = {}, + forkModal, + forkCommit, + pids = []; + + Fork.init = function() { + $('.fork_thread').on('click', onForkThreadClicked); + }; + + function onForkThreadClicked() { + forkModal = $('#fork-thread-modal'); + forkModal.removeClass('hide') + .css('position', 'fixed') + .css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px') + .css('top', '0px') + .css('z-index', '2000'); + + forkCommit = forkModal.find('#fork_thread_commit'); + + pids.length = 0; + + showNoPostsSelected(); + + forkModal.find('.close,#fork_thread_cancel').on('click', closeForkModal); + forkModal.find('#fork-title').on('change', checkForkButtonEnable); + $('#post-container').on('click', 'li[data-pid]', function() { + togglePostSelection($(this)); + }); + + forkCommit.on('click', createTopicFromPosts); + } + + function createTopicFromPosts() { + socket.emit('topics.createTopicFromPosts', { + title: forkModal.find('#fork-title').val(), + pids: pids + }, function(err) { + function fadeOutAndRemove(pid) { + $('#post-container li[data-pid="' + pid + '"]').fadeOut(500, function() { + $(this).remove(); + }); + } + + if(err) { + return app.alertError(err.message); + } + + translator.get('topic:fork_success', function(translated) { + app.alertSuccess(translated); + }); + + for(var i=0; i Date: Sat, 15 Mar 2014 17:56:21 -0400 Subject: [PATCH 7/8] moved to showForkModal --- public/src/forum/topic/fork.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/public/src/forum/topic/fork.js b/public/src/forum/topic/fork.js index 468b708a5a..5952e86920 100644 --- a/public/src/forum/topic/fork.js +++ b/public/src/forum/topic/fork.js @@ -15,16 +15,10 @@ define(function() { function onForkThreadClicked() { forkModal = $('#fork-thread-modal'); - forkModal.removeClass('hide') - .css('position', 'fixed') - .css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px') - .css('top', '0px') - .css('z-index', '2000'); - forkCommit = forkModal.find('#fork_thread_commit'); - pids.length = 0; + showForkModal(); showNoPostsSelected(); forkModal.find('.close,#fork_thread_cancel').on('click', closeForkModal); @@ -36,6 +30,14 @@ define(function() { forkCommit.on('click', createTopicFromPosts); } + function showForkModal() { + forkModal.removeClass('hide') + .css('position', 'fixed') + .css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px') + .css('top', '0px') + .css('z-index', '2000'); + } + function createTopicFromPosts() { socket.emit('topics.createTopicFromPosts', { title: forkModal.find('#fork-title').val(), From b4af4c72cc723f6d128b9124eaee1153e36ee893 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 15 Mar 2014 18:05:59 -0400 Subject: [PATCH 8/8] alertSuccess can take language strings --- public/src/forum/topic/fork.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/public/src/forum/topic/fork.js b/public/src/forum/topic/fork.js index 5952e86920..7bced35639 100644 --- a/public/src/forum/topic/fork.js +++ b/public/src/forum/topic/fork.js @@ -53,9 +53,7 @@ define(function() { return app.alertError(err.message); } - translator.get('topic:fork_success', function(translated) { - app.alertSuccess(translated); - }); + app.alertSuccess('[[topic:fork_success]]'); for(var i=0; i