feat(voyage): vendor DOMPurify >=3.1.1 + sanitize annotation-content
This commit is contained in:
parent
e839ba2a7a
commit
fc8c9eecdd
5 changed files with 105 additions and 6 deletions
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"generated_at": "2026-05-09T13:16:03.483Z",
|
||||
"generated_at": "2026-05-10T15:59:53.379Z",
|
||||
"pins": {
|
||||
"markdown-it": "14.1.0",
|
||||
"markdown-it-front-matter": "0.2.4",
|
||||
"highlight.js": "11.11.1"
|
||||
"highlight.js": "11.11.1",
|
||||
"dompurify": "3.2.6"
|
||||
},
|
||||
"highlight_languages": [
|
||||
"yaml",
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
"output_files": [
|
||||
"markdown-it.min.js",
|
||||
"markdown-it-front-matter.min.js",
|
||||
"highlight.min.js"
|
||||
"highlight.min.js",
|
||||
"dompurify.min.js"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
3
plugins/voyage/playground/lib/dompurify.min.js
vendored
Normal file
3
plugins/voyage/playground/lib/dompurify.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1135,6 +1135,10 @@
|
|||
<script src="lib/markdown-it.min.js"></script>
|
||||
<script src="lib/markdown-it-front-matter.min.js"></script>
|
||||
<script src="lib/highlight.min.js"></script>
|
||||
<!-- v4.3 Step 24 — DOMPurify ≥ 3.1.1 (UMD bundle exposes window.DOMPurify).
|
||||
Used by sanitizeAnnotation() to scrub annotation rich-text before DOM
|
||||
insertion. Pinned via scripts/vendor-playground-libs.mjs. -->
|
||||
<script src="lib/dompurify.min.js"></script>
|
||||
|
||||
<!-- Sample plan inlined for Step 8 first-run experience.
|
||||
Same content as tests/fixtures/annotation/annotation-plan.md (truncated). -->
|
||||
|
|
@ -1244,6 +1248,27 @@ playground first-run shows a complete round-trip-able artifact.
|
|||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
// v4.3 Step 24 — DOMPurify-backed annotation-content sanitizer.
|
||||
// Strips <script>, inline styles, and event-handler attributes; keeps
|
||||
// a small allowlist of inline-formatting tags so users can paste basic
|
||||
// rich-text (bold/italic/code) without breaking export round-trip.
|
||||
// Falls back to escapeHtml when DOMPurify is unavailable (file:// in a
|
||||
// browser without the vendored bundle, or test environments).
|
||||
function sanitizeAnnotation(html) {
|
||||
var input = String(html == null ? '' : html);
|
||||
if (typeof window !== 'undefined' && window.DOMPurify && typeof window.DOMPurify.sanitize === 'function') {
|
||||
return window.DOMPurify.sanitize(input, {
|
||||
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'code'],
|
||||
ALLOWED_ATTR: [],
|
||||
FORBID_TAGS: ['style', 'script'],
|
||||
FORBID_ATTR: ['style', 'onerror', 'onload'],
|
||||
});
|
||||
}
|
||||
// Defensive fallback — never inject untrusted HTML if DOMPurify
|
||||
// failed to load.
|
||||
return escapeHtml(input);
|
||||
}
|
||||
|
||||
// Parse frontmatter yourself (cheap line-walk) so deriveStorageKey can
|
||||
// see slug/type without wire-tapping the plugin.
|
||||
function quickParseFrontmatter(text) {
|
||||
|
|
@ -2306,7 +2331,11 @@ playground first-run shows a complete round-trip-able artifact.
|
|||
(annot.line ? '<span class="critique-card__line">linje ' + annot.line + '</span>' : '') +
|
||||
'</div>' +
|
||||
(annot.snippet ? '<div class="critique-card__snippet">' + escapeHtmlInline(annot.snippet) + '</div>' : '') +
|
||||
'<div class="critique-card__comment">' + escapeHtmlInline(annot.comment || '') + '</div>' +
|
||||
// v4.3 Step 24 — comment is user-entered rich-text; route through
|
||||
// sanitizeAnnotation (DOMPurify-backed) so basic inline-formatting
|
||||
// tags survive while <script>, inline styles, and event-handler
|
||||
// attributes are stripped before DOM insertion.
|
||||
'<div class="critique-card__comment">' + sanitizeAnnotation(annot.comment || '') + '</div>' +
|
||||
'<div class="critique-card__status' + (annot.exported ? ' critique-card__status--exported' : '') + '">' +
|
||||
(annot.exported ? 'Eksportert' : 'Pending') +
|
||||
'</div>';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue