From bc2588022f49f9ab146a863006c063ea0b580437 Mon Sep 17 00:00:00 2001 From: Henrique Limas Date: Wed, 24 May 2023 08:18:57 -0700 Subject: [PATCH 1/2] Add support for 'crossorigin' attribute on bootstrapScripts and bootstrapModules --- .../src/server/ReactFizzConfigDOM.js | 18 ++++++ .../src/__tests__/ReactDOMFizzServer-test.js | 58 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js index 5314564242ed9..fee7eecc1a642 100644 --- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js +++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js @@ -163,6 +163,7 @@ const startScriptSrc = stringToPrecomputedChunk(''); /** @@ -192,6 +193,7 @@ const scriptReplacer = ( export type BootstrapScriptDescriptor = { src: string, integrity?: string, + crossOrigin?: string, }; export type ExternalRuntimeScript = { src: string, @@ -265,6 +267,8 @@ export function createResponseState( typeof scriptConfig === 'string' ? scriptConfig : scriptConfig.src; const integrity = typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity; + const crossOrigin = + typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin; bootstrapChunks.push( startScriptSrc, @@ -282,6 +286,12 @@ export function createResponseState( stringToChunk(escapeTextForBrowser(integrity)), ); } + if (crossOrigin) { + bootstrapChunks.push( + scriptCrossOrigin, + stringToChunk(escapeTextForBrowser(crossOrigin)), + ); + } bootstrapChunks.push(endAsyncScript); } } @@ -292,6 +302,8 @@ export function createResponseState( typeof scriptConfig === 'string' ? scriptConfig : scriptConfig.src; const integrity = typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity; + const crossOrigin = + typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin; bootstrapChunks.push( startModuleSrc, @@ -310,6 +322,12 @@ export function createResponseState( stringToChunk(escapeTextForBrowser(integrity)), ); } + if (crossOrigin) { + bootstrapChunks.push( + scriptCrossOrigin, + stringToChunk(escapeTextForBrowser(crossOrigin)), + ); + } bootstrapChunks.push(endAsyncScript); } } diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index 2bf48eae39b18..6e8e2477dd3c3 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -3777,6 +3777,64 @@ describe('ReactDOMFizzServer', () => { ]); }); + it('accepts a crossOrigin property for bootstrapScripts and bootstrapModules', async () => { + await act(() => { + const {pipe} = renderToPipeableStream( + + + +
hello world
+ + , + { + bootstrapScripts: [ + 'foo', + { + src: 'bar', + }, + { + src: 'baz', + crossOrigin: 'anonymous', + }, + ], + bootstrapModules: [ + 'quux', + { + src: 'corge', + }, + { + src: 'grault', + crossOrigin: 'use-credentials', + }, + ], + }, + ); + pipe(writable); + }); + + expect(getVisibleChildren(document)).toEqual( + + + +
hello world
+ + , + ); + expect( + stripExternalRuntimeInNodes( + document.getElementsByTagName('script'), + renderOptions.unstable_externalRuntimeSrc, + ).map(n => n.outerHTML), + ).toEqual([ + '', + '', + '', + '', + '', + '', + ]); + }); + describe('bootstrapScriptContent escaping', () => { it('the "S" in " { window.__test_outlet = ''; From 08774ccd3ecb5b68344a6fc497a514da1b5806a7 Mon Sep 17 00:00:00 2001 From: Henrique Limas Date: Wed, 31 May 2023 20:36:31 -0700 Subject: [PATCH 2/2] Limit crossOrigin value usage --- .../src/server/ReactFizzConfigDOM.js | 16 ++++++++++++---- .../src/__tests__/ReactDOMFizzServer-test.js | 9 +++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js index fee7eecc1a642..b74492102158d 100644 --- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js +++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js @@ -268,7 +268,11 @@ export function createResponseState( const integrity = typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity; const crossOrigin = - typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin; + typeof scriptConfig === 'string' || scriptConfig.crossOrigin == null + ? undefined + : scriptConfig.crossOrigin === 'use-credentials' + ? 'use-credentials' + : ''; bootstrapChunks.push( startScriptSrc, @@ -286,7 +290,7 @@ export function createResponseState( stringToChunk(escapeTextForBrowser(integrity)), ); } - if (crossOrigin) { + if (typeof crossOrigin === 'string') { bootstrapChunks.push( scriptCrossOrigin, stringToChunk(escapeTextForBrowser(crossOrigin)), @@ -303,7 +307,11 @@ export function createResponseState( const integrity = typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity; const crossOrigin = - typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin; + typeof scriptConfig === 'string' || scriptConfig.crossOrigin == null + ? undefined + : scriptConfig.crossOrigin === 'use-credentials' + ? 'use-credentials' + : ''; bootstrapChunks.push( startModuleSrc, @@ -322,7 +330,7 @@ export function createResponseState( stringToChunk(escapeTextForBrowser(integrity)), ); } - if (crossOrigin) { + if (typeof crossOrigin === 'string') { bootstrapChunks.push( scriptCrossOrigin, stringToChunk(escapeTextForBrowser(crossOrigin)), diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index 6e8e2477dd3c3..be4a2353a1077 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -3794,7 +3794,11 @@ describe('ReactDOMFizzServer', () => { }, { src: 'baz', - crossOrigin: 'anonymous', + crossOrigin: '', + }, + { + src: 'qux', + crossOrigin: 'defaults-to-empty', }, ], bootstrapModules: [ @@ -3828,7 +3832,8 @@ describe('ReactDOMFizzServer', () => { ).toEqual([ '', '', - '', + '', + '', '', '', '',