mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-16 02:36:16 +01:00
closes #2458
This commit is contained in:
@@ -78,6 +78,16 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable)
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.reset-flags').on('click', function() {
|
||||||
|
var uids = getSelectedUids();
|
||||||
|
if (!uids.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.emit('admin.user.resetFlags', uids, done('Flags(s) reset!'));
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
$('.admin-user').on('click', function() {
|
$('.admin-user').on('click', function() {
|
||||||
var uids = getSelectedUids();
|
var uids = getSelectedUids();
|
||||||
if (!uids.length) {
|
if (!uids.length) {
|
||||||
|
|||||||
@@ -186,10 +186,23 @@ module.exports = function(db, module) {
|
|||||||
return callback(null, 0);
|
return callback(null, 0);
|
||||||
}
|
}
|
||||||
db.collection('objects').findOne({_key: key}, {_id: 0}, function(err, data) {
|
db.collection('objects').findOne({_key: key}, {_id: 0}, function(err, data) {
|
||||||
return callback(err, data ? data.members.length : 0);
|
callback(err, data ? data.members.length : 0);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.setsCount = function(keys, callback) {
|
||||||
|
module.getSetsMembers(keys, function(err, setsMembers) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var counts = setsMembers.map(function(members) {
|
||||||
|
return (members && members.length) || 0;
|
||||||
|
});
|
||||||
|
callback(null, counts);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.setRemoveRandom = function(key, callback) {
|
module.setRemoveRandom = function(key, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
db.collection('objects').findOne({_key:key}, function(err, data) {
|
db.collection('objects').findOne({_key:key}, function(err, data) {
|
||||||
|
|||||||
@@ -94,6 +94,14 @@ module.exports = function(redisClient, module) {
|
|||||||
redisClient.scard(key, callback);
|
redisClient.scard(key, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.setsCount = function(keys, callback) {
|
||||||
|
var multi = redisClient.multi();
|
||||||
|
for (var i=0; i<keys.length; ++i) {
|
||||||
|
multi.scard(keys[i]);
|
||||||
|
}
|
||||||
|
multi.exec(callback);
|
||||||
|
};
|
||||||
|
|
||||||
module.setRemoveRandom = function(key, callback) {
|
module.setRemoveRandom = function(key, callback) {
|
||||||
redisClient.spop(key, callback);
|
redisClient.spop(key, callback);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
var groups = require('../../groups'),
|
var db = require('../../database'),
|
||||||
|
groups = require('../../groups'),
|
||||||
user = require('../../user'),
|
user = require('../../user'),
|
||||||
events = require('../../events'),
|
events = require('../../events'),
|
||||||
websockets = require('../index'),
|
websockets = require('../index'),
|
||||||
@@ -104,6 +105,14 @@ User.resetLockouts = function(socket, uids, callback) {
|
|||||||
async.each(uids, user.auth.resetLockout, callback);
|
async.each(uids, user.auth.resetLockout, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
User.resetFlags = function(socket, uids, callback) {
|
||||||
|
if (!Array.isArray(uids)) {
|
||||||
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
user.resetFlags(uids, callback);
|
||||||
|
};
|
||||||
|
|
||||||
User.validateEmail = function(socket, uids, callback) {
|
User.validateEmail = function(socket, uids, callback) {
|
||||||
if (!Array.isArray(uids)) {
|
if (!Array.isArray(uids)) {
|
||||||
return callback(new Error('[[error:invalid-data]]'));
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
@@ -166,24 +175,42 @@ User.deleteUsers = function(socket, uids, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
User.search = function(socket, data, callback) {
|
User.search = function(socket, data, callback) {
|
||||||
user.search(data.query, data.type, function(err, data) {
|
user.search(data.query, data.type, function(err, searchData) {
|
||||||
function getEmail(userData, next) {
|
|
||||||
user.getUserField(userData.uid, 'email', function(err, email) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (!searchData.users.length) {
|
||||||
|
return callback(null, searchData);
|
||||||
}
|
}
|
||||||
|
|
||||||
userData.email = email;
|
var userData = searchData.users;
|
||||||
next();
|
var uids = userData.map(function(user) {
|
||||||
|
return user && user.uid;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
async.parallel({
|
||||||
|
users: function(next) {
|
||||||
|
user.getMultipleUserFields(uids, ['email'], next);
|
||||||
|
},
|
||||||
|
flagCounts: function(next) {
|
||||||
|
var sets = uids.map(function(uid) {
|
||||||
|
return 'uid:' + uid + ':flagged_by';
|
||||||
|
});
|
||||||
|
db.setsCount(sets, next);
|
||||||
|
}
|
||||||
|
}, function(err, results) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
async.each(data.users, getEmail, function(err) {
|
userData.forEach(function(user, index) {
|
||||||
callback(err, data);
|
if (user) {
|
||||||
|
user.email = (results.users[index] && results.users[index].email) || '';
|
||||||
|
user.flags = results.flagCounts[index] || 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
callback(null, searchData);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,4 +67,14 @@ module.exports = function(User) {
|
|||||||
db.sortedSetRemove('users:banned', uid, callback);
|
db.sortedSetRemove('users:banned', uid, callback);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
User.resetFlags = function(uids, callback) {
|
||||||
|
if (!Array.isArray(uids) || !uids.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var keys = uids.map(function(uid) {
|
||||||
|
return 'uid:' + uid + ':flagged_by';
|
||||||
|
});
|
||||||
|
db.deleteAll(keys, callback);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
<li><a href="#" class="ban-user"><i class="fa fa-fw fa-gavel"></i> Ban User</a></li>
|
<li><a href="#" class="ban-user"><i class="fa fa-fw fa-gavel"></i> Ban User</a></li>
|
||||||
<li><a href="#" class="unban-user"><i class="fa fa-fw fa-comment-o"></i> Unban User</a></li>
|
<li><a href="#" class="unban-user"><i class="fa fa-fw fa-comment-o"></i> Unban User</a></li>
|
||||||
<li><a href="#" class="reset-lockout"><i class="fa fa-fw fa-unlock"></i> Reset Lockout</a></li>
|
<li><a href="#" class="reset-lockout"><i class="fa fa-fw fa-unlock"></i> Reset Lockout</a></li>
|
||||||
|
<li><a href="#" class="reset-flags"><i class="fa fa-fw fa-flag"></i> Reset Flags</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="#" class="delete-user"><i class="fa fa-fw fa-trash-o"></i> Delete User</a></li>
|
<li><a href="#" class="delete-user"><i class="fa fa-fw fa-trash-o"></i> Delete User</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -43,22 +44,19 @@
|
|||||||
|
|
||||||
<i class="fa fa-spinner fa-spin hidden"></i>
|
<i class="fa fa-spinner fa-spin hidden"></i>
|
||||||
<span id="user-notfound-notify" class="label label-danger hide">User not found!</span><br/>
|
<span id="user-notfound-notify" class="label label-danger hide">User not found!</span><br/>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<ul id="users-container">
|
<ul id="users-container">
|
||||||
<!-- BEGIN users -->
|
<!-- BEGIN users -->
|
||||||
<div class="users-box" data-uid="{users.uid}" data-username="{users.username}">
|
<div class="users-box" data-uid="{users.uid}" data-username="{users.username}">
|
||||||
<div class="user-image">
|
<div class="user-image">
|
||||||
<img src="{users.picture}" class="img-thumbnail user-selectable"/>
|
<img src="{users.picture}" class="img-thumbnail user-selectable"/>
|
||||||
<div class="labels">
|
<div class="labels">
|
||||||
<!-- IF requireEmailConfirmation -->
|
<!-- IF config.requireEmailConfirmation -->
|
||||||
<!-- IF !users.email:confirmed -->
|
<!-- IF !users.email:confirmed -->
|
||||||
<span class="notvalidated label label-danger">Not Validated</span>
|
<span class="notvalidated label label-danger">Not Validated</span>
|
||||||
<!-- ENDIF !users.email:confirmed -->
|
<!-- ENDIF !users.email:confirmed -->
|
||||||
<!-- ENDIF requireEmailConfirmation -->
|
<!-- ENDIF config.requireEmailConfirmation -->
|
||||||
<span class="administrator label label-primary <!-- IF !users.administrator -->hide<!-- ENDIF !users.administrator -->">Admin</span>
|
<span class="administrator label label-primary <!-- IF !users.administrator -->hide<!-- ENDIF !users.administrator -->">Admin</span>
|
||||||
<span class="ban label label-danger <!-- IF !users.banned -->hide<!-- ENDIF !users.banned -->">Banned</span>
|
<span class="ban label label-danger <!-- IF !users.banned -->hide<!-- ENDIF !users.banned -->">Banned</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,6 +66,9 @@
|
|||||||
<!-- IF users.email -->
|
<!-- IF users.email -->
|
||||||
<small><span title="{users.email}">{users.email}</span></small>
|
<small><span title="{users.email}">{users.email}</span></small>
|
||||||
<!-- ENDIF users.email -->
|
<!-- ENDIF users.email -->
|
||||||
|
<!-- IF users.flags -->
|
||||||
|
<div><small><span><i class="fa fa-flag"></i> {users.flags}</span></small></div>
|
||||||
|
<!-- ENDIF users.flags -->
|
||||||
</div>
|
</div>
|
||||||
<!-- END users -->
|
<!-- END users -->
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user