fix(middleware): allow public access to search API (#104)#424
Open
csfalcao wants to merge 1 commit intoemdash-cms:mainfrom
Open
fix(middleware): allow public access to search API (#104)#424csfalcao wants to merge 1 commit intoemdash-cms:mainfrom
csfalcao wants to merge 1 commit intoemdash-cms:mainfrom
Conversation
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>
🦋 Changeset detectedLatest commit: 424ef63 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
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 |
Contributor
|
All contributors have signed the CLA ✍️ ✅ |
Author
|
I have read the CLA Document and I hereby sign the CLA |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes the public search bug from #104 at the middleware layer.
#107 removed the handler-level
requirePerm("search:read")check frompackages/core/src/astro/routes/api/search/index.tsand.../suggest.ts, but the auth middleware atpackages/core/src/astro/middleware/auth.ts(handlePasskeyAuth, ~line 587) still returned401 NOT_AUTHENTICATEDbefore the handler ran, because/_emdash/api/searchwas not inPUBLIC_API_EXACTorPUBLIC_API_PREFIXES. The handler-level change from #107 therefore never executed for anonymous callers, and the shipped<LiveSearch>component (which fetches without credentials per its JSDoc example) silently showed "No results found" on every query.Reproducible on
mainat commit 59bdca1:This PR adds
/_emdash/api/searchtoPUBLIC_API_EXACT. ThesearchWithDbquery layer already hardcodesstatus = 'published'and the SQL inquery.tsrepeats the filter, so anonymous callers only see published content — matching the safety justification given in #104's closing comment. Admin endpoints (/search/enable,/search/rebuild,/search/stats) remain gated because they are not added to the set — the exact-match check inisPublicEmDashRoutemeans the sub-paths do not inherit access./search/suggestis deliberately not included: while investigating I hit a separate FTS5 syntax bug ingetSuggestions(double*prefix,query.ts:279) that makes it return 500 regardless of auth. I'll file that as a separate issue with a failing test so it stays scoped.The existing E2E test
"search endpoint requires authentication"asserted the buggy behavior. It is replaced with:"search endpoint is publicly accessible"— asserts200for unauthenticated GET"search admin endpoints still require authentication"— asserts/statsand/enablestay gatedVerified locally against a fresh
demos/simplewith the seeded blog content:Closes #104. Follows up on #107.
Type of change
Checklist
pnpm typecheckpassespnpm --silent lint:json | jq '.diagnostics | length'returns 0pnpm testpasses (or targeted tests for my change)pnpm formathas been runOn the unchecked boxes — full transparency:
lint:jsonreturns2diagnostics on bothmain(commit 59bdca1) and this branch. Both are pre-existingtypescript-eslintwarnings in files this PR does not touch (packages/admin/vitest.config.ts,packages/core/src/astro/integration/vite-config.ts). This PR introduces zero new lint findings. I followedAGENTS.md's "do not touch code outside the scope of your change" guidance and left them alone.pnpm --filter emdash testshows 2 pre-existing failures intests/integration/plugins/capabilities.test.ts(HTTP capability timeouts at 5000ms). Reproduced on cleanmainat 59bdca1. Unrelated to auth or search. Targeted test run for the openapi test (tests/unit/api/openapi.test.ts, which references/search) passes 22/22.search.spec.tswere not run locally because Playwright browsers aren't installed on this machine. The behavior was verified directly viacurlagainst a runningdemos/simpleinstance — the same assertions the tests make. CI will execute the full Playwright suite.AI-generated code disclosure
Investigation, diff, test rewrites, and PR body were produced with Claude Opus 4.6 acting as an agent in this repo. Every change was reviewed line by line and all claims in this PR (repro commands, file paths, line numbers, pre-existing warnings, test names) were independently verified against the running demo and
git logonmain.Screenshots / test output
End-to-end verification via
curlagainstpnpm --filter emdash-demo devfrom a clean clone at commit 59bdca1 (confirming bug), and after applying this patch (confirming fix):Before (on main):
After (this branch):
The
<LiveSearch>header widget indemos/simple/templates/blognow returns live results in the dropdown instead of "No results found" for any query.