diff --git a/src/components/Markdown.svelte b/src/components/Markdown.svelte index cc8153889..199d0ff0c 100644 --- a/src/components/Markdown.svelte +++ b/src/components/Markdown.svelte @@ -18,7 +18,7 @@ canonicalize, isCommit, } from "@app/lib/utils"; - import { Renderer, markdown } from "@app/lib/markdown"; + import { Renderer, markdown, sanitizeConfig } from "@app/lib/markdown"; export let content: string; export let path: string = "/"; @@ -97,7 +97,8 @@ renderer: new Renderer($activeUnloadedRouteStore), breaks, }) as string, - ); + sanitizeConfig, + ) as string; } afterUpdate(async () => { diff --git a/src/lib/commit.ts b/src/lib/commit.ts index 8a23f3e1c..205295939 100644 --- a/src/lib/commit.ts +++ b/src/lib/commit.ts @@ -142,10 +142,10 @@ export function renderCommitDescription(text: string): string { out += escape(trimmed.slice(cursor)); return dompurify.sanitize(out, { /* eslint-disable @typescript-eslint/naming-convention */ - ADD_TAGS: ["radicle-external-link"], - ADD_ATTR: ["href"], + ALLOWED_TAGS: ["radicle-external-link"], + ALLOWED_ATTR: ["href"], /* eslint-enable @typescript-eslint/naming-convention */ - }); + }) as string; } export async function loadRepoActivity( diff --git a/src/lib/markdown.ts b/src/lib/markdown.ts index c23899832..c4d0bf951 100644 --- a/src/lib/markdown.ts +++ b/src/lib/markdown.ts @@ -1,7 +1,7 @@ +import type { Config } from "dompurify"; import type { MarkedExtension, Tokens } from "marked"; import type { Route } from "@app/lib/router"; -import dompurify from "dompurify"; import footnoteMarkedExtension from "marked-footnote"; import katexMarkedExtension from "marked-katex-extension"; import linkifyMarkedExtension from "marked-linkify-it"; @@ -12,7 +12,14 @@ import emojis from "@app/lib/emojis"; import { canonicalize, isUrl } from "@app/lib/utils"; import { routeToPath } from "@app/lib/router"; -dompurify.setConfig({ +/** + * DOMPurify configuration for sanitizing markdown-derived HTML. Pass this as + * the second argument to `dompurify.sanitize` at each call site instead of + * setting it globally — a global config leaks into other consumers of the + * DOMPurify singleton (e.g. mermaid's internal strict-mode sanitization), + * which would strip the SVG output of valid diagrams. + */ +export const sanitizeConfig: Config = { /* eslint-disable @typescript-eslint/naming-convention */ ALLOWED_ATTR: [ "align", @@ -67,7 +74,7 @@ dompurify.setConfig({ "ul", ], /* eslint-enable @typescript-eslint/naming-convention */ -}); +}; export class Renderer extends BaseRenderer { #route: Route; diff --git a/src/views/nodes/View.svelte b/src/views/nodes/View.svelte index cae4b4eb5..f6e12c77c 100644 --- a/src/views/nodes/View.svelte +++ b/src/views/nodes/View.svelte @@ -2,7 +2,7 @@ import type { BaseUrl, Node, NodeStats } from "@http-client"; import dompurify from "dompurify"; - import { markdown } from "@app/lib/markdown"; + import { markdown, sanitizeConfig } from "@app/lib/markdown"; import Command from "@app/components/Command.svelte"; import Icon from "@app/components/Icon.svelte"; @@ -25,7 +25,8 @@ function render(content: string): string { return dompurify.sanitize( markdown({ linkify: true, emojis: true }).parse(content) as string, - ); + sanitizeConfig, + ) as string; } diff --git a/src/views/repos/Source/RepoNameHeader.svelte b/src/views/repos/Source/RepoNameHeader.svelte index 48141f246..aaa322aa7 100644 --- a/src/views/repos/Source/RepoNameHeader.svelte +++ b/src/views/repos/Source/RepoNameHeader.svelte @@ -2,7 +2,7 @@ import type { BaseUrl, Repo, SeedingPolicy } from "@http-client"; import dompurify from "dompurify"; - import { markdown } from "@app/lib/markdown"; + import { markdown, sanitizeConfig } from "@app/lib/markdown"; import { formatRepositoryId, twemoji } from "@app/lib/utils"; import Badge from "@app/components/Badge.svelte"; @@ -19,7 +19,8 @@ function render(content: string): string { return dompurify.sanitize( markdown({ linkify: true, emojis: true }).parseInline(content) as string, - ); + sanitizeConfig, + ) as string; } $: project = repo.payloads["xyz.radicle.project"]; diff --git a/src/views/repos/components/InlineTitle.svelte b/src/views/repos/components/InlineTitle.svelte index 04f10ceb3..ab9773e82 100644 --- a/src/views/repos/components/InlineTitle.svelte +++ b/src/views/repos/components/InlineTitle.svelte @@ -1,6 +1,7 @@