From be8191de6071a2b5b54fce821779d4e17426408d Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Tue, 20 Jun 2017 02:40:54 +0430 Subject: [PATCH] protect serving SSR assets in production --- lib/core/renderer.js | 54 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/core/renderer.js b/lib/core/renderer.js index 8fce6fb271..ab6bdc9402 100644 --- a/lib/core/renderer.js +++ b/lib/core/renderer.js @@ -24,6 +24,27 @@ const parseTemplate = templateStr => _.template(templateStr, { interpolate: /{{([\s\S]+?)}}/g }) +const resourceMap = [ + { + key: 'clientManifest', + fileName: 'vue-ssr-client-manifest.json', + transform: JSON.parse + }, + { + key: 'serverBundle', + fileName: 'server-bundle.json', + transform: JSON.parse + }, + { + key: 'appTemplate', + fileName: 'index.html', + transform: parseTemplate + } +] + +// Protector utility against request to SSR bundle files +const ssrResourceRegex = new RegExp(resourceMap.map(resource => resource.fileName).join('|'), 'i') + export default class Renderer extends Tapable { constructor (nuxt) { super() @@ -91,29 +112,15 @@ export default class Renderer extends Tapable { return this } - async loadResources (_fs = fs, isServer) { + async loadResources (_fs) { let distPath = resolve(this.options.buildDir, 'dist') - const resourceMap = { - clientManifest: { - path: join(distPath, 'vue-ssr-client-manifest.json'), - transform: JSON.parse - }, - serverBundle: { - path: join(distPath, 'server-bundle.json'), - transform: JSON.parse - }, - appTemplate: { - path: join(distPath, 'index.html'), - transform: parseTemplate - } - } - let updated = [] - Object.keys(resourceMap).forEach(resourceKey => { - let { path, transform } = resourceMap[resourceKey] - let rawKey = '$$' + resourceKey + resourceMap.forEach(({ key, fileName, transform }) => { + let rawKey = '$$' + key + const path = join(distPath, fileName) + let rawData, data if (!_fs.existsSync(path)) { return // Resource not exists @@ -128,8 +135,8 @@ export default class Renderer extends Tapable { if (!data) { return // Invalid data ? } - this.resources[resourceKey] = data - updated.push(resourceKey) + this.resources[key] = data + updated.push(key) }) if (updated.length > 0) { @@ -151,7 +158,7 @@ export default class Renderer extends Tapable { basedir: this.options.rootDir }, this.options.render.ssr, this.options.build.ssr)) - if(this.options.build.ssr) { + if (this.options.build.ssr) { console.warn('[nuxt] `build.ssr` is deprecated and will be removed in 1.0 release, please use `renderer.ssr` instead!') } @@ -189,8 +196,7 @@ export default class Renderer extends Tapable { await this.serveStatic(req, res) // Serve .nuxt/dist/ files (only for production) - const isValidExtension = (req.url.slice(-3) === '.js') || (req.url.slice(-4) === '.css') || (req.url.slice(-4) === '.map') - if (!this.options.dev && isValidExtension) { + if (!this.options.dev && !ssrResourceRegex.test(req.url)) { const url = req.url if (req.url.indexOf(this.options.build.publicPath) === 0) { req.url = req.url.replace(this.options.build.publicPath, '/')