integrate-sdk 0.7.48 → 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/index.js +392 -30
- package/dist/oauth.js +380 -24
- package/dist/server.js +401 -33
- 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/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 +1 -1
package/dist/adapters/index.js
CHANGED
|
@@ -10,6 +10,280 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
12
|
|
|
13
|
+
// session-detector.ts
|
|
14
|
+
var exports_session_detector = {};
|
|
15
|
+
__export(exports_session_detector, {
|
|
16
|
+
tryDecodeJWT: () => tryDecodeJWT,
|
|
17
|
+
detectSessionContext: () => detectSessionContext
|
|
18
|
+
});
|
|
19
|
+
function tryDecodeJWT(token) {
|
|
20
|
+
try {
|
|
21
|
+
const parts = token.split(".");
|
|
22
|
+
if (parts.length !== 3) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const payloadPart = parts[1];
|
|
26
|
+
if (!payloadPart) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const base64 = payloadPart.replace(/-/g, "+").replace(/_/g, "/");
|
|
30
|
+
const jsonPayload = decodeURIComponent(atob(base64).split("").map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)).join(""));
|
|
31
|
+
return JSON.parse(jsonPayload);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function getCookies(request) {
|
|
37
|
+
const cookies = new Map;
|
|
38
|
+
const cookieHeader = request.headers.get("cookie");
|
|
39
|
+
if (!cookieHeader) {
|
|
40
|
+
return cookies;
|
|
41
|
+
}
|
|
42
|
+
const pairs = cookieHeader.split(";");
|
|
43
|
+
for (const pair of pairs) {
|
|
44
|
+
const [name, ...valueParts] = pair.split("=");
|
|
45
|
+
if (name && valueParts.length > 0) {
|
|
46
|
+
const trimmedName = name.trim();
|
|
47
|
+
const value = valueParts.join("=").trim();
|
|
48
|
+
cookies.set(trimmedName, value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return cookies;
|
|
52
|
+
}
|
|
53
|
+
function tryBetterAuth(cookies) {
|
|
54
|
+
const sessionToken = cookies.get("better-auth.session_token");
|
|
55
|
+
if (!sessionToken) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
59
|
+
if (!payload) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const userId = payload.sub || payload.userId || payload.user_id || payload.id;
|
|
63
|
+
if (!userId) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
userId,
|
|
68
|
+
sessionId: payload.jti || payload.sessionId
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function tryNextAuth(cookies) {
|
|
72
|
+
const sessionToken = cookies.get("__Secure-next-auth.session-token") || cookies.get("next-auth.session-token");
|
|
73
|
+
if (!sessionToken) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (sessionToken.includes(".")) {
|
|
77
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
78
|
+
if (payload) {
|
|
79
|
+
return {
|
|
80
|
+
userId: payload.sub || payload.userId || payload.user_id || payload.id,
|
|
81
|
+
sessionId: payload.jti
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
function tryClerk(cookies) {
|
|
88
|
+
const sessionToken = cookies.get("__session");
|
|
89
|
+
if (!sessionToken) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
93
|
+
if (!payload) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
userId: payload.sub || payload.userId,
|
|
98
|
+
organizationId: payload.org_id || payload.organizationId,
|
|
99
|
+
sessionId: payload.sid || payload.sessionId
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function tryLucia(cookies) {
|
|
103
|
+
const sessionToken = cookies.get("lucia_session");
|
|
104
|
+
if (!sessionToken) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
sessionId: sessionToken
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function tryGenericSession(cookies) {
|
|
112
|
+
const sessionToken = cookies.get("auth_session") || cookies.get("session");
|
|
113
|
+
if (!sessionToken) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (sessionToken.includes(".")) {
|
|
117
|
+
const payload = tryDecodeJWT(sessionToken);
|
|
118
|
+
if (payload) {
|
|
119
|
+
return {
|
|
120
|
+
userId: payload.sub || payload.userId || payload.user_id || payload.id,
|
|
121
|
+
sessionId: payload.jti || payload.sessionId || payload.sid
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
sessionId: sessionToken
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
async function detectSessionContext(request) {
|
|
130
|
+
const cookies = getCookies(request);
|
|
131
|
+
let context;
|
|
132
|
+
context = tryBetterAuth(cookies);
|
|
133
|
+
if (context?.userId) {
|
|
134
|
+
return context;
|
|
135
|
+
}
|
|
136
|
+
context = tryNextAuth(cookies);
|
|
137
|
+
if (context?.userId) {
|
|
138
|
+
return context;
|
|
139
|
+
}
|
|
140
|
+
context = tryClerk(cookies);
|
|
141
|
+
if (context?.userId) {
|
|
142
|
+
return context;
|
|
143
|
+
}
|
|
144
|
+
context = tryLucia(cookies);
|
|
145
|
+
if (context?.userId) {
|
|
146
|
+
return context;
|
|
147
|
+
}
|
|
148
|
+
context = tryGenericSession(cookies);
|
|
149
|
+
if (context?.userId) {
|
|
150
|
+
return context;
|
|
151
|
+
}
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// context-cookie.ts
|
|
156
|
+
var exports_context_cookie = {};
|
|
157
|
+
__export(exports_context_cookie, {
|
|
158
|
+
readContextCookie: () => readContextCookie,
|
|
159
|
+
getSetCookieHeader: () => getSetCookieHeader,
|
|
160
|
+
getContextCookieFromRequest: () => getContextCookieFromRequest,
|
|
161
|
+
getClearCookieHeader: () => getClearCookieHeader,
|
|
162
|
+
createContextCookie: () => createContextCookie,
|
|
163
|
+
CONTEXT_COOKIE_NAME: () => CONTEXT_COOKIE_NAME,
|
|
164
|
+
CONTEXT_COOKIE_MAX_AGE: () => CONTEXT_COOKIE_MAX_AGE
|
|
165
|
+
});
|
|
166
|
+
async function deriveKey(secret) {
|
|
167
|
+
const encoder = new TextEncoder;
|
|
168
|
+
const secretData = encoder.encode(secret);
|
|
169
|
+
const keyMaterial = await crypto.subtle.importKey("raw", secretData, { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"]);
|
|
170
|
+
const salt = encoder.encode("integrate-oauth-context-v1");
|
|
171
|
+
return await crypto.subtle.deriveKey({
|
|
172
|
+
name: "PBKDF2",
|
|
173
|
+
salt,
|
|
174
|
+
iterations: 1e5,
|
|
175
|
+
hash: "SHA-256"
|
|
176
|
+
}, keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
|
|
177
|
+
}
|
|
178
|
+
async function encryptPayload(payload, secret) {
|
|
179
|
+
const key = await deriveKey(secret);
|
|
180
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
181
|
+
const encoder = new TextEncoder;
|
|
182
|
+
const data = encoder.encode(JSON.stringify(payload));
|
|
183
|
+
const encrypted = await crypto.subtle.encrypt({
|
|
184
|
+
name: "AES-GCM",
|
|
185
|
+
iv
|
|
186
|
+
}, key, data);
|
|
187
|
+
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
188
|
+
combined.set(iv, 0);
|
|
189
|
+
combined.set(new Uint8Array(encrypted), iv.length);
|
|
190
|
+
return base64UrlEncode(combined);
|
|
191
|
+
}
|
|
192
|
+
async function decryptPayload(cookieValue, secret) {
|
|
193
|
+
try {
|
|
194
|
+
const combined = base64UrlDecode(cookieValue);
|
|
195
|
+
const iv = combined.slice(0, 12);
|
|
196
|
+
const encrypted = combined.slice(12);
|
|
197
|
+
const key = await deriveKey(secret);
|
|
198
|
+
const decrypted = await crypto.subtle.decrypt({
|
|
199
|
+
name: "AES-GCM",
|
|
200
|
+
iv
|
|
201
|
+
}, key, encrypted);
|
|
202
|
+
const decoder = new TextDecoder;
|
|
203
|
+
const json = decoder.decode(decrypted);
|
|
204
|
+
const payload = JSON.parse(json);
|
|
205
|
+
const age = Date.now() - payload.timestamp;
|
|
206
|
+
if (age > CONTEXT_COOKIE_MAX_AGE * 1000) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
return payload;
|
|
210
|
+
} catch (error) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function base64UrlEncode(data) {
|
|
215
|
+
const base64 = btoa(String.fromCharCode(...data));
|
|
216
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
217
|
+
}
|
|
218
|
+
function base64UrlDecode(str) {
|
|
219
|
+
let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
220
|
+
const padding = base64.length % 4;
|
|
221
|
+
if (padding) {
|
|
222
|
+
base64 += "=".repeat(4 - padding);
|
|
223
|
+
}
|
|
224
|
+
const binary = atob(base64);
|
|
225
|
+
const bytes = new Uint8Array(binary.length);
|
|
226
|
+
for (let i = 0;i < binary.length; i++) {
|
|
227
|
+
bytes[i] = binary.charCodeAt(i);
|
|
228
|
+
}
|
|
229
|
+
return bytes;
|
|
230
|
+
}
|
|
231
|
+
async function createContextCookie(context, provider, secret) {
|
|
232
|
+
const payload = {
|
|
233
|
+
context,
|
|
234
|
+
provider,
|
|
235
|
+
timestamp: Date.now()
|
|
236
|
+
};
|
|
237
|
+
return await encryptPayload(payload, secret);
|
|
238
|
+
}
|
|
239
|
+
async function readContextCookie(cookieValue, secret) {
|
|
240
|
+
const payload = await decryptPayload(cookieValue, secret);
|
|
241
|
+
if (!payload) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
context: payload.context,
|
|
246
|
+
provider: payload.provider
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function getSetCookieHeader(cookieValue, maxAge = CONTEXT_COOKIE_MAX_AGE) {
|
|
250
|
+
const attributes = [
|
|
251
|
+
`${CONTEXT_COOKIE_NAME}=${cookieValue}`,
|
|
252
|
+
`Max-Age=${maxAge}`,
|
|
253
|
+
"HttpOnly",
|
|
254
|
+
"Secure",
|
|
255
|
+
"SameSite=Lax",
|
|
256
|
+
"Path=/"
|
|
257
|
+
];
|
|
258
|
+
return attributes.join("; ");
|
|
259
|
+
}
|
|
260
|
+
function getClearCookieHeader() {
|
|
261
|
+
const attributes = [
|
|
262
|
+
`${CONTEXT_COOKIE_NAME}=`,
|
|
263
|
+
"Max-Age=0",
|
|
264
|
+
"HttpOnly",
|
|
265
|
+
"Secure",
|
|
266
|
+
"SameSite=Lax",
|
|
267
|
+
"Path=/"
|
|
268
|
+
];
|
|
269
|
+
return attributes.join("; ");
|
|
270
|
+
}
|
|
271
|
+
function getContextCookieFromRequest(request) {
|
|
272
|
+
const cookieHeader = request.headers.get("cookie");
|
|
273
|
+
if (!cookieHeader) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const cookies = cookieHeader.split(";");
|
|
277
|
+
for (const cookie of cookies) {
|
|
278
|
+
const [name, ...valueParts] = cookie.split("=");
|
|
279
|
+
if (name && name.trim() === CONTEXT_COOKIE_NAME) {
|
|
280
|
+
return valueParts.join("=").trim();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
var CONTEXT_COOKIE_NAME = "__integrate_oauth_ctx", CONTEXT_COOKIE_MAX_AGE = 300;
|
|
286
|
+
|
|
13
287
|
// base-handler.ts
|
|
14
288
|
class OAuthHandler {
|
|
15
289
|
config;
|
|
@@ -33,25 +307,35 @@ class OAuthHandler {
|
|
|
33
307
|
return headers;
|
|
34
308
|
}
|
|
35
309
|
async handleAuthorize(request) {
|
|
36
|
-
|
|
310
|
+
let webRequest;
|
|
311
|
+
let authorizeRequest;
|
|
312
|
+
if (request instanceof Request) {
|
|
313
|
+
webRequest = request;
|
|
314
|
+
authorizeRequest = await request.json();
|
|
315
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
316
|
+
authorizeRequest = await request.json();
|
|
317
|
+
} else {
|
|
318
|
+
authorizeRequest = request;
|
|
319
|
+
}
|
|
320
|
+
const providerConfig = this.config.providers[authorizeRequest.provider];
|
|
37
321
|
if (!providerConfig) {
|
|
38
|
-
throw new Error(`Provider ${
|
|
322
|
+
throw new Error(`Provider ${authorizeRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
39
323
|
}
|
|
40
324
|
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
41
|
-
throw new Error(`Missing OAuth credentials for ${
|
|
325
|
+
throw new Error(`Missing OAuth credentials for ${authorizeRequest.provider}. Check your environment variables.`);
|
|
42
326
|
}
|
|
43
327
|
const url = new URL("/oauth/authorize", this.serverUrl);
|
|
44
|
-
url.searchParams.set("provider",
|
|
328
|
+
url.searchParams.set("provider", authorizeRequest.provider);
|
|
45
329
|
url.searchParams.set("client_id", providerConfig.clientId);
|
|
46
330
|
url.searchParams.set("client_secret", providerConfig.clientSecret);
|
|
47
|
-
const scopes =
|
|
331
|
+
const scopes = authorizeRequest.scopes || providerConfig.scopes || [];
|
|
48
332
|
if (scopes.length > 0) {
|
|
49
333
|
url.searchParams.set("scope", scopes.join(","));
|
|
50
334
|
}
|
|
51
|
-
url.searchParams.set("state",
|
|
52
|
-
url.searchParams.set("code_challenge",
|
|
53
|
-
url.searchParams.set("code_challenge_method",
|
|
54
|
-
const redirectUri =
|
|
335
|
+
url.searchParams.set("state", authorizeRequest.state);
|
|
336
|
+
url.searchParams.set("code_challenge", authorizeRequest.codeChallenge);
|
|
337
|
+
url.searchParams.set("code_challenge_method", authorizeRequest.codeChallengeMethod);
|
|
338
|
+
const redirectUri = authorizeRequest.redirectUri || providerConfig.redirectUri;
|
|
55
339
|
if (redirectUri) {
|
|
56
340
|
url.searchParams.set("redirect_uri", redirectUri);
|
|
57
341
|
}
|
|
@@ -64,15 +348,62 @@ class OAuthHandler {
|
|
|
64
348
|
throw new Error(`MCP server failed to generate authorization URL: ${error}`);
|
|
65
349
|
}
|
|
66
350
|
const data = await response.json();
|
|
67
|
-
|
|
351
|
+
const result = data;
|
|
352
|
+
if (webRequest) {
|
|
353
|
+
try {
|
|
354
|
+
const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
|
|
355
|
+
const { createContextCookie: createContextCookie2, getSetCookieHeader: getSetCookieHeader2 } = await Promise.resolve().then(() => exports_context_cookie);
|
|
356
|
+
let context;
|
|
357
|
+
if (this.config.getSessionContext) {
|
|
358
|
+
context = await this.config.getSessionContext(webRequest);
|
|
359
|
+
}
|
|
360
|
+
if (!context || !context.userId) {
|
|
361
|
+
context = await detectSessionContext2(webRequest);
|
|
362
|
+
}
|
|
363
|
+
if (context && context.userId) {
|
|
364
|
+
const secret = this.apiKey || providerConfig.clientSecret;
|
|
365
|
+
const cookieValue = await createContextCookie2(context, authorizeRequest.provider, secret);
|
|
366
|
+
result.setCookie = getSetCookieHeader2(cookieValue);
|
|
367
|
+
}
|
|
368
|
+
} catch (error) {
|
|
369
|
+
console.warn("[OAuth] Failed to capture user context:", error);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return result;
|
|
68
373
|
}
|
|
69
374
|
async handleCallback(request) {
|
|
70
|
-
|
|
375
|
+
let webRequest;
|
|
376
|
+
let callbackRequest;
|
|
377
|
+
if (request instanceof Request) {
|
|
378
|
+
webRequest = request;
|
|
379
|
+
callbackRequest = await request.json();
|
|
380
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
381
|
+
callbackRequest = await request.json();
|
|
382
|
+
} else {
|
|
383
|
+
callbackRequest = request;
|
|
384
|
+
}
|
|
385
|
+
const providerConfig = this.config.providers[callbackRequest.provider];
|
|
71
386
|
if (!providerConfig) {
|
|
72
|
-
throw new Error(`Provider ${
|
|
387
|
+
throw new Error(`Provider ${callbackRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
73
388
|
}
|
|
74
389
|
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
75
|
-
throw new Error(`Missing OAuth credentials for ${
|
|
390
|
+
throw new Error(`Missing OAuth credentials for ${callbackRequest.provider}. Check your environment variables.`);
|
|
391
|
+
}
|
|
392
|
+
let context;
|
|
393
|
+
if (webRequest) {
|
|
394
|
+
try {
|
|
395
|
+
const { getContextCookieFromRequest: getContextCookieFromRequest2, readContextCookie: readContextCookie2 } = await Promise.resolve().then(() => exports_context_cookie);
|
|
396
|
+
const cookieValue = getContextCookieFromRequest2(webRequest);
|
|
397
|
+
if (cookieValue) {
|
|
398
|
+
const secret = this.apiKey || providerConfig.clientSecret;
|
|
399
|
+
const contextData = await readContextCookie2(cookieValue, secret);
|
|
400
|
+
if (contextData && contextData.provider === callbackRequest.provider) {
|
|
401
|
+
context = contextData.context;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
} catch (error) {
|
|
405
|
+
console.warn("[OAuth] Failed to restore user context:", error);
|
|
406
|
+
}
|
|
76
407
|
}
|
|
77
408
|
const url = new URL("/oauth/callback", this.serverUrl);
|
|
78
409
|
const response = await fetch(url.toString(), {
|
|
@@ -81,10 +412,10 @@ class OAuthHandler {
|
|
|
81
412
|
"Content-Type": "application/json"
|
|
82
413
|
}),
|
|
83
414
|
body: JSON.stringify({
|
|
84
|
-
provider:
|
|
85
|
-
code:
|
|
86
|
-
code_verifier:
|
|
87
|
-
state:
|
|
415
|
+
provider: callbackRequest.provider,
|
|
416
|
+
code: callbackRequest.code,
|
|
417
|
+
code_verifier: callbackRequest.codeVerifier,
|
|
418
|
+
state: callbackRequest.state,
|
|
88
419
|
client_id: providerConfig.clientId,
|
|
89
420
|
client_secret: providerConfig.clientSecret,
|
|
90
421
|
redirect_uri: providerConfig.redirectUri
|
|
@@ -95,7 +426,26 @@ class OAuthHandler {
|
|
|
95
426
|
throw new Error(`MCP server failed to exchange authorization code: ${error}`);
|
|
96
427
|
}
|
|
97
428
|
const data = await response.json();
|
|
98
|
-
|
|
429
|
+
const result = data;
|
|
430
|
+
if (this.config.setProviderToken && context) {
|
|
431
|
+
try {
|
|
432
|
+
const tokenData = {
|
|
433
|
+
accessToken: result.accessToken,
|
|
434
|
+
refreshToken: result.refreshToken,
|
|
435
|
+
tokenType: result.tokenType,
|
|
436
|
+
expiresIn: result.expiresIn,
|
|
437
|
+
expiresAt: result.expiresAt
|
|
438
|
+
};
|
|
439
|
+
await this.config.setProviderToken(callbackRequest.provider, tokenData, context);
|
|
440
|
+
} catch (error) {
|
|
441
|
+
console.error("[OAuth] Failed to save provider token:", error);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (webRequest) {
|
|
445
|
+
const { getClearCookieHeader: getClearCookieHeader2 } = await Promise.resolve().then(() => exports_context_cookie);
|
|
446
|
+
result.clearCookie = getClearCookieHeader2();
|
|
447
|
+
}
|
|
448
|
+
return result;
|
|
99
449
|
}
|
|
100
450
|
async handleStatus(provider, accessToken) {
|
|
101
451
|
const url = new URL("/oauth/status", this.serverUrl);
|
|
@@ -196,7 +546,7 @@ function generateCodeVerifier() {
|
|
|
196
546
|
} else {
|
|
197
547
|
throw new Error("crypto.getRandomValues is not available. Please use Node.js 19+ or a modern browser.");
|
|
198
548
|
}
|
|
199
|
-
return
|
|
549
|
+
return base64UrlEncode2(array);
|
|
200
550
|
}
|
|
201
551
|
async function generateCodeChallenge(verifier) {
|
|
202
552
|
const encoder = new TextEncoder;
|
|
@@ -209,7 +559,7 @@ async function generateCodeChallenge(verifier) {
|
|
|
209
559
|
} else {
|
|
210
560
|
throw new Error("crypto.subtle.digest is not available. Please use Node.js 19+ or a modern browser.");
|
|
211
561
|
}
|
|
212
|
-
return
|
|
562
|
+
return base64UrlEncode2(new Uint8Array(hashBuffer));
|
|
213
563
|
}
|
|
214
564
|
function generateState() {
|
|
215
565
|
const array = new Uint8Array(16);
|
|
@@ -220,18 +570,18 @@ function generateState() {
|
|
|
220
570
|
} else {
|
|
221
571
|
throw new Error("crypto.getRandomValues is not available. Please use Node.js 19+ or a modern browser.");
|
|
222
572
|
}
|
|
223
|
-
return
|
|
573
|
+
return base64UrlEncode2(array);
|
|
224
574
|
}
|
|
225
575
|
function generateStateWithReturnUrl(returnUrl) {
|
|
226
576
|
const csrf = generateState();
|
|
227
577
|
const stateData = returnUrl ? { csrf, returnUrl } : { csrf };
|
|
228
578
|
const encoder = new TextEncoder;
|
|
229
579
|
const jsonBytes = encoder.encode(JSON.stringify(stateData));
|
|
230
|
-
return
|
|
580
|
+
return base64UrlEncode2(jsonBytes);
|
|
231
581
|
}
|
|
232
582
|
function parseState(state) {
|
|
233
583
|
try {
|
|
234
|
-
const decoded =
|
|
584
|
+
const decoded = base64UrlDecode2(state);
|
|
235
585
|
const parsed = JSON.parse(decoded);
|
|
236
586
|
if (typeof parsed === "string") {
|
|
237
587
|
return { csrf: parsed };
|
|
@@ -246,7 +596,7 @@ function parseState(state) {
|
|
|
246
596
|
return { csrf: state };
|
|
247
597
|
}
|
|
248
598
|
}
|
|
249
|
-
function
|
|
599
|
+
function base64UrlEncode2(array) {
|
|
250
600
|
let base64 = "";
|
|
251
601
|
if (typeof Buffer !== "undefined") {
|
|
252
602
|
base64 = Buffer.from(array).toString("base64");
|
|
@@ -256,7 +606,7 @@ function base64UrlEncode(array) {
|
|
|
256
606
|
}
|
|
257
607
|
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
258
608
|
}
|
|
259
|
-
function
|
|
609
|
+
function base64UrlDecode2(str) {
|
|
260
610
|
let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
261
611
|
while (base64.length % 4 !== 0) {
|
|
262
612
|
base64 += "=";
|
|
@@ -418,9 +768,12 @@ function createNextOAuthHandler(config) {
|
|
|
418
768
|
const handlers = {
|
|
419
769
|
async authorize(req) {
|
|
420
770
|
try {
|
|
421
|
-
const
|
|
422
|
-
const
|
|
423
|
-
|
|
771
|
+
const result = await handler.handleAuthorize(req);
|
|
772
|
+
const response = Response.json(result);
|
|
773
|
+
if (result.setCookie) {
|
|
774
|
+
response.headers.set("Set-Cookie", result.setCookie);
|
|
775
|
+
}
|
|
776
|
+
return response;
|
|
424
777
|
} catch (error) {
|
|
425
778
|
console.error("[OAuth Authorize] Error:", error);
|
|
426
779
|
return Response.json({ error: error.message || "Failed to get authorization URL" }, { status: 500 });
|
|
@@ -428,9 +781,12 @@ function createNextOAuthHandler(config) {
|
|
|
428
781
|
},
|
|
429
782
|
async callback(req) {
|
|
430
783
|
try {
|
|
431
|
-
const
|
|
432
|
-
const
|
|
433
|
-
|
|
784
|
+
const result = await handler.handleCallback(req);
|
|
785
|
+
const response = Response.json(result);
|
|
786
|
+
if (result.clearCookie) {
|
|
787
|
+
response.headers.set("Set-Cookie", result.clearCookie);
|
|
788
|
+
}
|
|
789
|
+
return response;
|
|
434
790
|
} catch (error) {
|
|
435
791
|
console.error("[OAuth Callback] Error:", error);
|
|
436
792
|
return Response.json({ error: error.message || "Failed to exchange authorization code" }, { status: 500 });
|
|
@@ -647,18 +1003,24 @@ function toNodeHandler(config) {
|
|
|
647
1003
|
let webRes;
|
|
648
1004
|
if (req.method === "POST") {
|
|
649
1005
|
if (action === "authorize") {
|
|
650
|
-
const
|
|
651
|
-
const
|
|
1006
|
+
const result = await oauthHandler.handleAuthorize(webReq);
|
|
1007
|
+
const headers = { "Content-Type": "application/json" };
|
|
1008
|
+
if (result.setCookie) {
|
|
1009
|
+
headers["Set-Cookie"] = result.setCookie;
|
|
1010
|
+
}
|
|
652
1011
|
webRes = new Response(JSON.stringify(result), {
|
|
653
1012
|
status: 200,
|
|
654
|
-
headers
|
|
1013
|
+
headers
|
|
655
1014
|
});
|
|
656
1015
|
} else if (action === "callback") {
|
|
657
|
-
const
|
|
658
|
-
const
|
|
1016
|
+
const result = await oauthHandler.handleCallback(webReq);
|
|
1017
|
+
const headers = { "Content-Type": "application/json" };
|
|
1018
|
+
if (result.clearCookie) {
|
|
1019
|
+
headers["Set-Cookie"] = result.clearCookie;
|
|
1020
|
+
}
|
|
659
1021
|
webRes = new Response(JSON.stringify(result), {
|
|
660
1022
|
status: 200,
|
|
661
|
-
headers
|
|
1023
|
+
headers
|
|
662
1024
|
});
|
|
663
1025
|
} else if (action === "disconnect") {
|
|
664
1026
|
const authHeader = webReq.headers.get("authorization");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../../src/adapters/nextjs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG1E,KAAK,WAAW,GAAG,GAAG,CAAC;AACvB,KAAK,YAAY,GAAG,GAAG,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB;IAI7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;mBACkB,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../../src/adapters/nextjs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG1E,KAAK,WAAW,GAAG,GAAG,CAAC;AACvB,KAAK,YAAY,GAAG,GAAG,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB;IAI7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;mBACkB,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuBxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;kBACiB,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuBvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;gBACe,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA+BrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;oBACmB,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAiCzD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;;QAGC;;WAEG;kBAEI,WAAW,WACP;YAAE,MAAM,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,GAAG,OAAO,CAAC;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,GACpE,OAAO,CAAC,YAAY,CAAC;QA2BxB;;WAEG;iBAEI,WAAW,WACP;YAAE,MAAM,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,GAAG,OAAO,CAAC;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,GACpE,OAAO,CAAC,YAAY,CAAC;;IAiB5B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;aACY,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAelD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;qCAC8B;QAC/B,6DAA6D;QAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,iEAAiE;QACjE,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;QAKG;;WAEG;kBAEI,WAAW,WACP;YAAE,MAAM,EAAE;gBAAE,GAAG,EAAE,MAAM,EAAE,CAAA;aAAE,GAAG,OAAO,CAAC;gBAAE,GAAG,EAAE,MAAM,EAAE,CAAA;aAAE,CAAC,CAAA;SAAE,GAClE,OAAO,CAAC,YAAY,CAAC;QAsCxB;;WAEG;iBAEI,WAAW,WACP;YAAE,MAAM,EAAE;gBAAE,GAAG,EAAE,MAAM,EAAE,CAAA;aAAE,GAAG,OAAO,CAAC;gBAAE,GAAG,EAAE,MAAM,EAAE,CAAA;aAAE,CAAC,CAAA;SAAE,GAClE,OAAO,CAAC,YAAY,CAAC;;EA+F/B"}
|