diff --git a/apps/web/package.json b/apps/web/package.json index c5f2c8b..3e7a72f 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -15,6 +15,7 @@ "@astrojs/markdown-remark": "^7.3.1", "@astrojs/rss": "^4.0.19", "@astrojs/svelte": "^9.0.1", + "@civic-source/shared": "workspace:*", "@civic-source/types": "workspace:*", "@fontsource/public-sans": "^5.3.0", "@octokit/rest": "^22.0.1", diff --git a/apps/web/src/__tests__/markdown-sanitize.test.ts b/apps/web/src/__tests__/markdown-sanitize.test.ts index 06e0c9d..c4f775b 100644 --- a/apps/web/src/__tests__/markdown-sanitize.test.ts +++ b/apps/web/src/__tests__/markdown-sanitize.test.ts @@ -14,7 +14,18 @@ describe('markdown sanitization wiring', () => { it('astro config registers rehype-sanitize as a markdown rehype plugin', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const unifiedOptions = (astroConfig.markdown as any)?.unified?.options; + // eslint-disable-next-line @typescript-eslint/no-explicit-any const plugins = unifiedOptions?.rehypePlugins ?? (astroConfig.markdown as any)?.rehypePlugins ?? []; expect(plugins).toContain(rehypeSanitize); }); + + it('unified markdown renderer strips malicious script tags from output', async () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const unifiedProcessor = (astroConfig.markdown as any)?.unified; + expect(unifiedProcessor).toBeDefined(); + const renderer = await unifiedProcessor.createRenderer({}); + const result = await renderer.render('# Section Title\n\n\n\nLegitimate statutory text.'); + expect(result.code).not.toContain(' @@ -91,7 +110,7 @@ class="inline-flex items-center gap-1 rounded-md border border-gray-200 bg-white px-2.5 py-1 text-xs font-medium text-slate shadow-2xs hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700" aria-label="Toggle text size" > - Size: + Size: {textSize === 'sm' ? '17px' : textSize === 'base' ? '19px' : '21px'} @@ -102,7 +121,7 @@ class="inline-flex items-center gap-1 rounded-md border border-gray-200 bg-white px-2.5 py-1 text-xs font-medium text-slate shadow-2xs hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700" aria-label="Toggle reading line width" > - Width: + Width: {measureMode === 'standard' ? 'Standard' : 'Wide'} diff --git a/apps/web/src/components/SearchBar.svelte b/apps/web/src/components/SearchBar.svelte index 405aea5..17c3102 100644 --- a/apps/web/src/components/SearchBar.svelte +++ b/apps/web/src/components/SearchBar.svelte @@ -1,5 +1,5 @@ diff --git a/apps/web/src/layouts/BaseLayout.astro b/apps/web/src/layouts/BaseLayout.astro index 8cdad07..3bf386f 100644 --- a/apps/web/src/layouts/BaseLayout.astro +++ b/apps/web/src/layouts/BaseLayout.astro @@ -54,7 +54,7 @@ const titleEntries = Object.entries(TITLE_NAMES) - + {title === 'US Code Tracker' ? title : `${title} | US Code Tracker`}