From e4b3cd119a22f65173b8f71c139f6bcfe86fdf32 Mon Sep 17 00:00:00 2001
From: New Future <NewFuture@users.noreply.github.com>
Date: Thu, 14 Apr 2022 13:53:32 +0000
Subject: [PATCH 1/4] nonce for devtools

---
 src/devtools/devtools.tsx            | 21 ++++++++++++-
 src/devtools/tests/devtools.test.tsx | 45 ++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/src/devtools/devtools.tsx b/src/devtools/devtools.tsx
index 00a226de10..2ec41b842a 100644
--- a/src/devtools/devtools.tsx
+++ b/src/devtools/devtools.tsx
@@ -58,6 +58,10 @@ interface DevtoolsOptions {
    * Defaults to 'aside'.
    */
   containerElement?: string | any
+  /**
+   * nonce for style element for CSP
+   */
+  styleNonce?: string
 }
 
 interface DevtoolsPanelOptions {
@@ -73,6 +77,10 @@ interface DevtoolsPanelOptions {
    * A boolean variable indicating whether the panel is open or closed
    */
   isOpen?: boolean
+  /**
+   * nonce for style element for CSP
+   */
+  styleNonce?: string
   /**
    * A function that toggles the open and close state of the panel
    */
@@ -92,6 +100,7 @@ export function ReactQueryDevtools({
   toggleButtonProps = {},
   position = 'bottom-left',
   containerElement: Container = 'aside',
+  styleNonce,
 }: DevtoolsOptions): React.ReactElement | null {
   const rootRef = React.useRef<HTMLDivElement>(null)
   const panelRef = React.useRef<HTMLDivElement>(null)
@@ -229,6 +238,7 @@ export function ReactQueryDevtools({
       <ThemeProvider theme={theme}>
         <ReactQueryDevtoolsPanel
           ref={panelRef as any}
+          styleNonce={styleNonce || (window as any).__webpack_nonce__}
           {...otherPanelProps}
           style={{
             position: 'fixed',
@@ -375,7 +385,13 @@ export const ReactQueryDevtoolsPanel = React.forwardRef<
   HTMLDivElement,
   DevtoolsPanelOptions
 >(function ReactQueryDevtoolsPanel(props, ref): React.ReactElement {
-  const { isOpen = true, setIsOpen, handleDragStart, ...panelProps } = props
+  const {
+    isOpen = true,
+    styleNonce,
+    setIsOpen,
+    handleDragStart,
+    ...panelProps
+  } = props
 
   const queryClient = useQueryClient()
   const queryCache = queryClient.getQueryCache()
@@ -467,6 +483,9 @@ export const ReactQueryDevtoolsPanel = React.forwardRef<
         {...panelProps}
       >
         <style
+          scoped
+          nonce={styleNonce}
+          data-testid="react-query-devtools-panel-style"
           dangerouslySetInnerHTML={{
             __html: `
             .ReactQueryDevtoolsPanel * {
diff --git a/src/devtools/tests/devtools.test.tsx b/src/devtools/tests/devtools.test.tsx
index b529052a03..9442334832 100644
--- a/src/devtools/tests/devtools.test.tsx
+++ b/src/devtools/tests/devtools.test.tsx
@@ -16,6 +16,10 @@ import {
 } from './utils'
 
 describe('ReactQueryDevtools', () => {
+  afterEach(() => {
+    window.__webpack_nonce__ = undefined
+  })
+
   it('should be able to open and close devtools', async () => {
     const { queryClient } = createQueryClient()
 
@@ -391,4 +395,45 @@ describe('ReactQueryDevtools', () => {
     expect(queries[1]?.textContent).toEqual(query2Hash)
     expect(queries[2]?.textContent).toEqual(query3Hash)
   })
+
+  it('style should have scoped and nonce', async () => {
+    const { queryClient } = createQueryClient()
+
+    function Page() {
+      return <div></div>
+    }
+
+    renderWithClient(queryClient, <Page />, {
+      styleNonce: 'test-nonce',
+      initialIsOpen: false,
+    })
+    const styleTag = screen.queryByTestId('react-query-devtools-panel-style')
+
+    expect(styleTag).toHaveAttribute('scoped')
+    expect(styleTag).toHaveAttribute('nonce', 'test-nonce')
+
+    await screen.findByRole('button', { name: /react query devtools/i })
+  })
+
+  it('style accepts __webpack_nonce__', async () => {
+    const { queryClient } = createQueryClient()
+
+    function Page() {
+      return <div></div>
+    }
+
+    window.__webpack_nonce__ = 'test-webpack_nonce'
+    renderWithClient(queryClient, <Page />, { initialIsOpen: false })
+
+    const styleTag = screen.queryByTestId('react-query-devtools-panel-style')
+    expect(styleTag).toHaveAttribute('nonce', 'test-webpack_nonce')
+
+    await screen.findByRole('button')
+  })
 })
+
+declare global {
+  interface Window {
+    __webpack_nonce__: string | undefined
+  }
+}

From 999a124a4519b8fffe6a261ff005eeb1c7c29b9c Mon Sep 17 00:00:00 2001
From: New Future <NewFuture@users.noreply.github.com>
Date: Mon, 18 Apr 2022 02:44:52 +0000
Subject: [PATCH 2/4] remove __    expect(styleTag).toHaveAttribute('nonce',
 'test-webpack_nonce')

---
 src/devtools/devtools.tsx            |  3 +--
 src/devtools/tests/devtools.test.tsx | 31 ++--------------------------
 2 files changed, 3 insertions(+), 31 deletions(-)

diff --git a/src/devtools/devtools.tsx b/src/devtools/devtools.tsx
index 2ec41b842a..88ad995810 100644
--- a/src/devtools/devtools.tsx
+++ b/src/devtools/devtools.tsx
@@ -238,7 +238,7 @@ export function ReactQueryDevtools({
       <ThemeProvider theme={theme}>
         <ReactQueryDevtoolsPanel
           ref={panelRef as any}
-          styleNonce={styleNonce || (window as any).__webpack_nonce__}
+          styleNonce={styleNonce}
           {...otherPanelProps}
           style={{
             position: 'fixed',
@@ -485,7 +485,6 @@ export const ReactQueryDevtoolsPanel = React.forwardRef<
         <style
           scoped
           nonce={styleNonce}
-          data-testid="react-query-devtools-panel-style"
           dangerouslySetInnerHTML={{
             __html: `
             .ReactQueryDevtoolsPanel * {
diff --git a/src/devtools/tests/devtools.test.tsx b/src/devtools/tests/devtools.test.tsx
index 9442334832..2584f5cd22 100644
--- a/src/devtools/tests/devtools.test.tsx
+++ b/src/devtools/tests/devtools.test.tsx
@@ -16,10 +16,6 @@ import {
 } from './utils'
 
 describe('ReactQueryDevtools', () => {
-  afterEach(() => {
-    window.__webpack_nonce__ = undefined
-  })
-
   it('should be able to open and close devtools', async () => {
     const { queryClient } = createQueryClient()
 
@@ -403,37 +399,14 @@ describe('ReactQueryDevtools', () => {
       return <div></div>
     }
 
-    renderWithClient(queryClient, <Page />, {
+    const { container } = renderWithClient(queryClient, <Page />, {
       styleNonce: 'test-nonce',
       initialIsOpen: false,
     })
-    const styleTag = screen.queryByTestId('react-query-devtools-panel-style')
-
+    const styleTag = container.querySelector('style')
     expect(styleTag).toHaveAttribute('scoped')
     expect(styleTag).toHaveAttribute('nonce', 'test-nonce')
 
     await screen.findByRole('button', { name: /react query devtools/i })
   })
-
-  it('style accepts __webpack_nonce__', async () => {
-    const { queryClient } = createQueryClient()
-
-    function Page() {
-      return <div></div>
-    }
-
-    window.__webpack_nonce__ = 'test-webpack_nonce'
-    renderWithClient(queryClient, <Page />, { initialIsOpen: false })
-
-    const styleTag = screen.queryByTestId('react-query-devtools-panel-style')
-    expect(styleTag).toHaveAttribute('nonce', 'test-webpack_nonce')
-
-    await screen.findByRole('button')
-  })
 })
-
-declare global {
-  interface Window {
-    __webpack_nonce__: string | undefined
-  }
-}

From 4c411643d376f1ee0486973e0d9cf8cfd8a01741 Mon Sep 17 00:00:00 2001
From: New Future <NewFuture@users.noreply.github.com>
Date: Thu, 21 Apr 2022 09:30:58 +0000
Subject: [PATCH 3/4] remove scoped

---
 src/devtools/devtools.tsx            | 1 -
 src/devtools/tests/devtools.test.tsx | 1 -
 2 files changed, 2 deletions(-)

diff --git a/src/devtools/devtools.tsx b/src/devtools/devtools.tsx
index 88ad995810..d415a95147 100644
--- a/src/devtools/devtools.tsx
+++ b/src/devtools/devtools.tsx
@@ -483,7 +483,6 @@ export const ReactQueryDevtoolsPanel = React.forwardRef<
         {...panelProps}
       >
         <style
-          scoped
           nonce={styleNonce}
           dangerouslySetInnerHTML={{
             __html: `
diff --git a/src/devtools/tests/devtools.test.tsx b/src/devtools/tests/devtools.test.tsx
index 2584f5cd22..d3831bed46 100644
--- a/src/devtools/tests/devtools.test.tsx
+++ b/src/devtools/tests/devtools.test.tsx
@@ -404,7 +404,6 @@ describe('ReactQueryDevtools', () => {
       initialIsOpen: false,
     })
     const styleTag = container.querySelector('style')
-    expect(styleTag).toHaveAttribute('scoped')
     expect(styleTag).toHaveAttribute('nonce', 'test-nonce')
 
     await screen.findByRole('button', { name: /react query devtools/i })

From 3496c143a9fb3eacd90f95cb27ef6fe2d605ca64 Mon Sep 17 00:00:00 2001
From: Dominik Dorfmeister <office@dorfmeister.cc>
Date: Thu, 21 Apr 2022 14:15:57 +0200
Subject: [PATCH 4/4] Update src/devtools/tests/devtools.test.tsx

---
 src/devtools/tests/devtools.test.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/devtools/tests/devtools.test.tsx b/src/devtools/tests/devtools.test.tsx
index d3831bed46..4ee9820d6e 100644
--- a/src/devtools/tests/devtools.test.tsx
+++ b/src/devtools/tests/devtools.test.tsx
@@ -392,7 +392,7 @@ describe('ReactQueryDevtools', () => {
     expect(queries[2]?.textContent).toEqual(query3Hash)
   })
 
-  it('style should have scoped and nonce', async () => {
+  it('style should have a nonce', async () => {
     const { queryClient } = createQueryClient()
 
     function Page() {
