korbit-ai[bot] commented on code in PR #34273:
URL: https://github.com/apache/superset/pull/34273#discussion_r2224167760


##########
superset-frontend/src/embedded/index.tsx:
##########
@@ -245,21 +246,28 @@ window.addEventListener('message', function 
embeddedPageInitializer(event) {
     Switchboard.defineMethod('getDataMask', embeddedApi.getDataMask);
     Switchboard.defineMethod(
       'setThemeConfig',
-      (payload: { themeConfig: AnyThemeConfig }) => {
+      (payload: { themeConfig: SupersetThemeConfig }) => {
         const { themeConfig } = payload;
         log('Received setThemeConfig request:', themeConfig);
 
         try {
-          themeObject.setConfig(themeConfig);
+          const themeController = getThemeController();
+          themeController.setThemeConfig(themeConfig);
           return { success: true, message: 'Theme applied' };
         } catch (error) {
           logging.error('Failed to apply theme config:', error);
           throw new Error(`Failed to apply theme config: ${error.message}`);
         }
       },
     );
+
     Switchboard.start();
   }
 });
 
+// Clean up theme controller on page unload
+window.addEventListener('beforeunload', () => {
+  getThemeController().destroy();
+});

Review Comment:
   ### Missing lifecycle logging <sub>![category 
Logging](https://img.shields.io/badge/Logging-4f46e5)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The theme controller destruction is not logged, making it difficult to track 
lifecycle events.
   
   
   ###### Why this matters
   Without logging theme controller cleanup, debugging issues related to theme 
persistence or cleanup becomes more difficult.
   
   ###### Suggested change ∙ *Feature Preview*
   ```typescript
   window.addEventListener('beforeunload', () => {
     log('lifecycle', 'Destroying theme controller');
     getThemeController().destroy();
   });
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/6908d898-deaa-4749-b836-249e2fbf89d1/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/6908d898-deaa-4749-b836-249e2fbf89d1?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/6908d898-deaa-4749-b836-249e2fbf89d1?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/6908d898-deaa-4749-b836-249e2fbf89d1?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/6908d898-deaa-4749-b836-249e2fbf89d1)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:c7dcf9b0-c55c-4a0e-beaf-2cacec9ee342 -->
   
   
   [](c7dcf9b0-c55c-4a0e-beaf-2cacec9ee342)



##########
superset-frontend/src/embedded/EmbeddedContextProviders.tsx:
##########
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Route } from 'react-router-dom';
+import { getExtensionsRegistry } from '@superset-ui/core';
+import { Provider as ReduxProvider } from 'react-redux';
+import { QueryParamProvider } from 'use-query-params';
+import { DndProvider } from 'react-dnd';
+import { HTML5Backend } from 'react-dnd-html5-backend';
+import { FlashProvider, DynamicPluginProvider } from 'src/components';
+import { EmbeddedUiConfigProvider } from 'src/components/UiConfigContext';
+import { SupersetThemeProvider } from 'src/theme/ThemeProvider';
+import { ThemeController } from 'src/theme/ThemeController';
+import type { ThemeStorage } from '@superset-ui/core';
+import { store } from 'src/views/store';
+import getBootstrapData from 'src/utils/getBootstrapData';
+
+class ThemeMemoryStorageAdapter implements ThemeStorage {
+  private storage = new Map<string, string>();
+
+  getItem(key: string): string | null {
+    return this.storage.get(key) || null;
+  }
+
+  setItem(key: string, value: string): void {
+    this.storage.set(key, value);
+  }
+
+  removeItem(key: string): void {
+    this.storage.delete(key);
+  }
+}
+
+const themeController = new ThemeController({
+  storage: new ThemeMemoryStorageAdapter(),
+});
+
+export const getThemeController = (): ThemeController => themeController;

Review Comment:
   ### Global Singleton Anti-pattern <sub>![category 
Design](https://img.shields.io/badge/Design-0d9488)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The themeController is created as a global singleton with direct 
instantiation rather than using a proper dependency injection or factory 
pattern.
   
   
   ###### Why this matters
   Global singletons make the code harder to test, maintain, and modify. They 
also create hidden dependencies and make it difficult to switch implementations 
or configurations.
   
   ###### Suggested change ∙ *Feature Preview*
   ```typescript
   // Create a factory or context for managing the theme controller
   export class ThemeControllerFactory {
     private static instance: ThemeController | null = null;
   
     static getInstance(): ThemeController {
       if (!this.instance) {
         this.instance = new ThemeController({
           storage: new ThemeMemoryStorageAdapter(),
         });
       }
       return this.instance;
     }
   
     // For testing purposes
     static resetInstance(): void {
       this.instance = null;
     }
   }
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/2376eefe-1a26-4e7c-bc78-b5dd40bdf134/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/2376eefe-1a26-4e7c-bc78-b5dd40bdf134?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/2376eefe-1a26-4e7c-bc78-b5dd40bdf134?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/2376eefe-1a26-4e7c-bc78-b5dd40bdf134?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/2376eefe-1a26-4e7c-bc78-b5dd40bdf134)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:74c58047-faf3-42d9-9dc5-bc631b3214f4 -->
   
   
   [](74c58047-faf3-42d9-9dc5-bc631b3214f4)



