Skip to content

Commit 48cddd9

Browse files
committed
Pass through rate limits and other options cleanly from router
1 parent 1415c2d commit 48cddd9

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

src/server/auth/router.ts

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,43 @@ import { tokenHandler, TokenHandlerOptions } from "./handlers/token.js";
44
import { authorizationHandler, AuthorizationHandlerOptions } from "./handlers/authorize.js";
55
import { revocationHandler, RevocationHandlerOptions } from "./handlers/revoke.js";
66
import { metadataHandler } from "./handlers/metadata.js";
7+
import { OAuthServerProvider } from "./provider.js";
78

8-
export type MetadataOptions = {
9-
metadata: {
10-
/**
11-
* The authorization server's issuer identifier, which is a URL that uses the "https" scheme and has no query or fragment components.
12-
*/
13-
issuerUrl: URL;
14-
15-
/**
16-
* An optional URL of a page containing human-readable information that developers might want or need to know when using the authorization server.
17-
*/
18-
serviceDocumentationUrl?: URL;
19-
};
20-
};
9+
export type AuthRouterOptions = {
10+
/**
11+
* A provider implementing the actual authorization logic for this router.
12+
*/
13+
provider: OAuthServerProvider;
14+
15+
/**
16+
* The authorization server's issuer identifier, which is a URL that uses the "https" scheme and has no query or fragment components.
17+
*/
18+
issuerUrl: URL;
2119

22-
export type AuthRouterOptions =
23-
& AuthorizationHandlerOptions
24-
& Omit<ClientRegistrationHandlerOptions, "clientsStore">
25-
& MetadataOptions
26-
& RevocationHandlerOptions
27-
& TokenHandlerOptions;
20+
/**
21+
* An optional URL of a page containing human-readable information that developers might want or need to know when using the authorization server.
22+
*/
23+
serviceDocumentationUrl?: URL;
24+
25+
// Individual options per route
26+
authorizationOptions?: Omit<AuthorizationHandlerOptions, "provider">;
27+
clientRegistrationOptions?: Omit<ClientRegistrationHandlerOptions, "clientsStore">;
28+
revocationOptions?: Omit<RevocationHandlerOptions, "provider">;
29+
tokenOptions?: Omit<TokenHandlerOptions, "provider">;
30+
};
2831

2932
/**
3033
* Installs standard MCP authorization endpoints, including dynamic client registration and token revocation (if supported). Also advertises standard authorization server metadata, for easier discovery of supported configurations by clients.
3134
*
35+
* By default, rate limiting is applied to all endpoints to prevent abuse.
36+
*
3237
* This router MUST be installed at the application root, like so:
3338
*
3439
* const app = express();
3540
* app.use(mcpAuthRouter(...));
3641
*/
3742
export function mcpAuthRouter(options: AuthRouterOptions): RequestHandler {
38-
const issuer = options.metadata.issuerUrl;
43+
const issuer = options.issuerUrl;
3944

4045
// Technically RFC 8414 does not permit a localhost HTTPS exemption, but this will be necessary for ease of testing
4146
if (issuer.protocol !== "https:" && issuer.hostname !== "localhost" && issuer.hostname !== "127.0.0.1") {
@@ -55,7 +60,7 @@ export function mcpAuthRouter(options: AuthRouterOptions): RequestHandler {
5560

5661
const metadata = {
5762
issuer: issuer.href,
58-
service_documentation: options.metadata.serviceDocumentationUrl?.href,
63+
service_documentation: options.serviceDocumentationUrl?.href,
5964

6065
authorization_endpoint: new URL(authorization_endpoint, issuer).href,
6166
response_types_supported: ["code"],
@@ -72,16 +77,34 @@ export function mcpAuthRouter(options: AuthRouterOptions): RequestHandler {
7277
};
7378

7479
const router = express.Router();
75-
router.use(authorization_endpoint, authorizationHandler(options));
76-
router.use(token_endpoint, tokenHandler(options));
80+
81+
router.use(
82+
authorization_endpoint,
83+
authorizationHandler({ provider: options.provider, ...options.authorizationOptions })
84+
);
85+
86+
router.use(
87+
token_endpoint,
88+
tokenHandler({ provider: options.provider, ...options.tokenOptions })
89+
);
90+
7791
router.use("/.well-known/oauth-authorization-server", metadataHandler(metadata));
7892

7993
if (registration_endpoint) {
80-
router.use(registration_endpoint, clientRegistrationHandler({ clientsStore: options.provider.clientsStore, ...options }));
94+
router.use(
95+
registration_endpoint,
96+
clientRegistrationHandler({
97+
clientsStore: options.provider.clientsStore,
98+
...options,
99+
})
100+
);
81101
}
82102

83103
if (revocation_endpoint) {
84-
router.use(revocation_endpoint, revocationHandler(options));
104+
router.use(
105+
revocation_endpoint,
106+
revocationHandler({ provider: options.provider, ...options.revocationOptions })
107+
);
85108
}
86109

87110
return router;

0 commit comments

Comments
 (0)