fix(app): scope header overrides to gateway URLs only
- The session.webRequest.onHeadersReceived was stripping X-Frame-Options and modifying CSP for ALL responses including the Vite dev server, which could break the main app rendering. Now only applies to gateway URLs (127.0.0.1:18789 / localhost:18789). - Dashboard: only fetch channels/skills when gateway is running - Dashboard: guard against non-array channels/skills data - Gateway store: use dynamic import() instead of require() for chat store to avoid ESM/CJS issues in Vite
This commit is contained in:
@@ -75,12 +75,19 @@ async function initialize(): Promise<void> {
|
||||
// Create system tray
|
||||
createTray(mainWindow);
|
||||
|
||||
// Override security headers for the OpenClaw Control UI webview
|
||||
// Override security headers ONLY for the OpenClaw Gateway Control UI
|
||||
// The Control UI sets X-Frame-Options: DENY and CSP frame-ancestors 'none'
|
||||
// which prevents embedding in an Electron webview
|
||||
// which prevents embedding in an iframe. Only apply to gateway URLs.
|
||||
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
|
||||
const isGatewayUrl = details.url.includes('127.0.0.1:18789') || details.url.includes('localhost:18789');
|
||||
|
||||
if (!isGatewayUrl) {
|
||||
callback({ responseHeaders: details.responseHeaders });
|
||||
return;
|
||||
}
|
||||
|
||||
const headers = { ...details.responseHeaders };
|
||||
// Remove X-Frame-Options to allow embedding in webview
|
||||
// Remove X-Frame-Options to allow embedding in iframe
|
||||
delete headers['X-Frame-Options'];
|
||||
delete headers['x-frame-options'];
|
||||
// Remove restrictive CSP frame-ancestors
|
||||
|
||||
@@ -26,15 +26,19 @@ export function Dashboard() {
|
||||
const { channels, fetchChannels } = useChannelsStore();
|
||||
const { skills, fetchSkills } = useSkillsStore();
|
||||
|
||||
// Fetch data on mount
|
||||
useEffect(() => {
|
||||
fetchChannels();
|
||||
fetchSkills();
|
||||
}, [fetchChannels, fetchSkills]);
|
||||
const isGatewayRunning = gatewayStatus.state === 'running';
|
||||
|
||||
// Calculate statistics
|
||||
const connectedChannels = channels.filter((c) => c.status === 'connected').length;
|
||||
const enabledSkills = skills.filter((s) => s.enabled).length;
|
||||
// Fetch data only when gateway is running
|
||||
useEffect(() => {
|
||||
if (isGatewayRunning) {
|
||||
fetchChannels();
|
||||
fetchSkills();
|
||||
}
|
||||
}, [fetchChannels, fetchSkills, isGatewayRunning]);
|
||||
|
||||
// Calculate statistics safely
|
||||
const connectedChannels = Array.isArray(channels) ? channels.filter((c) => c.status === 'connected').length : 0;
|
||||
const enabledSkills = Array.isArray(skills) ? skills.filter((s) => s.enabled).length : 0;
|
||||
|
||||
// Calculate uptime
|
||||
const uptime = gatewayStatus.connectedAt
|
||||
|
||||
@@ -62,13 +62,18 @@ export const useGatewayStore = create<GatewayState>((set, get) => ({
|
||||
|
||||
// Listen for chat events from the gateway and forward to chat store
|
||||
window.electron.ipcRenderer.on('gateway:chat-message', (data) => {
|
||||
const { useChatStore } = require('./chat');
|
||||
const chatData = data as { message?: Record<string, unknown> } | Record<string, unknown>;
|
||||
// The event payload may be nested under 'message' or directly on data
|
||||
const event = ('message' in chatData && typeof chatData.message === 'object')
|
||||
? chatData.message as Record<string, unknown>
|
||||
: chatData as Record<string, unknown>;
|
||||
useChatStore.getState().handleChatEvent(event);
|
||||
try {
|
||||
// Dynamic import to avoid circular dependency
|
||||
import('./chat').then(({ useChatStore }) => {
|
||||
const chatData = data as { message?: Record<string, unknown> } | Record<string, unknown>;
|
||||
const event = ('message' in chatData && typeof chatData.message === 'object')
|
||||
? chatData.message as Record<string, unknown>
|
||||
: chatData as Record<string, unknown>;
|
||||
useChatStore.getState().handleChatEvent(event);
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn('Failed to forward chat event:', err);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user