##########
superset-frontend/src/embedded/EmbeddedContextProviders.tsx:
##########
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Route } from 'react-router-dom';
+import { getExtensionsRegistry } from '@superset-ui/core';
+import { Provider as ReduxProvider } from 'react-redux';
+import { QueryParamProvider } from 'use-query-params';
+import { DndProvider } from 'react-dnd';
+import { HTML5Backend } from 'react-dnd-html5-backend';
+import { FlashProvider, DynamicPluginProvider } from 'src/components';
+import { EmbeddedUiConfigProvider } from 'src/components/UiConfigContext';
+import { SupersetThemeProvider } from 'src/theme/ThemeProvider';
+import { ThemeController } from 'src/theme/ThemeController';
+import type { ThemeStorage } from '@superset-ui/core';
+import { store } from 'src/views/store';
+import getBootstrapData from 'src/utils/getBootstrapData';
+
+class ThemeMemoryStorageAdapter implements ThemeStorage {
+  private storage = new Map<string, string>();
+
+  getItem(key: string): string | null {
+    return this.storage.get(key) || null;
+  }
+
+  setItem(key: string, value: string): void {
+    this.storage.set(key, value);
+  }
+
+  removeItem(key: string): void {
+    this.storage.delete(key);
+  }
+}

Review Comment:
   ### Missing class purpose documentation <sub>![category 
Readability](https://img.shields.io/badge/Readability-0284c7)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The ThemeMemoryStorageAdapter class lacks a JSDoc comment explaining its 
purpose and responsibility in the theme management system.
   
   
   ###### Why this matters
   Without clear documentation, developers may not understand why a 
memory-based storage adapter is used instead of other storage options, 
potentially leading to incorrect usage or unnecessary modifications.
   
   ###### Suggested change ∙ *Feature Preview*
   Add JSDoc comment above the class:
   ```typescript
   /**
    * In-memory implementation of ThemeStorage interface for embedded contexts
    * where persistent storage is not required or desired.
    */
   class ThemeMemoryStorageAdapter implements ThemeStorage {
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/0ff2649a-4eb8-4d6d-a35a-dd702dbd16c6/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/0ff2649a-4eb8-4d6d-a35a-dd702dbd16c6?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/0ff2649a-4eb8-4d6d-a35a-dd702dbd16c6?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/0ff2649a-4eb8-4d6d-a35a-dd702dbd16c6?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/0ff2649a-4eb8-4d6d-a35a-dd702dbd16c6)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:0c3e7870-0939-4abc-9a27-1e3232c00f96 -->
   
   
   [](0c3e7870-0939-4abc-9a27-1e3232c00f96)



##########
superset/config.py:
##########
@@ -1890,11 +1890,16 @@
 }
 
 # Embedded config options
-GUEST_ROLE_NAME = "Public"
-GUEST_TOKEN_JWT_SECRET = "test-guest-secret-change-me"  # noqa: S105
+GUEST_TOKEN_JWT_SECRET = "guest_token_secret"  # noqa: S105

Review Comment:
   ### Hard-coded JWT Secret <sub>![category 
Security](https://img.shields.io/badge/Security-e11d48)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   Hard-coded JWT secret used for guest token generation which is visible in 
version control.
   
   
   ###### Why this matters
   If this secret is compromised, attackers could generate valid guest tokens 
to access embedded dashboards without authorization.
   
   ###### Suggested change ∙ *Feature Preview*
   Use an environment variable for the JWT secret:
   ```python
   GUEST_TOKEN_JWT_SECRET = os.environ.get('SUPERSET_GUEST_TOKEN_JWT_SECRET', 
'guest_token_secret')  # noqa: S105
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/f488bfaf-46a9-43fe-8c51-a7e7b2f881e3/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/f488bfaf-46a9-43fe-8c51-a7e7b2f881e3?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/f488bfaf-46a9-43fe-8c51-a7e7b2f881e3?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/f488bfaf-46a9-43fe-8c51-a7e7b2f881e3?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/f488bfaf-46a9-43fe-8c51-a7e7b2f881e3)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:9da7519c-b937-42f5-904d-5a6a176c0a4d -->
   
   
   [](9da7519c-b937-42f5-904d-5a6a176c0a4d)



