Skip to content

Commit

Permalink
nonce WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
vezaynk authored Nov 4, 2023
1 parent ff8043e commit 0a99ad3
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ You can optionally provide configuration options to the plugin:
- `heads` - Function that will return html tags to be appended to the document head tag
- `tails` - Function that will return html tags to be appended to the document body tag
- `transform` - Function that will be run to transform the root react element
- `postRenderHeads` - Function (called after render) that will return html tags to be appended to the document head tag. Useful when injecting styles that rely on rendering first.
- `postRenderHeads` - Function (called after render) that will return html tags to be appended to the document head tag. Useful when injecting styles that rely on rendering first. (Not available in streaming mode)

The plugin will render the component server side and return it, where as the route handler will return the props to the frontend when needed.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"release": "pnpm -F=fastify-renderer publish",
"preinstall": "npx only-allow pnpm",
"prerelease": "pnpm -F=fastify-renderer run gitpkg publish",
"test": "jest --forceExit -w=1",
"test": "jest --forceExit --runInBand",
"test:debug": "cross-env FR_DEBUG_SERVE=1 node --inspect-brk ./node_modules/.bin/jest --forceExit"
},
"repository": {
Expand Down
16 changes: 11 additions & 5 deletions packages/fastify-renderer/src/node/Plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ export class FastifyRendererPlugin {
/**
* Implements the backend integration logic for vite -- pulls out the chain of imported modules from the vite manifest and generates <script/> or <link/> tags to source the assets in the browser.
**/
pushImportTagsFromManifest = (bus: RenderBus, entryName: string, root = true) => {
pushImportTagsFromManifest(
bus: RenderBus,
entryName: string,
root = true,
styleNonce?: string,
scriptNonce?: string
) {
let manifestEntry = this.clientManifest![entryName]
if (!manifestEntry) {
// TODO: Refactor this away
Expand All @@ -93,25 +99,25 @@ export class FastifyRendererPlugin {

if (manifestEntry.imports) {
for (const submodule of manifestEntry.imports) {
this.pushImportTagsFromManifest(bus, submodule, false)
this.pushImportTagsFromManifest(bus, submodule, false, styleNonce, scriptNonce)
}
}
if (manifestEntry.css) {
for (const css of manifestEntry.css) {
bus.linkStylesheet(this.clientAssetPath(css))
bus.linkStylesheet(this.clientAssetPath(css), styleNonce)
}
}

const file = this.clientAssetPath(manifestEntry.file)

if (file.endsWith('.js')) {
if (root) {
bus.loadScript(file)
bus.loadScript(file, scriptNonce)
} else {
bus.preloadModule(file)
}
} else if (file.endsWith('.css')) {
bus.linkStylesheet(file)
bus.linkStylesheet(file, styleNonce)
}
}

Expand Down
12 changes: 6 additions & 6 deletions packages/fastify-renderer/src/node/RenderBus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ export class RenderBus {
this.push('head', `<link rel="modulepreload" crossorigin href="${path}">`)
}

linkStylesheet(path: string) {
if (this.included.has(path)) return
this.included.add(path)
this.push('head', stylesheetLinkTag(path))
linkStylesheet(href: string, nonce?: string) {
if (this.included.has(href)) return
this.included.add(href)
this.push('head', stylesheetLinkTag({ href, nonce }))
}

loadScript(src: string) {
this.push('tail', scriptTag(``, { src }))
loadScript(src: string, nonce?: string) {
this.push('tail', scriptTag(``, { src, nonce }))
}
}
12 changes: 8 additions & 4 deletions packages/fastify-renderer/src/node/renderers/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,24 @@ export interface Renderer {
vitePlugins(): Plugin[]
}

export function scriptTag(content: string, attrs: Record<string, string> = {}) {
export function scriptTag(content: string, attrs: Record<string, string | undefined> = {}) {
// if ('cspNonce' in render.reply) {
// attrs.nonce ??= (render.reply as any).cspNonce.script
// }

const attrsString = Object.entries(attrs)
.filter(([, value]) => value !== undefined)
.map(([key, value]) => `${key}="${value}"`)
.join(' ')

return `<script type="module" ${attrsString}>${content}</script>`
}

export function stylesheetLinkTag(href: string) {
const nonceString = '' //'cspNonce' in render.reply ? `nonce="${(render.reply as any).cspNonce.style}"` : ''
export function stylesheetLinkTag(attrs: Record<string, string | undefined>) {
const attrsString = Object.entries(attrs)
.filter(([, value]) => value !== undefined)
.map(([key, value]) => `${key}="${value}"`)
.join(' ')

return `<link rel="stylesheet" href="${href}" ${nonceString}>`
return `<link rel="stylesheet" ${attrsString}>`
}
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,13 @@ export class ReactRenderer implements Renderer {
} else {
const entrypointName = this.buildVirtualClientEntrypointModuleID(render)
const manifestEntryName = normalizePath(path.relative(this.viteConfig.root, entrypointName))
this.plugin.pushImportTagsFromManifest(bus, manifestEntryName)
this.plugin.pushImportTagsFromManifest(
bus,
manifestEntryName,
true,
(render.reply as any).cspNonce?.style as string | undefined,
(render.reply as any).cspNonce?.script as string | undefined
)
}

return bus
Expand Down

0 comments on commit 0a99ad3

Please sign in to comment.