'use strict'; var async = require('async'); var S = require('string'); var user = require('../../user'); var groups = require('../../groups'); var posts = require('../../posts'); var topics = require('../../topics'); var privileges = require('../../privileges'); var notifications = require('../../notifications'); var plugins = require('../../plugins'); var meta = require('../../meta'); var utils = require('../../utils'); module.exports = function (SocketPosts) { SocketPosts.flag = function (socket, data, callback) { if (!socket.uid) { return callback(new Error('[[error:not-logged-in]]')); } if (!data || !data.pid || !data.reason) { return callback(new Error('[[error:invalid-data]]')); } var flaggingUser = {}; var post; async.waterfall([ function (next) { posts.getPostFields(data.pid, ['pid', 'tid', 'uid', 'content', 'deleted'], next); }, function (postData, next) { if (parseInt(postData.deleted, 10) === 1) { return next(new Error('[[error:post-deleted]]')); } post = postData; topics.getTopicFields(post.tid, ['title', 'cid'], next); }, function (topicData, next) { post.topic = topicData; async.parallel({ isAdminOrMod: function (next) { privileges.categories.isAdminOrMod(post.topic.cid, socket.uid, next); }, userData: function (next) { user.getUserFields(socket.uid, ['username', 'reputation', 'banned'], next); }, }, next); }, function (user, next) { var minimumReputation = utils.isNumber(meta.config['privileges:flag']) ? parseInt(meta.config['privileges:flag'], 10) : 1; if (!user.isAdminOrMod && parseInt(user.userData.reputation, 10) < minimumReputation) { return next(new Error('[[error:not-enough-reputation-to-flag]]')); } if (parseInt(user.banned, 10) === 1) { return next(new Error('[[error:user-banned]]')); } flaggingUser = user.userData; flaggingUser.uid = socket.uid; posts.flag(post, socket.uid, data.reason, next); }, function (next) { async.parallel({ post: function (next) { posts.parsePost(post, next); }, admins: function (next) { groups.getMembers('administrators', 0, -1, next); }, globalMods: function (next) { groups.getMembers('Global Moderators', 0, -1, next); }, moderators: function (next) { groups.getMembers('cid:' + post.topic.cid + ':privileges:mods', 0, -1, next); }, }, next); }, function (results, next) { var title = S(post.topic.title).decodeHTMLEntities().s; var titleEscaped = title.replace(/%/g, '%').replace(/,/g, ','); notifications.create({ bodyShort: '[[notifications:user_flagged_post_in, ' + flaggingUser.username + ', ' + titleEscaped + ']]', bodyLong: post.content, pid: data.pid, path: '/post/' + data.pid, nid: 'post_flag:' + data.pid + ':uid:' + socket.uid, from: socket.uid, mergeId: 'notifications:user_flagged_post_in|' + data.pid, topicTitle: post.topic.title, }, function (err, notification) { if (err || !notification) { return next(err); } plugins.fireHook('action:post.flag', { post: post, reason: data.reason, flaggingUser: flaggingUser }); notifications.push(notification, results.admins.concat(results.moderators).concat(results.globalMods), next); }); }, ], callback); }; SocketPosts.dismissFlag = function (socket, pid, callback) { if (!pid || !socket.uid) { return callback(new Error('[[error:invalid-data]]')); } async.waterfall([ function (next) { user.isAdminOrGlobalMod(socket.uid, next); }, function (isAdminOrGlobalModerator, next) { if (!isAdminOrGlobalModerator) { return next(new Error('[[no-privileges]]')); } posts.dismissFlag(pid, next); }, ], callback); }; SocketPosts.dismissAllFlags = function (socket, data, callback) { async.waterfall([ function (next) { user.isAdminOrGlobalMod(socket.uid, next); }, function (isAdminOrGlobalModerator, next) { if (!isAdminOrGlobalModerator) { return next(new Error('[[no-privileges]]')); } posts.dismissAllFlags(next); }, ], callback); }; SocketPosts.updateFlag = function (socket, data, callback) { if (!data || !(data.pid && data.data)) { return callback(new Error('[[error:invalid-data]]')); } var payload = {}; async.waterfall([ function (next) { async.parallel([ async.apply(user.isAdminOrGlobalMod, socket.uid), async.apply(user.isModeratorOfAnyCategory, socket.uid), ], function (err, results) { next(err, results[0] || results[1]); }); }, function (allowed, next) { if (!allowed) { return next(new Error('[[no-privileges]]')); } // Translate form data into object payload = data.data.reduce(function (memo, cur) { memo[cur.name] = cur.value; return memo; }, payload); posts.updateFlagData(socket.uid, data.pid, payload, next); }, ], callback); }; };