fix(v3.18.1): wave-5 operator feedback (CSRF, orphan cleanup)#104
Merged
Conversation
SPA navigations swap <main> only; rotating the cookie on GET left the <head> meta token stale, mismatching subsequent POSTs (banner upload 403). Closes #101.
UpdateArticle now returns the previous banner value alongside its error. HandleEdit passes that to UnlinkOwnedUpload, which removes the file only when it matches /uploads/<slug>/<filename> shape and lives inside the slug's upload dir. External URLs, /static/... paths, and bare filenames are operator-managed and left alone. Closes #103.
Walks <UPLOAD_PATH>/<slug>/ once per boot and removes files no article references via banner field or body content (markdown image, raw HTML img/src, plain link). URL-decoded, traversal-rejected. Bounded by 60s timeout, runs async post-bind. Disable with ORPHAN_SWEEP_DISABLED=true. Refs #103.
Lets forkers size or weight tags via CSS attribute selectors without JS. Operator request, no semantics change for existing markup. Closes #100.
Best-effort cleanup must not crash the server. An unrecovered panic in runOrphanSweep would propagate to the runtime and bring down the process. Logged at Error level so it still surfaces in triage.
GetAllArticles() applies the v3.13.0 DedicatedRouteArticle predicate and omits type:page content. Without GetPages() in the union, Page banner uploads appeared unreferenced and were swept on every restart.
This was referenced May 19, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four issues from the log.1mb.dev operator: CSRF middleware preserves a valid cookie across GETs (#101); banner uploads no longer orphan on swap or remove (#103) via per-action unlink + startup sweep with reference tracking; tag-cloud anchors emit
data-countfor CSS weighting (#100); autosave warning element contract pinned by test (#102 — symptom not reproducible from code).Changes
middleware/middleware.goreuses an existing 64-char hex cookie on GET/HEAD; rotation only on absence/malformed. SPA<main>-only swap no longer staled meta against a rotated cookie.UpdateArticlereturns the prev banner;compose.UnlinkOwnedUploadremoves/uploads/<slug>/<filename>-shape files only,ContainSlugPath-protected, ENOENT-silent. External URLs,/static/..., and bare frontmatter filenames are operator-managed.<UPLOAD_PATH>/<slug>/, removes files no article references via banner field or body content (markdown image, raw HTMLimg/src, plain link). URL-decoded, traversal-rejected. Async post-bind, 60s timeout, panic-recovered.ORPHAN_SWEEP_DISABLED=trueopts out.data-count— one-line attribute on.tag-cloud-item.Test Plan
orphan sweep complete cleaned=Ndata-count="N"on each.tag-cloud-itemCloses #100, #101, #102, #103.