diff --git a/packages/strapi-plugin-graphql/services/GraphQL.js b/packages/strapi-plugin-graphql/services/GraphQL.js index 10b6cbb9a3..4ff6bf5059 100644 --- a/packages/strapi-plugin-graphql/services/GraphQL.js +++ b/packages/strapi-plugin-graphql/services/GraphQL.js @@ -193,19 +193,21 @@ module.exports = { // Extract custom resolver or type description. const { resolver: handler = {} } = _schema; - const queryName = isSingular ? - pluralize.singular(name): - pluralize.plural(name); + let queryName; + + if (isSingular === 'force') { + queryName = name; + } else { + queryName = isSingular ? + pluralize.singular(name): + pluralize.plural(name); + } // Retrieve policies. - const policies = isSingular ? - _.get(handler, `Query.${pluralize.singular(name)}.policies`, []): - _.get(handler, `Query.${pluralize.plural(name)}.policies`, []); + const policies = _.get(handler, `Query.${queryName}.policies`, []); // Retrieve resolverOf. - const resolverOf = isSingular ? - _.get(handler, `Query.${pluralize.singular(name)}.resolverOf`, ''): - _.get(handler, `Query.${pluralize.plural(name)}.resolverOf`, ''); + const resolverOf = _.get(handler, `Query.${queryName}.resolverOf`, ''); const policiesFn = []; @@ -216,13 +218,13 @@ module.exports = { // or the shadow CRUD resolver (aka Content-Manager). const resolver = (() => { // Try to retrieve custom resolver. - const resolver = isSingular ? - _.get(handler, `Query.${pluralize.singular(name)}.resolver`): - _.get(handler, `Query.${pluralize.plural(name)}.resolver`); + const resolver = _.get(handler, `Query.${queryName}.resolver`); + + if (_.isString(resolver) || _.isPlainObject(resolver)) { + const { handler = resolver } = _.isPlainObject(resolver) ? resolver : {}; - if (_.isString(resolver)) { // Retrieve the controller's action to be executed. - const [ name, action ] = resolver.split('.'); + const [ name, action ] = handler.split('.'); const controller = plugin ? _.get(strapi.plugins, `${plugin}.controllers.${_.toLower(name)}.${action}`): @@ -328,7 +330,7 @@ module.exports = { return async (obj, options, context) => { // Hack to be able to handle permissions for each query. - const ctx = Object.assign(context, { + const ctx = Object.assign(_.clone(context), { request: Object.assign(_.clone(context.request), { graphql: null }) @@ -362,6 +364,7 @@ module.exports = { return values && values.toJSON ? values.toJSON() : values; } + return resolver.call(null, obj, options, context); } @@ -560,7 +563,7 @@ module.exports = { switch (association.nature) { case 'manyToMany': { - const arrayOfIds = obj[association.alias].map(related => { + const arrayOfIds = (obj[association.alias] || []).map(related => { return related[ref.primaryKey] || related; }); @@ -642,9 +645,20 @@ module.exports = { return acc; } - acc[type][resolver] = _.isFunction(acc[type][resolver]) ? - acc[type][resolver]: - acc[type][resolver].resolver; + if (!_.isFunction(acc[type][resolver])) { + acc[type][resolver] = acc[type][resolver].resolver; + } + + if (_.isString(acc[type][resolver]) || _.isPlainObject(acc[type][resolver])) { + const { plugin = '' } = _.isPlainObject(acc[type][resolver]) ? acc[type][resolver] : {}; + + acc[type][resolver] = this.composeResolver( + strapi.plugins.graphql.config._schema.graphql, + plugin, + resolver, + 'force' // Avoid singular/pluralize and force query name. + ); + } return acc; }, acc); diff --git a/packages/strapi-plugin-users-permissions/config/policies/permissions.js b/packages/strapi-plugin-users-permissions/config/policies/permissions.js index 87ee1c59e0..3407b5ee41 100644 --- a/packages/strapi-plugin-users-permissions/config/policies/permissions.js +++ b/packages/strapi-plugin-users-permissions/config/policies/permissions.js @@ -39,9 +39,11 @@ module.exports = async (ctx, next) => { }, []); if (!permission) { - ctx.forbidden(); + if (ctx.request.graphql === null) { + return ctx.request.graphql = strapi.errors.forbidden(); + } - return ctx.request.graphql = ctx.body; + ctx.forbidden(); } // Execute the policies. diff --git a/packages/strapi/lib/middlewares/boom/index.js b/packages/strapi/lib/middlewares/boom/index.js index ad2940835a..ed2d590349 100644 --- a/packages/strapi/lib/middlewares/boom/index.js +++ b/packages/strapi/lib/middlewares/boom/index.js @@ -19,6 +19,7 @@ module.exports = strapi => { this.delegator = delegate(strapi.app.context, 'response'); this.createResponses(); + strapi.errors = Boom; strapi.app.use(async (ctx, next) => { try { // App logic.