RTE Posts upgrade: TipTap editor + sanitization for posts
Extend the wiki's RichTextEditor to the Posts editor and close the stored-XSS gap on public post bodies. - RichTextEditor: add `variant` prop — `full` (wiki), `post` (no internal wiki-page link picker), `minimal` (image-only, for Screenshots captions). Toolbar sections rendered conditionally. - PostEditor: replace the body textarea with a lazy-loaded RichTextEditor in Suspense; variant chosen by category (minimal for screenshots, post otherwise). - posts.model: sanitize body via shared cleanBody on create/update, treat an empty TipTap `<p></p>` as null, and auto-derive the excerpt from the body (max 280 chars) when left blank. - sanitizeHtml util: add deriveExcerpt() helper. - FiveOnFriday / NewsletterIssue: wrap dangerouslySetInnerHTML with DOMPurify.sanitize() as defense-in-depth on render. No schema or dependency changes. Verified end-to-end against the local stack: 24/24 API assertions and a full UI round-trip across all four post categories. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -42,4 +42,22 @@ function cleanBody(html) {
|
||||
return sanitizeHtml(String(html), OPTIONS)
|
||||
}
|
||||
|
||||
module.exports = { cleanBody, OPTIONS }
|
||||
/**
|
||||
* Derive a plain-text excerpt from body HTML. Strips tags, collapses
|
||||
* whitespace, and truncates to `max` chars (with an ellipsis). Used as the
|
||||
* excerpt fallback when an author leaves the excerpt field blank.
|
||||
* @param {string|null|undefined} html
|
||||
* @param {number} [max=280]
|
||||
* @returns {string|null}
|
||||
*/
|
||||
function deriveExcerpt(html, max = 280) {
|
||||
if (html == null) return null
|
||||
const text = String(html)
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim()
|
||||
if (!text) return null
|
||||
return text.length > max ? `${text.slice(0, max - 3)}...` : text
|
||||
}
|
||||
|
||||
module.exports = { cleanBody, deriveExcerpt, OPTIONS }
|
||||
|
||||
Reference in New Issue
Block a user