mirror of
https://github.com/wassname/talk.git
synced 2026-09-09 11:38:08 +08:00
First draft of toxic-comments
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
const {
|
||||
GraphQLObjectType,
|
||||
GraphQLInterfaceType
|
||||
} = require('graphql');
|
||||
const {maskErrors} = require('graphql-errors');
|
||||
const errors = require('../errors');
|
||||
const {Error: {ValidationError}} = require('mongoose');
|
||||
|
||||
// This function is pretty much copied verbatim from the graphql-tools repo:
|
||||
// https://github.com/apollographql/graphql-tools/blob/b12973c86e00be209d04af0184780998056051c4/src/schemaGenerator.ts#L180-L194
|
||||
const forEachField = (schema, fn) => {
|
||||
const typeMap = schema.getTypeMap();
|
||||
Object.keys(typeMap).forEach((typeName) => {
|
||||
const type = typeMap[typeName];
|
||||
|
||||
if (type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) {
|
||||
const fields = type.getFields();
|
||||
Object.keys(fields).forEach((fieldName) => {
|
||||
const field = fields[fieldName];
|
||||
fn(field, typeName, fieldName);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// If an APIError happens in a mutation, then respond with `{errors: Array}`
|
||||
// according to the schema.
|
||||
const decorateWithMutationErrorHandler = (field) => {
|
||||
const fieldResolver = field.resolve;
|
||||
field.resolve = async (obj, args, ctx, info) => {
|
||||
try {
|
||||
return await fieldResolver(obj, args, ctx, info);
|
||||
}
|
||||
catch(err) {
|
||||
if (err instanceof errors.APIError) {
|
||||
return {
|
||||
errors: [err]
|
||||
};
|
||||
} else if (err instanceof ValidationError) {
|
||||
|
||||
// TODO: wrap this with one of our internal errors.
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Masks errors during production and handle mutation errors inside the schema.
|
||||
const decorateWithErrorHandler = (schema) => {
|
||||
forEachField(schema, (field, typeName) => {
|
||||
|
||||
// Handle mutation errors.
|
||||
if (typeName === 'RootMutation') {
|
||||
decorateWithMutationErrorHandler(field);
|
||||
}
|
||||
|
||||
// If we are in production mode, don't show server errors to the front end.
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
|
||||
// Mask errors that are thrown if we are in a production environment.
|
||||
maskErrors(field);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
decorateWithErrorHandler,
|
||||
};
|
||||
@@ -154,7 +154,7 @@ const adjustKarma = (Comments, id, status) => async () => {
|
||||
* @param {String} [status='NONE'] the status of the new comment
|
||||
* @return {Promise} resolves to the created comment
|
||||
*/
|
||||
const createComment = async (context, {tags = [], body, asset_id, parent_id = null}, status = 'NONE') => {
|
||||
const createComment = async (context, {tags = [], body, asset_id, parent_id = null, metadata = {}}, status = 'NONE') => {
|
||||
const {user, loaders: {Comments}, pubsub} = context;
|
||||
|
||||
// Resolve the tags for the comment.
|
||||
@@ -166,7 +166,8 @@ const createComment = async (context, {tags = [], body, asset_id, parent_id = nu
|
||||
parent_id,
|
||||
status,
|
||||
tags,
|
||||
author_id: user.id
|
||||
author_id: user.id,
|
||||
metadata,
|
||||
});
|
||||
|
||||
// If the loaders are present, clear the caches for these values because we
|
||||
|
||||
@@ -1,35 +1,41 @@
|
||||
const wrapResponse = require('../helpers/response');
|
||||
|
||||
const RootMutation = {
|
||||
createComment(_, {comment}, {mutators: {Comment}}) {
|
||||
return wrapResponse('comment')(Comment.create(comment));
|
||||
async createComment(_, {input}, {mutators: {Comment}}) {
|
||||
return {
|
||||
comment: await Comment.create(input),
|
||||
};
|
||||
},
|
||||
editComment(_, {id, asset_id, edit: {body}}, {mutators: {Comment}}) {
|
||||
return wrapResponse('comment')(Comment.edit({id, asset_id, edit: {body}}));
|
||||
async editComment(_, {id, asset_id, edit: {body}}, {mutators: {Comment}}) {
|
||||
return {
|
||||
comment: await Comment.edit({id, asset_id, edit: {body}}),
|
||||
};
|
||||
},
|
||||
createFlag(_, {flag: {item_id, item_type, reason, message}}, {mutators: {Action}}) {
|
||||
return wrapResponse('flag')(Action.create({item_id, item_type, action_type: 'FLAG', group_id: reason, metadata: {message}}));
|
||||
async createFlag(_, {flag: {item_id, item_type, reason, message}}, {mutators: {Action}}) {
|
||||
return {
|
||||
flag: Action.create({item_id, item_type, action_type: 'FLAG', group_id: reason, metadata: {message}}),
|
||||
};
|
||||
},
|
||||
createDontAgree(_, {dontagree: {item_id, item_type, reason, message}}, {mutators: {Action}}) {
|
||||
return wrapResponse('dontagree')(Action.create({item_id, item_type, action_type: 'DONTAGREE', group_id: reason, metadata: {message}}));
|
||||
async createDontAgree(_, {dontagree: {item_id, item_type, reason, message}}, {mutators: {Action}}) {
|
||||
return {
|
||||
dontagree: await Action.create({item_id, item_type, action_type: 'DONTAGREE', group_id: reason, metadata: {message}}),
|
||||
};
|
||||
},
|
||||
deleteAction(_, {id}, {mutators: {Action}}) {
|
||||
return wrapResponse(null)(Action.delete({id}));
|
||||
async deleteAction(_, {id}, {mutators: {Action}}) {
|
||||
await Action.delete({id});
|
||||
},
|
||||
setUserStatus(_, {id, status}, {mutators: {User}}) {
|
||||
return wrapResponse(null)(User.setUserStatus({id, status}));
|
||||
async setUserStatus(_, {id, status}, {mutators: {User}}) {
|
||||
await User.setUserStatus({id, status});
|
||||
},
|
||||
suspendUser(_, {input: {id, message, until}}, {mutators: {User}}) {
|
||||
return wrapResponse(null)(User.suspendUser({id, message, until}));
|
||||
async suspendUser(_, {input: {id, message, until}}, {mutators: {User}}) {
|
||||
await User.suspendUser({id, message, until});
|
||||
},
|
||||
rejectUsername(_, {input: {id, message}}, {mutators: {User}}) {
|
||||
return wrapResponse(null)(User.rejectUsername({id, message}));
|
||||
async rejectUsername(_, {input: {id, message}}, {mutators: {User}}) {
|
||||
await User.rejectUsername({id, message});
|
||||
},
|
||||
ignoreUser(_, {id}, {mutators: {User}}) {
|
||||
return wrapResponse(null)(User.ignoreUser({id}));
|
||||
async ignoreUser(_, {id}, {mutators: {User}}) {
|
||||
await User.ignoreUser({id});
|
||||
},
|
||||
stopIgnoringUser(_, {id}, {mutators: {User}}) {
|
||||
return wrapResponse(null)(User.stopIgnoringUser({id}));
|
||||
async stopIgnoringUser(_, {id}, {mutators: {User}}) {
|
||||
await User.stopIgnoringUser({id});
|
||||
},
|
||||
async setCommentStatus(_, {id, status}, {mutators: {Comment}, pubsub}) {
|
||||
const comment = await Comment.setStatus({id, status});
|
||||
@@ -42,19 +48,20 @@ const RootMutation = {
|
||||
// Publish the comment status change via the subscription.
|
||||
pubsub.publish('commentRejected', comment);
|
||||
}
|
||||
return wrapResponse(null)(comment);
|
||||
},
|
||||
addTag(_, {tag}, {mutators: {Tag}}) {
|
||||
return wrapResponse(null)(Tag.add(tag));
|
||||
async addTag(_, {tag}, {mutators: {Tag}}) {
|
||||
await Tag.add(tag);
|
||||
},
|
||||
removeTag(_, {tag}, {mutators: {Tag}}) {
|
||||
return wrapResponse(null)(Tag.remove(tag));
|
||||
async removeTag(_, {tag}, {mutators: {Tag}}) {
|
||||
await Tag.remove(tag);
|
||||
},
|
||||
createToken(_, {input}, {mutators: {Token}}) {
|
||||
return wrapResponse('token')(Token.create(input));
|
||||
async createToken(_, {input}, {mutators: {Token}}) {
|
||||
return {
|
||||
token: await Token.create(input),
|
||||
};
|
||||
},
|
||||
revokeToken(_, {input}, {mutators: {Token}}) {
|
||||
return wrapResponse(null)(Token.revoke(input));
|
||||
async revokeToken(_, {input}, {mutators: {Token}}) {
|
||||
await Token.revoke(input);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+3
-7
@@ -1,6 +1,6 @@
|
||||
const {makeExecutableSchema} = require('graphql-tools');
|
||||
const {maskErrors} = require('graphql-errors');
|
||||
const {decorateWithHooks} = require('./hooks');
|
||||
const {decorateWithErrorHandler} = require('./errorHandler');
|
||||
|
||||
const plugins = require('../services/plugins');
|
||||
const resolvers = require('./resolvers');
|
||||
@@ -11,11 +11,7 @@ const schema = makeExecutableSchema({typeDefs, resolvers});
|
||||
// Plugin to the schema level resolvers to provide an before/after hook.
|
||||
decorateWithHooks(schema, plugins.get('server', 'hooks'));
|
||||
|
||||
// If we are in production mode, don't show server errors to the front end.
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
|
||||
// Mask errors that are thrown if we are in a production environment.
|
||||
maskErrors(schema);
|
||||
}
|
||||
// Handle errors like masking in production and mutation errors.
|
||||
decorateWithErrorHandler(schema);
|
||||
|
||||
module.exports = schema;
|
||||
|
||||
@@ -1033,7 +1033,7 @@ type RevokeTokenResponse implements Response {
|
||||
type RootMutation {
|
||||
|
||||
# Creates a comment on the asset.
|
||||
createComment(comment: CreateCommentInput!): CreateCommentResponse
|
||||
createComment(input: CreateCommentInput!): CreateCommentResponse
|
||||
|
||||
# Creates a flag on an entity.
|
||||
createFlag(flag: CreateFlagInput!): CreateFlagResponse
|
||||
@@ -1060,10 +1060,10 @@ type RootMutation {
|
||||
setCommentStatus(id: ID!, status: COMMENT_STATUS!): SetCommentStatusResponse
|
||||
|
||||
# Add a tag.
|
||||
addTag(tag: ModifyTagInput!): ModifyTagResponse!
|
||||
addTag(tag: ModifyTagInput!): ModifyTagResponse
|
||||
|
||||
# Removes a tag.
|
||||
removeTag(tag: ModifyTagInput!): ModifyTagResponse!
|
||||
removeTag(tag: ModifyTagInput!): ModifyTagResponse
|
||||
|
||||
# Ignore comments by another user
|
||||
ignoreUser(id: ID!): IgnoreUserResponse
|
||||
@@ -1072,7 +1072,7 @@ type RootMutation {
|
||||
createToken(input: CreateTokenInput!): CreateTokenResponse!
|
||||
|
||||
# RevokeToken will revoke an existing token.
|
||||
revokeToken(input: RevokeTokenInput!): RevokeTokenResponse!
|
||||
revokeToken(input: RevokeTokenInput!): RevokeTokenResponse
|
||||
|
||||
# Stop Ignoring comments by another user
|
||||
stopIgnoringUser(id: ID!): StopIgnoringUserResponse
|
||||
|
||||
Reference in New Issue
Block a user