mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-05 23:43:57 +00:00
refactor(mcp): scope bearer authentication to the MCP route
Reverts the change to the shared authenticate middleware, which made every authenticated route accept Authorization: Bearer tokens. Bearer support now lives in a wrapper middleware inside api-mcp, mounted only on /mcp; all other requests fall through to the app middleware unchanged. Removing the api-mcp module restores stock auth behaviour. https://claude.ai/code/session_01V27pYyjw2PGSWy7wNtiWKj
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import type { NextFunction, Request, RequestHandler, Response } from 'express';
|
||||
|
||||
import { hasPassword, hashedPassword } from '../api-data/session/session.service.js';
|
||||
|
||||
/**
|
||||
* Wraps the app authenticate middleware with support for the Authorization header.
|
||||
* MCP clients conventionally authenticate with `Authorization: Bearer <token>`
|
||||
* rather than cookies or query params; any other request falls through to the
|
||||
* app middleware, keeping the behaviour of the shared middleware untouched.
|
||||
*/
|
||||
export function makeMcpAuthenticate(fallback: RequestHandler): RequestHandler {
|
||||
return function mcpAuthenticate(req: Request, res: Response, next: NextFunction) {
|
||||
if (hasPassword) {
|
||||
const authHeader = req.headers.authorization;
|
||||
if (authHeader?.startsWith('Bearer ') && authHeader.slice(7) === hashedPassword) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
return fallback(req, res, next);
|
||||
};
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { socket } from './adapters/WebsocketAdapter.js';
|
||||
// Import Routers
|
||||
import { appRouter } from './api-data/index.js';
|
||||
import { integrationRouter } from './api-integration/integration.router.js';
|
||||
import { makeMcpAuthenticate } from './api-mcp/mcp.auth.js';
|
||||
import { mcpRouter } from './api-mcp/mcp.router.js';
|
||||
import { flushPendingWrites, getDataProvider } from './classes/data-provider/DataProvider.js';
|
||||
// Services
|
||||
@@ -101,7 +102,7 @@ app.get(`${prefix}/ready`, (_req, res) => {
|
||||
app.use(`${prefix}/login`, loginRouter); // router for login flow
|
||||
app.use(`${prefix}/data`, authenticate, appRouter); // router for application data
|
||||
app.use(`${prefix}/api`, authenticate, integrationRouter); // router for integrations
|
||||
app.use(`${prefix}/mcp`, authenticate, mcpRouter); // router for MCP agent integration
|
||||
app.use(`${prefix}/mcp`, makeMcpAuthenticate(authenticate), mcpRouter); // router for MCP agent integration
|
||||
|
||||
// serve static external files
|
||||
app.use(
|
||||
|
||||
@@ -90,15 +90,6 @@ export function makeAuthenticateMiddleware(prefix: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// MCP clients send Authorization: Bearer <token> rather than cookies
|
||||
const authHeader = req.headers.authorization;
|
||||
if (authHeader?.startsWith('Bearer ')) {
|
||||
const bearerToken = authHeader.slice(7);
|
||||
if (bearerToken === hashedPassword) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
|
||||
res.status(401).send('Unauthorized');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user