Skip to content

emdash

[email protected] scope: emdash Security

This release includes 1 security fix for security teams reviewing exposed deployments.

Published 16d Productivity & Wikis
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →
This release patches 1 known CVE

Topics

astro cms emdash typescript

Affected surfaces

auth

Summary

AI summary

Broad release touches Patch Changes, Minor Changes, https://github.com/swissky, and https://github.com/marcusbellamyshaw-cell.

Changes in this release

Security High

Ensures preview and editor-toolbar responses are not cached in shared edge cache without token verification, preventing unauthorized access to draft content.

Ensures preview and editor-toolbar responses are not cached in shared edge cache without token verification, preventing unauthorized access to draft content.

Source: granite4.1:30b@2026-07-15-audit

Confidence: high

Feature Medium

Adds HTTP API for content references under /_emdash/api/relations and /content/:collection/:id/references.

Adds HTTP API for content references under /_emdash/api/relations and /content/:collection/:id/references.

Source: llm_adapter@2026-07-15

Confidence: high

Feature Medium

MCP `content_create` and `content_update` now accept a `taxonomies` field for assigning taxonomy terms in the same transaction.

MCP `content_create` and `content_update` now accept a `taxonomies` field for assigning taxonomy terms in the same transaction.

Source: llm_adapter@2026-07-15

Confidence: high

Feature Medium

Adds `taxonomies:read` plugin capability with read-only taxonomy access via ctx.taxonomies.

Adds `taxonomies:read` plugin capability with read-only taxonomy access via ctx.taxonomies.

Source: llm_adapter@2026-07-15

Confidence: high

Feature Medium

Implements pagination for `search()` and `searchCollection()` with cursor support.

Implements pagination for `search()` and `searchCollection()` with cursor support.

Source: llm_adapter@2026-07-15

Confidence: high

Feature Medium

Adds admin REST endpoint and EmDashClient.mediaRepairUsage() for repairing content media usage indexes.

Adds admin REST endpoint and EmDashClient.mediaRepairUsage() for repairing content media usage indexes.

Source: llm_adapter@2026-07-15

Confidence: high

Feature Medium

Adds `toolbar` config option with "client" mode and dismiss button for editor toolbar delivery behind shared caches.

Adds `toolbar` config option with "client" mode and dismiss button for editor toolbar delivery behind shared caches.

Source: llm_adapter@2026-07-15

Confidence: high

Feature Low

Adds hreflang alternate links to page head for translated content via `<EmDashHead>` and `getHreflangAlternates()` helper.

Adds hreflang alternate links to page head for translated content via `<EmDashHead>` and `getHreflangAlternates()` helper.

Source: granite4.1:30b@2026-07-15-audit

Confidence: high

Performance Medium

Speeds up admin content-list search on collections with full‑text search enabled by using FTS5 index.

Speeds up admin content-list search on collections with full‑text search enabled by using FTS5 index.

Source: llm_adapter@2026-07-15

Confidence: high

Bugfix High

Fixes comment submissions bypassing Turnstile verification when secret key is set.

Fixes comment submissions bypassing Turnstile verification when secret key is set.

Source: llm_adapter@2026-07-15

Confidence: high

Bugfix Medium

Fixes admin dashboard scheduled-content summary to count entries with pending schedules instead of inferring from other statuses.

Fixes admin dashboard scheduled-content summary to count entries with pending schedules instead of inferring from other statuses.

Source: llm_adapter@2026-07-15

Confidence: high

Bugfix Medium

Fixes search across all collections failing when any collection lacks a `title` field.

Fixes search across all collections failing when any collection lacks a `title` field.

Source: llm_adapter@2026-07-15

Confidence: high

Bugfix Medium

Prevents database stampede on Postgres when pending migration fails at runtime; retries with backoff and avoids leaking idle connections.

Prevents database stampede on Postgres when pending migration fails at runtime; retries with backoff and avoids leaking idle connections.

Source: granite4.1:30b@2026-07-15-audit

Confidence: high

Bugfix Low

Fixes multi-paragraph blockquotes splitting into separate quotes; consecutive quote paragraphs render as a single blockquote.

Fixes multi-paragraph blockquotes splitting into separate quotes; consecutive quote paragraphs render as a single blockquote.

Source: granite4.1:30b@2026-07-15-audit

Confidence: high

Full changelog

