import sanitizeHtml from 'sanitize-html'; const CARD_HTML_CONFIG: sanitizeHtml.IOptions = { allowedTags: [ 'p', 'br', 'strong', 'em', 'b', 'i', 'u', 'ul', 'ol', 'li', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'span', ], allowedAttributes: { a: ['href', 'title', 'target', 'rel'], span: ['class'], '*': [], }, allowedSchemes: ['http', 'https', 'mailto', 'tel'], allowedSchemesAppliedToAttributes: ['href'], transformTags: { a: sanitizeHtml.simpleTransform('a', { rel: 'noopener noreferrer', target: '_blank' }), }, disallowedTagsMode: 'discard', }; export function sanitizeCardHtml(input: string | null | undefined): string { if (!input) return ''; return sanitizeHtml(input, CARD_HTML_CONFIG); } // Welcome text: solo formattazione inline base + a-capo. Niente link, niente liste. const WELCOME_TEXT_CONFIG: sanitizeHtml.IOptions = { allowedTags: ['b', 'i', 'strong', 'em', 'br', 'p', 'div', 'span'], allowedAttributes: {}, disallowedTagsMode: 'discard', }; export function sanitizeWelcomeText(input: string | null | undefined): string { if (!input) return ''; return sanitizeHtml(input, WELCOME_TEXT_CONFIG); } const HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/; export function isValidHexColor(value: unknown): value is string { return typeof value === 'string' && HEX_COLOR_RE.test(value); }