integrate-sdk 0.9.0 → 0.9.3-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/auto-routes.d.ts.map +1 -1
- package/dist/adapters/auto-routes.js +107 -1
- package/dist/adapters/base-handler.d.ts +30 -0
- package/dist/adapters/base-handler.d.ts.map +1 -1
- package/dist/adapters/index.js +98 -0
- package/dist/adapters/nextjs.d.ts +17 -0
- package/dist/adapters/nextjs.d.ts.map +1 -1
- package/dist/adapters/nextjs.js +98 -0
- package/dist/adapters/node.js +98 -0
- package/dist/adapters/svelte-kit.js +98 -0
- package/dist/adapters/tanstack-start.js +98 -0
- package/dist/index.js +98 -0
- package/dist/oauth.js +107 -1
- package/dist/server.js +98 -0
- package/dist/src/adapters/auto-routes.d.ts.map +1 -1
- package/dist/src/adapters/base-handler.d.ts +30 -0
- package/dist/src/adapters/base-handler.d.ts.map +1 -1
- package/dist/src/adapters/nextjs.d.ts +17 -0
- package/dist/src/adapters/nextjs.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -11826,6 +11826,81 @@ class OAuthHandler {
|
|
|
11826
11826
|
const data = await response.json();
|
|
11827
11827
|
return data;
|
|
11828
11828
|
}
|
|
11829
|
+
async handleRefresh(request) {
|
|
11830
|
+
let webRequest;
|
|
11831
|
+
let refreshRequest;
|
|
11832
|
+
if (request instanceof Request) {
|
|
11833
|
+
webRequest = request;
|
|
11834
|
+
refreshRequest = await request.json();
|
|
11835
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
11836
|
+
refreshRequest = await request.json();
|
|
11837
|
+
} else {
|
|
11838
|
+
refreshRequest = request;
|
|
11839
|
+
}
|
|
11840
|
+
const providerConfig = this.config.providers[refreshRequest.provider];
|
|
11841
|
+
if (!providerConfig) {
|
|
11842
|
+
throw new Error(`Provider ${refreshRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
11843
|
+
}
|
|
11844
|
+
let context;
|
|
11845
|
+
if (webRequest) {
|
|
11846
|
+
try {
|
|
11847
|
+
if (this.config.getSessionContext) {
|
|
11848
|
+
context = await this.config.getSessionContext(webRequest);
|
|
11849
|
+
}
|
|
11850
|
+
if (!context || !context.userId) {
|
|
11851
|
+
const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
|
|
11852
|
+
context = await detectSessionContext2(webRequest);
|
|
11853
|
+
}
|
|
11854
|
+
} catch (error) {}
|
|
11855
|
+
}
|
|
11856
|
+
const body = {
|
|
11857
|
+
provider: refreshRequest.provider,
|
|
11858
|
+
refresh_token: refreshRequest.refreshToken,
|
|
11859
|
+
client_id: providerConfig.clientId
|
|
11860
|
+
};
|
|
11861
|
+
if (providerConfig.clientSecret) {
|
|
11862
|
+
body.client_secret = providerConfig.clientSecret;
|
|
11863
|
+
}
|
|
11864
|
+
if (providerConfig.config?.subdomain) {
|
|
11865
|
+
body.subdomain = providerConfig.config.subdomain;
|
|
11866
|
+
}
|
|
11867
|
+
const url = new URL("/oauth/refresh", this.serverUrl);
|
|
11868
|
+
const response = await fetch(url.toString(), {
|
|
11869
|
+
method: "POST",
|
|
11870
|
+
headers: this.getHeaders({
|
|
11871
|
+
"Content-Type": "application/json"
|
|
11872
|
+
}),
|
|
11873
|
+
body: JSON.stringify(body)
|
|
11874
|
+
});
|
|
11875
|
+
if (!response.ok) {
|
|
11876
|
+
const error = await response.text();
|
|
11877
|
+
const lowerError = error.toLowerCase();
|
|
11878
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
11879
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
11880
|
+
}
|
|
11881
|
+
throw new Error(`Token refresh failed: ${error}`);
|
|
11882
|
+
}
|
|
11883
|
+
const data = await response.json();
|
|
11884
|
+
const result = data;
|
|
11885
|
+
if (this.config.setProviderToken) {
|
|
11886
|
+
try {
|
|
11887
|
+
const tokenData = {
|
|
11888
|
+
accessToken: result.accessToken,
|
|
11889
|
+
refreshToken: result.refreshToken,
|
|
11890
|
+
tokenType: result.tokenType,
|
|
11891
|
+
expiresIn: result.expiresIn,
|
|
11892
|
+
expiresAt: result.expiresAt,
|
|
11893
|
+
scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
|
|
11894
|
+
};
|
|
11895
|
+
const email = result.email || await fetchUserEmail(refreshRequest.provider, tokenData);
|
|
11896
|
+
if (email) {
|
|
11897
|
+
tokenData.email = email;
|
|
11898
|
+
}
|
|
11899
|
+
await this.config.setProviderToken(refreshRequest.provider, tokenData, email, context);
|
|
11900
|
+
} catch (error) {}
|
|
11901
|
+
}
|
|
11902
|
+
return result;
|
|
11903
|
+
}
|
|
11829
11904
|
async handleToolCall(request, authHeader, integrationsHeader) {
|
|
11830
11905
|
const url = this.serverUrl;
|
|
11831
11906
|
const headers = this.getHeaders({
|
|
@@ -11956,6 +12031,23 @@ function createNextOAuthHandler(config) {
|
|
|
11956
12031
|
return Response.json({ error: error.message || "Failed to disconnect provider" }, { status: 500 });
|
|
11957
12032
|
}
|
|
11958
12033
|
},
|
|
12034
|
+
async refresh(req) {
|
|
12035
|
+
try {
|
|
12036
|
+
const result = await handler.handleRefresh(req);
|
|
12037
|
+
const response = Response.json(result);
|
|
12038
|
+
if (handler.hasDatabaseCallbacks()) {
|
|
12039
|
+
response.headers.set("X-Integrate-Use-Database", "true");
|
|
12040
|
+
}
|
|
12041
|
+
return response;
|
|
12042
|
+
} catch (error) {
|
|
12043
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
12044
|
+
logger33.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
12045
|
+
} else {
|
|
12046
|
+
logger33.error("[OAuth Refresh] Error:", error);
|
|
12047
|
+
}
|
|
12048
|
+
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
12049
|
+
}
|
|
12050
|
+
},
|
|
11959
12051
|
createRoutes() {
|
|
11960
12052
|
return {
|
|
11961
12053
|
async POST(req, context) {
|
|
@@ -11970,6 +12062,9 @@ function createNextOAuthHandler(config) {
|
|
|
11970
12062
|
if (action === "disconnect") {
|
|
11971
12063
|
return handlers.disconnect(req);
|
|
11972
12064
|
}
|
|
12065
|
+
if (action === "refresh") {
|
|
12066
|
+
return handlers.refresh(req);
|
|
12067
|
+
}
|
|
11973
12068
|
if (action === "mcp") {
|
|
11974
12069
|
return handlers.mcp(req);
|
|
11975
12070
|
}
|
|
@@ -12015,6 +12110,9 @@ function createNextOAuthHandler(config) {
|
|
|
12015
12110
|
if (action === "disconnect") {
|
|
12016
12111
|
return handlers.disconnect(req);
|
|
12017
12112
|
}
|
|
12113
|
+
if (action === "refresh") {
|
|
12114
|
+
return handlers.refresh(req);
|
|
12115
|
+
}
|
|
12018
12116
|
return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
|
|
12019
12117
|
}
|
|
12020
12118
|
if (segments.length === 1 && segments[0] === "mcp") {
|
|
@@ -11826,6 +11826,81 @@ class OAuthHandler {
|
|
|
11826
11826
|
const data = await response.json();
|
|
11827
11827
|
return data;
|
|
11828
11828
|
}
|
|
11829
|
+
async handleRefresh(request) {
|
|
11830
|
+
let webRequest;
|
|
11831
|
+
let refreshRequest;
|
|
11832
|
+
if (request instanceof Request) {
|
|
11833
|
+
webRequest = request;
|
|
11834
|
+
refreshRequest = await request.json();
|
|
11835
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
11836
|
+
refreshRequest = await request.json();
|
|
11837
|
+
} else {
|
|
11838
|
+
refreshRequest = request;
|
|
11839
|
+
}
|
|
11840
|
+
const providerConfig = this.config.providers[refreshRequest.provider];
|
|
11841
|
+
if (!providerConfig) {
|
|
11842
|
+
throw new Error(`Provider ${refreshRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
11843
|
+
}
|
|
11844
|
+
let context;
|
|
11845
|
+
if (webRequest) {
|
|
11846
|
+
try {
|
|
11847
|
+
if (this.config.getSessionContext) {
|
|
11848
|
+
context = await this.config.getSessionContext(webRequest);
|
|
11849
|
+
}
|
|
11850
|
+
if (!context || !context.userId) {
|
|
11851
|
+
const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
|
|
11852
|
+
context = await detectSessionContext2(webRequest);
|
|
11853
|
+
}
|
|
11854
|
+
} catch (error) {}
|
|
11855
|
+
}
|
|
11856
|
+
const body = {
|
|
11857
|
+
provider: refreshRequest.provider,
|
|
11858
|
+
refresh_token: refreshRequest.refreshToken,
|
|
11859
|
+
client_id: providerConfig.clientId
|
|
11860
|
+
};
|
|
11861
|
+
if (providerConfig.clientSecret) {
|
|
11862
|
+
body.client_secret = providerConfig.clientSecret;
|
|
11863
|
+
}
|
|
11864
|
+
if (providerConfig.config?.subdomain) {
|
|
11865
|
+
body.subdomain = providerConfig.config.subdomain;
|
|
11866
|
+
}
|
|
11867
|
+
const url = new URL("/oauth/refresh", this.serverUrl);
|
|
11868
|
+
const response = await fetch(url.toString(), {
|
|
11869
|
+
method: "POST",
|
|
11870
|
+
headers: this.getHeaders({
|
|
11871
|
+
"Content-Type": "application/json"
|
|
11872
|
+
}),
|
|
11873
|
+
body: JSON.stringify(body)
|
|
11874
|
+
});
|
|
11875
|
+
if (!response.ok) {
|
|
11876
|
+
const error = await response.text();
|
|
11877
|
+
const lowerError = error.toLowerCase();
|
|
11878
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
11879
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
11880
|
+
}
|
|
11881
|
+
throw new Error(`Token refresh failed: ${error}`);
|
|
11882
|
+
}
|
|
11883
|
+
const data = await response.json();
|
|
11884
|
+
const result = data;
|
|
11885
|
+
if (this.config.setProviderToken) {
|
|
11886
|
+
try {
|
|
11887
|
+
const tokenData = {
|
|
11888
|
+
accessToken: result.accessToken,
|
|
11889
|
+
refreshToken: result.refreshToken,
|
|
11890
|
+
tokenType: result.tokenType,
|
|
11891
|
+
expiresIn: result.expiresIn,
|
|
11892
|
+
expiresAt: result.expiresAt,
|
|
11893
|
+
scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
|
|
11894
|
+
};
|
|
11895
|
+
const email = result.email || await fetchUserEmail(refreshRequest.provider, tokenData);
|
|
11896
|
+
if (email) {
|
|
11897
|
+
tokenData.email = email;
|
|
11898
|
+
}
|
|
11899
|
+
await this.config.setProviderToken(refreshRequest.provider, tokenData, email, context);
|
|
11900
|
+
} catch (error) {}
|
|
11901
|
+
}
|
|
11902
|
+
return result;
|
|
11903
|
+
}
|
|
11829
11904
|
async handleToolCall(request, authHeader, integrationsHeader) {
|
|
11830
11905
|
const url = this.serverUrl;
|
|
11831
11906
|
const headers = this.getHeaders({
|
|
@@ -11956,6 +12031,23 @@ function createNextOAuthHandler(config) {
|
|
|
11956
12031
|
return Response.json({ error: error.message || "Failed to disconnect provider" }, { status: 500 });
|
|
11957
12032
|
}
|
|
11958
12033
|
},
|
|
12034
|
+
async refresh(req) {
|
|
12035
|
+
try {
|
|
12036
|
+
const result = await handler.handleRefresh(req);
|
|
12037
|
+
const response = Response.json(result);
|
|
12038
|
+
if (handler.hasDatabaseCallbacks()) {
|
|
12039
|
+
response.headers.set("X-Integrate-Use-Database", "true");
|
|
12040
|
+
}
|
|
12041
|
+
return response;
|
|
12042
|
+
} catch (error) {
|
|
12043
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
12044
|
+
logger33.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
12045
|
+
} else {
|
|
12046
|
+
logger33.error("[OAuth Refresh] Error:", error);
|
|
12047
|
+
}
|
|
12048
|
+
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
12049
|
+
}
|
|
12050
|
+
},
|
|
11959
12051
|
createRoutes() {
|
|
11960
12052
|
return {
|
|
11961
12053
|
async POST(req, context) {
|
|
@@ -11970,6 +12062,9 @@ function createNextOAuthHandler(config) {
|
|
|
11970
12062
|
if (action === "disconnect") {
|
|
11971
12063
|
return handlers.disconnect(req);
|
|
11972
12064
|
}
|
|
12065
|
+
if (action === "refresh") {
|
|
12066
|
+
return handlers.refresh(req);
|
|
12067
|
+
}
|
|
11973
12068
|
if (action === "mcp") {
|
|
11974
12069
|
return handlers.mcp(req);
|
|
11975
12070
|
}
|
|
@@ -12015,6 +12110,9 @@ function createNextOAuthHandler(config) {
|
|
|
12015
12110
|
if (action === "disconnect") {
|
|
12016
12111
|
return handlers.disconnect(req);
|
|
12017
12112
|
}
|
|
12113
|
+
if (action === "refresh") {
|
|
12114
|
+
return handlers.refresh(req);
|
|
12115
|
+
}
|
|
12018
12116
|
return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
|
|
12019
12117
|
}
|
|
12020
12118
|
if (segments.length === 1 && segments[0] === "mcp") {
|
package/dist/index.js
CHANGED
|
@@ -2817,6 +2817,23 @@ function createNextOAuthHandler(config) {
|
|
|
2817
2817
|
return Response.json({ error: error.message || "Failed to disconnect provider" }, { status: 500 });
|
|
2818
2818
|
}
|
|
2819
2819
|
},
|
|
2820
|
+
async refresh(req) {
|
|
2821
|
+
try {
|
|
2822
|
+
const result = await handler.handleRefresh(req);
|
|
2823
|
+
const response = Response.json(result);
|
|
2824
|
+
if (handler.hasDatabaseCallbacks()) {
|
|
2825
|
+
response.headers.set("X-Integrate-Use-Database", "true");
|
|
2826
|
+
}
|
|
2827
|
+
return response;
|
|
2828
|
+
} catch (error) {
|
|
2829
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
2830
|
+
logger6.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
2831
|
+
} else {
|
|
2832
|
+
logger6.error("[OAuth Refresh] Error:", error);
|
|
2833
|
+
}
|
|
2834
|
+
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
2835
|
+
}
|
|
2836
|
+
},
|
|
2820
2837
|
createRoutes() {
|
|
2821
2838
|
return {
|
|
2822
2839
|
async POST(req, context) {
|
|
@@ -2831,6 +2848,9 @@ function createNextOAuthHandler(config) {
|
|
|
2831
2848
|
if (action === "disconnect") {
|
|
2832
2849
|
return handlers.disconnect(req);
|
|
2833
2850
|
}
|
|
2851
|
+
if (action === "refresh") {
|
|
2852
|
+
return handlers.refresh(req);
|
|
2853
|
+
}
|
|
2834
2854
|
if (action === "mcp") {
|
|
2835
2855
|
return handlers.mcp(req);
|
|
2836
2856
|
}
|
|
@@ -2876,6 +2896,9 @@ function createNextOAuthHandler(config) {
|
|
|
2876
2896
|
if (action === "disconnect") {
|
|
2877
2897
|
return handlers.disconnect(req);
|
|
2878
2898
|
}
|
|
2899
|
+
if (action === "refresh") {
|
|
2900
|
+
return handlers.refresh(req);
|
|
2901
|
+
}
|
|
2879
2902
|
return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
|
|
2880
2903
|
}
|
|
2881
2904
|
if (segments.length === 1 && segments[0] === "mcp") {
|
|
@@ -12205,6 +12228,81 @@ class OAuthHandler {
|
|
|
12205
12228
|
const data = await response.json();
|
|
12206
12229
|
return data;
|
|
12207
12230
|
}
|
|
12231
|
+
async handleRefresh(request) {
|
|
12232
|
+
let webRequest;
|
|
12233
|
+
let refreshRequest;
|
|
12234
|
+
if (request instanceof Request) {
|
|
12235
|
+
webRequest = request;
|
|
12236
|
+
refreshRequest = await request.json();
|
|
12237
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
12238
|
+
refreshRequest = await request.json();
|
|
12239
|
+
} else {
|
|
12240
|
+
refreshRequest = request;
|
|
12241
|
+
}
|
|
12242
|
+
const providerConfig = this.config.providers[refreshRequest.provider];
|
|
12243
|
+
if (!providerConfig) {
|
|
12244
|
+
throw new Error(`Provider ${refreshRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
12245
|
+
}
|
|
12246
|
+
let context;
|
|
12247
|
+
if (webRequest) {
|
|
12248
|
+
try {
|
|
12249
|
+
if (this.config.getSessionContext) {
|
|
12250
|
+
context = await this.config.getSessionContext(webRequest);
|
|
12251
|
+
}
|
|
12252
|
+
if (!context || !context.userId) {
|
|
12253
|
+
const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
|
|
12254
|
+
context = await detectSessionContext2(webRequest);
|
|
12255
|
+
}
|
|
12256
|
+
} catch (error) {}
|
|
12257
|
+
}
|
|
12258
|
+
const body = {
|
|
12259
|
+
provider: refreshRequest.provider,
|
|
12260
|
+
refresh_token: refreshRequest.refreshToken,
|
|
12261
|
+
client_id: providerConfig.clientId
|
|
12262
|
+
};
|
|
12263
|
+
if (providerConfig.clientSecret) {
|
|
12264
|
+
body.client_secret = providerConfig.clientSecret;
|
|
12265
|
+
}
|
|
12266
|
+
if (providerConfig.config?.subdomain) {
|
|
12267
|
+
body.subdomain = providerConfig.config.subdomain;
|
|
12268
|
+
}
|
|
12269
|
+
const url = new URL("/oauth/refresh", this.serverUrl);
|
|
12270
|
+
const response = await fetch(url.toString(), {
|
|
12271
|
+
method: "POST",
|
|
12272
|
+
headers: this.getHeaders({
|
|
12273
|
+
"Content-Type": "application/json"
|
|
12274
|
+
}),
|
|
12275
|
+
body: JSON.stringify(body)
|
|
12276
|
+
});
|
|
12277
|
+
if (!response.ok) {
|
|
12278
|
+
const error = await response.text();
|
|
12279
|
+
const lowerError = error.toLowerCase();
|
|
12280
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
12281
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
12282
|
+
}
|
|
12283
|
+
throw new Error(`Token refresh failed: ${error}`);
|
|
12284
|
+
}
|
|
12285
|
+
const data = await response.json();
|
|
12286
|
+
const result = data;
|
|
12287
|
+
if (this.config.setProviderToken) {
|
|
12288
|
+
try {
|
|
12289
|
+
const tokenData = {
|
|
12290
|
+
accessToken: result.accessToken,
|
|
12291
|
+
refreshToken: result.refreshToken,
|
|
12292
|
+
tokenType: result.tokenType,
|
|
12293
|
+
expiresIn: result.expiresIn,
|
|
12294
|
+
expiresAt: result.expiresAt,
|
|
12295
|
+
scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
|
|
12296
|
+
};
|
|
12297
|
+
const email = result.email || await fetchUserEmail(refreshRequest.provider, tokenData);
|
|
12298
|
+
if (email) {
|
|
12299
|
+
tokenData.email = email;
|
|
12300
|
+
}
|
|
12301
|
+
await this.config.setProviderToken(refreshRequest.provider, tokenData, email, context);
|
|
12302
|
+
} catch (error) {}
|
|
12303
|
+
}
|
|
12304
|
+
return result;
|
|
12305
|
+
}
|
|
12208
12306
|
async handleToolCall(request, authHeader, integrationsHeader) {
|
|
12209
12307
|
const url = this.serverUrl;
|
|
12210
12308
|
const headers = this.getHeaders({
|
package/dist/oauth.js
CHANGED
|
@@ -2639,6 +2639,23 @@ function createNextOAuthHandler(config) {
|
|
|
2639
2639
|
return Response.json({ error: error.message || "Failed to disconnect provider" }, { status: 500 });
|
|
2640
2640
|
}
|
|
2641
2641
|
},
|
|
2642
|
+
async refresh(req) {
|
|
2643
|
+
try {
|
|
2644
|
+
const result = await handler.handleRefresh(req);
|
|
2645
|
+
const response = Response.json(result);
|
|
2646
|
+
if (handler.hasDatabaseCallbacks()) {
|
|
2647
|
+
response.headers.set("X-Integrate-Use-Database", "true");
|
|
2648
|
+
}
|
|
2649
|
+
return response;
|
|
2650
|
+
} catch (error) {
|
|
2651
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
2652
|
+
logger6.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
2653
|
+
} else {
|
|
2654
|
+
logger6.error("[OAuth Refresh] Error:", error);
|
|
2655
|
+
}
|
|
2656
|
+
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
2657
|
+
}
|
|
2658
|
+
},
|
|
2642
2659
|
createRoutes() {
|
|
2643
2660
|
return {
|
|
2644
2661
|
async POST(req, context) {
|
|
@@ -2653,6 +2670,9 @@ function createNextOAuthHandler(config) {
|
|
|
2653
2670
|
if (action === "disconnect") {
|
|
2654
2671
|
return handlers.disconnect(req);
|
|
2655
2672
|
}
|
|
2673
|
+
if (action === "refresh") {
|
|
2674
|
+
return handlers.refresh(req);
|
|
2675
|
+
}
|
|
2656
2676
|
if (action === "mcp") {
|
|
2657
2677
|
return handlers.mcp(req);
|
|
2658
2678
|
}
|
|
@@ -2698,6 +2718,9 @@ function createNextOAuthHandler(config) {
|
|
|
2698
2718
|
if (action === "disconnect") {
|
|
2699
2719
|
return handlers.disconnect(req);
|
|
2700
2720
|
}
|
|
2721
|
+
if (action === "refresh") {
|
|
2722
|
+
return handlers.refresh(req);
|
|
2723
|
+
}
|
|
2701
2724
|
return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
|
|
2702
2725
|
}
|
|
2703
2726
|
if (segments.length === 1 && segments[0] === "mcp") {
|
|
@@ -12039,6 +12062,81 @@ class OAuthHandler {
|
|
|
12039
12062
|
const data = await response.json();
|
|
12040
12063
|
return data;
|
|
12041
12064
|
}
|
|
12065
|
+
async handleRefresh(request) {
|
|
12066
|
+
let webRequest;
|
|
12067
|
+
let refreshRequest;
|
|
12068
|
+
if (request instanceof Request) {
|
|
12069
|
+
webRequest = request;
|
|
12070
|
+
refreshRequest = await request.json();
|
|
12071
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
12072
|
+
refreshRequest = await request.json();
|
|
12073
|
+
} else {
|
|
12074
|
+
refreshRequest = request;
|
|
12075
|
+
}
|
|
12076
|
+
const providerConfig = this.config.providers[refreshRequest.provider];
|
|
12077
|
+
if (!providerConfig) {
|
|
12078
|
+
throw new Error(`Provider ${refreshRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
12079
|
+
}
|
|
12080
|
+
let context;
|
|
12081
|
+
if (webRequest) {
|
|
12082
|
+
try {
|
|
12083
|
+
if (this.config.getSessionContext) {
|
|
12084
|
+
context = await this.config.getSessionContext(webRequest);
|
|
12085
|
+
}
|
|
12086
|
+
if (!context || !context.userId) {
|
|
12087
|
+
const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
|
|
12088
|
+
context = await detectSessionContext2(webRequest);
|
|
12089
|
+
}
|
|
12090
|
+
} catch (error) {}
|
|
12091
|
+
}
|
|
12092
|
+
const body = {
|
|
12093
|
+
provider: refreshRequest.provider,
|
|
12094
|
+
refresh_token: refreshRequest.refreshToken,
|
|
12095
|
+
client_id: providerConfig.clientId
|
|
12096
|
+
};
|
|
12097
|
+
if (providerConfig.clientSecret) {
|
|
12098
|
+
body.client_secret = providerConfig.clientSecret;
|
|
12099
|
+
}
|
|
12100
|
+
if (providerConfig.config?.subdomain) {
|
|
12101
|
+
body.subdomain = providerConfig.config.subdomain;
|
|
12102
|
+
}
|
|
12103
|
+
const url = new URL("/oauth/refresh", this.serverUrl);
|
|
12104
|
+
const response = await fetch(url.toString(), {
|
|
12105
|
+
method: "POST",
|
|
12106
|
+
headers: this.getHeaders({
|
|
12107
|
+
"Content-Type": "application/json"
|
|
12108
|
+
}),
|
|
12109
|
+
body: JSON.stringify(body)
|
|
12110
|
+
});
|
|
12111
|
+
if (!response.ok) {
|
|
12112
|
+
const error = await response.text();
|
|
12113
|
+
const lowerError = error.toLowerCase();
|
|
12114
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
12115
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
12116
|
+
}
|
|
12117
|
+
throw new Error(`Token refresh failed: ${error}`);
|
|
12118
|
+
}
|
|
12119
|
+
const data = await response.json();
|
|
12120
|
+
const result = data;
|
|
12121
|
+
if (this.config.setProviderToken) {
|
|
12122
|
+
try {
|
|
12123
|
+
const tokenData = {
|
|
12124
|
+
accessToken: result.accessToken,
|
|
12125
|
+
refreshToken: result.refreshToken,
|
|
12126
|
+
tokenType: result.tokenType,
|
|
12127
|
+
expiresIn: result.expiresIn,
|
|
12128
|
+
expiresAt: result.expiresAt,
|
|
12129
|
+
scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
|
|
12130
|
+
};
|
|
12131
|
+
const email = result.email || await fetchUserEmail(refreshRequest.provider, tokenData);
|
|
12132
|
+
if (email) {
|
|
12133
|
+
tokenData.email = email;
|
|
12134
|
+
}
|
|
12135
|
+
await this.config.setProviderToken(refreshRequest.provider, tokenData, email, context);
|
|
12136
|
+
} catch (error) {}
|
|
12137
|
+
}
|
|
12138
|
+
return result;
|
|
12139
|
+
}
|
|
12042
12140
|
async handleToolCall(request, authHeader, integrationsHeader) {
|
|
12043
12141
|
const url = this.serverUrl;
|
|
12044
12142
|
const headers = this.getHeaders({
|
|
@@ -12132,9 +12230,17 @@ async function POST2(req, context) {
|
|
|
12132
12230
|
const result = await handler.handleDisconnect({ provider: body.provider }, accessToken, req);
|
|
12133
12231
|
return createSuccessResponse(result);
|
|
12134
12232
|
}
|
|
12233
|
+
if (action === "refresh") {
|
|
12234
|
+
const result = await handler.handleRefresh(req);
|
|
12235
|
+
return createSuccessResponse(result);
|
|
12236
|
+
}
|
|
12135
12237
|
return createErrorResponse(`Unknown action: ${action}`, 404);
|
|
12136
12238
|
} catch (error) {
|
|
12137
|
-
|
|
12239
|
+
if (action === "refresh" && error.message?.toLowerCase().includes("not supported")) {
|
|
12240
|
+
logger34.info(`[OAuth ${action}] Not supported for this provider:`, error.message);
|
|
12241
|
+
} else {
|
|
12242
|
+
logger34.error(`[OAuth ${action}] Error:`, error);
|
|
12243
|
+
}
|
|
12138
12244
|
return createErrorResponse(error.message, 500);
|
|
12139
12245
|
}
|
|
12140
12246
|
}
|
package/dist/server.js
CHANGED
|
@@ -3114,6 +3114,81 @@ class OAuthHandler {
|
|
|
3114
3114
|
const data = await response.json();
|
|
3115
3115
|
return data;
|
|
3116
3116
|
}
|
|
3117
|
+
async handleRefresh(request) {
|
|
3118
|
+
let webRequest;
|
|
3119
|
+
let refreshRequest;
|
|
3120
|
+
if (request instanceof Request) {
|
|
3121
|
+
webRequest = request;
|
|
3122
|
+
refreshRequest = await request.json();
|
|
3123
|
+
} else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
|
|
3124
|
+
refreshRequest = await request.json();
|
|
3125
|
+
} else {
|
|
3126
|
+
refreshRequest = request;
|
|
3127
|
+
}
|
|
3128
|
+
const providerConfig = this.config.providers[refreshRequest.provider];
|
|
3129
|
+
if (!providerConfig) {
|
|
3130
|
+
throw new Error(`Provider ${refreshRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
3131
|
+
}
|
|
3132
|
+
let context;
|
|
3133
|
+
if (webRequest) {
|
|
3134
|
+
try {
|
|
3135
|
+
if (this.config.getSessionContext) {
|
|
3136
|
+
context = await this.config.getSessionContext(webRequest);
|
|
3137
|
+
}
|
|
3138
|
+
if (!context || !context.userId) {
|
|
3139
|
+
const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
|
|
3140
|
+
context = await detectSessionContext2(webRequest);
|
|
3141
|
+
}
|
|
3142
|
+
} catch (error) {}
|
|
3143
|
+
}
|
|
3144
|
+
const body = {
|
|
3145
|
+
provider: refreshRequest.provider,
|
|
3146
|
+
refresh_token: refreshRequest.refreshToken,
|
|
3147
|
+
client_id: providerConfig.clientId
|
|
3148
|
+
};
|
|
3149
|
+
if (providerConfig.clientSecret) {
|
|
3150
|
+
body.client_secret = providerConfig.clientSecret;
|
|
3151
|
+
}
|
|
3152
|
+
if (providerConfig.config?.subdomain) {
|
|
3153
|
+
body.subdomain = providerConfig.config.subdomain;
|
|
3154
|
+
}
|
|
3155
|
+
const url = new URL("/oauth/refresh", this.serverUrl);
|
|
3156
|
+
const response = await fetch(url.toString(), {
|
|
3157
|
+
method: "POST",
|
|
3158
|
+
headers: this.getHeaders({
|
|
3159
|
+
"Content-Type": "application/json"
|
|
3160
|
+
}),
|
|
3161
|
+
body: JSON.stringify(body)
|
|
3162
|
+
});
|
|
3163
|
+
if (!response.ok) {
|
|
3164
|
+
const error = await response.text();
|
|
3165
|
+
const lowerError = error.toLowerCase();
|
|
3166
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
3167
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
3168
|
+
}
|
|
3169
|
+
throw new Error(`Token refresh failed: ${error}`);
|
|
3170
|
+
}
|
|
3171
|
+
const data = await response.json();
|
|
3172
|
+
const result = data;
|
|
3173
|
+
if (this.config.setProviderToken) {
|
|
3174
|
+
try {
|
|
3175
|
+
const tokenData = {
|
|
3176
|
+
accessToken: result.accessToken,
|
|
3177
|
+
refreshToken: result.refreshToken,
|
|
3178
|
+
tokenType: result.tokenType,
|
|
3179
|
+
expiresIn: result.expiresIn,
|
|
3180
|
+
expiresAt: result.expiresAt,
|
|
3181
|
+
scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
|
|
3182
|
+
};
|
|
3183
|
+
const email = result.email || await fetchUserEmail(refreshRequest.provider, tokenData);
|
|
3184
|
+
if (email) {
|
|
3185
|
+
tokenData.email = email;
|
|
3186
|
+
}
|
|
3187
|
+
await this.config.setProviderToken(refreshRequest.provider, tokenData, email, context);
|
|
3188
|
+
} catch (error) {}
|
|
3189
|
+
}
|
|
3190
|
+
return result;
|
|
3191
|
+
}
|
|
3117
3192
|
async handleToolCall(request, authHeader, integrationsHeader) {
|
|
3118
3193
|
const url = this.serverUrl;
|
|
3119
3194
|
const headers = this.getHeaders({
|
|
@@ -3244,6 +3319,23 @@ function createNextOAuthHandler(config) {
|
|
|
3244
3319
|
return Response.json({ error: error.message || "Failed to disconnect provider" }, { status: 500 });
|
|
3245
3320
|
}
|
|
3246
3321
|
},
|
|
3322
|
+
async refresh(req) {
|
|
3323
|
+
try {
|
|
3324
|
+
const result = await handler.handleRefresh(req);
|
|
3325
|
+
const response = Response.json(result);
|
|
3326
|
+
if (handler.hasDatabaseCallbacks()) {
|
|
3327
|
+
response.headers.set("X-Integrate-Use-Database", "true");
|
|
3328
|
+
}
|
|
3329
|
+
return response;
|
|
3330
|
+
} catch (error) {
|
|
3331
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
3332
|
+
logger7.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
3333
|
+
} else {
|
|
3334
|
+
logger7.error("[OAuth Refresh] Error:", error);
|
|
3335
|
+
}
|
|
3336
|
+
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
3337
|
+
}
|
|
3338
|
+
},
|
|
3247
3339
|
createRoutes() {
|
|
3248
3340
|
return {
|
|
3249
3341
|
async POST(req, context) {
|
|
@@ -3258,6 +3350,9 @@ function createNextOAuthHandler(config) {
|
|
|
3258
3350
|
if (action === "disconnect") {
|
|
3259
3351
|
return handlers.disconnect(req);
|
|
3260
3352
|
}
|
|
3353
|
+
if (action === "refresh") {
|
|
3354
|
+
return handlers.refresh(req);
|
|
3355
|
+
}
|
|
3261
3356
|
if (action === "mcp") {
|
|
3262
3357
|
return handlers.mcp(req);
|
|
3263
3358
|
}
|
|
@@ -3303,6 +3398,9 @@ function createNextOAuthHandler(config) {
|
|
|
3303
3398
|
if (action === "disconnect") {
|
|
3304
3399
|
return handlers.disconnect(req);
|
|
3305
3400
|
}
|
|
3401
|
+
if (action === "refresh") {
|
|
3402
|
+
return handlers.refresh(req);
|
|
3403
|
+
}
|
|
3306
3404
|
return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
|
|
3307
3405
|
}
|
|
3308
3406
|
if (segments.length === 1 && segments[0] === "mcp") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-routes.d.ts","sourceRoot":"","sources":["../../../src/adapters/auto-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAe1E;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAErE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,GAAG,IAAI,CAEhE;AAED;;;;;;;;;;;;;;;;;GAiBG;AAkBH;;;GAGG;AACH,wBAAsB,IAAI,CACxB,GAAG,EAAE,GAAG,EACR,OAAO,CAAC,EAAE;IAAE,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACvC,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"auto-routes.d.ts","sourceRoot":"","sources":["../../../src/adapters/auto-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAe1E;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAErE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,GAAG,IAAI,CAEhE;AAED;;;;;;;;;;;;;;;;;GAiBG;AAkBH;;;GAGG;AACH,wBAAsB,IAAI,CACxB,GAAG,EAAE,GAAG,EACR,OAAO,CAAC,EAAE;IAAE,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACvC,OAAO,CAAC,GAAG,CAAC,CAwEd;AAED;;;GAGG;AACH,wBAAsB,GAAG,CACvB,GAAG,EAAE,GAAG,EACR,OAAO,CAAC,EAAE;IAAE,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACvC,OAAO,CAAC,GAAG,CAAC,CAoCd"}
|
|
@@ -179,6 +179,25 @@ export interface DisconnectResponse {
|
|
|
179
179
|
success: boolean;
|
|
180
180
|
provider: string;
|
|
181
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Request body for token refresh endpoint
|
|
184
|
+
*/
|
|
185
|
+
export interface RefreshRequest {
|
|
186
|
+
provider: string;
|
|
187
|
+
refreshToken: string;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Response from token refresh endpoint
|
|
191
|
+
*/
|
|
192
|
+
export interface RefreshResponse {
|
|
193
|
+
accessToken: string;
|
|
194
|
+
refreshToken?: string;
|
|
195
|
+
tokenType: string;
|
|
196
|
+
expiresIn: number;
|
|
197
|
+
expiresAt?: string;
|
|
198
|
+
scopes?: string[];
|
|
199
|
+
email?: string;
|
|
200
|
+
}
|
|
182
201
|
/**
|
|
183
202
|
* Request body for MCP tool call endpoint
|
|
184
203
|
*/
|
|
@@ -285,6 +304,17 @@ export declare class OAuthHandler {
|
|
|
285
304
|
* @throws Error if MCP server request fails
|
|
286
305
|
*/
|
|
287
306
|
handleDisconnect(request: DisconnectRequest, accessToken: string, webRequest?: Request): Promise<DisconnectResponse>;
|
|
307
|
+
/**
|
|
308
|
+
* Handle token refresh
|
|
309
|
+
* Refreshes an expired access token via the MCP server's /oauth/refresh endpoint
|
|
310
|
+
*
|
|
311
|
+
* @param request - Refresh request with provider and refreshToken, OR full Web Request object
|
|
312
|
+
* @returns Refreshed token data
|
|
313
|
+
*
|
|
314
|
+
* @throws Error if provider is not configured
|
|
315
|
+
* @throws Error if MCP server request fails
|
|
316
|
+
*/
|
|
317
|
+
handleRefresh(request: RefreshRequest | Request): Promise<RefreshResponse>;
|
|
288
318
|
/**
|
|
289
319
|
* Handle MCP tool call
|
|
290
320
|
* Forwards tool call requests to MCP server with API key and provider token
|