-
Notifications
You must be signed in to change notification settings - Fork 12
feat: add client-side event search #585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Add a search feature that lets users search across all past and upcoming events by title, talk name, speaker name, or sponsor. Uses a static JSON index generated at build time and Fuse.js for fuzzy matching on the client. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
||
| const index = allEvents.map((event) => { | ||
| const override = overrides[event.eventUrl] || {}; | ||
| const description = (event.description || '').replace(/<[^>]*>/g, '').slice(0, 200); |
Check failure
Code scanning / CodeQL
Incomplete multi-character sanitization High
<script
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 days ago
In general, the best way to fix this is to replace the custom regex-based stripping with a robust HTML sanitization mechanism that safely converts arbitrary HTML input into plain text (or safely allowed HTML) and does not rely on a single multi-character regex pass. For this search index, the intended behavior appears to be: “strip HTML and keep a short text snippet,” so converting the HTML description to plain text is appropriate and preserves functionality.
The single best fix here, without changing the rest of the script’s behavior, is to replace the .replace(/<[^>]*>/g, '') with a safe HTML-to-text conversion function. Because this is a Node script, we can use a well-known library such as striptags, which is designed to remove HTML tags correctly and does not suffer from the incomplete multi-character sanitization problem. Concretely:
- Add an import for
striptagsat the top ofscripts/generate-search-index.mjs. - Replace the current computation of
descriptionat line 193 with a call tostriptags, followed by.slice(0, 200)as before.
No other logic needs to change: we still limit the text to 200 characters and keep the same structure of entry. The only functional difference is that descriptions are now stripped using a robust algorithm instead of a brittle regex, which addresses the CodeQL warning about incomplete sanitization.
-
Copy modified line R4 -
Copy modified line R194
| @@ -1,6 +1,7 @@ | ||
| import { writeFileSync } from 'node:fs'; | ||
| import { resolve, dirname } from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
| import striptags from 'striptags'; | ||
|
|
||
| const MEETUP_GQL_URL = 'https://www.meetup.com/gql2'; | ||
| const LYONJS_MEETUP_ID = 18305583; | ||
| @@ -190,7 +191,7 @@ | ||
|
|
||
| const index = allEvents.map((event) => { | ||
| const override = overrides[event.eventUrl] || {}; | ||
| const description = (event.description || '').replace(/<[^>]*>/g, '').slice(0, 200); | ||
| const description = striptags(event.description || '').slice(0, 200); | ||
|
|
||
| const entry = { | ||
| id: event.id, |
-
Copy modified lines R26-R27
| @@ -23,7 +23,8 @@ | ||
| "react-markdown": "^10.0.0", | ||
| "sharp": "^0.34.0", | ||
| "temporal-polyfill": "^0.3.0", | ||
| "yet-another-react-lightbox": "^3.21.4" | ||
| "yet-another-react-lightbox": "^3.21.4", | ||
| "striptags": "^3.2.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@playwright/test": "1.58.2", |
| Package | Version | Security advisories |
| striptags (npm) | 3.2.0 | None |
Summary
scripts/generate-search-index.mjsHow it works
generate-search-index.mjsfetches events from Meetup GraphQL API, enriches withdata-override.ts(talks, speakers, sponsors), writespublic/search-index.jsonTest plan
pnpm buildsucceeds (generates index then builds Next.js)🤖 Generated with Claude Code