mirror of
https://github.com/strapi/strapi.git
synced 2025-09-09 00:26:28 +00:00
wip
This commit is contained in:
parent
b63c330c58
commit
1da801ac64
@ -376,6 +376,8 @@ class Strapi {
|
||||
// Initialize middlewares.
|
||||
await initializeMiddlewares(this);
|
||||
|
||||
await this.server.initRouting();
|
||||
|
||||
await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
|
||||
|
||||
this.cron.start();
|
||||
|
@ -10,7 +10,6 @@ dotenv.config({ path: process.env.ENV_PATH });
|
||||
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||
|
||||
const getPrefixedDeps = require('../../utils/get-prefixed-dependencies');
|
||||
const loadConfigDir = require('./config-loader');
|
||||
const loadFunction = require('./load-functions');
|
||||
|
||||
@ -31,15 +30,6 @@ const defaultConfig = {
|
||||
admin: { autoOpen: false },
|
||||
},
|
||||
admin: {},
|
||||
middleware: {
|
||||
timeout: 1000,
|
||||
load: {
|
||||
before: ['responseTime', 'logger', 'cors', 'responses', 'gzip'],
|
||||
order: [],
|
||||
after: ['parser', 'router'],
|
||||
},
|
||||
settings: {},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = (dir, initialConfig = {}) => {
|
||||
@ -63,7 +53,6 @@ module.exports = (dir, initialConfig = {}) => {
|
||||
strapi: strapiVersion,
|
||||
},
|
||||
functions: loadFunction(path.join(configDir, 'functions')),
|
||||
installedMiddlewares: getPrefixedDeps('@strapi/middleware', pkgJSON),
|
||||
};
|
||||
|
||||
const baseConfig = omit('plugins', loadConfigDir(configDir)); // plugin config will be loaded later
|
||||
|
@ -9,18 +9,18 @@ const glob = require('../../load/glob');
|
||||
* Load middlewares
|
||||
*/
|
||||
module.exports = async function(strapi) {
|
||||
const installedMiddlewares = strapi.config.get('installedMiddlewares');
|
||||
// const installedMiddlewares = strapi.config.get('installedMiddlewares');
|
||||
const appPath = strapi.config.get('appPath');
|
||||
|
||||
let middlewares = {};
|
||||
|
||||
const loaders = createLoaders(strapi);
|
||||
// const loaders = createLoaders(strapi);
|
||||
|
||||
await loaders.loadMiddlewareDependencies(installedMiddlewares, middlewares);
|
||||
// await loaders.loadMiddlewareDependencies(installedMiddlewares, middlewares);
|
||||
// internal middlewares
|
||||
await loaders.loadInternalMiddlewares(middlewares);
|
||||
// await loaders.loadInternalMiddlewares(middlewares);
|
||||
// local middleware
|
||||
await loaders.loadLocalMiddlewares(appPath, middlewares);
|
||||
// await loaders.loadLocalMiddlewares(appPath, middlewares);
|
||||
|
||||
return middlewares;
|
||||
};
|
||||
|
5
packages/core/strapi/lib/middlewares/compression.js
Normal file
5
packages/core/strapi/lib/middlewares/compression.js
Normal file
@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const compress = require('koa-compress');
|
||||
|
||||
module.exports = (options = {}) => compress(options);
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"error": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Boom hook
|
||||
*/
|
||||
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
const Boom = require('@hapi/boom');
|
||||
const delegate = require('delegates');
|
||||
|
||||
const boomMethods = [
|
||||
'badRequest',
|
||||
'unauthorized',
|
||||
'paymentRequired',
|
||||
'forbidden',
|
||||
'notFound',
|
||||
'methodNotAllowed',
|
||||
'notAcceptable',
|
||||
'proxyAuthRequired',
|
||||
'clientTimeout',
|
||||
'conflict',
|
||||
'resourceGone',
|
||||
'lengthRequired',
|
||||
'preconditionFailed',
|
||||
'entityTooLarge',
|
||||
'uriTooLong',
|
||||
'unsupportedMediaType',
|
||||
'rangeNotSatisfiable',
|
||||
'expectationFailed',
|
||||
'teapot',
|
||||
'badData',
|
||||
'locked',
|
||||
'failedDependency',
|
||||
'preconditionRequired',
|
||||
'tooManyRequests',
|
||||
'illegal',
|
||||
'badImplementation',
|
||||
'notImplemented',
|
||||
'badGateway',
|
||||
'serverUnavailable',
|
||||
'gatewayTimeout',
|
||||
];
|
||||
|
||||
const formatBoomPayload = boomError => {
|
||||
if (!Boom.isBoom(boomError)) {
|
||||
boomError = Boom.boomify(boomError, {
|
||||
statusCode: boomError.status || 500,
|
||||
});
|
||||
}
|
||||
|
||||
const { output } = boomError;
|
||||
|
||||
if (output.statusCode < 500 && !_.isNil(boomError.data)) {
|
||||
output.payload.data = boomError.data;
|
||||
}
|
||||
|
||||
return { status: output.statusCode, body: output.payload };
|
||||
};
|
||||
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
/**
|
||||
* Initialize the hook
|
||||
*/
|
||||
|
||||
initialize() {
|
||||
this.delegator = delegate(strapi.server.app.context, 'response');
|
||||
this.createResponses();
|
||||
|
||||
strapi.errors = Boom;
|
||||
strapi.server.use(async (ctx, next) => {
|
||||
try {
|
||||
// App logic.
|
||||
await next();
|
||||
} catch (error) {
|
||||
// emit error if configured
|
||||
if (strapi.config.get('server.emitErrors', false)) {
|
||||
strapi.server.app.emit('error', error, ctx);
|
||||
}
|
||||
|
||||
// Log error.
|
||||
|
||||
const { status, body } = formatBoomPayload(error);
|
||||
|
||||
if (status >= 500) {
|
||||
strapi.log.error(error);
|
||||
}
|
||||
|
||||
ctx.body = body;
|
||||
ctx.status = status;
|
||||
}
|
||||
});
|
||||
|
||||
strapi.server.use(async (ctx, next) => {
|
||||
await next();
|
||||
// Empty body is considered as `notFound` response.
|
||||
if (_.isNil(ctx.body) && (_.isNil(ctx.status) || ctx.status === 404)) {
|
||||
ctx.notFound();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Custom function to avoid ctx.body repeat
|
||||
createResponses() {
|
||||
boomMethods.forEach(method => {
|
||||
strapi.server.app.response[method] = function(msg, ...rest) {
|
||||
const boomError = Boom[method](msg, ...rest) || {};
|
||||
|
||||
const { status, body } = formatBoomPayload(boomError);
|
||||
|
||||
// keep retro-compatibility for old error formats
|
||||
body.message = msg || body.data || body.message;
|
||||
|
||||
this.body = body;
|
||||
this.status = status;
|
||||
};
|
||||
|
||||
this.delegator.method(method);
|
||||
});
|
||||
|
||||
strapi.server.app.response.send = function(data, status = 200) {
|
||||
this.status = status;
|
||||
this.body = data;
|
||||
};
|
||||
|
||||
strapi.server.app.response.created = function(data) {
|
||||
this.status = 201;
|
||||
this.body = data;
|
||||
};
|
||||
|
||||
strapi.server.app.response.deleted = function(data) {
|
||||
if (_.isNil(data)) {
|
||||
this.status = 204;
|
||||
} else {
|
||||
this.status = 200;
|
||||
this.body = data;
|
||||
}
|
||||
};
|
||||
|
||||
this.delegator
|
||||
.method('send')
|
||||
.method('created')
|
||||
.method('deleted');
|
||||
},
|
||||
};
|
||||
};
|
134
packages/core/strapi/lib/middlewares/errors.js
Normal file
134
packages/core/strapi/lib/middlewares/errors.js
Normal file
@ -0,0 +1,134 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Boom hook
|
||||
*/
|
||||
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
const Boom = require('@hapi/boom');
|
||||
const delegate = require('delegates');
|
||||
|
||||
const boomMethods = [
|
||||
'badRequest',
|
||||
'unauthorized',
|
||||
'paymentRequired',
|
||||
'forbidden',
|
||||
'notFound',
|
||||
'methodNotAllowed',
|
||||
'notAcceptable',
|
||||
'proxyAuthRequired',
|
||||
'clientTimeout',
|
||||
'conflict',
|
||||
'resourceGone',
|
||||
'lengthRequired',
|
||||
'preconditionFailed',
|
||||
'entityTooLarge',
|
||||
'uriTooLong',
|
||||
'unsupportedMediaType',
|
||||
'rangeNotSatisfiable',
|
||||
'expectationFailed',
|
||||
'teapot',
|
||||
'badData',
|
||||
'locked',
|
||||
'failedDependency',
|
||||
'preconditionRequired',
|
||||
'tooManyRequests',
|
||||
'illegal',
|
||||
'badImplementation',
|
||||
'notImplemented',
|
||||
'badGateway',
|
||||
'serverUnavailable',
|
||||
'gatewayTimeout',
|
||||
];
|
||||
|
||||
const formatBoomPayload = boomError => {
|
||||
if (!Boom.isBoom(boomError)) {
|
||||
boomError = Boom.boomify(boomError, {
|
||||
statusCode: boomError.status || 500,
|
||||
});
|
||||
}
|
||||
|
||||
const { output } = boomError;
|
||||
|
||||
if (output.statusCode < 500 && !_.isNil(boomError.data)) {
|
||||
output.payload.data = boomError.data;
|
||||
}
|
||||
|
||||
return { status: output.statusCode, body: output.payload };
|
||||
};
|
||||
|
||||
const createResponseUtils = () => {
|
||||
const delegator = delegate(strapi.server.app.context, 'response');
|
||||
|
||||
boomMethods.forEach(method => {
|
||||
strapi.server.app.response[method] = function(msg, ...rest) {
|
||||
const boomError = Boom[method](msg, ...rest) || {};
|
||||
|
||||
const { status, body } = formatBoomPayload(boomError);
|
||||
|
||||
// keep retro-compatibility for old error formats
|
||||
body.message = msg || body.data || body.message;
|
||||
|
||||
this.body = body;
|
||||
this.status = status;
|
||||
};
|
||||
|
||||
delegator.method(method);
|
||||
});
|
||||
|
||||
strapi.server.app.response.send = function(data, status = 200) {
|
||||
this.status = status;
|
||||
this.body = data;
|
||||
};
|
||||
|
||||
strapi.server.app.response.created = function(data) {
|
||||
this.status = 201;
|
||||
this.body = data;
|
||||
};
|
||||
|
||||
strapi.server.app.response.deleted = function(data) {
|
||||
if (_.isNil(data)) {
|
||||
this.status = 204;
|
||||
} else {
|
||||
this.status = 200;
|
||||
this.body = data;
|
||||
}
|
||||
};
|
||||
|
||||
delegator
|
||||
.method('send')
|
||||
.method('created')
|
||||
.method('deleted');
|
||||
};
|
||||
|
||||
// TODO: inject strapi
|
||||
module.exports = () => {
|
||||
createResponseUtils();
|
||||
strapi.errors = Boom;
|
||||
|
||||
return async (ctx, next) => {
|
||||
try {
|
||||
// App logic.
|
||||
await next();
|
||||
|
||||
if (_.isNil(ctx.body) && (_.isNil(ctx.status) || ctx.status === 404)) {
|
||||
ctx.notFound();
|
||||
}
|
||||
} catch (error) {
|
||||
// emit error if configured
|
||||
if (strapi.config.get('server.emitErrors', false)) {
|
||||
strapi.server.app.emit('error', error, ctx);
|
||||
}
|
||||
|
||||
const { status, body } = formatBoomPayload(error);
|
||||
|
||||
if (status >= 500) {
|
||||
strapi.log.error(error);
|
||||
}
|
||||
|
||||
ctx.body = body;
|
||||
ctx.status = status;
|
||||
}
|
||||
};
|
||||
};
|
17
packages/core/strapi/lib/middlewares/favicon.js
Normal file
17
packages/core/strapi/lib/middlewares/favicon.js
Normal file
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
const { resolve } = require('path');
|
||||
const { defaultsDeep } = require('lodash');
|
||||
const favicon = require('koa-favicon');
|
||||
|
||||
const defaults = {
|
||||
path: 'favicon.ico',
|
||||
maxAge: 86400000,
|
||||
};
|
||||
|
||||
// TODO: inject strapi
|
||||
module.exports = options => {
|
||||
const { maxAge, path: faviconPath } = defaultsDeep(defaults, options);
|
||||
|
||||
return favicon(resolve(strapi.dirs.root, faviconPath), { maxAge });
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"favicon": {
|
||||
"enabled": true,
|
||||
"path": "favicon.ico",
|
||||
"maxAge": 86400000
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// Node.js core.
|
||||
const { resolve } = require('path');
|
||||
const favicon = require('koa-favicon');
|
||||
|
||||
/**
|
||||
* Favicon hook
|
||||
*/
|
||||
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
/**
|
||||
* Initialize the hook
|
||||
*/
|
||||
|
||||
initialize() {
|
||||
const { maxAge, path: faviconPath } = strapi.config.middleware.settings.favicon;
|
||||
|
||||
strapi.server.use(
|
||||
favicon(resolve(strapi.dirs.root, faviconPath), {
|
||||
maxAge,
|
||||
})
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"gzip": {
|
||||
"enabled": false,
|
||||
"options": {}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Gzip hook
|
||||
*/
|
||||
const compress = require('koa-compress');
|
||||
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
/**
|
||||
* Initialize the hook
|
||||
*/
|
||||
|
||||
initialize() {
|
||||
const { options = {} } = strapi.config.middleware.settings.gzip;
|
||||
strapi.server.use(compress(options));
|
||||
},
|
||||
};
|
||||
};
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"helmet": {
|
||||
"enabled": true,
|
||||
"crossOriginEmbedderPolicy": false,
|
||||
"crossOriginOpenerPolicy": false,
|
||||
"crossOriginResourcePolicy": false,
|
||||
"originAgentCluster": false,
|
||||
"contentSecurityPolicy": false,
|
||||
"xssFilter": false,
|
||||
"hsts": {
|
||||
"maxAge": 31536000,
|
||||
"includeSubDomains": true
|
||||
},
|
||||
"frameguard": {
|
||||
"action": "sameorigin"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,120 +1,156 @@
|
||||
'use strict';
|
||||
|
||||
const { uniq, difference, get, isUndefined, merge } = require('lodash');
|
||||
const compression = require('./compression');
|
||||
const cors = require('./cors');
|
||||
const errors = require('./errors');
|
||||
const favicon = require('./favicon');
|
||||
const ip = require('./ip');
|
||||
const logger = require('./logger');
|
||||
const poweredBy = require('./powered-by');
|
||||
const requestParser = require('./request-parser');
|
||||
const responseTime = require('./response-time');
|
||||
const responseHandlers = require('./response-handlers');
|
||||
const security = require('./security');
|
||||
// session: require('./session'),
|
||||
const publicStatic = require('./public');
|
||||
|
||||
const requiredMiddlewares = [
|
||||
'auth',
|
||||
'responses',
|
||||
'router',
|
||||
'logger',
|
||||
'error',
|
||||
'cors',
|
||||
'cron',
|
||||
'xframe',
|
||||
'xss',
|
||||
'public',
|
||||
'favicon',
|
||||
const INTERNAL_MIDDLEWARES = [
|
||||
errors,
|
||||
ip,
|
||||
security,
|
||||
cors,
|
||||
responseTime,
|
||||
poweredBy,
|
||||
logger,
|
||||
compression,
|
||||
responseHandlers,
|
||||
requestParser,
|
||||
favicon,
|
||||
publicStatic,
|
||||
];
|
||||
|
||||
module.exports = async function(strapi) {
|
||||
/** Utils */
|
||||
const middlewareConfig = strapi.config.middleware;
|
||||
module.exports = async strapi => {
|
||||
for (const middlewareFactory of INTERNAL_MIDDLEWARES) {
|
||||
// const config = strapi.config.get(`middlwares`);
|
||||
const middleware = middlewareFactory({});
|
||||
|
||||
// check if a middleware exists
|
||||
const middlewareExists = key => {
|
||||
return !isUndefined(strapi.middleware[key]);
|
||||
};
|
||||
|
||||
// check if a middleware is enabled
|
||||
const middlewareEnabled = key => {
|
||||
return (
|
||||
requiredMiddlewares.includes(key) ||
|
||||
get(middlewareConfig, ['settings', key, 'enabled'], false) === true
|
||||
);
|
||||
};
|
||||
|
||||
// list of enabled middlewares
|
||||
const enabledMiddlewares = Object.keys(strapi.middleware).filter(middlewareEnabled);
|
||||
|
||||
// Method to initialize middlewares and emit an event.
|
||||
const initialize = middlewareKey => {
|
||||
if (strapi.middleware[middlewareKey].loaded === true) return;
|
||||
|
||||
const module = strapi.middleware[middlewareKey].load;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(
|
||||
() => reject(`(middleware: ${middlewareKey}) is taking too long to load.`),
|
||||
middlewareConfig.timeout || 1000
|
||||
);
|
||||
strapi.middleware[middlewareKey] = merge(strapi.middleware[middlewareKey], module);
|
||||
|
||||
Promise.resolve()
|
||||
.then(() => module.initialize(strapi))
|
||||
.then(() => {
|
||||
clearTimeout(timeout);
|
||||
strapi.middleware[middlewareKey].loaded = true;
|
||||
resolve();
|
||||
})
|
||||
.catch(err => {
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Run init functions
|
||||
*/
|
||||
|
||||
// Run beforeInitialize of every middleware
|
||||
await Promise.all(
|
||||
enabledMiddlewares.map(key => {
|
||||
const { beforeInitialize } = strapi.middleware[key].load;
|
||||
if (typeof beforeInitialize === 'function') {
|
||||
return beforeInitialize(strapi);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// run the initialization of an array of middlewares sequentially
|
||||
const initMiddlewaresSeq = async middlewareArr => {
|
||||
for (let key of uniq(middlewareArr)) {
|
||||
await initialize(key);
|
||||
}
|
||||
};
|
||||
|
||||
const middlewaresBefore = get(middlewareConfig, 'load.before', [])
|
||||
.filter(middlewareExists)
|
||||
.filter(middlewareEnabled);
|
||||
|
||||
const middlewaresAfter = get(middlewareConfig, 'load.after', [])
|
||||
.filter(middlewareExists)
|
||||
.filter(middlewareEnabled);
|
||||
|
||||
const middlewaresOrder = get(middlewareConfig, 'load.order', [])
|
||||
.filter(middlewareExists)
|
||||
.filter(middlewareEnabled);
|
||||
|
||||
const unspecifiedMiddlewares = difference(
|
||||
enabledMiddlewares,
|
||||
middlewaresBefore,
|
||||
middlewaresOrder,
|
||||
middlewaresAfter
|
||||
);
|
||||
|
||||
// before
|
||||
await initMiddlewaresSeq(middlewaresBefore);
|
||||
|
||||
// ordered // rest of middlewares
|
||||
await Promise.all([
|
||||
initMiddlewaresSeq(middlewaresOrder),
|
||||
Promise.all(unspecifiedMiddlewares.map(initialize)),
|
||||
]);
|
||||
|
||||
// after
|
||||
await initMiddlewaresSeq(middlewaresAfter);
|
||||
strapi.server.use(middleware);
|
||||
}
|
||||
};
|
||||
|
||||
// const requiredMiddlewares = [
|
||||
// 'auth',
|
||||
// 'responses',
|
||||
// 'router',
|
||||
// 'logger',
|
||||
// 'error',
|
||||
// 'cors',
|
||||
// 'cron',
|
||||
// 'xframe',
|
||||
// 'xss',
|
||||
// 'public',
|
||||
// 'favicon',
|
||||
// ];
|
||||
|
||||
// module.exports = async function(strapi) {
|
||||
// /** Utils */
|
||||
// const middlewareConfig = strapi.config.middleware;
|
||||
|
||||
// // check if a middleware exists
|
||||
// const middlewareExists = key => {
|
||||
// return !isUndefined(strapi.middleware[key]);
|
||||
// };
|
||||
|
||||
// // check if a middleware is enabled
|
||||
// const middlewareEnabled = key => {
|
||||
// return (
|
||||
// requiredMiddlewares.includes(key) ||
|
||||
// get(middlewareConfig, ['settings', key, 'enabled'], false) === true
|
||||
// );
|
||||
// };
|
||||
|
||||
// // list of enabled middlewares
|
||||
// const enabledMiddlewares = Object.keys(strapi.middleware).filter(middlewareEnabled);
|
||||
|
||||
// // Method to initialize middlewares and emit an event.
|
||||
// const initialize = middlewareKey => {
|
||||
// if (strapi.middleware[middlewareKey].loaded === true) return;
|
||||
|
||||
// const module = strapi.middleware[middlewareKey].load;
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const timeout = setTimeout(
|
||||
// () => reject(`(middleware: ${middlewareKey}) is taking too long to load.`),
|
||||
// middlewareConfig.timeout || 1000
|
||||
// );
|
||||
// strapi.middleware[middlewareKey] = merge(strapi.middleware[middlewareKey], module);
|
||||
|
||||
// Promise.resolve()
|
||||
// .then(() => module.initialize(strapi))
|
||||
// .then(() => {
|
||||
// clearTimeout(timeout);
|
||||
// strapi.middleware[middlewareKey].loaded = true;
|
||||
// resolve();
|
||||
// })
|
||||
// .catch(err => {
|
||||
// clearTimeout(timeout);
|
||||
|
||||
// if (err) {
|
||||
// return reject(err);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * Run init functions
|
||||
// */
|
||||
|
||||
// // Run beforeInitialize of every middleware
|
||||
// await Promise.all(
|
||||
// enabledMiddlewares.map(key => {
|
||||
// const { beforeInitialize } = strapi.middleware[key].load;
|
||||
// if (typeof beforeInitialize === 'function') {
|
||||
// return beforeInitialize(strapi);
|
||||
// }
|
||||
// })
|
||||
// );
|
||||
|
||||
// // run the initialization of an array of middlewares sequentially
|
||||
// const initMiddlewaresSeq = async middlewareArr => {
|
||||
// for (let key of uniq(middlewareArr)) {
|
||||
// await initialize(key);
|
||||
// }
|
||||
// };
|
||||
|
||||
// const middlewaresBefore = get(middlewareConfig, 'load.before', [])
|
||||
// .filter(middlewareExists)
|
||||
// .filter(middlewareEnabled);
|
||||
|
||||
// const middlewaresAfter = get(middlewareConfig, 'load.after', [])
|
||||
// .filter(middlewareExists)
|
||||
// .filter(middlewareEnabled);
|
||||
|
||||
// const middlewaresOrder = get(middlewareConfig, 'load.order', [])
|
||||
// .filter(middlewareExists)
|
||||
// .filter(middlewareEnabled);
|
||||
|
||||
// const unspecifiedMiddlewares = difference(
|
||||
// enabledMiddlewares,
|
||||
// middlewaresBefore,
|
||||
// middlewaresOrder,
|
||||
// middlewaresAfter
|
||||
// );
|
||||
|
||||
// // before
|
||||
// await initMiddlewaresSeq(middlewaresBefore);
|
||||
|
||||
// // ordered // rest of middlewares
|
||||
// await Promise.all([
|
||||
// initMiddlewaresSeq(middlewaresOrder),
|
||||
// Promise.all(unspecifiedMiddlewares.map(initialize)),
|
||||
// ]);
|
||||
|
||||
// // after
|
||||
// await initMiddlewaresSeq(middlewaresAfter);
|
||||
// };
|
||||
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"parser": {
|
||||
"enabled": true,
|
||||
"multipart": true,
|
||||
"queryStringParser": {
|
||||
"strictNullHandling": true,
|
||||
"arrayLimit": 100,
|
||||
"depth": 20
|
||||
}
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const body = require('koa-body');
|
||||
const qs = require('qs');
|
||||
const { omit } = require('lodash');
|
||||
|
||||
/**
|
||||
* Body parser hook
|
||||
*/
|
||||
const addQsParser = (app, settings) => {
|
||||
Object.defineProperty(app.request, 'query', {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
/*
|
||||
* Get parsed query-string.
|
||||
*/
|
||||
get() {
|
||||
const qstr = this.querystring;
|
||||
const cache = (this._querycache = this._querycache || {});
|
||||
return cache[qstr] || (cache[qstr] = qs.parse(qstr, settings));
|
||||
},
|
||||
|
||||
/*
|
||||
* Set query-string as an object.
|
||||
*/
|
||||
set(obj) {
|
||||
this.querystring = qs.stringify(obj);
|
||||
},
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
/**
|
||||
* Initialize the hook
|
||||
*/
|
||||
initialize() {
|
||||
strapi.server.use(async (ctx, next) => {
|
||||
// disable for graphql
|
||||
// TODO: find a better way later
|
||||
if (ctx.url === '/graphql') {
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await body({
|
||||
patchKoa: true,
|
||||
...omit(strapi.config.middleware.settings.parser, 'queryStringParser'),
|
||||
})(ctx, next);
|
||||
return res;
|
||||
} catch (e) {
|
||||
if ((e || {}).message && e.message.includes('maxFileSize exceeded')) {
|
||||
throw strapi.errors.entityTooLarge('FileTooBig', {
|
||||
errors: [
|
||||
{
|
||||
id: 'Upload.status.sizeLimit',
|
||||
message: `file is bigger than the limit size!`,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
addQsParser(
|
||||
strapi.server.app,
|
||||
strapi.config.get('middleware.settings.parser.queryStringParser')
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
@ -18,6 +18,12 @@ const serveStatic = require('./serve-static');
|
||||
*/
|
||||
|
||||
module.exports = strapi => {
|
||||
|
||||
|
||||
return async (ctx, next) => {
|
||||
return next();
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Initialize the hook
|
||||
|
73
packages/core/strapi/lib/middlewares/request-parser.js
Normal file
73
packages/core/strapi/lib/middlewares/request-parser.js
Normal file
@ -0,0 +1,73 @@
|
||||
'use strict';
|
||||
|
||||
const { defaultsDeep } = require('lodash/fp');
|
||||
const body = require('koa-body');
|
||||
const qs = require('qs');
|
||||
|
||||
const defaults = {
|
||||
multipart: true,
|
||||
queryStringParser: {
|
||||
strictNullHandling: true,
|
||||
arrayLimit: 100,
|
||||
depth: 20,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Body parser hook
|
||||
*/
|
||||
const addQsParser = (app, settings) => {
|
||||
Object.defineProperty(app.request, 'query', {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
/*
|
||||
* Get parsed query-string.
|
||||
*/
|
||||
get() {
|
||||
const qstr = this.querystring;
|
||||
const cache = (this._querycache = this._querycache || {});
|
||||
return cache[qstr] || (cache[qstr] = qs.parse(qstr, settings));
|
||||
},
|
||||
|
||||
/*
|
||||
* Set query-string as an object.
|
||||
*/
|
||||
set(obj) {
|
||||
this.querystring = qs.stringify(obj);
|
||||
},
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
// TODO: inject strapi
|
||||
module.exports = options => {
|
||||
const { queryStringParser, ...bodyOptions } = defaultsDeep(defaults, options);
|
||||
|
||||
addQsParser(strapi.server.app, queryStringParser);
|
||||
|
||||
return async (ctx, next) => {
|
||||
// disable for graphql
|
||||
// TODO: find a better way later
|
||||
if (ctx.url === '/graphql') {
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
return body({ patchKoa: true, ...bodyOptions })(ctx, next);
|
||||
} catch (e) {
|
||||
if ((e || {}).message && e.message.includes('maxFileSize exceeded')) {
|
||||
throw strapi.errors.entityTooLarge('FileTooBig', {
|
||||
errors: [
|
||||
{
|
||||
id: 'parser.file.status.sizeLimit',
|
||||
message: `file is bigger than the limit size!`,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
16
packages/core/strapi/lib/middlewares/response-handlers.js
Normal file
16
packages/core/strapi/lib/middlewares/response-handlers.js
Normal file
@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
const { prop, isFunction } = require('lodash/fp');
|
||||
|
||||
module.exports = (options = {}) => {
|
||||
return async (ctx, next) => {
|
||||
await next();
|
||||
|
||||
const status = ctx.status;
|
||||
const handler = prop(`handlers.${status}`, options);
|
||||
|
||||
if (isFunction(handler)) {
|
||||
await handler(ctx);
|
||||
}
|
||||
};
|
||||
};
|
12
packages/core/strapi/lib/middlewares/response-time.js
Normal file
12
packages/core/strapi/lib/middlewares/response-time.js
Normal file
@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = () => {
|
||||
return async (ctx, next) => {
|
||||
const start = Date.now();
|
||||
|
||||
await next();
|
||||
|
||||
const delta = Math.ceil(Date.now() - start);
|
||||
ctx.set('X-Response-Time', delta + 'ms');
|
||||
};
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"responseTime": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* X-Response-Time hook
|
||||
*/
|
||||
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
/**
|
||||
* Initialize the hook
|
||||
*/
|
||||
|
||||
initialize() {
|
||||
strapi.server.use(async (ctx, next) => {
|
||||
const start = Date.now();
|
||||
|
||||
await next();
|
||||
|
||||
const delta = Math.ceil(Date.now() - start);
|
||||
|
||||
ctx.set('X-Response-Time', delta + 'ms'); // eslint-disable-line prefer-template
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"responses": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
initialize() {
|
||||
strapi.server.use(async (ctx, next) => {
|
||||
await next();
|
||||
|
||||
const status = ctx.status;
|
||||
const responseFn = strapi.config.get(`middleware.settings.responses.handlers.${status}`);
|
||||
if (_.isFunction(responseFn)) {
|
||||
await responseFn(ctx);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"router": {
|
||||
"enabled": true,
|
||||
"prefix": "",
|
||||
"routes": {}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ const { createHTTPServer } = require('./http-server');
|
||||
const { createRouteManager } = require('./routing');
|
||||
const { createAdminAPI } = require('./admin-api');
|
||||
const { createContentAPI } = require('./content-api');
|
||||
const registerAllRoutes = require('./register-routes');
|
||||
|
||||
const healthCheck = async ctx => {
|
||||
ctx.set('strapi', 'You are so French!');
|
||||
@ -89,6 +90,10 @@ const createServer = strapi => {
|
||||
return this;
|
||||
},
|
||||
|
||||
initRouting() {
|
||||
registerAllRoutes(strapi);
|
||||
},
|
||||
|
||||
listen(...args) {
|
||||
if (!state.mounted) {
|
||||
this.mount();
|
||||
|
@ -19,7 +19,7 @@ const createRouteScopeGenerator = namespace => route => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = strapi => {
|
||||
module.exports = (server, strapi) => {
|
||||
const registerAdminRoutes = () => {
|
||||
const generateRouteScope = createRouteScopeGenerator(`admin::`);
|
||||
|
||||
@ -28,7 +28,7 @@ module.exports = strapi => {
|
||||
route.info = { pluginName: 'admin' };
|
||||
});
|
||||
|
||||
strapi.server.routes({
|
||||
server.routes({
|
||||
type: 'admin',
|
||||
prefix: '/admin',
|
||||
routes: strapi.admin.routes,
|
||||
@ -47,7 +47,7 @@ module.exports = strapi => {
|
||||
route.info = { pluginName };
|
||||
});
|
||||
|
||||
strapi.server.routes({
|
||||
server.routes({
|
||||
type: 'admin',
|
||||
prefix: `/${pluginName}`,
|
||||
routes: plugin.routes,
|
||||
@ -61,7 +61,7 @@ module.exports = strapi => {
|
||||
route.info = { pluginName };
|
||||
});
|
||||
|
||||
strapi.server.routes(router);
|
||||
server.routes(router);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ module.exports = strapi => {
|
||||
route.info = { apiName };
|
||||
});
|
||||
|
||||
return strapi.server.routes(router);
|
||||
return server.routes(router);
|
||||
});
|
||||
}
|
||||
};
|
@ -1,25 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const getPrefixedDeps = require('../get-prefixed-dependencies');
|
||||
|
||||
describe('getPrefixedDeps', () => {
|
||||
test('Returns a list of the dependencies and removes the prefix', () => {
|
||||
expect(
|
||||
getPrefixedDeps('test-prefix', {
|
||||
dependencies: {
|
||||
'test-prefix-packagename': '1',
|
||||
},
|
||||
})
|
||||
).toEqual(['packagename']);
|
||||
});
|
||||
|
||||
test('Ignores exact names', () => {
|
||||
expect(
|
||||
getPrefixedDeps('test-prefix', {
|
||||
dependencies: {
|
||||
'test-prefix': '1',
|
||||
},
|
||||
})
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = (prefix, pkgJSON) => {
|
||||
return Object.keys(pkgJSON.dependencies)
|
||||
.filter(d => d.startsWith(prefix) && d.length > prefix.length)
|
||||
.map(pkgName => pkgName.substring(prefix.length + 1));
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user