@decodo/mcp-server 1.2.5 → 1.3.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.
Files changed (58) hide show
  1. package/README.md +61 -43
  2. package/build/auth/credential.js +4 -1
  3. package/build/auth/credential.js.map +1 -1
  4. package/build/clients/hosts.js +10 -0
  5. package/build/clients/hosts.js.map +1 -0
  6. package/build/clients/scraper-api-client.js +15 -5
  7. package/build/clients/scraper-api-client.js.map +1 -1
  8. package/build/index.js +2 -2
  9. package/build/index.js.map +1 -1
  10. package/build/oauth/backend.js +3 -0
  11. package/build/oauth/backend.js.map +1 -0
  12. package/build/oauth/backends/decodo/index.js +71 -0
  13. package/build/oauth/backends/decodo/index.js.map +1 -0
  14. package/build/oauth/backends/decodo/request-jwt.js +62 -0
  15. package/build/oauth/backends/decodo/request-jwt.js.map +1 -0
  16. package/build/oauth/backends/decodo/token-exchange.js +88 -0
  17. package/build/oauth/backends/decodo/token-exchange.js.map +1 -0
  18. package/build/oauth/backends/mock/dashboard.js +84 -0
  19. package/build/oauth/backends/mock/dashboard.js.map +1 -0
  20. package/build/oauth/backends/mock/index.js +42 -0
  21. package/build/oauth/backends/mock/index.js.map +1 -0
  22. package/build/oauth/backends/mock/subscription-api.js +130 -0
  23. package/build/oauth/backends/mock/subscription-api.js.map +1 -0
  24. package/build/oauth/bounded-body.js +29 -0
  25. package/build/oauth/bounded-body.js.map +1 -0
  26. package/build/oauth/clients-store.js +142 -0
  27. package/build/oauth/clients-store.js.map +1 -0
  28. package/build/oauth/config.js +77 -0
  29. package/build/oauth/config.js.map +1 -0
  30. package/build/oauth/cookies.js +25 -0
  31. package/build/oauth/cookies.js.map +1 -0
  32. package/build/oauth/index.js +46 -0
  33. package/build/oauth/index.js.map +1 -0
  34. package/build/oauth/provider.js +172 -0
  35. package/build/oauth/provider.js.map +1 -0
  36. package/build/oauth/redirect-uris.js +17 -0
  37. package/build/oauth/redirect-uris.js.map +1 -0
  38. package/build/oauth/router.js +68 -0
  39. package/build/oauth/router.js.map +1 -0
  40. package/build/oauth/sealer.js +55 -0
  41. package/build/oauth/sealer.js.map +1 -0
  42. package/build/oauth/token-exchange.js +17 -0
  43. package/build/oauth/token-exchange.js.map +1 -0
  44. package/build/oauth/ttl-store.js +47 -0
  45. package/build/oauth/ttl-store.js.map +1 -0
  46. package/build/server/app.js +77 -0
  47. package/build/server/app.js.map +1 -0
  48. package/build/server/revoked-credentials.js +25 -0
  49. package/build/server/revoked-credentials.js.map +1 -0
  50. package/build/server/sapi-base-server.js +2 -2
  51. package/build/server/sapi-base-server.js.map +1 -1
  52. package/build/server/sapi-http-server.js +2 -2
  53. package/build/server/sapi-http-server.js.map +1 -1
  54. package/build/server/trust-proxy.js +19 -0
  55. package/build/server/trust-proxy.js.map +1 -0
  56. package/build/server.js +6 -44
  57. package/build/server.js.map +1 -1
  58. package/package.json +3 -9
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Decodo MCP Server
2
2
 
