From 001cc6431bfdb9822138e7990ce52f115a6e2bca Mon Sep 17 00:00:00 2001 From: jubnl Date: Tue, 5 May 2026 14:16:28 +0200 Subject: [PATCH] fix: 404 JSON + open CORS for all /.well-known/* paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ChatGPT probes /.well-known/openid-configuration and the RFC 8414 path-suffixed form /.well-known/oauth-authorization-server/mcp before (or instead of) following the RFC 9728 WWW-Authenticate chain. Both returned 200 HTML from the SPA catch-all, which clients can't parse as JSON — ChatGPT reported 'does not implement OAuth'. Two fixes: - Extend open-CORS pre-middleware from /.well-known/oauth-* to all /.well-known/* so browser-based probes aren't CORS-blocked - Add a 404 JSON catch-all for /.well-known/* paths the SDK metadata router doesn't handle, placed before the SPA catch-all --- server/src/app.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/server/src/app.ts b/server/src/app.ts index 916dbb28..a57c359f 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -100,10 +100,12 @@ export function createApp(): express.Application { // with Bearer tokens from any origin. /oauth/register and /oauth/authorize need it for // browser-based DCR/authorization preflights — the global cors({ origin: false }) would // answer OPTIONS without Access-Control-Allow-Origin before the SDK's own cors() runs. + // All /.well-known/* paths get open CORS so clients probing openid-configuration or the + // RFC 8414 path-suffixed AS metadata form don't get CORS-blocked (they get 404 JSON instead). app.use( (req: Request, _res: Response, next: NextFunction) => { if ( - req.path.startsWith('/.well-known/oauth-') || + req.path.startsWith('/.well-known/') || req.path === '/oauth/register' || req.path === '/oauth/authorize' || req.path === '/mcp' @@ -428,6 +430,15 @@ export function createApp(): express.Application { app.get('/mcp', mcpHandler); app.delete('/mcp', mcpHandler); + // Return 404 JSON for any /.well-known/* path the SDK metadata router doesn't handle. + // Without this, the SPA catch-all serves HTML — clients probing + // /.well-known/openid-configuration or the RFC 8414 path-suffixed AS metadata URL + // receive a 200 HTML response they can't parse as JSON, causing "does not implement OAuth". + app.use((req: Request, res: Response, next: NextFunction) => { + if (req.path.startsWith('/.well-known/')) return res.status(404).json({ error: 'not_found' }); + next(); + }); + // Production static file serving if (process.env.NODE_ENV === 'production') { const publicPath = path.join(__dirname, '../public');