@samanhappy/mcphub 0.9.16 → 0.10.0
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/README.md +67 -0
- package/README.zh.md +65 -0
- package/dist/config/index.js +17 -4
- package/dist/config/index.js.map +1 -1
- package/dist/controllers/authController.js +16 -0
- package/dist/controllers/authController.js.map +1 -1
- package/dist/controllers/oauthCallbackController.js +276 -0
- package/dist/controllers/oauthCallbackController.js.map +1 -0
- package/dist/controllers/serverController.js +1 -1
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/controllers/userController.js +23 -1
- package/dist/controllers/userController.js.map +1 -1
- package/dist/routes/index.js +3 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/server.js +10 -0
- package/dist/server.js.map +1 -1
- package/dist/services/mcpOAuthProvider.js +472 -0
- package/dist/services/mcpOAuthProvider.js.map +1 -0
- package/dist/services/mcpService.js +321 -191
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/oauthClientRegistration.js +444 -0
- package/dist/services/oauthClientRegistration.js.map +1 -0
- package/dist/services/oauthService.js +216 -0
- package/dist/services/oauthService.js.map +1 -0
- package/dist/services/oauthSettingsStore.js +106 -0
- package/dist/services/oauthSettingsStore.js.map +1 -0
- package/dist/utils/passwordValidation.js +38 -0
- package/dist/utils/passwordValidation.js.map +1 -0
- package/dist/utils/path.js.map +1 -1
- package/frontend/dist/assets/index-BP5IZhlg.js +251 -0
- package/frontend/dist/assets/index-BP5IZhlg.js.map +1 -0
- package/frontend/dist/assets/index-C_58ZhSt.css +1 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +3 -2
- package/frontend/dist/assets/index-DDUK8zl_.js +0 -217
- package/frontend/dist/assets/index-DDUK8zl_.js.map +0 -1
- package/frontend/dist/assets/index-DcVhHcn9.css +0 -1
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP OAuth Provider Implementation
|
|
3
|
+
*
|
|
4
|
+
* Implements OAuthClientProvider interface from @modelcontextprotocol/sdk/client/auth.js
|
|
5
|
+
* to handle OAuth 2.0 authentication for upstream MCP servers using the SDK's built-in
|
|
6
|
+
* OAuth support.
|
|
7
|
+
*
|
|
8
|
+
* This provider integrates with our existing OAuth infrastructure:
|
|
9
|
+
* - Dynamic client registration (RFC7591)
|
|
10
|
+
* - Token storage and refresh
|
|
11
|
+
* - Authorization flow handling
|
|
12
|
+
*/
|
|
13
|
+
import { randomBytes } from 'node:crypto';
|
|
14
|
+
import { loadSettings } from '../config/index.js';
|
|
15
|
+
import { initializeOAuthForServer, getRegisteredClient, removeRegisteredClient, fetchScopesFromServer, } from './oauthClientRegistration.js';
|
|
16
|
+
import { clearOAuthData, loadServerConfig, mutateOAuthSettings, persistClientCredentials, persistTokens, updatePendingAuthorization, } from './oauthSettingsStore.js';
|
|
17
|
+
// Import getServerByName to access ServerInfo
|
|
18
|
+
import { getServerByName } from './mcpService.js';
|
|
19
|
+
/**
|
|
20
|
+
* MCPHub OAuth Provider for server-side OAuth flows
|
|
21
|
+
*
|
|
22
|
+
* This provider handles OAuth authentication for upstream MCP servers.
|
|
23
|
+
* Unlike browser-based providers, this runs in a Node.js server environment,
|
|
24
|
+
* so the authorization flow requires external handling (e.g., via web UI).
|
|
25
|
+
*/
|
|
26
|
+
export class MCPHubOAuthProvider {
|
|
27
|
+
constructor(serverName, serverConfig) {
|
|
28
|
+
this.serverName = serverName;
|
|
29
|
+
this.serverConfig = serverConfig;
|
|
30
|
+
}
|
|
31
|
+
getSystemInstallBaseUrl() {
|
|
32
|
+
const settings = loadSettings();
|
|
33
|
+
return settings.systemConfig?.install?.baseUrl;
|
|
34
|
+
}
|
|
35
|
+
sanitizeRedirectUri(input) {
|
|
36
|
+
if (!input) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const url = new URL(input);
|
|
41
|
+
url.searchParams.delete('server');
|
|
42
|
+
const params = url.searchParams.toString();
|
|
43
|
+
url.search = params ? `?${params}` : '';
|
|
44
|
+
return url.toString();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
buildRedirectUriFromBase(baseUrl) {
|
|
51
|
+
if (!baseUrl) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const trimmed = baseUrl.trim();
|
|
55
|
+
if (!trimmed) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const normalizedBase = trimmed.endsWith('/') ? trimmed : `${trimmed}/`;
|
|
60
|
+
const redirect = new URL('oauth/callback', normalizedBase);
|
|
61
|
+
return this.sanitizeRedirectUri(redirect.toString());
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get redirect URL for OAuth callback
|
|
69
|
+
*/
|
|
70
|
+
get redirectUrl() {
|
|
71
|
+
const dynamicConfig = this.serverConfig.oauth?.dynamicRegistration;
|
|
72
|
+
const metadata = dynamicConfig?.metadata || {};
|
|
73
|
+
const fallback = 'http://localhost:3000/oauth/callback';
|
|
74
|
+
const systemConfigured = this.buildRedirectUriFromBase(this.getSystemInstallBaseUrl());
|
|
75
|
+
const metadataConfigured = this.sanitizeRedirectUri(metadata.redirect_uris?.[0]);
|
|
76
|
+
return systemConfigured ?? metadataConfigured ?? fallback;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get client metadata for dynamic registration or static configuration
|
|
80
|
+
*/
|
|
81
|
+
get clientMetadata() {
|
|
82
|
+
const dynamicConfig = this.serverConfig.oauth?.dynamicRegistration;
|
|
83
|
+
const metadata = dynamicConfig?.metadata || {};
|
|
84
|
+
// Use redirectUrl getter to ensure consistent callback URL
|
|
85
|
+
const redirectUri = this.redirectUrl;
|
|
86
|
+
const systemConfigured = this.buildRedirectUriFromBase(this.getSystemInstallBaseUrl());
|
|
87
|
+
const metadataRedirects = metadata.redirect_uris && metadata.redirect_uris.length > 0
|
|
88
|
+
? metadata.redirect_uris
|
|
89
|
+
.map((uri) => this.sanitizeRedirectUri(uri))
|
|
90
|
+
.filter((uri) => Boolean(uri))
|
|
91
|
+
: [];
|
|
92
|
+
const redirectUris = [];
|
|
93
|
+
if (systemConfigured) {
|
|
94
|
+
redirectUris.push(systemConfigured);
|
|
95
|
+
}
|
|
96
|
+
for (const uri of metadataRedirects) {
|
|
97
|
+
if (!redirectUris.includes(uri)) {
|
|
98
|
+
redirectUris.push(uri);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!redirectUris.includes(redirectUri)) {
|
|
102
|
+
redirectUris.push(redirectUri);
|
|
103
|
+
}
|
|
104
|
+
const tokenEndpointAuthMethod = metadata.token_endpoint_auth_method && metadata.token_endpoint_auth_method !== ''
|
|
105
|
+
? metadata.token_endpoint_auth_method
|
|
106
|
+
: this.serverConfig.oauth?.clientSecret
|
|
107
|
+
? 'client_secret_post'
|
|
108
|
+
: 'none';
|
|
109
|
+
return {
|
|
110
|
+
...metadata, // Include any additional custom metadata
|
|
111
|
+
client_name: metadata.client_name || `MCPHub - ${this.serverName}`,
|
|
112
|
+
redirect_uris: redirectUris,
|
|
113
|
+
grant_types: metadata.grant_types || ['authorization_code', 'refresh_token'],
|
|
114
|
+
response_types: metadata.response_types || ['code'],
|
|
115
|
+
token_endpoint_auth_method: tokenEndpointAuthMethod,
|
|
116
|
+
scope: metadata.scope || this.serverConfig.oauth?.scopes?.join(' ') || 'openid',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
async ensureScopesFromServer() {
|
|
120
|
+
const serverUrl = this.serverConfig.url;
|
|
121
|
+
const existingScopes = this.serverConfig.oauth?.scopes;
|
|
122
|
+
if (!serverUrl) {
|
|
123
|
+
return existingScopes;
|
|
124
|
+
}
|
|
125
|
+
if (existingScopes && existingScopes.length > 0) {
|
|
126
|
+
return existingScopes;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const scopes = await fetchScopesFromServer(serverUrl);
|
|
130
|
+
if (scopes && scopes.length > 0) {
|
|
131
|
+
const updatedConfig = await mutateOAuthSettings(this.serverName, ({ oauth }) => {
|
|
132
|
+
oauth.scopes = scopes;
|
|
133
|
+
});
|
|
134
|
+
if (updatedConfig) {
|
|
135
|
+
this.serverConfig = updatedConfig;
|
|
136
|
+
}
|
|
137
|
+
console.log(`Stored auto-detected scopes for ${this.serverName}: ${scopes.join(', ')}`);
|
|
138
|
+
return scopes;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
console.warn(`Failed to auto-detect scopes for ${this.serverName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
143
|
+
}
|
|
144
|
+
return existingScopes;
|
|
145
|
+
}
|
|
146
|
+
generateState() {
|
|
147
|
+
const payload = {
|
|
148
|
+
server: this.serverName,
|
|
149
|
+
nonce: randomBytes(16).toString('hex'),
|
|
150
|
+
};
|
|
151
|
+
const base64 = Buffer.from(JSON.stringify(payload)).toString('base64');
|
|
152
|
+
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
153
|
+
}
|
|
154
|
+
async state() {
|
|
155
|
+
if (!this._currentState) {
|
|
156
|
+
this._currentState = this.generateState();
|
|
157
|
+
}
|
|
158
|
+
return this._currentState;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get previously registered client information
|
|
162
|
+
*/
|
|
163
|
+
clientInformation() {
|
|
164
|
+
const clientInfo = getRegisteredClient(this.serverName);
|
|
165
|
+
if (!clientInfo) {
|
|
166
|
+
// Try to use static client configuration from cached serverConfig first
|
|
167
|
+
let serverConfig = this.serverConfig;
|
|
168
|
+
// If cached config doesn't have clientId, reload from settings
|
|
169
|
+
if (!serverConfig?.oauth?.clientId) {
|
|
170
|
+
const storedConfig = loadServerConfig(this.serverName);
|
|
171
|
+
if (storedConfig) {
|
|
172
|
+
this.serverConfig = storedConfig;
|
|
173
|
+
serverConfig = storedConfig;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Try to use static client configuration from serverConfig
|
|
177
|
+
if (serverConfig?.oauth?.clientId) {
|
|
178
|
+
return {
|
|
179
|
+
client_id: serverConfig.oauth.clientId,
|
|
180
|
+
client_secret: serverConfig.oauth.clientSecret,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
client_id: clientInfo.clientId,
|
|
187
|
+
client_secret: clientInfo.clientSecret,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Save registered client information
|
|
192
|
+
* Called by SDK after successful dynamic registration
|
|
193
|
+
*/
|
|
194
|
+
async saveClientInformation(info) {
|
|
195
|
+
console.log(`Saving OAuth client information for server: ${this.serverName}`);
|
|
196
|
+
const scopeString = info.scope?.trim();
|
|
197
|
+
const scopes = scopeString && scopeString.length > 0
|
|
198
|
+
? scopeString.split(/\s+/).filter((value) => value.length > 0)
|
|
199
|
+
: undefined;
|
|
200
|
+
try {
|
|
201
|
+
const updatedConfig = await persistClientCredentials(this.serverName, {
|
|
202
|
+
clientId: info.client_id,
|
|
203
|
+
clientSecret: info.client_secret,
|
|
204
|
+
scopes,
|
|
205
|
+
});
|
|
206
|
+
if (updatedConfig) {
|
|
207
|
+
this.serverConfig = updatedConfig;
|
|
208
|
+
}
|
|
209
|
+
if (!scopes || scopes.length === 0) {
|
|
210
|
+
await this.ensureScopesFromServer();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
console.error(`Failed to persist OAuth client credentials for server ${this.serverName}:`, error);
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get stored OAuth tokens
|
|
220
|
+
*/
|
|
221
|
+
tokens() {
|
|
222
|
+
// Use cached config first, but reload if needed
|
|
223
|
+
let serverConfig = this.serverConfig;
|
|
224
|
+
// If cached config doesn't have tokens, try reloading
|
|
225
|
+
if (!serverConfig?.oauth?.accessToken) {
|
|
226
|
+
const storedConfig = loadServerConfig(this.serverName);
|
|
227
|
+
if (storedConfig) {
|
|
228
|
+
this.serverConfig = storedConfig;
|
|
229
|
+
serverConfig = storedConfig;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (!serverConfig?.oauth?.accessToken) {
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
access_token: serverConfig.oauth.accessToken,
|
|
237
|
+
token_type: 'Bearer',
|
|
238
|
+
refresh_token: serverConfig.oauth.refreshToken,
|
|
239
|
+
// Note: expires_in is not typically stored, only the token itself
|
|
240
|
+
// The SDK will handle token refresh when needed
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Save OAuth tokens
|
|
245
|
+
* Called by SDK after successful token exchange or refresh
|
|
246
|
+
*/
|
|
247
|
+
async saveTokens(tokens) {
|
|
248
|
+
const currentOAuth = this.serverConfig.oauth;
|
|
249
|
+
const accessTokenChanged = currentOAuth?.accessToken !== tokens.access_token;
|
|
250
|
+
const refreshTokenProvided = tokens.refresh_token !== undefined;
|
|
251
|
+
const refreshTokenChanged = refreshTokenProvided && currentOAuth?.refreshToken !== tokens.refresh_token;
|
|
252
|
+
const hadPending = Boolean(currentOAuth?.pendingAuthorization);
|
|
253
|
+
if (!accessTokenChanged && !refreshTokenChanged && !hadPending) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
console.log(`Saving OAuth tokens for server: ${this.serverName}`);
|
|
257
|
+
const updatedConfig = await persistTokens(this.serverName, {
|
|
258
|
+
accessToken: tokens.access_token,
|
|
259
|
+
refreshToken: refreshTokenProvided ? (tokens.refresh_token ?? null) : undefined,
|
|
260
|
+
clearPendingAuthorization: hadPending,
|
|
261
|
+
});
|
|
262
|
+
if (updatedConfig) {
|
|
263
|
+
this.serverConfig = updatedConfig;
|
|
264
|
+
}
|
|
265
|
+
this._codeVerifier = undefined;
|
|
266
|
+
this._currentState = undefined;
|
|
267
|
+
const serverInfo = getServerByName(this.serverName);
|
|
268
|
+
if (serverInfo) {
|
|
269
|
+
serverInfo.oauth = undefined;
|
|
270
|
+
}
|
|
271
|
+
console.log(`Saved OAuth tokens for server: ${this.serverName}`);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Redirect to authorization URL
|
|
275
|
+
* In a server environment, we can't directly redirect the user
|
|
276
|
+
* Instead, we store the URL in ServerInfo for the frontend to access
|
|
277
|
+
*/
|
|
278
|
+
async redirectToAuthorization(url) {
|
|
279
|
+
console.log('='.repeat(80));
|
|
280
|
+
console.log(`OAuth Authorization Required for server: ${this.serverName}`);
|
|
281
|
+
console.log(`Authorization URL: ${url.toString()}`);
|
|
282
|
+
console.log('='.repeat(80));
|
|
283
|
+
let state = url.searchParams.get('state') || undefined;
|
|
284
|
+
if (!state) {
|
|
285
|
+
state = await this.state();
|
|
286
|
+
url.searchParams.set('state', state);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
this._currentState = state;
|
|
290
|
+
}
|
|
291
|
+
const authorizationUrl = url.toString();
|
|
292
|
+
try {
|
|
293
|
+
const pendingUpdate = {
|
|
294
|
+
authorizationUrl,
|
|
295
|
+
state,
|
|
296
|
+
};
|
|
297
|
+
if (this._codeVerifier) {
|
|
298
|
+
pendingUpdate.codeVerifier = this._codeVerifier;
|
|
299
|
+
}
|
|
300
|
+
const updatedConfig = await updatePendingAuthorization(this.serverName, pendingUpdate);
|
|
301
|
+
if (updatedConfig) {
|
|
302
|
+
this.serverConfig = updatedConfig;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
console.error(`Failed to persist pending OAuth authorization state for ${this.serverName}:`, error);
|
|
307
|
+
}
|
|
308
|
+
// Store the authorization URL in ServerInfo for the frontend to access
|
|
309
|
+
const serverInfo = getServerByName(this.serverName);
|
|
310
|
+
if (serverInfo) {
|
|
311
|
+
serverInfo.status = 'oauth_required';
|
|
312
|
+
serverInfo.oauth = {
|
|
313
|
+
authorizationUrl,
|
|
314
|
+
state,
|
|
315
|
+
codeVerifier: this._codeVerifier,
|
|
316
|
+
};
|
|
317
|
+
console.log(`Stored OAuth authorization URL in ServerInfo for server: ${this.serverName}`);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.warn(`ServerInfo not found for ${this.serverName}, cannot store authorization URL`);
|
|
321
|
+
}
|
|
322
|
+
// Throw error to indicate authorization is needed
|
|
323
|
+
// The error will be caught in the connection flow and handled appropriately
|
|
324
|
+
throw new Error(`OAuth authorization required for server ${this.serverName}. Please complete OAuth flow via web UI.`);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Save PKCE code verifier for later use in token exchange
|
|
328
|
+
*/
|
|
329
|
+
async saveCodeVerifier(verifier) {
|
|
330
|
+
this._codeVerifier = verifier;
|
|
331
|
+
try {
|
|
332
|
+
const updatedConfig = await updatePendingAuthorization(this.serverName, {
|
|
333
|
+
codeVerifier: verifier,
|
|
334
|
+
});
|
|
335
|
+
if (updatedConfig) {
|
|
336
|
+
this.serverConfig = updatedConfig;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
console.error(`Failed to persist OAuth code verifier for ${this.serverName}:`, error);
|
|
341
|
+
}
|
|
342
|
+
console.log(`Saved code verifier for server: ${this.serverName}`);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Retrieve PKCE code verifier for token exchange
|
|
346
|
+
*/
|
|
347
|
+
async codeVerifier() {
|
|
348
|
+
if (this._codeVerifier) {
|
|
349
|
+
return this._codeVerifier;
|
|
350
|
+
}
|
|
351
|
+
const storedConfig = loadServerConfig(this.serverName);
|
|
352
|
+
const storedVerifier = storedConfig?.oauth?.pendingAuthorization?.codeVerifier;
|
|
353
|
+
if (storedVerifier) {
|
|
354
|
+
this.serverConfig = storedConfig || this.serverConfig;
|
|
355
|
+
this._codeVerifier = storedVerifier;
|
|
356
|
+
return storedVerifier;
|
|
357
|
+
}
|
|
358
|
+
throw new Error(`No code verifier stored for server: ${this.serverName}`);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Invalidate cached OAuth credentials when the SDK detects they are no longer valid.
|
|
362
|
+
* This keeps stored configuration in sync and forces a fresh authorization flow.
|
|
363
|
+
*/
|
|
364
|
+
async invalidateCredentials(scope) {
|
|
365
|
+
const storedConfig = loadServerConfig(this.serverName);
|
|
366
|
+
if (!storedConfig?.oauth) {
|
|
367
|
+
if (scope === 'verifier' || scope === 'all') {
|
|
368
|
+
this._codeVerifier = undefined;
|
|
369
|
+
}
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
let currentConfig = storedConfig;
|
|
373
|
+
const assignUpdatedConfig = (updated) => {
|
|
374
|
+
if (updated) {
|
|
375
|
+
currentConfig = updated;
|
|
376
|
+
this.serverConfig = updated;
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
this.serverConfig = currentConfig;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
assignUpdatedConfig(currentConfig);
|
|
383
|
+
let changed = false;
|
|
384
|
+
if (scope === 'tokens' || scope === 'all') {
|
|
385
|
+
if (currentConfig.oauth.accessToken || currentConfig.oauth.refreshToken) {
|
|
386
|
+
const updated = await clearOAuthData(this.serverName, 'tokens');
|
|
387
|
+
assignUpdatedConfig(updated);
|
|
388
|
+
changed = true;
|
|
389
|
+
console.warn(`Cleared OAuth tokens for server: ${this.serverName}`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (scope === 'client' || scope === 'all') {
|
|
393
|
+
const supportsDynamicClient = currentConfig.oauth.dynamicRegistration?.enabled === true;
|
|
394
|
+
if (supportsDynamicClient &&
|
|
395
|
+
(currentConfig.oauth.clientId || currentConfig.oauth.clientSecret)) {
|
|
396
|
+
removeRegisteredClient(this.serverName);
|
|
397
|
+
const updated = await clearOAuthData(this.serverName, 'client');
|
|
398
|
+
assignUpdatedConfig(updated);
|
|
399
|
+
changed = true;
|
|
400
|
+
console.warn(`Cleared OAuth client registration for server: ${this.serverName}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (scope === 'verifier' || scope === 'all') {
|
|
404
|
+
this._codeVerifier = undefined;
|
|
405
|
+
this._currentState = undefined;
|
|
406
|
+
if (currentConfig.oauth.pendingAuthorization) {
|
|
407
|
+
const updated = await clearOAuthData(this.serverName, 'verifier');
|
|
408
|
+
assignUpdatedConfig(updated);
|
|
409
|
+
changed = true;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (changed) {
|
|
413
|
+
this._currentState = undefined;
|
|
414
|
+
const serverInfo = getServerByName(this.serverName);
|
|
415
|
+
if (serverInfo) {
|
|
416
|
+
serverInfo.status = 'oauth_required';
|
|
417
|
+
serverInfo.oauth = undefined;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
const prepopulateScopesIfMissing = async (serverName, serverConfig) => {
|
|
423
|
+
if (!serverConfig.oauth || serverConfig.oauth.scopes?.length) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if (!serverConfig.url) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
const scopes = await fetchScopesFromServer(serverConfig.url);
|
|
431
|
+
if (scopes && scopes.length > 0) {
|
|
432
|
+
const updatedConfig = await mutateOAuthSettings(serverName, ({ oauth }) => {
|
|
433
|
+
oauth.scopes = scopes;
|
|
434
|
+
});
|
|
435
|
+
if (!serverConfig.oauth) {
|
|
436
|
+
serverConfig.oauth = {};
|
|
437
|
+
}
|
|
438
|
+
serverConfig.oauth.scopes = scopes;
|
|
439
|
+
if (updatedConfig) {
|
|
440
|
+
console.log(`Stored auto-detected scopes for ${serverName}: ${scopes.join(', ')}`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
console.warn(`Failed to auto-detect scopes for ${serverName} during provider initialization: ${error instanceof Error ? error.message : String(error)}`);
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
/**
|
|
449
|
+
* Create an OAuth provider for a server if OAuth is configured
|
|
450
|
+
*
|
|
451
|
+
* @param serverName - Name of the server
|
|
452
|
+
* @param serverConfig - Server configuration
|
|
453
|
+
* @returns OAuthClientProvider instance or undefined if OAuth not configured
|
|
454
|
+
*/
|
|
455
|
+
export const createOAuthProvider = async (serverName, serverConfig) => {
|
|
456
|
+
// Ensure scopes are pre-populated if dynamic registration already ran previously
|
|
457
|
+
await prepopulateScopesIfMissing(serverName, serverConfig);
|
|
458
|
+
// Initialize OAuth for the server (performs registration if needed)
|
|
459
|
+
// This ensures the client is registered before the SDK tries to use it
|
|
460
|
+
try {
|
|
461
|
+
await initializeOAuthForServer(serverName, serverConfig);
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
console.warn(`Failed to initialize OAuth for server ${serverName}:`, error);
|
|
465
|
+
// Continue anyway - the SDK might be able to handle it
|
|
466
|
+
}
|
|
467
|
+
// Create and return the provider
|
|
468
|
+
const provider = new MCPHubOAuthProvider(serverName, serverConfig);
|
|
469
|
+
console.log(`Created OAuth provider for server: ${serverName}`);
|
|
470
|
+
return provider;
|
|
471
|
+
};
|
|
472
|
+
//# sourceMappingURL=mcpOAuthProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpOAuthProvider.js","sourceRoot":"","sources":["../../src/services/mcpOAuthProvider.ts"],"names":[],"mappings":"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"}
|