Commit Graph

9 Commits

Author SHA1 Message Date
Benjamin Price
f112ac4819 fix: use stable site hash for install telemetry deduplication (#298)
* fix: use stable site hash for install telemetry deduplication (#297)

generateSiteHash() used Date.now() as the hash seed, producing a different
hash on every call. Since the installs table uses PRIMARY KEY (plugin_id,
site_hash), the same site could insert unlimited rows, inflating install
counts and making "Most Popular" sorting meaningless.

Fix: use the site's request origin as a stable hash seed. The same origin
always produces the same hash, so the marketplace deduplicates correctly.

Also denormalizes install_count on the plugins table to avoid a COUNT(*)
subquery per row in searchPlugins(). The count is recalculated atomically
on each upsertInstall() call.

Fixes #297

* chore: add changeset for install telemetry fix

* fix: address review feedback on install telemetry

- Replace crypto.subtle fallback with FNV-1a hash to avoid origin
  leakage and collisions from truncated seed strings
- Remove duplicate p.install_count from SELECT (p.* already includes it)
- Use explicit p.install_count in ORDER BY clause
- Use db.batch() for atomic upsert + count recomputation instead of
  separate statements with misleading meta.changes check
2026-04-07 22:37:00 +01:00
Matt Kane
91e31fb2ca fix: validate sandbox plugin exports and fix plugin packaging (#363)
* fix(webhook-notifier): add build step and export built files

The webhook-notifier plugin exported raw TypeScript source from its
package.json exports (./sandbox pointed to src/sandbox-entry.ts).
When the Vite plugin resolved this at site build time, it embedded
unbuilt TypeScript into the sandbox module, causing "Unexpected token
'{'" errors at runtime.

Add a tsdown build step (matching sandboxed-test's pattern) and update
the exports map to point to dist/*.mjs.

Fixes #150

* fix(core): reject unbuilt source in sandbox module generator and bundle validator

Add two validation checks to prevent plugins with misconfigured exports
from silently breaking site builds:

1. generateSandboxedPluginsModule() now throws a clear error if a
   sandbox entrypoint resolves to a TypeScript/JSX source file instead
   of pre-built JavaScript. This catches the problem at site build time
   with an actionable message.

2. The `emdash bundle` command now validates that all package.json
   exports point to built files (.js/.mjs), not source (.ts/.tsx/.jsx).
   This catches the misconfiguration at plugin publish time, before
   consumers are affected.

Fixes #150

* chore: add changeset for sandbox source validation

* fix: use slash syntax for e18e rule override in oxlintrc

The test file override for e18e/prefer-static-regex used parenthesis
syntax ("e18e(prefer-static-regex)") which is the diagnostic display
format, not the config format. Changed to slash syntax to match the
top-level rule declarations so the override actually takes effect.

* test: add tests for sandbox source validation

Add tests for both validation checks:

- generateSandboxedPluginsModule: verifies it embeds pre-built JS,
  rejects .ts/.tsx/.mts source files, and includes the plugin ID in
  error messages.

- findSourceExports: verifies it flags .ts/.tsx/.mts/.cts/.jsx exports,
  accepts .mjs/.js exports, and handles conditional export maps.

Also extracts findSourceExports() from the inline bundle.ts validation
into bundle-utils.ts so it can be tested without the CLI harness.

* fix(atproto, audit-log): add build step and export built files

Same issue as webhook-notifier — both plugins exported raw TypeScript
source from their package.json sandbox exports. Add tsdown build steps
and update exports to point to dist/*.mjs.

* refactor(smoke): replace sequential per-site astro builds with recursive pnpm build

The build verification section was running `astro build` individually
and sequentially for every demo and template (~12 sites). Replace with
a single `pnpm run --recursive --filter {./demos/*} --filter
{./templates/*} build` which pnpm parallelizes automatically.
2026-04-07 22:34:35 +01:00
Hasan Smadi
dbaf8c6f85 fix(visual-editing): don’t open admin for portableText; simplify starter PT markup (#40)
* fix(visual-editing): PT inline editing; align starter templates

* chore(admin): format router.tsx

---------

Co-authored-by: Matt Kane <mkane@cloudflare.com>
2026-04-06 20:10:09 +00:00
Benjamin Price
8c693b582d fix: prevent media upload OOM on Workers for large images (#262)
* fix: prevent media upload OOM on Workers via client thumbnails + server safety net

Large image uploads (5MB+) crash Cloudflare Workers (128MB limit) because
generatePlaceholder() decodes entire images to raw RGBA pixels. A 4000x3000
JPEG becomes ~48MB RGBA, exceeding the isolate memory budget.

Two-layer fix:
- Client-side: browser generates a 64px canvas thumbnail for oversized images
  and sends it alongside the upload. Server generates blurhash from the
  thumbnail (~16KB RGBA) instead of decoding the full image.
- Server-side: reads dimensions from image headers via image-size and skips
  placeholder generation when estimated decoded size exceeds 32MB. This covers
  API/CLI uploads that don't provide thumbnails.

* chore: add changeset for media upload OOM fix

* fix: clamp upload thumbnail to 64x64 box for extreme aspect ratios

Naive sizing (thumbW=64, thumbH=(h/w)*64) could produce an enormous canvas
for very tall or very wide images — e.g. a 100x840000 image would allocate
a 64x537600 canvas client-side, reintroducing the memory blowup this feature
exists to prevent.

Extract computeThumbnailSize() that fits the image within a 64x64 box by
scaling against max(width, height), wrap canvas allocation and drawImage
in try/catch with a no-thumbnail fallback, and add unit tests covering
extreme aspect ratios.

---------

Co-authored-by: Matt Kane <mkane@cloudflare.com>
2026-04-06 07:14:39 +00:00
seslly
d2114523a5 fix: passkeys behind TLS reverse proxy (#225)
* fix: passkeys behind TLS reverse proxy

Add passkeyPublicOrigin and wire it through passkey routes so origin/rpId match
the browser when dev runs behind nginx. Expose dev-only /_emdash/api/dev/passkey-url,
add admin messaging for insecure WebAuthn contexts, nginx repro under demos/simple,
and direct kysely dependency for the simple demo Node adapter bundle.

Made-with: Cursor

* docs: add passkeyPublicOrigin to configuration reference

Adds the new passkeyPublicOrigin option and reverse proxy guidance
to the public-facing configuration docs as requested in PR review.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* update tests and more docs

* fix: add missing refresh-server-pat fixture and restore docs heading

---------

Co-authored-by: Joseph Eftekhari <jdeftekhari@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 07:41:07 +01:00
Justin White
9269759674 fix: magic links missing root prefix (#133)
* Fix magic links

* Include changeset

---------

Co-authored-by: Matt Kane <mkane@cloudflare.com>
2026-04-04 19:47:05 +01:00
Matt Kane
ca3c2b77e1 Format 2026-04-01 11:51:57 +01:00
Matt Kane
2e863566b3 Fix scope 2026-04-01 10:58:32 +01:00
Matt Kane
43fcb9a131 first commit 2026-04-01 10:44:22 +01:00