Skip to content

feat(core): forward the pre-auth credential on magic link verify and serve the confirm route - #219

Merged
Bccorb merged 1 commit into
mainfrom
fix/magic-link-confirm-support
Oct 18, 2026
Merged

Bccorb merged 1 commit into
mainfrom
fix/magic-link-confirm-support

Conversation

@Bccorb

@Bccorb Bccorb commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Supports the magic link confirmation step added in seamless-auth-api 0.19.0.

  • GET /magic-link/verify/:token forwards the opening browser's pre-auth credential when it has one: the ephemeral token from the signed pre-auth cookie (cookie transport, verified with verifyCookieJwt) or the client's Authorization header (bearer transport). Missing, stale or forged credentials send no Authorization and never yield a 401. Client IP, user agent and the service token are forwarded exactly as before.
  • verifyMagicLinkHandler takes an optional authorization; new core export magicLinkVerifyAuthorization builds it. Express, Fastify and Next.js all use the core handler now (Express had its own authFetch, Fastify and Next.js used proxyRequest).
  • ensureCookies is unchanged: verify stays ungated, the handler reads the cookie itself. No new manifest credential kind.
  • 409 confirmation_required passes through verbatim, requestedFrom included (asserted in core and in both parity suites).
  • POST /magic-link/verify/{token}/confirm is served by the manifest catch-alls. Bundled manifest regenerated with node scripts/sync-adapter-manifest.mjs from the API branch's adapter-manifest.json. Origin guard covers it (cross-site POST gets 403, tested in Express and both parity suites).
  • Tests: manifest matching rows, ensureCookies (table and manifest), redaction of the confirm path, public exports, parity scenarios copied to Fastify and Next.js.
  • Docs: Express and core READMEs. Changeset: minor for core, express, fastify, nextjs.

Merge after the API change is released.

Checks (local, Node v24.18.0, pnpm 10.33.0)

Done in 240ms using pnpm v10.33.0

@seamless-auth/core dependencies: @seamless-auth/types "^0.28.0" is current (latest 0.28.0).
@seamless-auth/nextjs dependencies: @seamless-auth/types "^0.28.0" is current (latest 0.28.0).
packages/core build: Done
packages/express build: Done
packages/nextjs build: Done
packages/fastify build: Done
packages/core test:       [SeamlessAuth] Failed to verify signed auth response (ERR_JWS_SIGNATURE_VERIFICATION_FAILED).
packages/core test: Test Suites: 35 passed, 35 total
packages/core test: Tests:       428 passed, 428 total
packages/express test: Test Suites: 33 passed, 33 total
packages/express test: Tests:       216 passed, 216 total
packages/nextjs test: Test Suites: 7 passed, 7 total
packages/nextjs test: Tests:       179 passed, 179 total
packages/fastify test: Test Suites: 8 passed, 8 total
packages/fastify test: Tests:       180 passed, 180 total

Release order

Part of the v0.19 security release (fells-code/seamless-auth-api#385). Merge this before fells-code/seamless-auth-api#449: that PR's conformance run builds this repo from main, and its Next.js same-browser magic link case needs the pre-auth credential forwarded on verify. Compatible with the current API, which ignores an Authorization header on verify.

…serve the confirm route

Verify now sends the opening browser's pre-auth session to the auth API when
it has one, read from the signed pre-auth cookie in cookie transport or the
client's Authorization header in bearer transport. A missing or unverifiable
one sends nothing and never becomes a 401. Express, Fastify and Next.js all go
through verifyMagicLinkHandler, which takes the new optional authorization.

The bundled fallback manifest is resynced from the auth API and now lists
POST /magic-link/verify/{token}/confirm, which the manifest catch-alls serve.
The 409 confirmation_required body, requestedFrom included, passes through
unchanged.
@Bccorb
Bccorb merged commit 5b009f1 into main Oct 18, 2026
4 checks passed
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.

1 participant