Skip to content

Commit afae421

Browse files
committed
Move OAuth definitions into shared, add more
1 parent 41e0d26 commit afae421

File tree

4 files changed

+108
-81
lines changed

4 files changed

+108
-81
lines changed

src/client/auth.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
registerClient,
77
} from "./auth.js";
88

9-
109
// Mock fetch globally
1110
const mockFetch = jest.fn();
1211
global.fetch = mockFetch;

src/client/auth.ts

Lines changed: 2 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,7 @@
11
import pkceChallenge from "pkce-challenge";
2-
import { z } from "zod";
32
import { LATEST_PROTOCOL_VERSION } from "../types.js";
4-
5-
export const OAuthMetadataSchema = z
6-
.object({
7-
issuer: z.string(),
8-
authorization_endpoint: z.string(),
9-
token_endpoint: z.string(),
10-
registration_endpoint: z.string().optional(),
11-
scopes_supported: z.array(z.string()).optional(),
12-
response_types_supported: z.array(z.string()),
13-
response_modes_supported: z.array(z.string()).optional(),
14-
grant_types_supported: z.array(z.string()).optional(),
15-
token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
16-
token_endpoint_auth_signing_alg_values_supported: z
17-
.array(z.string())
18-
.optional(),
19-
service_documentation: z.string().optional(),
20-
revocation_endpoint: z.string().optional(),
21-
revocation_endpoint_auth_methods_supported: z.array(z.string()).optional(),
22-
revocation_endpoint_auth_signing_alg_values_supported: z
23-
.array(z.string())
24-
.optional(),
25-
introspection_endpoint: z.string().optional(),
26-
introspection_endpoint_auth_methods_supported: z
27-
.array(z.string())
28-
.optional(),
29-
introspection_endpoint_auth_signing_alg_values_supported: z
30-
.array(z.string())
31-
.optional(),
32-
code_challenge_methods_supported: z.array(z.string()).optional(),
33-
})
34-
.passthrough();
35-
36-
export const OAuthTokensSchema = z
37-
.object({
38-
access_token: z.string(),
39-
token_type: z.string(),
40-
expires_in: z.number().optional(),
41-
scope: z.string().optional(),
42-
refresh_token: z.string().optional(),
43-
})
44-
.strip();
45-
46-
/**
47-
* Client metadata schema according to RFC 7591 OAuth 2.0 Dynamic Client Registration
48-
*/
49-
export const OAuthClientMetadataSchema = z.object({
50-
redirect_uris: z.array(z.string()),
51-
token_endpoint_auth_method: z.string().optional(),
52-
grant_types: z.array(z.string()).optional(),
53-
response_types: z.array(z.string()).optional(),
54-
client_name: z.string().optional(),
55-
client_uri: z.string().optional(),
56-
logo_uri: z.string().optional(),
57-
scope: z.string().optional(),
58-
contacts: z.array(z.string()).optional(),
59-
tos_uri: z.string().optional(),
60-
policy_uri: z.string().optional(),
61-
jwks_uri: z.string().optional(),
62-
jwks: z.any().optional(),
63-
software_id: z.string().optional(),
64-
software_version: z.string().optional(),
65-
}).passthrough();
66-
67-
/**
68-
* Client information response schema according to RFC 7591
69-
*/
70-
export const OAuthClientInformationSchema = z.object({
71-
client_id: z.string(),
72-
client_secret: z.string().optional(),
73-
client_id_issued_at: z.number().optional(),
74-
client_secret_expires_at: z.number().optional(),
75-
}).passthrough();
76-
77-
export type OAuthMetadata = z.infer<typeof OAuthMetadataSchema>;
78-
export type OAuthTokens = z.infer<typeof OAuthTokensSchema>;
79-
80-
export type OAuthClientMetadata = z.infer<typeof OAuthClientMetadataSchema>;
81-
export type OAuthClientInformation = z.infer<typeof OAuthClientInformationSchema>;
3+
import type { OAuthClientMetadata, OAuthClientInformation, OAuthTokens, OAuthMetadata } from "../shared/auth.js";
4+
import { OAuthClientInformationSchema, OAuthMetadataSchema, OAuthTokensSchema } from "../shared/auth.js";
825

