mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 03:55:55 +01:00
ban users, closes #125, banning a user hides all posts topics of a user and their profile page becomes inaccessible
This commit is contained in:
@@ -8,6 +8,11 @@
|
||||
return (parent.attr('data-admin') !== "0");
|
||||
}
|
||||
|
||||
function isUserBanned(element) {
|
||||
var parent = $(element).parents('.users-box');
|
||||
return (parent.attr('data-banned') !== "" && parent.attr('data-banned') !== "0");
|
||||
}
|
||||
|
||||
function getUID(element) {
|
||||
var parent = $(element).parents('.users-box');
|
||||
return parent.attr('data-uid');
|
||||
@@ -34,6 +39,20 @@
|
||||
deleteBtn.show();
|
||||
});
|
||||
|
||||
jQuery('.ban-btn').each(function(index, element) {
|
||||
var banBtn = $(element);
|
||||
var isAdmin = isUserAdmin(banBtn);
|
||||
var isBanned = isUserBanned(banBtn);
|
||||
|
||||
if(isAdmin)
|
||||
banBtn.addClass('disabled');
|
||||
else if(isBanned)
|
||||
banBtn.addClass('btn-warning');
|
||||
else
|
||||
banBtn.removeClass('btn-warning');
|
||||
|
||||
});
|
||||
|
||||
jQuery('.admin-btn').on('click', function() {
|
||||
var adminBtn = $(this);
|
||||
var isAdmin = isUserAdmin(adminBtn);
|
||||
@@ -74,6 +93,30 @@
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
jQuery('.ban-btn').on('click', function() {
|
||||
var banBtn = $(this);
|
||||
var isAdmin = isUserAdmin(banBtn);
|
||||
var isBanned = isUserBanned(banBtn);
|
||||
var parent = banBtn.parents('.users-box');
|
||||
var uid = getUID(banBtn);
|
||||
|
||||
if(!isAdmin) {
|
||||
if(isBanned) {
|
||||
socket.emit('api:admin.user.unbanUser', uid);
|
||||
banBtn.removeClass('btn-warning');
|
||||
parent.attr('data-banned', 0);
|
||||
} else {
|
||||
bootbox.confirm('Do you really want to ban "' + parent.attr('data-username') +'"?', function(confirm) {
|
||||
socket.emit('api:admin.user.banUser', uid);
|
||||
banBtn.addClass('btn-warning');
|
||||
parent.attr('data-banned', 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<ul id="users-container" class="users">
|
||||
<!-- BEGIN users -->
|
||||
<div class="users-box" data-uid="{users.uid}" data-admin="{users.administrator}" data-username="{users.username}">
|
||||
<div class="users-box" data-uid="{users.uid}" data-admin="{users.administrator}" data-username="{users.username}" data-banned="{users.banned}">
|
||||
<a href="/users/{users.userslug}">
|
||||
<img src="{users.picture}" class="img-polaroid"/>
|
||||
</a>
|
||||
@@ -37,6 +37,9 @@
|
||||
<div>
|
||||
<a href="#" class="btn delete-btn btn-danger">Delete</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" class="btn ban-btn">Ban</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END users -->
|
||||
</ul>
|
||||
|
||||
@@ -58,8 +58,39 @@ var RDB = require('./../redis.js'),
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
UserAdmin.banUser = function(uid, theirid, socket) {
|
||||
user.isAdministrator(uid, function(amIAdmin) {
|
||||
user.isAdministrator(theirid, function(areTheyAdmin) {
|
||||
if(amIAdmin && !areTheyAdmin) {
|
||||
user.ban(theirid, function(err, result) {
|
||||
|
||||
socket.emit('event:alert', {
|
||||
title: 'User Banned',
|
||||
message: 'This user is banned!',
|
||||
type: 'success',
|
||||
timeout: 2000
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
UserAdmin.unbanUser = function(uid, theirid, socket) {
|
||||
user.isAdministrator(uid, function(amIAdmin) {
|
||||
if(amIAdmin) {
|
||||
user.unban(theirid, function(err, result) {
|
||||
socket.emit('event:alert', {
|
||||
title: 'User Unbanned',
|
||||
message: 'This user is unbanned!',
|
||||
type: 'success',
|
||||
timeout: 2000
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ var RDB = require('./redis.js'),
|
||||
}
|
||||
|
||||
function getActiveUsers(next) {
|
||||
user.getMultipleUserFields(active_users, ['username', 'userslug', 'picture'], function(users) {
|
||||
user.getMultipleUserFields(active_users, ['username', 'userslug', 'picture', 'banned'], function(users) {
|
||||
users = user.filterBannedUsers(users);
|
||||
next(null, users);
|
||||
});
|
||||
}
|
||||
@@ -66,7 +67,6 @@ var RDB = require('./redis.js'),
|
||||
categoryData.moderators = moderators;
|
||||
categoryData.show_sidebar = 'hidden';
|
||||
categoryData.no_topics_message = 'show';
|
||||
|
||||
callback(null, categoryData);
|
||||
});
|
||||
} else {
|
||||
@@ -200,11 +200,12 @@ var RDB = require('./redis.js'),
|
||||
return;
|
||||
}
|
||||
|
||||
posts.getPostSummaryByPids(pids, function(posts) {
|
||||
if(posts.length > count) {
|
||||
posts = posts.slice(0, count);
|
||||
posts.getPostSummaryByPids(pids, function(postData) {
|
||||
postData = posts.filterBannedPosts(postData);
|
||||
if(postData.length > count) {
|
||||
postData = postData.slice(0, count);
|
||||
}
|
||||
callback(posts);
|
||||
callback(postData);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
15
src/posts.js
15
src/posts.js
@@ -32,12 +32,13 @@ var RDB = require('./redis.js'),
|
||||
}
|
||||
|
||||
Posts.addUserInfoToPost = function(post, callback) {
|
||||
user.getUserFields(post.uid, ['username', 'userslug', 'reputation', 'postcount', 'picture', 'signature'], function(userData) {
|
||||
user.getUserFields(post.uid, ['username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned'], function(userData) {
|
||||
|
||||
post.username = userData.username || 'anonymous';
|
||||
post.userslug = userData.userslug || '';
|
||||
post.user_rep = userData.reputation || 0;
|
||||
post.user_postcount = userData.postcount || 0;
|
||||
post.user_banned = userData.banned || '0';
|
||||
post.picture = userData.picture || require('gravatar').url('', {}, https=global.nconf.get('https'));
|
||||
post.signature = postTools.markdownToHTML(userData.signature, true);
|
||||
|
||||
@@ -55,7 +56,7 @@ var RDB = require('./redis.js'),
|
||||
|
||||
Posts.getPostSummaryByPids = function(pids, callback) {
|
||||
|
||||
var returnData = [];
|
||||
var posts = [];
|
||||
|
||||
function getPostSummary(pid, callback) {
|
||||
Posts.getPostFields(pid, ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'], function(postData) {
|
||||
@@ -70,7 +71,7 @@ var RDB = require('./redis.js'),
|
||||
postData.content = utils.strip_tags(postTools.markdownToHTML(postData.content));
|
||||
|
||||
postData.topicSlug = topicSlug;
|
||||
returnData.push(postData);
|
||||
posts.push(postData);
|
||||
callback(null);
|
||||
});
|
||||
});
|
||||
@@ -80,13 +81,19 @@ var RDB = require('./redis.js'),
|
||||
|
||||
async.eachSeries(pids, getPostSummary, function(err) {
|
||||
if(!err) {
|
||||
callback(returnData);
|
||||
callback(posts);
|
||||
} else {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Posts.filterBannedPosts = function(posts) {
|
||||
return posts.filter(function(post) {
|
||||
return post.user_banned === '0';
|
||||
});
|
||||
}
|
||||
|
||||
Posts.getPostData = function(pid, callback) {
|
||||
RDB.hgetall('post:' + pid, function(err, data) {
|
||||
if(err === null) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
passportFacebook = require('passport-facebook').Strategy,
|
||||
login_strategies = [],
|
||||
nconf = require('nconf'),
|
||||
users = require('../user'),
|
||||
user = require('../user'),
|
||||
winston = require('winston'),
|
||||
login_module = require('./../login.js');
|
||||
|
||||
@@ -143,9 +143,9 @@
|
||||
});
|
||||
|
||||
app.post('/register', function(req, res) {
|
||||
users.create(req.body.username, req.body.password, req.body.email, function(err, uid) {
|
||||
user.create(req.body.username, req.body.password, req.body.email, function(err, uid) {
|
||||
|
||||
if (err === null && uid > 0) {
|
||||
if (err === null && uid) {
|
||||
req.login({
|
||||
uid: uid
|
||||
}, function() {
|
||||
|
||||
@@ -68,9 +68,15 @@ var user = require('./../user.js'),
|
||||
return;
|
||||
}
|
||||
|
||||
user.getUserField(uid, 'banned', function(banned) {
|
||||
if(banned && banned === '1') {
|
||||
next();
|
||||
} else {
|
||||
app.build_header({ req: req, res: res }, function(err, header) {
|
||||
res.send(header + app.create_route('users/' + req.params.userslug, 'account') + templates['footer']);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -321,18 +327,21 @@ var user = require('./../user.js'),
|
||||
|
||||
function getUsersSortedByJoinDate(req, res) {
|
||||
user.getUsers('users:joindate', 0, 49, function(err, data) {
|
||||
data = user.filterBannedUsers(data);
|
||||
res.json({ search_display: 'none', loadmore_display:'block', users:data });
|
||||
});
|
||||
}
|
||||
|
||||
function getUsersSortedByPosts(req, res) {
|
||||
user.getUsers('users:postcount', 0, 49, function(err, data) {
|
||||
data = user.filterBannedUsers(data);
|
||||
res.json({ search_display: 'none', loadmore_display:'block', users:data });
|
||||
});
|
||||
}
|
||||
|
||||
function getUsersSortedByReputation(req, res) {
|
||||
user.getUsers('users:reputation', 0, 49, function(err, data) {
|
||||
data = user.filterBannedUsers(data);
|
||||
res.json({ search_display: 'none', loadmore_display:'block', users:data });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -291,15 +291,32 @@ var RDB = require('./redis.js'),
|
||||
if(!numPosts)
|
||||
return callback(new Error('no-undeleted-pids-found'));
|
||||
|
||||
while(numPosts--) {
|
||||
if(posts[numPosts].deleted !== '1') {
|
||||
callback(null, posts[numPosts].pid);
|
||||
posts = posts.reverse();
|
||||
lastPostId = 0;
|
||||
|
||||
function isPostVisible(post, next) {
|
||||
if(post.deleted !== '1') {
|
||||
user.getUserField(post.uid, 'banned', function(banned) {
|
||||
if(banned && banned === '1') {
|
||||
next(null);
|
||||
} else {
|
||||
lastPostId = post.pid
|
||||
next(post.pid);
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, nothing was found...
|
||||
async.eachSeries(posts, isPostVisible, function(err) {
|
||||
if(err) {
|
||||
callback(null, lastPostId);
|
||||
} else {
|
||||
callback(new Error('no-undeleted-pids-found'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}(exports));
|
||||
@@ -78,6 +78,8 @@ marked.setOptions({
|
||||
var fav_data = results[0],
|
||||
privileges = results[2];
|
||||
|
||||
postData = posts.filterBannedPosts(postData);
|
||||
|
||||
for(var i=0; i<postData.length; ++i) {
|
||||
postData[i].fav_star_class = fav_data[postData[i].pid] ? 'icon-star' : 'icon-star-empty';
|
||||
postData[i]['display_moderator_tools'] = (postData[i].uid == current_user || privileges.editable) ? 'show' : 'none';
|
||||
@@ -149,7 +151,9 @@ marked.setOptions({
|
||||
Topics.getTopicsByTids(topicIds, uid, function(topicData) {
|
||||
unreadTopics.topics = topicData;
|
||||
unreadTopics.nextStart = start + tids.length;
|
||||
if(uid === 0)
|
||||
if(!topicData || topicData.length === 0)
|
||||
unreadTopics.no_topics_message = 'show';
|
||||
if(uid === 0 || topicData.length === 0)
|
||||
unreadTopics.show_markallread_button = 'hidden';
|
||||
callback(unreadTopics);
|
||||
});
|
||||
@@ -192,9 +196,9 @@ marked.setOptions({
|
||||
|
||||
function getTopicInfo(topicData, callback) {
|
||||
|
||||
function getUserName(next) {
|
||||
user.getUserField(topicData.uid, 'username', function(username) {
|
||||
next(null, username);
|
||||
function getUserInfo(next) {
|
||||
user.getUserFields(topicData.uid, ['username', 'banned'], function(userData) {
|
||||
next(null, userData);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -217,24 +221,23 @@ marked.setOptions({
|
||||
});
|
||||
}
|
||||
|
||||
async.parallel([getUserName, hasReadTopic, getTeaserInfo, getPrivileges], function(err, results) {
|
||||
var username = results[0],
|
||||
hasReadTopic = results[1],
|
||||
teaserInfo = results[2],
|
||||
privileges = results[3];
|
||||
|
||||
async.parallel([getUserInfo, hasReadTopic, getTeaserInfo, getPrivileges], function(err, results) {
|
||||
callback({
|
||||
username: username,
|
||||
hasread: hasReadTopic,
|
||||
teaserInfo: teaserInfo,
|
||||
privileges: privileges
|
||||
username: results[0].username,
|
||||
userbanned: results[0].banned,
|
||||
hasread: results[1],
|
||||
teaserInfo: results[2],
|
||||
privileges: results[3]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function isTopicVisible(topicData, topicInfo) {
|
||||
var deleted = parseInt(topicData.deleted, 10) !== 0;
|
||||
return !deleted || (deleted && topicInfo.privileges.view_deleted) || topicData.uid === current_user;
|
||||
var banned = false;
|
||||
if(topicData.userbanned)
|
||||
banned = parseInt(topicData.userbanned, 10) !== 0;
|
||||
return !banned && (!deleted || (deleted && topicInfo.privileges.view_deleted) || topicData.uid === current_user);
|
||||
}
|
||||
|
||||
function loadTopic(tid, callback) {
|
||||
@@ -252,6 +255,7 @@ marked.setOptions({
|
||||
topicData.relativeTime = utils.relativeTime(topicData.timestamp);
|
||||
|
||||
topicData.username = topicInfo.username;
|
||||
topicData.userbanned = topicInfo.userbanned;
|
||||
topicData.badgeclass = (topicInfo.hasread && current_user != 0) ? '' : 'badge-important';
|
||||
topicData.teaser_text = topicInfo.teaserInfo.text || '',
|
||||
topicData.teaser_username = topicInfo.teaserInfo.username || '';
|
||||
|
||||
22
src/user.js
22
src/user.js
@@ -41,7 +41,7 @@ var utils = require('./../public/src/utils.js'),
|
||||
} else next();
|
||||
}
|
||||
], function(err, results) {
|
||||
if (err) return callback(err, 0); // FIXME: Maintaining the 0 for backwards compatibility. Do we need this?
|
||||
if (err) return callback(err, null);
|
||||
|
||||
RDB.incr('global:next_user_id', function(err, uid) {
|
||||
RDB.handle(err);
|
||||
@@ -67,6 +67,7 @@ var utils = require('./../public/src/utils.js'),
|
||||
'postcount': 0,
|
||||
'lastposttime': 0,
|
||||
'administrator': (uid == 1) ? 1 : 0,
|
||||
'banned': 0,
|
||||
'showemail': 0
|
||||
});
|
||||
|
||||
@@ -127,6 +128,14 @@ var utils = require('./../public/src/utils.js'),
|
||||
});
|
||||
}
|
||||
|
||||
User.ban = function(uid, callback) {
|
||||
User.setUserField(uid, 'banned', 1, callback);
|
||||
}
|
||||
|
||||
User.unban = function(uid, callback) {
|
||||
User.setUserField(uid, 'banned', 0, callback);
|
||||
}
|
||||
|
||||
User.getUserField = function(uid, field, callback) {
|
||||
RDB.hget('user:' + uid, field, function(err, data) {
|
||||
if(err === null) {
|
||||
@@ -190,6 +199,12 @@ var utils = require('./../public/src/utils.js'),
|
||||
});
|
||||
}
|
||||
|
||||
User.filterBannedUsers = function(users) {
|
||||
return users.filter(function(user) {
|
||||
return (!user.banned || user.banned === '0');
|
||||
});
|
||||
}
|
||||
|
||||
User.updateProfile = function(uid, data, callback) {
|
||||
|
||||
var fields = ['email', 'fullname', 'website', 'location', 'birthday', 'signature'];
|
||||
@@ -309,8 +324,8 @@ var utils = require('./../public/src/utils.js'),
|
||||
});
|
||||
}
|
||||
|
||||
User.setUserField = function(uid, field, value) {
|
||||
RDB.hset('user:' + uid, field, value);
|
||||
User.setUserField = function(uid, field, value, callback) {
|
||||
RDB.hset('user:' + uid, field, value, callback);
|
||||
}
|
||||
|
||||
User.setUserFields = function(uid, data) {
|
||||
@@ -345,7 +360,6 @@ var utils = require('./../public/src/utils.js'),
|
||||
async.eachSeries(uids, iterator, function(err) {
|
||||
callback(err, data);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -671,6 +671,7 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
|
||||
if(err) {
|
||||
winston.err(err);
|
||||
} else {
|
||||
data = user.filterBannedUsers(data);
|
||||
callback({users:data});
|
||||
}
|
||||
});
|
||||
@@ -704,14 +705,27 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('api:admin.user.banUser', function(theirid) {
|
||||
if(uid && uid > 0) {
|
||||
admin.user.banUser(uid, theirid, socket);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('api:admin.user.unbanUser', function(theirid) {
|
||||
if(uid && uid > 0) {
|
||||
admin.user.unbanUser(uid, theirid, socket);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('api:admin.user.search', function(username) {
|
||||
if(uid && uid > 0) {
|
||||
user.search(username, function(data) {
|
||||
data = user.filterBannedUsers(data);
|
||||
socket.emit('api:admin.user.search', data);
|
||||
});
|
||||
}
|
||||
else
|
||||
} else {
|
||||
socket.emit('api:admin.user.search', null);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('api:admin.themes.getInstalled', function(callback) {
|
||||
|
||||
Reference in New Issue
Block a user