You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.9 KiB
JavaScript

'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, '&#37;').replace(/,/g, '&#44;');
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);
};
};