30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import sanitizeHtml from 'sanitize-html';
|
|
|
|
/**
|
|
* Sanitizes HTML content to prevent XSS attacks.
|
|
* Use this before passing content to dangerouslySetInnerHTML.
|
|
*/
|
|
export function sanitizeHTML(html: string): string {
|
|
if (!html) return '';
|
|
|
|
// Remplacer les espaces insécables par des espaces normaux
|
|
// Empêche le navigateur de considérer un paragraphe entier comme un seul mot
|
|
const cleanHtml = html.replace(/ |\u00A0/g, ' ');
|
|
|
|
return sanitizeHtml(cleanHtml, {
|
|
allowedTags: [
|
|
'p', 'br', 'b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li',
|
|
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'span', 'div',
|
|
'img', 'table', 'thead', 'tbody', 'tr', 'th', 'td'
|
|
],
|
|
allowedAttributes: {
|
|
'a': ['href', 'target', 'rel'],
|
|
'img': ['src', 'alt'],
|
|
'*': ['class', 'style']
|
|
},
|
|
selfClosing: ['img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta'],
|
|
// Standard URLs only
|
|
allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'tel'],
|
|
});
|
|
}
|