Commit c5fa77b
fix(frontend): render raw HTML in package READMEs (sanitized) (#602)
## Problem
Package README pages show raw HTML tags as **literal visible text**. For
example,
[mops.one/googlemail-client@0.1.3](https://mops.one/googlemail-client@0.1.3)
renders a `<details>`/`<summary>` collapsible block as the plain strings
`<details>` and `<summary>` rather than a working disclosure widget.
GitHub renders the same README correctly.
## Root cause
`frontend/logic/markdown-to-html.ts` configures markdown-it with `html:
false`, which **escapes all raw HTML** in README source. The inline
comment even read `// Enable HTML tags in source` — the opposite of what
`false` does. GitHub, by contrast, permits a *sanitized allowlist* of
tags (including `<details>`/`<summary>`), which is why authors write
them.
## Fix
Enable `html: true` and sanitize the rendered output with **DOMPurify**
— the standard, GitHub-equivalent approach:
- Allows a safe tag allowlist (incl. `<details>`/`<summary>`, and keeps
`class` so starry-night syntax highlighting is preserved).
- Strips `<script>`, inline event handlers, and `javascript:` URLs — so
enabling raw HTML does **not** open an XSS hole, which matters since
READMEs are arbitrary third-party author content.
Two incidental cleanups in the same file:
- Corrected the misleading comment to match behavior.
- Removed a dead duplicate `mdit.render(markdown)` call whose result was
discarded (the source was parsed twice per render).
## Impact / retroactivity
README → HTML conversion happens **client-side at view time**
(`PackageReadme.svelte` calls `markdownToHtml(readme, …)` on each
render), from the stored Markdown source. So this fix repairs **every
already-published package page** on the next load — no republish,
version bump, or re-upload required.
## Validation
- `svelte-check --threshold error` → **0 errors** (pre-existing warnings
unchanged).
- DOMPurify v3 ships its own types; pinned exact (`3.4.11`) to match the
repo's dependency convention. Lockfile gains only the single dependency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Kamil Listopad <listopadkamil@gmail.com>1 parent 0af0025 commit c5fa77b
4 files changed
Lines changed: 76 additions & 6 deletions
File tree
- frontend
- components/package
- logic
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
136 | 137 | | |
137 | 138 | | |
138 | 139 | | |
139 | | - | |
| 140 | + | |
140 | 141 | | |
141 | 142 | | |
142 | 143 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| |||
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
22 | | - | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
45 | 46 | | |
46 | 47 | | |
47 | 48 | | |
48 | | - | |
49 | | - | |
50 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
51 | 97 | | |
52 | 98 | | |
53 | 99 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
35 | | - | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| 40 | + | |
39 | 41 | | |
40 | 42 | | |
41 | 43 | | |
| |||
0 commit comments