diff --git a/services/web/app/src/infrastructure/ExpressLocals.js b/services/web/app/src/infrastructure/ExpressLocals.js index 3318d2e47f..63a4b59f1d 100644 --- a/services/web/app/src/infrastructure/ExpressLocals.js +++ b/services/web/app/src/infrastructure/ExpressLocals.js @@ -77,6 +77,12 @@ module.exports = function(webRouter, privateApiRouter, publicApiRouter) { staticFilesBase = '' } + res.locals.buildBaseAssetPath = function() { + // Return the base asset path (including the CDN url) so that webpack can + // use this to dynamically fetch scripts (e.g. PDFjs worker) + return Url.resolve(staticFilesBase, '/') + } + res.locals.buildJsPath = function(jsFile) { let path if (IS_DEV_ENV) { @@ -88,7 +94,7 @@ module.exports = function(webRouter, privateApiRouter, publicApiRouter) { // In production: resolve path from webpack manifest file // We are guaranteed to have a manifest file since webpack compiles in // the build - path = webpackManifest[jsFile] + path = `/${webpackManifest[jsFile]}` } return Url.resolve(staticFilesBase, path) @@ -96,7 +102,7 @@ module.exports = function(webRouter, privateApiRouter, publicApiRouter) { // Temporary hack while jQuery/Angular dependencies are *not* bundled, // instead copied into output directory - res.locals.buildCopiedJsAssetPath = function(jsFile, opts = {}) { + res.locals.buildCopiedJsAssetPath = function(jsFile) { let path if (IS_DEV_ENV) { // In dev: resolve path to root directory @@ -107,27 +113,17 @@ module.exports = function(webRouter, privateApiRouter, publicApiRouter) { // In production: resolve path from webpack manifest file // We are guaranteed to have a manifest file since webpack compiles in // the build - path = webpackManifest[jsFile] + path = `/${webpackManifest[jsFile]}` } - if (opts.cdn !== false) { - path = Url.resolve(staticFilesBase, path) - } - - if (opts.qs) { - path = path + '?' + querystring.stringify(opts.qs) - } - - return path + return Url.resolve(staticFilesBase, path) } - res.locals.mathJaxPath = res.locals.buildCopiedJsAssetPath( - 'js/libs/mathjax/MathJax.js', + res.locals.mathJaxPath = `/js/libs/mathjax/MathJax.js?${querystring.stringify( { - cdn: false, - qs: { config: 'TeX-AMS_HTML,Safe' } + config: 'TeX-AMS_HTML,Safe' } - ) + )}` res.locals.lib = PackageVersions.lib @@ -168,7 +164,7 @@ module.exports = function(webRouter, privateApiRouter, publicApiRouter) { // In production: resolve path from webpack manifest file // We are guaranteed to have a manifest file since webpack compiles in // the build - path = webpackManifest[cssFileName] + path = `/${webpackManifest[cssFileName]}` } return Url.resolve(staticFilesBase, path) diff --git a/services/web/app/views/layout.pug b/services/web/app/views/layout.pug index c2595b1d0c..924276ea11 100644 --- a/services/web/app/views/layout.pug +++ b/services/web/app/views/layout.pug @@ -47,6 +47,9 @@ html( script(type="text/javascript"). window.csrfToken = "#{csrfToken}"; + //- Configure dynamically loaded assets (via webpack) to be downloaded from CDN + //- See: https://webpack.js.org/guides/public-path/#on-the-fly + window.baseAssetPath = "#{buildBaseAssetPath()}" script(src=buildCopiedJsAssetPath('js/libs/jquery-1.11.1.min.js')) script(type="text/javascript"). diff --git a/services/web/frontend/js/base.js b/services/web/frontend/js/base.js index a319f7881f..a06f41ac7f 100644 --- a/services/web/frontend/js/base.js +++ b/services/web/frontend/js/base.js @@ -14,6 +14,11 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ + +// Configure dynamically loaded assets (via webpack) to be downloaded from CDN +// See: https://webpack.js.org/guides/public-path/#on-the-fly +__webpack_public_path__ = window.baseAssetPath + define([ 'libraries', 'libs/polyfills/symbol', diff --git a/services/web/webpack.config.js b/services/web/webpack.config.js index 110c6356f0..24cef9477c 100644 --- a/services/web/webpack.config.js +++ b/services/web/webpack.config.js @@ -41,9 +41,6 @@ module.exports = { output: { path: path.join(__dirname, '/public'), - // Serve from the root of public directory - publicPath: '/', - // By default write into js directory filename: 'js/[name].js', @@ -82,7 +79,12 @@ module.exports = { options: { // Write into js directory (note: customising this is not possible // with pdfjs-dist/webpack auto loader) - name: 'js/pdfjs-worker.[hash].js' + name: 'js/pdfjs-worker.[hash].js', + // Override dynamically-set publicPath to explicitly use root. + // This prevents a security problem where the Worker - normally + // loaded from a CDN - has cross-origin issues, by forcing it to not + // be loaded from the CDN + publicPath: '/' } } ]