Skip to content

fix(admin): prevent admin basepath from being prepended to non-admin URLs#1720

Merged
ascorbic merged 6 commits into
emdash-cms:mainfrom
segmentationfaulter:main
Jul 9, 2026
Merged

fix(admin): prevent admin basepath from being prepended to non-admin URLs#1720
ascorbic merged 6 commits into
emdash-cms:mainfrom
segmentationfaulter:main

Conversation

@segmentationfaulter

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes a regression from #398 where OAuth provider login buttons (Google, GitHub) on the admin login page link to /_emdash/admin/_emdash/api/auth/oauth/google instead of /_emdash/api/auth/oauth/google, causing a 404.

Root cause: In KumoRouterLink (the component bridging Kumo's LinkButton to TanStack Router), normalizeAdminHref returned non-admin /_emdash/* paths unchanged. These were then passed to TanStack Router's , which prepended the admin basepath /_emdash/admin.

Fix: normalizeAdminHref now returns "" for paths outside the admin basepath, causing KumoRouterLink to render a plain tag instead of a router . This also corrects the behavior for any non-admin absolute path used with LinkButton.

Closes #1671

Type of change

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

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Do not include messages.po changes except in translation PRs — a workflow extracts catalogs on merge to main.
  • 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 — model/tool:

Screenshots / test output

@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6b24b44

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

This PR includes changesets to release 16 packages
Name Type
@emdash-cms/admin Patch
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/sandbox-workerd Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/do-demo-site Patch
@emdash-cms/do-solo-demo-site Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
create-emdash Patch
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds 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

@github-actions github-actions Bot added review/needs-review No maintainer or bot review yet area/admin size/M labels Jul 2, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

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

@emdash-cms/auth

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

@emdash-cms/auth-atproto

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

@emdash-cms/blocks

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

@emdash-cms/cloudflare

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

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

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

emdash

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

create-emdash

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

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

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

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@1720

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@1720

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@1720

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@1720

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@1720

@emdash-cms/x402

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

@emdash-cms/plugin-ai-moderation

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

@emdash-cms/plugin-atproto

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

@emdash-cms/plugin-audit-log

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

@emdash-cms/plugin-color

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

@emdash-cms/plugin-embeds

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

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@1720

@emdash-cms/plugin-forms

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

@emdash-cms/plugin-webhook-notifier

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

commit: 6b24b44

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a focused, correct fix for the OAuth login-button regression. The approach is sound: KumoRouterLink was treating every root-absolute path as an in-SPA TanStack route, so non-admin /_emdash/* URLs like the OAuth endpoints got the admin basepath prepended. Returning "" from normalizeAdminHref for those paths forces KumoRouterLink to render a plain <a> tag, which is exactly what external-facing/EmDash API URLs need.

What I checked:

  • The diff and full App.tsx; normalizeAdminHref is only consumed by KumoRouterLink and the new placement correctly handles /_emdash/admin/* before falling through to the non-admin /_emdash/ guard.
  • The OAuth button components (packages/core/src/auth/providers/google-admin.tsx, github-admin.tsx) use LinkButton href="/_emdash/api/auth/oauth/..." through Kumo, confirming the broken path described in the PR.
  • router.tsx hardcodes basepath: "/_emdash/admin", matching the ADMIN_BASEPATH constant in App.tsx, so the hardcoded check is consistent with the rest of the admin package.
  • The new unit test covers the key cases: admin basepath stripping, query/hash handling, non-admin /_emdash/ paths, root-relative admin routes, and external/protocol/mailto URLs.
  • A changeset is present and properly scoped to @emdash-cms/admin as a patch.

I noted a possible minor improvement—the test imports the helper through App.tsx, which pulls in the whole admin module graph, but the function is pure and import-time side effects in this file are safe, so this is not a blocker. Otherwise no logic bugs, security issues, or AGENTS.md convention violations. LGTM.

@github-actions github-actions Bot added review/approved Approved; no new commits since and removed review/needs-review No maintainer or bot review yet labels Jul 2, 2026
@masonjames

Copy link
Copy Markdown
Contributor

Tested this against a real deployed EmDash site and the fix holds up.

Environment checked:

  • OAuth env verified present in the running container for Google and GitHub providers

What I verified:

  • The admin login page now renders the Google link as /_emdash/api/auth/oauth/google, not /_emdash/admin/_emdash/api/auth/oauth/google.
  • The GitHub login link also leaves the admin SPA correctly via /_emdash/api/auth/oauth/github.
  • Google OAuth starts at https://accounts.google.com/o/oauth2/v2/auth.
  • GitHub OAuth starts at https://github.com/login/oauth/authorize.
  • After adding the production Google callback URI, the Google flow completes and lands back in the EmDash admin for the existing user.
  • The deployed app routes checked cleanly: /, /_emdash/admin/login

Local/project gates run during the PR-equivalent deployment:

  • pnpm lint:json | jq '.diagnostics | length'
  • pnpm lint:quick
  • pnpm typecheck
  • focused admin regression test for normalizeAdminHref
  • Mason site local CI via scripts/mj/ci-local.sh
  • Swarm service/image/env verification through platform-infra

This covers real-site admin/OAuth behavior that the bot cannot verify. From triage, this looks ready for maintainer review/merge.

@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!

@ascorbic ascorbic enabled auto-merge (squash) July 9, 2026 19:45
@ascorbic ascorbic merged commit 9792226 into emdash-cms:main Jul 9, 2026
43 checks passed
@emdashbot emdashbot Bot mentioned this pull request Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clicking "Login with Google" on the admin dashboard navigates to an incorrect URL

4 participants