diff --git a/.planning/phases/17-blog-companions/17-REVIEW-FIX.md b/.planning/phases/17-blog-companions/17-REVIEW-FIX.md index c273830..e02ba49 100644 --- a/.planning/phases/17-blog-companions/17-REVIEW-FIX.md +++ b/.planning/phases/17-blog-companions/17-REVIEW-FIX.md @@ -26,7 +26,7 @@ Paths outside `summercms.go` are relative to `/media/nvme/dev/golem15/summercms. ## Fixed Issues -### CR-01: Sitemap writes admin-supplied `javascript:` URLs into `` (stored XSS) +### CR-01: Sitemap writes admin-supplied `javascript:` URLs into ``, which sitemap.xsl renders as a clickable link on the public origin (stored XSS) **Files modified:** - `summercms.go`: `modules/signpost/signpost.go`, `modules/signpost/signpost_test.go`, `modules/signpost/README.md`, `docs/plugins/menu-item-types.md` @@ -45,7 +45,7 @@ Paths outside `summercms.go` are relative to `/media/nvme/dev/golem15/summercms. - **Framework.** `signpost.Registry.Pattern` now ignores an item override that is not a path: it must start with a single `/`, with no `//` or `/\` prefix, no surrounding whitespace and no control characters. The next layer then applies. The new helper `signpost.ValidItemPattern` is documented in the README and in `docs/plugins/menu-item-types.md`. - **Design choice.** The review's `allowedSitemapURL` would also have refused relative paths such as `about`. That would reject PHP data that worked, so the rule I applied is wider: a relative or `/` path, or an absolute `http`/`https` URL. Any other scheme is refused, and so are protocol-relative `//host` and `/\host`, a bare `#fragment`, surrounding whitespace and control characters. `//evil.test/x` cannot leave the site, because `Url::to` puts it under the root host. -### WR-01: Moving a menu entry to another menu orphans its subtree; a parent from another menu overrides the chosen menu +### WR-01: Moving a menu entry to another menu orphans its subtree, and a parent from another menu silently overrides the chosen menu **Files modified:** `sm-menu-plugin`: `models/menu_entry.go`, `controllers/menuentries.go`, `lang/en/lang.yaml`, `lang/pl/lang.yaml`, `README.md`, `menu_smoke_test.go` **Commit:** `7255d34` (sm-menu-plugin) @@ -56,7 +56,7 @@ Paths outside `summercms.go` are relative to `/media/nvme/dev/golem15/summercms. - **UI text.** The `menu_comment` help text explains both behaviours. - **Design choice.** I chose refusal over scoping the parent options, because `RelationExtendOptionsQuery` gets no record context. -### WR-02: Reorder page sends overlapping saves; out-of-order completion leaves an older tree +### WR-02: Reorder page sends overlapping saves; out-of-order completion leaves the database on an older tree than the screen shows **Files modified:** `summercms.go`: `admin/src/views/ReorderView.vue`, `admin/tests/views/ReorderView.test.ts`, `docs/backend/lists-and-filters.md` **Commits:** `e1ac983`, plus `27bb13b` (dist rebuild) @@ -67,7 +67,7 @@ Paths outside `summercms.go` are relative to `/media/nvme/dev/golem15/summercms. - **Failures.** A failed save does not restore the old tree if a later save is waiting or a move is still in its 400 ms debounce, because that later save carries the whole tree. A 409 drops a queued save of the same set and reloads. - **Tests.** Two new specs cover a failure with a queued move and a late response after a partition switch. Both fail against the old code. -### WR-03: A registry menu entry or sitemap row saved without a reference passes validation and then disappears +### WR-03: A registry menu entry or sitemap row saved without a reference passes validation and then silently disappears **Files modified:** - `sm-menu-plugin`: `controllers/menuentries.go`, `lang/en/lang.yaml`, `lang/pl/lang.yaml`, `README.md`, `menu_smoke_test.go` @@ -80,7 +80,7 @@ Paths outside `summercms.go` are relative to `/media/nvme/dev/golem15/summercms. - **Sitemap rows.** The definitions controller refuses the same case per row (`data..reference`). It reuses the PHP phrase `golem15.sitemap::lang.item.reference_required`. - **Not changed.** `cabana.amongOptions` is left as it is. Required-ness is per type, which the plugins know and cabana does not. -### WR-04: `journal-post` resolves unpublished posts, exposing drafts on the anonymous menu API and in sitemap.xml +### WR-04: `journal-post` resolves unpublished posts, exposing draft titles and URLs on the anonymous menu API and in sitemap.xml **Files modified:** `sm-journal-plugin`: `classes/menu_item_types.go`, `menu_item_types_test.go`, `menu_item_types_smoke_test.go`, `README.md` **Commit:** `31d901c` (sm-journal-plugin)