836
/**
847
* Implements an end-to-end OAuth client to be used with one MCP server.

src/client/sse.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { createServer, type IncomingMessage, type Server } from "http";
22
import { AddressInfo } from "net";
33
import { JSONRPCMessage } from "../types.js";
44
import { SSEClientTransport } from "./sse.js";
5-
import { OAuthClientProvider, OAuthTokens, UnauthorizedError } from "./auth.js";
5+
import { OAuthClientProvider, UnauthorizedError } from "./auth.js";
6+
import { OAuthTokens } from "../shared/auth.js";
67

78
describe("SSEClientTransport", () => {
89
let server: Server;

src/shared/auth.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { z } from "zod";
2+
3+
/**
4+
* RFC 8414 OAuth 2.0 Authorization Server Metadata
5+
*/
6+
export const OAuthMetadataSchema = z
7+
.object({
8+
issuer: z.string(),
9+
authorization_endpoint: z.string(),
10+
token_endpoint: z.string(),
11+
registration_endpoint: z.string().optional(),
12+
scopes_supported: z.array(z.string()).optional(),
13+
response_types_supported: z.array(z.string()),
14+
response_modes_supported: z.array(z.string()).optional(),
15+
grant_types_supported: z.array(z.string()).optional(),
16+
token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
17+
token_endpoint_auth_signing_alg_values_supported: z
18+
.array(z.string())
19+
.optional(),
20+
service_documentation: z.string().optional(),
21+
revocation_endpoint: z.string().optional(),
22+
revocation_endpoint_auth_methods_supported: z.array(z.string()).optional(),
23+
revocation_endpoint_auth_signing_alg_values_supported: z
24+
.array(z.string())
25+
.optional(),
26+
introspection_endpoint: z.string().optional(),
27+
introspection_endpoint_auth_methods_supported: z
28+
.array(z.string())
29+
.optional(),
30+
introspection_endpoint_auth_signing_alg_values_supported: z
31+
.array(z.string())
32+
.optional(),
33+
code_challenge_methods_supported: z.array(z.string()).optional(),
34+
})
35+
.passthrough();
36+
37+
/**
38+
* OAuth 2.1 token response
39+
*/
40+
export const OAuthTokensSchema = z
41+
.object({
42+
access_token: z.string(),
43+
token_type: z.string(),
44+
expires_in: z.number().optional(),
45+
scope: z.string().optional(),
46+
refresh_token: z.string().optional(),
47+
})
48+
.strip();
49+
50+
/**
51+
* OAuth 2.1 error response
52+
*/
53+
export const OAuthErrorSchema = z
54+
.object({
55+
error: z.string(),
56+
error_description: z.string().optional(),
57+
error_uri: z.string().optional(),
58+
});
59+
60+
/**
61+
* RFC 7591 OAuth 2.0 Dynamic Client Registration metadata
62+
*/
63+
export const OAuthClientMetadataSchema = z.object({
64+
redirect_uris: z.array(z.string()),
65+
token_endpoint_auth_method: z.string().optional(),
66+
grant_types: z.array(z.string()).optional(),
67+
response_types: z.array(z.string()).optional(),
68+
client_name: z.string().optional(),
69+
client_uri: z.string().optional(),
70+
logo_uri: z.string().optional(),
71+
scope: z.string().optional(),
72+
contacts: z.array(z.string()).optional(),
73+
tos_uri: z.string().optional(),
74+
policy_uri: z.string().optional(),
75+
jwks_uri: z.string().optional(),
76+
jwks: z.any().optional(),
77+
software_id: z.string().optional(),
78+
software_version: z.string().optional(),
79+
}).passthrough();
80+
81+
/**
82+
* RFC 7591 OAuth 2.0 Dynamic Client Registration response
83+
*/
84+
export const OAuthClientInformationSchema = OAuthClientMetadataSchema.extend({
85+
client_id: z.string(),
86+
client_secret: z.string().optional(),
87+
client_id_issued_at: z.number().optional(),
88+
client_secret_expires_at: z.number().optional(),
89+
}).passthrough();
90+
91+
/**
92+
* RFC 7591 OAuth 2.0 Dynamic Client Registration error response
93+
*/
94+
export const OAuthClientRegistrationErrorSchema = z.object({
95+
error: z.string(),
96+
error_description: z.string().optional(),
97+
}).strip();
98+
99+
export type OAuthMetadata = z.infer<typeof OAuthMetadataSchema>;
100+
export type OAuthTokens = z.infer<typeof OAuthTokensSchema>;
101+
export type OAuthError = z.infer<typeof OAuthErrorSchema>;
102+
export type OAuthClientMetadata = z.infer<typeof OAuthClientMetadataSchema>;
103+
export type OAuthClientInformation = z.infer<typeof OAuthClientInformationSchema>;
104+
export type OAuthClientRegistrationError = z.infer<typeof OAuthClientRegistrationErrorSchema>;

0 commit comments

Comments
 (0)