From 8b71175c4658df5c24fb95b59f83928698c1f540 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 4 Dec 2017 09:27:56 -0700 Subject: [PATCH] adjusted logic flow for comment flags --- graph/mutators/action.js | 107 ++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 30 deletions(-) diff --git a/graph/mutators/action.js b/graph/mutators/action.js index 93806ced9..1ef9014a8 100644 --- a/graph/mutators/action.js +++ b/graph/mutators/action.js @@ -1,28 +1,72 @@ -const ActionsService = require('../../services/actions'); -const UsersService = require('../../services/users'); const errors = require('../../errors'); const {CREATE_ACTION, DELETE_ACTION} = require('../../perms/constants'); +/** + * getActionItem will return the item that is associated with the given action. + * If it does not exist, it will throw an error. + * + * @param {Object} ctx the graphql context for the request + * @param {Object} action the action being performed + * @return {Promise} resolves to the referenced item + */ +const getActionItem = async (ctx, {item_id, item_type}) => { + const { + loaders: { + Comments, + Users, + }, + } = ctx; + + if (item_type === 'COMMENTS') { + const comment = await Comments.get.load(item_id); + if (!comment) { + throw errors.ErrNotFound; + } + + return comment; + } else if (item_type === 'USERS') { + const user = await Users.getByID.load(item_id); + if (!user) { + throw errors.ErrNotFound; + } + + return user; + } +}; + /** * Creates an action on a item. If the item is a user flag, sets the user's status to * pending. - * @param {Object} user the user performing the request - * @param {String} item_id id of the item to add the action to - * @param {String} item_type type of the item - * @param {String} action_type type of the action - * @return {Promise} resolves to the action created + * + * @param {Object} ctx the graphql context for the request + * @param {Object} action the action being created + * @return {Promise} resolves to the action created */ -const createAction = async ({user = {}, pubsub, loaders: {Comments}}, {item_id, item_type, action_type, group_id, metadata = {}}) => { +const createAction = async (ctx, {item_id, item_type, action_type, group_id, metadata = {}}) => { + const { + user = {}, + pubsub, + connectors: { + services: { + Actions, + }, + }, + } = ctx; - let comment; - if (item_type === 'COMMENTS') { - comment = await Comments.get.load(item_id); - if (!comment) { - throw new Error('Comment not found'); + // Gets the item referenced by the action. + const item = await getActionItem(ctx, {item_id, item_type}); + + if (action_type === 'FLAG' && item_type === 'USERS') { + + // The item is a user, and this is a flag. Check to see if they are staff, + // if they are, don't permit the flag. + if (item.isStaff()) { + throw errors.ErrNotAuthorized; } } - let action = await ActionsService.create({ + // Create the action itself. + let action = await Actions.create({ item_id, item_type, user_id: user.id, @@ -31,17 +75,11 @@ const createAction = async ({user = {}, pubsub, loaders: {Comments}}, {item_id, metadata }); - if (item_type === 'USERS' && action_type === 'FLAG') { + if (action_type === 'FLAG' && item_type === 'COMMENTS') { - // Set the user as pending if it was a user flag and user has no Admin, Staff or Moderation roles - let user = await UsersService.findById(item_id); - if(!user.isStaff()){ - await UsersService.setStatus(item_id, 'PENDING'); - } - } - - if (comment) { - pubsub.publish('commentFlagged', comment); + // The item is a comment, and this is a flag. Push that the comment was + // flagged, don't wait for it to finish. + pubsub.publish('commentFlagged', item); } return action; @@ -53,16 +91,25 @@ const createAction = async ({user = {}, pubsub, loaders: {Comments}}, {item_id, * @param {String} id the id of the action to delete * @return {Promise} resolves to the deleted action, or null if not found. */ -const deleteAction = ({user}, {id}) => { - return ActionsService.delete({id, user_id: user.id}); +const deleteAction = (ctx, {id}) => { + const { + user, + connectors: { + services: { + Actions, + }, + }, + } = ctx; + + return Actions.delete({id, user_id: user.id}); }; -module.exports = (context) => { - if (context.user && context.user.can(CREATE_ACTION, DELETE_ACTION)) { +module.exports = (ctx) => { + if (ctx.user && ctx.user.can(CREATE_ACTION, DELETE_ACTION)) { return { Action: { - create: (action) => createAction(context, action), - delete: (action) => deleteAction(context, action) + create: (action) => createAction(ctx, action), + delete: (action) => deleteAction(ctx, action) } }; }