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.
@@ -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
- logger34.error(`[OAuth ${action}] Error:`, error);
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,CA+Dd;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"}
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