@dr.pogodin/react-utils 1.12.10 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -103,7 +103,10 @@ async function factory(webpackConfig, options) {
103
103
 
104
104
  server.use((0, _compression.default)());
105
105
  server.use((0, _helmet.default)({
106
- contentSecurityPolicy: false
106
+ contentSecurityPolicy: false,
107
+ crossOriginEmbedderPolicy: false,
108
+ crossOriginOpenerPolicy: false,
109
+ crossOriginResourcePolicy: false
107
110
  }));
108
111
 
109
112
  if (!options.noCsp) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/server.js"],"names":["defaultCspSettings","directives","helmet","contentSecurityPolicy","getDefaultDirectives","array","filter","item","push","getDefaultCspSettings","factory","webpackConfig","options","rendererOps","renderer","publicPath","output","server","beforeExpressJsSetup","logger","httpsRedirect","use","req","res","next","schema","headers","url","host","originalUrl","redirect","noCsp","nonce","cspNonce","cspSettings","cspSettingsHook","favicon","send","express","json","limit","urlencoded","extended","requestIp","mw","loggerMiddleware","token","clientIp","FORMAT","stream","write","info","bind","header","devMode","webpack","require","webpackDevMiddleware","webpackHotMiddleware","compiler","serverSideRender","static","path","onExpressJsSetup","ERRORS","NOT_FOUND","CODES","dontAttachDefaultErrorHandler","beforeExpressJsError","error","status","INTERNAL_SERVER_ERROR","serverSide","log","message","process","env","NODE_ENV"],"mappings":"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","sourcesContent":["/**\n * Creation of standard ExpressJS server for ReactJS apps.\n */\n\nimport {\n cloneDeep,\n mapValues,\n pick,\n} from 'lodash';\n\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport express from 'express';\nimport favicon from 'serve-favicon';\nimport helmet from 'helmet';\nimport loggerMiddleware from 'morgan';\nimport requestIp from 'request-ip';\nimport { v4 as uuid } from 'uuid';\n\nimport rendererFactory from './renderer';\n\nimport {\n CODES,\n ERRORS,\n fail,\n getErrorForCode,\n} from './utils/errors';\n\n/**\n * Default Content Security Policy settings.\n * @ignore\n */\nconst defaultCspSettings = {\n directives: mapValues(\n helmet.contentSecurityPolicy.getDefaultDirectives(),\n\n // 'https:' options (automatic re-write of insecure URLs to secure ones)\n // is removed to facilitate local development with HTTP server. In cloud\n // deployments we assume Apache or Nginx server in front of out app takes\n // care about such re-writes.\n (array) => array.filter((item) => item !== 'https:'),\n ),\n};\ndefaultCspSettings.directives['frame-src'] = [\n \"'self'\",\n\n // YouTube domain is whitelisted to allow <YouTubeVideo> component to work\n // out of box.\n 'https://*.youtube.com',\n];\ndefaultCspSettings.directives['script-src'].push(\"'unsafe-eval'\");\n\n// No need for automatic re-writes via Content Security Policy settings:\n// the forefront Apache or Nginx server is supposed to take care of this\n// in production cloud deployments.\ndelete defaultCspSettings.directives['upgrade-insecure-requests'];\n\n/**\n * @category Utilities\n * @func server/getDefaultCspSettings\n * @global\n * @desc\n * ```js\n * import { server } from '@dr.pogodin/react-utils';\n * const { getDefaultCspSettings } from '@dr.pogodin/react-utils';\n * ```\n * @return {{\n * directives: object\n * }} A deep copy of default CSP settings object used by `react-utils`,\n * with the exception of `nonce-xxx` clause in `script-src` directive,\n * which is added dynamically for each request.\n */\nexport function getDefaultCspSettings() {\n return cloneDeep(defaultCspSettings);\n}\n\nexport default async function factory(webpackConfig, options) {\n const rendererOps = pick(options, [\n 'Application',\n 'beforeRender',\n 'favicon',\n 'maxSsrRounds',\n 'noCsp',\n 'ssrTimeout',\n 'staticCacheController',\n 'staticCacheSize',\n ]);\n const renderer = rendererFactory(webpackConfig, rendererOps);\n const { publicPath } = webpackConfig.output;\n\n const server = express();\n\n if (options.beforeExpressJsSetup) {\n await options.beforeExpressJsSetup(server);\n }\n\n server.logger = options.logger;\n\n if (options.httpsRedirect) {\n server.use((req, res, next) => {\n const schema = req.headers['x-forwarded-proto'];\n if (schema === 'http') {\n let url = `https://${req.headers.host}`;\n if (req.originalUrl !== '/') url += req.originalUrl;\n return res.redirect(url);\n }\n return next();\n });\n }\n\n server.use(compression());\n server.use(helmet({ contentSecurityPolicy: false }));\n\n if (!options.noCsp) {\n server.use((req, res, next) => {\n req.nonce = uuid();\n\n // TODO: This is deprecated, but it is kept for now for backward\n // compatibility. Should be removed sometime later.\n req.cspNonce = req.nonce;\n\n // The deep clone is necessary here to ensure that default value can't be\n // mutated during request processing.\n let cspSettings = cloneDeep(defaultCspSettings);\n cspSettings.directives['script-src'].push(`'nonce-${req.nonce}'`);\n if (options.cspSettingsHook) {\n cspSettings = options.cspSettingsHook(cspSettings, req);\n }\n helmet.contentSecurityPolicy(cspSettings)(req, res, next);\n });\n }\n\n if (options.favicon) {\n server.use(favicon(options.favicon));\n }\n\n server.use('/robots.txt', (req, res) => res.send('User-agent: *\\nDisallow:'));\n\n server.use(express.json({ limit: '300kb' }));\n server.use(express.urlencoded({ extended: false }));\n server.use(cookieParser());\n server.use(requestIp.mw());\n\n loggerMiddleware.token('ip', (req) => req.clientIp);\n const FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';\n server.use(loggerMiddleware(FORMAT, {\n stream: {\n write: options.logger.info.bind(options.logger),\n },\n }));\n\n /* Ensures no caching for the service worker script. */\n server.use(`${publicPath}service-worker.js`, (req, res, next) => {\n res.header('Cache-Control', 'no-cache');\n next();\n });\n\n /* Setup of Hot Module Reloading for development environment.\n * These dependencies are not used, nor installed for production use,\n * hence we should violate some import-related lint rules. */\n /* eslint-disable global-require */\n /* eslint-disable import/no-extraneous-dependencies */\n /* eslint-disable import/no-unresolved */\n if (options.devMode) {\n const webpack = require('webpack');\n const webpackDevMiddleware = require('webpack-dev-middleware');\n const webpackHotMiddleware = require('webpack-hot-middleware');\n const compiler = webpack(webpackConfig);\n server.use(webpackDevMiddleware(compiler, {\n publicPath,\n serverSideRender: true,\n }));\n server.use(webpackHotMiddleware(compiler));\n }\n /* eslint-enable global-require */\n /* eslint-enable import/no-extraneous-dependencies */\n /* eslint-enable import/no-unresolved */\n\n server.use(publicPath, express.static(webpackConfig.output.path));\n\n if (options.onExpressJsSetup) {\n await options.onExpressJsSetup(server);\n }\n server.use(renderer);\n\n /* Detects 404 errors, and forwards them to the error handler. */\n server.use(() => fail(ERRORS.NOT_FOUND, CODES.NOT_FOUND));\n\n let dontAttachDefaultErrorHandler;\n if (options.beforeExpressJsError) {\n dontAttachDefaultErrorHandler = await options.beforeExpressJsError(server);\n }\n\n /* Error handler. */\n if (!dontAttachDefaultErrorHandler) {\n // TODO: It is better to move the default error handler definition\n // to a stand-alone function at top-level, but the use of options.logger\n // prevents to do it without some extra refactoring. Should be done sometime\n // though.\n /* eslint-disable no-unused-vars */\n server.use((error, req, res, next) => {\n /* eslint-enable no-unused-vars */\n const status = error.status || CODES.INTERNAL_SERVER_ERROR;\n const serverSide = status >= CODES.INTERNAL_SERVER_ERROR;\n\n // Log server-side errors always, client-side at debug level only.\n options.logger.log(serverSide ? 'error' : 'debug', error);\n\n let message = error.message || getErrorForCode(status);\n if (serverSide && process.env.NODE_ENV === 'production') {\n message = ERRORS.INTERNAL_SERVER_ERROR;\n }\n\n res.status(status).send(message);\n });\n }\n\n return server;\n}\n"],"file":"server.js"}
1
+ {"version":3,"sources":["../../../src/server/server.js"],"names":["defaultCspSettings","directives","helmet","contentSecurityPolicy","getDefaultDirectives","array","filter","item","push","getDefaultCspSettings","factory","webpackConfig","options","rendererOps","renderer","publicPath","output","server","beforeExpressJsSetup","logger","httpsRedirect","use","req","res","next","schema","headers","url","host","originalUrl","redirect","crossOriginEmbedderPolicy","crossOriginOpenerPolicy","crossOriginResourcePolicy","noCsp","nonce","cspNonce","cspSettings","cspSettingsHook","favicon","send","express","json","limit","urlencoded","extended","requestIp","mw","loggerMiddleware","token","clientIp","FORMAT","stream","write","info","bind","header","devMode","webpack","require","webpackDevMiddleware","webpackHotMiddleware","compiler","serverSideRender","static","path","onExpressJsSetup","ERRORS","NOT_FOUND","CODES","dontAttachDefaultErrorHandler","beforeExpressJsError","error","status","INTERNAL_SERVER_ERROR","serverSide","log","message","process","env","NODE_ENV"],"mappings":"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","sourcesContent":["/**\n * Creation of standard ExpressJS server for ReactJS apps.\n */\n\nimport {\n cloneDeep,\n mapValues,\n pick,\n} from 'lodash';\n\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport express from 'express';\nimport favicon from 'serve-favicon';\nimport helmet from 'helmet';\nimport loggerMiddleware from 'morgan';\nimport requestIp from 'request-ip';\nimport { v4 as uuid } from 'uuid';\n\nimport rendererFactory from './renderer';\n\nimport {\n CODES,\n ERRORS,\n fail,\n getErrorForCode,\n} from './utils/errors';\n\n/**\n * Default Content Security Policy settings.\n * @ignore\n */\nconst defaultCspSettings = {\n directives: mapValues(\n helmet.contentSecurityPolicy.getDefaultDirectives(),\n\n // 'https:' options (automatic re-write of insecure URLs to secure ones)\n // is removed to facilitate local development with HTTP server. In cloud\n // deployments we assume Apache or Nginx server in front of out app takes\n // care about such re-writes.\n (array) => array.filter((item) => item !== 'https:'),\n ),\n};\ndefaultCspSettings.directives['frame-src'] = [\n \"'self'\",\n\n // YouTube domain is whitelisted to allow <YouTubeVideo> component to work\n // out of box.\n 'https://*.youtube.com',\n];\ndefaultCspSettings.directives['script-src'].push(\"'unsafe-eval'\");\n\n// No need for automatic re-writes via Content Security Policy settings:\n// the forefront Apache or Nginx server is supposed to take care of this\n// in production cloud deployments.\ndelete defaultCspSettings.directives['upgrade-insecure-requests'];\n\n/**\n * @category Utilities\n * @func server/getDefaultCspSettings\n * @global\n * @desc\n * ```js\n * import { server } from '@dr.pogodin/react-utils';\n * const { getDefaultCspSettings } from '@dr.pogodin/react-utils';\n * ```\n * @return {{\n * directives: object\n * }} A deep copy of default CSP settings object used by `react-utils`,\n * with the exception of `nonce-xxx` clause in `script-src` directive,\n * which is added dynamically for each request.\n */\nexport function getDefaultCspSettings() {\n return cloneDeep(defaultCspSettings);\n}\n\nexport default async function factory(webpackConfig, options) {\n const rendererOps = pick(options, [\n 'Application',\n 'beforeRender',\n 'favicon',\n 'maxSsrRounds',\n 'noCsp',\n 'ssrTimeout',\n 'staticCacheController',\n 'staticCacheSize',\n ]);\n const renderer = rendererFactory(webpackConfig, rendererOps);\n const { publicPath } = webpackConfig.output;\n\n const server = express();\n\n if (options.beforeExpressJsSetup) {\n await options.beforeExpressJsSetup(server);\n }\n\n server.logger = options.logger;\n\n if (options.httpsRedirect) {\n server.use((req, res, next) => {\n const schema = req.headers['x-forwarded-proto'];\n if (schema === 'http') {\n let url = `https://${req.headers.host}`;\n if (req.originalUrl !== '/') url += req.originalUrl;\n return res.redirect(url);\n }\n return next();\n });\n }\n\n server.use(compression());\n server.use(\n helmet({\n contentSecurityPolicy: false,\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n }),\n );\n\n if (!options.noCsp) {\n server.use((req, res, next) => {\n req.nonce = uuid();\n\n // TODO: This is deprecated, but it is kept for now for backward\n // compatibility. Should be removed sometime later.\n req.cspNonce = req.nonce;\n\n // The deep clone is necessary here to ensure that default value can't be\n // mutated during request processing.\n let cspSettings = cloneDeep(defaultCspSettings);\n cspSettings.directives['script-src'].push(`'nonce-${req.nonce}'`);\n if (options.cspSettingsHook) {\n cspSettings = options.cspSettingsHook(cspSettings, req);\n }\n helmet.contentSecurityPolicy(cspSettings)(req, res, next);\n });\n }\n\n if (options.favicon) {\n server.use(favicon(options.favicon));\n }\n\n server.use('/robots.txt', (req, res) => res.send('User-agent: *\\nDisallow:'));\n\n server.use(express.json({ limit: '300kb' }));\n server.use(express.urlencoded({ extended: false }));\n server.use(cookieParser());\n server.use(requestIp.mw());\n\n loggerMiddleware.token('ip', (req) => req.clientIp);\n const FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';\n server.use(loggerMiddleware(FORMAT, {\n stream: {\n write: options.logger.info.bind(options.logger),\n },\n }));\n\n /* Ensures no caching for the service worker script. */\n server.use(`${publicPath}service-worker.js`, (req, res, next) => {\n res.header('Cache-Control', 'no-cache');\n next();\n });\n\n /* Setup of Hot Module Reloading for development environment.\n * These dependencies are not used, nor installed for production use,\n * hence we should violate some import-related lint rules. */\n /* eslint-disable global-require */\n /* eslint-disable import/no-extraneous-dependencies */\n /* eslint-disable import/no-unresolved */\n if (options.devMode) {\n const webpack = require('webpack');\n const webpackDevMiddleware = require('webpack-dev-middleware');\n const webpackHotMiddleware = require('webpack-hot-middleware');\n const compiler = webpack(webpackConfig);\n server.use(webpackDevMiddleware(compiler, {\n publicPath,\n serverSideRender: true,\n }));\n server.use(webpackHotMiddleware(compiler));\n }\n /* eslint-enable global-require */\n /* eslint-enable import/no-extraneous-dependencies */\n /* eslint-enable import/no-unresolved */\n\n server.use(publicPath, express.static(webpackConfig.output.path));\n\n if (options.onExpressJsSetup) {\n await options.onExpressJsSetup(server);\n }\n server.use(renderer);\n\n /* Detects 404 errors, and forwards them to the error handler. */\n server.use(() => fail(ERRORS.NOT_FOUND, CODES.NOT_FOUND));\n\n let dontAttachDefaultErrorHandler;\n if (options.beforeExpressJsError) {\n dontAttachDefaultErrorHandler = await options.beforeExpressJsError(server);\n }\n\n /* Error handler. */\n if (!dontAttachDefaultErrorHandler) {\n // TODO: It is better to move the default error handler definition\n // to a stand-alone function at top-level, but the use of options.logger\n // prevents to do it without some extra refactoring. Should be done sometime\n // though.\n /* eslint-disable no-unused-vars */\n server.use((error, req, res, next) => {\n /* eslint-enable no-unused-vars */\n const status = error.status || CODES.INTERNAL_SERVER_ERROR;\n const serverSide = status >= CODES.INTERNAL_SERVER_ERROR;\n\n // Log server-side errors always, client-side at debug level only.\n options.logger.log(serverSide ? 'error' : 'debug', error);\n\n let message = error.message || getErrorForCode(status);\n if (serverSide && process.env.NODE_ENV === 'production') {\n message = ERRORS.INTERNAL_SERVER_ERROR;\n }\n\n res.status(status).send(message);\n });\n }\n\n return server;\n}\n"],"file":"server.js"}
@@ -26,7 +26,7 @@ delete defaultCspSettings.directives["upgrade-insecure-requests"];/**
26
26
  * }} A deep copy of default CSP settings object used by `react-utils`,
27
27
  * with the exception of `nonce-xxx` clause in `script-src` directive,
28
28
  * which is added dynamically for each request.
29
- */function getDefaultCspSettings(){return(0,_lodash.cloneDeep)(defaultCspSettings)}async function factory(webpackConfig,options){const rendererOps=(0,_lodash.pick)(options,["Application","beforeRender","favicon","maxSsrRounds","noCsp","ssrTimeout","staticCacheController","staticCacheSize"]);const renderer=(0,_renderer.default)(webpackConfig,rendererOps);const{publicPath}=webpackConfig.output;const server=(0,_express.default)();if(options.beforeExpressJsSetup){await options.beforeExpressJsSetup(server)}server.logger=options.logger;if(options.httpsRedirect){server.use((req,res,next)=>{const schema=req.headers["x-forwarded-proto"];if(schema==="http"){let url=`https://${req.headers.host}`;if(req.originalUrl!=="/")url+=req.originalUrl;return res.redirect(url)}return next()})}server.use((0,_compression.default)());server.use((0,_helmet.default)({contentSecurityPolicy:false}));if(!options.noCsp){server.use((req,res,next)=>{req.nonce=(0,_uuid.v4)();// TODO: This is deprecated, but it is kept for now for backward
29
+ */function getDefaultCspSettings(){return(0,_lodash.cloneDeep)(defaultCspSettings)}async function factory(webpackConfig,options){const rendererOps=(0,_lodash.pick)(options,["Application","beforeRender","favicon","maxSsrRounds","noCsp","ssrTimeout","staticCacheController","staticCacheSize"]);const renderer=(0,_renderer.default)(webpackConfig,rendererOps);const{publicPath}=webpackConfig.output;const server=(0,_express.default)();if(options.beforeExpressJsSetup){await options.beforeExpressJsSetup(server)}server.logger=options.logger;if(options.httpsRedirect){server.use((req,res,next)=>{const schema=req.headers["x-forwarded-proto"];if(schema==="http"){let url=`https://${req.headers.host}`;if(req.originalUrl!=="/")url+=req.originalUrl;return res.redirect(url)}return next()})}server.use((0,_compression.default)());server.use((0,_helmet.default)({contentSecurityPolicy:false,crossOriginEmbedderPolicy:false,crossOriginOpenerPolicy:false,crossOriginResourcePolicy:false}));if(!options.noCsp){server.use((req,res,next)=>{req.nonce=(0,_uuid.v4)();// TODO: This is deprecated, but it is kept for now for backward
30
30
  // compatibility. Should be removed sometime later.
31
31
  req.cspNonce=req.nonce;// The deep clone is necessary here to ensure that default value can't be
32
32
  // mutated during request processing.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/server.js"],"names":["defaultCspSettings","directives","helmet","contentSecurityPolicy","getDefaultDirectives","array","filter","item","push","getDefaultCspSettings","factory","webpackConfig","options","rendererOps","renderer","publicPath","output","server","beforeExpressJsSetup","logger","httpsRedirect","use","req","res","next","schema","headers","url","host","originalUrl","redirect","noCsp","nonce","cspNonce","cspSettings","cspSettingsHook","favicon","send","express","json","limit","urlencoded","extended","requestIp","mw","loggerMiddleware","token","clientIp","FORMAT","stream","write","info","bind","header","devMode","webpack","require","webpackDevMiddleware","webpackHotMiddleware","compiler","serverSideRender","static","path","onExpressJsSetup","ERRORS","NOT_FOUND","CODES","dontAttachDefaultErrorHandler","beforeExpressJsError","error","status","INTERNAL_SERVER_ERROR","serverSide","log","message","process","env","NODE_ENV"],"mappings":"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","sourcesContent":["/**\n * Creation of standard ExpressJS server for ReactJS apps.\n */\n\nimport {\n cloneDeep,\n mapValues,\n pick,\n} from 'lodash';\n\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport express from 'express';\nimport favicon from 'serve-favicon';\nimport helmet from 'helmet';\nimport loggerMiddleware from 'morgan';\nimport requestIp from 'request-ip';\nimport { v4 as uuid } from 'uuid';\n\nimport rendererFactory from './renderer';\n\nimport {\n CODES,\n ERRORS,\n fail,\n getErrorForCode,\n} from './utils/errors';\n\n/**\n * Default Content Security Policy settings.\n * @ignore\n */\nconst defaultCspSettings = {\n directives: mapValues(\n helmet.contentSecurityPolicy.getDefaultDirectives(),\n\n // 'https:' options (automatic re-write of insecure URLs to secure ones)\n // is removed to facilitate local development with HTTP server. In cloud\n // deployments we assume Apache or Nginx server in front of out app takes\n // care about such re-writes.\n (array) => array.filter((item) => item !== 'https:'),\n ),\n};\ndefaultCspSettings.directives['frame-src'] = [\n \"'self'\",\n\n // YouTube domain is whitelisted to allow <YouTubeVideo> component to work\n // out of box.\n 'https://*.youtube.com',\n];\ndefaultCspSettings.directives['script-src'].push(\"'unsafe-eval'\");\n\n// No need for automatic re-writes via Content Security Policy settings:\n// the forefront Apache or Nginx server is supposed to take care of this\n// in production cloud deployments.\ndelete defaultCspSettings.directives['upgrade-insecure-requests'];\n\n/**\n * @category Utilities\n * @func server/getDefaultCspSettings\n * @global\n * @desc\n * ```js\n * import { server } from '@dr.pogodin/react-utils';\n * const { getDefaultCspSettings } from '@dr.pogodin/react-utils';\n * ```\n * @return {{\n * directives: object\n * }} A deep copy of default CSP settings object used by `react-utils`,\n * with the exception of `nonce-xxx` clause in `script-src` directive,\n * which is added dynamically for each request.\n */\nexport function getDefaultCspSettings() {\n return cloneDeep(defaultCspSettings);\n}\n\nexport default async function factory(webpackConfig, options) {\n const rendererOps = pick(options, [\n 'Application',\n 'beforeRender',\n 'favicon',\n 'maxSsrRounds',\n 'noCsp',\n 'ssrTimeout',\n 'staticCacheController',\n 'staticCacheSize',\n ]);\n const renderer = rendererFactory(webpackConfig, rendererOps);\n const { publicPath } = webpackConfig.output;\n\n const server = express();\n\n if (options.beforeExpressJsSetup) {\n await options.beforeExpressJsSetup(server);\n }\n\n server.logger = options.logger;\n\n if (options.httpsRedirect) {\n server.use((req, res, next) => {\n const schema = req.headers['x-forwarded-proto'];\n if (schema === 'http') {\n let url = `https://${req.headers.host}`;\n if (req.originalUrl !== '/') url += req.originalUrl;\n return res.redirect(url);\n }\n return next();\n });\n }\n\n server.use(compression());\n server.use(helmet({ contentSecurityPolicy: false }));\n\n if (!options.noCsp) {\n server.use((req, res, next) => {\n req.nonce = uuid();\n\n // TODO: This is deprecated, but it is kept for now for backward\n // compatibility. Should be removed sometime later.\n req.cspNonce = req.nonce;\n\n // The deep clone is necessary here to ensure that default value can't be\n // mutated during request processing.\n let cspSettings = cloneDeep(defaultCspSettings);\n cspSettings.directives['script-src'].push(`'nonce-${req.nonce}'`);\n if (options.cspSettingsHook) {\n cspSettings = options.cspSettingsHook(cspSettings, req);\n }\n helmet.contentSecurityPolicy(cspSettings)(req, res, next);\n });\n }\n\n if (options.favicon) {\n server.use(favicon(options.favicon));\n }\n\n server.use('/robots.txt', (req, res) => res.send('User-agent: *\\nDisallow:'));\n\n server.use(express.json({ limit: '300kb' }));\n server.use(express.urlencoded({ extended: false }));\n server.use(cookieParser());\n server.use(requestIp.mw());\n\n loggerMiddleware.token('ip', (req) => req.clientIp);\n const FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';\n server.use(loggerMiddleware(FORMAT, {\n stream: {\n write: options.logger.info.bind(options.logger),\n },\n }));\n\n /* Ensures no caching for the service worker script. */\n server.use(`${publicPath}service-worker.js`, (req, res, next) => {\n res.header('Cache-Control', 'no-cache');\n next();\n });\n\n /* Setup of Hot Module Reloading for development environment.\n * These dependencies are not used, nor installed for production use,\n * hence we should violate some import-related lint rules. */\n /* eslint-disable global-require */\n /* eslint-disable import/no-extraneous-dependencies */\n /* eslint-disable import/no-unresolved */\n if (options.devMode) {\n const webpack = require('webpack');\n const webpackDevMiddleware = require('webpack-dev-middleware');\n const webpackHotMiddleware = require('webpack-hot-middleware');\n const compiler = webpack(webpackConfig);\n server.use(webpackDevMiddleware(compiler, {\n publicPath,\n serverSideRender: true,\n }));\n server.use(webpackHotMiddleware(compiler));\n }\n /* eslint-enable global-require */\n /* eslint-enable import/no-extraneous-dependencies */\n /* eslint-enable import/no-unresolved */\n\n server.use(publicPath, express.static(webpackConfig.output.path));\n\n if (options.onExpressJsSetup) {\n await options.onExpressJsSetup(server);\n }\n server.use(renderer);\n\n /* Detects 404 errors, and forwards them to the error handler. */\n server.use(() => fail(ERRORS.NOT_FOUND, CODES.NOT_FOUND));\n\n let dontAttachDefaultErrorHandler;\n if (options.beforeExpressJsError) {\n dontAttachDefaultErrorHandler = await options.beforeExpressJsError(server);\n }\n\n /* Error handler. */\n if (!dontAttachDefaultErrorHandler) {\n // TODO: It is better to move the default error handler definition\n // to a stand-alone function at top-level, but the use of options.logger\n // prevents to do it without some extra refactoring. Should be done sometime\n // though.\n /* eslint-disable no-unused-vars */\n server.use((error, req, res, next) => {\n /* eslint-enable no-unused-vars */\n const status = error.status || CODES.INTERNAL_SERVER_ERROR;\n const serverSide = status >= CODES.INTERNAL_SERVER_ERROR;\n\n // Log server-side errors always, client-side at debug level only.\n options.logger.log(serverSide ? 'error' : 'debug', error);\n\n let message = error.message || getErrorForCode(status);\n if (serverSide && process.env.NODE_ENV === 'production') {\n message = ERRORS.INTERNAL_SERVER_ERROR;\n }\n\n res.status(status).send(message);\n });\n }\n\n return server;\n}\n"],"file":"server.js"}
1
+ {"version":3,"sources":["../../../src/server/server.js"],"names":["defaultCspSettings","directives","helmet","contentSecurityPolicy","getDefaultDirectives","array","filter","item","push","getDefaultCspSettings","factory","webpackConfig","options","rendererOps","renderer","publicPath","output","server","beforeExpressJsSetup","logger","httpsRedirect","use","req","res","next","schema","headers","url","host","originalUrl","redirect","crossOriginEmbedderPolicy","crossOriginOpenerPolicy","crossOriginResourcePolicy","noCsp","nonce","cspNonce","cspSettings","cspSettingsHook","favicon","send","express","json","limit","urlencoded","extended","requestIp","mw","loggerMiddleware","token","clientIp","FORMAT","stream","write","info","bind","header","devMode","webpack","require","webpackDevMiddleware","webpackHotMiddleware","compiler","serverSideRender","static","path","onExpressJsSetup","ERRORS","NOT_FOUND","CODES","dontAttachDefaultErrorHandler","beforeExpressJsError","error","status","INTERNAL_SERVER_ERROR","serverSide","log","message","process","env","NODE_ENV"],"mappings":"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","sourcesContent":["/**\n * Creation of standard ExpressJS server for ReactJS apps.\n */\n\nimport {\n cloneDeep,\n mapValues,\n pick,\n} from 'lodash';\n\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport express from 'express';\nimport favicon from 'serve-favicon';\nimport helmet from 'helmet';\nimport loggerMiddleware from 'morgan';\nimport requestIp from 'request-ip';\nimport { v4 as uuid } from 'uuid';\n\nimport rendererFactory from './renderer';\n\nimport {\n CODES,\n ERRORS,\n fail,\n getErrorForCode,\n} from './utils/errors';\n\n/**\n * Default Content Security Policy settings.\n * @ignore\n */\nconst defaultCspSettings = {\n directives: mapValues(\n helmet.contentSecurityPolicy.getDefaultDirectives(),\n\n // 'https:' options (automatic re-write of insecure URLs to secure ones)\n // is removed to facilitate local development with HTTP server. In cloud\n // deployments we assume Apache or Nginx server in front of out app takes\n // care about such re-writes.\n (array) => array.filter((item) => item !== 'https:'),\n ),\n};\ndefaultCspSettings.directives['frame-src'] = [\n \"'self'\",\n\n // YouTube domain is whitelisted to allow <YouTubeVideo> component to work\n // out of box.\n 'https://*.youtube.com',\n];\ndefaultCspSettings.directives['script-src'].push(\"'unsafe-eval'\");\n\n// No need for automatic re-writes via Content Security Policy settings:\n// the forefront Apache or Nginx server is supposed to take care of this\n// in production cloud deployments.\ndelete defaultCspSettings.directives['upgrade-insecure-requests'];\n\n/**\n * @category Utilities\n * @func server/getDefaultCspSettings\n * @global\n * @desc\n * ```js\n * import { server } from '@dr.pogodin/react-utils';\n * const { getDefaultCspSettings } from '@dr.pogodin/react-utils';\n * ```\n * @return {{\n * directives: object\n * }} A deep copy of default CSP settings object used by `react-utils`,\n * with the exception of `nonce-xxx` clause in `script-src` directive,\n * which is added dynamically for each request.\n */\nexport function getDefaultCspSettings() {\n return cloneDeep(defaultCspSettings);\n}\n\nexport default async function factory(webpackConfig, options) {\n const rendererOps = pick(options, [\n 'Application',\n 'beforeRender',\n 'favicon',\n 'maxSsrRounds',\n 'noCsp',\n 'ssrTimeout',\n 'staticCacheController',\n 'staticCacheSize',\n ]);\n const renderer = rendererFactory(webpackConfig, rendererOps);\n const { publicPath } = webpackConfig.output;\n\n const server = express();\n\n if (options.beforeExpressJsSetup) {\n await options.beforeExpressJsSetup(server);\n }\n\n server.logger = options.logger;\n\n if (options.httpsRedirect) {\n server.use((req, res, next) => {\n const schema = req.headers['x-forwarded-proto'];\n if (schema === 'http') {\n let url = `https://${req.headers.host}`;\n if (req.originalUrl !== '/') url += req.originalUrl;\n return res.redirect(url);\n }\n return next();\n });\n }\n\n server.use(compression());\n server.use(\n helmet({\n contentSecurityPolicy: false,\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n }),\n );\n\n if (!options.noCsp) {\n server.use((req, res, next) => {\n req.nonce = uuid();\n\n // TODO: This is deprecated, but it is kept for now for backward\n // compatibility. Should be removed sometime later.\n req.cspNonce = req.nonce;\n\n // The deep clone is necessary here to ensure that default value can't be\n // mutated during request processing.\n let cspSettings = cloneDeep(defaultCspSettings);\n cspSettings.directives['script-src'].push(`'nonce-${req.nonce}'`);\n if (options.cspSettingsHook) {\n cspSettings = options.cspSettingsHook(cspSettings, req);\n }\n helmet.contentSecurityPolicy(cspSettings)(req, res, next);\n });\n }\n\n if (options.favicon) {\n server.use(favicon(options.favicon));\n }\n\n server.use('/robots.txt', (req, res) => res.send('User-agent: *\\nDisallow:'));\n\n server.use(express.json({ limit: '300kb' }));\n server.use(express.urlencoded({ extended: false }));\n server.use(cookieParser());\n server.use(requestIp.mw());\n\n loggerMiddleware.token('ip', (req) => req.clientIp);\n const FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';\n server.use(loggerMiddleware(FORMAT, {\n stream: {\n write: options.logger.info.bind(options.logger),\n },\n }));\n\n /* Ensures no caching for the service worker script. */\n server.use(`${publicPath}service-worker.js`, (req, res, next) => {\n res.header('Cache-Control', 'no-cache');\n next();\n });\n\n /* Setup of Hot Module Reloading for development environment.\n * These dependencies are not used, nor installed for production use,\n * hence we should violate some import-related lint rules. */\n /* eslint-disable global-require */\n /* eslint-disable import/no-extraneous-dependencies */\n /* eslint-disable import/no-unresolved */\n if (options.devMode) {\n const webpack = require('webpack');\n const webpackDevMiddleware = require('webpack-dev-middleware');\n const webpackHotMiddleware = require('webpack-hot-middleware');\n const compiler = webpack(webpackConfig);\n server.use(webpackDevMiddleware(compiler, {\n publicPath,\n serverSideRender: true,\n }));\n server.use(webpackHotMiddleware(compiler));\n }\n /* eslint-enable global-require */\n /* eslint-enable import/no-extraneous-dependencies */\n /* eslint-enable import/no-unresolved */\n\n server.use(publicPath, express.static(webpackConfig.output.path));\n\n if (options.onExpressJsSetup) {\n await options.onExpressJsSetup(server);\n }\n server.use(renderer);\n\n /* Detects 404 errors, and forwards them to the error handler. */\n server.use(() => fail(ERRORS.NOT_FOUND, CODES.NOT_FOUND));\n\n let dontAttachDefaultErrorHandler;\n if (options.beforeExpressJsError) {\n dontAttachDefaultErrorHandler = await options.beforeExpressJsError(server);\n }\n\n /* Error handler. */\n if (!dontAttachDefaultErrorHandler) {\n // TODO: It is better to move the default error handler definition\n // to a stand-alone function at top-level, but the use of options.logger\n // prevents to do it without some extra refactoring. Should be done sometime\n // though.\n /* eslint-disable no-unused-vars */\n server.use((error, req, res, next) => {\n /* eslint-enable no-unused-vars */\n const status = error.status || CODES.INTERNAL_SERVER_ERROR;\n const serverSide = status >= CODES.INTERNAL_SERVER_ERROR;\n\n // Log server-side errors always, client-side at debug level only.\n options.logger.log(serverSide ? 'error' : 'debug', error);\n\n let message = error.message || getErrorForCode(status);\n if (serverSide && process.env.NODE_ENV === 'production') {\n message = ERRORS.INTERNAL_SERVER_ERROR;\n }\n\n res.status(status).send(message);\n });\n }\n\n return server;\n}\n"],"file":"server.js"}
package/package.json CHANGED
@@ -130,5 +130,5 @@
130
130
  "lint:scss": "stylelint -- **/*.{css,scss}",
131
131
  "test": "npm run lint && npm run jest"
132
132
  },
133
- "version": "1.12.10"
133
+ "version": "1.13.0"
134
134
  }