@kya-os/mcp-i-core 1.8.0 → 1.8.2

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.
Files changed (111) hide show
  1. package/dist/conformance/capability-verifier-adapter.d.ts +66 -0
  2. package/dist/conformance/capability-verifier-adapter.js +61 -0
  3. package/dist/conformance/index.d.ts +3 -1
  4. package/dist/conformance/index.js +7 -1
  5. package/dist/conformance/validate-level2.d.ts +13 -3
  6. package/dist/conformance/validate-level2.js +15 -5
  7. package/dist/conformance/vc-jwt-verifier.d.ts +55 -0
  8. package/dist/conformance/vc-jwt-verifier.js +147 -0
  9. package/dist/delegation/did-web-resolver.d.ts +60 -0
  10. package/dist/delegation/did-web-resolver.js +129 -0
  11. package/dist/index.d.ts +2 -1
  12. package/dist/index.js +9 -1
  13. package/package.json +3 -3
  14. package/dist/auth/handshake.d.ts +0 -119
  15. package/dist/auth/handshake.js +0 -250
  16. package/dist/auth/index.d.ts +0 -6
  17. package/dist/auth/index.js +0 -11
  18. package/dist/auth/types.d.ts +0 -46
  19. package/dist/auth/types.js +0 -10
  20. package/dist/cache/oauth-config-cache.d.ts +0 -69
  21. package/dist/cache/oauth-config-cache.js +0 -76
  22. package/dist/cache/tool-protection-cache.d.ts +0 -89
  23. package/dist/cache/tool-protection-cache.js +0 -118
  24. package/dist/compliance/index.d.ts +0 -8
  25. package/dist/compliance/index.js +0 -24
  26. package/dist/compliance/schema-registry.d.ts +0 -50
  27. package/dist/compliance/schema-registry.js +0 -438
  28. package/dist/compliance/schema-verifier.d.ts +0 -110
  29. package/dist/compliance/schema-verifier.js +0 -518
  30. package/dist/config/remote-config.d.ts +0 -173
  31. package/dist/config/remote-config.js +0 -253
  32. package/dist/config.d.ts +0 -182
  33. package/dist/config.js +0 -148
  34. package/dist/identity/idp-token-resolver.d.ts +0 -69
  35. package/dist/identity/idp-token-resolver.js +0 -136
  36. package/dist/identity/idp-token-storage.interface.d.ts +0 -80
  37. package/dist/identity/idp-token-storage.interface.js +0 -14
  38. package/dist/identity/user-did-manager.d.ts +0 -228
  39. package/dist/identity/user-did-manager.js +0 -356
  40. package/dist/logging/index.d.ts +0 -5
  41. package/dist/logging/index.js +0 -10
  42. package/dist/logging/logger.d.ts +0 -33
  43. package/dist/logging/logger.js +0 -104
  44. package/dist/proof/generator.d.ts +0 -109
  45. package/dist/proof/generator.js +0 -236
  46. package/dist/proof/index.d.ts +0 -5
  47. package/dist/proof/index.js +0 -11
  48. package/dist/providers/base.d.ts +0 -95
  49. package/dist/providers/base.js +0 -47
  50. package/dist/providers/memory.d.ts +0 -42
  51. package/dist/providers/memory.js +0 -121
  52. package/dist/runtime/audit-logger.d.ts +0 -37
  53. package/dist/runtime/audit-logger.js +0 -9
  54. package/dist/runtime/base.d.ts +0 -375
  55. package/dist/runtime/base.js +0 -1491
  56. package/dist/runtime/ext-apps-constants.d.ts +0 -14
  57. package/dist/runtime/ext-apps-constants.js +0 -17
  58. package/dist/services/access-control.service.d.ts +0 -138
  59. package/dist/services/access-control.service.js +0 -721
  60. package/dist/services/authorization/authorization-registry.d.ts +0 -29
  61. package/dist/services/authorization/authorization-registry.js +0 -58
  62. package/dist/services/authorization/types.d.ts +0 -53
  63. package/dist/services/authorization/types.js +0 -10
  64. package/dist/services/batch-delegation.service.d.ts +0 -53
  65. package/dist/services/batch-delegation.service.js +0 -95
  66. package/dist/services/crypto.service.d.ts +0 -69
  67. package/dist/services/crypto.service.js +0 -225
  68. package/dist/services/delegation-error-formatter.d.ts +0 -124
  69. package/dist/services/delegation-error-formatter.js +0 -214
  70. package/dist/services/errors.d.ts +0 -49
  71. package/dist/services/errors.js +0 -66
  72. package/dist/services/index.d.ts +0 -9
  73. package/dist/services/index.js +0 -15
  74. package/dist/services/oauth-config.service.d.ts +0 -53
  75. package/dist/services/oauth-config.service.js +0 -141
  76. package/dist/services/oauth-provider-registry.d.ts +0 -88
  77. package/dist/services/oauth-provider-registry.js +0 -128
  78. package/dist/services/oauth-service.d.ts +0 -122
  79. package/dist/services/oauth-service.js +0 -442
  80. package/dist/services/oauth-token-retrieval.service.d.ts +0 -49
  81. package/dist/services/oauth-token-retrieval.service.js +0 -150
  82. package/dist/services/policy.service.d.ts +0 -130
  83. package/dist/services/policy.service.js +0 -399
  84. package/dist/services/proof-verifier.d.ts +0 -98
  85. package/dist/services/proof-verifier.js +0 -319
  86. package/dist/services/provider-resolver.d.ts +0 -89
  87. package/dist/services/provider-resolver.js +0 -196
  88. package/dist/services/provider-validator.d.ts +0 -55
  89. package/dist/services/provider-validator.js +0 -135
  90. package/dist/services/session-registration.service.d.ts +0 -80
  91. package/dist/services/session-registration.service.js +0 -174
  92. package/dist/services/storage.service.d.ts +0 -116
  93. package/dist/services/storage.service.js +0 -411
  94. package/dist/services/tool-context-builder.d.ts +0 -74
  95. package/dist/services/tool-context-builder.js +0 -215
  96. package/dist/services/tool-protection.service.d.ts +0 -193
  97. package/dist/services/tool-protection.service.js +0 -736
  98. package/dist/session/index.d.ts +0 -5
  99. package/dist/session/index.js +0 -11
  100. package/dist/session/manager.d.ts +0 -113
  101. package/dist/session/manager.js +0 -273
  102. package/dist/types/oauth-required-error.d.ts +0 -46
  103. package/dist/types/oauth-required-error.js +0 -42
  104. package/dist/types/tool-protection.d.ts +0 -144
  105. package/dist/types/tool-protection.js +0 -48
  106. package/dist/utils/cors.d.ts +0 -44
  107. package/dist/utils/cors.js +0 -71
  108. package/dist/utils/index.d.ts +0 -8
  109. package/dist/utils/index.js +0 -24
  110. package/dist/utils/storage-keys.d.ts +0 -120
  111. package/dist/utils/storage-keys.js +0 -217
