Skip to content

fix: allow public access to search API for frontend LiveSearch - #107

Merged
ascorbic merged 4 commits into
emdash-cms:mainfrom
mvanhorn:osc/104-public-search-api
Apr 6, 2026
Merged

fix: allow public access to search API for frontend LiveSearch#107
ascorbic merged 4 commits into
emdash-cms:mainfrom
mvanhorn:osc/104-public-search-api

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

The /_emdash/api/search and /_emdash/api/search/suggest endpoints require search:read permission, returning 401 for unauthenticated requests. The LiveSearch component hardcodes these endpoints, so frontend search is broken for public visitors.

Removed the requirePerm(user, "search:read") check and its import from both search/index.ts and search/suggest.ts. Also removed the unused user destructuring from locals.

This is safe because searchWithDb and getSuggestions both default to status: "published" (search/query.ts:71), so unauthenticated visitors only see published content. Admin search routes (rebuild, enable, stats) still require search:manage.

Matches the pattern of other public-facing routes like comments/[collection]/[contentId] and widget-components that work without auth.

Closes #104

Type of change

  • Bug fix
  • Feature (requires approved Discussion)
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm --silent lint:json | jq '.diagnostics | length' returns 0
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

AI-generated code disclosure

  • This PR includes AI-generated code

Screenshots / test output

  • pnpm typecheck passes
  • pnpm test:unit passes (2095 tests)
The search and suggest endpoints required search:read permission,
blocking unauthenticated visitors from using the LiveSearch component.
This is safe because the search query layer defaults to status=published,
so public users only see published content.

Fixes emdash-cms#104
@changeset-bot

changeset-bot Bot commented Apr 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3e9dd3b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/plugin-ai-moderation Patch
@emdash-cms/plugin-atproto Patch
@emdash-cms/plugin-audit-log Patch
@emdash-cms/plugin-color Patch
@emdash-cms/plugin-embeds Patch
@emdash-cms/plugin-forms Patch
@emdash-cms/plugin-webhook-notifier Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ascorbic ascorbic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@pkg-pr-new

pkg-pr-new Bot commented Apr 5, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@107

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@107

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@107

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@107

emdash

npm i https://pkg.pr.new/emdash@107

create-emdash

npm i https://pkg.pr.new/create-emdash@107

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@107

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@107

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@107

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@107

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@107

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@107

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@107

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@107

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@107

commit: 3e9dd3b

@mvanhorn

mvanhorn commented Apr 5, 2026

Copy link
Copy Markdown
Contributor Author

Updated the PR description to use the required template - "Validate PR" check should pass now. Let me know if a changeset is needed for this.

@ascorbic

ascorbic commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

Thanks. Yes, a changeset is needed for anything that affects published packages. This fixes a bug, so would be a patch change

@JULJERYT

JULJERYT commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

is this changeset ok?

---
"emdash": patch
---

Allow public access to search API
Patch bump for emdash - allows public access to search API endpoints.

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

mvanhorn commented Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

Added changeset (patch bump for emdash) in fa8e5bd.

@ascorbic
ascorbic enabled auto-merge (squash) April 6, 2026 19:56
@ascorbic
ascorbic merged commit b297fdd into emdash-cms:main Apr 6, 2026
25 checks passed
@emdashbot emdashbot Bot mentioned this pull request Apr 6, 2026
@mvanhorn

mvanhorn commented Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

Appreciate the merge, @ascorbic. Happy to contribute more to emdash.

@emdashbot emdashbot Bot mentioned this pull request Apr 8, 2026
csfalcao added a commit to csfalcao/emdash that referenced this pull request Apr 10, 2026
PR emdash-cms#107 removed the handler-level `requirePerm()` check from the search
endpoints, but the auth middleware still returned 401 before the handlers
ran because `/_emdash/api/search` was not in `PUBLIC_API_EXACT`. The
handler-level changes therefore never executed for anonymous callers,
and the shipped `LiveSearch` component (which fetches without credentials)
silently showed "No results found" on every query.

This change adds `/_emdash/api/search` to `PUBLIC_API_EXACT` so the
middleware lets anonymous GET requests reach the handler. The query
layer already hardcodes `status='published'`, so anonymous callers
still only see published content. Admin endpoints (`/enable`, `/rebuild`,
`/stats`, and `/suggest`) remain authenticated because they are not in
the set.

The existing E2E test `"search endpoint requires authentication"` asserted
the buggy behavior and is replaced with two new tests: one verifying
public access to `/_emdash/api/search`, and one verifying that `/stats`
and `/enable` remain gated.

Closes emdash-cms#104. Follows up on emdash-cms#107.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ascorbic added a commit that referenced this pull request Apr 11, 2026
#424)

PR #107 removed the handler-level `requirePerm()` check from the search
endpoints, but the auth middleware still returned 401 before the handlers
ran because `/_emdash/api/search` was not in `PUBLIC_API_EXACT`. The
handler-level changes therefore never executed for anonymous callers,
and the shipped `LiveSearch` component (which fetches without credentials)
silently showed "No results found" on every query.

This change adds `/_emdash/api/search` to `PUBLIC_API_EXACT` so the
middleware lets anonymous GET requests reach the handler. The query
layer already hardcodes `status='published'`, so anonymous callers
still only see published content. Admin endpoints (`/enable`, `/rebuild`,
`/stats`, and `/suggest`) remain authenticated because they are not in
the set.

The existing E2E test `"search endpoint requires authentication"` asserted
the buggy behavior and is replaced with two new tests: one verifying
public access to `/_emdash/api/search`, and one verifying that `/stats`
and `/enable` remain gated.

Closes #104. Follows up on #107.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Matt Kane <mkane@cloudflare.com>
@emdashbot emdashbot Bot mentioned this pull request Apr 12, 2026
fmhall pushed a commit to fmhall/emdash that referenced this pull request Apr 13, 2026
emdash-cms#424)

PR emdash-cms#107 removed the handler-level `requirePerm()` check from the search
endpoints, but the auth middleware still returned 401 before the handlers
ran because `/_emdash/api/search` was not in `PUBLIC_API_EXACT`. The
handler-level changes therefore never executed for anonymous callers,
and the shipped `LiveSearch` component (which fetches without credentials)
silently showed "No results found" on every query.

This change adds `/_emdash/api/search` to `PUBLIC_API_EXACT` so the
middleware lets anonymous GET requests reach the handler. The query
layer already hardcodes `status='published'`, so anonymous callers
still only see published content. Admin endpoints (`/enable`, `/rebuild`,
`/stats`, and `/suggest`) remain authenticated because they are not in
the set.

The existing E2E test `"search endpoint requires authentication"` asserted
the buggy behavior and is replaced with two new tests: one verifying
public access to `/_emdash/api/search`, and one verifying that `/stats`
and `/enable` remain gated.

Closes emdash-cms#104. Follows up on emdash-cms#107.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Matt Kane <mkane@cloudflare.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment