Skip to content

feat: Implement basic web search UI in serve.py#7

Open
oasis-parzival wants to merge 1 commit intoMakiDevelop:mainfrom
oasis-parzival:jarvis-fix-1775327598
Open

feat: Implement basic web search UI in serve.py#7
oasis-parzival wants to merge 1 commit intoMakiDevelop:mainfrom
oasis-parzival:jarvis-fix-1775327598

Conversation

@oasis-parzival
Copy link
Copy Markdown

Closes #4

This PR adds a simple, self-contained web UI to the serve.py application, allowing users to perform searches directly through a browser. The UI is implemented with inline HTML, CSS, and JavaScript to avoid any external dependencies or build processes, focusing on a clean and functional design similar to Hacker News. It directly calls the existing /search endpoint and displays results in a readable list format.

@MakiDevelop
Copy link
Copy Markdown
Owner

Thanks for the contribution! Idea is welcome (issue #4) but there's a security issue that blocks merge plus a few rough edges:

🔴 Critical — Stored XSS via innerHTML

resultDiv.innerHTML = `
    <div class="score">Score: ${result.signal_score.toFixed(3)}</div>
    <div class="route">Route: ${result.route}</div>
    <div>Title: ${result.title}</div>
    <div>Core Insight: ${result.core_insight}</div>
`;

result.title / result.core_insight come from rewritten external pages (this is exactly what the pipeline ingests). A malicious page can inject <script> or <img onerror> that survives ingestion → executed in the browser when user searches.

Fix: use textContent per field, or escape via a helper:

function el(tag, cls, text) {
    const e = document.createElement(tag);
    if (cls) e.className = cls;
    if (text != null) e.textContent = text;
    return e;
}

resultDiv.appendChild(el('div', 'score', `Score: ${result.signal_score.toFixed(3)}`));
resultDiv.appendChild(el('div', 'route', `Route: ${result.route}`));
resultDiv.appendChild(el('div', null, `Title: ${result.title}`));
resultDiv.appendChild(el('div', null, `Core Insight: ${result.core_insight}`));

🟡 Other issues

  1. Query not URL-encodedfetch(\/search?q=${query}`)breaks on&, #, +. Use encodeURIComponent(query)`.
  2. No error handling — if /search fails, page silently does nothing. Wrap in try/catch and show an error div.
  3. No clickable URL — users likely want to jump to the original source. Add result.url as an <a target="_blank" rel="noopener noreferrer">.
  4. Empty query — server returns 400 but UI just shows "No results found." Consider client-side guard.

Path forward

Fix #1 (XSS) — that's the blocker. Items 2-4 are nice-to-have but #2 (encoding) is also a real bug that will frustrate testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add simple web UI for search

2 participants