Minor Changes

  • #1535 0360900 Thanks @MA2153! - Adds an HTTP API for content references: relation-definition CRUD under /_emdash/api/relations (editor-readable, admin-writable) and directed reference edges on content entries under /_emdash/api/content/:collection/:id/references/:relation/{children,parents} (ownership-aware). References are stored only in the references table — no collection column. The edge reads are cursor-paginated (?cursor/?limit, default 50, max 100) and return nextCursor; each resolved entry carries the locale of the variant returned.

  • #1874 1526f96 Thanks @Vallhalen! - MCP content_create and content_update now accept a taxonomies field
    ({ [taxonomyName]: [termSlug, ...] }) that assigns taxonomy terms in the
    same transaction as the content write. Term slugs are resolved in the entry's
    locale via the same code path as the /terms/{taxonomy} REST route, so the
    two entry points can't drift. Also exposed on the REST POST and PUT
    content endpoints for parity. Fixes #953.

  • #1719 7c5de08 Thanks @swissky! - Adds a taxonomies:read plugin capability with read-only taxonomy access: plugins that declare it get ctx.taxonomies to list taxonomy definitions (getAll()), fetch the terms of a taxonomy (getTerms()), and read the terms assigned to a content entry (getEntryTerms()) — in-process and in both sandbox runners.

  • #1578 58f594b Thanks @marcusbellamyshaw-cell! - Implements pagination for search() and searchCollection()

    search() advertised keyset pagination through its types (options.cursor, SearchResponse.nextCursor) but never read the cursor or returned one, so results were silently capped at limit with no way to load a second page.

    Both search() and searchCollection() now honour cursor and return a nextCursor whenever more matches exist. Pass the previous nextCursor back as cursor to walk subsequent pages; it becomes undefined on the last page. The /_emdash/api/search endpoint accepts a cursor query parameter and returns nextCursor in its response (a malformed cursor returns a 400 INVALID_CURSOR).

    let cursor: string | undefined;
    do {
    	const { items, nextCursor } = await search("quarterly report", {
    		limit: 20,
    		cursor,
    	});
    	render(items);
    	cursor = nextCursor;
    } while (cursor);
    
  • #1867 c57b12b Thanks @khoinguyenpham04! - Adds an admin REST endpoint and EmDashClient.mediaRepairUsage() client method for repairing content media usage indexes by collection or across all collections.

  • #1886 60811c0 Thanks @swissky! - Adds a toolbar config option for reliable editor-toolbar delivery behind shared caches. toolbar: "client" keeps public HTML identical for every visitor and shows a client-side "Edit" pill for logged-in editors that opens a fresh, uncached editor render via an _edit query param; toolbar: false disables the toolbar entirely. The toolbar can now also be dismissed in the browser via its × button. The default ("server") is unchanged.

Patch Changes

  • #1865 582ea2c Thanks @khoinguyenpham04! - Fixes the admin dashboard scheduled-content summary so it counts entries with pending schedules instead of inferring the count from other statuses.

  • #1857 77e8968 Thanks @swissky! - Speeds up the admin content-list search on collections with full-text search enabled: the filter is now served from the FTS5 index (token-prefix matching plus slug-prefix lookup) instead of scanning every row. Collections without search enabled, and PostgreSQL databases, keep the previous substring matching.

  • #1905 e12f393 Thanks @swissky! - Fixes multi-paragraph blockquotes splitting into separate quotes: consecutive quote paragraphs now render as a single blockquote on the site and load as one quote block in the editor, so merging them no longer reverts on reload.

  • #1854 e4e76f5 Thanks @swissky! - Fixes comment submissions bypassing Turnstile: when the EMDASH_TURNSTILE_SECRET_KEY (or TURNSTILE_SECRET_KEY) environment variable is set, the public comment endpoint now verifies the submitted Turnstile token server-side and rejects submissions without a valid one. Sites without a configured secret key are unaffected.

  • #1550 cbc7d6b Thanks @marcusbellamyshaw-cell! - Fixes search across all collections failing with D1_ERROR: no such column: c.title when any search-enabled collection has no title field (#1178). title is an optional field, not a guaranteed column, so calling search (or the MCP search tool) without a collections filter could error instead of searching everything. Cross-collection search now works regardless of which collections define a title; results from a collection without one simply omit the title, and autocomplete suggestions skip such collections rather than erroring.

  • #1907 15f4057 Thanks @swissky! - Adds hreflang alternate links to the page head for translated content. <EmDashHead> now emits a <link rel="alternate" hreflang="..."> per published translation (plus x-default) automatically, and a new getHreflangAlternates() helper resolves the same set for hand-rolled heads.

  • #1875 b116525 Thanks @ascorbic! - Fixes a database stampede on Postgres when a pending migration fails at runtime: requests no longer pile up waiting on the migration lock, failed migrations are retried with a backoff instead of on every request, and failed attempts no longer leak idle database connections.

  • #1855 450ea81 Thanks @swissky! - Fixes preview and editor-toolbar responses being stored in the shared edge cache when route caching is enabled: requests with a _preview token and toolbar-injected editor pages now opt out of the route cache, so draft content is no longer served from the cache without token verification and toolbar markup no longer leaks to anonymous visitors.

  • #1892 9c0733f Thanks @ascorbic! - Fixes taxonomy term counts (Categories/Tags widgets, term pages, and the admin term list) so they only include content that is publicly visible: published or scheduled-and-due entries that have not been trashed. Counts are now also scoped to the taxonomy's declared collections.

  • Updated dependencies [582ea2c, 582ea2c, d2f5ddc, d237e96, 9792226, 7c5de08, 60811c0]:

Security Fixes

  • Comment submissions now verify Turnstile token server‑side when `EMDASH_TURNSTILE_SECRET_KEY` (or `TURNSTILE_SECRET_KEY`) is set, rejecting invalid tokens

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track emdash

Get notified when new releases ship.

Sign up free

About emdash

All releases →

Related context

Related tools

Earlier breaking changes

Beta — feedback welcome: [email protected]