fix: remove CSP nonce from style-src to unblock reagraph canvas (#425)
Replace style-src nonce directive with unsafe-inline to support reagraph's runtime <style> injection. Add style-src-elem and style-src-attr directives for CSP Level 3 compliance. Extend fitNodesInView retries from 2 to 4 for more reliable canvas sizing. Closes #414 Supersedes #415
This commit is contained in:
parent
00a22a2e24
commit
4671946e97
|
|
@ -267,9 +267,11 @@ export function MemoryGraph() {
|
|||
useEffect(() => {
|
||||
if (!graphNodes.length) return
|
||||
// reagraph force layout needs time to settle before fitNodesInView works
|
||||
const t1 = setTimeout(() => graphRef.current?.fitNodesInView(), 800)
|
||||
const t2 = setTimeout(() => graphRef.current?.fitNodesInView(), 2000)
|
||||
return () => { clearTimeout(t1); clearTimeout(t2) }
|
||||
const t1 = setTimeout(() => graphRef.current?.fitNodesInView(undefined, { animated: false }), 800)
|
||||
const t2 = setTimeout(() => graphRef.current?.fitNodesInView(undefined, { animated: false }), 2500)
|
||||
const t3 = setTimeout(() => graphRef.current?.fitNodesInView(undefined, { animated: false }), 5000)
|
||||
const t4 = setTimeout(() => graphRef.current?.fitNodesInView(undefined, { animated: false }), 8000)
|
||||
return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); clearTimeout(t4) }
|
||||
}, [graphNodes.length, selectedAgent])
|
||||
|
||||
// Navigation helpers
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ describe('buildMissionControlCsp', () => {
|
|||
const csp = buildMissionControlCsp({ nonce: 'nonce-123', googleEnabled: false })
|
||||
|
||||
expect(csp).toContain(`script-src 'self' 'nonce-nonce-123' 'strict-dynamic'`)
|
||||
expect(csp).toContain(`style-src 'self' 'nonce-nonce-123'`)
|
||||
expect(csp).toContain("style-src 'self' 'unsafe-inline'")
|
||||
expect(csp).toContain("style-src-elem 'self' 'unsafe-inline'")
|
||||
expect(csp).toContain("style-src-attr 'unsafe-inline'")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -19,6 +21,6 @@ describe('buildNonceRequestHeaders', () => {
|
|||
})
|
||||
|
||||
expect(headers.get('x-nonce')).toBe('nonce-123')
|
||||
expect(headers.get('Content-Security-Policy')).toContain(`'nonce-nonce-123'`)
|
||||
expect(headers.get('Content-Security-Policy')).toContain("style-src 'self' 'unsafe-inline'")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ export function buildMissionControlCsp(input: { nonce: string; googleEnabled: bo
|
|||
`object-src 'none'`,
|
||||
`frame-ancestors 'none'`,
|
||||
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic' blob:${googleEnabled ? ' https://accounts.google.com' : ''}`,
|
||||
`style-src 'self' 'nonce-${nonce}'`,
|
||||
`style-src 'self' 'unsafe-inline'`,
|
||||
`style-src-elem 'self' 'unsafe-inline'`,
|
||||
`style-src-attr 'unsafe-inline'`,
|
||||
`connect-src 'self' ws: wss: http://127.0.0.1:* http://localhost:* https://cdn.jsdelivr.net`,
|
||||
`img-src 'self' data: blob:${googleEnabled ? ' https://*.googleusercontent.com https://lh3.googleusercontent.com' : ''}`,
|
||||
`font-src 'self' data:`,
|
||||
|
|
|
|||
Loading…
Reference in New Issue