Skip to content

feat(nextjs): serve the admin console from a Next.js application - #187

Merged
Bccorb merged 1 commit into
mainfrom
feat/nextjs-console-proxy
Oct 6, 2026
Merged

Bccorb merged 1 commit into
mainfrom
feat/nextjs-console-proxy

Conversation

@Bccorb

@Bccorb Bccorb commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #185.

Adds createSeamlessConsoleProxy to @seamless-auth/nextjs, the counterpart of the Express and Fastify console proxies:

// app/console/[[...path]]/route.ts
import { createSeamlessConsoleProxy } from "@seamless-auth/nextjs";

export const { GET, HEAD } = createSeamlessConsoleProxy({
  authServerUrl: process.env.AUTH_SERVER_URL!,
});
  • Same behavior as the siblings: forwards only the method and the path (no cookies, no Authorization), copies content-type, cache-control, etag, and last-modified back, refuses encoded %2f/%5c, and never requests outside the console subtree. An unreachable upstream answers 502.
  • Like the Fastify proxy, decisions are made on the request URL, not on decoded catch-all params. The Request URL parser collapses .. and %2e%2e, so a traversal shows up as a path outside the mount and gets a 400.
  • Returns only GET and HEAD. Next.js answers 405 for methods the route does not export, so a write never reaches the handler. The handler still guards the method in case it is wired to another export.
  • New mountPath option (default /console), because a route handler does not know where it is mounted. It must include any Next.js basePath. basePath keeps the sibling meaning (the upstream subtree).
  • Upstream null-body statuses pass through without a body (the Response constructor would throw, see fix(nextjs): send no body on a null-body status #181).

Scope item 2 (CORS for a dashboard on another origin)

Not included. Same origin is documented as the only supported shape. A CORS mode would mean credentialed cross-origin requests to the cookie session routes, which needs its own design. If we want it, it should be a separate issue.

Tests

  • packages/nextjs/tests/parity.test.js: the Fastify console scenarios, plus the console root, run against Next.js and Express (status, body, content type, cache control, and upstream URLs must match). The "write is refused" scenario is left out because Next.js handles that before the handler runs.
  • packages/nextjs/tests/consoleProxy.test.js: exported methods, HEAD, the response header allowlist, no forwarded credentials, null-body status, mountPath and basePath, and paths outside the mount.

pnpm build, pnpm test (core 314, express 190, nextjs 124, fastify 108), and pnpm check:types-current all pass.

Cross-repo

Once this ships, fells-code/seamless-cli#219 can offer --admin=api for the Next.js full-stack template.

Add createSeamlessConsoleProxy, a GET/HEAD route handler for
app/console/[[...path]]/route.ts that proxies the dashboard SPA from the
auth server, matching the Express and Fastify console proxies. The console
parity scenarios now run against Next.js and Express.

Closes #185
@Bccorb
Bccorb merged commit 6538393 into main Oct 6, 2026
2 checks passed
@Bccorb
Bccorb deleted the feat/nextjs-console-proxy branch October 6, 2026 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(nextjs): serve the admin console from a Next.js application

1 participant