@autumnsgrove/groveengine 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -401,10 +401,10 @@
401
401
  // Sanitize HTML content to prevent XSS attacks (browser-only for SSR compatibility)
402
402
  let DOMPurify = $state(null);
403
403
 
404
- // Load DOMPurify only in browser
404
+ // Load DOMPurify only in browser (avoids jsdom dependency for SSR)
405
405
  onMount(async () => {
406
406
  if (browser) {
407
- const module = await import('isomorphic-dompurify');
407
+ const module = await import('dompurify');
408
408
  DOMPurify = module.default;
409
409
  }
410
410
  });
@@ -1,9 +1,23 @@
1
1
  /**
2
2
  * Centralized sanitization utilities for XSS prevention
3
- * Uses isomorphic-dompurify for both server-side and client-side sanitization
3
+ *
4
+ * Uses DOMPurify for client-side sanitization. On the server (SSR),
5
+ * content is passed through unsanitized since it will be sanitized
6
+ * when the page hydrates on the client.
7
+ *
8
+ * This approach avoids bundling jsdom (required by isomorphic-dompurify)
9
+ * which doesn't work in Cloudflare Workers.
4
10
  */
5
11
 
6
- import DOMPurify from "isomorphic-dompurify";
12
+ import { browser } from "$app/environment";
13
+
14
+ // Dynamically import DOMPurify only in browser
15
+ let DOMPurify = null;
16
+ if (browser) {
17
+ import("dompurify").then((module) => {
18
+ DOMPurify = module.default;
19
+ });
20
+ }
7
21
 
8
22
  /**
9
23
  * Sanitize HTML content to prevent XSS attacks
@@ -15,6 +29,11 @@ export function sanitizeHTML(html) {
15
29
  return "";
16
30
  }
17
31
 
32
+ // On server, pass through - will be sanitized on client hydration
33
+ if (!browser || !DOMPurify) {
34
+ return html;
35
+ }
36
+
18
37
  const config = {
19
38
  FORBID_TAGS: [
20
39
  "script",
@@ -61,6 +80,11 @@ export function sanitizeSVG(svg) {
61
80
  return "";
62
81
  }
63
82
 
83
+ // On server, pass through - will be sanitized on client hydration
84
+ if (!browser || !DOMPurify) {
85
+ return svg;
86
+ }
87
+
64
88
  return DOMPurify.sanitize(svg, {
65
89
  USE_PROFILES: { svg: true, svgFilters: true },
66
90
  ALLOWED_TAGS: [
@@ -156,6 +180,11 @@ export function sanitizeMarkdown(markdownHTML) {
156
180
  return "";
157
181
  }
158
182
 
183
+ // On server, pass through - will be sanitized on client hydration
184
+ if (!browser || !DOMPurify) {
185
+ return markdownHTML;
186
+ }
187
+
159
188
  // For markdown, we allow a broader set of tags but still sanitize
160
189
  return DOMPurify.sanitize(markdownHTML, {
161
190
  ALLOWED_TAGS: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autumnsgrove/groveengine",
3
- "version": "0.4.7",
3
+ "version": "0.4.8",
4
4
  "description": "Multi-tenant blog engine for Grove Platform. Features gutter annotations, markdown editing, magic code auth, and Cloudflare Workers deployment.",
5
5
  "author": "AutumnsGrove",
6
6
  "license": "MIT",
@@ -181,7 +181,7 @@
181
181
  "@types/dompurify": "^3.0.5",
182
182
  "chart.js": "^4.5.1",
183
183
  "clsx": "^2.1.1",
184
- "isomorphic-dompurify": "^2.33.0",
184
+ "dompurify": "^3.3.0",
185
185
  "gray-matter": "^4.0.3",
186
186
  "lucide-svelte": "^0.554.0",
187
187
  "marked": "^17.0.1",