@samanhappy/mcphub 0.10.2 → 0.10.4
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 +39 -1
- package/dist/config/index.js +24 -0
- package/dist/config/index.js.map +1 -1
- package/dist/constants/oauthServerDefaults.js +36 -0
- package/dist/constants/oauthServerDefaults.js.map +1 -0
- package/dist/controllers/oauthClientController.js +252 -0
- package/dist/controllers/oauthClientController.js.map +1 -0
- package/dist/controllers/oauthDynamicRegistrationController.js +479 -0
- package/dist/controllers/oauthDynamicRegistrationController.js.map +1 -0
- package/dist/controllers/oauthServerController.js +449 -0
- package/dist/controllers/oauthServerController.js.map +1 -0
- package/dist/controllers/openApiController.js +6 -3
- package/dist/controllers/openApiController.js.map +1 -1
- package/dist/controllers/serverController.js +116 -23
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/middlewares/auth.js +23 -2
- package/dist/middlewares/auth.js.map +1 -1
- package/dist/middlewares/userContext.js +27 -11
- package/dist/middlewares/userContext.js.map +1 -1
- package/dist/models/OAuth.js +291 -0
- package/dist/models/OAuth.js.map +1 -0
- package/dist/routes/index.js +25 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/server.js +4 -1
- package/dist/server.js.map +1 -1
- package/dist/services/dataServicex.js +3 -0
- package/dist/services/dataServicex.js.map +1 -1
- package/dist/services/mcpService.js +2 -94
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/oauthServerService.js +339 -0
- package/dist/services/oauthServerService.js.map +1 -0
- package/dist/services/sseService.js +368 -45
- package/dist/services/sseService.js.map +1 -1
- package/dist/utils/oauthBearer.js +35 -0
- package/dist/utils/oauthBearer.js.map +1 -0
- package/frontend/dist/assets/index-D-WhIyV-.js +251 -0
- package/frontend/dist/assets/index-D-WhIyV-.js.map +1 -0
- package/frontend/dist/index.html +1 -1
- package/mcp_settings.json +111 -0
- package/package.json +2 -1
- package/frontend/dist/assets/index-CZR9_tjG.js +0 -251
- package/frontend/dist/assets/index-CZR9_tjG.js.map +0 -1
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import { createOAuthClient, findOAuthClientById, updateOAuthClient, deleteOAuthClient, } from '../models/OAuth.js';
|
|
3
|
+
import { loadSettings } from '../config/index.js';
|
|
4
|
+
// Store registration access tokens (in production, use database)
|
|
5
|
+
const registrationTokens = new Map();
|
|
6
|
+
/**
|
|
7
|
+
* Generate registration access token
|
|
8
|
+
*/
|
|
9
|
+
const generateRegistrationToken = (clientId) => {
|
|
10
|
+
const token = crypto.randomBytes(32).toString('hex');
|
|
11
|
+
registrationTokens.set(token, {
|
|
12
|
+
clientId,
|
|
13
|
+
createdAt: new Date(),
|
|
14
|
+
});
|
|
15
|
+
return token;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Verify registration access token
|
|
19
|
+
*/
|
|
20
|
+
const verifyRegistrationToken = (token) => {
|
|
21
|
+
const data = registrationTokens.get(token);
|
|
22
|
+
if (!data) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
// Token expires after 30 days
|
|
26
|
+
const expiresAt = new Date(data.createdAt.getTime() + 30 * 24 * 60 * 60 * 1000);
|
|
27
|
+
if (new Date() > expiresAt) {
|
|
28
|
+
registrationTokens.delete(token);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return data.clientId;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* POST /oauth/register
|
|
35
|
+
* RFC 7591 Dynamic Client Registration
|
|
36
|
+
* Public endpoint for registering new OAuth clients
|
|
37
|
+
*/
|
|
38
|
+
export const registerClient = (req, res) => {
|
|
39
|
+
try {
|
|
40
|
+
const settings = loadSettings();
|
|
41
|
+
const oauthConfig = settings.systemConfig?.oauthServer;
|
|
42
|
+
// Check if dynamic registration is enabled
|
|
43
|
+
if (!oauthConfig?.dynamicRegistration?.enabled) {
|
|
44
|
+
res.status(403).json({
|
|
45
|
+
error: 'invalid_request',
|
|
46
|
+
error_description: 'Dynamic client registration is not enabled',
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Validate required fields
|
|
51
|
+
const { redirect_uris, client_name, grant_types, response_types, scope, token_endpoint_auth_method, application_type, contacts, logo_uri, client_uri, policy_uri, tos_uri, jwks_uri, jwks, } = req.body;
|
|
52
|
+
// redirect_uris is required
|
|
53
|
+
if (!redirect_uris || !Array.isArray(redirect_uris) || redirect_uris.length === 0) {
|
|
54
|
+
res.status(400).json({
|
|
55
|
+
error: 'invalid_redirect_uri',
|
|
56
|
+
error_description: 'redirect_uris is required and must be a non-empty array',
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Validate redirect URIs
|
|
61
|
+
for (const uri of redirect_uris) {
|
|
62
|
+
try {
|
|
63
|
+
const url = new URL(uri);
|
|
64
|
+
// For security, only allow https (except localhost for development)
|
|
65
|
+
if (url.protocol !== 'https:' &&
|
|
66
|
+
!url.hostname.match(/^(localhost|127\.0\.0\.1|\[::1\])$/)) {
|
|
67
|
+
res.status(400).json({
|
|
68
|
+
error: 'invalid_redirect_uri',
|
|
69
|
+
error_description: `Redirect URI must use HTTPS: ${uri}`,
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
res.status(400).json({
|
|
76
|
+
error: 'invalid_redirect_uri',
|
|
77
|
+
error_description: `Invalid redirect URI: ${uri}`,
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Generate client credentials
|
|
83
|
+
const clientId = crypto.randomBytes(16).toString('hex');
|
|
84
|
+
// Determine if client secret is needed based on token_endpoint_auth_method
|
|
85
|
+
const authMethod = token_endpoint_auth_method || 'client_secret_basic';
|
|
86
|
+
const needsSecret = authMethod !== 'none';
|
|
87
|
+
const clientSecret = needsSecret ? crypto.randomBytes(32).toString('hex') : undefined;
|
|
88
|
+
// Default grant types
|
|
89
|
+
const defaultGrantTypes = ['authorization_code', 'refresh_token'];
|
|
90
|
+
const clientGrantTypes = grant_types || defaultGrantTypes;
|
|
91
|
+
// Validate grant types
|
|
92
|
+
const allowedGrantTypes = oauthConfig.dynamicRegistration.allowedGrantTypes || [
|
|
93
|
+
'authorization_code',
|
|
94
|
+
'refresh_token',
|
|
95
|
+
];
|
|
96
|
+
for (const grantType of clientGrantTypes) {
|
|
97
|
+
if (!allowedGrantTypes.includes(grantType)) {
|
|
98
|
+
res.status(400).json({
|
|
99
|
+
error: 'invalid_client_metadata',
|
|
100
|
+
error_description: `Grant type not allowed: ${grantType}`,
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Validate scopes
|
|
106
|
+
const requestedScopes = scope ? scope.split(' ') : ['read', 'write'];
|
|
107
|
+
const allowedScopes = oauthConfig.allowedScopes || ['read', 'write'];
|
|
108
|
+
for (const requestedScope of requestedScopes) {
|
|
109
|
+
if (!allowedScopes.includes(requestedScope)) {
|
|
110
|
+
res.status(400).json({
|
|
111
|
+
error: 'invalid_client_metadata',
|
|
112
|
+
error_description: `Scope not allowed: ${requestedScope}`,
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Generate registration access token
|
|
118
|
+
const registrationAccessToken = generateRegistrationToken(clientId);
|
|
119
|
+
const baseUrl = settings.systemConfig?.install?.baseUrl || `${req.protocol}://${req.get('host')}`;
|
|
120
|
+
const registrationClientUri = `${baseUrl}/oauth/register/${clientId}`;
|
|
121
|
+
// Create OAuth client
|
|
122
|
+
const client = {
|
|
123
|
+
clientId,
|
|
124
|
+
clientSecret,
|
|
125
|
+
name: client_name || 'Dynamically Registered Client',
|
|
126
|
+
redirectUris: redirect_uris,
|
|
127
|
+
grants: clientGrantTypes,
|
|
128
|
+
scopes: requestedScopes,
|
|
129
|
+
owner: 'dynamic-registration',
|
|
130
|
+
// Store additional metadata
|
|
131
|
+
metadata: {
|
|
132
|
+
application_type: application_type || 'web',
|
|
133
|
+
contacts,
|
|
134
|
+
logo_uri,
|
|
135
|
+
client_uri,
|
|
136
|
+
policy_uri,
|
|
137
|
+
tos_uri,
|
|
138
|
+
jwks_uri,
|
|
139
|
+
jwks,
|
|
140
|
+
token_endpoint_auth_method: authMethod,
|
|
141
|
+
response_types: response_types || ['code'],
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
const createdClient = createOAuthClient(client);
|
|
145
|
+
// Build response according to RFC 7591
|
|
146
|
+
const response = {
|
|
147
|
+
client_id: createdClient.clientId,
|
|
148
|
+
client_name: createdClient.name,
|
|
149
|
+
redirect_uris: createdClient.redirectUris,
|
|
150
|
+
grant_types: createdClient.grants,
|
|
151
|
+
response_types: client.metadata?.response_types || ['code'],
|
|
152
|
+
scope: (createdClient.scopes || []).join(' '),
|
|
153
|
+
token_endpoint_auth_method: authMethod,
|
|
154
|
+
registration_access_token: registrationAccessToken,
|
|
155
|
+
registration_client_uri: registrationClientUri,
|
|
156
|
+
client_id_issued_at: Math.floor(Date.now() / 1000),
|
|
157
|
+
};
|
|
158
|
+
// Include client secret if generated
|
|
159
|
+
if (clientSecret) {
|
|
160
|
+
response.client_secret = clientSecret;
|
|
161
|
+
response.client_secret_expires_at = 0; // 0 means it doesn't expire
|
|
162
|
+
}
|
|
163
|
+
// Include optional metadata
|
|
164
|
+
if (application_type)
|
|
165
|
+
response.application_type = application_type;
|
|
166
|
+
if (contacts)
|
|
167
|
+
response.contacts = contacts;
|
|
168
|
+
if (logo_uri)
|
|
169
|
+
response.logo_uri = logo_uri;
|
|
170
|
+
if (client_uri)
|
|
171
|
+
response.client_uri = client_uri;
|
|
172
|
+
if (policy_uri)
|
|
173
|
+
response.policy_uri = policy_uri;
|
|
174
|
+
if (tos_uri)
|
|
175
|
+
response.tos_uri = tos_uri;
|
|
176
|
+
if (jwks_uri)
|
|
177
|
+
response.jwks_uri = jwks_uri;
|
|
178
|
+
if (jwks)
|
|
179
|
+
response.jwks = jwks;
|
|
180
|
+
res.status(201).json(response);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error('Dynamic client registration error:', error);
|
|
184
|
+
if (error instanceof Error && error.message.includes('already exists')) {
|
|
185
|
+
res.status(400).json({
|
|
186
|
+
error: 'invalid_client_metadata',
|
|
187
|
+
error_description: 'Client with this ID already exists',
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
res.status(500).json({
|
|
192
|
+
error: 'server_error',
|
|
193
|
+
error_description: 'Failed to register client',
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* GET /oauth/register/:clientId
|
|
200
|
+
* RFC 7591 Client Configuration Endpoint
|
|
201
|
+
* Read client configuration
|
|
202
|
+
*/
|
|
203
|
+
export const getClientConfiguration = (req, res) => {
|
|
204
|
+
try {
|
|
205
|
+
const { clientId } = req.params;
|
|
206
|
+
const authHeader = req.headers.authorization;
|
|
207
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
208
|
+
res.status(401).json({
|
|
209
|
+
error: 'invalid_token',
|
|
210
|
+
error_description: 'Registration access token required',
|
|
211
|
+
});
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const token = authHeader.substring(7);
|
|
215
|
+
const tokenClientId = verifyRegistrationToken(token);
|
|
216
|
+
if (!tokenClientId || tokenClientId !== clientId) {
|
|
217
|
+
res.status(401).json({
|
|
218
|
+
error: 'invalid_token',
|
|
219
|
+
error_description: 'Invalid or expired registration access token',
|
|
220
|
+
});
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const client = findOAuthClientById(clientId);
|
|
224
|
+
if (!client) {
|
|
225
|
+
res.status(404).json({
|
|
226
|
+
error: 'invalid_client',
|
|
227
|
+
error_description: 'Client not found',
|
|
228
|
+
});
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// Build response
|
|
232
|
+
const response = {
|
|
233
|
+
client_id: client.clientId,
|
|
234
|
+
client_name: client.name,
|
|
235
|
+
redirect_uris: client.redirectUris,
|
|
236
|
+
grant_types: client.grants,
|
|
237
|
+
response_types: client.metadata?.response_types || ['code'],
|
|
238
|
+
scope: (client.scopes || []).join(' '),
|
|
239
|
+
token_endpoint_auth_method: client.metadata?.token_endpoint_auth_method || 'client_secret_basic',
|
|
240
|
+
};
|
|
241
|
+
// Include optional metadata
|
|
242
|
+
if (client.metadata) {
|
|
243
|
+
if (client.metadata.application_type)
|
|
244
|
+
response.application_type = client.metadata.application_type;
|
|
245
|
+
if (client.metadata.contacts)
|
|
246
|
+
response.contacts = client.metadata.contacts;
|
|
247
|
+
if (client.metadata.logo_uri)
|
|
248
|
+
response.logo_uri = client.metadata.logo_uri;
|
|
249
|
+
if (client.metadata.client_uri)
|
|
250
|
+
response.client_uri = client.metadata.client_uri;
|
|
251
|
+
if (client.metadata.policy_uri)
|
|
252
|
+
response.policy_uri = client.metadata.policy_uri;
|
|
253
|
+
if (client.metadata.tos_uri)
|
|
254
|
+
response.tos_uri = client.metadata.tos_uri;
|
|
255
|
+
if (client.metadata.jwks_uri)
|
|
256
|
+
response.jwks_uri = client.metadata.jwks_uri;
|
|
257
|
+
if (client.metadata.jwks)
|
|
258
|
+
response.jwks = client.metadata.jwks;
|
|
259
|
+
}
|
|
260
|
+
res.json(response);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
console.error('Get client configuration error:', error);
|
|
264
|
+
res.status(500).json({
|
|
265
|
+
error: 'server_error',
|
|
266
|
+
error_description: 'Failed to retrieve client configuration',
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* PUT /oauth/register/:clientId
|
|
272
|
+
* RFC 7591 Client Update Endpoint
|
|
273
|
+
* Update client configuration
|
|
274
|
+
*/
|
|
275
|
+
export const updateClientConfiguration = (req, res) => {
|
|
276
|
+
try {
|
|
277
|
+
const { clientId } = req.params;
|
|
278
|
+
const authHeader = req.headers.authorization;
|
|
279
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
280
|
+
res.status(401).json({
|
|
281
|
+
error: 'invalid_token',
|
|
282
|
+
error_description: 'Registration access token required',
|
|
283
|
+
});
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const token = authHeader.substring(7);
|
|
287
|
+
const tokenClientId = verifyRegistrationToken(token);
|
|
288
|
+
if (!tokenClientId || tokenClientId !== clientId) {
|
|
289
|
+
res.status(401).json({
|
|
290
|
+
error: 'invalid_token',
|
|
291
|
+
error_description: 'Invalid or expired registration access token',
|
|
292
|
+
});
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const client = findOAuthClientById(clientId);
|
|
296
|
+
if (!client) {
|
|
297
|
+
res.status(404).json({
|
|
298
|
+
error: 'invalid_client',
|
|
299
|
+
error_description: 'Client not found',
|
|
300
|
+
});
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const { redirect_uris, client_name, grant_types, scope, contacts, logo_uri, client_uri, policy_uri, tos_uri, } = req.body;
|
|
304
|
+
const settings = loadSettings();
|
|
305
|
+
const oauthConfig = settings.systemConfig?.oauthServer;
|
|
306
|
+
// Validate redirect URIs if provided
|
|
307
|
+
if (redirect_uris) {
|
|
308
|
+
if (!Array.isArray(redirect_uris) || redirect_uris.length === 0) {
|
|
309
|
+
res.status(400).json({
|
|
310
|
+
error: 'invalid_redirect_uri',
|
|
311
|
+
error_description: 'redirect_uris must be a non-empty array',
|
|
312
|
+
});
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
for (const uri of redirect_uris) {
|
|
316
|
+
try {
|
|
317
|
+
const url = new URL(uri);
|
|
318
|
+
if (url.protocol !== 'https:' &&
|
|
319
|
+
!url.hostname.match(/^(localhost|127\.0\.0\.1|\[::1\])$/)) {
|
|
320
|
+
res.status(400).json({
|
|
321
|
+
error: 'invalid_redirect_uri',
|
|
322
|
+
error_description: `Redirect URI must use HTTPS: ${uri}`,
|
|
323
|
+
});
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch (e) {
|
|
328
|
+
res.status(400).json({
|
|
329
|
+
error: 'invalid_redirect_uri',
|
|
330
|
+
error_description: `Invalid redirect URI: ${uri}`,
|
|
331
|
+
});
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Validate grant types if provided
|
|
337
|
+
if (grant_types) {
|
|
338
|
+
const allowedGrantTypes = oauthConfig?.dynamicRegistration?.allowedGrantTypes || [
|
|
339
|
+
'authorization_code',
|
|
340
|
+
'refresh_token',
|
|
341
|
+
];
|
|
342
|
+
for (const grantType of grant_types) {
|
|
343
|
+
if (!allowedGrantTypes.includes(grantType)) {
|
|
344
|
+
res.status(400).json({
|
|
345
|
+
error: 'invalid_client_metadata',
|
|
346
|
+
error_description: `Grant type not allowed: ${grantType}`,
|
|
347
|
+
});
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// Validate scopes if provided
|
|
353
|
+
if (scope) {
|
|
354
|
+
const requestedScopes = scope.split(' ');
|
|
355
|
+
const allowedScopes = oauthConfig?.allowedScopes || ['read', 'write'];
|
|
356
|
+
for (const requestedScope of requestedScopes) {
|
|
357
|
+
if (!allowedScopes.includes(requestedScope)) {
|
|
358
|
+
res.status(400).json({
|
|
359
|
+
error: 'invalid_client_metadata',
|
|
360
|
+
error_description: `Scope not allowed: ${requestedScope}`,
|
|
361
|
+
});
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// Build updates
|
|
367
|
+
const updates = {};
|
|
368
|
+
if (client_name)
|
|
369
|
+
updates.name = client_name;
|
|
370
|
+
if (redirect_uris)
|
|
371
|
+
updates.redirectUris = redirect_uris;
|
|
372
|
+
if (grant_types)
|
|
373
|
+
updates.grants = grant_types;
|
|
374
|
+
if (scope)
|
|
375
|
+
updates.scopes = scope.split(' ');
|
|
376
|
+
// Update metadata
|
|
377
|
+
if (client.metadata || contacts || logo_uri || client_uri || policy_uri || tos_uri) {
|
|
378
|
+
updates.metadata = {
|
|
379
|
+
...client.metadata,
|
|
380
|
+
contacts,
|
|
381
|
+
logo_uri,
|
|
382
|
+
client_uri,
|
|
383
|
+
policy_uri,
|
|
384
|
+
tos_uri,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
const updatedClient = updateOAuthClient(clientId, updates);
|
|
388
|
+
if (!updatedClient) {
|
|
389
|
+
res.status(500).json({
|
|
390
|
+
error: 'server_error',
|
|
391
|
+
error_description: 'Failed to update client',
|
|
392
|
+
});
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
// Build response
|
|
396
|
+
const response = {
|
|
397
|
+
client_id: updatedClient.clientId,
|
|
398
|
+
client_name: updatedClient.name,
|
|
399
|
+
redirect_uris: updatedClient.redirectUris,
|
|
400
|
+
grant_types: updatedClient.grants,
|
|
401
|
+
response_types: updatedClient.metadata?.response_types || ['code'],
|
|
402
|
+
scope: (updatedClient.scopes || []).join(' '),
|
|
403
|
+
token_endpoint_auth_method: updatedClient.metadata?.token_endpoint_auth_method || 'client_secret_basic',
|
|
404
|
+
};
|
|
405
|
+
// Include optional metadata
|
|
406
|
+
if (updatedClient.metadata) {
|
|
407
|
+
if (updatedClient.metadata.application_type)
|
|
408
|
+
response.application_type = updatedClient.metadata.application_type;
|
|
409
|
+
if (updatedClient.metadata.contacts)
|
|
410
|
+
response.contacts = updatedClient.metadata.contacts;
|
|
411
|
+
if (updatedClient.metadata.logo_uri)
|
|
412
|
+
response.logo_uri = updatedClient.metadata.logo_uri;
|
|
413
|
+
if (updatedClient.metadata.client_uri)
|
|
414
|
+
response.client_uri = updatedClient.metadata.client_uri;
|
|
415
|
+
if (updatedClient.metadata.policy_uri)
|
|
416
|
+
response.policy_uri = updatedClient.metadata.policy_uri;
|
|
417
|
+
if (updatedClient.metadata.tos_uri)
|
|
418
|
+
response.tos_uri = updatedClient.metadata.tos_uri;
|
|
419
|
+
if (updatedClient.metadata.jwks_uri)
|
|
420
|
+
response.jwks_uri = updatedClient.metadata.jwks_uri;
|
|
421
|
+
if (updatedClient.metadata.jwks)
|
|
422
|
+
response.jwks = updatedClient.metadata.jwks;
|
|
423
|
+
}
|
|
424
|
+
res.json(response);
|
|
425
|
+
}
|
|
426
|
+
catch (error) {
|
|
427
|
+
console.error('Update client configuration error:', error);
|
|
428
|
+
res.status(500).json({
|
|
429
|
+
error: 'server_error',
|
|
430
|
+
error_description: 'Failed to update client configuration',
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
/**
|
|
435
|
+
* DELETE /oauth/register/:clientId
|
|
436
|
+
* RFC 7591 Client Delete Endpoint
|
|
437
|
+
* Delete client registration
|
|
438
|
+
*/
|
|
439
|
+
export const deleteClientRegistration = (req, res) => {
|
|
440
|
+
try {
|
|
441
|
+
const { clientId } = req.params;
|
|
442
|
+
const authHeader = req.headers.authorization;
|
|
443
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
444
|
+
res.status(401).json({
|
|
445
|
+
error: 'invalid_token',
|
|
446
|
+
error_description: 'Registration access token required',
|
|
447
|
+
});
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
const token = authHeader.substring(7);
|
|
451
|
+
const tokenClientId = verifyRegistrationToken(token);
|
|
452
|
+
if (!tokenClientId || tokenClientId !== clientId) {
|
|
453
|
+
res.status(401).json({
|
|
454
|
+
error: 'invalid_token',
|
|
455
|
+
error_description: 'Invalid or expired registration access token',
|
|
456
|
+
});
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const deleted = deleteOAuthClient(clientId);
|
|
460
|
+
if (!deleted) {
|
|
461
|
+
res.status(404).json({
|
|
462
|
+
error: 'invalid_client',
|
|
463
|
+
error_description: 'Client not found',
|
|
464
|
+
});
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
// Clean up registration token
|
|
468
|
+
registrationTokens.delete(token);
|
|
469
|
+
res.status(204).send();
|
|
470
|
+
}
|
|
471
|
+
catch (error) {
|
|
472
|
+
console.error('Delete client registration error:', error);
|
|
473
|
+
res.status(500).json({
|
|
474
|
+
error: 'server_error',
|
|
475
|
+
error_description: 'Failed to delete client registration',
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
//# sourceMappingURL=oauthDynamicRegistrationController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauthDynamicRegistrationController.js","sourceRoot":"","sources":["../../src/controllers/oauthDynamicRegistrationController.ts"],"names":[],"mappings":"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"}
|