chatbot-nc 2.2.28 → 2.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/type/index.d.ts +61 -0
- package/dist/cjs/utils/index.d.ts +7 -0
- package/dist/cjs/utils/index.js +3 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/mcp-oauth.d.ts +8 -0
- package/dist/cjs/utils/mcp-oauth.js +118 -0
- package/dist/cjs/utils/mcp-oauth.js.map +1 -0
- package/dist/esm/type/index.d.ts +61 -0
- package/dist/esm/utils/index.d.ts +7 -0
- package/dist/esm/utils/index.js +3 -1
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/mcp-oauth.d.ts +8 -0
- package/dist/esm/utils/mcp-oauth.js +124 -0
- package/dist/esm/utils/mcp-oauth.js.map +1 -0
- package/package.json +1 -1
package/dist/cjs/type/index.d.ts
CHANGED
|
@@ -2,3 +2,64 @@ export type OAuthKeys = 'AuthURL' | 'AccessTokenURL' | 'CallBackURL' | 'CodeChal
|
|
|
2
2
|
export type ApiKeys = 'AuthApiHeader' | 'AuthApiValue';
|
|
3
3
|
export type BasicAuthKeys = 'AuthBasicUsername' | 'AuthBasicPassword';
|
|
4
4
|
export type BearerAuthKeys = 'AuthBearerUsername' | 'AuthBearerPassword' | 'AuthBearerURL' | 'AuthBearerToken';
|
|
5
|
+
export type OAuthProtectedResourceMetadata = {
|
|
6
|
+
/**
|
|
7
|
+
* Protected resource identifier
|
|
8
|
+
* Example:
|
|
9
|
+
* https://gmail.googleapis.com
|
|
10
|
+
*/
|
|
11
|
+
resource?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Authorization servers protecting this resource
|
|
14
|
+
*/
|
|
15
|
+
authorization_servers: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Supported bearer token methods
|
|
18
|
+
* Example:
|
|
19
|
+
* ["header"]
|
|
20
|
+
*/
|
|
21
|
+
bearer_methods_supported?: string[];
|
|
22
|
+
/**
|
|
23
|
+
* Supported resource documentation
|
|
24
|
+
*/
|
|
25
|
+
resource_documentation?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Supported scopes for this resource
|
|
28
|
+
*/
|
|
29
|
+
scopes_supported?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* JWT signing algorithms supported for access tokens
|
|
32
|
+
*/
|
|
33
|
+
resource_signing_alg_values_supported?: string[];
|
|
34
|
+
/**
|
|
35
|
+
* Additional custom fields
|
|
36
|
+
*/
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
export type OAuthMetadata = {
|
|
40
|
+
issuer: string;
|
|
41
|
+
authorization_endpoint: string;
|
|
42
|
+
token_endpoint: string;
|
|
43
|
+
registration_endpoint?: string;
|
|
44
|
+
revocation_endpoint?: string;
|
|
45
|
+
code_challenge_methods_supported?: string[];
|
|
46
|
+
grant_types_supported?: string[];
|
|
47
|
+
response_types_supported?: string[];
|
|
48
|
+
scopes_supported?: string[];
|
|
49
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
50
|
+
};
|
|
51
|
+
export type ClientRegistration = {
|
|
52
|
+
client_name: string;
|
|
53
|
+
client_uri?: string;
|
|
54
|
+
redirect_uris: string[];
|
|
55
|
+
grant_types: string[];
|
|
56
|
+
response_types: string[];
|
|
57
|
+
token_endpoint_auth_method: string;
|
|
58
|
+
scope?: string;
|
|
59
|
+
};
|
|
60
|
+
export type ClientCredentials = {
|
|
61
|
+
client_id: string;
|
|
62
|
+
client_secret?: string;
|
|
63
|
+
client_id_issued_at?: number;
|
|
64
|
+
client_secret_expires_at?: number;
|
|
65
|
+
};
|
|
@@ -51,4 +51,11 @@ export declare const Utils: {
|
|
|
51
51
|
AttachClientHeaders: (clientHeaders?: string, contentType?: string, sessionAttributes?: Record<string, string>) => Promise<Record<string, string>>;
|
|
52
52
|
};
|
|
53
53
|
jwt: typeof jwt;
|
|
54
|
+
MCPOAuth: {
|
|
55
|
+
discoverOAuthResourceMetadata: (mcpServerUrl: string) => Promise<import("../type").OAuthProtectedResourceMetadata>;
|
|
56
|
+
discoverOAuthMetadata: (mcpServerUrl: string) => Promise<import("../type").OAuthMetadata>;
|
|
57
|
+
registerClient: (metadata: import("../type").OAuthMetadata, redirectUri: string) => Promise<import("../type").ClientCredentials>;
|
|
58
|
+
buildAuthorizationUrl: (metadata: import("../type").OAuthMetadata, clientId: string, redirectUri: string, state: string, codeChallenge?: string, codeChallengeMethod?: string, scopes?: string[], resource?: string) => Promise<string>;
|
|
59
|
+
handleCallBack: (callbackUrl: string, storedState: string, codeVerifier: string) => Promise<string>;
|
|
60
|
+
};
|
|
54
61
|
};
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -29,11 +29,13 @@ const intent_1 = require("./intent");
|
|
|
29
29
|
const date_format_1 = require("./date-format");
|
|
30
30
|
const jwt = __importStar(require("jsonwebtoken"));
|
|
31
31
|
const auth_1 = require("./auth");
|
|
32
|
+
const mcp_oauth_1 = require("./mcp-oauth");
|
|
32
33
|
exports.Utils = {
|
|
33
34
|
Intents: intent_1.Intents,
|
|
34
35
|
Common: common_1.Common,
|
|
35
36
|
DateFormat: date_format_1.DateFormat,
|
|
36
37
|
Auth: auth_1.Auth,
|
|
37
|
-
jwt
|
|
38
|
+
jwt,
|
|
39
|
+
MCPOAuth: mcp_oauth_1.MCPOAuth
|
|
38
40
|
};
|
|
39
41
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,qCAAkC;AAClC,qCAAmC;AACnC,+CAA2C;AAC3C,kDAAoC;AACpC,iCAA8B;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,qCAAkC;AAClC,qCAAmC;AACnC,+CAA2C;AAC3C,kDAAoC;AACpC,iCAA8B;AAC9B,2CAAuC;AAG1B,QAAA,KAAK,GAAG;IACjB,OAAO,EAAP,gBAAO;IACP,MAAM,EAAN,eAAM;IACN,UAAU,EAAV,wBAAU;IACV,IAAI,EAAJ,WAAI;IACJ,GAAG;IACH,QAAQ,EAAR,oBAAQ;CACX,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ClientCredentials, OAuthMetadata, OAuthProtectedResourceMetadata } from "../type";
|
|
2
|
+
export declare const MCPOAuth: {
|
|
3
|
+
discoverOAuthResourceMetadata: (mcpServerUrl: string) => Promise<OAuthProtectedResourceMetadata>;
|
|
4
|
+
discoverOAuthMetadata: (mcpServerUrl: string) => Promise<OAuthMetadata>;
|
|
5
|
+
registerClient: (metadata: OAuthMetadata, redirectUri: string) => Promise<ClientCredentials>;
|
|
6
|
+
buildAuthorizationUrl: (metadata: OAuthMetadata, clientId: string, redirectUri: string, state: string, codeChallenge?: string, codeChallengeMethod?: string, scopes?: string[], resource?: string) => Promise<string>;
|
|
7
|
+
handleCallBack: (callbackUrl: string, storedState: string, codeVerifier: string) => Promise<string>;
|
|
8
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MCPOAuth = void 0;
|
|
4
|
+
const discoverOAuthResourceMetadata = async (mcpServerUrl) => {
|
|
5
|
+
const url = new URL(mcpServerUrl);
|
|
6
|
+
const protectedResourceUrl = new URL("/.well-known/oauth-protected-resource", url);
|
|
7
|
+
// Step 1: RFC 9470 - Get Protected Resource Metadata
|
|
8
|
+
const protectedResourceResponse = await fetch(protectedResourceUrl.toString());
|
|
9
|
+
if (!protectedResourceResponse.ok) {
|
|
10
|
+
throw new Error(`Failed to fetch protected resource metadata: ` +
|
|
11
|
+
`${protectedResourceResponse.status}`);
|
|
12
|
+
}
|
|
13
|
+
const protectedResource = (await protectedResourceResponse.json());
|
|
14
|
+
return protectedResource;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Discovers OAuth configuration for an MCP server using RFC 9470 + RFC 8414.
|
|
18
|
+
*/
|
|
19
|
+
const discoverOAuthMetadata = async (mcpServerUrl) => {
|
|
20
|
+
var _a;
|
|
21
|
+
const protectedResource = (await discoverOAuthResourceMetadata(mcpServerUrl));
|
|
22
|
+
const authServers = protectedResource.authorization_servers;
|
|
23
|
+
if (!Array.isArray(authServers) || authServers.length === 0) {
|
|
24
|
+
throw new Error("No authorization servers found in protected resource metadata");
|
|
25
|
+
}
|
|
26
|
+
// Use the first authorization server
|
|
27
|
+
const authServerUrl = authServers[0];
|
|
28
|
+
// Step 2: RFC 8414 - Get Authorization Server Metadata
|
|
29
|
+
const metadataUrl = new URL("/.well-known/oauth-authorization-server", authServerUrl);
|
|
30
|
+
const metadataResponse = await fetch(metadataUrl.toString());
|
|
31
|
+
if (!metadataResponse.ok) {
|
|
32
|
+
throw new Error(`Failed to fetch authorization server metadata: ` +
|
|
33
|
+
`${metadataResponse.status}`);
|
|
34
|
+
}
|
|
35
|
+
const metadata = (await metadataResponse.json());
|
|
36
|
+
// Validate required fields
|
|
37
|
+
if (!metadata.authorization_endpoint || !metadata.token_endpoint) {
|
|
38
|
+
throw new Error("Missing required OAuth endpoints in metadata");
|
|
39
|
+
}
|
|
40
|
+
// Warn if PKCE support isn't advertised
|
|
41
|
+
if (!((_a = metadata.code_challenge_methods_supported) === null || _a === void 0 ? void 0 : _a.includes("S256"))) {
|
|
42
|
+
console.warn("Server does not advertise S256 PKCE support, " +
|
|
43
|
+
"but we will use it anyway");
|
|
44
|
+
}
|
|
45
|
+
return metadata;
|
|
46
|
+
};
|
|
47
|
+
const registerClient = async (metadata, redirectUri) => {
|
|
48
|
+
var _a, _b, _c, _d;
|
|
49
|
+
if (!metadata.registration_endpoint)
|
|
50
|
+
throw new Error("Server does not support dynamic client registration");
|
|
51
|
+
const registrationRequest = {
|
|
52
|
+
client_name: "Your MCP Client",
|
|
53
|
+
client_uri: "https://example.com",
|
|
54
|
+
redirect_uris: [redirectUri],
|
|
55
|
+
grant_types: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.grant_types_supported) !== null && _a !== void 0 ? _a : ["authorization_code", "refresh_token"],
|
|
56
|
+
response_types: (_b = metadata === null || metadata === void 0 ? void 0 : metadata.response_types_supported) !== null && _b !== void 0 ? _b : ["code"],
|
|
57
|
+
token_endpoint_auth_method: ((_c = metadata === null || metadata === void 0 ? void 0 : metadata.token_endpoint_auth_methods_supported) === null || _c === void 0 ? void 0 : _c.length) && ((_d = metadata === null || metadata === void 0 ? void 0 : metadata.token_endpoint_auth_methods_supported) === null || _d === void 0 ? void 0 : _d.includes("none")) ? "none" : metadata === null || metadata === void 0 ? void 0 : metadata.token_endpoint_auth_methods_supported[0],
|
|
58
|
+
};
|
|
59
|
+
const response = await fetch(metadata.registration_endpoint, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
Accept: "application/json",
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify(registrationRequest),
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
const errorBody = await response.text();
|
|
69
|
+
throw new Error(`Client registration failed: ${response.status} - ${errorBody}`);
|
|
70
|
+
}
|
|
71
|
+
const credentials = (await response.json());
|
|
72
|
+
// Store credentials securely
|
|
73
|
+
return credentials;
|
|
74
|
+
};
|
|
75
|
+
const buildAuthorizationUrl = async (metadata, clientId, redirectUri, state, codeChallenge, codeChallengeMethod, scopes = [], resource) => {
|
|
76
|
+
let param = {
|
|
77
|
+
response_type: "code",
|
|
78
|
+
client_id: clientId,
|
|
79
|
+
redirect_uri: redirectUri,
|
|
80
|
+
state: state,
|
|
81
|
+
prompt: "consent",
|
|
82
|
+
};
|
|
83
|
+
if (scopes.length)
|
|
84
|
+
param.scope = scopes.join(" ");
|
|
85
|
+
if (codeChallengeMethod)
|
|
86
|
+
param.code_challenge = codeChallenge;
|
|
87
|
+
if (codeChallengeMethod)
|
|
88
|
+
param.code_challenge_method = codeChallengeMethod;
|
|
89
|
+
if (resource)
|
|
90
|
+
param.resource = resource;
|
|
91
|
+
const params = new URLSearchParams(param);
|
|
92
|
+
return `${metadata.authorization_endpoint}?${params.toString()}`;
|
|
93
|
+
};
|
|
94
|
+
const handleCallBack = async (callbackUrl, storedState, codeVerifier) => {
|
|
95
|
+
const params = parseCallback(callbackUrl);
|
|
96
|
+
if (params.error) {
|
|
97
|
+
throw new Error(`OAuth error: ${params.error} - ` +
|
|
98
|
+
`${params.error_description || "Unknown error"}`);
|
|
99
|
+
}
|
|
100
|
+
if (params.state !== storedState) {
|
|
101
|
+
throw new Error("Invalid state parameter - possible CSRF attack");
|
|
102
|
+
}
|
|
103
|
+
if (!params.code) {
|
|
104
|
+
throw new Error("Missing authorization code");
|
|
105
|
+
}
|
|
106
|
+
return params.code;
|
|
107
|
+
};
|
|
108
|
+
const parseCallback = (url) => {
|
|
109
|
+
const urlParams = new URLSearchParams(new URL(url).search);
|
|
110
|
+
return {
|
|
111
|
+
code: urlParams.get("code") || undefined,
|
|
112
|
+
state: urlParams.get("state") || undefined,
|
|
113
|
+
error: urlParams.get("error") || undefined,
|
|
114
|
+
error_description: urlParams.get("error_description") || undefined,
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
exports.MCPOAuth = { discoverOAuthResourceMetadata, discoverOAuthMetadata, registerClient, buildAuthorizationUrl, handleCallBack };
|
|
118
|
+
//# sourceMappingURL=mcp-oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-oauth.js","sourceRoot":"","sources":["../../../utils/mcp-oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/type/index.d.ts
CHANGED
|
@@ -2,3 +2,64 @@ export type OAuthKeys = 'AuthURL' | 'AccessTokenURL' | 'CallBackURL' | 'CodeChal
|
|
|
2
2
|
export type ApiKeys = 'AuthApiHeader' | 'AuthApiValue';
|
|
3
3
|
export type BasicAuthKeys = 'AuthBasicUsername' | 'AuthBasicPassword';
|
|
4
4
|
export type BearerAuthKeys = 'AuthBearerUsername' | 'AuthBearerPassword' | 'AuthBearerURL' | 'AuthBearerToken';
|
|
5
|
+
export type OAuthProtectedResourceMetadata = {
|
|
6
|
+
/**
|
|
7
|
+
* Protected resource identifier
|
|
8
|
+
* Example:
|
|
9
|
+
* https://gmail.googleapis.com
|
|
10
|
+
*/
|
|
11
|
+
resource?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Authorization servers protecting this resource
|
|
14
|
+
*/
|
|
15
|
+
authorization_servers: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Supported bearer token methods
|
|
18
|
+
* Example:
|
|
19
|
+
* ["header"]
|
|
20
|
+
*/
|
|
21
|
+
bearer_methods_supported?: string[];
|
|
22
|
+
/**
|
|
23
|
+
* Supported resource documentation
|
|
24
|
+
*/
|
|
25
|
+
resource_documentation?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Supported scopes for this resource
|
|
28
|
+
*/
|
|
29
|
+
scopes_supported?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* JWT signing algorithms supported for access tokens
|
|
32
|
+
*/
|
|
33
|
+
resource_signing_alg_values_supported?: string[];
|
|
34
|
+
/**
|
|
35
|
+
* Additional custom fields
|
|
36
|
+
*/
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
export type OAuthMetadata = {
|
|
40
|
+
issuer: string;
|
|
41
|
+
authorization_endpoint: string;
|
|
42
|
+
token_endpoint: string;
|
|
43
|
+
registration_endpoint?: string;
|
|
44
|
+
revocation_endpoint?: string;
|
|
45
|
+
code_challenge_methods_supported?: string[];
|
|
46
|
+
grant_types_supported?: string[];
|
|
47
|
+
response_types_supported?: string[];
|
|
48
|
+
scopes_supported?: string[];
|
|
49
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
50
|
+
};
|
|
51
|
+
export type ClientRegistration = {
|
|
52
|
+
client_name: string;
|
|
53
|
+
client_uri?: string;
|
|
54
|
+
redirect_uris: string[];
|
|
55
|
+
grant_types: string[];
|
|
56
|
+
response_types: string[];
|
|
57
|
+
token_endpoint_auth_method: string;
|
|
58
|
+
scope?: string;
|
|
59
|
+
};
|
|
60
|
+
export type ClientCredentials = {
|
|
61
|
+
client_id: string;
|
|
62
|
+
client_secret?: string;
|
|
63
|
+
client_id_issued_at?: number;
|
|
64
|
+
client_secret_expires_at?: number;
|
|
65
|
+
};
|
|
@@ -51,4 +51,11 @@ export declare const Utils: {
|
|
|
51
51
|
AttachClientHeaders: (clientHeaders?: string, contentType?: string, sessionAttributes?: Record<string, string>) => Promise<Record<string, string>>;
|
|
52
52
|
};
|
|
53
53
|
jwt: typeof jwt;
|
|
54
|
+
MCPOAuth: {
|
|
55
|
+
discoverOAuthResourceMetadata: (mcpServerUrl: string) => Promise<import("../type").OAuthProtectedResourceMetadata>;
|
|
56
|
+
discoverOAuthMetadata: (mcpServerUrl: string) => Promise<import("../type").OAuthMetadata>;
|
|
57
|
+
registerClient: (metadata: import("../type").OAuthMetadata, redirectUri: string) => Promise<import("../type").ClientCredentials>;
|
|
58
|
+
buildAuthorizationUrl: (metadata: import("../type").OAuthMetadata, clientId: string, redirectUri: string, state: string, codeChallenge?: string, codeChallengeMethod?: string, scopes?: string[], resource?: string) => Promise<string>;
|
|
59
|
+
handleCallBack: (callbackUrl: string, storedState: string, codeVerifier: string) => Promise<string>;
|
|
60
|
+
};
|
|
54
61
|
};
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -3,11 +3,13 @@ import { Intents } from "./intent";
|
|
|
3
3
|
import { DateFormat } from "./date-format";
|
|
4
4
|
import * as jwt from 'jsonwebtoken';
|
|
5
5
|
import { Auth } from "./auth";
|
|
6
|
+
import { MCPOAuth } from "./mcp-oauth";
|
|
6
7
|
export const Utils = {
|
|
7
8
|
Intents,
|
|
8
9
|
Common,
|
|
9
10
|
DateFormat,
|
|
10
11
|
Auth,
|
|
11
|
-
jwt
|
|
12
|
+
jwt,
|
|
13
|
+
MCPOAuth
|
|
12
14
|
};
|
|
13
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utils/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utils/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,MAAM,CAAC,MAAM,KAAK,GAAG;IACjB,OAAO;IACP,MAAM;IACN,UAAU;IACV,IAAI;IACJ,GAAG;IACH,QAAQ;CACX,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ClientCredentials, OAuthMetadata, OAuthProtectedResourceMetadata } from "../type";
|
|
2
|
+
export declare const MCPOAuth: {
|
|
3
|
+
discoverOAuthResourceMetadata: (mcpServerUrl: string) => Promise<OAuthProtectedResourceMetadata>;
|
|
4
|
+
discoverOAuthMetadata: (mcpServerUrl: string) => Promise<OAuthMetadata>;
|
|
5
|
+
registerClient: (metadata: OAuthMetadata, redirectUri: string) => Promise<ClientCredentials>;
|
|
6
|
+
buildAuthorizationUrl: (metadata: OAuthMetadata, clientId: string, redirectUri: string, state: string, codeChallenge?: string, codeChallengeMethod?: string, scopes?: string[], resource?: string) => Promise<string>;
|
|
7
|
+
handleCallBack: (callbackUrl: string, storedState: string, codeVerifier: string) => Promise<string>;
|
|
8
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
const discoverOAuthResourceMetadata = (mcpServerUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
11
|
+
const url = new URL(mcpServerUrl);
|
|
12
|
+
const protectedResourceUrl = new URL("/.well-known/oauth-protected-resource", url);
|
|
13
|
+
// Step 1: RFC 9470 - Get Protected Resource Metadata
|
|
14
|
+
const protectedResourceResponse = yield fetch(protectedResourceUrl.toString());
|
|
15
|
+
if (!protectedResourceResponse.ok) {
|
|
16
|
+
throw new Error(`Failed to fetch protected resource metadata: ` +
|
|
17
|
+
`${protectedResourceResponse.status}`);
|
|
18
|
+
}
|
|
19
|
+
const protectedResource = (yield protectedResourceResponse.json());
|
|
20
|
+
return protectedResource;
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Discovers OAuth configuration for an MCP server using RFC 9470 + RFC 8414.
|
|
24
|
+
*/
|
|
25
|
+
const discoverOAuthMetadata = (mcpServerUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
var _a;
|
|
27
|
+
const protectedResource = (yield discoverOAuthResourceMetadata(mcpServerUrl));
|
|
28
|
+
const authServers = protectedResource.authorization_servers;
|
|
29
|
+
if (!Array.isArray(authServers) || authServers.length === 0) {
|
|
30
|
+
throw new Error("No authorization servers found in protected resource metadata");
|
|
31
|
+
}
|
|
32
|
+
// Use the first authorization server
|
|
33
|
+
const authServerUrl = authServers[0];
|
|
34
|
+
// Step 2: RFC 8414 - Get Authorization Server Metadata
|
|
35
|
+
const metadataUrl = new URL("/.well-known/oauth-authorization-server", authServerUrl);
|
|
36
|
+
const metadataResponse = yield fetch(metadataUrl.toString());
|
|
37
|
+
if (!metadataResponse.ok) {
|
|
38
|
+
throw new Error(`Failed to fetch authorization server metadata: ` +
|
|
39
|
+
`${metadataResponse.status}`);
|
|
40
|
+
}
|
|
41
|
+
const metadata = (yield metadataResponse.json());
|
|
42
|
+
// Validate required fields
|
|
43
|
+
if (!metadata.authorization_endpoint || !metadata.token_endpoint) {
|
|
44
|
+
throw new Error("Missing required OAuth endpoints in metadata");
|
|
45
|
+
}
|
|
46
|
+
// Warn if PKCE support isn't advertised
|
|
47
|
+
if (!((_a = metadata.code_challenge_methods_supported) === null || _a === void 0 ? void 0 : _a.includes("S256"))) {
|
|
48
|
+
console.warn("Server does not advertise S256 PKCE support, " +
|
|
49
|
+
"but we will use it anyway");
|
|
50
|
+
}
|
|
51
|
+
return metadata;
|
|
52
|
+
});
|
|
53
|
+
const registerClient = (metadata, redirectUri) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
+
var _a, _b, _c, _d;
|
|
55
|
+
if (!metadata.registration_endpoint)
|
|
56
|
+
throw new Error("Server does not support dynamic client registration");
|
|
57
|
+
const registrationRequest = {
|
|
58
|
+
client_name: "Your MCP Client",
|
|
59
|
+
client_uri: "https://example.com",
|
|
60
|
+
redirect_uris: [redirectUri],
|
|
61
|
+
grant_types: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.grant_types_supported) !== null && _a !== void 0 ? _a : ["authorization_code", "refresh_token"],
|
|
62
|
+
response_types: (_b = metadata === null || metadata === void 0 ? void 0 : metadata.response_types_supported) !== null && _b !== void 0 ? _b : ["code"],
|
|
63
|
+
token_endpoint_auth_method: ((_c = metadata === null || metadata === void 0 ? void 0 : metadata.token_endpoint_auth_methods_supported) === null || _c === void 0 ? void 0 : _c.length) && ((_d = metadata === null || metadata === void 0 ? void 0 : metadata.token_endpoint_auth_methods_supported) === null || _d === void 0 ? void 0 : _d.includes("none")) ? "none" : metadata === null || metadata === void 0 ? void 0 : metadata.token_endpoint_auth_methods_supported[0],
|
|
64
|
+
};
|
|
65
|
+
const response = yield fetch(metadata.registration_endpoint, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
Accept: "application/json",
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify(registrationRequest),
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const errorBody = yield response.text();
|
|
75
|
+
throw new Error(`Client registration failed: ${response.status} - ${errorBody}`);
|
|
76
|
+
}
|
|
77
|
+
const credentials = (yield response.json());
|
|
78
|
+
// Store credentials securely
|
|
79
|
+
return credentials;
|
|
80
|
+
});
|
|
81
|
+
const buildAuthorizationUrl = (metadata_1, clientId_1, redirectUri_1, state_1, codeChallenge_1, codeChallengeMethod_1, ...args_1) => __awaiter(void 0, [metadata_1, clientId_1, redirectUri_1, state_1, codeChallenge_1, codeChallengeMethod_1, ...args_1], void 0, function* (metadata, clientId, redirectUri, state, codeChallenge, codeChallengeMethod, scopes = [], resource) {
|
|
82
|
+
let param = {
|
|
83
|
+
response_type: "code",
|
|
84
|
+
client_id: clientId,
|
|
85
|
+
redirect_uri: redirectUri,
|
|
86
|
+
state: state,
|
|
87
|
+
prompt: "consent",
|
|
88
|
+
};
|
|
89
|
+
if (scopes.length)
|
|
90
|
+
param.scope = scopes.join(" ");
|
|
91
|
+
if (codeChallengeMethod)
|
|
92
|
+
param.code_challenge = codeChallenge;
|
|
93
|
+
if (codeChallengeMethod)
|
|
94
|
+
param.code_challenge_method = codeChallengeMethod;
|
|
95
|
+
if (resource)
|
|
96
|
+
param.resource = resource;
|
|
97
|
+
const params = new URLSearchParams(param);
|
|
98
|
+
return `${metadata.authorization_endpoint}?${params.toString()}`;
|
|
99
|
+
});
|
|
100
|
+
const handleCallBack = (callbackUrl, storedState, codeVerifier) => __awaiter(void 0, void 0, void 0, function* () {
|
|
101
|
+
const params = parseCallback(callbackUrl);
|
|
102
|
+
if (params.error) {
|
|
103
|
+
throw new Error(`OAuth error: ${params.error} - ` +
|
|
104
|
+
`${params.error_description || "Unknown error"}`);
|
|
105
|
+
}
|
|
106
|
+
if (params.state !== storedState) {
|
|
107
|
+
throw new Error("Invalid state parameter - possible CSRF attack");
|
|
108
|
+
}
|
|
109
|
+
if (!params.code) {
|
|
110
|
+
throw new Error("Missing authorization code");
|
|
111
|
+
}
|
|
112
|
+
return params.code;
|
|
113
|
+
});
|
|
114
|
+
const parseCallback = (url) => {
|
|
115
|
+
const urlParams = new URLSearchParams(new URL(url).search);
|
|
116
|
+
return {
|
|
117
|
+
code: urlParams.get("code") || undefined,
|
|
118
|
+
state: urlParams.get("state") || undefined,
|
|
119
|
+
error: urlParams.get("error") || undefined,
|
|
120
|
+
error_description: urlParams.get("error_description") || undefined,
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
export const MCPOAuth = { discoverOAuthResourceMetadata, discoverOAuthMetadata, registerClient, buildAuthorizationUrl, handleCallBack };
|
|
124
|
+
//# sourceMappingURL=mcp-oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-oauth.js","sourceRoot":"","sources":["../../../utils/mcp-oauth.ts"],"names":[],"mappings":";;;;;;;;;AAEA,MAAM,6BAA6B,GAAG,CAAO,YAAoB,EAA2C,EAAE;IAC7G,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAA;IACjC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CACnC,uCAAuC,EACvC,GAAG,CACH,CAAA;IAED,qDAAqD;IACrD,MAAM,yBAAyB,GAAG,MAAM,KAAK,CAC5C,oBAAoB,CAAC,QAAQ,EAAE,CAC/B,CAAA;IACD,IAAI,CAAC,yBAAyB,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACd,+CAA+C;YAC/C,GAAG,yBAAyB,CAAC,MAAM,EAAE,CACrC,CAAA;IACF,CAAC;IAED,MAAM,iBAAiB,GAAG,CAAC,MAAM,yBAAyB,CAAC,IAAI,EAAE,CAAmC,CAAA;IACpG,OAAO,iBAAiB,CAAA;AACzB,CAAC,CAAA,CAAA;AAED;;GAEG;AACH,MAAM,qBAAqB,GAAG,CAAO,YAAoB,EAA0B,EAAE;;IACpF,MAAM,iBAAiB,GAAG,CAAC,MAAM,6BAA6B,CAAC,YAAY,CAAC,CAAmC,CAAA;IAC/G,MAAM,WAAW,GAAG,iBAAiB,CAAC,qBAAqB,CAAC;IAE5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACd,+DAA+D,CAC/D,CAAA;IACF,CAAC;IAED,qCAAqC;IACrC,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAEpC,uDAAuD;IACvD,MAAM,WAAW,GAAG,IAAI,GAAG,CAC1B,yCAAyC,EACzC,aAAa,CACb,CAAA;IACD,MAAM,gBAAgB,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAA;IAE5D,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACd,iDAAiD;YACjD,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAC5B,CAAA;IACF,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAgB,CAAC,IAAI,EAAE,CAAkB,CAAC;IAGlE,2BAA2B;IAC3B,IAAI,CAAC,QAAQ,CAAC,sBAAsB,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IAChE,CAAC;IAED,wCAAwC;IACxC,IAAI,CAAC,CAAA,MAAA,QAAQ,CAAC,gCAAgC,0CAAE,QAAQ,CAAC,MAAM,CAAC,CAAA,EAAE,CAAC;QAClE,OAAO,CAAC,IAAI,CACX,+CAA+C;YAC/C,2BAA2B,CAC3B,CAAA;IACF,CAAC;IAED,OAAO,QAAQ,CAAA;AAChB,CAAC,CAAA,CAAA;AAED,MAAM,cAAc,GAAG,CAAO,QAAuB,EAAE,WAAmB,EAA8B,EAAE;;IACzG,IAAI,CAAC,QAAQ,CAAC,qBAAqB;QAClC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;IAEvE,MAAM,mBAAmB,GAAuB;QAC/C,WAAW,EAAE,iBAAiB;QAC9B,UAAU,EAAE,qBAAqB;QACjC,aAAa,EAAE,CAAC,WAAW,CAAC;QAC5B,WAAW,EAAE,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,qBAAqB,mCAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC;QACvF,cAAc,EAAE,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,wBAAwB,mCAAI,CAAC,MAAM,CAAC;QAC9D,0BAA0B,EAAE,CAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,qCAAqC,0CAAE,MAAM,MAAI,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,qCAAqC,0CAAE,QAAQ,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,qCAAqC,CAAE,CAAC,CAAC;KACvN,CAAA;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,qBAAqB,EAAE;QAC5D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;SAC1B;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC;KACzC,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QACvC,MAAM,IAAI,KAAK,CACd,+BAA+B,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAC/D,CAAA;IACF,CAAC;IACD,MAAM,WAAW,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAsB,CAAA;IAEhE,6BAA6B;IAC7B,OAAO,WAAW,CAAA;AACnB,CAAC,CAAA,CAAA;AAED,MAAM,qBAAqB,GAAG,oGASX,EAAE,2IARpB,QAAuB,EACvB,QAAgB,EAChB,WAAmB,EACnB,KAAa,EACb,aAAsB,EACtB,mBAA4B,EAC5B,SAAmB,EAAE,EACrB,QAAiB;IAEjB,IAAI,KAAK,GAAG;QACX,aAAa,EAAE,MAAM;QACrB,SAAS,EAAE,QAAQ;QACnB,YAAY,EAAE,WAAW;QACzB,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,SAAS;KACM,CAAA;IACxB,IAAI,MAAM,CAAC,MAAM;QAChB,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,mBAAmB;QACtB,KAAK,CAAC,cAAc,GAAG,aAAa,CAAC;IACtC,IAAI,mBAAmB;QACtB,KAAK,CAAC,qBAAqB,GAAG,mBAAmB,CAAC;IACnD,IAAI,QAAQ;QACX,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,CAAA;IAEzC,OAAO,GAAG,QAAQ,CAAC,sBAAsB,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;AACjE,CAAC,CAAA,CAAA;AAED,MAAM,cAAc,GAAG,CAAO,WAAmB,EAAE,WAAmB,EAAE,YAAoB,EAAE,EAAE;IAC/F,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;IAEzC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACd,gBAAgB,MAAM,CAAC,KAAK,KAAK;YACjC,GAAG,MAAM,CAAC,iBAAiB,IAAI,eAAe,EAAE,CAChD,CAAA;IACF,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IAClE,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAA;AACnB,CAAC,CAAA,CAAA;AASD,MAAM,aAAa,GAAG,CAAC,GAAW,EAAkB,EAAE;IACpD,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;IAC1D,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS;QACxC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS;QAC1C,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS;QAC1C,iBAAiB,EAAE,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,SAAS;KACnE,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,6BAA6B,EAAE,qBAAqB,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,CAAC"}
|