##########
superset/config.py:
##########
@@ -264,7 +264,7 @@ def _try_json_readsha(filepath: str, length: int) -> str | 
None:
 QUERY_SEARCH_LIMIT = 1000
 
 # Flask-WTF flag for CSRF
-WTF_CSRF_ENABLED = True
+WTF_CSRF_ENABLED = False

Review Comment:
   ### CSRF Protection Disabled <sub>![category 
Security](https://img.shields.io/badge/Security-e11d48)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   CSRF protection is disabled globally, which makes the application vulnerable 
to Cross-Site Request Forgery attacks.
   
   
   ###### Why this matters
   Attackers could perform unauthorized actions on behalf of authenticated 
users without their consent, potentially compromising data security in embedded 
dashboards.
   
   ###### Suggested change ∙ *Feature Preview*
   Keep CSRF protection enabled and instead add specific routes that need CSRF 
exemption to WTF_CSRF_EXEMPT_LIST:
   ```python
   WTF_CSRF_ENABLED = True
   WTF_CSRF_EXEMPT_LIST = [
       'superset.views.core.log',
       'superset.views.core.explore_json',
       'superset.charts.data.api.data',
       'superset.dashboards.api.cache_dashboard_screenshot',
       # Add your embedded dashboard endpoints here
   ]
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/ccdf2da1-65a4-40eb-bcbd-0ee86b5ba5d7/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/ccdf2da1-65a4-40eb-bcbd-0ee86b5ba5d7?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/ccdf2da1-65a4-40eb-bcbd-0ee86b5ba5d7?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/ccdf2da1-65a4-40eb-bcbd-0ee86b5ba5d7?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/ccdf2da1-65a4-40eb-bcbd-0ee86b5ba5d7)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:b2246d33-d666-4e95-a175-fd79ee898c21 -->
   
   
   [](b2246d33-d666-4e95-a175-fd79ee898c21)



##########
superset-frontend/src/types/bootstrapTypes.ts:
##########
@@ -189,7 +189,7 @@ export interface BootstrapThemeData {
   bootstrapDefaultTheme: AnyThemeConfig | null;
   bootstrapDarkTheme: AnyThemeConfig | null;
   bootstrapThemeSettings: SerializableThemeSettings | null;
-  hasBootstrapThemes: boolean;
+  hasCustomThemes: boolean;

Review Comment:
   ### Ambiguous boolean property name <sub>![category 
Readability](https://img.shields.io/badge/Readability-0284c7)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The property name 'hasCustomThemes' is ambiguous about what constitutes a 
'custom' theme.
   
   
   ###### Why this matters
   Developers may misinterpret what this boolean represents - whether it means 
user-defined themes, non-default themes, or themes from a specific source.
   
   ###### Suggested change ∙ *Feature Preview*
   Rename to be more specific about what constitutes a custom theme, e.g.: 
`hasUserDefinedThemes` or `hasNonDefaultThemes`
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/e33d2afd-bea3-4abf-b889-52fd852ddee8/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/e33d2afd-bea3-4abf-b889-52fd852ddee8?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/e33d2afd-bea3-4abf-b889-52fd852ddee8?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/e33d2afd-bea3-4abf-b889-52fd852ddee8?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/e33d2afd-bea3-4abf-b889-52fd852ddee8)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:ede9b37e-c135-4e1e-89fb-e23c9266f016 -->
   
   
   [](ede9b37e-c135-4e1e-89fb-e23c9266f016)



##########
superset-frontend/src/embedded/EmbeddedContextProviders.tsx:
##########
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Route } from 'react-router-dom';
+import { getExtensionsRegistry } from '@superset-ui/core';
+import { Provider as ReduxProvider } from 'react-redux';
+import { QueryParamProvider } from 'use-query-params';
+import { DndProvider } from 'react-dnd';
+import { HTML5Backend } from 'react-dnd-html5-backend';
+import { FlashProvider, DynamicPluginProvider } from 'src/components';
+import { EmbeddedUiConfigProvider } from 'src/components/UiConfigContext';
+import { SupersetThemeProvider } from 'src/theme/ThemeProvider';
+import { ThemeController } from 'src/theme/ThemeController';
+import type { ThemeStorage } from '@superset-ui/core';
+import { store } from 'src/views/store';
+import getBootstrapData from 'src/utils/getBootstrapData';
+
+class ThemeMemoryStorageAdapter implements ThemeStorage {
+  private storage = new Map<string, string>();
+
+  getItem(key: string): string | null {
+    return this.storage.get(key) || null;
+  }
+
+  setItem(key: string, value: string): void {
+    this.storage.set(key, value);
+  }
+
+  removeItem(key: string): void {
+    this.storage.delete(key);
+  }
+}
+
+const themeController = new ThemeController({
+  storage: new ThemeMemoryStorageAdapter(),
+});
+
+export const getThemeController = (): ThemeController => themeController;
+
+const { common } = getBootstrapData();
+const extensionsRegistry = getExtensionsRegistry();
+
+export const EmbeddedContextProviders: React.FC = ({ children }) => {
+  const RootContextProviderExtension = extensionsRegistry.get(
+    'root.context.provider',
+  );
+
+  return (
+    <SupersetThemeProvider themeController={themeController}>
+      <ReduxProvider store={store}>
+        <DndProvider backend={HTML5Backend}>
+          <FlashProvider messages={common.flash_messages}>
+            <EmbeddedUiConfigProvider>
+              <DynamicPluginProvider>
+                <QueryParamProvider
+                  ReactRouterRoute={Route}
+                  stringifyOptions={{ encode: false }}

Review Comment:
   ### Disabled URL Parameter Encoding <sub>![category 
Security](https://img.shields.io/badge/Security-e11d48)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The QueryParamProvider is configured to disable URL parameter encoding, 
which could lead to XSS vulnerabilities if query parameters contain malicious 
content.
   
   
   ###### Why this matters
   Disabling encoding of URL parameters means special characters and 
potentially harmful content won't be properly escaped, making the application 
vulnerable to XSS attacks through URL manipulation.
   
   ###### Suggested change ∙ *Feature Preview*
   Remove the stringifyOptions or set encode to true:
   ```typescript
   <QueryParamProvider ReactRouterRoute={Route}>
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/1a165113-c740-4cce-804b-6bd9d1bb1a9b/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/1a165113-c740-4cce-804b-6bd9d1bb1a9b?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/1a165113-c740-4cce-804b-6bd9d1bb1a9b?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/1a165113-c740-4cce-804b-6bd9d1bb1a9b?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/1a165113-c740-4cce-804b-6bd9d1bb1a9b)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:6de6331d-260f-4baf-8ef9-31f8331b2eb1 -->
   
   
   [](6de6331d-260f-4baf-8ef9-31f8331b2eb1)



