You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
1.2 KiB
60 lines
1.2 KiB
/** |
|
* HTML sanitization using DOMPurify |
|
*/ |
|
|
|
import DOMPurify from 'dompurify'; |
|
import { browser } from '$app/environment'; |
|
|
|
/** |
|
* Sanitize HTML content |
|
*/ |
|
export function sanitizeHtml(dirty: string): string { |
|
// Only sanitize in browser - during SSR, return as-is (will be sanitized on client) |
|
if (!browser) { |
|
return dirty; |
|
} |
|
|
|
const config = { |
|
ALLOWED_TAGS: [ |
|
'p', |
|
'br', |
|
'strong', |
|
'em', |
|
'u', |
|
's', |
|
'code', |
|
'pre', |
|
'a', |
|
'ul', |
|
'ol', |
|
'li', |
|
'blockquote', |
|
'h1', |
|
'h2', |
|
'h3', |
|
'h4', |
|
'h5', |
|
'h6', |
|
'img', |
|
'video', |
|
'audio', |
|
'div', |
|
'span' |
|
], |
|
ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'class', 'controls', 'preload', 'loading', 'autoplay', 'width', 'height', 'data-pubkey', 'data-event-id', 'data-placeholder', 'data-nostr-profile', 'data-nostr-event', 'data-mounted'], |
|
ALLOW_DATA_ATTR: true, |
|
KEEP_CONTENT: true, |
|
// Ensure images are preserved |
|
FORBID_TAGS: [], |
|
FORBID_ATTR: [] |
|
}; |
|
|
|
return DOMPurify.sanitize(dirty, config); |
|
} |
|
|
|
/** |
|
* Sanitize markdown-rendered HTML |
|
*/ |
|
export function sanitizeMarkdown(html: string): string { |
|
return sanitizeHtml(html); |
|
}
|
|
|