@@ -1,442 +0,0 @@
1
- "use strict";
2
- /**
3
- * OAuth Service
4
- *
5
- * Handles OAuth token exchange and refresh using PKCE (Proof Key for Code Exchange).
6
- * Supports both direct PKCE exchange with OAuth providers and proxy mode via AgentShield.
7
- *
8
- * MCP-I Provider Registry Model:
9
- * - Client secrets are NOT sent via the API response
10
- * - Agents receive metadata.clientSecretName from AgentShield
11
- * - Secrets are resolved at runtime from secure storage (Cloudflare Worker env)
12
- * - The SecretResolver interface enables platform-specific secret resolution
13
- *
14
- * @package @kya-os/mcp-i-core
15
- */
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.OAuthService = exports.defaultSecretResolver = void 0;
18
- /**
19
- * Default secret resolver that uses environment variables
20
- * Used when no custom resolver is provided
21
- */
22
- exports.defaultSecretResolver = {
23
- async resolveSecret(secretName) {
24
- // For Node.js environments, check process.env
25
- if (typeof process !== "undefined" && process.env) {
26
- return process.env[secretName];
27
- }
28
- return undefined;
29
- },
30
- };
31
- /**
32
- * Service for OAuth token exchange and refresh
33
- */
34
- class OAuthService {
35
- config;
36
- constructor(config) {
37
- this.config = {
38
- configService: config.configService,
39
- fetchProvider: config.fetchProvider,
40
- agentShieldApiUrl: config.agentShieldApiUrl,
41
- agentShieldApiKey: config.agentShieldApiKey,
42
- projectId: config.projectId,
43
- logger: config.logger || (() => { }),
44
- secretResolver: config.secretResolver || exports.defaultSecretResolver,
45
- };
46
- }
47
- /**
48
- * Resolve client secret for a provider using the MCP-I provider-registry model
49
- *
50
- * Resolution order:
51
- * 1. If metadata.clientSecretName exists, resolve from secure storage
52
- * 2. Fall back to clientSecret field (legacy/backward compatibility)
53
- *
54
- * @param providerConfig - The OAuth provider configuration
55
- * @returns The resolved client secret, or undefined if not available
56
- */
57
- async resolveClientSecret(providerConfig) {
58
- // MCP-I Provider Registry model: resolve secret by name
59
- if (providerConfig.metadata?.clientSecretName) {
60
- const secretName = providerConfig.metadata.clientSecretName;
61
- this.config.logger("[OAuthService] Resolving client secret by name", {
62
- secretName,
63
- version: providerConfig.metadata.clientSecretVersion,
64
- });
65
- const secret = await this.config.secretResolver.resolveSecret(secretName);
66
- if (secret) {
67
- this.config.logger("[OAuthService] Client secret resolved successfully", {
68
- secretName,
69
- });
70
- return secret;
71
- }
72
- this.config.logger("[OAuthService] Client secret not found in secure storage", {
73
- secretName,
74
- });
75
- // Fall through to try clientSecret field
76
- }
77
- // Legacy model: use clientSecret directly (if provided)
78
- // DEPRECATED: This path is for backward compatibility only
79
- // New deployments should use metadata.clientSecretName with secure storage
80
- if (providerConfig.clientSecret) {
81
- this.config.logger("[OAuthService] DEPRECATED: Using legacy clientSecret field - " +
82
- "migrate to metadata.clientSecretName for better security", {
83
- telemetry: {
84
- event: "oauth.deprecated_client_secret_used",
85
- hasMetadata: !!providerConfig.metadata,
86
- hasSecretName: !!providerConfig.metadata?.clientSecretName,
87
- },
88
- });
89
- return providerConfig.clientSecret;
90
- }
91
- return undefined;
92
- }
93
- /**
94
- * Exchange authorization code for IDP tokens using PKCE
95
- *
96
- * For PKCE providers: Exchanges code directly with OAuth provider (no client secret)
97
- * For proxy mode: Exchanges code via AgentShield API
98
- *
99
- * @param provider - OAuth provider name (e.g., "github", "google")
100
- * @param code - Authorization code from OAuth callback
101
- * @param codeVerifier - PKCE code verifier (optional for non-PKCE providers in proxy mode)
102
- * @param redirectUri - Redirect URI used in authorization request
103
- * @returns IDP tokens (access_token, refresh_token, expires_at, etc.)
104
- */
105
- async exchangeToken(provider, code, codeVerifier, redirectUri) {
106
- // Fetch provider config
107
- const oauthConfig = await this.config.configService.getOAuthConfig(this.config.projectId);
108
- const providerConfig = oauthConfig.providers[provider];
109
- if (!providerConfig) {
110
- throw new Error(`Provider "${provider}" not configured for project "${this.config.projectId}"`);
111
- }
112
- // For PKCE providers, require codeVerifier
113
- if (providerConfig.supportsPKCE && !providerConfig.proxyMode) {
114
- if (!codeVerifier) {
115
- throw new Error(`Provider "${provider}" requires PKCE code_verifier for token exchange`);
116
- }
117
- return this.exchangeTokenPKCE(providerConfig, code, codeVerifier, redirectUri || "");
118
- }
119
- // For proxy mode, codeVerifier is optional (only included if PKCE is supported)
120
- if (providerConfig.proxyMode) {
121
- return this.exchangeTokenProxy(providerConfig, code, codeVerifier, redirectUri || "");
122
- }
123
- throw new Error(`Provider "${provider}" configuration is invalid: must support PKCE or use proxy mode`);
124
- }
125
- /**
126
- * Exchange token directly with OAuth provider using PKCE
127
- */
128
- async exchangeTokenPKCE(providerConfig, code, codeVerifier, redirectUri) {
129
- // Resolve client secret using MCP-I provider-registry model
130
- const clientSecret = await this.resolveClientSecret(providerConfig);
131
- this.config.logger("[OAuthService] Exchanging token with PKCE", {
132
- provider: providerConfig.authorizationUrl,
133
- tokenUrl: providerConfig.tokenUrl,
134
- hasClientSecret: !!clientSecret,
135
- resolvedViaSecretName: !!providerConfig.metadata?.clientSecretName,
136
- });
137
- // Build token exchange parameters
138
- // Note: GitHub OAuth Apps require client_secret even with PKCE
139
- // (GitHub Apps can use PKCE without client_secret, but OAuth Apps cannot)
140
- const params = {
141
- grant_type: "authorization_code",
142
- code,
143
- redirect_uri: redirectUri,
144
- client_id: providerConfig.clientId,
145
- code_verifier: codeVerifier,
146
- };
147
- // Include client_secret if resolved (either from secure storage or legacy field)
148
- // This is required for GitHub OAuth Apps and other providers that need it
149
- if (clientSecret) {
150
- params.client_secret = clientSecret;
151
- }
152
- const response = await this.config.fetchProvider.fetch(providerConfig.tokenUrl, {
153
- method: "POST",
154
- headers: {
155
- "Content-Type": "application/x-www-form-urlencoded",
156
- Accept: "application/json",
157
- },
158
- body: new URLSearchParams(params).toString(),
159
- });
160
- if (!response.ok) {
161
- const errorText = await response.text().catch(() => "Unknown error");
162
- let errorData;
163
- try {
164
- errorData = JSON.parse(errorText);
165
- }
166
- catch {
167
- errorData = { error: errorText };
168
- }
169
- const errorMessage = errorData.error_description || errorData.error || errorText;
170
- this.config.logger("[OAuthService] Token exchange failed", {
171
- status: response.status,
172
- error: errorMessage,
173
- provider: providerConfig.tokenUrl,
174
- });
175
- throw new Error(`Token exchange failed: ${errorMessage} (${response.status})`);
176
- }
177
- const tokens = await response.json();
178
- // GitHub returns errors with 200 status - check for error field first
179
- if (tokens.error) {
180
- this.config.logger("[OAuthService] Token exchange returned error (200 status)", {
181
- error: tokens.error,
182
- errorDescription: tokens.error_description,
183
- errorUri: tokens.error_uri,
184
- provider: providerConfig.tokenUrl,
185
- responseKeys: Object.keys(tokens),
186
- });
187
- throw new Error(`Token exchange failed: ${tokens.error_description || tokens.error}`);
188
- }
189
- // Validate required fields
190
- if (!tokens.access_token) {
191
- this.config.logger("[OAuthService] Token response missing access_token", {
192
- responseKeys: Object.keys(tokens),
193
- provider: providerConfig.tokenUrl,
194
- });
195
- throw new Error("Token response missing access_token");
196
- }
197
- // Calculate expiration timestamp
198
- const expiresIn = tokens.expires_in || 3600; // Default 1 hour
199
- const expiresAt = Date.now() + expiresIn * 1000;
200
- const idpTokens = {
201
- access_token: tokens.access_token,
202
- refresh_token: tokens.refresh_token,
203
- expires_in: expiresIn,
204
- expires_at: expiresAt,
205
- token_type: tokens.token_type || "Bearer",
206
- scope: tokens.scope,
207
- };
208
- this.config.logger("[OAuthService] Token exchange successful", {
209
- provider: providerConfig.tokenUrl,
210
- expiresAt: new Date(expiresAt).toISOString(),
211
- hasRefreshToken: !!idpTokens.refresh_token,
212
- });
213
- return idpTokens;
214
- }
215
- /**
216
- * Exchange token via AgentShield proxy (for providers that require proxy mode)
217
- *
218
- * Note: For Phase 3 two-step flow, OAuth tokens are retrieved separately via
219
- * OAuthTokenRetrievalService in the callback handler. This method maintains
220
- * backward compatibility for direct proxy mode usage.
221
- */
222
- async exchangeTokenProxy(providerConfig, code, codeVerifier, redirectUri) {
223
- // Exchange via AgentShield proxy endpoint
224
- const proxyUrl = `${this.config.agentShieldApiUrl}/api/v1/oauth/token`;
225
- this.config.logger("[OAuthService] Exchanging token via proxy", {
226
- proxyUrl,
227
- provider: providerConfig.authorizationUrl,
228
- hasCodeVerifier: !!codeVerifier,
229
- supportsPKCE: providerConfig.supportsPKCE,
230
- });
231
- // Build request body - only include code_verifier if PKCE is supported and provided
232
- const requestBody = {
233
- grant_type: "authorization_code",
234
- code,
235
- redirect_uri: redirectUri || "",
236
- provider: providerConfig.authorizationUrl,
237
- project_id: this.config.projectId,
238
- };
239
- // Include code_verifier only if provider supports PKCE and verifier is provided
240
- if (providerConfig.supportsPKCE && codeVerifier) {
241
- requestBody.code_verifier = codeVerifier;
242
- }
243
- const response = await this.config.fetchProvider.fetch(proxyUrl, {
244
- method: "POST",
245
- headers: {
246
- "Content-Type": "application/json",
247
- Authorization: `Bearer ${this.config.agentShieldApiKey}`,
248
- },
249
- body: JSON.stringify(requestBody),
250
- });
251
- if (!response.ok) {
252
- const errorText = await response.text().catch(() => "Unknown error");
253
- let errorData;
254
- try {
255
- errorData = JSON.parse(errorText);
256
- }
257
- catch {
258
- errorData = { error: errorText };
259
- }
260
- const errorMessage = errorData.error_description || errorData.error || errorText;
261
- this.config.logger("[OAuthService] Proxy token exchange failed", {
262
- status: response.status,
263
- error: errorMessage,
264
- proxyUrl,
265
- });
266
- throw new Error(`Proxy token exchange failed: ${errorMessage} (${response.status})`);
267
- }
268
- const result = await response.json();
269
- const tokens = result.data || result;
270
- // Validate required fields
271
- if (!tokens.access_token) {
272
- throw new Error("Proxy token response missing access_token");
273
- }
274
- // Calculate expiration timestamp
275
- const expiresIn = tokens.expires_in || 3600; // Default 1 hour
276
- const expiresAt = Date.now() + expiresIn * 1000;
277
- const idpTokens = {
278
- access_token: tokens.access_token,
279
- refresh_token: tokens.refresh_token,
280
- expires_in: expiresIn,
281
- expires_at: expiresAt,
282
- token_type: tokens.token_type || "Bearer",
283
- scope: tokens.scope,
284
- };
285
- this.config.logger("[OAuthService] Proxy token exchange successful", {
286
- proxyUrl,
287
- expiresAt: new Date(expiresAt).toISOString(),
288
- hasRefreshToken: !!idpTokens.refresh_token,
289
- });
290
- return idpTokens;
291
- }
292
- /**
293
- * Refresh IDP access token using refresh token
294
- *
295
- * For PKCE providers: Refreshes directly with OAuth provider
296
- * For proxy mode: Refreshes via AgentShield API
297
- *
298
- * @param provider - OAuth provider name
299
- * @param refreshToken - Refresh token from previous token exchange
300
- * @returns New IDP tokens or null if refresh failed
301
- */
302
- async refreshToken(provider, refreshToken) {
303
- // Fetch provider config
304
- const oauthConfig = await this.config.configService.getOAuthConfig(this.config.projectId);
305
- const providerConfig = oauthConfig.providers[provider];
306
- if (!providerConfig) {
307
- this.config.logger("[OAuthService] Provider not found for refresh", {
308
- provider,
309
- });
310
- return null;
311
- }
312
- // For PKCE providers, refresh directly with OAuth provider
313
- if (providerConfig.supportsPKCE && !providerConfig.proxyMode) {
314
- return this.refreshTokenPKCE(providerConfig, refreshToken);
315
- }
316
- // For proxy mode, refresh via AgentShield
317
- if (providerConfig.proxyMode) {
318
- return this.refreshTokenProxy(providerConfig, refreshToken);
319
- }
320
- return null;
321
- }
322
- /**
323
- * Refresh token directly with OAuth provider using PKCE
324
- */
325
- async refreshTokenPKCE(providerConfig, refreshToken) {
326
- this.config.logger("[OAuthService] Refreshing token with PKCE", {
327
- provider: providerConfig.tokenUrl,
328
- });
329
- try {
330
- const response = await this.config.fetchProvider.fetch(providerConfig.tokenUrl, {
331
- method: "POST",
332
- headers: {
333
- "Content-Type": "application/x-www-form-urlencoded",
334
- Accept: "application/json",
335
- },
336
- body: new URLSearchParams({
337
- grant_type: "refresh_token",
338
- refresh_token: refreshToken,
339
- client_id: providerConfig.clientId,
340
- }).toString(),
341
- });
342
- if (!response.ok) {
343
- this.config.logger("[OAuthService] Token refresh failed", {
344
- status: response.status,
345
- provider: providerConfig.tokenUrl,
346
- });
347
- return null;
348
- }
349
- const tokens = await response.json();
350
- if (!tokens.access_token) {
351
- this.config.logger("[OAuthService] Token refresh response missing access_token");
352
- return null;
353
- }
354
- // Calculate expiration timestamp
355
- const expiresIn = tokens.expires_in || 3600; // Default 1 hour
356
- const expiresAt = Date.now() + expiresIn * 1000;
357
- const idpTokens = {
358
- access_token: tokens.access_token,
359
- refresh_token: tokens.refresh_token || refreshToken, // Use new refresh token if provided, otherwise keep old one
360
- expires_in: expiresIn,
361
- expires_at: expiresAt,
362
- token_type: tokens.token_type || "Bearer",
363
- scope: tokens.scope,
364
- };
365
- this.config.logger("[OAuthService] Token refresh successful", {
366
- provider: providerConfig.tokenUrl,
367
- expiresAt: new Date(expiresAt).toISOString(),
368
- });
369
- return idpTokens;
370
- }
371
- catch (error) {
372
- this.config.logger("[OAuthService] Token refresh error", {
373
- error: error instanceof Error ? error.message : String(error),
374
- provider: providerConfig.tokenUrl,
375
- });
376
- return null;
377
- }
378
- }
379
- /**
380
- * Refresh token via AgentShield proxy
381
- */
382
- async refreshTokenProxy(providerConfig, refreshToken) {
383
- const proxyUrl = `${this.config.agentShieldApiUrl}/api/v1/oauth/token`;
384
- this.config.logger("[OAuthService] Refreshing token via proxy", {
385
- proxyUrl,
386
- provider: providerConfig.authorizationUrl,
387
- });
388
- try {
389
- const response = await this.config.fetchProvider.fetch(proxyUrl, {
390
- method: "POST",
391
- headers: {
392
- "Content-Type": "application/json",
393
- Authorization: `Bearer ${this.config.agentShieldApiKey}`,
394
- },
395
- body: JSON.stringify({
396
- grant_type: "refresh_token",
397
- refresh_token: refreshToken,
398
- provider: providerConfig.authorizationUrl,
399
- project_id: this.config.projectId,
400
- }),
401
- });
402
- if (!response.ok) {
403
- this.config.logger("[OAuthService] Proxy token refresh failed", {
404
- status: response.status,
405
- proxyUrl,
406
- });
407
- return null;
408
- }
409
- const result = await response.json();
410
- const tokens = result.data || result;
411
- if (!tokens.access_token) {
412
- this.config.logger("[OAuthService] Proxy token refresh response missing access_token");
413
- return null;
414
- }
415
- // Calculate expiration timestamp
416
- const expiresIn = tokens.expires_in || 3600; // Default 1 hour
417
- const expiresAt = Date.now() + expiresIn * 1000;
418
- const idpTokens = {
419
- access_token: tokens.access_token,
420
- refresh_token: tokens.refresh_token || refreshToken,
421
- expires_in: expiresIn,
422
- expires_at: expiresAt,
423
- token_type: tokens.token_type || "Bearer",
424
- scope: tokens.scope,
425
- };
426
- this.config.logger("[OAuthService] Proxy token refresh successful", {
427
- proxyUrl,
428
- expiresAt: new Date(expiresAt).toISOString(),
429
- });
430
- return idpTokens;
431
- }
432
- catch (error) {
433
- this.config.logger("[OAuthService] Proxy token refresh error", {
434
- error: error instanceof Error ? error.message : String(error),
435
- proxyUrl,
436
- });
437
- return null;
438
- }
439
- }
440
- }
441
- exports.OAuthService = OAuthService;
442
- //# sourceMappingURL=oauth-service.js.map
@@ -1,49 +0,0 @@
1
- /**
2
- * OAuth Token Retrieval Service
3
- *
4
- * Retrieves OAuth tokens from AgentShield after receiving delegation token.
5
- * Implements the two-step token flow for Phase 3 custom IDP support.
6
- *
7
- * @package @kya-os/mcp-i-core
8
- */
9
- import type { IdpTokens } from "@kya-os/contracts/config";
10
- /**
11
- * Configuration for OAuthTokenRetrievalService
12
- */
13
- export interface OAuthTokenRetrievalServiceConfig {
14
- /** AgentShield API base URL */
15
- baseUrl: string;
16
- /** Fetch implementation */
17
- fetchProvider: typeof fetch;
18
- /** Optional logger callback */
19
- logger?: (message: string, data?: any) => void;
20
- /** Optional retry configuration */
21
- retryConfig?: {
22
- maxRetries?: number;
23
- retryDelay?: number;
24
- retryBackoff?: number;
25
- };
26
- }
27
- /**
28
- * Service for retrieving OAuth tokens from AgentShield
29
- */
30
- export declare class OAuthTokenRetrievalService {
31
- private config;
32
- constructor(config: OAuthTokenRetrievalServiceConfig);
33
- /**
34
- * Retrieve OAuth tokens from AgentShield
35
- *
36
- * @param delegationId - Delegation ID from token exchange response
37
- * @param delegationToken - Delegation token (JWT) for authorization
38
- * @returns OAuth tokens mapped to IdpTokens format, or null if unavailable
39
- */
40
- retrieveTokens(delegationId: string, delegationToken: string): Promise<IdpTokens | null>;
41
- /**
42
- * Map AgentShield response to IdpTokens format
43
- *
44
- * @param data - Response data from AgentShield
45
- * @returns IdpTokens object
46
- */
47
- private mapToIdpTokens;
48
- }
49
- //# sourceMappingURL=oauth-token-retrieval.service.d.ts.map
@@ -1,150 +0,0 @@
1
- "use strict";
2
- /**
3
- * OAuth Token Retrieval Service
4
- *
5
- * Retrieves OAuth tokens from AgentShield after receiving delegation token.
6
- * Implements the two-step token flow for Phase 3 custom IDP support.
7
- *
8
- * @package @kya-os/mcp-i-core
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.OAuthTokenRetrievalService = void 0;
12
- /**
13
- * Service for retrieving OAuth tokens from AgentShield
14
- */
15
- class OAuthTokenRetrievalService {
16
- config;
17
- constructor(config) {
18
- const defaultRetryConfig = {
19
- maxRetries: 3,
20
- retryDelay: 1000,
21
- retryBackoff: 2,
22
- };
23
- this.config = {
24
- ...config,
25
- logger: config.logger || (() => { }),
26
- retryConfig: {
27
- ...defaultRetryConfig,
28
- ...config.retryConfig,
29
- },
30
- };
31
- }
32
- /**
33
- * Retrieve OAuth tokens from AgentShield
34
- *
35
- * @param delegationId - Delegation ID from token exchange response
36
- * @param delegationToken - Delegation token (JWT) for authorization
37
- * @returns OAuth tokens mapped to IdpTokens format, or null if unavailable
38
- */
39
- async retrieveTokens(delegationId, delegationToken) {
40
- const endpoint = `${this.config.baseUrl}/api/v1/bouncer/delegations/${delegationId}/tokens`;
41
- this.config.logger("[OAuthTokenRetrievalService] Retrieving OAuth tokens", {
42
- delegationId,
43
- endpoint,
44
- });
45
- let lastError = null;
46
- let attempt = 0;
47
- // Retry logic for transient failures
48
- while (attempt <= this.config.retryConfig.maxRetries) {
49
- try {
50
- const response = await this.config.fetchProvider(endpoint, {
51
- method: "GET",
52
- headers: {
53
- Authorization: `Bearer ${delegationToken}`,
54
- Accept: "application/json",
55
- },
56
- });
57
- if (!response.ok) {
58
- const errorData = await response.json().catch(() => ({}));
59
- if (response.status === 404 || response.status === 401) {
60
- // Token unavailable or unauthorized - don't retry
61
- this.config.logger("[OAuthTokenRetrievalService] Tokens unavailable", {
62
- status: response.status,
63
- delegationId,
64
- error: errorData,
65
- });
66
- return null;
67
- }
68
- // Transient error - retry
69
- const errorMessage = errorData.error?.message ||
70
- errorData.error ||
71
- errorData.message ||
72
- `HTTP ${response.status}`;
73
- throw new Error(`Token retrieval failed: ${errorMessage}`);
74
- }
75
- const result = (await response.json());
76
- if (!result.success) {
77
- this.config.logger("[OAuthTokenRetrievalService] Token retrieval error response", {
78
- delegationId,
79
- error: result.error,
80
- });
81
- return null;
82
- }
83
- // Map response to IdpTokens format
84
- const tokens = this.mapToIdpTokens(result.data);
85
- this.config.logger("[OAuthTokenRetrievalService] OAuth tokens retrieved successfully", {
86
- delegationId,
87
- expiresAt: new Date(tokens.expires_at).toISOString(),
88
- hasRefreshToken: !!tokens.refresh_token,
89
- });
90
- return tokens;
91
- }
92
- catch (error) {
93
- lastError = error instanceof Error ? error : new Error(String(error));
94
- if (attempt < this.config.retryConfig.maxRetries) {
95
- const delay = this.config.retryConfig.retryDelay *
96
- Math.pow(this.config.retryConfig.retryBackoff, attempt);
97
- this.config.logger("[OAuthTokenRetrievalService] Retry attempt failed, retrying", {
98
- attempt: attempt + 1,
99
- maxRetries: this.config.retryConfig.maxRetries,
100
- delay,
101
- error: lastError.message,
102
- });
103
- await new Promise((resolve) => setTimeout(resolve, delay));
104
- attempt++;
105
- }
106
- else {
107
- // Max retries exceeded
108
- this.config.logger("[OAuthTokenRetrievalService] Max retries exceeded", {
109
- delegationId,
110
- error: lastError.message,
111
- attempts: attempt + 1,
112
- });
113
- // Return null instead of throwing - delegation token still valid
114
- return null;
115
- }
116
- }
117
- }
118
- return null;
119
- }
120
- /**
121
- * Map AgentShield response to IdpTokens format
122
- *
123
- * @param data - Response data from AgentShield
124
- * @returns IdpTokens object
125
- */
126
- mapToIdpTokens(data) {
127
- // Convert ISO 8601 string to milliseconds timestamp
128
- let expiresAt;
129
- if (data.oauth_expires_at) {
130
- expiresAt = new Date(data.oauth_expires_at).getTime();
131
- }
132
- else if (data.oauth_expires_in) {
133
- expiresAt = Date.now() + data.oauth_expires_in * 1000;
134
- }
135
- else {
136
- // Default to 1 hour if neither provided
137
- expiresAt = Date.now() + 3600 * 1000;
138
- }
139
- return {
140
- access_token: data.oauth_access_token,
141
- refresh_token: data.oauth_refresh_token || undefined,
142
- expires_in: data.oauth_expires_in || undefined,
143
- expires_at: expiresAt,
144
- token_type: data.oauth_token_type || "Bearer",
145
- scope: data.oauth_scope || undefined,
146
- };
147
- }
148
- }
149
- exports.OAuthTokenRetrievalService = OAuthTokenRetrievalService;
150
- //# sourceMappingURL=oauth-token-retrieval.service.js.map