fix(nuxt): restrict access to single renderer outside of test/rootDir (#20543)

This commit is contained in:
Daniel Roe 2023-04-27 11:31:52 +01:00 committed by GitHub
parent 48c034cf02
commit 65a8f4eb3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 19 additions and 3 deletions

View File

@ -23,7 +23,7 @@ const nuxtApp = useNuxtApp()
const onResolve = nuxtApp.deferHydration() const onResolve = nuxtApp.deferHydration()
const url = process.server ? nuxtApp.ssrContext.url : window.location.pathname const url = process.server ? nuxtApp.ssrContext.url : window.location.pathname
const SingleRenderer = process.dev && process.server && url.startsWith('/__nuxt_component_test__/') && defineAsyncComponent(() => import('#build/test-component-wrapper.mjs') const SingleRenderer = process.test && process.dev && process.server && url.startsWith('/__nuxt_component_test__/') && /* #__PURE__ */ defineAsyncComponent(() => import('#build/test-component-wrapper.mjs')
.then(r => r.default(process.server ? url : window.location.href))) .then(r => r.default(process.server ? url : window.location.href)))
// Inject default route (outside of pages) as active route // Inject default route (outside of pages) as active route

View File

@ -1,13 +1,20 @@
import { parseURL } from 'ufo' import { parseURL } from 'ufo'
import { defineComponent, h } from 'vue' import { defineComponent, h } from 'vue'
import { parseQuery } from 'vue-router' import { parseQuery } from 'vue-router'
import { resolve } from 'pathe'
// @ts-expect-error virtual file
import { devRootDir } from '#build/nuxt.config.mjs'
export default (url:string) => defineComponent({ export default (url: string) => defineComponent({
name: 'NuxtTestComponentWrapper', name: 'NuxtTestComponentWrapper',
async setup (props, { attrs }) { async setup (props, { attrs }) {
const query = parseQuery(parseURL(url).search) const query = parseQuery(parseURL(url).search)
const urlProps = query.props ? JSON.parse(query.props as string) : {} const urlProps = query.props ? JSON.parse(query.props as string) : {}
const path = resolve(query.path as string)
if (!path.startsWith(devRootDir)) {
throw new Error(`[nuxt] Cannot access path outside of project root directory: \`${path}\`.`)
}
const comp = await import(/* @vite-ignore */ query.path as string).then(r => r.default) const comp = await import(/* @vite-ignore */ query.path as string).then(r => r.default)
return () => [ return () => [
h('div', 'Component Test Wrapper for ' + query.path), h('div', 'Component Test Wrapper for ' + query.path),

View File

@ -299,7 +299,8 @@ export const nuxtConfigTemplate = {
return [ return [
...Object.entries(ctx.nuxt.options.app).map(([k, v]) => `export const ${camelCase('app-' + k)} = ${JSON.stringify(v)}`), ...Object.entries(ctx.nuxt.options.app).map(([k, v]) => `export const ${camelCase('app-' + k)} = ${JSON.stringify(v)}`),
`export const renderJsonPayloads = ${!!ctx.nuxt.options.experimental.renderJsonPayloads}`, `export const renderJsonPayloads = ${!!ctx.nuxt.options.experimental.renderJsonPayloads}`,
`export const devPagesDir = ${ctx.nuxt.options.dev ? JSON.stringify(ctx.nuxt.options.dir.pages) : 'null'}` `export const devPagesDir = ${ctx.nuxt.options.dev ? JSON.stringify(ctx.nuxt.options.dir.pages) : 'null'}`,
`export const devRootDir = ${ctx.nuxt.options.dev ? JSON.stringify(ctx.nuxt.options.rootDir) : 'null'}`
].join('\n\n') ].join('\n\n')
} }
} }

View File

@ -1,4 +1,5 @@
import { resolve } from 'pathe' import { resolve } from 'pathe'
import { isTest } from 'std-env'
import { withoutLeadingSlash } from 'ufo' import { withoutLeadingSlash } from 'ufo'
import { defineUntypedSchema } from 'untyped' import { defineUntypedSchema } from 'untyped'
@ -21,6 +22,7 @@ export default defineUntypedSchema({
define: { define: {
$resolve: async (val, get) => ({ $resolve: async (val, get) => ({
'process.dev': await get('dev'), 'process.dev': await get('dev'),
'process.test': isTest,
...val || {} ...val || {}
}) })
}, },

View File

@ -45,6 +45,7 @@
"postcss-import": "^15.1.0", "postcss-import": "^15.1.0",
"postcss-loader": "^7.2.4", "postcss-loader": "^7.2.4",
"postcss-url": "^10.1.3", "postcss-url": "^10.1.3",
"std-env": "^3.3.2",
"time-fix-plugin": "^2.0.7", "time-fix-plugin": "^2.0.7",
"ufo": "^1.1.1", "ufo": "^1.1.1",
"unplugin": "^1.3.1", "unplugin": "^1.3.1",

View File

@ -10,6 +10,7 @@ import FriendlyErrorsWebpackPlugin from '@nuxt/friendly-errors-webpack-plugin'
import escapeRegExp from 'escape-string-regexp' import escapeRegExp from 'escape-string-regexp'
import { joinURL } from 'ufo' import { joinURL } from 'ufo'
import type { NuxtOptions } from '@nuxt/schema' import type { NuxtOptions } from '@nuxt/schema'
import { isTest } from 'std-env'
import type { WarningFilter } from '../plugins/warning-ignore' import type { WarningFilter } from '../plugins/warning-ignore'
import WarningIgnorePlugin from '../plugins/warning-ignore' import WarningIgnorePlugin from '../plugins/warning-ignore'
import type { WebpackConfigContext } from '../utils/config' import type { WebpackConfigContext } from '../utils/config'
@ -233,6 +234,7 @@ function getEnv (ctx: WebpackConfigContext) {
'process.env.NODE_ENV': JSON.stringify(ctx.config.mode), 'process.env.NODE_ENV': JSON.stringify(ctx.config.mode),
'process.mode': JSON.stringify(ctx.config.mode), 'process.mode': JSON.stringify(ctx.config.mode),
'process.dev': options.dev, 'process.dev': options.dev,
'process.test': isTest,
__NUXT_VERSION__: JSON.stringify(ctx.nuxt._version), __NUXT_VERSION__: JSON.stringify(ctx.nuxt._version),
'process.env.VUE_ENV': JSON.stringify(ctx.name), 'process.env.VUE_ENV': JSON.stringify(ctx.name),
'process.browser': ctx.isClient, 'process.browser': ctx.isClient,

View File

@ -1044,6 +1044,9 @@ importers:
postcss-url: postcss-url:
specifier: ^10.1.3 specifier: ^10.1.3
version: 10.1.3(postcss@8.4.23) version: 10.1.3(postcss@8.4.23)
std-env:
specifier: ^3.3.2
version: 3.3.2
time-fix-plugin: time-fix-plugin:
specifier: ^2.0.7 specifier: ^2.0.7
version: 2.0.7(webpack@5.80.0) version: 2.0.7(webpack@5.80.0)