github emdash-cms/emdash @emdash-cms/blocks@0.39.0

Minor Changes

  • #3188 4fef109 Thanks @ascorbic! - Adds saved-entry panels and actions for sandboxed plugins. Declare collection-filtered admin.editorPanels and admin.editorActions entries that point to private plugin routes.

    Panels load Block Kit only when an editor opens them. Actions support confirmation and can return a toast, request an entry refresh, or navigate through a structured link target. EmDash reloads and ownership-authorizes the saved entry before invocation, then exposes only its canonical identity, locale, and version through routeCtx.ui; unsaved editor values never cross the sandbox boundary.

    createPluginRuntimeTestHost() includes panel and action helpers that exercise the production authorization, response-validation, and Worker Loader path.

  • #3251 dbd77ef Thanks @ascorbic! - Adds explicit, consented access to selected unsaved content for sandboxed editor panels and actions.

    Plugins can request admin.editor-draft:read to receive extension-selected field values after an editor invokes them, and admin.editor-draft:patch to propose atomic whole-field set or clear operations. Patch access does not imply read access. Each extension must declare explicit collection scope and narrow its access to field slugs, translatable fields, or both.

    EmDash authenticates and authorizes the saved entry, reloads its schema and revision, validates snapshot and patch limits, and rejects stale or invalid responses. The admin shows a host-rendered before-and-after preview, applies accepted changes to the visible form, marks it dirty, and leaves saving to the editor. Panel load and ordinary typing do not expose draft data or invoke the plugin.

    createPluginRuntimeTestHost() now provides draft capture and host-validated patch application helpers for production-boundary plugin tests.

  • #3174 06bad83 Thanks @ascorbic! - Adds structured Block Kit navigation and host-attested administrator locale context for sandboxed plugin pages and dashboard widgets.

    Plugins can return link elements that target saved content, another page declared by the same plugin, generated plugin settings, or an external HTTP, HTTPS, or mailto: URL. EmDash constructs internal admin URLs and opens external links with noopener noreferrer. Links never dispatch block actions and cannot appear as form fields.

    Block Kit route handlers receive routeCtx.ui with the validated surface, administrator locale, and text direction. The host validates every sandboxed page and widget response before rendering it, rejects undeclared plugin-page targets and active URL protocols, and permits external images only over HTTPS to hosts declared in allowedHosts under network:request consent or under network:request:unrestricted consent. Responses are limited to 256 KiB, 20 levels, 2,000 nodes, 1,000 items per array, and 64 KiB per string.

    createPluginRuntimeTestHost() adds admin.loadPage(), loadWidget(), act(), and submit() helpers that exercise the private production route, Worker Loader isolate, host UI context, and response validation.

    This is a breaking security tightening for sandboxed plugins that return an external Block Kit image without matching network authority. EmDash rejects the complete page or widget response instead of allowing the administrator's browser to contact an unapproved host.

    What should I do?

    If a plugin returns external Block Kit images, add network:request and every image hostname to allowedHosts, or add network:request:unrestricted when the plugin genuinely requires any hostname. Publish a plugin update so administrators can review and approve the expanded authority. Root-relative images need no manifest change.

Patch Changes

Don't miss a new emdash release

NewReleases is sending notifications on new releases.