mirror of
https://github.com/wassname/talk.git
synced 2026-08-16 11:29:31 +08:00
Adjusted query/tag flow
This commit is contained in:
+140
-15
@@ -18,18 +18,25 @@ const Wordlist = require('../../services/wordlist');
|
||||
*/
|
||||
const createComment = ({user, loaders: {Comments}, pubsub}, {body, asset_id, parent_id = null}, status = 'NONE') => {
|
||||
|
||||
// Add the staff tag for comments created as a staff member.
|
||||
let tags = [];
|
||||
if (user.hasRoles('ADMIN') || user.hasRoles('MODERATOR')) {
|
||||
tags = [{
|
||||
tag: {
|
||||
name: 'STAFF'
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
return CommentsService.publicCreate({
|
||||
body,
|
||||
asset_id,
|
||||
parent_id,
|
||||
status,
|
||||
tags,
|
||||
author_id: user.id
|
||||
})
|
||||
.then(async (comment) => {
|
||||
|
||||
if (user.hasRoles('ADMIN') || user.hasRoles('MODERATOR')) {
|
||||
await CommentsService.addTag(comment.id, 'STAFF', user.id);
|
||||
}
|
||||
.then((comment) => {
|
||||
|
||||
// If the loaders are present, clear the caches for these values because we
|
||||
// just added a new comment, hence the counts should be updated. We should
|
||||
@@ -204,21 +211,139 @@ const setCommentStatus = ({user, loaders: {Comments}}, {id, status}) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a tag to a Comment
|
||||
* @param {String} id identifier of the comment (uuid)
|
||||
* @param {String} tag name of the tag
|
||||
* Adds a tag to a Comment.
|
||||
*/
|
||||
const addCommentTag = ({user, loaders: {Comments}}, {id, tag}) => {
|
||||
return CommentsService.addTag(id, tag, user.id);
|
||||
const addCommentTag = async ({user, loaders: {Assets, Comments, Settings}}, {id, asset_id, name}) => {
|
||||
|
||||
// If the current user does not have the ADMIN or MODERATOR role
|
||||
if (!user || !user.can('mutation:addCommentTag')) {
|
||||
throw errors.ErrNotAuthorized;
|
||||
}
|
||||
|
||||
// Load the settings from the dataloader, it will be cached if it was
|
||||
// retrieved already.
|
||||
let settings = await AssetsService.rectifySettings(AssetsService.findById(asset_id));
|
||||
|
||||
// Try to find the tag in the asset tags. This will contain the permission
|
||||
// information.
|
||||
let tag = settings.tags.find((globalTag) => {
|
||||
return globalTag.name === name && globalTag.models.include('COMMENTS');
|
||||
});
|
||||
|
||||
// Create the new tagLink that will be created to attach to the comment.
|
||||
let tagLink = {
|
||||
tag,
|
||||
assigned_by: user.id,
|
||||
created_at: new Date()
|
||||
};
|
||||
|
||||
// If the tag was found, we need to ensure that the current user can indeed
|
||||
// set this tag on the comment.
|
||||
if (tag) {
|
||||
|
||||
// If the tag has roles defined, and the current user has at least one of
|
||||
// the required roles, then add the tag without checking for ownership.
|
||||
if (tag.permissions && tag.permissions.roles && tag.permissions.roles.some((role) => user.roles.include(role))) {
|
||||
return CommentsService.addTag(id, tagLink, false);
|
||||
}
|
||||
|
||||
// If the permissions allow for self assignment, then ensure that the query
|
||||
// is compose with that in mind.
|
||||
if (tag.permissions && tag.permissions.self) {
|
||||
|
||||
// Otherwise, we assume that we have to check to see that the user indeed
|
||||
// owns the resource before allowing the tag to get added.
|
||||
return CommentsService.addTag(id, tagLink, true);
|
||||
}
|
||||
|
||||
throw errors.ErrNotAuthorized;
|
||||
}
|
||||
|
||||
// Only admin/moderators can add unique tags, these are tags that are not in
|
||||
// the global list.
|
||||
if (!(user.hasRoles('ADMIN') || user.hasRoles('MODERATOR'))) {
|
||||
throw errors.ErrNotAuthorized;
|
||||
}
|
||||
|
||||
// Generate the tag in the event now that we have to create the tag for this
|
||||
// specific comment.
|
||||
tagLink.tag = {
|
||||
name,
|
||||
permissions: {
|
||||
public: true,
|
||||
self: false,
|
||||
roles: []
|
||||
},
|
||||
models: ['COMMENTS'],
|
||||
created_at: new Date()
|
||||
};
|
||||
|
||||
// Actually attach the new tag that we created to the comment.
|
||||
return CommentsService.addTag(id, tagLink, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a tag from a Comment
|
||||
* @param {String} id identifier of the comment (uuid)
|
||||
* @param {String} tag name of the tag
|
||||
* Removes a tag from a Comment.
|
||||
*/
|
||||
const removeCommentTag = ({user, loaders: {Comments}}, {id, tag}) => {
|
||||
return CommentsService.removeTag(id, tag);
|
||||
const removeCommentTag = async ({user, loaders: {Comments}}, {id, asset_id, name}) => {
|
||||
|
||||
// If the current user does not have the ADMIN or MODERATOR role
|
||||
if (!user || !user.can('mutation:removeCommentTag')) {
|
||||
throw errors.ErrNotAuthorized;
|
||||
}
|
||||
|
||||
// Load the settings from the dataloader, it will be cached if it was
|
||||
// retrieved already.
|
||||
let settings = await AssetsService.rectifySettings(AssetsService.findById(asset_id));
|
||||
|
||||
// Try to find the tag in the asset tags. This will contain the permission
|
||||
// information.
|
||||
let tag = settings.tags.find((globalTag) => {
|
||||
return globalTag.name === name && globalTag.models.include('COMMENTS');
|
||||
});
|
||||
|
||||
// Create the new tagLink that will be created to attach to the comment.
|
||||
let tagLink = {
|
||||
tag,
|
||||
assigned_by: user.id
|
||||
};
|
||||
|
||||
// If the tag was found, we need to ensure that the current user can indeed
|
||||
// remove this tag on the comment.
|
||||
if (tag) {
|
||||
|
||||
// If the tag has roles defined, and the current user has at least one of
|
||||
// the required roles, then remove the tag without checking for ownership.
|
||||
if (tag.permissions && tag.permissions.roles && tag.permissions.roles.some((role) => user.roles.include(role))) {
|
||||
return CommentsService.removeTag(id, tagLink, false);
|
||||
}
|
||||
|
||||
// If the permissions allow for self assignment, then ensure that the query
|
||||
// is compose with that in mind.
|
||||
if (tag.permissions && tag.permissions.self) {
|
||||
|
||||
// Otherwise, we assume that we have to check to see that the user indeed
|
||||
// owns the resource before allowing the tag to get removed.
|
||||
return CommentsService.removeTag(id, tagLink, true);
|
||||
}
|
||||
|
||||
throw errors.ErrNotAuthorized;
|
||||
}
|
||||
|
||||
// Only admin/moderators can remove unique tags, these are tags that are not
|
||||
// in the global list.
|
||||
if (!(user.hasRoles('ADMIN') || user.hasRoles('MODERATOR'))) {
|
||||
throw errors.ErrNotAuthorized;
|
||||
}
|
||||
|
||||
// Generate the tag in the event now that we have to create the tag for this
|
||||
// specific comment.
|
||||
tagLink.tag = {
|
||||
name
|
||||
};
|
||||
|
||||
// Actually attach the new tag that we created to the comment.
|
||||
return CommentsService.removeTag(id, tagLink, false);
|
||||
};
|
||||
|
||||
module.exports = (context) => {
|
||||
|
||||
@@ -16,6 +16,8 @@ const RootMutation = require('./root_mutation');
|
||||
const RootQuery = require('./root_query');
|
||||
const Settings = require('./settings');
|
||||
const Subscription = require('./subscription');
|
||||
const TagLink = require('./tag_link');
|
||||
const Tag = require('./tag');
|
||||
const UserError = require('./user_error');
|
||||
const User = require('./user');
|
||||
const ValidationUserError = require('./validation_user_error');
|
||||
@@ -39,6 +41,8 @@ let resolvers = {
|
||||
RootQuery,
|
||||
Settings,
|
||||
Subscription,
|
||||
TagLink,
|
||||
Tag,
|
||||
UserError,
|
||||
User,
|
||||
ValidationUserError,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const wrapResponse = require('../helpers/response');
|
||||
const CommentsService = require('../../services/comments');
|
||||
|
||||
const RootMutation = {
|
||||
createComment(_, {comment}, {mutators: {Comment}}) {
|
||||
@@ -29,12 +28,12 @@ const RootMutation = {
|
||||
setCommentStatus(_, {id, status}, {mutators: {Comment}}) {
|
||||
return wrapResponse(null)(Comment.setCommentStatus({id, status}));
|
||||
},
|
||||
addCommentTag(_, {id, tag}, {mutators: {Comment}}) {
|
||||
return wrapResponse('comment')(Comment.addCommentTag({id, tag}).then(() => CommentsService.findById(id)));
|
||||
},
|
||||
removeCommentTag(_, {id, tag}, {mutators: {Comment}}) {
|
||||
return wrapResponse('comment')(Comment.removeCommentTag({id, tag}).then(() => CommentsService.findById(id)));
|
||||
addCommentTag(_, {id, asset_id, name}, {mutators: {Comment}}) {
|
||||
return wrapResponse('comment')(Comment.addCommentTag({id, asset_id, name}));
|
||||
},
|
||||
removeCommentTag(_, {id, asset_id, name}, {mutators: {Comment}}) {
|
||||
return wrapResponse('comment')(Comment.removeCommentTag({id, asset_id, name}));
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = RootMutation;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
const Tag = {
|
||||
|
||||
};
|
||||
|
||||
module.exports = Tag;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const TagLink = {
|
||||
assigned_by({assigned_by}, _, {user, loaders: {Users}}) {
|
||||
if (user && user.hasRole('ADMIN')) {
|
||||
return Users.getByID.load(assigned_by);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = TagLink;
|
||||
+26
-10
@@ -52,14 +52,30 @@ type User {
|
||||
status: USER_STATUS
|
||||
}
|
||||
|
||||
# Tag represents the underlying Tag that can be either stored in a global list
|
||||
# or added uniquely to the entity.
|
||||
type Tag {
|
||||
# the actual tag for the comment.
|
||||
id: String!
|
||||
|
||||
# the user that assigned the tag. If NULL then the system automatically tagged it.
|
||||
added_by: String
|
||||
# The actual name of the tag entry.
|
||||
name: String!
|
||||
|
||||
# the time when the tag was assigned.
|
||||
# The time that this Tag was created.
|
||||
created_at: Date!
|
||||
}
|
||||
|
||||
# TagLink is used to associate a given Tag with a Model via a TagLink.
|
||||
type TagLink {
|
||||
|
||||
# The underlying Tag that is either duplicated from the global list or created
|
||||
# uniquely for this specific model.
|
||||
tag: Tag!
|
||||
|
||||
# The user that assigned the tag. This TagLink could have been created by the
|
||||
# system, in which case this will be null. It could also be null if the
|
||||
# current user is not an Admin/Moderator.
|
||||
assigned_by: User
|
||||
|
||||
# The date that the TagLink was created.
|
||||
created_at: Date!
|
||||
}
|
||||
|
||||
@@ -176,7 +192,7 @@ type Comment {
|
||||
body: String!
|
||||
|
||||
# the tags on the comment
|
||||
tags: [Tag]
|
||||
tags: [TagLink!]
|
||||
|
||||
# the user who authored the comment.
|
||||
user: User
|
||||
@@ -702,15 +718,15 @@ type SetCommentStatusResponse implements Response {
|
||||
|
||||
# Response to addCommentTag mutation
|
||||
type AddCommentTagResponse implements Response {
|
||||
|
||||
# An array of errors relating to the mutation that occured.
|
||||
comment: Comment
|
||||
errors: [UserError]
|
||||
}
|
||||
|
||||
# Response to removeCommentTag mutation
|
||||
type RemoveCommentTagResponse implements Response {
|
||||
|
||||
# An array of errors relating to the mutation that occured.
|
||||
comment: Comment
|
||||
errors: [UserError]
|
||||
}
|
||||
|
||||
@@ -751,10 +767,10 @@ type RootMutation {
|
||||
setCommentStatus(id: ID!, status: COMMENT_STATUS!): SetCommentStatusResponse
|
||||
|
||||
# Add tag to comment.
|
||||
addCommentTag(id: ID!, tag: String!): AddCommentTagResponse
|
||||
addCommentTag(id: ID!, asset_id: ID!, name: String!): AddCommentTagResponse
|
||||
|
||||
# Remove tag from comment.
|
||||
removeCommentTag(id: ID!, tag: String!): RemoveCommentTagResponse
|
||||
removeCommentTag(id: ID!, asset_id: ID!, name: String!): RemoveCommentTagResponse
|
||||
|
||||
# Ignore comments by another user
|
||||
ignoreUser(id: ID!): IgnoreUserResponse
|
||||
|
||||
Reference in New Issue
Block a user