3
3
  [![](https://dcbadge.limes.pink/api/server/https://discord.gg/Ja8dqKgvbZ)](https://discord.gg/Ja8dqKgvbZ)
4
- [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=Decodo&config=eyJ1cmwiOiJodHRwczovL21jcC5kZWNvZG8uY29tL21jcCIsImhlYWRlcnMiOnsiQXV0aG9yaXphdGlvbiI6IkJhc2ljIDx3ZWJfYWR2YW5jZWRfdG9rZW4%2BIn19)
4
+ [![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=Decodo&config=eyJ1cmwiOiJodHRwczovL21jcC5kZWNvZG8uY29tL21jcCIsImhlYWRlcnMiOnsiQXV0aG9yaXphdGlvbiI6IkJlYXJlciA8YXBpX2tleT4ifX0%3D)
5
5
 
6
6
  <p align="center">
7
7
  <a href="https://dashboard.decodo.com/integrations?utm_source=github&utm_medium=social&utm_campaign=mcp_server"> <img src="https://github.com/user-attachments/assets/a1e52a9e-3da1-4081-b3c6-053aafb8f196"/></a>
@@ -80,15 +80,17 @@ scraping infrastructure from scratch. Common scenarios:
80
80
 
81
81
  1. **Create a free account** at [dashboard.decodo.com](https://dashboard.decodo.com/) – up to 2K
82
82
  free requests, no credit card required.
83
- 2. **Get your authentication token.** Obtain a Web Scraping API basic authentication token from the dashboard.
83
+ 2. **Get your API key.** Copy your Web Data API key from your Web Data API subscription on the
84
+ [dashboard](https://dashboard.decodo.com/web-data/playground). Older plans have a basic
85
+ authentication token, which also works (see [Authentication](#authentication)).
84
86
  3. **Download Node.js 18+** from https://nodejs.org.
85
- 4. **Get MCP client** like Claude Desktop, Cursor, Windsurf or other MCP-compatible
86
- tools.
87
+ 4. **Get MCP client** like Claude Desktop, Cursor, Windsurf or other MCP-compatible tools.
87
88
  5. **Configure the MCP server** in your AI client (see configuration examples below).
88
89
 
89
- ## Connecting to [Decodo's MCP server](https://mcp.decodo.com/mcp)
90
+ ## Connecting to [Decodo's MCP server](https://mcp.decodo.com/mcp)
90
91
 
91
- Open your preferred MCP client and add the following configuration (see examples for Claude Code, Cursor, Windsurf bellow):
92
+ Open your preferred MCP client and add the following configuration (see examples for Claude Code,
93
+ Cursor, Windsurf bellow):
92
94
 
93
95
  ```
94
96
  {
@@ -96,14 +98,24 @@ Open your preferred MCP client and add the following configuration (see examples
96
98
  "Decodo": {
97
99
  "url": "https://mcp.decodo.com/mcp",
98
100
  "headers": {
99
- "Authorization": "Basic <basic_auth_token>"
101
+ "Authorization": "Bearer <api_key>"
100
102
  }
101
103
  }
102
104
  }
103
105
  }
104
106
  ```
105
107
 
108
+ ### Authentication
109
+
110
+ | Credential | Where to get it | Hosted server header | Local server env |
111
+ | -------------------------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------- | -------------------------------------- |
112
+ | **API key** (recommended) | Web Data API subscription on the [dashboard](https://dashboard.decodo.com/web-data/playground) | `Authorization: Bearer <api_key>` | `SCRAPER_API_TOKEN=<api_key>` |
113
+ | **Basic authentication token** (older plans) | Web Scraping API page on the dashboard | `Authorization: Basic <basic_auth_token>` | `SCRAPER_API_TOKEN=<basic_auth_token>` |
114
+
115
+ The local server reads either credential from `SCRAPER_API_TOKEN` and works out which one it got.
116
+
106
117
  ### Claude Desktop
118
+
107
119
  1. Open Claude Desktop → Settings → Developer → Edit Config.
108
120
  2. Add to claude_desktop_config.json:
109
121
 
@@ -114,35 +126,40 @@ Open your preferred MCP client and add the following configuration (see examples
114
126
  "command": "npx",
115
127
  "args": ["-y", "@decodo/mcp-server"],
116
128
  "env": {
117
- "SCRAPER_API_TOKEN": "<basic_auth_token>",
129
+ "SCRAPER_API_TOKEN": "<api_key>",
118
130
  "TOOLSETS": "web,ai"
119
131
  }
120
132
  }
121
133
  }
122
134
  }
123
135
  ```
136
+
124
137
  3. Save and restart Claude Desktop.
125
138
 
126
139
  ### Cursor
127
- 1. Open Settings → MCP.
128
- 2. Click Add a new global MCP server (opens mcp.json).
129
- 3. Add the same configuration as above.
130
- 4. Save — look for a green status indicator next to Decodo.
140
+
141
+ 1. Open Settings → MCP.
142
+ 2. Click Add a new global MCP server (opens mcp.json).
143
+ 3. Add the same configuration as above.
144
+ 4. Save — look for a green status indicator next to Decodo.
131
145
 
132
146
  ### Windsurf
133
- 1. Open Settings → Windsurf Settings.
134
- 2. Scroll to Cascade → Add custom server + (opens mcp_config.json).
135
- 3. Add the same configuration as above.
136
- 4. Save and restart Windsurf.
147
+
148
+ 1. Open Settings → Windsurf Settings.
149
+ 2. Scroll to Cascade → Add custom server + (opens mcp_config.json).
150
+ 3. Add the same configuration as above.
151
+ 4. Save and restart Windsurf.
137
152
 
138
153
  ## Test your setup
154
+
139
155
  Once connected, try this prompt in your client:
140
156
 
141
- ▎ "Scrape the titles of the top 5 articles from Hacker News"
157
+ ▎ "Scrape the titles of the top 5 articles from Hacker News"
158
+
159
+ You should get a structured list back within seconds. If you see an auth error, double-check your
160
+ API key on the dashboard.
142
161
 
143
- You should get a structured list back within seconds. If you see an auth error, double-check your token from the dashboard.
144
162
  ## Optional: enable specific toolsets
145
-
146
163
 
147
164
  # Running the MCP server locally
148
165
 
@@ -193,7 +210,7 @@ this:
193
210
  "command": "node",
194
211
  "args": ["/Users/your.user/projects/decodo-mcp/build/index.js"],
195
212
  "env": {
196
- "SCRAPER_API_TOKEN": "<web_scraping_api_base64_token>"
213
+ "SCRAPER_API_TOKEN": "<api_key>"
197
214
  }
198
215
  }
199
216
  }
@@ -211,7 +228,7 @@ comma-separated list via the `toolsets` query parameter:
211
228
  "Decodo MCP Server": {
212
229
  "url": "https://mcp.decodo.com/mcp?toolsets=web,ai",
213
230
  "headers": {
214
- "Authorization": "Basic <your_auth_token>"
231
+ "Authorization": "Bearer <api_key>"
215
232
  }
216
233
  }
217
234
  ```
@@ -267,23 +284,23 @@ The server exposes the following tools:
267
284
 
268
285
  The following parameters are inferred from user prompts:
269
286
 
270
- | Parameter | Description |
271
- | --------------- | ----------------------------------------------------------------------------------------------------- |
272
- | `jsRender` | Renders target URL in a headless browser. |
273
- | `geo` | Sets the country from which the request will originate. |
274
- | `locale` | Sets the locale of the request. |
275
- | `tokenLimit` | Truncates the response content up to this limit. Useful if the context window is small. |
276
- | `prompt` | Prompt to send to AI tools (`chatgpt`, `perplexity`). |
277
- | `search` | Activates ChatGPT's web search functionality (`chatgpt` only). |
278
- | `xhr` | When true, includes XHR or fetch responses in the scrape result where supported (e.g. `tiktok_post`). |
287
+ | Parameter | Description |
288
+ | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
289
+ | `jsRender` | Renders target URL in a headless browser. |
290
+ | `geo` | Sets the country from which the request will originate. |
291
+ | `locale` | Sets the locale of the request. |
292
+ | `tokenLimit` | Truncates the response content up to this limit. Useful if the context window is small. |
293
+ | `prompt` | Prompt to send to AI tools (`chatgpt`, `perplexity`). |
294
+ | `search` | Activates ChatGPT's web search functionality (`chatgpt` only). |
295
+ | `xhr` | When true, includes XHR or fetch responses in the scrape result where supported (e.g. `tiktok_post`). |
279
296
  | `deviceType` | Device type to emulate (`desktop`, `mobile`, `tablet`). Parsed targets are stricter: Amazon tools are desktop-only so they omit it, and `bing_search`/`google_ai_mode` accept `desktop` and `mobile` only. |
280
- | `domain` | Domain to use for the request (e.g., `amazon.com`, `amazon.co.uk`, `bing.com`). |
281
- | `pageFrom` | Starting page number for pagination. |
282
- | `deliveryZip` | ZIP code for delivery location (Target, Walmart). |
283
- | `storeId` | Store ID for local inventory (Walmart). |
284
- | `country` | Country for TikTok Shop requests. |
285
- | `limit` | Maximum number of results to return (e.g., YouTube channel videos). |
286
- | `language_code` | Language code for subtitles (e.g., `en`, `es`). |
297
+ | `domain` | Domain to use for the request (e.g., `amazon.com`, `amazon.co.uk`, `bing.com`). |
298
+ | `pageFrom` | Starting page number for pagination. |
299
+ | `deliveryZip` | ZIP code for delivery location (Target, Walmart). |
300
+ | `storeId` | Store ID for local inventory (Walmart). |
301
+ | `country` | Country for TikTok Shop requests. |
302
+ | `limit` | Maximum number of results to return (e.g., YouTube channel videos). |
303
+ | `language_code` | Language code for subtitles (e.g., `en`, `es`). |
287
304
 
288
305
  ## Examples
289
306
 
@@ -319,13 +336,14 @@ Scrape hacker news, return full content.
319
336
 
320
337
  ## Use with Decodo agent skills
321
338
 
322
- This server gives your agent the scraping *tools*. [`Decodo/agent-skills`](https://github.com/Decodo/agent-skills)
323
- teaches it **when** to reach for them, **which** surface to use, and **how** to call it — so the agent
324
- picks the right tool and parameters on its own instead of guessing.
339
+ This server gives your agent the scraping _tools_.
340
+ [`Decodo/agent-skills`](https://github.com/Decodo/agent-skills) teaches it **when** to reach for
341
+ them, **which** surface to use, and **how** to call it — so the agent picks the right tool and
342
+ parameters on its own instead of guessing.
325
343
 
326
- The skills route across the `decodo` CLI, this hosted MCP server, and the raw HTTP API, and fall back
327
- to the MCP server automatically when no shell is available. Pairing the two gives your agent both the
328
- execution layer (this server) and the decision layer (the skills) in a single setup.
344
+ The skills route across the `decodo` CLI, this hosted MCP server, and the raw HTTP API, and fall
345
+ back to the MCP server automatically when no shell is available. Pairing the two gives your agent
346
+ both the execution layer (this server) and the decision layer (the skills) in a single setup.
329
347
 
330
348
  **Quick start** (Claude Code):
331
349
 
@@ -21,7 +21,10 @@ const credentialFromAuthHeader = (header) => {
21
21
  if (!scheme || !value || rest.length > 0) {
22
22
  return;
23
23
  }
24
- return toCredential(TYPE_BY_SCHEME[scheme], value);
24
+ if (!TYPE_BY_SCHEME[scheme]) {
25
+ return;
26
+ }
27
+ return toCredential((0, detect_credential_type_1.detectCredentialType)(value), value);
25
28
  };
26
29
  exports.credentialFromAuthHeader = credentialFromAuthHeader;
27
30
  //# sourceMappingURL=credential.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"credential.js","sourceRoot":"","sources":["../../src/auth/credential.ts"],"names":[],"mappings":";;;AAAA,2CAAqD;AACrD,qEAAgE;AAGhE,MAAM,cAAc,GAAyC;IAC3D,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,qBAAS,CAAC,KAAK;IACpC,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,qBAAS,CAAC,OAAO;CACxC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAA0B,EAAE,KAAa,EAA8B,EAAE;IAC7F,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC,CAAC;AAEK,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAA8B,EAAE,CAC/E,YAAY,CAAC,IAAA,6CAAoB,EAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AADtC,QAAA,mBAAmB,uBACmB;AAE5C,MAAM,wBAAwB,GAAG,CAAC,MAAc,EAA8B,EAAE;IACrF,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE5D,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO;IACT,CAAC;IAED,OAAO,YAAY,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;AACrD,CAAC,CAAC;AARW,QAAA,wBAAwB,4BAQnC"}
1
+ {"version":3,"file":"credential.js","sourceRoot":"","sources":["../../src/auth/credential.ts"],"names":[],"mappings":";;;AAAA,2CAAqD;AACrD,qEAAgE;AAGhE,MAAM,cAAc,GAAyC;IAC3D,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,qBAAS,CAAC,KAAK;IACpC,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,qBAAS,CAAC,OAAO;CACxC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAA0B,EAAE,KAAa,EAA8B,EAAE;IAC7F,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC,CAAC;AAEK,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAA8B,EAAE,CAC/E,YAAY,CAAC,IAAA,6CAAoB,EAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AADtC,QAAA,mBAAmB,uBACmB;AAE5C,MAAM,wBAAwB,GAAG,CAAC,MAAc,EAA8B,EAAE;IACrF,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE5D,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,OAAO,YAAY,CAAC,IAAA,6CAAoB,EAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AAC1D,CAAC,CAAC;AAZW,QAAA,wBAAwB,4BAYnC"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scrapingApiHostsFromEnv = void 0;
4
+ const hostFromEnv = (env, key) => { var _a; return ((_a = env[key]) === null || _a === void 0 ? void 0 : _a.trim()) || undefined; };
5
+ const scrapingApiHostsFromEnv = (env = process.env) => ({
6
+ scraperApi: hostFromEnv(env, 'DECODO_SAPI_HOST'),
7
+ dataApi: hostFromEnv(env, 'DECODO_DATA_API_HOST'),
8
+ });
9
+ exports.scrapingApiHostsFromEnv = scrapingApiHostsFromEnv;
10
+ //# sourceMappingURL=hosts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosts.js","sourceRoot":"","sources":["../../src/clients/hosts.ts"],"names":[],"mappings":";;;AAOA,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAE,GAAW,EAAsB,EAAE,WAAC,OAAA,CAAA,MAAA,GAAG,CAAC,GAAG,CAAC,0CAAE,IAAI,EAAE,KAAI,SAAS,CAAA,EAAA,CAAC;AAE1F,MAAM,uBAAuB,GAAG,CAAC,MAAW,OAAO,CAAC,GAAG,EAAoB,EAAE,CAAC,CAAC;IACpF,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,kBAAkB,CAAC;IAChD,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,sBAAsB,CAAC;CAClD,CAAC,CAAC;AAHU,QAAA,uBAAuB,2BAGjC"}
@@ -14,6 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.ScraperApiClient = void 0;
15
15
  const sdk_ts_1 = require("@decodo/sdk-ts");
16
16
  const auth_1 = require("../auth");
17
+ const hosts_1 = require("./hosts");
17
18
  const utils_1 = require("../utils");
18
19
  const logger_1 = require("../logger");
19
20
  const retry_1 = require("./retry");
@@ -25,7 +26,7 @@ const API_PARAM_ALIASES = new Map([
25
26
  ['deliveryZip', 'delivery_zip'],
26
27
  ]);
27
28
  class ScraperApiClient {
28
- constructor({ maxRetries = retry_1.MAX_RETRIES, delayMs = retry_1.BASE_RETRY_DELAY_MS, } = {}) {
29
+ constructor({ maxRetries = retry_1.MAX_RETRIES, delayMs = retry_1.BASE_RETRY_DELAY_MS, onAuthenticationError, hosts = (0, hosts_1.scrapingApiHostsFromEnv)(), } = {}) {
29
30
  this.transformScrapingParams = ({ scrapingParams, }) => {
30
31
  var _a;
31
32
  const { jsRender, headless, target } = scrapingParams, rest = __rest(scrapingParams, ["jsRender", "headless", "target"]);
@@ -45,11 +46,16 @@ class ScraperApiClient {
45
46
  }
46
47
  return { data: result.content };
47
48
  };
48
- this.sdkError = ({ error, target, authType, startMs, }) => {
49
+ this.sdkError = ({ error, target, auth, startMs, }) => {
50
+ var _a;
49
51
  const latencyMs = Date.now() - startMs;
52
+ const authType = auth.type;
50
53
  const message = error instanceof Error ? error.message : String(error);
51
54
  if (error instanceof sdk_ts_1.DecodoError) {
52
55
  const sdkMessage = error instanceof sdk_ts_1.AuthenticationError ? 'Authentication failed.' : error.message;
56
+ if (error instanceof sdk_ts_1.AuthenticationError) {
57
+ (_a = this.onAuthenticationError) === null || _a === void 0 ? void 0 : _a.call(this, auth);
58
+ }
53
59
  (0, logger_1.log)('error', 'tool_call', {
54
60
  outcome: 'error',
55
61
  target,
@@ -84,7 +90,9 @@ class ScraperApiClient {
84
90
  });
85
91
  return error;
86
92
  };
87
- this.sdkCredentials = (auth) => auth.type === auth_1.AUTH_TYPE.API_KEY ? { apiKey: auth.value } : { token: auth.value };
93
+ this.sdkTransport = (auth) => auth.type === auth_1.AUTH_TYPE.API_KEY
94
+ ? { apiKey: auth.value, baseUrl: this.hosts.dataApi }
95
+ : { token: auth.value, baseUrl: this.hosts.scraperApi };
88
96
  this.scrape = async ({ auth, scrapingParams, extra, }) => {
89
97
  var _a, _b, _c, _d;
90
98
  const notifier = new utils_1.ProgressNotifier(extra);
@@ -95,7 +103,7 @@ class ScraperApiClient {
95
103
  const params = this.transformScrapingParams({ scrapingParams });
96
104
  const { target } = params;
97
105
  const { webScrapingApi } = new sdk_ts_1.DecodoClient({
98
- webScrapingApi: Object.assign(Object.assign({}, this.sdkCredentials(auth)), { integrationHeader: INTEGRATION_HEADER }),
106
+ webScrapingApi: Object.assign(Object.assign({}, this.sdkTransport(auth)), { integrationHeader: INTEGRATION_HEADER }),
99
107
  timeoutMs: REQUEST_TIMEOUT_MS,
100
108
  });
101
109
  let lastError;
@@ -138,7 +146,7 @@ class ScraperApiClient {
138
146
  break;
139
147
  }
140
148
  }
141
- throw this.sdkError({ error: lastError, target, authType: auth.type, startMs });
149
+ throw this.sdkError({ error: lastError, target, auth, startMs });
142
150
  }
143
151
  finally {
144
152
  notifier.stopWaitingNotifications();
@@ -146,6 +154,8 @@ class ScraperApiClient {
146
154
  };
147
155
  this.maxRetries = maxRetries;
148
156
  this.delayMs = delayMs;
157
+ this.onAuthenticationError = onAuthenticationError;
158
+ this.hosts = hosts;
149
159
  }
150
160
  }
151
161
  exports.ScraperApiClient = ScraperApiClient;
@@ -1 +1 @@
1
- {"version":3,"file":"scraper-api-client.js","sourceRoot":"","sources":["../../src/clients/scraper-api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,2CAMwB;AAGxB,kCAAoC;AAEpC,oCAA2D;AAC3D,sCAAgC;AAChC,mCASiB;AAEjB,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,kBAAkB,GAAG,MAAO,CAAC;AAEnC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,CAAC,YAAY,EAAE,aAAa,CAAC;IAC7B,CAAC,UAAU,EAAE,WAAW,CAAC;IACzB,CAAC,aAAa,EAAE,cAAc,CAAC;CAChC,CAAC,CAAC;AAEH,MAAa,gBAAgB;IAK3B,YAAY,EACV,UAAU,GAAG,mBAAW,EACxB,OAAO,GAAG,2BAAmB,MAI3B,EAAE;QAKN,4BAAuB,GAAG,CAAC,EACzB,cAAc,GAGf,EAAiB,EAAE;;YAClB,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,KAAc,cAAc,EAAvB,IAAI,UAAK,cAAc,EAAxD,kCAAuC,CAAiB,CAAC;YAE/D,MAAM,WAAW,mBACf,MAAM,EAAE,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,eAAM,CAAC,SAAS,IAC/B,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAChE,CAAC;YAEF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChD,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;oBACzB,SAAS;gBACX,CAAC;gBAED,WAAW,CAAC,MAAA,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,mCAAI,GAAG,CAAC,GAAG,KAAK,CAAC;YACzD,CAAC;YAED,OAAO,WAAuC,CAAC;QACjD,CAAC,CAAC;QAEF,sBAAiB,GAAG,CAAI,EAAE,GAAG,EAAyB,EAAE,EAAE;YACxD,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;YAE7B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACtD,CAAC;YAED,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,OAAY,EAAE,CAAC;QACvC,CAAC,CAAC;QAEM,aAAQ,GAAG,CAAC,EAClB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,GAMR,EAAW,EAAE;YACZ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YACvC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEvE,IAAI,KAAK,YAAY,oBAAW,EAAE,CAAC;gBACjC,MAAM,UAAU,GACd,KAAK,YAAY,4BAAmB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;gBAElF,IAAA,YAAG,EAAC,OAAO,EAAE,WAAW,EAAE;oBACxB,OAAO,EAAE,OAAO;oBAChB,MAAM;oBACN,SAAS,EAAE,QAAQ;oBACnB,UAAU,EAAE,cAAc;oBAC1B,eAAe,EAAE,KAAK,CAAC,UAAU;oBACjC,OAAO,EAAE,UAAU;oBACnB,UAAU,EAAE,SAAS;iBACtB,CAAC,CAAC;gBAEH,OAAO,IAAI,KAAK,CAAC,+BAA+B,KAAK,CAAC,UAAU,MAAM,UAAU,EAAE,CAAC,CAAC;YACtF,CAAC;YAED,MAAM,SAAS,GAAG,KAAK,YAAY,qBAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAA,2BAAmB,EAAC,KAAK,CAAC,CAAC;YAE3F,IAAI,SAAS,EAAE,CAAC;gBACd,IAAA,YAAG,EAAC,OAAO,EAAE,WAAW,EAAE;oBACxB,OAAO,EAAE,OAAO;oBAChB,MAAM;oBACN,SAAS,EAAE,QAAQ;oBACnB,UAAU,EAAE,SAAS;oBACrB,UAAU,EAAE,SAAS;oBACrB,OAAO;oBACP,UAAU,EAAE,SAAS;iBACtB,CAAC,CAAC;gBAEH,OAAO,IAAI,KAAK,CAAC,6CAA6C,SAAS,EAAE,CAAC,CAAC;YAC7E,CAAC;YAED,IAAA,YAAG,EAAC,OAAO,EAAE,WAAW,EAAE;gBACxB,OAAO,EAAE,OAAO;gBAChB,MAAM;gBACN,SAAS,EAAE,QAAQ;gBACnB,UAAU,EAAE,YAAY;gBACxB,OAAO;gBACP,UAAU,EAAE,SAAS;aACtB,CAAC,CAAC;YAEH,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEM,mBAAc,GAAG,CAAC,IAAoB,EAAE,EAAE,CAChD,IAAI,CAAC,IAAI,KAAK,gBAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnF,WAAM,GAAG,KAAK,EAAc,EAC1B,IAAI,EACJ,cAAc,EACd,KAAK,GAKN,EAAE,EAAE;;YACH,MAAM,QAAQ,GAAG,IAAI,wBAAgB,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE3B,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,MAAM,CAAC,qCAAqC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAEnE,QAAQ,CAAC,yBAAyB,CAAC,gCAAwB,EAAE,2BAAmB,CAAC,CAAC;gBAElF,MAAM,MAAM,GAAG,IAAI,CAAC,uBAAuB,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;gBAChE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;gBAE1B,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,qBAAY,CAAC;oBAC1C,cAAc,kCACT,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAC5B,iBAAiB,EAAE,kBAAkB,GACtC;oBACD,SAAS,EAAE,kBAAkB;iBAC9B,CAAC,CAAC;gBAEH,IAAI,SAAkB,CAAC;gBAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;oBAC5D,IAAI,CAAC;wBACH,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;wBAEhD,QAAQ,CAAC,wBAAwB,EAAE,CAAC;wBAEpC,MAAM,QAAQ,CAAC,MAAM,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;wBAExD,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAI,EAAE,GAAG,EAAE,CAAC,CAAC;wBAElD,IAAA,YAAG,EAAC,MAAM,EAAE,WAAW,EAAE;4BACvB,OAAO,EAAE,SAAS;4BAClB,MAAM;4BACN,SAAS,EAAE,IAAI,CAAC,IAAI;4BACpB,eAAe,EAAE,MAAA,MAAA,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,0CAAE,WAAW,mCAAI,IAAI;4BACpD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;4BAChC,OAAO;yBACR,CAAC,CAAC;wBAEH,OAAO,MAAM,CAAC;oBAChB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,SAAS,GAAG,KAAK,CAAC;wBAElB,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,IAAI,IAAA,mBAAW,EAAC,KAAK,CAAC,EAAE,CAAC;4BACpD,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;4BACtE,MAAM,MAAM,GACV,KAAK,YAAY,oBAAW;gCAC1B,CAAC,CAAC,UAAU,KAAK,CAAC,UAAU,EAAE;gCAC9B,CAAC,CAAC,iBAAiB,MAAA,IAAA,2BAAmB,EAAC,KAAK,CAAC,mCAAI,SAAS,EAAE,CAAC;4BAEjE,IAAA,YAAG,EAAC,MAAM,EAAE,iBAAiB,EAAE;gCAC7B,MAAM;gCACN,OAAO,EAAE,OAAO,GAAG,CAAC;gCACpB,WAAW,EAAE,IAAI,CAAC,UAAU;gCAC5B,MAAM;gCACN,UAAU,EAAE,MAAA,IAAA,2BAAmB,EAAC,KAAK,CAAC,mCAAI,IAAI;gCAC9C,eAAe,EAAE,KAAK,YAAY,oBAAW,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;gCACvE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;6BAC9B,CAAC,CAAC;4BAEH,MAAM,QAAQ,CAAC,MAAM,CAAC,aAAa,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;4BAEjF,MAAM,IAAA,aAAK,EAAC,OAAO,CAAC,CAAC;4BACrB,SAAS;wBACX,CAAC;wBAED,MAAM;oBACR,CAAC;gBACH,CAAC;gBAED,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAClF,CAAC;oBAAS,CAAC;gBACT,QAAQ,CAAC,wBAAwB,EAAE,CAAC;YACtC,CAAC;QACH,CAAC,CAAC;QAvLA,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CAsLF;AApMD,4CAoMC"}
1
+ {"version":3,"file":"scraper-api-client.js","sourceRoot":"","sources":["../../src/clients/scraper-api-client.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -10,13 +10,13 @@ const parseEnvsOrExit = () => {
10
10
  const envs = ['SCRAPER_API_TOKEN'];
11
11
  for (const envKey of envs) {
12
12
  if (!process.env[envKey]) {
13
- console.error(`env ${envKey} missing`);
13
+ console.error(`env ${envKey} missing: set your API key or basic auth token`);
14
14
  process.exit(1);
15
15
  }
16
16
  }
17
17
  const sapiAuth = (0, auth_1.credentialFromValue)(process.env['SCRAPER_API_TOKEN']);
18
18
  if (!sapiAuth) {
19
- console.error('env SCRAPER_API_TOKEN missing');
19
+ console.error('env SCRAPER_API_TOKEN missing: set your API key or basic auth token');
20
20
  process.exit(1);
21
21
  }
22
22
  return { sapiAuth };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yBAAuB;AAEvB,wEAAiF;AACjF,iCAA6C;AAC7C,kEAAmE;AACnE,mCAA0C;AAE1C,MAAM,eAAe,GAAG,GAAG,EAAE;IAC3B,MAAM,IAAI,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAEnC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,UAAU,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,0BAAmB,EAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAW,CAAC,CAAC;IAEjF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;IACtB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAE7C,4DAA4D;IAC5D,MAAM,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;IAEvC,MAAM,aAAa,GAAG,IAAI,yCAAqB,CAAC;QAC9C,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,IAAA,uBAAe,EAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,OAAO,CAAC,KAAK,CAAC,sCAAsC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yBAAuB;AAEvB,wEAAiF;AACjF,iCAA6C;AAC7C,kEAAmE;AACnE,mCAA0C;AAE1C,MAAM,eAAe,GAAG,GAAG,EAAE;IAC3B,MAAM,IAAI,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAEnC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,gDAAgD,CAAC,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,0BAAmB,EAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAW,CAAC,CAAC;IAEjF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;IACtB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAE7C,4DAA4D;IAC5D,MAAM,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;IAEvC,MAAM,aAAa,GAAG,IAAI,yCAAqB,CAAC;QAC9C,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,IAAA,uBAAe,EAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,OAAO,CAAC,KAAK,CAAC,sCAAsC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/oauth/backend.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDecodoBackend = exports.DecodoBackend = exports.DASHBOARD_QUERY = void 0;
4
+ const errors_js_1 = require("@modelcontextprotocol/sdk/server/auth/errors.js");
5
+ const logger_1 = require("../../../logger");
6
+ const token_exchange_1 = require("../../token-exchange");
7
+ const request_jwt_1 = require("./request-jwt");
8
+ const token_exchange_2 = require("./token-exchange");
9
+ exports.DASHBOARD_QUERY = {
10
+ REQUEST_UUID: 'request_uuid',
11
+ };
12
+ class DecodoBackend {
13
+ constructor({ client, dashboardAuthorizeUrl, callbackUrl, issuer, fetch, }) {
14
+ this.client = client;
15
+ this.dashboardAuthorizeUrl = dashboardAuthorizeUrl;
16
+ this.callbackUrl = callbackUrl;
17
+ this.issuer = issuer;
18
+ this.tokenExchange = new token_exchange_2.HttpTokenExchange({ baseUrl: client.baseUrl, clientId: client.clientId, fetch });
19
+ if (client.privateKey && client.kid) {
20
+ this.privateKey = (0, request_jwt_1.parsePrivateKey)(client.privateKey);
21
+ }
22
+ else {
23
+ (0, logger_1.log)('warn', 'oauth.token_exchange_client_incomplete', {
24
+ message: 'TOKEN_EXCHANGE_PRIVATE_KEY and TOKEN_EXCHANGE_KID are required for sign-in',
25
+ });
26
+ }
27
+ }
28
+ async authorizationUrl({ state, codeChallenge }) {
29
+ if (!this.privateKey) {
30
+ throw new errors_js_1.ServerError('sign-in is not configured on this server');
31
+ }
32
+ const request = (0, request_jwt_1.signRequestJwt)({
33
+ privateKey: this.privateKey,
34
+ kid: this.client.kid,
35
+ claims: (0, request_jwt_1.requestJwtClaims)({
36
+ issuer: this.issuer,
37
+ clientId: this.client.clientId,
38
+ redirectUri: this.callbackUrl.href,
39
+ state,
40
+ codeChallenge,
41
+ }),
42
+ });
43
+ let pending;
44
+ try {
45
+ pending = await this.tokenExchange.createRequest(request);
46
+ }
47
+ catch (error) {
48
+ if (error instanceof token_exchange_1.TokenExchangeError) {
49
+ (0, logger_1.log)('error', 'oauth.token_exchange.request_failed', { error: error.message });
50
+ throw new errors_js_1.ServerError('could not start sign-in with the Decodo backend');
51
+ }
52
+ throw error;
53
+ }
54
+ const url = new URL(this.dashboardAuthorizeUrl);
55
+ url.searchParams.set(exports.DASHBOARD_QUERY.REQUEST_UUID, pending.uuid);
56
+ return url;
57
+ }
58
+ exchange(params) {
59
+ return this.tokenExchange.exchange(params);
60
+ }
61
+ }
62
+ exports.DecodoBackend = DecodoBackend;
63
+ const createDecodoBackend = (config, { callbackUrl, fetch }) => new DecodoBackend({
64
+ client: config.tokenExchange,
65
+ dashboardAuthorizeUrl: config.dashboardAuthorizeUrl,
66
+ callbackUrl,
67
+ issuer: config.publicUrl.host,
68
+ fetch,
69
+ });
70
+ exports.createDecodoBackend = createDecodoBackend;
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/oauth/backends/decodo/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyRequestJwt = exports.parsePrivateKey = exports.requestJwtClaims = exports.signRequestJwt = exports.REQUEST_JWT = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ exports.REQUEST_JWT = {
6
+ AUDIENCE: 'subscription-api',
7
+ SCOPE: 'sapi_token',
8
+ CODE_CHALLENGE_METHOD: 'S256',
9
+ LIFETIME_SECONDS: 120,
10
+ };
11
+ const base64url = (value) => Buffer.from(value).toString('base64url');
12
+ const signRequestJwt = ({ privateKey, kid, claims, }) => {
13
+ const header = { alg: 'RS256', typ: 'JWT', kid };
14
+ const signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(claims))}`;
15
+ const signature = (0, node_crypto_1.sign)('sha256', Buffer.from(signingInput), privateKey);
16
+ return `${signingInput}.${base64url(signature)}`;
17
+ };
18
+ exports.signRequestJwt = signRequestJwt;
19
+ const requestJwtClaims = ({ issuer, clientId, redirectUri, state, codeChallenge, nowSeconds = Math.floor(Date.now() / 1000), }) => ({
20
+ iss: issuer,
21
+ aud: exports.REQUEST_JWT.AUDIENCE,
22
+ iat: nowSeconds,
23
+ exp: nowSeconds + exports.REQUEST_JWT.LIFETIME_SECONDS,
24
+ client_id: clientId,
25
+ redirect_uri: redirectUri,
26
+ state,
27
+ code_challenge: codeChallenge,
28
+ code_challenge_method: exports.REQUEST_JWT.CODE_CHALLENGE_METHOD,
29
+ scope: exports.REQUEST_JWT.SCOPE,
30
+ });
31
+ exports.requestJwtClaims = requestJwtClaims;
32
+ const parsePrivateKey = (pem) => {
33
+ try {
34
+ return (0, node_crypto_1.createPrivateKey)(pem);
35
+ }
36
+ catch (error) {
37
+ throw new Error(`TOKEN_EXCHANGE_PRIVATE_KEY is not a valid PEM private key: ${error.message}`, { cause: error });
38
+ }
39
+ };
40
+ exports.parsePrivateKey = parsePrivateKey;
41
+ const verifyRequestJwt = (token, publicKey) => {
42
+ const [encodedHeader, encodedClaims, encodedSignature, ...rest] = token.split('.');
43
+ if (!encodedHeader || !encodedClaims || !encodedSignature || rest.length > 0) {
44
+ return;
45
+ }
46
+ try {
47
+ const header = JSON.parse(Buffer.from(encodedHeader, 'base64url').toString('utf8'));
48
+ if (header.alg !== 'RS256') {
49
+ return;
50
+ }
51
+ const valid = (0, node_crypto_1.verify)('sha256', Buffer.from(`${encodedHeader}.${encodedClaims}`), publicKey, Buffer.from(encodedSignature, 'base64url'));
52
+ if (!valid) {
53
+ return;
54
+ }
55
+ return { header, claims: JSON.parse(Buffer.from(encodedClaims, 'base64url').toString('utf8')) };
56
+ }
57
+ catch (_a) {
58
+ return;
59
+ }
60
+ };
61
+ exports.verifyRequestJwt = verifyRequestJwt;
62
+ //# sourceMappingURL=request-jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-jwt.js","sourceRoot":"","sources":["../../../../src/oauth/backends/decodo/request-jwt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpTokenExchange = void 0;
4
+ const token_exchange_1 = require("../../token-exchange");
5
+ const REQUEST_TIMEOUT_MS = 5000;
6
+ const STATUS_TO_ERROR = {
7
+ 400: token_exchange_1.TOKEN_EXCHANGE_ERROR.INVALID_GRANT,
8
+ 403: token_exchange_1.TOKEN_EXCHANGE_ERROR.INVALID_CLIENT,
9
+ };
10
+ const APP_CODES = new Set([token_exchange_1.TOKEN_EXCHANGE_ERROR.INVALID_GRANT, token_exchange_1.TOKEN_EXCHANGE_ERROR.INVALID_CLIENT]);
11
+ class HttpTokenExchange {
12
+ constructor({ baseUrl, clientId, fetch = globalThis.fetch }) {
13
+ const base = baseUrl.href.endsWith('/') ? baseUrl.href : `${baseUrl.href}/`;
14
+ this.requestUrl = new URL('request', base);
15
+ this.exchangeUrl = new URL('exchange', base);
16
+ this.clientId = clientId;
17
+ this.fetch = fetch;
18
+ }
19
+ async createRequest(requestJwt) {
20
+ const response = await this.post(this.requestUrl, { client_id: this.clientId, request: requestJwt });
21
+ if (!response.ok) {
22
+ throw new token_exchange_1.TokenExchangeError(token_exchange_1.TOKEN_EXCHANGE_ERROR.SERVER_ERROR, `token exchange request rejected with ${response.status}: ${await this.detail(response)}`);
23
+ }
24
+ const body = (await this.jsonBody(response));
25
+ if (typeof body.uuid !== 'string' || !body.uuid) {
26
+ throw new token_exchange_1.TokenExchangeError(token_exchange_1.TOKEN_EXCHANGE_ERROR.SERVER_ERROR, 'token exchange request response has no uuid');
27
+ }
28
+ return {
29
+ uuid: body.uuid,
30
+ clientName: typeof body.client_name === 'string' ? body.client_name : '',
31
+ expiresAt: typeof body.expires_at === 'string' ? body.expires_at : '',
32
+ };
33
+ }
34
+ async exchange({ code, codeVerifier }) {
35
+ const response = await this.post(this.exchangeUrl, { client_id: this.clientId, code, code_verifier: codeVerifier });
36
+ if (!response.ok) {
37
+ throw new token_exchange_1.TokenExchangeError(await this.errorCode(response), `token exchange responded with ${response.status}`);
38
+ }
39
+ const body = (await this.jsonBody(response));
40
+ if (typeof body.sapi_token !== 'string' || !body.sapi_token) {
41
+ throw new token_exchange_1.TokenExchangeError(token_exchange_1.TOKEN_EXCHANGE_ERROR.SERVER_ERROR, 'token exchange response has no sapi_token');
42
+ }
43
+ return body.sapi_token;
44
+ }
45
+ async post(url, body) {
46
+ try {
47
+ return await this.fetch(url, {
48
+ method: 'POST',
49
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
50
+ body: JSON.stringify(body),
51
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
52
+ });
53
+ }
54
+ catch (error) {
55
+ throw new token_exchange_1.TokenExchangeError(token_exchange_1.TOKEN_EXCHANGE_ERROR.SERVER_ERROR, `token exchange call failed: ${error instanceof Error ? error.message : String(error)}`);
56
+ }
57
+ }
58
+ async jsonBody(response) {
59
+ try {
60
+ return await response.json();
61
+ }
62
+ catch (_a) {
63
+ throw new token_exchange_1.TokenExchangeError(token_exchange_1.TOKEN_EXCHANGE_ERROR.SERVER_ERROR, `token exchange responded ${response.status} with a non-JSON body`);
64
+ }
65
+ }
66
+ async errorBody(response) {
67
+ try {
68
+ return (await response.json());
69
+ }
70
+ catch (_a) {
71
+ return {};
72
+ }
73
+ }
74
+ async detail(response) {
75
+ const body = await this.errorBody(response);
76
+ return typeof body.detail === 'string' ? body.detail : 'no detail';
77
+ }
78
+ async errorCode(response) {
79
+ var _a;
80
+ const body = await this.errorBody(response);
81
+ if (typeof body.app_code === 'string' && APP_CODES.has(body.app_code)) {
82
+ return body.app_code;
83
+ }
84
+ return (_a = STATUS_TO_ERROR[response.status]) !== null && _a !== void 0 ? _a : token_exchange_1.TOKEN_EXCHANGE_ERROR.SERVER_ERROR;
85
+ }
86
+ }
87
+ exports.HttpTokenExchange = HttpTokenExchange;
88
+ //# sourceMappingURL=token-exchange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-exchange.js","sourceRoot":"","sources":["../../../../src/oauth/backends/decodo/token-exchange.ts"],"names":[],"mappings":"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"}