fix(web): make top-bar search work under strict CSP#105
Merged
Conversation
The top-bar search box used an inline `onfocus="openSearch()"` handler.
The app sends a strict nonce-based CSP (`script-src 'self' 'nonce-...'`,
no `unsafe-inline`), which blocks all inline event handlers. Focusing the
box therefore did nothing — the search modal never opened and no query
ever ran. `/api/search` itself was fine.
Replace the inline handler with a CSP-compliant `addEventListener`:
- `onfocus="openSearch()"` → `id="searchTrigger"`
- wire `searchTrigger.addEventListener('focus', openSearch)`
Verified live in browser (rebuilt image): modal opens on focus, typing
returns results, 0 CSP console errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X9biLMX3yYXrHFRWz7U5gi
There was a problem hiding this comment.
Pull request overview
This PR updates the Web UI’s top-bar search trigger to be compatible with the app’s strict nonce-based Content Security Policy (CSP) by removing an inline event handler and wiring the behavior via JavaScript.
Changes:
- Replace inline
onfocus="openSearch()"on the top-bar search input with anidhook (searchTrigger). - Add a DOM event listener that opens the search modal when the trigger is interacted with.
Comment on lines
+1042
to
+1045
| const searchTriggerEl = document.getElementById('searchTrigger'); | ||
| if (searchTriggerEl) { | ||
| searchTriggerEl.addEventListener('focus', openSearch); | ||
| } |
The base.html change (onfocus → addEventListener) propagates to every page that extends it. Regenerated all golden render snapshots with UPDATE_TEMPLATE_SNAPSHOTS=1. Diff is limited to the searchTrigger swap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X9biLMX3yYXrHFRWz7U5gi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Top-bar search does nothing — clicking/focusing the box never opens the search modal, so no query runs. Reported as "Suche geht nicht".
Root cause
The top-bar search box used an inline
onfocus="openSearch()"handler. The app sends a strict nonce-based CSP (script-src 'self' 'nonce-...', nounsafe-inline, set inweb.py:598), which blocks all inline event handlers. So focus never firedopenSearch()→ modal never opened →#searchInputnever received input →/api/searchwas never called./api/searchitself was healthy (verifiedcurl ...?q=test→ 200 with results). The bug was purely the CSP-blocked entry point.Fix
lore/templates/base.html:onfocus="openSearch()"→id="searchTrigger"searchTrigger.addEventListener('focus', openSearch)(CSP-compliant, matches the pattern already used for#searchInputand Cmd/Ctrl+K)Verification
Rebuilt the image, drove it live with Playwright:
Search sessionsdialog ✅testreturns 10 results ✅Follow-ups (not in this PR)
session.html,sessions.html,projects.html, …) still use inlineon*=handlers → same CSP bug, likely dead buttons. Separate sweep.lore-sync.servicefailed +fastembedmissing in container (semantic search degraded to FTS-only).🤖 Generated with Claude Code
https://claude.ai/code/session_01X9biLMX3yYXrHFRWz7U5gi