@decodo/mcp-server 1.2.6 → 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 (57) hide show
  1. package/build/auth/credential.js +4 -1
  2. package/build/auth/credential.js.map +1 -1
  3. package/build/clients/hosts.js +10 -0
  4. package/build/clients/hosts.js.map +1 -0
  5. package/build/clients/scraper-api-client.js +15 -5
  6. package/build/clients/scraper-api-client.js.map +1 -1
  7. package/build/index.js +2 -2
  8. package/build/index.js.map +1 -1
  9. package/build/oauth/backend.js +3 -0
  10. package/build/oauth/backend.js.map +1 -0
  11. package/build/oauth/backends/decodo/index.js +71 -0
  12. package/build/oauth/backends/decodo/index.js.map +1 -0
  13. package/build/oauth/backends/decodo/request-jwt.js +62 -0
  14. package/build/oauth/backends/decodo/request-jwt.js.map +1 -0
  15. package/build/oauth/backends/decodo/token-exchange.js +88 -0
  16. package/build/oauth/backends/decodo/token-exchange.js.map +1 -0
  17. package/build/oauth/backends/mock/dashboard.js +84 -0
  18. package/build/oauth/backends/mock/dashboard.js.map +1 -0
  19. package/build/oauth/backends/mock/index.js +42 -0
  20. package/build/oauth/backends/mock/index.js.map +1 -0
  21. package/build/oauth/backends/mock/subscription-api.js +130 -0
  22. package/build/oauth/backends/mock/subscription-api.js.map +1 -0
  23. package/build/oauth/bounded-body.js +29 -0
  24. package/build/oauth/bounded-body.js.map +1 -0
  25. package/build/oauth/clients-store.js +142 -0
  26. package/build/oauth/clients-store.js.map +1 -0
  27. package/build/oauth/config.js +77 -0
  28. package/build/oauth/config.js.map +1 -0
  29. package/build/oauth/cookies.js +25 -0
  30. package/build/oauth/cookies.js.map +1 -0
  31. package/build/oauth/index.js +46 -0
  32. package/build/oauth/index.js.map +1 -0
  33. package/build/oauth/provider.js +172 -0
  34. package/build/oauth/provider.js.map +1 -0
  35. package/build/oauth/redirect-uris.js +17 -0
  36. package/build/oauth/redirect-uris.js.map +1 -0
  37. package/build/oauth/router.js +68 -0
  38. package/build/oauth/router.js.map +1 -0
  39. package/build/oauth/sealer.js +55 -0
  40. package/build/oauth/sealer.js.map +1 -0
  41. package/build/oauth/token-exchange.js +17 -0
  42. package/build/oauth/token-exchange.js.map +1 -0
  43. package/build/oauth/ttl-store.js +47 -0
  44. package/build/oauth/ttl-store.js.map +1 -0
  45. package/build/server/app.js +77 -0
  46. package/build/server/app.js.map +1 -0
  47. package/build/server/revoked-credentials.js +25 -0
  48. package/build/server/revoked-credentials.js.map +1 -0
  49. package/build/server/sapi-base-server.js +2 -2
  50. package/build/server/sapi-base-server.js.map +1 -1
  51. package/build/server/sapi-http-server.js +2 -2
  52. package/build/server/sapi-http-server.js.map +1 -1
  53. package/build/server/trust-proxy.js +19 -0
  54. package/build/server/trust-proxy.js.map +1 -0
  55. package/build/server.js +6 -44
  56. package/build/server.js.map +1 -1
  57. package/package.json +3 -9
