diff --git a/packages/strapi/lib/Strapi.js b/packages/strapi/lib/Strapi.js index 338038edaa..b21145ba00 100644 --- a/packages/strapi/lib/Strapi.js +++ b/packages/strapi/lib/Strapi.js @@ -19,11 +19,10 @@ const mixinAfter = require('./private/after'); * @constructor */ - // Private properties +// Private properties let _instance = null; class Strapi extends EventEmitter { - constructor() { super(); diff --git a/packages/strapi/lib/configuration/hooks/core/bodyParser/index.js b/packages/strapi/lib/configuration/hooks/core/bodyParser/index.js index f39c971c3b..c1e1a20f11 100644 --- a/packages/strapi/lib/configuration/hooks/core/bodyParser/index.js +++ b/packages/strapi/lib/configuration/hooks/core/bodyParser/index.js @@ -6,22 +6,13 @@ module.exports = strapi => { return { - /** * Default options */ defaults: { parser: { - encode: 'utf-8', - formLimit: '56kb', - jsonLimit: '1mb', - strict: true, - extendTypes: { - json: [ - 'application/x-javascript' - ] - } + multipart: true } }, @@ -30,13 +21,11 @@ module.exports = strapi => { */ initialize: cb => { - strapi.app.use(strapi.middlewares.bodyparser({ - encode: strapi.config.parser.encode, - formLimit: strapi.config.parser.formLimit, - jsonLimit: strapi.config.parser.jsonLimit, - strict: strapi.config.parser.strict, - extendTypes: strapi.config.parser.extendTypes - })); + strapi.app.use( + strapi.middlewares.convert( + strapi.middlewares.body(strapi.config.parser) + ) + ); cb(); } diff --git a/packages/strapi/lib/configuration/hooks/core/router/index.js b/packages/strapi/lib/configuration/hooks/core/router/index.js index 5d27601d6e..4f0f03c122 100644 --- a/packages/strapi/lib/configuration/hooks/core/router/index.js +++ b/packages/strapi/lib/configuration/hooks/core/router/index.js @@ -22,7 +22,6 @@ const regex = require('strapi-utils').regex; module.exports = strapi => { return { - /** * Default options */ @@ -52,25 +51,39 @@ module.exports = strapi => { // and match the controller and action to the desired endpoint. _.forEach(strapi.config.routes, value => { - if (_.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path'))) { + if ( + _.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path')) + ) { return; } const endpoint = `${value.method} ${value.path}`; try { - const {policies, action, validate} = routerChecker(value, endpoint); + const { policies, action, validate } = routerChecker(value, endpoint); if (_.isUndefined(action) || !_.isFunction(action)) { - return strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.'); + return strapi.log.warn( + 'Ignored attempt to bind route `' + + endpoint + + '` to unknown controller/action.' + ); } - strapi.router.route(_.omitBy({ - method: value.method, - path: value.path, - handler: _.remove([strapi.middlewares.compose(policies), action], o => _.isFunction(o)), - validate - }, _.isEmpty)); + strapi.router.route( + _.omitBy( + { + method: value.method, + path: value.path, + handler: _.remove( + [strapi.middlewares.compose(policies), action], + o => _.isFunction(o) + ), + validate + }, + _.isEmpty + ) + ); } catch (err) { cb(err); } @@ -81,31 +94,47 @@ module.exports = strapi => { const routerAdmin = strapi.middlewares.joiRouter(); _.forEach(strapi.admin.config.routes, value => { - if (_.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path'))) { + if ( + _.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path')) + ) { return; } const endpoint = `${value.method} ${value.path}`; try { - const {policies, action, validate} = routerChecker(value, endpoint); + const { policies, action, validate } = routerChecker(value, endpoint); if (_.isUndefined(action) || !_.isFunction(action)) { - return strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.'); + return strapi.log.warn( + 'Ignored attempt to bind route `' + + endpoint + + '` to unknown controller/action.' + ); } - routerAdmin.route(_.omitBy({ - method: value.method, - path: value.path, - handler: _.remove([strapi.middlewares.compose(policies), action], o => _.isFunction(o)), - validate - }, _.isEmpty)); + routerAdmin.route( + _.omitBy( + { + method: value.method, + path: value.path, + handler: _.remove( + [strapi.middlewares.compose(policies), action], + o => _.isFunction(o) + ), + validate + }, + _.isEmpty + ) + ); } catch (err) { cb(err); } }); - routerAdmin.prefix(strapi.config.admin || `/${strapi.config.paths.admin}`); + routerAdmin.prefix( + strapi.config.admin || `/${strapi.config.paths.admin}` + ); // TODO: // - Mount on main router `strapi.router.use(routerAdmin.middleware());` @@ -120,29 +149,50 @@ module.exports = strapi => { const router = strapi.middlewares.joiRouter(); // Exclude routes with prefix. - const excludedRoutes = _.omitBy(value, o => !o.hasOwnProperty('prefix')); + const excludedRoutes = _.omitBy( + value, + o => !o.hasOwnProperty('prefix') + ); // Add others routes to the plugin's router. _.forEach(_.omit(value, _.keys(excludedRoutes)), value => { - if (_.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path'))) { + if ( + _.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path')) + ) { return; } const endpoint = `${value.method} ${value.path}`; try { - const {policies, action, validate} = routerChecker(value, endpoint, plugin); + const { policies, action, validate } = routerChecker( + value, + endpoint, + plugin + ); if (_.isUndefined(action) || !_.isFunction(action)) { - return strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.'); + return strapi.log.warn( + 'Ignored attempt to bind route `' + + endpoint + + '` to unknown controller/action.' + ); } - router.route(_.omitBy({ - method: value.method, - path: value.path, - handler: _.remove([strapi.middlewares.compose(policies), action], o => _.isFunction(o)), - validate - }, _.isEmpty)); + router.route( + _.omitBy( + { + method: value.method, + path: value.path, + handler: _.remove( + [strapi.middlewares.compose(policies), action], + o => _.isFunction(o) + ), + validate + }, + _.isEmpty + ) + ); } catch (err) { cb(err); } @@ -153,25 +203,44 @@ module.exports = strapi => { // /!\ Could override main router's routes. if (!_.isEmpty(excludedRoutes)) { _.forEach(excludedRoutes, value => { - if (_.isEmpty(_.get(value, 'method')) || _.isEmpty(_.get(value, 'path'))) { + if ( + _.isEmpty(_.get(value, 'method')) || + _.isEmpty(_.get(value, 'path')) + ) { return; } const endpoint = `${value.method} ${value.path}`; try { - const {policies, action, validate} = routerChecker(value, endpoint, plugin); + const { policies, action, validate } = routerChecker( + value, + endpoint, + plugin + ); if (_.isUndefined(action) || !_.isFunction(action)) { - return strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.'); + return strapi.log.warn( + 'Ignored attempt to bind route `' + + endpoint + + '` to unknown controller/action.' + ); } - strapi.router.route(_.omitBy({ - method: value.method, - path: value.path, - handler: _.remove([strapi.middlewares.compose(policies), action], o => _.isFunction(o)), - validate - }, _.isEmpty)); + strapi.router.route( + _.omitBy( + { + method: value.method, + path: value.path, + handler: _.remove( + [strapi.middlewares.compose(policies), action], + o => _.isFunction(o) + ), + validate + }, + _.isEmpty + ) + ); } catch (err) { cb(err); } @@ -187,11 +256,13 @@ module.exports = strapi => { // Let the router use our routes and allowed methods. strapi.app.use(strapi.router.middleware()); - strapi.app.use(strapi.router.router.allowedMethods({ - throw: false, - notImplemented: () => Boom.notImplemented(), - methodNotAllowed: () => Boom.methodNotAllowed() - })); + strapi.app.use( + strapi.router.router.allowedMethods({ + throw: false, + notImplemented: () => Boom.notImplemented(), + methodNotAllowed: () => Boom.methodNotAllowed() + }) + ); strapi.app.use(responsesPolicy); @@ -218,7 +289,10 @@ module.exports = strapi => { // Define controller and action names. const handler = _.trim(value.handler).split('.'); - const controller = plugin ? strapi.plugins[plugin].controllers[handler[0].toLowerCase()] : strapi.controllers[handler[0].toLowerCase()] || strapi.admin.controllers[handler[0].toLowerCase()]; + const controller = plugin + ? strapi.plugins[plugin].controllers[handler[0].toLowerCase()] + : strapi.controllers[handler[0].toLowerCase()] || + strapi.admin.controllers[handler[0].toLowerCase()]; const action = controller[handler[1]]; // Retrieve the API's name where the controller is located @@ -235,11 +309,17 @@ module.exports = strapi => { policies.push(responsesPolicy); // Allow string instead of array of policies. - if (!_.isArray(_.get(value, 'config.policies')) && !_.isEmpty(_.get(value, 'config.policies'))) { + if ( + !_.isArray(_.get(value, 'config.policies')) && + !_.isEmpty(_.get(value, 'config.policies')) + ) { value.config.policies = [value.config.policies]; } - if (_.isArray(_.get(value, 'config.policies')) && !_.isEmpty(_.get(value, 'config.policies'))) { + if ( + _.isArray(_.get(value, 'config.policies')) && + !_.isEmpty(_.get(value, 'config.policies')) + ) { _.forEach(value.config.policies, policy => { // Define global policy prefix. const globalPolicyPrefix = 'global.'; @@ -247,33 +327,103 @@ module.exports = strapi => { const policySplited = policy.split('.'); // Looking for global policy or namespaced. - if (_.startsWith(policy, globalPolicyPrefix, 0) && !_.isEmpty(strapi.config.policies, policy.replace(globalPolicyPrefix, ''))) { + if ( + _.startsWith(policy, globalPolicyPrefix, 0) && + !_.isEmpty( + strapi.config.policies, + policy.replace(globalPolicyPrefix, '') + ) + ) { // Global policy. - return policies.push(strapi.config.policies[policy.replace(globalPolicyPrefix, '').toLowerCase()]); - } else if (_.startsWith(policy, pluginPolicyPrefix, 0) && strapi.plugins[policySplited[1]] && !_.isEmpty(_.get(strapi.plugins, policySplited[1] + '.config.policies.' + policySplited[2].toLowerCase()))) { + return policies.push( + strapi.config.policies[ + policy.replace(globalPolicyPrefix, '').toLowerCase() + ] + ); + } else if ( + _.startsWith(policy, pluginPolicyPrefix, 0) && + strapi.plugins[policySplited[1]] && + !_.isEmpty( + _.get( + strapi.plugins, + policySplited[1] + + '.config.policies.' + + policySplited[2].toLowerCase() + ) + ) + ) { // Plugin's policies can be used from app APIs with a specific syntax (`plugins.pluginName.policyName`). - return policies.push(_.get(strapi.plugins, policySplited[1] + '.config.policies.' + policySplited[2].toLowerCase())); - } else if (!_.startsWith(policy, globalPolicyPrefix, 0) && plugin && !_.isEmpty(_.get(strapi.plugins, plugin + '.config.policies.' + policy.toLowerCase()))) { + return policies.push( + _.get( + strapi.plugins, + policySplited[1] + + '.config.policies.' + + policySplited[2].toLowerCase() + ) + ); + } else if ( + !_.startsWith(policy, globalPolicyPrefix, 0) && + plugin && + !_.isEmpty( + _.get( + strapi.plugins, + plugin + '.config.policies.' + policy.toLowerCase() + ) + ) + ) { // Plugin policy used in the plugin itself. - return policies.push(_.get(strapi.plugins, plugin + '.config.policies.' + policy.toLowerCase())); - } else if (!_.startsWith(policy, globalPolicyPrefix, 0) && !_.isEmpty(_.get(strapi.api, currentApiName + '.config.policies.' + policy.toLowerCase()))) { + return policies.push( + _.get( + strapi.plugins, + plugin + '.config.policies.' + policy.toLowerCase() + ) + ); + } else if ( + !_.startsWith(policy, globalPolicyPrefix, 0) && + !_.isEmpty( + _.get( + strapi.api, + currentApiName + '.config.policies.' + policy.toLowerCase() + ) + ) + ) { // API policy used in the API itself. - return policies.push(_.get(strapi.api, currentApiName + '.config.policies.' + policy.toLowerCase())); + return policies.push( + _.get( + strapi.api, + currentApiName + '.config.policies.' + policy.toLowerCase() + ) + ); } - strapi.log.error('Ignored attempt to bind route `' + endpoint + '` with unknown policy `' + policy + '`.'); + strapi.log.error( + 'Ignored attempt to bind route `' + + endpoint + + '` with unknown policy `' + + policy + + '`.' + ); }); } // Init validate. const validate = {}; - if (_.isString(_.get(value, 'config.validate')) && !_.isEmpty(_.get(value, 'config.validate'))) { - const validator = _.get(strapi.api, currentApiName + '.validators.' + value.config.validate); + if ( + _.isString(_.get(value, 'config.validate')) && + !_.isEmpty(_.get(value, 'config.validate')) + ) { + const validator = _.get( + strapi.api, + currentApiName + '.validators.' + value.config.validate + ); - _.merge(validate, _.mapValues(validator, value => { - return builder.build(value); - })); + _.merge( + validate, + _.mapValues(validator, value => { + return builder.build(value); + }) + ); } return { diff --git a/packages/strapi/package.json b/packages/strapi/package.json index 0bc35f3275..142e68e689 100644 --- a/packages/strapi/package.json +++ b/packages/strapi/package.json @@ -34,13 +34,14 @@ }, "dependencies": { "async": "^2.1.2", + "await-busboy": "^1.0.1", "boom": "^4.2.0", "consolidate": "~0.14.0", "delegates": "^1.0.0", "kcors": "^2.2.0", "koa": "^2.1.0", "koa-better-static": "^1.0.5", - "koa-bodyparser": "^4.1.0", + "koa-body": "^2.0.0", "koa-compose": "^3.2.1", "koa-compress": "^2.0.0", "koa-convert": "^1.2.0", diff --git a/packages/strapi/test/middlewares.js b/packages/strapi/test/middlewares.js index fa5a1b5a5b..452736603d 100644 --- a/packages/strapi/test/middlewares.js +++ b/packages/strapi/test/middlewares.js @@ -16,7 +16,7 @@ describe('middlewares', () => { }); it('`strapi.middlewares.bodyparser` should be a function', () => { - assert(typeof strapi.middlewares.bodyparser === 'function'); + assert(typeof strapi.middlewares.body === 'function'); }); it('`strapi.middlewares.compose` should be a function', () => {