diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 799bdb6..ad4afd2 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -53,6 +53,29 @@ app.addContentTypeParser( }, ); +// RFC 6749 ยง3.2 makes application/x-www-form-urlencoded the mandatory wire +// format for the OAuth token endpoint, and most DCR-emitting clients +// (Claude Desktop included) post it that way without negotiating. Fastify +// has no built-in parser for it, so without this every POST /oauth/token +// hit 415 before reaching our handler. Parsed into a plain object so the +// existing zod schemas don't need to change. +app.addContentTypeParser( + 'application/x-www-form-urlencoded', + { parseAs: 'string' }, + (_req, body, done) => { + const text = body as string; + if (!text) return done(null, {}); + try { + const params = new URLSearchParams(text); + const out: Record = {}; + for (const [k, v] of params) out[k] = v; + done(null, out); + } catch (err) { + done(err as Error, undefined); + } + }, +); + await app.register(cors, { origin: [config.NEXT_PUBLIC_APP_URL], credentials: true,