A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 1.4 kB View raw
1import sanitizeHtml from 'sanitize-html'; 2 3/** 4 * Sanitise rendered article HTML before injecting it into a reading page. 5 * 6 * Article content comes from arbitrary PDSes and is UNTRUSTED — a malicious record 7 * could embed `<script>`/`onerror`/etc. We allow only the tags + attributes the curated 8 * blocks (Decision 0002) and inline rich text produce; everything else is stripped. 9 * External links get `rel="noopener noreferrer nofollow ugc"` and open in a new tab. 10 */ 11const OPTIONS: sanitizeHtml.IOptions = { 12 allowedTags: [ 13 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 14 'ul', 'ol', 'li', 15 'blockquote', 'cite', 16 'pre', 'code', 'kbd', 17 'hr', 'figure', 'figcaption', 'img', 18 'strong', 'em', 'b', 'i', 's', 'del', 'ins', 'sub', 'sup', 'mark', 19 'a', 'br', 'span', 20 'button', // video-embed facade play button (no iframe — injected client-side, Task 7) 21 ], 22 allowedAttributes: { 23 a: [ 'href', 'title', 'rel', 'target' ], 24 img: [ 'src', 'alt', 'loading' ], 25 button: [ 'type', 'data-embed-provider', 'data-embed-id' ], 26 '*': [ 'class' ], 27 }, 28 allowedSchemes: [ 'http', 'https', 'mailto' ], 29 allowedSchemesByTag: { img: [ 'http', 'https' ] }, 30 transformTags: { 31 a: sanitizeHtml.simpleTransform( 'a', { 32 rel: 'noopener noreferrer nofollow ugc', 33 target: '_blank', 34 } ), 35 }, 36}; 37 38export function sanitizeArticleHtml( html: string ): string { 39 return sanitizeHtml( html, OPTIONS ); 40}