mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 11:35:55 +01:00
@@ -390,8 +390,11 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
|
||||
}
|
||||
|
||||
function toggleModTools(postHtml, privileges) {
|
||||
postHtml.find('.edit, .delete').toggleClass('none', !privileges.editable);
|
||||
postHtml.find('.move').toggleClass('none', !privileges.move);
|
||||
postHtml.find('.edit, .delete').toggleClass('none', !privileges.meta.editable);
|
||||
postHtml.find('.move').toggleClass('none', !privileges.meta.move);
|
||||
postHtml.find('.reply, .quote').toggleClass('none', !$('.post_reply').length)
|
||||
var isSelfPost = parseInt(postHtml.attr('data-uid'), 10) === parseInt(app.uid, 10);
|
||||
postHtml.find('.chat, .flag').toggleClass('none', isSelfPost);
|
||||
}
|
||||
|
||||
function loadMorePosts(tid, after, callback) {
|
||||
|
||||
@@ -21,10 +21,6 @@ define(['forum/topic/fork', 'forum/topic/move'], function(fork, move) {
|
||||
ThreadTools.setPinnedState({tid: tid, isPinned: true});
|
||||
}
|
||||
|
||||
if (ajaxify.variables.get('expose_tools') === '1') {
|
||||
|
||||
$('.thread-tools').removeClass('hide');
|
||||
|
||||
$('.delete_thread').on('click', function(e) {
|
||||
var command = threadState.deleted !== '1' ? 'delete' : 'restore';
|
||||
|
||||
@@ -67,7 +63,6 @@ define(['forum/topic/fork', 'forum/topic/move'], function(fork, move) {
|
||||
});
|
||||
|
||||
fork.init();
|
||||
}
|
||||
|
||||
socket.emit('topics.followCheck', tid, function(err, state) {
|
||||
setFollowState(state);
|
||||
|
||||
@@ -10,27 +10,27 @@ var topicsController = {},
|
||||
meta = require('./../meta'),
|
||||
topics = require('./../topics'),
|
||||
posts = require('../posts'),
|
||||
threadTools = require('./../threadTools'),
|
||||
privileges = require('../privileges'),
|
||||
utils = require('./../../public/src/utils');
|
||||
|
||||
topicsController.get = function(req, res, next) {
|
||||
var tid = req.params.topic_id,
|
||||
page = req.query.page || 1,
|
||||
uid = req.user ? req.user.uid : 0,
|
||||
privileges;
|
||||
userPrivileges;
|
||||
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
threadTools.privileges(tid, uid, function(err, userPrivileges) {
|
||||
privileges.topics.get(tid, uid, function(err, privileges) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (!userPrivileges.meta.read) {
|
||||
if (!privileges.meta.read) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
privileges = userPrivileges;
|
||||
userPrivileges = privileges;
|
||||
next();
|
||||
});
|
||||
},
|
||||
@@ -45,7 +45,7 @@ topicsController.get = function(req, res, next) {
|
||||
|
||||
topics.getTopicWithPosts(tid, uid, start, end, function (err, topicData) {
|
||||
if (topicData) {
|
||||
if (parseInt(topicData.deleted, 10) === 1 && parseInt(topicData.expose_tools, 10) === 0) {
|
||||
if (parseInt(topicData.deleted, 10) === 1 && !userPrivileges.view_deleted) {
|
||||
return next(new Error('[[error:no-topic]]'));
|
||||
}
|
||||
topicData.currentPage = page;
|
||||
@@ -154,7 +154,7 @@ topicsController.get = function(req, res, next) {
|
||||
}
|
||||
}
|
||||
|
||||
data.privileges = privileges;
|
||||
data.privileges = userPrivileges;
|
||||
|
||||
var topic_url = tid + (req.params.slug ? '/' + req.params.slug : '');
|
||||
var queryString = qs.stringify(req.query);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
var privileges = {};
|
||||
|
||||
require('./privileges/categories')(privileges);
|
||||
require('./privileges/topics')(privileges);
|
||||
require('./privileges/posts')(privileges);
|
||||
|
||||
|
||||
module.exports = privileges;
|
||||
28
src/privileges/categories.js
Normal file
28
src/privileges/categories.js
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
|
||||
user = require('../user'),
|
||||
helpers = require('./helpers');
|
||||
|
||||
|
||||
module.exports = function(privileges) {
|
||||
|
||||
privileges.categories = {};
|
||||
|
||||
privileges.categories.canRead = function(cid, uid, callback) {
|
||||
helpers.some([
|
||||
function(next) {
|
||||
helpers.allowedTo('read', uid, cid, next);
|
||||
},
|
||||
function(next) {
|
||||
user.isModerator(uid, cid, next);
|
||||
},
|
||||
function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
};
|
||||
@@ -10,6 +10,16 @@ var async = require('async'),
|
||||
|
||||
var helpers = {};
|
||||
|
||||
helpers.some = function(tasks, callback) {
|
||||
async.some(tasks, function(task, next) {
|
||||
task(function(err, result) {
|
||||
next(!err && result);
|
||||
});
|
||||
}, function(result) {
|
||||
callback(null, result);
|
||||
});
|
||||
};
|
||||
|
||||
helpers.allowedTo = function(privilege, uid, cid, callback) {
|
||||
categories.getCategoryField(cid, 'disabled', function(err, disabled) {
|
||||
if (err) {
|
||||
@@ -47,7 +57,7 @@ function isMember(method, group, uid, callback) {
|
||||
return callback(null, null);
|
||||
}
|
||||
|
||||
method(group, uid, callback);
|
||||
method(uid, group, callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -59,28 +59,12 @@ module.exports = function(privileges) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.some([
|
||||
function(next) {
|
||||
helpers.allowedTo('read', uid, cid, next);
|
||||
},
|
||||
function(next) {
|
||||
user.isModerator(uid, cid, next);
|
||||
},
|
||||
function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], function(task, next) {
|
||||
task(function(err, result) {
|
||||
next(!err && result);
|
||||
});
|
||||
}, function(result) {
|
||||
callback(null, result);
|
||||
});
|
||||
privileges.categories.canRead(cid, uid, callback);
|
||||
});
|
||||
};
|
||||
|
||||
privileges.posts.canEdit = function(pid, uid, callback) {
|
||||
async.some([
|
||||
helpers.some([
|
||||
function(next) {
|
||||
posts.isOwner(pid, uid, next);
|
||||
},
|
||||
@@ -101,12 +85,22 @@ module.exports = function(privileges) {
|
||||
function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], function(task, next) {
|
||||
task(function(err, result) {
|
||||
next(!err && result);
|
||||
});
|
||||
}, function(result) {
|
||||
callback(null, result);
|
||||
], callback);
|
||||
};
|
||||
|
||||
privileges.posts.canMove = function(pid, uid, callback) {
|
||||
helpers.some([
|
||||
function(next) {
|
||||
posts.getCidByPid(pid, function(err, cid) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
user.isModerator(uid, cid, next);
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
};
|
||||
|
||||
122
src/privileges/topics.js
Normal file
122
src/privileges/topics.js
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
|
||||
topics = require('../topics'),
|
||||
user = require('../user'),
|
||||
helpers = require('./helpers'),
|
||||
groups = require('../groups'),
|
||||
categories = require('../categories');
|
||||
|
||||
module.exports = function(privileges) {
|
||||
|
||||
privileges.topics = {};
|
||||
|
||||
privileges.topics.get = function(tid, uid, callback) {
|
||||
|
||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
async.parallel({
|
||||
'topics:reply': function(next) {
|
||||
helpers.allowedTo('topics:reply', uid, cid, next);
|
||||
},
|
||||
read: function(next) {
|
||||
helpers.allowedTo('read', uid, cid, next);
|
||||
},
|
||||
manage_topic: function(next) {
|
||||
helpers.hasEnoughReputationFor('privileges:manage_topic', uid, next);
|
||||
},
|
||||
isAdministrator: function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
},
|
||||
isModerator: function(next) {
|
||||
user.isModerator(uid, cid, next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var editable = results.isAdministrator || results.isModerator || results.manage_topic;
|
||||
|
||||
callback(null, {
|
||||
meta: {
|
||||
'topics:reply': results['topics:reply'],
|
||||
editable: editable,
|
||||
view_deleted: editable,
|
||||
read: results.read
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
privileges.topics.canRead = function(tid, uid, callback) {
|
||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
privileges.categories.canRead(cid, uid, callback);
|
||||
});
|
||||
};
|
||||
|
||||
privileges.topics.canReply = function(tid, uid, callback) {
|
||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
helpers.some([
|
||||
function(next) {
|
||||
helpers.allowedTo('topics:reply', uid, cid, next);
|
||||
},
|
||||
function(next) {
|
||||
user.isModerator(uid, cid, next);
|
||||
},
|
||||
function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], callback);
|
||||
});
|
||||
};
|
||||
|
||||
privileges.topics.canEdit = function(tid, uid, callback) {
|
||||
helpers.some([
|
||||
function(next) {
|
||||
helpers.hasEnoughReputationFor('privileges:manage_topic', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
user.isModerator(uid, cid, next);
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
privileges.topics.canMove = function(tid, uid, callback) {
|
||||
helpers.some([
|
||||
function(next) {
|
||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
user.isModerator(uid, cid, next);
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
};
|
||||
@@ -7,30 +7,29 @@ var posts = require('./../posts'),
|
||||
rss = require('rss'),
|
||||
nconf = require('nconf'),
|
||||
|
||||
ThreadTools = require('./../threadTools'),
|
||||
CategoryTools = require('./../categoryTools');
|
||||
privileges = require('../privileges');
|
||||
|
||||
function hasTopicPrivileges(req, res, next) {
|
||||
var tid = req.params.topic_id;
|
||||
|
||||
hasPrivileges(ThreadTools, tid, req, res, next);
|
||||
hasPrivileges(privileges.topics.canRead, tid, req, res, next);
|
||||
}
|
||||
|
||||
function hasCategoryPrivileges(req, res, next) {
|
||||
var cid = req.params.category_id;
|
||||
|
||||
hasPrivileges(CategoryTools, cid, req, res, next);
|
||||
hasPrivileges(privileges.categories.canRead, cid, req, res, next);
|
||||
}
|
||||
|
||||
function hasPrivileges(module, id, req, res, next) {
|
||||
function hasPrivileges(method, id, req, res, next) {
|
||||
var uid = req.user ? req.user.uid || 0 : 0;
|
||||
|
||||
module.privileges(id, uid, function(err, privileges) {
|
||||
method(id, uid, function(err, canRead) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if(!privileges.read) {
|
||||
if (!canRead) {
|
||||
return res.redirect('403');
|
||||
}
|
||||
|
||||
@@ -66,7 +65,7 @@ function generateForTopic(req, res, next) {
|
||||
}
|
||||
|
||||
topicData.posts.forEach(function(postData) {
|
||||
if (parseInt(postData.deleted, 10) === 0) {
|
||||
if (!postData.deleted) {
|
||||
dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString();
|
||||
|
||||
feed.item({
|
||||
|
||||
@@ -37,8 +37,15 @@ SocketPosts.reply = function(socket, data, callback) {
|
||||
}
|
||||
|
||||
if (postData) {
|
||||
var privileges = {
|
||||
meta : {
|
||||
'topics:reply': true
|
||||
}
|
||||
};
|
||||
|
||||
websockets.server.sockets.emit('event:new_post', {
|
||||
posts: [postData]
|
||||
posts: [postData],
|
||||
privileges: privileges
|
||||
});
|
||||
|
||||
module.parent.exports.emitTopicPostStats();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
var topics = require('../topics'),
|
||||
categories = require('../categories'),
|
||||
privileges = require('../privileges'),
|
||||
threadTools = require('../threadTools'),
|
||||
categoryTools = require('../categoryTools'),
|
||||
websockets = require('./index'),
|
||||
@@ -181,12 +182,12 @@ function doTopicAction(action, socket, tids, callback) {
|
||||
}
|
||||
|
||||
async.each(tids, function(tid, next) {
|
||||
threadTools.privileges(tid, socket.uid, function(err, privileges) {
|
||||
privileges.topics.canEdit(tid, socket.uid, function(err, canEdit) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if(!privileges || !privileges.meta.editable) {
|
||||
if(!canEdit) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
@@ -218,13 +219,9 @@ SocketTopics.movePost = function(socket, data, callback) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
|
||||
threadTools.privileges(data.tid, socket.uid, function(err, privileges) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if(!(privileges.admin || privileges.moderator)) {
|
||||
return callback(new Error('[[error:no-privileges]]'));
|
||||
privileges.posts.canMove(data.tid, socket.uid, function(err, canMove) {
|
||||
if (err || !canMove) {
|
||||
return callback(err || new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
topics.movePostToTopic(data.pid, data.tid, callback);
|
||||
@@ -240,10 +237,10 @@ SocketTopics.move = function(socket, data, callback) {
|
||||
var oldCid;
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
threadTools.privileges(tid, socket.uid, next);
|
||||
privileges.topics.canMove(tid, socket.uid, next);
|
||||
},
|
||||
function(privileges, next) {
|
||||
if(!(privileges.admin || privileges.moderator)) {
|
||||
function(canMove, next) {
|
||||
if (!canMove) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
next();
|
||||
@@ -336,7 +333,7 @@ SocketTopics.loadMore = function(socket, data, callback) {
|
||||
topics.getTopicPosts(data.tid, start, end, socket.uid, false, next);
|
||||
},
|
||||
privileges: function(next) {
|
||||
threadTools.privileges(data.tid, socket.uid, next);
|
||||
privileges.topics.get(data.tid, socket.uid, next);
|
||||
}
|
||||
}, callback);
|
||||
});
|
||||
|
||||
@@ -23,38 +23,6 @@ var winston = require('winston'),
|
||||
db.isSortedSetMember('topics:tid', tid, callback);
|
||||
};
|
||||
|
||||
ThreadTools.privileges = function(tid, uid, callback) {
|
||||
async.parallel({
|
||||
categoryPrivs: function(next) {
|
||||
topics.getTopicField(tid, 'cid', function(err, cid) {
|
||||
CategoryTools.privileges(cid, uid, next);
|
||||
});
|
||||
},
|
||||
hasEnoughRep: function(next) {
|
||||
if (parseInt(meta.config['privileges:disabled'], 10)) {
|
||||
return next(null, false);
|
||||
} else {
|
||||
user.getUserField(uid, 'reputation', function(err, reputation) {
|
||||
if (err) {
|
||||
return next(null, false);
|
||||
}
|
||||
next(null, parseInt(reputation, 10) >= parseInt(meta.config['privileges:manage_topic'], 10));
|
||||
});
|
||||
}
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var privileges = results.categoryPrivs;
|
||||
privileges.meta.editable = privileges.meta.editable || results.hasEnoughRep;
|
||||
privileges.meta.view_deleted = privileges.meta.view_deleted || results.hasEnoughRep;
|
||||
|
||||
callback(null, privileges);
|
||||
});
|
||||
};
|
||||
|
||||
ThreadTools.delete = function(tid, uid, callback) {
|
||||
toggleDelete(tid, uid, true, callback);
|
||||
};
|
||||
|
||||
@@ -11,7 +11,8 @@ var async = require('async'),
|
||||
user = require('./user'),
|
||||
categories = require('./categories'),
|
||||
categoryTools = require('./categoryTools'),
|
||||
threadTools = require('./threadTools');
|
||||
threadTools = require('./threadTools'),
|
||||
privileges = require('./privileges');
|
||||
|
||||
(function(Topics) {
|
||||
|
||||
@@ -132,8 +133,8 @@ var async = require('async'),
|
||||
}
|
||||
|
||||
async.filter(tids, function(tid, next) {
|
||||
threadTools.privileges(tid, uid, function(err, privileges) {
|
||||
next(!err && privileges.meta.read);
|
||||
privileges.topics.canRead(tid, uid, function(err, canRead) {
|
||||
next(!err && canRead);
|
||||
});
|
||||
}, function(tids) {
|
||||
Topics.getTopicsByTids(tids, uid, function(err, topicData) {
|
||||
@@ -269,9 +270,6 @@ var async = require('async'),
|
||||
posts: function(next) {
|
||||
Topics.getTopicPosts(tid, start, end, uid, false, next);
|
||||
},
|
||||
privileges: function(next) {
|
||||
threadTools.privileges(tid, uid, next);
|
||||
},
|
||||
category: function(next) {
|
||||
Topics.getCategoryData(tid, next);
|
||||
},
|
||||
@@ -291,7 +289,6 @@ var async = require('async'),
|
||||
topicData.thread_tools = results.threadTools;
|
||||
topicData.pageCount = results.pageCount;
|
||||
topicData.unreplied = parseInt(topicData.postcount, 10) === 1;
|
||||
topicData.expose_tools = results.privileges.meta.editable ? 1 : 0;
|
||||
|
||||
callback(null, topicData);
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ var async = require('async'),
|
||||
meta = require('./../meta'),
|
||||
posts = require('./../posts'),
|
||||
threadTools = require('./../threadTools'),
|
||||
privileges = require('../privileges'),
|
||||
categoryTools = require('./../categoryTools');
|
||||
|
||||
module.exports = function(Topics) {
|
||||
@@ -144,7 +145,6 @@ module.exports = function(Topics) {
|
||||
uid = data.uid,
|
||||
toPid = data.toPid,
|
||||
content = data.content,
|
||||
privileges,
|
||||
postData;
|
||||
|
||||
async.waterfall([
|
||||
@@ -173,11 +173,10 @@ module.exports = function(Topics) {
|
||||
return next(new Error('[[error:topic-locked]]'));
|
||||
}
|
||||
|
||||
threadTools.privileges(tid, uid, next);
|
||||
privileges.topics.canReply(tid, uid, next);
|
||||
},
|
||||
function(privilegesData, next) {
|
||||
privileges = privilegesData;
|
||||
if (!privileges.meta['topics:reply']) {
|
||||
function(canReply, next) {
|
||||
if (!canReply) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
next();
|
||||
@@ -232,7 +231,8 @@ module.exports = function(Topics) {
|
||||
postData.favourited = false;
|
||||
postData.votes = 0;
|
||||
postData.display_moderator_tools = true;
|
||||
postData.display_move_tools = privileges.admin || privileges.moderator;
|
||||
postData.display_move_tools = true;
|
||||
postData.selfPost = false;
|
||||
postData.relativeTime = utils.toISOString(postData.timestamp);
|
||||
|
||||
next(null, postData);
|
||||
|
||||
@@ -8,7 +8,7 @@ var async = require('async'),
|
||||
user = require('./../user'),
|
||||
notifications = require('./../notifications'),
|
||||
categories = require('./../categories'),
|
||||
threadTools = require('./../threadTools');
|
||||
privileges = require('../privileges');
|
||||
|
||||
module.exports = function(Topics) {
|
||||
|
||||
@@ -49,8 +49,8 @@ module.exports = function(Topics) {
|
||||
});
|
||||
|
||||
async.filter(newtids, function(tid, next) {
|
||||
threadTools.privileges(tid, uid, function(err, privileges) {
|
||||
next(!err && privileges.meta.read);
|
||||
privileges.topics.canRead(tid, uid, function(err, canRead) {
|
||||
next(!err && canRead);
|
||||
});
|
||||
}, function(newtids) {
|
||||
unreadTids.push.apply(unreadTids, newtids);
|
||||
|
||||
Reference in New Issue
Block a user