diff --git a/src/privileges/posts.js b/src/privileges/posts.js index ed5fddf0ae..60ed7ed1d3 100644 --- a/src/privileges/posts.js +++ b/src/privileges/posts.js @@ -32,6 +32,7 @@ module.exports = function (privileges) { 'topics:read': async.apply(helpers.isUserAllowedTo, 'topics:read', uid, cids), read: async.apply(helpers.isUserAllowedTo, 'read', uid, cids), 'posts:edit': async.apply(helpers.isUserAllowedTo, 'posts:edit', uid, cids), + 'posts:history': async.apply(helpers.isUserAllowedTo, 'posts:history', uid, cids), 'posts:view_deleted': async.apply(helpers.isUserAllowedTo, 'posts:view_deleted', uid, cids), }, next); }, @@ -39,7 +40,8 @@ module.exports = function (privileges) { var privileges = pids.map(function (pid, i) { var isAdminOrMod = results.isAdmin || results.isModerator[i]; var editable = isAdminOrMod || (results.isOwner[i] && results['posts:edit'][i]); - var viewDeletedPosts = isAdminOrMod || (results.isOwner[i] && results['posts:view_deleted'][i]); + var viewDeletedPosts = isAdminOrMod || results.isOwner[i] || results['posts:view_deleted'][i]; + var viewHistory = isAdminOrMod || results.isOwner[i] || results['posts:history'][i]; return { editable: editable, @@ -48,6 +50,7 @@ module.exports = function (privileges) { isAdminOrMod: isAdminOrMod, 'topics:read': results['topics:read'][i] || isAdminOrMod, read: results.read[i] || isAdminOrMod, + 'posts:history': viewHistory, 'posts:view_deleted': viewDeletedPosts, }; }); diff --git a/src/socket.io/posts/diffs.js b/src/socket.io/posts/diffs.js index 2070a338e1..ef5c887dd7 100644 --- a/src/socket.io/posts/diffs.js +++ b/src/socket.io/posts/diffs.js @@ -7,11 +7,7 @@ var privileges = require('../../privileges'); module.exports = function (SocketPosts) { SocketPosts.getDiffs = function (socket, data, callback) { async.waterfall([ - function (next) { - privileges.posts.can('posts:history', data.pid, socket.uid, function (err, allowed) { - next(err || allowed ? null : new Error('[[error:no-privileges]]')); - }); - }, + async.apply(privilegeCheck, data.pid, socket.uid), function (next) { posts.diffs.list(data.pid, next); }, @@ -23,12 +19,29 @@ module.exports = function (SocketPosts) { }; SocketPosts.showPostAt = function (socket, data, callback) { - privileges.posts.can('posts:history', data.pid, socket.uid, function (err, allowed) { - if (err || !allowed) { - return callback(err || new Error('[[error:no-privileges]]')); + privilegeCheck(data.pid, socket.uid, function (err) { + if (err) { + return callback(err); } posts.diffs.load(data.pid, data.since, socket.uid, callback); }); }; + + function privilegeCheck(pid, uid, callback) { + async.parallel({ + deleted: async.apply(posts.getPostField, pid, 'deleted'), + privileges: async.apply(privileges.posts.get, [pid], uid), + }, function (err, payload) { + if (err) { + return callback(err); + } + + payload.deleted = parseInt(payload.deleted, 10); + payload.privileges = payload.privileges[0]; + + const allowed = payload.privileges['posts:history'] && (payload.deleted ? payload.privileges['posts:view_deleted'] : true); + callback(!allowed ? new Error('[[error:no-privileges]]') : null); + }); + } };