diff --git a/graph/mutators/comment.js b/graph/mutators/comment.js index c815dc51e..31072d98f 100644 --- a/graph/mutators/comment.js +++ b/graph/mutators/comment.js @@ -293,7 +293,16 @@ const setStatus = async (ctx, { id, status }) => { */ const editComment = async ( ctx, - { id, asset_id, edit: { body, metadata = {} } } + { + id, + asset_id, + edit: { + body, + metadata = {}, + status: commentStatus, + actions: commentActions = [], + }, + } ) => { const { connectors: { @@ -303,7 +312,13 @@ const editComment = async ( // Build up the new comment we're setting. We need to check this with // moderation now. - let comment = { id, asset_id, body }; + let comment = { + id, + asset_id, + body, + status: commentStatus, + actions: commentActions, + }; // Determine the new status of the comment. const { actions, status } = await Moderation.process(ctx, comment); diff --git a/plugins/talk-plugin-akismet/server/hooks.js b/plugins/talk-plugin-akismet/server/hooks.js index 4e24af4b3..3e7eba83a 100644 --- a/plugins/talk-plugin-akismet/server/hooks.js +++ b/plugins/talk-plugin-akismet/server/hooks.js @@ -25,85 +25,104 @@ let enabled = true; // } // }); +async function checkForSpam(ctx, { asset_id, body }) { + const req = ctx.parent.parent; + const loaders = ctx.loaders; + + //If the key validation failed, then we can't run with the client. + if (!enabled) { + debug('not enabled, passing'); + return; + } + + let spam = false; + try { + const user_ip = get(req, 'ip', false); + if (!user_ip) { + debug('no ip on request'); + return; + } + + // Get some headers from the request. + const user_agent = req.get('User-Agent'); + if (!user_agent || user_agent.length === 0) { + debug('no user agent on request'); + return; + } + + const referrer = req.get('Referrer'); + if (!referrer || referrer.length === 0) { + debug('no referrer on request'); + return; + } + + // Get the Asset that the comment is being made against. + const asset = await loaders.Assets.getByID.load(asset_id); + if (!asset) { + debug('asset not found for new comment'); + return; + } + + // Send off the comment to Akismet to check to see what they say. + spam = await client.checkSpam({ + user_ip, + user_agent, + referrer, + permalink: asset.url, + comment_type: 'comment', + comment_content: body, + is_test: false, + }); + + debug(`comment analyzed as ${spam ? 'being' : 'not being'} spam`); + + return spam; + } catch (err) { + console.trace(err); + return; + } +} + +function handlePositiveSpam(input) { + // Attach reason information for the flag being added. + input.status = 'SYSTEM_WITHHELD'; + input.actions = + input.actions && input.actions.length >= 0 ? input.actions : []; + input.actions.push({ + action_type: 'FLAG', + user_id: null, + group_id: 'SPAM_COMMENT', + metadata: {}, + }); +} + module.exports = { RootMutation: { - createComment: { - async pre(_, { input }, ctx) { - const req = ctx.parent.parent; - const loaders = ctx.loaders; - - //If the key validation failed, then we can't run with the client. - if (!enabled) { - debug('not enabled, passing'); - return; + editComment: { + pre: async (_, { asset_id, edit: { body }, edit }, ctx) => { + const spam = await checkForSpam(ctx, { asset_id, body }); + if (spam) { + // Mark the comment as positive spam. + handlePositiveSpam(edit); } - - let spam = false; - try { - const user_ip = get(req, 'ip', false); - if (!user_ip) { - debug('no ip on request'); - return; + }, + }, + createComment: { + pre: async (_, { input }, ctx) => { + const spam = await checkForSpam(ctx, input); + if (spam) { + if (input.checkSpam) { + throw new ErrSpam(); } - // Get some headers from the request. - const user_agent = req.get('User-Agent'); - if (!user_agent || user_agent.length === 0) { - debug('no user agent on request'); - return; - } - - const referrer = req.get('Referrer'); - if (!referrer || referrer.length === 0) { - debug('no referrer on request'); - return; - } - - // Get the Asset that the comment is being made against. - const asset = await loaders.Assets.getByID.load(input.asset_id); - if (!asset) { - debug('asset not found for new comment'); - return; - } - - // Send off the comment to Akismet to check to see what they say. - spam = await client.checkSpam({ - user_ip, - user_agent, - referrer, - permalink: asset.url, - comment_type: 'comment', - comment_content: input.body, - is_test: false, - }); - - debug(`comment analyzed as ${spam ? 'being' : 'not being'} spam`); - } catch (err) { - console.trace(err); - return; + // Mark the comment as positive spam. + handlePositiveSpam(input); } // Attach scores to metadata. input.metadata = merge({}, input.metadata || {}, { akismet: spam, }); - - if (spam) { - if (input.checkSpam) { - throw new ErrSpam(); - } - - // Attach reason information for the flag being added. - input.status = 'SYSTEM_WITHHELD'; - input.actions = - input.actions && input.actions.length >= 0 ? input.actions : []; - input.actions.push({ - action_type: 'FLAG', - user_id: null, - group_id: 'SPAM_COMMENT', - metadata: {}, - }); - } }, }, }, diff --git a/plugins/talk-plugin-toxic-comments/server/hooks.js b/plugins/talk-plugin-toxic-comments/server/hooks.js index d35b5cc20..be9fbb68a 100644 --- a/plugins/talk-plugin-toxic-comments/server/hooks.js +++ b/plugins/talk-plugin-toxic-comments/server/hooks.js @@ -1,40 +1,59 @@ const { getScores, isToxic } = require('./perspective'); const { ErrToxic } = require('./errors'); +function handlePositiveToxic(input) { + input.status = 'SYSTEM_WITHHELD'; + input.actions = + input.actions && input.actions.length >= 0 ? input.actions : []; + input.actions.push({ + action_type: 'FLAG', + user_id: null, + group_id: 'TOXIC_COMMENT', + metadata: {}, + }); +} + +async function getScore(body) { + // Try getting scores. + let scores; + try { + scores = await getScores(body); + } catch (err) { + // Warn and let mutation pass. + console.trace(err); // TODO: log/handle this differently? + return; + } + + return scores; +} + module.exports = { RootMutation: { + editComment: { + pre: async (_, { edit: { body }, edit }) => { + const scores = await getScore(body); + if (isToxic(scores)) { + handlePositiveToxic(edit); + } + }, + }, createComment: { async pre(_, { input }, _context, _info) { - // Try getting scores. - let scores; - try { - scores = await getScores(input.body); - } catch (err) { - // Warn and let mutation pass. - console.trace(err); // TODO: log/handle this differently? - return; - } - - // Attach scores to metadata. - input.metadata = Object.assign({}, input.metadata, { - perspective: scores, - }); + const scores = await getScore(input.body); if (isToxic(scores)) { if (input.checkToxicity) { throw new ErrToxic(); } - input.status = 'SYSTEM_WITHHELD'; - input.actions = - input.actions && input.actions.length >= 0 ? input.actions : []; - input.actions.push({ - action_type: 'FLAG', - user_id: null, - group_id: 'TOXIC_COMMENT', - metadata: {}, - }); + // Mark the comment as positive toxic. + handlePositiveToxic(input); } + + // Attach scores to metadata. + input.metadata = Object.assign({}, input.metadata, { + perspective: scores, + }); }, }, },