diff --git a/frontend/package.json b/frontend/package.json index 91031de..fe8f1fc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,6 +24,7 @@ "@tailwindcss/typography": "^0.5.15", "@tailwindcss/vite": "^4.0.0", "@types/markdown-it": "^14.1.2", + "dompurify": "^3.2.6", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-svelte": "^3.0.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 9dce47f..fd5c867 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: '@types/markdown-it': specifier: ^14.1.2 version: 14.1.2 + dompurify: + specifier: ^3.2.6 + version: 3.2.6 eslint: specifier: ^9.18.0 version: 9.31.0(jiti@2.4.2) @@ -640,6 +643,9 @@ packages: '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@typescript-eslint/eslint-plugin@8.38.0': resolution: {integrity: sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -809,6 +815,9 @@ packages: devalue@5.1.1: resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + dompurify@3.2.6: + resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==} + enhanced-resolve@5.18.2: resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} engines: {node: '>=10.13.0'} @@ -1997,6 +2006,9 @@ snapshots: '@types/resolve@1.20.2': {} + '@types/trusted-types@2.0.7': + optional: true + '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -2175,6 +2187,10 @@ snapshots: devalue@5.1.1: {} + dompurify@3.2.6: + optionalDependencies: + '@types/trusted-types': 2.0.7 + enhanced-resolve@5.18.2: dependencies: graceful-fs: 4.2.11 diff --git a/frontend/src/lib/common/framework/ui/SafeHtml.svelte b/frontend/src/lib/common/framework/ui/SafeHtml.svelte new file mode 100644 index 0000000..e01f980 --- /dev/null +++ b/frontend/src/lib/common/framework/ui/SafeHtml.svelte @@ -0,0 +1,11 @@ + + +{@html sanitizedHtml} diff --git a/frontend/src/lib/post/framework/ui/PostContentPage.svelte b/frontend/src/lib/post/framework/ui/PostContentPage.svelte index a19d596..d8093b8 100644 --- a/frontend/src/lib/post/framework/ui/PostContentPage.svelte +++ b/frontend/src/lib/post/framework/ui/PostContentPage.svelte @@ -3,6 +3,7 @@ import PostContentHeader from '$lib/post/framework/ui/PostContentHeader.svelte'; import { getContext, onMount } from 'svelte'; import markdownit from 'markdown-it'; + import SafeHtml from '$lib/common/framework/ui/SafeHtml.svelte'; const { id }: { id: number } = $props(); @@ -15,12 +16,12 @@ onMount(() => postBloc.dispatch({ event: PostEventType.PostLoadedEvent, id: id })); - + {#if state.data} - {@html parsedContent} + {/if}