##########
superset-frontend/src/embedded/index.tsx:
##########
@@ -245,21 +246,28 @@
     Switchboard.defineMethod('getDataMask', embeddedApi.getDataMask);
     Switchboard.defineMethod(
       'setThemeConfig',
-      (payload: { themeConfig: AnyThemeConfig }) => {
+      (payload: { themeConfig: SupersetThemeConfig }) => {
         const { themeConfig } = payload;
         log('Received setThemeConfig request:', themeConfig);
 
         try {
-          themeObject.setConfig(themeConfig);
+          const themeController = getThemeController();
+          themeController.setThemeConfig(themeConfig);
           return { success: true, message: 'Theme applied' };
         } catch (error) {
           logging.error('Failed to apply theme config:', error);
           throw new Error(`Failed to apply theme config: ${error.message}`);
         }
       },
     );
+
     Switchboard.start();
   }
 });
 
+// Clean up theme controller on page unload
+window.addEventListener('beforeunload', () => {
+  getThemeController().destroy();

Review Comment:
   ### Unsafe Theme Controller Cleanup <sub>![category Error 
Handling](https://img.shields.io/badge/Error%20Handling-ea580c)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The theme controller destruction call doesn't handle potential errors if the 
controller is already destroyed or unavailable.
   
   
   ###### Why this matters
   This could lead to uncaught runtime errors during page unload if the theme 
controller instance is not available.
   
   ###### Suggested change ∙ *Feature Preview*
   Add error handling around the theme controller cleanup:
   ```typescript
   window.addEventListener('beforeunload', () => {
     try {
       const controller = getThemeController();
       if (controller) {
         controller.destroy();
       }
     } catch (error) {
       logging.warn('Failed to destroy theme controller:', error);
     }
   });
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/af94d9e8-ae92-4f6e-ae14-3c6c8147d285/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/af94d9e8-ae92-4f6e-ae14-3c6c8147d285?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/af94d9e8-ae92-4f6e-ae14-3c6c8147d285?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/af94d9e8-ae92-4f6e-ae14-3c6c8147d285?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/af94d9e8-ae92-4f6e-ae14-3c6c8147d285)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:04f85097-fbbc-4c41-9bcd-ed5837a9786a -->
   
   
   [](04f85097-fbbc-4c41-9bcd-ed5837a9786a)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to