Skip to content

feat(routes): declare adapter behaviour in defineRoute and publish an adapter manifest - #380

Merged
Bccorb merged 1 commit into
mainfrom
feat/adapter-manifest
Oct 8, 2026
Merged

Bccorb merged 1 commit into
mainfrom
feat/adapter-manifest

Conversation

@Bccorb

@Bccorb Bccorb commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Part of #371. Closes #372.

Why

Server adapters hard-code per-route knowledge: which token a route takes, and which tokens a response issues or clears. In seamless-auth-server that is seven files per new route, the Express and Fastify adapters have drifted before, and a Go, Rust or Python adapter would have to copy all of it. This makes the API the source of that knowledge so adapters follow data instead.

What changes

  • adapter option on defineRoute. Access routes default to an exposed passthrough that sends the access token, so most routes need nothing. The routes that differ declare credential, issues, clears, body.pick (adapter cookie transport only) and delivery. The API itself stays bearer and JSON only.
  • Rules checked at registration, in the same spirit as the decoy check:
    • a public route must say whether adapters expose it (adapter: false or an object)
    • an ephemeral route must name preAuth or registration
    • a credential must fit the route's scope
    • a route that always returns a token must declare what it issues
  • GET /.well-known/seamless-adapter.json serves the manifest (schemaVersion: 1). npm run generate:api also writes it to adapter-manifest.json, and a test keeps the committed copy in step. Health, JWKS, the manifest itself and the conformance routes are adapter: false.
  • POST for the four OTP send routes and the magic-link request. They send a message, and the SDK already calls them with POST so a cross-site page cannot trigger them without a CORS preflight. A generic adapter following the manifest would otherwise have exposed GET. The GET forms keep working, are marked deprecated, and are not in the manifest.

/login keeps its narrowed body (message, identifierType, loginMethods).

Contract impact

Additive: one new endpoint, five new POST routes, five GET routes deprecated. No existing route changes shape. Consumers:

Found while mapping the adapter

These are for fells-code/seamless-auth-server#201 and are not changed here:

  • POST /totp/verify-login (TOTP sign-in) has no adapter passthrough, so TOTP sign-in does not work through an adapter today. It is in the manifest.
  • The adapter exposes POST /users/update, which does not exist on the API.
  • Under cookie transport the adapter passes the re-minted ephemeral token from the OTP send routes to the browser.

Checks

  • npm run typecheck, npm run lint and npm run format:check are clean.
  • npm run test:run: 135 files, 1795 passed.
  • npm run build passes.
  • A security review of the diff found no issues. It confirmed that adapter is metadata only, that the POST variants carry the same auth, decoy and limiter middleware, and that the manifest exposes nothing sensitive.

… adapter manifest

Server adapters hard-code which token each route takes and which tokens a
response issues or clears. Routes now declare that with an `adapter` option,
and the API publishes it at GET /.well-known/seamless-adapter.json (also
committed as adapter-manifest.json by `npm run generate:api`), so adapters
in any language can follow data instead of a hand-maintained route list.

Registration fails when a public route does not say whether adapters expose
it, when an ephemeral route does not name the token it takes, or when a
route that always returns a token does not say what it issues.

The four OTP send routes and the magic-link request now also accept POST.
They send a message, and a GET can be triggered cross-site without a CORS
preflight. The GET forms still work and are deprecated.

Part of #371. Closes #372.
@Bccorb
Bccorb merged commit f0a7866 into main Oct 8, 2026
7 checks passed
@Bccorb
Bccorb deleted the feat/adapter-manifest branch October 8, 2026 01:52
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(routes): declare adapter behaviour in defineRoute and emit an adapter manifest

1 participant