blocks WIP

v1.18.x
Baris Usakli 7 years ago
parent e8a3c23d42
commit 584f88e092

@ -17,7 +17,8 @@ define('forum/account/blocks', ['forum/account/header', 'autocomplete'], functio
$('.block-edit').on('click', '[data-action="toggle"]', function () {
var uid = parseInt(this.getAttribute('data-uid'), 10);
socket.emit('user.toggleBlock', {
uid: uid,
blockeeUid: uid,
blockerUid: ajaxify.data.uid,
}, Blocks.refreshList);
});
};

@ -210,16 +210,16 @@ module.exports = function (SocketUser) {
SocketUser.toggleBlock = function (socket, data, callback) {
async.waterfall([
function (next) {
user.blocks.can(data.uid, next);
user.blocks.can(socket.uid, data.blockerUid, data.blockeeUid, next);
},
function (can, next) {
if (!can) {
return next(new Error('[[error:cannot-block-privileged]]'));
}
user.blocks.is(data.uid, socket.uid, next);
user.blocks.is(data.blockeeUid, data.blockerUid, next);
},
function (is, next) {
user.blocks[is ? 'remove' : 'add'](data.uid, socket.uid, next);
user.blocks[is ? 'remove' : 'add'](data.blockeeUid, data.blockerUid, next);
},
], callback);
};

@ -2,40 +2,46 @@
var async = require('async');
var db = require('../database');
var LRU = require('lru-cache');
module.exports = function (User) {
User.blocks = {
_cache: LRU({
max: 100,
length: function () { return 1; },
maxAge: 0,
}),
};
User.blocks = {};
User.blocks.is = function (targetUid, uid, callback) {
User.blocks.list(uid, function (err, blocks) {
callback(err, blocks.includes(parseInt(targetUid, 10)));
});
db.isSortedSetMember('uid:' + uid + ':blocked_uids', String(targetUid), callback);
};
User.blocks.can = function (uid, callback) {
User.blocks.can = function (callerUid, blockerUid, blockeeUid, callback) {
// Administrators and global moderators cannot be blocked
User.isAdminOrGlobalMod(uid, (err, can) => callback(err, !can));
async.waterfall([
function (next) {
async.parallel({
isCallerAdminOrMod: function (next) {
User.isAdminOrGlobalMod(callerUid, next);
},
isBlockeeAdminOrMod: function (next) {
User.isAdminOrGlobalMod(blockeeUid, next);
},
}, next);
},
function (results, next) {
if (results.isBlockeeAdminOrMod) {
return callback(null, false);
}
if (parseInt(callerUid, 10) !== parseInt(blockerUid, 10) && !results.isCallerAdminOrMod) {
return callback(null, false);
}
next(null, true);
},
], callback);
};
User.blocks.list = function (uid, callback) {
if (User.blocks._cache.has(uid)) {
return setImmediate(callback, null, User.blocks._cache.get(uid));
}
db.getSortedSetRange('uid:' + uid + ':blocked_uids', 0, -1, function (err, blocked) {
if (err) {
return callback(err);
}
blocked = blocked.map(uid => parseInt(uid, 10)).filter(Boolean);
User.blocks._cache.set(uid, blocked);
callback(null, blocked);
});
};
@ -45,11 +51,6 @@ module.exports = function (User) {
async.apply(this.applyChecks, true, targetUid, uid),
async.apply(db.sortedSetAdd.bind(db), 'uid:' + uid + ':blocked_uids', Date.now(), targetUid),
async.apply(User.incrementUserFieldBy, uid, 'blocksCount', 1),
function (_blank, next) {
User.blocks._cache.del(uid);
setImmediate(next);
},
async.apply(User.blocks.list, uid),
], callback);
};
@ -58,11 +59,6 @@ module.exports = function (User) {
async.apply(this.applyChecks, false, targetUid, uid),
async.apply(db.sortedSetRemove.bind(db), 'uid:' + uid + ':blocked_uids', targetUid),
async.apply(User.decrementUserFieldBy, uid, 'blocksCount', 1),
function (_blank, next) {
User.blocks._cache.del(uid);
setImmediate(next);
},
async.apply(User.blocks.list, uid),
], callback);
};
@ -77,11 +73,14 @@ module.exports = function (User) {
};
User.blocks.filterUids = function (targetUid, uids, callback) {
async.filter(uids, function (uid, next) {
User.blocks.is(targetUid, uid, function (err, blocked) {
next(err, !blocked);
});
}, callback);
const sets = uids.map(uid => 'uid:' + uid + ':blocked_uids');
db.isMemberOfSortedSets(sets, targetUid, function (err, isMembers) {
if (err) {
return callback(err);
}
uids = uids.filter((uid, index) => isMembers[index]);
callback(null, uids);
});
};
User.blocks.filter = function (uid, property, set, callback) {

@ -1797,6 +1797,30 @@ describe('User', function () {
});
});
describe('.toggle()', function () {
it('should toggle block', function (done) {
socketUser.toggleBlock({ uid: 1 }, { blockerUid: 1, blockeeUid: blockeeUid }, function (err) {
assert.ifError(err);
User.blocks.is(blockeeUid, 1, function (err, blocked) {
assert.ifError(err);
assert(blocked);
done();
});
});
});
it('should toggle block', function (done) {
socketUser.toggleBlock({ uid: 1 }, { blockerUid: 1, blockeeUid: blockeeUid }, function (err) {
assert.ifError(err);
User.blocks.is(blockeeUid, 1, function (err, blocked) {
assert.ifError(err);
assert(!blocked);
done();
});
});
});
});
describe('.add()', function () {
it('should block a uid', function (done) {
User.blocks.add(blockeeUid, 1, function (err, blocked_uids) {

Loading…
Cancel
Save