feat(breakwater): Markdown renderer and HTML sanitizer with the forum policy (D-17)

- modules/breakwater exports Render(markdown) and Purify(html): goldmark GFM
  in its default safe mode (raw HTML stripped, unsafe links dropped), then a
  named bluemonday policy built from NewPolicy, not the UGC preset
- the policy is the PHP golem15/forum HTMLPurifier config 1:1: the fixed
  element list, a[href|rel|target], http/https/mailto only, rel=nofollow on
  every link, target=_blank plus noopener on fully-qualified links
- tests cover the PHP ForumMarkdownRenderTest corpus, links per scheme,
  blank input, the Purify allow-list and concurrent use; testable examples
  feed the docs page snippets
- module README, root module table row, introduction.md Utilities row and
  docs/services/markdown.md (which gate serves user content vs admin fields)
- go.mod and go.sum unchanged: bluemonday v1.0.27 and goldmark v1.8.6 were
  already pinned
This commit is contained in:
Jakub Zych
2026-10-18 14:52:30 +02:00
parent 5ccf726e8a
commit 98bc6de8f5
7 changed files with 430 additions and 1 deletions

View File

@@ -96,6 +96,7 @@ The `migrate`, `migrate:status`, `migrate:rollback`, `serve` and admin commands
| [boardwalk](modules/boardwalk/README.md) | HTTP handler that serves the embedded admin SPA build under a configurable path prefix. | The walkway along the beach front; it is the path admins take into the admin SPA. |
| [bonfire](modules/bonfire/README.md) | Declarative console commands for the `summer` tool and application binaries, adapted to Cobra with typed input, prompts and styled output. | The evening fire where everyone gathers; the command line is where you sit down and fire off commands. |
| [bouncer](modules/bouncer/README.md) | Authentication for SummerCMS: HS256 JWT minting, verification and refresh, request guards, a revoked-token blacklist and bcrypt password helpers. | Checks IDs at the beach club door; it authenticates requests and turns away the ones without a valid token. |
| [breakwater](modules/breakwater/README.md) | Markdown renderer and HTML sanitizer for user-submitted content: GitHub Flavored Markdown through goldmark, then a fixed bluemonday allow-list that adds nofollow and target=_blank to links. | A breakwater takes the force of the open sea; user Markdown and HTML break on the policy and only calm, allow-listed HTML reaches the shore. |
| [cabana](modules/cabana/README.md) | Schema-driven admin backend that compiles WinterCMS-style YAML list, form, filter and relation definitions at boot and serves them as a JSON admin API next to the embedded admin SPA. | The beach hut where the staff run the beach; it is the admin backend. |
| [compass](modules/compass/README.md) | Layered YAML configuration with per-environment directories, `SUMMER_` environment overrides, embedded plugin defaults and dot-path access. | Points you the right way; configuration tells the application how to behave in each environment. |
| [conga](modules/conga/README.md) | Background jobs on River over the shared Postgres pool: transactional dispatch, a `summer_jobs` progress record, in-process or dedicated workers, and a wall-clock scheduler. | A line of dancers moving one after another; jobs queue up and are worked through in order. |