@@ -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":"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"}
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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"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.mockDashboardRouter = void 0;
7
+ const express_1 = __importDefault(require("express"));
8
+ const decodo_1 = require("../decodo");
9
+ const subscription_api_1 = require("./subscription-api");
10
+ const escapeHtml = (value) => value.replace(/[&<>"']/g, character => `&#${character.charCodeAt(0)};`);
11
+ const page = (body) => `<!doctype html>
12
+ <html lang="en">
13
+ <head>
14
+ <meta charset="utf-8">
15
+ <meta name="viewport" content="width=device-width, initial-scale=1">
16
+ <title>Decodo mock approval</title>
17
+ <style>
18
+ body { font-family: system-ui, sans-serif; max-width: 32rem; margin: 3rem auto; padding: 0 1rem; color: #1a1a1a; }
19
+ .banner { background: #fff3cd; border: 1px solid #ffe69c; padding: .75rem 1rem; border-radius: .5rem; margin-bottom: 1.5rem; }
20
+ label { display: block; margin: 1rem 0 .25rem; font-weight: 600; }
21
+ input { width: 100%; padding: .5rem; font: inherit; box-sizing: border-box; }
22
+ .actions { display: flex; gap: .75rem; margin-top: 1.5rem; }
23
+ button { padding: .6rem 1.2rem; font: inhe rit; border-radius: .4rem; border: 1px solid #999; background: #fff; cursor: pointer; }
24
+ button[value=approve] { background: #1a1a1a; color: #fff; border-color: #1a1a1a; }
25
+ </style>
26
+ </head>
27
+ <body>
28
+ ${body}
29
+ </body>
30
+ </html>`;
31
+ const mockDashboardRouter = ({ api, defaultScraperApiKey, }) => {
32
+ const router = express_1.default.Router();
33
+ router.use(express_1.default.urlencoded({ extended: false }));
34
+ router.get('/authorize', (req, res) => {
35
+ const uuid = req.query[decodo_1.DASHBOARD_QUERY.REQUEST_UUID];
36
+ const pending = typeof uuid === 'string' ? api.pendingRequest(uuid) : undefined;
37
+ if (!pending) {
38
+ res.status(400).send(page('<h1>Invalid request</h1><p>This connection request is unknown or has expired.</p>'));
39
+ return;
40
+ }
41
+ res.status(200).send(page(`
42
+ <div class="banner">Mock consent page. The real one lives on dashboard.decodo.com.</div>
43
+ <h1>Allow <strong>${escapeHtml(pending.client_id)}</strong> to use your Scraping API key?</h1>
44
+ <form method="post" action="authorize/decision">
45
+ <input type="hidden" name="request_uuid" value="${escapeHtml(pending.uuid)}">
46
+ <label for="scraper_api_key">Scraping API key to release</label>
47
+ <input id="scraper_api_key" name="scraper_api_key" value="${escapeHtml(defaultScraperApiKey)}" placeholder="Paste a real key to make the tools work">
48
+ <div class="actions">
49
+ <button type="submit" name="decision" value="approve">Approve</button>
50
+ <button type="submit" name="decision" value="deny">Deny</button>
51
+ </div>
52
+ </form>`));
53
+ });
54
+ router.post('/authorize/decision', (req, res) => {
55
+ var _a;
56
+ const { request_uuid: uuid, decision, scraper_api_key: scraperApiKey } = (_a = req.body) !== null && _a !== void 0 ? _a : {};
57
+ if (typeof uuid !== 'string' || typeof decision !== 'string') {
58
+ res.status(400).send(page('<h1>Bad request</h1><p>Missing request_uuid or decision.</p>'));
59
+ return;
60
+ }
61
+ const key = typeof scraperApiKey === 'string' && scraperApiKey.trim() ? scraperApiKey.trim() : defaultScraperApiKey;
62
+ let decided;
63
+ try {
64
+ decided = api.decide({ uuid, decision, scraperApiKey: key });
65
+ }
66
+ catch (error) {
67
+ const detail = error instanceof subscription_api_1.MockRequestError ? error.message : 'unexpected error';
68
+ res.status(409).send(page(`<h1>Request can no longer be decided</h1><p>${escapeHtml(detail)}</p>`));
69
+ return;
70
+ }
71
+ const redirect = new URL(decided.redirectUri);
72
+ redirect.searchParams.set('state', decided.state);
73
+ if (decided.code) {
74
+ redirect.searchParams.set('code', decided.code);
75
+ }
76
+ else {
77
+ redirect.searchParams.set('error', decided.error);
78
+ }
79
+ res.redirect(302, redirect.href);
80
+ });
81
+ return router;
82
+ };
83
+ exports.mockDashboardRouter = mockDashboardRouter;
84
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../../src/oauth/backends/mock/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createMockBackend = exports.MOCK_PATH = void 0;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const express_1 = __importDefault(require("express"));
9
+ const logger_1 = require("../../../logger");
10
+ const decodo_1 = require("../decodo");
11
+ const dashboard_1 = require("./dashboard");
12
+ const subscription_api_1 = require("./subscription-api");
13
+ exports.MOCK_PATH = '/mock';
14
+ const MOCK_CLIENT = { clientId: 'mcp-mock', kid: 'mock-key' };
15
+ const createMockBackend = (config, { callbackUrl, fetch }) => {
16
+ const { privateKey, publicKey } = (0, node_crypto_1.generateKeyPairSync)('rsa', {
17
+ modulusLength: 2048,
18
+ privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
19
+ publicKeyEncoding: { type: 'spki', format: 'pem' },
20
+ });
21
+ const dashboardAuthorizeUrl = new URL(`${exports.MOCK_PATH}/dashboard/authorize`, config.publicUrl);
22
+ const baseUrl = new URL(`${exports.MOCK_PATH}/subscription-api/token-exchange`, config.publicUrl);
23
+ const api = new subscription_api_1.MockSubscriptionApi((0, node_crypto_1.createPublicKey)(publicKey), Object.assign(Object.assign({}, MOCK_CLIENT), { redirectUri: callbackUrl.href }));
24
+ const router = express_1.default.Router();
25
+ router.use(`${exports.MOCK_PATH}/dashboard`, (0, dashboard_1.mockDashboardRouter)({ api, defaultScraperApiKey: config.mockScraperApiKey }));
26
+ router.use(`${exports.MOCK_PATH}/subscription-api`, (0, subscription_api_1.mockSubscriptionApiRouter)(api));
27
+ const backend = new decodo_1.DecodoBackend({
28
+ client: Object.assign(Object.assign({}, MOCK_CLIENT), { privateKey, baseUrl }),
29
+ dashboardAuthorizeUrl,
30
+ callbackUrl,
31
+ issuer: config.publicUrl.host,
32
+ fetch,
33
+ });
34
+ (0, logger_1.log)('warn', 'oauth.mock_backend', { dashboardAuthorizeUrl: dashboardAuthorizeUrl.href });
35
+ return {
36
+ authorizationUrl: authorization => backend.authorizationUrl(authorization),
37
+ exchange: params => backend.exchange(params),
38
+ router,
39
+ };
40
+ };
41
+ exports.createMockBackend = createMockBackend;
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/oauth/backends/mock/index.ts"],"names":[],"mappings":";;;;;;AAAA,6CAAmE;AACnE,sDAA8B;AAC9B,4CAAsC;AAEtC,sCAA0C;AAC1C,2CAAkD;AAClD,yDAAoF;AAEvE,QAAA,SAAS,GAAG,OAAO,CAAC;AAEjC,MAAM,WAAW,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AAEvD,MAAM,iBAAiB,GAAwB,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;IACvF,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAA,iCAAmB,EAAC,KAAK,EAAE;QAC3D,aAAa,EAAE,IAAI;QACnB,kBAAkB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;QACpD,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;KACnD,CAAC,CAAC;IAEH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,GAAG,iBAAS,sBAAsB,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5F,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,iBAAS,kCAAkC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAE1F,MAAM,GAAG,GAAG,IAAI,sCAAmB,CAAC,IAAA,6BAAe,EAAC,SAAS,CAAC,kCAAO,WAAW,KAAE,WAAW,EAAE,WAAW,CAAC,IAAI,IAAG,CAAC;IAEnH,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,GAAG,iBAAS,YAAY,EAAE,IAAA,+BAAmB,EAAC,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;IACnH,MAAM,CAAC,GAAG,CAAC,GAAG,iBAAS,mBAAmB,EAAE,IAAA,4CAAyB,EAAC,GAAG,CAAC,CAAC,CAAC;IAE5E,MAAM,OAAO,GAAG,IAAI,sBAAa,CAAC;QAChC,MAAM,kCAAO,WAAW,KAAE,UAAU,EAAE,OAAO,GAAE;QAC/C,qBAAqB;QACrB,WAAW;QACX,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI;QAC7B,KAAK;KACN,CAAC,CAAC;IAEH,IAAA,YAAG,EAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,qBAAqB,EAAE,qBAAqB,CAAC,IAAI,EAAE,CAAC,CAAC;IAEzF,OAAO;QACL,gBAAgB,EAAE,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC;QAC1E,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5C,MAAM;KACP,CAAC;AACJ,CAAC,CAAC;AA/BW,QAAA,iBAAiB,qBA+B5B"}