diff --git a/public/src/client/topic/votes.js b/public/src/client/topic/votes.js index 2ead12f80497..b4365697ed69 100644 --- a/public/src/client/topic/votes.js +++ b/public/src/client/topic/votes.js @@ -37,6 +37,9 @@ define('forum/topic/votes', [ socket.emit('posts.getUpvoters', [pid], function (err, data) { if (err) { + if (err.message === '[[error:no-privileges]]') { + return; + } return alerts.error(err); } if (_showTooltip[pid] && data.length) { @@ -98,7 +101,7 @@ define('forum/topic/votes', [ }; Votes.showVotes = function (pid) { - socket.emit('posts.getVoters', { pid: pid, cid: ajaxify.data.cid }, function (err, data) { + socket.emit('posts.getVoters', { pid: pid }, function (err, data) { if (err) { if (err.message === '[[error:no-privileges]]') { return; diff --git a/src/socket.io/posts/votes.js b/src/socket.io/posts/votes.js index 4c971efd82cc..3e1be2b5e397 100644 --- a/src/socket.io/posts/votes.js +++ b/src/socket.io/posts/votes.js @@ -10,14 +10,14 @@ const meta = require('../../meta'); module.exports = function (SocketPosts) { SocketPosts.getVoters = async function (socket, data) { - if (!data || !data.pid || !data.cid) { + if (!data || !data.pid) { throw new Error('[[error:invalid-data]]'); } - const showDownvotes = !meta.config['downvote:disabled']; - const canSeeVotes = meta.config.votesArePublic || await privileges.categories.isAdminOrMod(data.cid, socket.uid); - if (!canSeeVotes) { + const cid = await posts.getCidByPid(data.pid); + if (!await canSeeVotes(socket.uid, cid)) { throw new Error('[[error:no-privileges]]'); } + const showDownvotes = !meta.config['downvote:disabled']; const [upvoteUids, downvoteUids] = await Promise.all([ db.getSetMembers(`pid:${data.pid}:upvote`), showDownvotes ? db.getSetMembers(`pid:${data.pid}:downvote`) : [], @@ -42,21 +42,12 @@ module.exports = function (SocketPosts) { throw new Error('[[error:invalid-data]]'); } - const [cids, data, isAdmin] = await Promise.all([ - posts.getCidsByPids(pids), - posts.getUpvotedUidsByPids(pids), - privileges.users.isAdministrator(socket.uid), - ]); - - if (!isAdmin) { - const isAllowed = await privileges.categories.isUserAllowedTo( - 'topics:read', _.uniq(cids), socket.uid - ); - if (isAllowed.includes(false)) { - throw new Error('[[error:no-privileges]]'); - } + const cids = await posts.getCidsByPids(pids); + if ((await canSeeVotes(socket.uid, cids)).includes(false)) { + throw new Error('[[error:no-privileges]]'); } + const data = await posts.getUpvotedUidsByPids(pids); if (!data.length) { return []; } @@ -84,4 +75,23 @@ module.exports = function (SocketPosts) { ); return result; }; + + async function canSeeVotes(uid, cids) { + const isArray = Array.isArray(cids); + if (!isArray) { + cids = [cids]; + } + const [canRead, isAdmin, isMod] = await Promise.all([ + privileges.categories.isUserAllowedTo( + 'topics:read', _.uniq(cids), uid + ), + privileges.users.isAdministrator(uid), + privileges.users.isModerator(uid, cids), + ]); + + const checks = cids.map( + (cid, index) => isAdmin || isMod[index] || (canRead[index] && !!meta.config.votesArePublic) + ); + return isArray ? checks : checks[0]; + } };