integrate-sdk 0.7.47 → 0.7.49
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/adapters/auto-routes.d.ts.map +1 -1
- package/dist/adapters/auto-routes.js +380 -24
- package/dist/adapters/base-handler.d.ts +50 -6
- package/dist/adapters/base-handler.d.ts.map +1 -1
- package/dist/adapters/base-handler.js +368 -18
- package/dist/adapters/context-cookie.d.ts +85 -0
- package/dist/adapters/context-cookie.d.ts.map +1 -0
- package/dist/adapters/context-cookie.js +152 -0
- package/dist/adapters/index.js +399 -37
- package/dist/adapters/nextjs.d.ts.map +1 -1
- package/dist/adapters/nextjs.js +387 -31
- package/dist/adapters/node.d.ts.map +1 -1
- package/dist/adapters/node.js +380 -24
- package/dist/adapters/session-detector.d.ts +37 -0
- package/dist/adapters/session-detector.d.ts.map +1 -0
- package/dist/adapters/session-detector.js +157 -0
- package/dist/adapters/solid-start.js +387 -31
- package/dist/adapters/svelte-kit.js +387 -31
- package/dist/ai/google.d.ts.map +1 -1
- package/dist/ai/google.js +6 -2
- package/dist/ai/index.js +6 -2
- package/dist/index.js +392 -30
- package/dist/oauth.js +380 -24
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +560 -289
- package/dist/src/adapters/auto-routes.d.ts.map +1 -1
- package/dist/src/adapters/base-handler.d.ts +50 -6
- package/dist/src/adapters/base-handler.d.ts.map +1 -1
- package/dist/src/adapters/context-cookie.d.ts +85 -0
- package/dist/src/adapters/context-cookie.d.ts.map +1 -0
- package/dist/src/adapters/nextjs.d.ts.map +1 -1
- package/dist/src/adapters/node.d.ts.map +1 -1
- package/dist/src/adapters/session-detector.d.ts +37 -0
- package/dist/src/adapters/session-detector.d.ts.map +1 -0
- package/dist/src/ai/google.d.ts.map +1 -1
- package/dist/src/config/types.d.ts +24 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/package.json +33 -1
- package/server.ts +57 -1
package/dist/server.js
CHANGED
|
@@ -261,6 +261,280 @@ function base64UrlDecode(str) {
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
// src/adapters/session-detector.ts
|
|
265
|
+
var exports_session_detector = {};
|
|
266
|
+
__export(exports_session_detector, {
|
|
267
|
+
tryDecodeJWT: () => tryDecodeJWT,
|
|
268
|
+
detectSessionContext: () => detectSessionContext
|
|
269
|
+
});
|
|
270
|
+
function tryDecodeJWT(token) {
|
|
271
|
+
try {
|
|
272
|
+
const parts = token.split(".");
|
|
273
|
+
if (parts.length !== 3) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const payloadPart = parts[1];
|
|
277
|
+
if (!payloadPart) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const base64 = payloadPart.replace(/-/g, "+").replace(/_/g, "/");
|
|
281
|
+
const jsonPayload = decodeURIComponent(atob(base64).split("").map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)).join(""));
|
|
282
|
+
return JSON.parse(jsonPayload);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function getCookies(request) {
|
|
288
|
+
const cookies = new Map;
|
|
289
|
+
const cookieHeader = request.headers.get("cookie");
|
|
290
|
+
if (!cookieHeader) {
|
|
291
|
+
return cookies;
|
|
292
|
+
}
|
|
293
|
+
const pairs = cookieHeader.split(";");
|
|
294
|
+
for (const pair of pairs) {
|
|
295
|
+
const [name, ...valueParts] = pair.split("=");
|
|
296
|
+
if (name && valueParts.length > 0) {
|
|
297
|
+
const trimmedName = name.trim();
|
|
298
|
+
const value = valueParts.join("=").trim();
|
|
299
|
+
cookies.set(trimmedName, value);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return cookies;
|
|
303
|
+
}
|
|
304
|
+
function tryBetterAuth(cookies) {
|
|
305
|
+
const sessionToken = cookies.get("better-auth.session_token");
|
|
306
|
+
if (!sessionToken) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
310
|
+
if (!payload) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const userId = payload.sub || payload.userId || payload.user_id || payload.id;
|
|
314
|
+
if (!userId) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
userId,
|
|
319
|
+
sessionId: payload.jti || payload.sessionId
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function tryNextAuth(cookies) {
|
|
323
|
+
const sessionToken = cookies.get("__Secure-next-auth.session-token") || cookies.get("next-auth.session-token");
|
|
324
|
+
if (!sessionToken) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (sessionToken.includes(".")) {
|
|
328
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
329
|
+
if (payload) {
|
|
330
|
+
return {
|
|
331
|
+
userId: payload.sub || payload.userId || payload.user_id || payload.id,
|
|
332
|
+
sessionId: payload.jti
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
function tryClerk(cookies) {
|
|
339
|
+
const sessionToken = cookies.get("__session");
|
|
340
|
+
if (!sessionToken) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
344
|
+
if (!payload) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
userId: payload.sub || payload.userId,
|
|
349
|
+
organizationId: payload.org_id || payload.organizationId,
|
|
350
|
+
sessionId: payload.sid || payload.sessionId
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function tryLucia(cookies) {
|
|
354
|
+
const sessionToken = cookies.get("lucia_session");
|
|
355
|
+
if (!sessionToken) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
sessionId: sessionToken
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function tryGenericSession(cookies) {
|
|
363
|
+
const sessionToken = cookies.get("auth_session") || cookies.get("session");
|
|
364
|
+
if (!sessionToken) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (sessionToken.includes(".")) {
|
|
368
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
369
|
+
if (payload) {
|
|
370
|
+
return {
|
|
371
|
+
userId: payload.sub || payload.userId || payload.user_id || payload.id,
|
|
372
|
+
sessionId: payload.jti || payload.sessionId || payload.sid
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return {
|
|
377
|
+
sessionId: sessionToken
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
async function detectSessionContext(request) {
|
|
381
|
+
const cookies = getCookies(request);
|
|
382
|
+
let context;
|
|
383
|
+
context = tryBetterAuth(cookies);
|
|
384
|
+
if (context?.userId) {
|
|
385
|
+
return context;
|
|
386
|
+
}
|
|
387
|
+
context = tryNextAuth(cookies);
|
|
388
|
+
if (context?.userId) {
|
|
389
|
+
return context;
|
|
390
|
+
}
|
|
391
|
+
context = tryClerk(cookies);
|
|
392
|
+
if (context?.userId) {
|
|
393
|
+
return context;
|
|
394
|
+
}
|
|
395
|
+
context = tryLucia(cookies);
|
|
396
|
+
if (context?.userId) {
|
|
397
|
+
return context;
|
|
398
|
+
}
|
|
399
|
+
context = tryGenericSession(cookies);
|
|
400
|
+
if (context?.userId) {
|
|
401
|
+
return context;
|
|
402
|
+
}
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// src/adapters/context-cookie.ts
|
|
407
|
+
var exports_context_cookie = {};
|
|
408
|
+
__export(exports_context_cookie, {
|
|
409
|
+
readContextCookie: () => readContextCookie,
|
|
410
|
+
getSetCookieHeader: () => getSetCookieHeader,
|
|
411
|
+
getContextCookieFromRequest: () => getContextCookieFromRequest,
|
|
412
|
+
getClearCookieHeader: () => getClearCookieHeader,
|
|
413
|
+
createContextCookie: () => createContextCookie,
|
|
414
|
+
CONTEXT_COOKIE_NAME: () => CONTEXT_COOKIE_NAME,
|
|
415
|
+
CONTEXT_COOKIE_MAX_AGE: () => CONTEXT_COOKIE_MAX_AGE
|
|
416
|
+
});
|
|
417
|
+
async function deriveKey(secret) {
|
|
418
|
+
const encoder = new TextEncoder;
|
|
419
|
+
const secretData = encoder.encode(secret);
|
|
420
|
+
const keyMaterial = await crypto.subtle.importKey("raw", secretData, { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"]);
|
|
421
|
+
const salt = encoder.encode("integrate-oauth-context-v1");
|
|
422
|
+
return await crypto.subtle.deriveKey({
|
|
423
|
+
name: "PBKDF2",
|
|
424
|
+
salt,
|
|
425
|
+
iterations: 1e5,
|
|
426
|
+
hash: "SHA-256"
|
|
427
|
+
}, keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
|
|
428
|
+
}
|
|
429
|
+
async function encryptPayload(payload, secret) {
|
|
430
|
+
const key = await deriveKey(secret);
|
|
431
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
432
|
+
const encoder = new TextEncoder;
|
|
433
|
+
const data = encoder.encode(JSON.stringify(payload));
|
|
434
|
+
const encrypted = await crypto.subtle.encrypt({
|
|
435
|
+
name: "AES-GCM",
|
|
436
|
+
iv
|
|
437
|
+
}, key, data);
|
|
438
|
+
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
439
|
+
combined.set(iv, 0);
|
|
440
|
+
combined.set(new Uint8Array(encrypted), iv.length);
|
|
441
|
+
return base64UrlEncode2(combined);
|
|
442
|
+
}
|
|
443
|
+
async function decryptPayload(cookieValue, secret) {
|
|
444
|
+
try {
|
|
445
|
+
const combined = base64UrlDecode2(cookieValue);
|
|
446
|
+
const iv = combined.slice(0, 12);
|
|
447
|
+
const encrypted = combined.slice(12);
|
|
448
|
+
const key = await deriveKey(secret);
|
|
449
|
+
const decrypted = await crypto.subtle.decrypt({
|
|
450
|
+
name: "AES-GCM",
|
|
451
|
+
iv
|
|
452
|
+
}, key, encrypted);
|
|
453
|
+
const decoder = new TextDecoder;
|
|
454
|
+
const json = decoder.decode(decrypted);
|
|
455
|
+
const payload = JSON.parse(json);
|
|
456
|
+
const age = Date.now() - payload.timestamp;
|
|
457
|
+
if (age > CONTEXT_COOKIE_MAX_AGE * 1000) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
return payload;
|
|
461
|
+
} catch (error) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function base64UrlEncode2(data) {
|
|
466
|
+
const base64 = btoa(String.fromCharCode(...data));
|
|
467
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
468
|
+
}
|
|
469
|
+
function base64UrlDecode2(str) {
|
|
470
|
+
let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
471
|
+
const padding = base64.length % 4;
|
|
472
|
+
if (padding) {
|
|
473
|
+
base64 += "=".repeat(4 - padding);
|
|
474
|
+
}
|
|
475
|
+
const binary = atob(base64);
|
|
476
|
+
const bytes = new Uint8Array(binary.length);
|
|
477
|
+
for (let i = 0;i < binary.length; i++) {
|
|
478
|
+
bytes[i] = binary.charCodeAt(i);
|
|
479
|
+
}
|
|
480
|
+
return bytes;
|
|
481
|
+
}
|
|
482
|
+
async function createContextCookie(context, provider, secret) {
|
|
483
|
+
const payload = {
|
|
484
|
+
context,
|
|
485
|
+
provider,
|
|
486
|
+
timestamp: Date.now()
|
|
487
|
+
};
|
|
488
|
+
return await encryptPayload(payload, secret);
|
|
489
|
+
}
|
|
490
|
+
async function readContextCookie(cookieValue, secret) {
|
|
491
|
+
const payload = await decryptPayload(cookieValue, secret);
|
|
492
|
+
if (!payload) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
return {
|
|
496
|
+
context: payload.context,
|
|
497
|
+
provider: payload.provider
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
function getSetCookieHeader(cookieValue, maxAge = CONTEXT_COOKIE_MAX_AGE) {
|
|
501
|
+
const attributes = [
|
|
502
|
+
`${CONTEXT_COOKIE_NAME}=${cookieValue}`,
|
|
503
|
+
`Max-Age=${maxAge}`,
|
|
504
|
+
"HttpOnly",
|
|
505
|
+
"Secure",
|
|
506
|
+
"SameSite=Lax",
|
|
507
|
+
"Path=/"
|
|
508
|
+
];
|
|
509
|
+
return attributes.join("; ");
|
|
510
|
+
}
|
|
511
|
+
function getClearCookieHeader() {
|
|
512
|
+
const attributes = [
|
|
513
|
+
`${CONTEXT_COOKIE_NAME}=`,
|
|
514
|
+
"Max-Age=0",
|
|
515
|
+
"HttpOnly",
|
|
516
|
+
"Secure",
|
|
517
|
+
"SameSite=Lax",
|
|
518
|
+
"Path=/"
|
|
519
|
+
];
|
|
520
|
+
return attributes.join("; ");
|
|
521
|
+
}
|
|
522
|
+
function getContextCookieFromRequest(request) {
|
|
523
|
+
const cookieHeader = request.headers.get("cookie");
|
|
524
|
+
if (!cookieHeader) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
const cookies = cookieHeader.split(";");
|
|
528
|
+
for (const cookie of cookies) {
|
|
529
|
+
const [name, ...valueParts] = cookie.split("=");
|
|
530
|
+
if (name && name.trim() === CONTEXT_COOKIE_NAME) {
|
|
531
|
+
return valueParts.join("=").trim();
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
var CONTEXT_COOKIE_NAME = "__integrate_oauth_ctx", CONTEXT_COOKIE_MAX_AGE = 300;
|
|
537
|
+
|
|
264
538
|
// src/adapters/base-handler.ts
|
|
265
539
|
var exports_base_handler = {};
|
|
266
540
|
__export(exports_base_handler, {
|
|
@@ -289,25 +563,35 @@ class OAuthHandler {
|
|
|
289
563
|
return headers;
|
|
290
564
|
}
|
|
291
565
|
async handleAuthorize(request) {
|
|
292
|
-
|
|
566
|
+
let webRequest;
|
|
567
|
+
let authorizeRequest;
|
|
568
|
+
if (request instanceof Request) {
|
|
569
|
+
webRequest = request;
|
|
570
|
+
authorizeRequest = await request.json();
|
|
571
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
572
|
+
authorizeRequest = await request.json();
|
|
573
|
+
} else {
|
|
574
|
+
authorizeRequest = request;
|
|
575
|
+
}
|
|
576
|
+
const providerConfig = this.config.providers[authorizeRequest.provider];
|
|
293
577
|
if (!providerConfig) {
|
|
294
|
-
throw new Error(`Provider ${
|
|
578
|
+
throw new Error(`Provider ${authorizeRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
295
579
|
}
|
|
296
580
|
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
297
|
-
throw new Error(`Missing OAuth credentials for ${
|
|
581
|
+
throw new Error(`Missing OAuth credentials for ${authorizeRequest.provider}. Check your environment variables.`);
|
|
298
582
|
}
|
|
299
583
|
const url = new URL("/oauth/authorize", this.serverUrl);
|
|
300
|
-
url.searchParams.set("provider",
|
|
584
|
+
url.searchParams.set("provider", authorizeRequest.provider);
|
|
301
585
|
url.searchParams.set("client_id", providerConfig.clientId);
|
|
302
586
|
url.searchParams.set("client_secret", providerConfig.clientSecret);
|
|
303
|
-
const scopes =
|
|
587
|
+
const scopes = authorizeRequest.scopes || providerConfig.scopes || [];
|
|
304
588
|
if (scopes.length > 0) {
|
|
305
589
|
url.searchParams.set("scope", scopes.join(","));
|
|
306
590
|
}
|
|
307
|
-
url.searchParams.set("state",
|
|
308
|
-
url.searchParams.set("code_challenge",
|
|
309
|
-
url.searchParams.set("code_challenge_method",
|
|
310
|
-
const redirectUri =
|
|
591
|
+
url.searchParams.set("state", authorizeRequest.state);
|
|
592
|
+
url.searchParams.set("code_challenge", authorizeRequest.codeChallenge);
|
|
593
|
+
url.searchParams.set("code_challenge_method", authorizeRequest.codeChallengeMethod);
|
|
594
|
+
const redirectUri = authorizeRequest.redirectUri || providerConfig.redirectUri;
|
|
311
595
|
if (redirectUri) {
|
|
312
596
|
url.searchParams.set("redirect_uri", redirectUri);
|
|
313
597
|
}
|
|
@@ -320,15 +604,62 @@ class OAuthHandler {
|
|
|
320
604
|
throw new Error(`MCP server failed to generate authorization URL: ${error}`);
|
|
321
605
|
}
|
|
322
606
|
const data = await response.json();
|
|
323
|
-
|
|
607
|
+
const result = data;
|
|
608
|
+
if (webRequest) {
|
|
609
|
+
try {
|
|
610
|
+
const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
|
|
611
|
+
const { createContextCookie: createContextCookie2, getSetCookieHeader: getSetCookieHeader2 } = await Promise.resolve().then(() => exports_context_cookie);
|
|
612
|
+
let context;
|
|
613
|
+
if (this.config.getSessionContext) {
|
|
614
|
+
context = await this.config.getSessionContext(webRequest);
|
|
615
|
+
}
|
|
616
|
+
if (!context || !context.userId) {
|
|
617
|
+
context = await detectSessionContext2(webRequest);
|
|
618
|
+
}
|
|
619
|
+
if (context && context.userId) {
|
|
620
|
+
const secret = this.apiKey || providerConfig.clientSecret;
|
|
621
|
+
const cookieValue = await createContextCookie2(context, authorizeRequest.provider, secret);
|
|
622
|
+
result.setCookie = getSetCookieHeader2(cookieValue);
|
|
623
|
+
}
|
|
624
|
+
} catch (error) {
|
|
625
|
+
console.warn("[OAuth] Failed to capture user context:", error);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return result;
|
|
324
629
|
}
|
|
325
630
|
async handleCallback(request) {
|
|
326
|
-
|
|
631
|
+
let webRequest;
|
|
632
|
+
let callbackRequest;
|
|
633
|
+
if (request instanceof Request) {
|
|
634
|
+
webRequest = request;
|
|
635
|
+
callbackRequest = await request.json();
|
|
636
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
637
|
+
callbackRequest = await request.json();
|
|
638
|
+
} else {
|
|
639
|
+
callbackRequest = request;
|
|
640
|
+
}
|
|
641
|
+
const providerConfig = this.config.providers[callbackRequest.provider];
|
|
327
642
|
if (!providerConfig) {
|
|
328
|
-
throw new Error(`Provider ${
|
|
643
|
+
throw new Error(`Provider ${callbackRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
329
644
|
}
|
|
330
645
|
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
331
|
-
throw new Error(`Missing OAuth credentials for ${
|
|
646
|
+
throw new Error(`Missing OAuth credentials for ${callbackRequest.provider}. Check your environment variables.`);
|
|
647
|
+
}
|
|
648
|
+
let context;
|
|
649
|
+
if (webRequest) {
|
|
650
|
+
try {
|
|
651
|
+
const { getContextCookieFromRequest: getContextCookieFromRequest2, readContextCookie: readContextCookie2 } = await Promise.resolve().then(() => exports_context_cookie);
|
|
652
|
+
const cookieValue = getContextCookieFromRequest2(webRequest);
|
|
653
|
+
if (cookieValue) {
|
|
654
|
+
const secret = this.apiKey || providerConfig.clientSecret;
|
|
655
|
+
const contextData = await readContextCookie2(cookieValue, secret);
|
|
656
|
+
if (contextData && contextData.provider === callbackRequest.provider) {
|
|
657
|
+
context = contextData.context;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
} catch (error) {
|
|
661
|
+
console.warn("[OAuth] Failed to restore user context:", error);
|
|
662
|
+
}
|
|
332
663
|
}
|
|
333
664
|
const url = new URL("/oauth/callback", this.serverUrl);
|
|
334
665
|
const response = await fetch(url.toString(), {
|
|
@@ -337,10 +668,10 @@ class OAuthHandler {
|
|
|
337
668
|
"Content-Type": "application/json"
|
|
338
669
|
}),
|
|
339
670
|
body: JSON.stringify({
|
|
340
|
-
provider:
|
|
341
|
-
code:
|
|
342
|
-
code_verifier:
|
|
343
|
-
state:
|
|
671
|
+
provider: callbackRequest.provider,
|
|
672
|
+
code: callbackRequest.code,
|
|
673
|
+
code_verifier: callbackRequest.codeVerifier,
|
|
674
|
+
state: callbackRequest.state,
|
|
344
675
|
client_id: providerConfig.clientId,
|
|
345
676
|
client_secret: providerConfig.clientSecret,
|
|
346
677
|
redirect_uri: providerConfig.redirectUri
|
|
@@ -351,7 +682,26 @@ class OAuthHandler {
|
|
|
351
682
|
throw new Error(`MCP server failed to exchange authorization code: ${error}`);
|
|
352
683
|
}
|
|
353
684
|
const data = await response.json();
|
|
354
|
-
|
|
685
|
+
const result = data;
|
|
686
|
+
if (this.config.setProviderToken && context) {
|
|
687
|
+
try {
|
|
688
|
+
const tokenData = {
|
|
689
|
+
accessToken: result.accessToken,
|
|
690
|
+
refreshToken: result.refreshToken,
|
|
691
|
+
tokenType: result.tokenType,
|
|
692
|
+
expiresIn: result.expiresIn,
|
|
693
|
+
expiresAt: result.expiresAt
|
|
694
|
+
};
|
|
695
|
+
await this.config.setProviderToken(callbackRequest.provider, tokenData, context);
|
|
696
|
+
} catch (error) {
|
|
697
|
+
console.error("[OAuth] Failed to save provider token:", error);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
if (webRequest) {
|
|
701
|
+
const { getClearCookieHeader: getClearCookieHeader2 } = await Promise.resolve().then(() => exports_context_cookie);
|
|
702
|
+
result.clearCookie = getClearCookieHeader2();
|
|
703
|
+
}
|
|
704
|
+
return result;
|
|
355
705
|
}
|
|
356
706
|
async handleStatus(provider, accessToken) {
|
|
357
707
|
const url = new URL("/oauth/status", this.serverUrl);
|
|
@@ -1667,9 +2017,12 @@ function createNextOAuthHandler(config) {
|
|
|
1667
2017
|
const handlers = {
|
|
1668
2018
|
async authorize(req) {
|
|
1669
2019
|
try {
|
|
1670
|
-
const
|
|
1671
|
-
const
|
|
1672
|
-
|
|
2020
|
+
const result = await handler.handleAuthorize(req);
|
|
2021
|
+
const response = Response.json(result);
|
|
2022
|
+
if (result.setCookie) {
|
|
2023
|
+
response.headers.set("Set-Cookie", result.setCookie);
|
|
2024
|
+
}
|
|
2025
|
+
return response;
|
|
1673
2026
|
} catch (error) {
|
|
1674
2027
|
console.error("[OAuth Authorize] Error:", error);
|
|
1675
2028
|
return Response.json({ error: error.message || "Failed to get authorization URL" }, { status: 500 });
|
|
@@ -1677,9 +2030,12 @@ function createNextOAuthHandler(config) {
|
|
|
1677
2030
|
},
|
|
1678
2031
|
async callback(req) {
|
|
1679
2032
|
try {
|
|
1680
|
-
const
|
|
1681
|
-
const
|
|
1682
|
-
|
|
2033
|
+
const result = await handler.handleCallback(req);
|
|
2034
|
+
const response = Response.json(result);
|
|
2035
|
+
if (result.clearCookie) {
|
|
2036
|
+
response.headers.set("Set-Cookie", result.clearCookie);
|
|
2037
|
+
}
|
|
2038
|
+
return response;
|
|
1683
2039
|
} catch (error) {
|
|
1684
2040
|
console.error("[OAuth Callback] Error:", error);
|
|
1685
2041
|
return Response.json({ error: error.message || "Failed to exchange authorization code" }, { status: 500 });
|
|
@@ -2034,12 +2390,16 @@ function createMCPServer(config) {
|
|
|
2034
2390
|
client.__oauthConfig = {
|
|
2035
2391
|
providers,
|
|
2036
2392
|
serverUrl: config.serverUrl,
|
|
2037
|
-
apiKey: config.apiKey
|
|
2393
|
+
apiKey: config.apiKey,
|
|
2394
|
+
getSessionContext: config.getSessionContext,
|
|
2395
|
+
setProviderToken: config.setProviderToken
|
|
2038
2396
|
};
|
|
2039
2397
|
const { POST, GET } = createOAuthRouteHandlers({
|
|
2040
2398
|
providers,
|
|
2041
2399
|
serverUrl: config.serverUrl,
|
|
2042
|
-
apiKey: config.apiKey
|
|
2400
|
+
apiKey: config.apiKey,
|
|
2401
|
+
getSessionContext: config.getSessionContext,
|
|
2402
|
+
setProviderToken: config.setProviderToken
|
|
2043
2403
|
});
|
|
2044
2404
|
const handler = async (request, context) => {
|
|
2045
2405
|
const method = request.method.toUpperCase();
|
|
@@ -2200,7 +2560,9 @@ function toNextJsHandler(clientOrOptions, redirectOptions) {
|
|
|
2200
2560
|
config = {
|
|
2201
2561
|
providers: options.providers,
|
|
2202
2562
|
serverUrl: options.serverUrl,
|
|
2203
|
-
apiKey: options.apiKey
|
|
2563
|
+
apiKey: options.apiKey,
|
|
2564
|
+
getSessionContext: options.getSessionContext,
|
|
2565
|
+
setProviderToken: options.setProviderToken
|
|
2204
2566
|
};
|
|
2205
2567
|
redirectUrl = options.redirectUrl;
|
|
2206
2568
|
errorRedirectUrl = options.errorRedirectUrl;
|
|
@@ -2341,6 +2703,171 @@ function toSvelteKitHandler(clientOrHandlerOrOptions, _redirectOptions) {
|
|
|
2341
2703
|
}
|
|
2342
2704
|
};
|
|
2343
2705
|
}
|
|
2706
|
+
// src/adapters/node.ts
|
|
2707
|
+
function fromNodeHeaders(nodeHeaders) {
|
|
2708
|
+
const webHeaders = new Headers;
|
|
2709
|
+
for (const [key, value] of Object.entries(nodeHeaders)) {
|
|
2710
|
+
if (value !== undefined) {
|
|
2711
|
+
if (Array.isArray(value)) {
|
|
2712
|
+
value.forEach((v) => webHeaders.append(key, v));
|
|
2713
|
+
} else {
|
|
2714
|
+
webHeaders.set(key, value);
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
return webHeaders;
|
|
2719
|
+
}
|
|
2720
|
+
async function toWebRequest(req) {
|
|
2721
|
+
const protocol = req.socket.encrypted ? "https" : "http";
|
|
2722
|
+
const host = req.headers.host || "localhost";
|
|
2723
|
+
const url = `${protocol}://${host}${req.url}`;
|
|
2724
|
+
const headers = fromNodeHeaders(req.headers);
|
|
2725
|
+
let body;
|
|
2726
|
+
if (req.method && ["POST", "PUT", "PATCH"].includes(req.method)) {
|
|
2727
|
+
body = await new Promise((resolve, reject) => {
|
|
2728
|
+
let data = "";
|
|
2729
|
+
req.on("data", (chunk) => data += chunk);
|
|
2730
|
+
req.on("end", () => resolve(data));
|
|
2731
|
+
req.on("error", reject);
|
|
2732
|
+
});
|
|
2733
|
+
}
|
|
2734
|
+
return new Request(url, {
|
|
2735
|
+
method: req.method,
|
|
2736
|
+
headers,
|
|
2737
|
+
body: body || undefined
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2740
|
+
async function sendWebResponse(webRes, nodeRes) {
|
|
2741
|
+
nodeRes.statusCode = webRes.status;
|
|
2742
|
+
webRes.headers.forEach((value, key) => {
|
|
2743
|
+
nodeRes.setHeader(key, value);
|
|
2744
|
+
});
|
|
2745
|
+
const body = await webRes.text();
|
|
2746
|
+
nodeRes.end(body);
|
|
2747
|
+
}
|
|
2748
|
+
function toNodeHandler(config) {
|
|
2749
|
+
const oauthHandler = new OAuthHandler(config);
|
|
2750
|
+
return async (req, res) => {
|
|
2751
|
+
try {
|
|
2752
|
+
const webReq = await toWebRequest(req);
|
|
2753
|
+
const url = new URL(webReq.url);
|
|
2754
|
+
const segments = url.pathname.split("/").filter(Boolean);
|
|
2755
|
+
const action = segments[segments.length - 1];
|
|
2756
|
+
let webRes;
|
|
2757
|
+
if (req.method === "POST") {
|
|
2758
|
+
if (action === "authorize") {
|
|
2759
|
+
const result = await oauthHandler.handleAuthorize(webReq);
|
|
2760
|
+
const headers = { "Content-Type": "application/json" };
|
|
2761
|
+
if (result.setCookie) {
|
|
2762
|
+
headers["Set-Cookie"] = result.setCookie;
|
|
2763
|
+
}
|
|
2764
|
+
webRes = new Response(JSON.stringify(result), {
|
|
2765
|
+
status: 200,
|
|
2766
|
+
headers
|
|
2767
|
+
});
|
|
2768
|
+
} else if (action === "callback") {
|
|
2769
|
+
const result = await oauthHandler.handleCallback(webReq);
|
|
2770
|
+
const headers = { "Content-Type": "application/json" };
|
|
2771
|
+
if (result.clearCookie) {
|
|
2772
|
+
headers["Set-Cookie"] = result.clearCookie;
|
|
2773
|
+
}
|
|
2774
|
+
webRes = new Response(JSON.stringify(result), {
|
|
2775
|
+
status: 200,
|
|
2776
|
+
headers
|
|
2777
|
+
});
|
|
2778
|
+
} else if (action === "disconnect") {
|
|
2779
|
+
const authHeader = webReq.headers.get("authorization");
|
|
2780
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
2781
|
+
webRes = new Response(JSON.stringify({ error: "Missing or invalid Authorization header" }), {
|
|
2782
|
+
status: 400,
|
|
2783
|
+
headers: { "Content-Type": "application/json" }
|
|
2784
|
+
});
|
|
2785
|
+
} else {
|
|
2786
|
+
const accessToken = authHeader.substring(7);
|
|
2787
|
+
const body = await webReq.json();
|
|
2788
|
+
const { provider } = body;
|
|
2789
|
+
if (!provider) {
|
|
2790
|
+
webRes = new Response(JSON.stringify({ error: "Missing provider in request body" }), {
|
|
2791
|
+
status: 400,
|
|
2792
|
+
headers: { "Content-Type": "application/json" }
|
|
2793
|
+
});
|
|
2794
|
+
} else {
|
|
2795
|
+
const result = await oauthHandler.handleDisconnect({ provider }, accessToken);
|
|
2796
|
+
webRes = new Response(JSON.stringify(result), {
|
|
2797
|
+
status: 200,
|
|
2798
|
+
headers: { "Content-Type": "application/json" }
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
} else {
|
|
2803
|
+
webRes = new Response(JSON.stringify({ error: `Unknown action: ${action}` }), {
|
|
2804
|
+
status: 404,
|
|
2805
|
+
headers: { "Content-Type": "application/json" }
|
|
2806
|
+
});
|
|
2807
|
+
}
|
|
2808
|
+
} else if (req.method === "GET" && action === "status") {
|
|
2809
|
+
const provider = url.searchParams.get("provider");
|
|
2810
|
+
const authHeader = webReq.headers.get("authorization");
|
|
2811
|
+
if (!provider) {
|
|
2812
|
+
webRes = new Response(JSON.stringify({ error: "Missing provider query parameter" }), {
|
|
2813
|
+
status: 400,
|
|
2814
|
+
headers: { "Content-Type": "application/json" }
|
|
2815
|
+
});
|
|
2816
|
+
} else if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
2817
|
+
webRes = new Response(JSON.stringify({ error: "Missing or invalid Authorization header" }), {
|
|
2818
|
+
status: 400,
|
|
2819
|
+
headers: { "Content-Type": "application/json" }
|
|
2820
|
+
});
|
|
2821
|
+
} else {
|
|
2822
|
+
const accessToken = authHeader.substring(7);
|
|
2823
|
+
const result = await oauthHandler.handleStatus(provider, accessToken);
|
|
2824
|
+
webRes = new Response(JSON.stringify(result), {
|
|
2825
|
+
status: 200,
|
|
2826
|
+
headers: { "Content-Type": "application/json" }
|
|
2827
|
+
});
|
|
2828
|
+
}
|
|
2829
|
+
} else {
|
|
2830
|
+
webRes = new Response(JSON.stringify({ error: `Unknown action: ${action}` }), {
|
|
2831
|
+
status: 404,
|
|
2832
|
+
headers: { "Content-Type": "application/json" }
|
|
2833
|
+
});
|
|
2834
|
+
}
|
|
2835
|
+
await sendWebResponse(webRes, res);
|
|
2836
|
+
} catch (error) {
|
|
2837
|
+
console.error("[OAuth Handler] Error:", error);
|
|
2838
|
+
const errorRes = new Response(JSON.stringify({ error: error.message || "Internal server error" }), {
|
|
2839
|
+
status: 500,
|
|
2840
|
+
headers: { "Content-Type": "application/json" }
|
|
2841
|
+
});
|
|
2842
|
+
await sendWebResponse(errorRes, res);
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2845
|
+
}
|
|
2846
|
+
// src/adapters/svelte-kit.ts
|
|
2847
|
+
async function svelteKitHandler({
|
|
2848
|
+
authConfig,
|
|
2849
|
+
event,
|
|
2850
|
+
resolve,
|
|
2851
|
+
basePath = "/api/integrate"
|
|
2852
|
+
}) {
|
|
2853
|
+
const { url } = event;
|
|
2854
|
+
const baseUrl = new URL(basePath, url.origin);
|
|
2855
|
+
if (!url.pathname.startsWith(baseUrl.pathname)) {
|
|
2856
|
+
return resolve(event);
|
|
2857
|
+
}
|
|
2858
|
+
return authConfig(event.request);
|
|
2859
|
+
}
|
|
2860
|
+
// src/adapters/tanstack-start.ts
|
|
2861
|
+
function toTanStackStartHandler(handler) {
|
|
2862
|
+
const baseHandler = async ({ request }) => {
|
|
2863
|
+
return handler(request);
|
|
2864
|
+
};
|
|
2865
|
+
return {
|
|
2866
|
+
GET: baseHandler,
|
|
2867
|
+
POST: baseHandler
|
|
2868
|
+
};
|
|
2869
|
+
}
|
|
2870
|
+
var createTanStackOAuthHandler = toTanStackStartHandler;
|
|
2344
2871
|
// node_modules/zod/v3/external.js
|
|
2345
2872
|
var exports_external = {};
|
|
2346
2873
|
__export(exports_external, {
|
|
@@ -6362,13 +6889,6 @@ async function getProviderTokens(manualTokens) {
|
|
|
6362
6889
|
}
|
|
6363
6890
|
throw new Error("Provider tokens not found. Please pass tokens manually via options.providerTokens or set the x-integrate-tokens header in your request.");
|
|
6364
6891
|
}
|
|
6365
|
-
async function tryGetProviderTokens(manualTokens) {
|
|
6366
|
-
try {
|
|
6367
|
-
return await getProviderTokens(manualTokens);
|
|
6368
|
-
} catch {
|
|
6369
|
-
return null;
|
|
6370
|
-
}
|
|
6371
|
-
}
|
|
6372
6892
|
|
|
6373
6893
|
// src/ai/utils.ts
|
|
6374
6894
|
function getProviderForTool(client, toolName) {
|
|
@@ -6580,49 +7100,6 @@ async function getOpenAITools(client, options) {
|
|
|
6580
7100
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
6581
7101
|
return convertMCPToolsToOpenAI(client, finalOptions);
|
|
6582
7102
|
}
|
|
6583
|
-
async function handleOpenAIToolCalls(client, toolCalls, options) {
|
|
6584
|
-
const toolOutputs = [];
|
|
6585
|
-
for (const output of toolCalls) {
|
|
6586
|
-
if (output.type === "function_call") {
|
|
6587
|
-
const toolCall = {
|
|
6588
|
-
id: output.id ?? "",
|
|
6589
|
-
name: output.name,
|
|
6590
|
-
arguments: output.arguments
|
|
6591
|
-
};
|
|
6592
|
-
try {
|
|
6593
|
-
const result = await executeOpenAIToolCall(client, toolCall, options);
|
|
6594
|
-
toolOutputs.push({
|
|
6595
|
-
call_id: output.call_id ?? output.id ?? "",
|
|
6596
|
-
type: "function_call_output",
|
|
6597
|
-
output: result,
|
|
6598
|
-
status: "completed"
|
|
6599
|
-
});
|
|
6600
|
-
} catch (error) {
|
|
6601
|
-
toolOutputs.push({
|
|
6602
|
-
call_id: output.call_id ?? output.id ?? "",
|
|
6603
|
-
type: "function_call_output",
|
|
6604
|
-
output: error instanceof Error ? error.message : "Unknown error",
|
|
6605
|
-
status: "incomplete"
|
|
6606
|
-
});
|
|
6607
|
-
}
|
|
6608
|
-
}
|
|
6609
|
-
}
|
|
6610
|
-
return toolOutputs;
|
|
6611
|
-
}
|
|
6612
|
-
async function handleOpenAIResponse(client, response, options) {
|
|
6613
|
-
let providerTokens = options?.providerTokens;
|
|
6614
|
-
if (!providerTokens) {
|
|
6615
|
-
try {
|
|
6616
|
-
providerTokens = await getProviderTokens();
|
|
6617
|
-
} catch {}
|
|
6618
|
-
}
|
|
6619
|
-
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
6620
|
-
const functionCalls = response.output.filter((output) => output.type === "function_call");
|
|
6621
|
-
if (functionCalls.length === 0) {
|
|
6622
|
-
return response;
|
|
6623
|
-
}
|
|
6624
|
-
return handleOpenAIToolCalls(client, functionCalls, finalOptions);
|
|
6625
|
-
}
|
|
6626
7103
|
// src/ai/anthropic.ts
|
|
6627
7104
|
function convertMCPToolToAnthropic(mcpTool, _client, _options) {
|
|
6628
7105
|
return {
|
|
@@ -6643,29 +7120,6 @@ async function executeAnthropicToolCall(client, toolUse, options) {
|
|
|
6643
7120
|
const result = await executeToolWithToken(client, toolUse.name, toolUse.input, options);
|
|
6644
7121
|
return JSON.stringify(result);
|
|
6645
7122
|
}
|
|
6646
|
-
async function handleAnthropicToolCalls(client, messageContent, options) {
|
|
6647
|
-
const toolResults = [];
|
|
6648
|
-
const toolUseBlocks = messageContent.filter((block) => block.type === "tool_use" && ("id" in block) && ("name" in block) && ("input" in block));
|
|
6649
|
-
for (const toolUse of toolUseBlocks) {
|
|
6650
|
-
try {
|
|
6651
|
-
const result = await executeAnthropicToolCall(client, toolUse, options);
|
|
6652
|
-
toolResults.push({
|
|
6653
|
-
type: "tool_result",
|
|
6654
|
-
tool_use_id: toolUse.id,
|
|
6655
|
-
content: result
|
|
6656
|
-
});
|
|
6657
|
-
} catch (error) {
|
|
6658
|
-
toolResults.push({
|
|
6659
|
-
type: "tool_result",
|
|
6660
|
-
tool_use_id: toolUse.id,
|
|
6661
|
-
content: JSON.stringify({
|
|
6662
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
6663
|
-
})
|
|
6664
|
-
});
|
|
6665
|
-
}
|
|
6666
|
-
}
|
|
6667
|
-
return toolResults;
|
|
6668
|
-
}
|
|
6669
7123
|
async function getAnthropicTools(client, options) {
|
|
6670
7124
|
await ensureClientConnected(client);
|
|
6671
7125
|
let providerTokens = options?.providerTokens;
|
|
@@ -6677,29 +7131,14 @@ async function getAnthropicTools(client, options) {
|
|
|
6677
7131
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
6678
7132
|
return convertMCPToolsToAnthropic(client, finalOptions);
|
|
6679
7133
|
}
|
|
6680
|
-
async function handleAnthropicMessage(client, message, options) {
|
|
6681
|
-
let providerTokens = options?.providerTokens;
|
|
6682
|
-
if (!providerTokens) {
|
|
6683
|
-
try {
|
|
6684
|
-
providerTokens = await getProviderTokens();
|
|
6685
|
-
} catch {}
|
|
6686
|
-
}
|
|
6687
|
-
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
6688
|
-
const toolResults = await handleAnthropicToolCalls(client, message.content, finalOptions);
|
|
6689
|
-
if (toolResults.length === 0) {
|
|
6690
|
-
return [];
|
|
6691
|
-
}
|
|
6692
|
-
return [
|
|
6693
|
-
{
|
|
6694
|
-
role: "user",
|
|
6695
|
-
content: toolResults
|
|
6696
|
-
}
|
|
6697
|
-
];
|
|
6698
|
-
}
|
|
6699
7134
|
// src/ai/google.ts
|
|
6700
7135
|
async function getGoogleType() {
|
|
6701
|
-
const
|
|
6702
|
-
|
|
7136
|
+
const packageName = ["@google", "genai"].join("/");
|
|
7137
|
+
const googleGenAI = await import(packageName).catch(() => null);
|
|
7138
|
+
if (!googleGenAI) {
|
|
7139
|
+
throw new Error("The @google/genai package is required to use Google AI integration. Install it with: npm install @google/genai");
|
|
7140
|
+
}
|
|
7141
|
+
return googleGenAI.Type;
|
|
6703
7142
|
}
|
|
6704
7143
|
function convertJsonSchemaTypeToGoogleType(type, TypeEnum) {
|
|
6705
7144
|
const typeMap = {
|
|
@@ -6951,183 +7390,16 @@ async function getAITools(client, provider, options) {
|
|
|
6951
7390
|
throw new Error(`Unsupported AI provider: ${provider}`);
|
|
6952
7391
|
}
|
|
6953
7392
|
}
|
|
6954
|
-
// src/adapters/node.ts
|
|
6955
|
-
function fromNodeHeaders(nodeHeaders) {
|
|
6956
|
-
const webHeaders = new Headers;
|
|
6957
|
-
for (const [key, value] of Object.entries(nodeHeaders)) {
|
|
6958
|
-
if (value !== undefined) {
|
|
6959
|
-
if (Array.isArray(value)) {
|
|
6960
|
-
value.forEach((v) => webHeaders.append(key, v));
|
|
6961
|
-
} else {
|
|
6962
|
-
webHeaders.set(key, value);
|
|
6963
|
-
}
|
|
6964
|
-
}
|
|
6965
|
-
}
|
|
6966
|
-
return webHeaders;
|
|
6967
|
-
}
|
|
6968
|
-
async function toWebRequest(req) {
|
|
6969
|
-
const protocol = req.socket.encrypted ? "https" : "http";
|
|
6970
|
-
const host = req.headers.host || "localhost";
|
|
6971
|
-
const url = `${protocol}://${host}${req.url}`;
|
|
6972
|
-
const headers = fromNodeHeaders(req.headers);
|
|
6973
|
-
let body;
|
|
6974
|
-
if (req.method && ["POST", "PUT", "PATCH"].includes(req.method)) {
|
|
6975
|
-
body = await new Promise((resolve, reject) => {
|
|
6976
|
-
let data = "";
|
|
6977
|
-
req.on("data", (chunk) => data += chunk);
|
|
6978
|
-
req.on("end", () => resolve(data));
|
|
6979
|
-
req.on("error", reject);
|
|
6980
|
-
});
|
|
6981
|
-
}
|
|
6982
|
-
return new Request(url, {
|
|
6983
|
-
method: req.method,
|
|
6984
|
-
headers,
|
|
6985
|
-
body: body || undefined
|
|
6986
|
-
});
|
|
6987
|
-
}
|
|
6988
|
-
async function sendWebResponse(webRes, nodeRes) {
|
|
6989
|
-
nodeRes.statusCode = webRes.status;
|
|
6990
|
-
webRes.headers.forEach((value, key) => {
|
|
6991
|
-
nodeRes.setHeader(key, value);
|
|
6992
|
-
});
|
|
6993
|
-
const body = await webRes.text();
|
|
6994
|
-
nodeRes.end(body);
|
|
6995
|
-
}
|
|
6996
|
-
function toNodeHandler(config) {
|
|
6997
|
-
const oauthHandler = new OAuthHandler(config);
|
|
6998
|
-
return async (req, res) => {
|
|
6999
|
-
try {
|
|
7000
|
-
const webReq = await toWebRequest(req);
|
|
7001
|
-
const url = new URL(webReq.url);
|
|
7002
|
-
const segments = url.pathname.split("/").filter(Boolean);
|
|
7003
|
-
const action = segments[segments.length - 1];
|
|
7004
|
-
let webRes;
|
|
7005
|
-
if (req.method === "POST") {
|
|
7006
|
-
if (action === "authorize") {
|
|
7007
|
-
const body = await webReq.json();
|
|
7008
|
-
const result = await oauthHandler.handleAuthorize(body);
|
|
7009
|
-
webRes = new Response(JSON.stringify(result), {
|
|
7010
|
-
status: 200,
|
|
7011
|
-
headers: { "Content-Type": "application/json" }
|
|
7012
|
-
});
|
|
7013
|
-
} else if (action === "callback") {
|
|
7014
|
-
const body = await webReq.json();
|
|
7015
|
-
const result = await oauthHandler.handleCallback(body);
|
|
7016
|
-
webRes = new Response(JSON.stringify(result), {
|
|
7017
|
-
status: 200,
|
|
7018
|
-
headers: { "Content-Type": "application/json" }
|
|
7019
|
-
});
|
|
7020
|
-
} else if (action === "disconnect") {
|
|
7021
|
-
const authHeader = webReq.headers.get("authorization");
|
|
7022
|
-
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
7023
|
-
webRes = new Response(JSON.stringify({ error: "Missing or invalid Authorization header" }), {
|
|
7024
|
-
status: 400,
|
|
7025
|
-
headers: { "Content-Type": "application/json" }
|
|
7026
|
-
});
|
|
7027
|
-
} else {
|
|
7028
|
-
const accessToken = authHeader.substring(7);
|
|
7029
|
-
const body = await webReq.json();
|
|
7030
|
-
const { provider } = body;
|
|
7031
|
-
if (!provider) {
|
|
7032
|
-
webRes = new Response(JSON.stringify({ error: "Missing provider in request body" }), {
|
|
7033
|
-
status: 400,
|
|
7034
|
-
headers: { "Content-Type": "application/json" }
|
|
7035
|
-
});
|
|
7036
|
-
} else {
|
|
7037
|
-
const result = await oauthHandler.handleDisconnect({ provider }, accessToken);
|
|
7038
|
-
webRes = new Response(JSON.stringify(result), {
|
|
7039
|
-
status: 200,
|
|
7040
|
-
headers: { "Content-Type": "application/json" }
|
|
7041
|
-
});
|
|
7042
|
-
}
|
|
7043
|
-
}
|
|
7044
|
-
} else {
|
|
7045
|
-
webRes = new Response(JSON.stringify({ error: `Unknown action: ${action}` }), {
|
|
7046
|
-
status: 404,
|
|
7047
|
-
headers: { "Content-Type": "application/json" }
|
|
7048
|
-
});
|
|
7049
|
-
}
|
|
7050
|
-
} else if (req.method === "GET" && action === "status") {
|
|
7051
|
-
const provider = url.searchParams.get("provider");
|
|
7052
|
-
const authHeader = webReq.headers.get("authorization");
|
|
7053
|
-
if (!provider) {
|
|
7054
|
-
webRes = new Response(JSON.stringify({ error: "Missing provider query parameter" }), {
|
|
7055
|
-
status: 400,
|
|
7056
|
-
headers: { "Content-Type": "application/json" }
|
|
7057
|
-
});
|
|
7058
|
-
} else if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
7059
|
-
webRes = new Response(JSON.stringify({ error: "Missing or invalid Authorization header" }), {
|
|
7060
|
-
status: 400,
|
|
7061
|
-
headers: { "Content-Type": "application/json" }
|
|
7062
|
-
});
|
|
7063
|
-
} else {
|
|
7064
|
-
const accessToken = authHeader.substring(7);
|
|
7065
|
-
const result = await oauthHandler.handleStatus(provider, accessToken);
|
|
7066
|
-
webRes = new Response(JSON.stringify(result), {
|
|
7067
|
-
status: 200,
|
|
7068
|
-
headers: { "Content-Type": "application/json" }
|
|
7069
|
-
});
|
|
7070
|
-
}
|
|
7071
|
-
} else {
|
|
7072
|
-
webRes = new Response(JSON.stringify({ error: `Unknown action: ${action}` }), {
|
|
7073
|
-
status: 404,
|
|
7074
|
-
headers: { "Content-Type": "application/json" }
|
|
7075
|
-
});
|
|
7076
|
-
}
|
|
7077
|
-
await sendWebResponse(webRes, res);
|
|
7078
|
-
} catch (error) {
|
|
7079
|
-
console.error("[OAuth Handler] Error:", error);
|
|
7080
|
-
const errorRes = new Response(JSON.stringify({ error: error.message || "Internal server error" }), {
|
|
7081
|
-
status: 500,
|
|
7082
|
-
headers: { "Content-Type": "application/json" }
|
|
7083
|
-
});
|
|
7084
|
-
await sendWebResponse(errorRes, res);
|
|
7085
|
-
}
|
|
7086
|
-
};
|
|
7087
|
-
}
|
|
7088
|
-
// src/adapters/svelte-kit.ts
|
|
7089
|
-
async function svelteKitHandler({
|
|
7090
|
-
authConfig,
|
|
7091
|
-
event,
|
|
7092
|
-
resolve,
|
|
7093
|
-
basePath = "/api/integrate"
|
|
7094
|
-
}) {
|
|
7095
|
-
const { url } = event;
|
|
7096
|
-
const baseUrl = new URL(basePath, url.origin);
|
|
7097
|
-
if (!url.pathname.startsWith(baseUrl.pathname)) {
|
|
7098
|
-
return resolve(event);
|
|
7099
|
-
}
|
|
7100
|
-
return authConfig(event.request);
|
|
7101
|
-
}
|
|
7102
|
-
// src/adapters/tanstack-start.ts
|
|
7103
|
-
function toTanStackStartHandler(handler) {
|
|
7104
|
-
const baseHandler = async ({ request }) => {
|
|
7105
|
-
return handler(request);
|
|
7106
|
-
};
|
|
7107
|
-
return {
|
|
7108
|
-
GET: baseHandler,
|
|
7109
|
-
POST: baseHandler
|
|
7110
|
-
};
|
|
7111
|
-
}
|
|
7112
|
-
var createTanStackOAuthHandler = toTanStackStartHandler;
|
|
7113
7393
|
export {
|
|
7114
|
-
tryGetProviderTokens,
|
|
7115
7394
|
toTanStackStartHandler,
|
|
7116
7395
|
toSvelteKitHandler,
|
|
7117
7396
|
toSolidStartHandler,
|
|
7118
7397
|
toNodeHandler,
|
|
7119
7398
|
toNextJsHandler,
|
|
7120
7399
|
svelteKitHandler,
|
|
7121
|
-
jsonSchemaToZod,
|
|
7122
|
-
jsonSchemaPropertyToZod,
|
|
7123
|
-
handleOpenAIToolCalls,
|
|
7124
|
-
handleOpenAIResponse,
|
|
7125
|
-
handleAnthropicToolCalls,
|
|
7126
|
-
handleAnthropicMessage,
|
|
7127
7400
|
gmailIntegration,
|
|
7128
7401
|
githubIntegration,
|
|
7129
7402
|
getVercelAITools,
|
|
7130
|
-
getProviderTokens,
|
|
7131
7403
|
getProviderForTool,
|
|
7132
7404
|
getOpenAITools,
|
|
7133
7405
|
getMastraTools,
|
|
@@ -7145,7 +7417,6 @@ export {
|
|
|
7145
7417
|
executeGoogleFunctionCall,
|
|
7146
7418
|
executeCloudflareToolCall,
|
|
7147
7419
|
executeAnthropicToolCall,
|
|
7148
|
-
ensureClientConnected,
|
|
7149
7420
|
createTanStackOAuthHandler,
|
|
7150
7421
|
createSimpleIntegration,
|
|
7151
7422
|
createNextOAuthHandler,
|