From 50e6ee749ecba2da4d3baf6b7ec53d094450e0d5 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 7 Apr 2026 00:05:37 -0400 Subject: [PATCH] Fix image rendering in markdown comments - markdown.js: add renderMarkdownComments() called on DOMContentLoaded to process [data-markdown] elements that were never being rendered on page load - CSP: allow https: in img-src so external images in markdown aren't blocked Co-Authored-By: Claude Sonnet 4.6 --- assets/js/markdown.js | 13 +++++++++++++ middleware/SecurityHeadersMiddleware.php | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/assets/js/markdown.js b/assets/js/markdown.js index c5825fc..65c1768 100644 --- a/assets/js/markdown.js +++ b/assets/js/markdown.js @@ -436,11 +436,24 @@ function processPlainTextComments() { }); } +/** + * Render all [data-markdown] comment elements that haven't been rendered yet + */ +function renderMarkdownComments() { + document.querySelectorAll('.comment-text[data-markdown]:not([data-rendered])').forEach(el => { + el.innerHTML = parseMarkdown(el.textContent); + el.dataset.rendered = '1'; + }); +} + // Run on page load document.addEventListener('DOMContentLoaded', function() { + renderMarkdownComments(); processPlainTextComments(); }); +window.renderMarkdownComments = renderMarkdownComments; + // Expose for manual use window.autoLinkUrls = autoLinkUrls; window.processPlainTextComments = processPlainTextComments; diff --git a/middleware/SecurityHeadersMiddleware.php b/middleware/SecurityHeadersMiddleware.php index f86206a..31c0a36 100644 --- a/middleware/SecurityHeadersMiddleware.php +++ b/middleware/SecurityHeadersMiddleware.php @@ -28,7 +28,7 @@ class SecurityHeadersMiddleware { // Content Security Policy - restricts where resources can be loaded from // Using nonces for scripts to prevent XSS attacks while allowing inline scripts with valid nonces // All inline event handlers have been refactored to use addEventListener with data-action attributes - header("Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{$nonce}' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://cdn.jsdelivr.net;"); + header("Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{$nonce}' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://cdn.jsdelivr.net;"); // Prevent clickjacking by disallowing framing header("X-Frame-Options: DENY");