From 26b7d48f1fb3981babfa5be0501340e94a4616c8 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 24 Jan 2017 17:06:40 -0700 Subject: [PATCH 1/3] Comment ordering fixed, banned users can't do anything --- client/coral-framework/helpers/validate.js | 2 +- graph/index.js | 4 ++ graph/loaders/comments.js | 48 +++++++++++++--------- graph/mutators/action.js | 2 +- graph/mutators/comment.js | 2 +- graph/mutators/user.js | 2 +- models/user.js | 27 ++++++++++++ 7 files changed, 64 insertions(+), 23 deletions(-) diff --git a/client/coral-framework/helpers/validate.js b/client/coral-framework/helpers/validate.js index 6e5db3662..b267fb7c0 100644 --- a/client/coral-framework/helpers/validate.js +++ b/client/coral-framework/helpers/validate.js @@ -1,5 +1,5 @@ export default { - email: email => (/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(email)), + email: email => (/^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(email)), password: pass => (/^(?=.{8,}).*$/.test(pass)), confirmPassword: () => true, displayName: displayName => (/^[a-zA-Z0-9_]+$/.test(displayName)) diff --git a/graph/index.js b/graph/index.js index 7fddce2eb..f8695afbb 100644 --- a/graph/index.js +++ b/graph/index.js @@ -12,3 +12,7 @@ module.exports = { context: new Context(req) }) }; + +process.on('unhandledRejection', (err) => { + console.error(err); +}); diff --git a/graph/loaders/comments.js b/graph/loaders/comments.js index 35463dfd0..77c5d172c 100644 --- a/graph/loaders/comments.js +++ b/graph/loaders/comments.js @@ -7,31 +7,41 @@ const CommentModel = require('../../models/comment'); const CommentsService = require('../../services/comments'); /** - * Retrieves comments by an array of asset id's. + * Retrieves comments by an array of asset id's, results are returned in reverse + * chronological order. * @param {Array} ids array of ids to lookup */ -const genCommentsByAssetID = (context, ids) => CommentModel.find({ - asset_id: { - $in: ids - }, - parent_id: null, - status: { - $in: [null, 'ACCEPTED'] - } -}).then(util.arrayJoinBy(ids, 'asset_id')); +const genCommentsByAssetID = (context, ids) => { + return CommentModel.find({ + asset_id: { + $in: ids + }, + parent_id: null, + status: { + $in: [null, 'ACCEPTED'] + } + }) + .sort({created_at: -1}) + .then(util.arrayJoinBy(ids, 'asset_id')); +}; /** - * Retrieves comments by an array of parent ids. + * Retrieves comments by an array of parent ids, results are returned in + * chronological order. * @param {Array} ids array of ids to lookup */ -const genCommentsByParentID = (context, ids) => CommentModel.find({ - parent_id: { - $in: ids - }, - status: { - $in: [null, 'ACCEPTED'] - } -}).then(util.arrayJoinBy(ids, 'parent_id')); +const genCommentsByParentID = (context, ids) => { + return CommentModel.find({ + parent_id: { + $in: ids + }, + status: { + $in: [null, 'ACCEPTED'] + } + }) + .sort({created_at: 1}) + .then(util.arrayJoinBy(ids, 'parent_id')); +}; const getCommentsByStatusAndAssetID = (context, {status = null, asset_id = null}) => { diff --git a/graph/mutators/action.js b/graph/mutators/action.js index cf80c496d..ab51c9a20 100644 --- a/graph/mutators/action.js +++ b/graph/mutators/action.js @@ -37,7 +37,7 @@ module.exports = (context) => { // TODO: refactor to something that'll return an error in the event an attempt // is made to mutate state while not logged in. There's got to be a better way // to do this. - if (context.user) { + if (context.user && context.user.can('mutation:createAction', 'mutation:deleteAction')) { return { Action: { create: (action) => createAction(context, action), diff --git a/graph/mutators/comment.js b/graph/mutators/comment.js index 6bd7cea26..cc62e48df 100644 --- a/graph/mutators/comment.js +++ b/graph/mutators/comment.js @@ -144,7 +144,7 @@ module.exports = (context) => { // TODO: refactor to something that'll return an error in the event an attempt // is made to mutate state while not logged in. There's got to be a better way // to do this. - if (context.user) { + if (context.user && context.user.can('mutation:createComment')) { return { Comment: { create: (comment) => createPublicComment(context, comment) diff --git a/graph/mutators/user.js b/graph/mutators/user.js index 22837caae..96049bbab 100644 --- a/graph/mutators/user.js +++ b/graph/mutators/user.js @@ -15,7 +15,7 @@ module.exports = (context) => { // TODO: refactor to something that'll return an error in the event an attempt // is made to mutate state while not logged in. There's got to be a better way // to do this. - if (context.user) { + if (context.user && context.user.can('mutation:updateUserSettings')) { return { User: { updateSettings: (settings) => updateUserSettings(context, settings) diff --git a/models/user.js b/models/user.js index 0b8edf0fd..9c447fa5d 100644 --- a/models/user.js +++ b/models/user.js @@ -130,6 +130,33 @@ UserSchema.method('hasRoles', function(...roles) { }); }); +/** + * All the graph operations that are available for a user. + * @type {Array} + */ +const USER_GRAPH_OPERATIONS = [ + 'mutation:createComment', + 'mutation:createAction', + 'mutation:deleteAction', + 'mutation:updateUserSettings' +]; + +/** + * Can returns true if the user is allowed to perform a specific graph + * operation. + */ +UserSchema.method('can', function(...actions) { + if (actions.some((action) => USER_GRAPH_OPERATIONS.indexOf(action) === -1)) { + throw new Error(`invalid actions: ${actions}`); + } + + if (this.status === 'BANNED') { + return false; + } + + return true; +}); + // Create the User model. const UserModel = mongoose.model('User', UserSchema); From eb469df573f222ed0ecba36f078d2ae00f8437ab Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 24 Jan 2017 17:08:12 -0700 Subject: [PATCH 2/3] Removed debugging tool --- graph/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/graph/index.js b/graph/index.js index f8695afbb..7fddce2eb 100644 --- a/graph/index.js +++ b/graph/index.js @@ -12,7 +12,3 @@ module.exports = { context: new Context(req) }) }; - -process.on('unhandledRejection', (err) => { - console.error(err); -}); From 373f119ac244faf817e48a40b0c9cef6a1b0be3a Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 24 Jan 2017 17:22:29 -0700 Subject: [PATCH 3/3] Added more comment sorting --- graph/loaders/comments.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/graph/loaders/comments.js b/graph/loaders/comments.js index 77c5d172c..9a67bb621 100644 --- a/graph/loaders/comments.js +++ b/graph/loaders/comments.js @@ -62,7 +62,7 @@ const getCommentsByActionTypeAndAssetID = (context, {action_type, asset_id = nul id: { $in: actions.map((action) => action.item_id) } - }); + }).sort({created_at: 1}); if (asset_id) { comments = comments.where({asset_id}); @@ -72,11 +72,15 @@ const getCommentsByActionTypeAndAssetID = (context, {action_type, asset_id = nul }); }; -const genCommentsByAuthorID = (context, authorIDs) => CommentModel.find({ - author_id: { - $in: authorIDs - } -}).then(util.arrayJoinBy(authorIDs, 'author_id')); +const genCommentsByAuthorID = (context, authorIDs) => { + return CommentModel.find({ + author_id: { + $in: authorIDs + } + }) + .sort({created_at: -1}) + .then(util.arrayJoinBy(authorIDs, 'author_id')); +}; /** * Creates a set of loaders based on a GraphQL context.