- runtimeConfig.siteCache.allowProxied (NUXT_SITE_CACHE_ALLOW_PROXIED, default
false) lets the shared purge route accept a request that came through a
TLS-terminating proxy; the bearer token is then the only gate
- shared lib, route and spec stay byte-identical across the three layers,
with updated sha256 pins and two new sitePurge specs
- version 0.5.0
- server/lib/siteCachePurge.ts and the route, byte for byte from
vue-faq-layer (sha256 pinned in tests/sitePurge.test.ts)
- runtimeConfig.siteCache.purgeToken (NUXT_SITE_CACHE_PURGE_TOKEN) and the
'/api/__site__/**': { cache: false } route rule
- /api/__journal__/cache/purge, app/utils/siteCache.ts and
journal.cachePurgeToken unchanged, documented as aliases for one release
- version 0.4.0
Nitro's cached handler renders from a header-less copy of the request, so
under swr route rules useJournalApi, /rss.xml and the sitemap source
forwarded only the Nuxt peer and every cache miss shared one Journal API
rate-limit bucket (deferred in Phase 16). A Nitro plugin records
x-forwarded-for plus the peer in event.context.journalForwardedFor on the
request hook; the three callers forward it. Same key as the host app's
workaround, which keeps working. The acme SSR smoke's x-forwarded-for check
on the now route-cached playground is the test.
- exact names: purge auth disabled, proxied before the token, missing or
wrong bearer; purge removes every route cache entry and only those
- parsePurgeEvent kinds, control characters, 200-character cap, non-objects
- privateRevalidate with and without max-age, the 304 form, static values
- privateRevalidate sets max-age=0 on cache-control values with s-maxage
- server/plugins/journal-revalidate.ts wraps res.setHeader per request, so
Nitro's 200 and h3's 304 answers both carry it
- purge-check: max-age=0 on 200 and 304, purged _payload.json, a second
purge after re-caching, X-Real-IP refused, 404 on a server without a token
- README: cachePurgeToken row and a Site cache purge section
- htmlGate.ts mirrors the four editor-output rules of the Go policy:
figure data-embed (^youtube$) and data-id (^[A-Za-z0-9_-]{11}$),
img alt with any text, ol start (integer)
- embeds.ts: EMBED_PROVIDERS (youtube on youtube-nocookie.com),
EMBED_PLACEHOLDER and expandEmbeds
- JournalPostBody and JournalCategoryHeader render
expandEmbeds(sanitizeJournalHtml(html)); payload transforms only sanitize
- .journal-embed styles (16 / 9 block, borderless iframe)
- tests: byte copy of the editor corpus, mirror and pipeline cases;
acme hello-acme carries a placeholder and the SSR smoke checks the iframe
- README Embeds section and decision note Policy amendment
The three-regex gate could be bypassed (an attribute without a space,
<svg/onload>, entity-encoded or tab-split javascript: URLs, MathML
xlink:href, base, meta refresh, forms) and it blanked a whole post or
category when ordinary text such as "Data: 12 maja 2024" matched.
- sanitizeJournalHtml runs sanitize-html with the Journal plugin's
bluemonday policy: UGC elements plus footer, class, schema.org
microdata, four validated inline styles, footnote roles, dir=auto,
two chat transcript data attributes; http, https, mailto and
relative URLs only
- gateJournalHtml and isSafeJournalHtml keep their signatures; html is
always the sanitized value and is never blanked
- post body, category content and both page payloads are sanitized;
the blocked notice, its style and string, and the blocked props and
content_blocked field are removed
- toPostView moves to postView.ts so list pages and cards do not load
the sanitizer
- tests cover every bypass from the review, the Data:/metadata: text
and an imported author footer; the SSR smoke expects the unsafe
sample's safe paragraphs
- node --test over routes, client (fake fetcher, include_empty=1),
pagination, htmlGate (Go FormatHTML parity cases), sitemap, seo and
pl/en i18n parity
- package script test and a Testing line in the README
- author pages resolve slug or login and canonicalise to the slug
- tag pages, per-page SEO meta and canonicals that keep ?page=N
- sitemap source pages the API and builds locs from journal.routes
- /rss.xml proxies the API feed with x-forwarded-for
- neutral README; version 0.1.0