From dfa4cd4ae3b910a9200c1f722bcff701a80660bf Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Wed, 11 Dec 2013 21:40:55 -0500 Subject: [PATCH 01/21] closes #653 --- src/websockets.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/websockets.js b/src/websockets.js index b7ccb81ee2..4547f1d3b1 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -714,10 +714,10 @@ websockets.init = function(io) { return; } - var finalMessage = username + ' : ' + msg, - notifText = 'New message from ' + username + '', - username = usersData[0].username, - toUsername = usersData[1].username; + var username = usersData[0].username, + toUsername = usersData[1].username, + finalMessage = username + ' : ' + msg, + notifText = 'New message from ' + username + ''; if (!isUserOnline(touid)) { notifications.create(notifText, 'javascript:app.openChat('' + username + '', ' + uid + ');', 'notification_' + uid + '_' + touid, function(nid) { From 1abfe5de634ba52ac8fbd1aed64af595c124cb0f Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Thu, 12 Dec 2013 12:17:58 -0500 Subject: [PATCH 02/21] added err to addUserInfoToPost --- src/posts.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/posts.js b/src/posts.js index fd250d5b38..dcb53d6379 100644 --- a/src/posts.js +++ b/src/posts.js @@ -14,7 +14,8 @@ var db = require('./database'), async = require('async'), nconf = require('nconf'), validator = require('validator'), - winston = require('winston'); + winston = require('winston'), + gravatar = require('gravatar'); (function(Posts) { var customUserInfo = {}; @@ -202,12 +203,16 @@ var db = require('./database'), } postTools.parseSignature(userData.signature, function(err, signature) { + if(err) { + return callback(err); + } + post.username = userData.username || 'anonymous'; post.userslug = userData.userslug || ''; post.user_rep = userData.reputation || 0; post.user_postcount = userData.postcount || 0; post.user_banned = parseInt(userData.banned, 10) === 1; - post.picture = userData.picture || require('gravatar').url('', {}, https = nconf.get('https')); + post.picture = userData.picture || gravatar.url('', {}, https = nconf.get('https')); post.signature = signature; for (var info in customUserInfo) { @@ -217,11 +222,16 @@ var db = require('./database'), } plugins.fireHook('filter:posts.custom_profile_info', {profile: "", uid: post.uid, pid: post.pid}, function(err, profile_info) { + if(err) { + return callback(err); + } post.additional_profile_info = profile_info.profile; if (post.editor !== '') { user.getUserFields(post.editor, ['username', 'userslug'], function(err, editorData) { - if (err) return callback(); + if (err) { + return callback(); + } post.editorname = editorData.username; post.editorslug = editorData.userslug; From 885242018f8ddb66c0a9a73b70437aeb7171cef6 Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Thu, 12 Dec 2013 12:19:03 -0500 Subject: [PATCH 03/21] one more --- src/posts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/posts.js b/src/posts.js index dcb53d6379..6beabd964f 100644 --- a/src/posts.js +++ b/src/posts.js @@ -230,7 +230,7 @@ var db = require('./database'), if (post.editor !== '') { user.getUserFields(post.editor, ['username', 'userslug'], function(err, editorData) { if (err) { - return callback(); + return callback(err); } post.editorname = editorData.username; From cf8f0ca2252bf4d3ddc9441355debf766989a1aa Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 12 Dec 2013 16:02:12 -0500 Subject: [PATCH 04/21] cleanup --- src/routes/api.js | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/routes/api.js b/src/routes/api.js index ca0955ccbe..68ee19967f 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -39,29 +39,22 @@ var path = require('path'), res.json(200, config); }); - app.get('/home', function (req, res, next) { + app.get('/home', function (req, res) { var uid = (req.user) ? req.user.uid : 0; categories.getAllCategories(uid, function (err, data) { data.categories = data.categories.filter(function (category) { return (!category.disabled || parseInt(category.disabled, 10) === 0); }); - function getRecentReplies(category, callback) { - categories.getRecentReplies(category.cid, 2, function (err, posts) { - if(err) { - return callback(err); - } + function iterator(category, callback) { + categories.getRecentReplies(category.cid, 2, function (posts) { category.posts = posts; category.post_count = posts.length > 2 ? 2 : posts.length; callback(null); }); } - async.each(data.categories, getRecentReplies, function (err) { - if(err) { - return next(err); - } - + async.each(data.categories, iterator, function (err) { data.motd_class = (parseInt(meta.config.show_motd, 10) === 1 || meta.config.show_motd === undefined) ? '' : ' none'; data.motd_class += (meta.config.motd && meta.config.motd.length > 0 ? '' : ' default'); @@ -244,10 +237,6 @@ var path = require('path'), return callback(err, null); } - if(pids.length > 50) { - pids = pids.splice(0, 50); - } - posts.getPostSummaryByPids(pids, false, function (err, posts) { if (err){ return callback(err, null); @@ -263,10 +252,6 @@ var path = require('path'), return callback(err, null); } - if(tids.length > 50) { - tids = tids.splice(0, 50); - } - topics.getTopicsByTids(tids, 0, function (topics) { callback(null, topics); }, 0); @@ -313,7 +298,7 @@ var path = require('path'), app.get('/500', function(req, res) { res.json({errorMessage: 'testing'}); - }) + }); }); } }(exports)); \ No newline at end of file From 4397da144ff8a8463e6ee66c9b2006bc4036049d Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 12 Dec 2013 16:07:15 -0500 Subject: [PATCH 05/21] fixes crash introduced @1021615848e49da3434f00cfdb6fb79ab5990b47 --- src/routes/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/api.js b/src/routes/api.js index 68ee19967f..0635188db3 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -47,7 +47,7 @@ var path = require('path'), }); function iterator(category, callback) { - categories.getRecentReplies(category.cid, 2, function (posts) { + categories.getRecentReplies(category.cid, 2, function (err, posts) { category.posts = posts; category.post_count = posts.length > 2 ? 2 : posts.length; callback(null); From 9d88b9eed3ddec07b3b61a8a0737ac64d39fb215 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 13 Dec 2013 15:55:24 -0500 Subject: [PATCH 06/21] default motd now shows @NodeBB, and not @dcplabs --- src/routes/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/api.js b/src/routes/api.js index 0635188db3..d1e7da2fb9 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -58,7 +58,7 @@ var path = require('path'), data.motd_class = (parseInt(meta.config.show_motd, 10) === 1 || meta.config.show_motd === undefined) ? '' : ' none'; data.motd_class += (meta.config.motd && meta.config.motd.length > 0 ? '' : ' default'); - data.motd = require('marked')(meta.config.motd || "\n\n# NodeBB v" + pkg.version + "\nWelcome to NodeBB, the discussion platform of the future."); + data.motd = require('marked')(meta.config.motd || "\n\n# NodeBB v" + pkg.version + "\nWelcome to NodeBB, the discussion platform of the future."); res.json(data); }); }); From bf27ade251249617f59e9f43942f201a415e57e4 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 13 Dec 2013 16:26:32 -0500 Subject: [PATCH 07/21] admin - added ability to remove icon from categories --- public/templates/admin/categories.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/templates/admin/categories.tpl b/public/templates/admin/categories.tpl index a8da120e82..25b85daf68 100644 --- a/public/templates/admin/categories.tpl +++ b/public/templates/admin/categories.tpl @@ -160,6 +160,6 @@ \ No newline at end of file From 27a01f6c6162d6aee16d6bd2f61acd21a3e88d5f Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Fri, 13 Dec 2013 16:36:29 -0500 Subject: [PATCH 08/21] closes #657 --- public/templates/search.tpl | 63 ++++++++++++++++++++++--------------- src/routes/api.js | 4 ++- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/public/templates/search.tpl b/public/templates/search.tpl index 9bea91611c..0f2ad27a30 100644 --- a/public/templates/search.tpl +++ b/public/templates/search.tpl @@ -15,41 +15,54 @@ diff --git a/src/routes/api.js b/src/routes/api.js index d1e7da2fb9..45e9514ce8 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -270,7 +270,9 @@ var path = require('path'), show_results: '', search_query: req.params.term, posts: results[0], - topics: results[1] + topics: results[1], + post_matches : results[0].length, + topic_matches : results[1].length }); }); } else { From 770cea93290eaaf9a6994d0e93b2dd66e426baf8 Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Sat, 14 Dec 2013 16:29:33 -0500 Subject: [PATCH 09/21] added more error first to some functions --- src/posts.js | 22 +++++++++++++++------- src/routes/user.js | 16 +++++++++++----- src/user.js | 17 +++++++---------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/posts.js b/src/posts.js index 6beabd964f..74c9e2fb0f 100644 --- a/src/posts.js +++ b/src/posts.js @@ -449,8 +449,9 @@ var db = require('./database'), Posts.uploadPostImage = function(image, callback) { - if(!image) + if(!image) { return callback('invalid image', null); + } require('./imgur').upload(meta.config.imgurClientID, image.data, 'base64', function(err, data) { if(err) { @@ -465,22 +466,29 @@ var db = require('./database'), } Posts.getPostsByUid = function(uid, start, end, callback) { - user.getPostIds(uid, start, end, function(pids) { + user.getPostIds(uid, start, end, function(err, pids) { + if(err) { + return callback(err); + } if (pids && pids.length) { plugins.fireHook('filter:post.getTopic', pids, function(err, posts) { + if(err) { + return callback(err); + } - if (!err & 0 < posts.length) { + if (posts && posts.length) { Posts.getPostsByPids(pids, function(err, posts) { plugins.fireHook('action:post.gotTopic', posts); - callback(posts); + callback(null, posts); }); } else { - callback(posts); + callback(null, []); } }); - } else - callback([]); + } else { + callback(null, []); + } }); } diff --git a/src/routes/user.js b/src/routes/user.js index a978e50eee..d7b88ff03e 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -181,7 +181,7 @@ var fs = require('fs'), user.setUserField(uid, 'picture', imageUrl); if (convertToPNG) { - im.convert([uploadPath, 'png:-'], + im.convert([uploadPath, 'png:-'], function(err, stdout){ if (err) { winston.err(err); @@ -191,10 +191,10 @@ var fs = require('fs'), return; } - fs.writeFileSync(uploadPath, stdout, 'binary'); + fs.writeFileSync(uploadPath, stdout, 'binary'); }); } - + res.json({ path: imageUrl @@ -393,18 +393,24 @@ var fs = require('fs'), }); }); - app.get('/api/user/:userslug', function (req, res) { + app.get('/api/user/:userslug', function (req, res, next) { var callerUID = req.user ? req.user.uid : '0'; getUserDataByUserSlug(req.params.userslug, callerUID, function (userData) { if (userData) { user.isFollowing(callerUID, userData.theirid, function (isFollowing) { - posts.getPostsByUid(userData.theirid, 0, 9, function (posts) { + posts.getPostsByUid(userData.theirid, 0, 9, function (err, posts) { + + if(err) { + return next(err); + } userData.posts = posts.filter(function (p) { return p && parseInt(p.deleted, 10) !== 1; }); + userData.isFollowing = isFollowing; + if (!userData.profileviews) { userData.profileviews = 1; } diff --git a/src/user.js b/src/user.js index bfd8f47826..fd6a6eea31 100644 --- a/src/user.js +++ b/src/user.js @@ -444,21 +444,18 @@ var bcrypt = require('bcrypt'), User.getPostIds = function(uid, start, stop, callback) { db.getListRange('uid:' + uid + ':posts', start, stop, function(err, pids) { - if (!err) { - if (pids && pids.length) { - callback(pids); - } else { - callback([]); - } + if(err) { + return callback(err); + } + + if (pids && pids.length) { + callback(null, pids); } else { - console.log(err); - callback([]); + callback(null, []); } }); }; - - User.follow = function(uid, followid, callback) { db.setAdd('following:' + uid, followid, function(err, data) { if (!err) { From 25bac03babd7c109c905a6aec27d03fb329cb416 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Sun, 15 Dec 2013 14:12:36 -0500 Subject: [PATCH 10/21] fixed facebook + gplus authentication - callbackURL was invalid --- src/routes/authentication.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/authentication.js b/src/routes/authentication.js index 743ad9f9b0..5b4291d45d 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -72,7 +72,7 @@ login_strategies.push({ name: 'google', url: '/auth/google', - callbackURL: nconf.get('url') + '/auth/google/callback', + callbackURL: '/auth/google/callback', icon: 'google-plus', scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email' }); @@ -95,7 +95,7 @@ login_strategies.push({ name: 'facebook', url: '/auth/facebook', - callbackURL: nconf.get('url') + '/auth/facebook/callback', + callbackURL: '/auth/facebook/callback', icon: 'facebook', scope: 'email' }); From 58a3f33200919fbc6c7705ceb57e534f74147713 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Mon, 16 Dec 2013 15:40:59 -0500 Subject: [PATCH 11/21] plugins - added api routes to filter:admin.create_routes --- src/routes/admin.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/routes/admin.js b/src/routes/admin.js index cd3994f144..47331ea8aa 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -244,7 +244,7 @@ var nconf = require('nconf'), var custom_routes = { 'routes': [], - 'api_methods': [] + 'api': [] }; plugins.ready(function() { @@ -264,6 +264,19 @@ var nconf = require('nconf'), }(route)); } } + + var apiRoutes = custom_routes.api; + for (var route in apiRoutes) { + if (apiRoutes.hasOwnProperty(route)) { + (function(route) { + app[apiRoutes[route].method || 'get']('/admin/api' + apiRoutes[route].route, function(req, res) { + apiRoutes[route].callback(req, res, function(data) { + res.json(data); + }); + }); + }(route)); + } + } }); }); From a2c9867902512db95594761586c9db1f8a6cb4f1 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Mon, 16 Dec 2013 15:45:52 -0500 Subject: [PATCH 12/21] plugins - woops, wrong namespace for admin api calls --- src/routes/admin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/admin.js b/src/routes/admin.js index 47331ea8aa..3bb8783340 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -269,7 +269,7 @@ var nconf = require('nconf'), for (var route in apiRoutes) { if (apiRoutes.hasOwnProperty(route)) { (function(route) { - app[apiRoutes[route].method || 'get']('/admin/api' + apiRoutes[route].route, function(req, res) { + app[apiRoutes[route].method || 'get']('/api/admin' + apiRoutes[route].route, function(req, res) { apiRoutes[route].callback(req, res, function(data) { res.json(data); }); From 9cb20c3886cb1680f72ee9f3265d5754b6b12798 Mon Sep 17 00:00:00 2001 From: Baris Soner Usakli Date: Mon, 16 Dec 2013 19:12:26 -0500 Subject: [PATCH 13/21] added callback to api categories.get --- public/src/forum/topic.js | 5 ++--- src/websockets.js | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index 3a47ce901c..824ef1cfb8 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -102,7 +102,7 @@ define(function() { var loadingEl = document.getElementById('categories-loading'); if (loadingEl) { - socket.once('api:categories.get', function(data) { + socket.emit('api:categories.get', function(data) { // Render categories var categoriesFrag = document.createDocumentFragment(), categoryEl = document.createElement('li'), @@ -172,7 +172,6 @@ define(function() { } }); }); - socket.emit('api:categories.get'); } }); } @@ -802,7 +801,7 @@ define(function() { pagination.parentNode.style.display = 'block'; progressBarContainer.css('display', ''); - + if (scrollTop < jQuery('.posts > .post-row:first-child').height() && Topic.postCount > 1) { localStorage.removeItem("topic:" + tid + ":bookmark"); pagination.innerHTML = '1 out of ' + Topic.postCount; diff --git a/src/websockets.js b/src/websockets.js index 4547f1d3b1..81a3bbe221 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -591,9 +591,9 @@ websockets.init = function(io) { threadTools.move(data.tid, data.cid, socket); }); - socket.on('api:categories.get', function() { + socket.on('api:categories.get', function(callback) { categories.getAllCategories(0, function(err, categories) { - socket.emit('api:categories.get', categories); + callback(categories); }); }); From 35ad3be9690d9c4548134e494edb70a980375da8 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 17 Dec 2013 20:34:21 +0000 Subject: [PATCH 14/21] Adding support for restricting category read access based on user groups --- public/src/forum/admin/categories.js | 37 +++++++++++++++++- public/templates/admin/categories.tpl | 8 +++- src/categoryTools.js | 54 ++++++++++++++++++++++++++- src/groups.js | 36 ++++++++++++++++++ src/routes/api.js | 30 +++++++++++---- src/websockets.js | 31 +++++++++++++++ 6 files changed, 186 insertions(+), 10 deletions(-) diff --git a/public/src/forum/admin/categories.js b/public/src/forum/admin/categories.js index 0874ffa878..73eafde5df 100644 --- a/public/src/forum/admin/categories.js +++ b/public/src/forum/admin/categories.js @@ -211,6 +211,7 @@ define(['uploader'], function(uploader) { var modal = $('#category-permissions-modal'), searchEl = modal.find('#permission-search'), resultsEl = modal.find('.search-results'), + groupsResultsEl = modal.find('.groups-results'), searchDelay; searchEl.off().on('keyup', function() { @@ -263,6 +264,40 @@ define(['uploader'], function(uploader) { searchEl.keyup(); }); + // User Groups and privileges + socket.emit('api:admin.categories.groupsearch', cid, function(err, results) { + var groupsFrag = document.createDocumentFragment(), + liEl = document.createElement('li'); + var numResults = results.length, + resultObj; + + for(var x=0;x' + + '' + + '' + + '' + + '' + + ' '+resultObj.name; + + groupsFrag.appendChild(liEl.cloneNode(true)); + } + + groupsResultsEl.html(groupsFrag); + }); + + groupsResultsEl.off().on('click', '[data-gpriv]', function(e) { + var btnEl = $(this), + gid = btnEl.parents('li[data-gid]').attr('data-gid'), + privilege = this.getAttribute('data-gpriv'); + e.preventDefault(); + socket.emit('api:admin.categories.setGroupPrivilege', cid, gid, privilege, !btnEl.hasClass('active'), function(err, privileges) { + btnEl.toggleClass('active', privileges[privilege]); + }); + }) + modal.modal(); }; @@ -312,4 +347,4 @@ define(['uploader'], function(uploader) { }; return Categories; -}); \ No newline at end of file +}); diff --git a/public/templates/admin/categories.tpl b/public/templates/admin/categories.tpl index 25b85daf68..9651b387a9 100644 --- a/public/templates/admin/categories.tpl +++ b/public/templates/admin/categories.tpl @@ -154,6 +154,12 @@
    +
    +
    + +
    +
    +
      @@ -162,4 +168,4 @@ - \ No newline at end of file + diff --git a/src/categoryTools.js b/src/categoryTools.js index ccbce0f4fd..e1f79e8c07 100644 --- a/src/categoryTools.js +++ b/src/categoryTools.js @@ -65,4 +65,56 @@ CategoryTools.privileges = function(cid, uid, callback) { }); }; -module.exports = CategoryTools; \ No newline at end of file +CategoryTools.groupPrivileges = function(cid, gid, callback) { + async.parallel({ + "+gr": function(next) { + var key = 'cid:' + cid + ':privileges:+gr'; + Groups.exists(key, function(err, exists) { + if (exists) { + async.parallel({ + isMember: function(next) { + Groups.isMemberByGroupName(gid, key, next); + }, + isEmpty: function(next) { + Groups.isEmptyByGroupName(key, next); + } + }, next); + } else { + next(null, { + isMember: false, + isEmpty: true + }); + } + }); + }, + "+gw": function(next) { + var key = 'cid:' + cid + ':privileges:+gw'; + Groups.exists(key, function(err, exists) { + if (exists) { + async.parallel({ + isMember: function(next) { + Groups.isMemberByGroupName(gid, key, next); + }, + isEmpty: function(next) { + Groups.isEmptyByGroupName(key, next); + } + }, next); + } else { + next(null, { + isMember: false, + isEmpty: true + }); + } + }); + } + }, function(err, privileges) { + callback(err, !privileges ? null : { + "+gr": privileges['+gr'].isMember, + "+gw": privileges['+gw'].isMember, + read: (privileges['+gr'].isMember || privileges['+gr'].isEmpty), + write: (privileges['+gw'].isMember || privileges['+gw'].isEmpty), + }); + }); +}; + +module.exports = CategoryTools; diff --git a/src/groups.js b/src/groups.js index 3d56520257..782cca7ff3 100644 --- a/src/groups.js +++ b/src/groups.js @@ -263,4 +263,40 @@ }); }; + Groups.getCategoryAccess = function(cid, uid, callback){ + var access = false; + // check user group read access level + async.series([function(callback){ + // get groups with read permission + db.getObjectField('group:gid', 'cid:' + cid + ':privileges:+gr', function(err, gid){ + // get the user groups that belong to this read group + db.getSetMembers('gid:' + gid + ':members', function (err, gids) { + // check if user belong to any of these user groups + var groups_check = new Array(); + gids.forEach(function(cgid){ + groups_check.push(function(callback){ + Groups.isMember(uid, cgid, function(err, isMember){ + if (isMember){ + access = true; + } + callback(null, gids); + }) + }); + }); + // do a series check. We want to make sure we check all the groups before determining if the user + // has access or not. + async.series(groups_check, function(err, results){ + callback(null, results); + }); + }); + }); + + }], + function(err, results){ + // if the read group is empty we will asume that read access has been granted to ALL + if (results[0].length == 0){ access = true; } + callback(false, access); + }); + }; + }(module.exports)); diff --git a/src/routes/api.js b/src/routes/api.js index 45e9514ce8..cb28e0bffb 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -4,6 +4,7 @@ var path = require('path'), db = require('../database'), user = require('../user'), + groups = require('../groups'), auth = require('./authentication'), topics = require('../topics'), posts = require('../posts'), @@ -121,7 +122,15 @@ var path = require('path'), if (parseInt(data.deleted, 10) === 1 && parseInt(data.expose_tools, 10) === 0) { return res.json(404, {}); } - res.json(data); + // get the category this post belongs to and check category access + var cid = data.category_slug.split("/")[0]; + groups.getCategoryAccess(cid, uid, function(err, access){ + if (access){ + res.json(data); + } else { + res.send(403); + } + }) } else next(); }); }); @@ -132,13 +141,20 @@ var path = require('path'), // Category Whitelisting categoryTools.privileges(req.params.id, uid, function(err, privileges) { if (!err && privileges.read) { - categories.getCategoryById(req.params.id, uid, function (err, data) { - if (!err && data && parseInt(data.disabled, 10) === 0) { - res.json(data); + groups.getCategoryAccess(req.params.id, uid, function(err, access){ + if (access){ + categories.getCategoryById(req.params.id, uid, function (err, data) { + if (!err && data && parseInt(data.disabled, 10) === 0) { + res.json(data); + } else { + next(); + } + }, req.params.id, uid); } else { - next(); + res.send(403); } - }, req.params.id, uid); + + }); } else { res.send(403); } @@ -303,4 +319,4 @@ var path = require('path'), }); }); } -}(exports)); \ No newline at end of file +}(exports)); diff --git a/src/websockets.js b/src/websockets.js index 81a3bbe221..2000b34617 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -1084,6 +1084,37 @@ websockets.init = function(io) { }); }); + socket.on('api:admin.categories.setGroupPrivilege', function(cid, gid, privilege, set, callback) { + var cb = function(err) { + CategoryTools.groupPrivileges(cid, gid, callback); + }; + + if (set) { + groups.joinByGroupName('cid:' + cid + ':privileges:' + privilege, gid, cb); + } else { + groups.leaveByGroupName('cid:' + cid + ':privileges:' + privilege, gid, cb); + } + }); + + socket.on('api:admin.categories.groupsearch', function(cid, callback) { + groups.list({expand:false}, function(err, data){ + async.map(data, function(groupObj, next) { + CategoryTools.groupPrivileges(cid, groupObj.gid, function(err, privileges) { + if (!err) { + groupObj.privileges = privileges; + } else { + winston.error('[socket api:admin.categories.groupsearch] Could not retrieve permissions'); + } + + next(null, groupObj); + }); + }, function(err, data) { + if (!callback) socket.emit('api:admin.categories.groupsearch', data); + else callback(null, data); + }); + }); + }); + socket.on('api:admin.themes.getInstalled', function(callback) { meta.themes.get(function(err, themeArr) { callback(themeArr); From 9435acfa7130a77d9f5c841a2d30fa551a50b97f Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 17 Dec 2013 15:37:42 -0500 Subject: [PATCH 15/21] skip debug messages for supervisor --- nodebb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodebb b/nodebb index ded766b51e..880afdf563 100755 --- a/nodebb +++ b/nodebb @@ -20,7 +20,7 @@ case "$1" in echo "Launching NodeBB in \"development\" mode." echo "To run the production build of NodeBB, please use \"forever\"." echo "More Information: https://github.com/designcreateplay/NodeBB/wiki/How-to-run-NodeBB" - NODE_ENV=development supervisor --extensions 'node|js|tpl' -- app $1 + NODE_ENV=development supervisor -q --extensions 'node|js|tpl' -- app $1 ;; language) From 32a32fcf5cc28d65290232e0604626b4278be303 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 17 Dec 2013 15:42:01 -0500 Subject: [PATCH 16/21] match login.tpl button to look like register.tpl --- public/templates/login.tpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/templates/login.tpl b/public/templates/login.tpl index cad99bc5a4..233986f339 100644 --- a/public/templates/login.tpl +++ b/public/templates/login.tpl @@ -40,7 +40,8 @@
      -   [[login:forgot_password]] +
      +   [[login:forgot_password]]
      From f9e2b5082602f46976cc311fbb151194f7f3564f Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 17 Dec 2013 16:01:08 -0500 Subject: [PATCH 17/21] dynamically update user rep in post footer if reputation is increased --- public/templates/topic.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index 7802c41524..7c21d1a849 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -109,7 +109,7 @@