fix(landing-page): render iframe embed codes instead of stripping them
The embed section passed code through SafeHtmlContent which ran DOMPurify with FORBID_TAGS including 'iframe', silently removing the element. Replaced SafeHtmlContent with a new sanitizeEmbedHtml() that uses a whitelist of ALLOWED_TAGS: ['iframe'] and restricts src to https: only, so Google Forms, YouTube, and other https embeds render while javascript: sources and non-iframe tags are still blocked.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
import type { OrgLandingPageLabels, OrgLandingPageTheme, LandingPageEmbed } from './types';
|
import type { OrgLandingPageLabels, OrgLandingPageTheme, LandingPageEmbed } from './types';
|
||||||
import SecondaryActionButton from './secondary-action-button.svelte';
|
import SecondaryActionButton from './secondary-action-button.svelte';
|
||||||
import EditableLandingSection from './editable-section.svelte';
|
import EditableLandingSection from './editable-section.svelte';
|
||||||
import SafeHtmlContent from '../safe-html-content/safe-html-content.svelte';
|
import { sanitizeEmbedHtml } from '../../tools/sanitize';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
embed,
|
embed,
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
style="border: 1px solid #262a35; background: #0f1218; box-shadow: 0 30px 90px -30px rgba(0,0,0,0.7);"
|
style="border: 1px solid #262a35; background: #0f1218; box-shadow: 0 30px 90px -30px rgba(0,0,0,0.7);"
|
||||||
>
|
>
|
||||||
<div class="ui:p-5 ui:overflow-x-auto" style="color: #e9eaed;">
|
<div class="ui:p-5 ui:overflow-x-auto" style="color: #e9eaed;">
|
||||||
<SafeHtmlContent content={embed.code} />
|
{@html sanitizeEmbedHtml(embed.code)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if embed.code}
|
{#if embed.code}
|
||||||
<div class="ui:flex ui:w-full ui:justify-center">
|
<div class="ui:flex ui:w-full ui:justify-center">
|
||||||
<SafeHtmlContent content={embed.code} />
|
{@html sanitizeEmbedHtml(embed.code)}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if embed.code}
|
{#if embed.code}
|
||||||
<div class="ui:flex ui:w-full ui:justify-center">
|
<div class="ui:flex ui:w-full ui:justify-center">
|
||||||
<SafeHtmlContent content={embed.code} />
|
{@html sanitizeEmbedHtml(embed.code)}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -133,6 +133,34 @@ export function splitHtmlAndSvg(html: string): ContentSegment[] {
|
|||||||
return segments;
|
return segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitizes an embed code snippet (e.g. a pasted <iframe>). Allows only
|
||||||
|
* <iframe> tags with https: sources; everything else is stripped. Use this
|
||||||
|
* for org landing-page embed sections — not for general rich-text content.
|
||||||
|
*/
|
||||||
|
export function sanitizeEmbedHtml(html: string): string {
|
||||||
|
if (typeof html !== 'string') return '';
|
||||||
|
if (!browser) return '';
|
||||||
|
|
||||||
|
return DOMPurify.sanitize(html, {
|
||||||
|
ALLOWED_TAGS: ['iframe'],
|
||||||
|
ALLOWED_ATTR: [
|
||||||
|
'src',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'frameborder',
|
||||||
|
'marginheight',
|
||||||
|
'marginwidth',
|
||||||
|
'title',
|
||||||
|
'loading',
|
||||||
|
'allow',
|
||||||
|
'allowfullscreen',
|
||||||
|
'sandbox'
|
||||||
|
],
|
||||||
|
ALLOWED_URI_REGEXP: /^https:/i
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strips all HTML tags and returns plain text
|
* Strips all HTML tags and returns plain text
|
||||||
* Use this when you only need the text content
|
* Use this when you only need the text content
|
||||||
|
|||||||
Reference in New Issue
Block a user