@reblu/site-blocks 0.3.0 → 0.3.1

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.
Files changed (2) hide show
  1. package/README.md +21 -0
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -13,6 +13,7 @@ a different-looking site for every tenant, with zero forks.
13
13
  | Export | Entry | Purpose |
14
14
  | ------ | ----- | ------- |
15
15
  | `readingTime`, `formatPrice`, `buildShareUrls`, `markdownToSafeHtml` | `.` | Pure, framework-agnostic helpers (RSC-safe). |
16
+ | `sanitizeHtml` | `.` | Sanitises an HTML string before `dangerouslySetInnerHTML` — the **HTML boundary**. See "Security boundaries" below. |
16
17
  | `MarkdownRenderer` | `.` | Canonical Blog renderer: `marked` → **hast-util-sanitize** (XSS) → component map, with a YouTube-domain allowlist. RSC-safe. |
17
18
  | `Treatment`, `Specialty`, `ProfileCard`, `ProductCard` | `.` | Presentational organisms over the SITE API contracts. RSC-safe. |
18
19
  | `useCollection` | `./client` | Headless filterable/sortable/paginated collection hook (facets, category, tag, search). Serves both page and blog indexes. |
@@ -25,5 +26,25 @@ a different-looking site for every tenant, with zero forks.
25
26
  - **`@reblu/site-blocks`** = organisms + headless data hooks. Higher churn — its
26
27
  own package so a breaking change in an organism does not bump the stable atoms.
27
28
 
29
+ ## Security boundaries
30
+
31
+ Two sinks, two different helpers, in two different packages — do not reach for
32
+ one where the other belongs:
33
+
34
+ | Sink | Helper | Package |
35
+ | ---- | ------ | ------- |
36
+ | HTML rendered via `dangerouslySetInnerHTML` | `sanitizeHtml` (strip/allowlist sanitiser) | `@reblu/site-blocks` (here) |
37
+ | `<script type="application/ld+json">` body | `jsonLdScriptContent` / `<JsonLd>` (escaper) | [`@reblu/site-next/json-ld`](../site-next#structured-data-json-ld) |
38
+
39
+ A `<script>` body is HTML's **raw-text** context: the parser ends it on the
40
+ first `</script` byte sequence regardless of whether that sequence sits inside
41
+ a JSON string, so `JSON.stringify`-ing tenant data straight into a JSON-LD
42
+ `<script>` is a stored-XSS sink `sanitizeHtml` does not cover (it sanitises
43
+ markup, not JSON). `jsonLdScriptContent` lives in `@reblu/site-next` rather
44
+ than here: it has zero dependencies of its own, and this package's main entry
45
+ bundles `parse5` + the `hast-util-*` chain + `marked` for `sanitizeHtml`
46
+ (`treeshake: false`, ~463 KB unminified) — importing the escaper from here
47
+ would drag that parser chain behind a 40-line function.
48
+
28
49
  Types come from [`@reblu/site-contracts`](../site-contracts) (the SDK view of the
29
50
  `/api/site/*` responses). No Zod and no Prisma reach the consumer runtime.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reblu/site-blocks",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Data-driven presentational organisms for Reblu SITEs (Collection, MarkdownRenderer, Treatment, Specialty, ProfileCard, ProductCard) — clean, token-driven, white-label.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Reblu — Adolfo Unturbe",
@@ -59,7 +59,7 @@
59
59
  "dependencies": {
60
60
  "class-variance-authority": "^0.7.1",
61
61
  "html-react-parser": "^6.1.5",
62
- "@reblu/site-contracts": "0.3.0",
62
+ "@reblu/site-contracts": "0.4.0",
63
63
  "@reblu/site-ui": "0.3.1"
64
64
  },
65
65
  "peerDependencies": {