From aaf16f0ccf4764c036d4e38c70065e7f855940aa Mon Sep 17 00:00:00 2001 From: Patrick Nappa Date: Fri, 1 May 2026 10:35:10 +1000 Subject: [PATCH] [NFC] Remove @devhigley/parse-proxy as a dependency This is a random package written by someone, which serves as a risk for supply chain integrity. There is no trusted publishing established for this package, so there's a high risk that it could be taken over & cause an attack against all your consumers. The package isn't very well written, and has some bad handling for cases which are likely to be brought up. The behaviour can be fully implemented using builtins. For example, `localhost:8000` throws, which is a fairly common path to handling proxies, whilst IPv6 support is also non-existent (e.g. http://[::1]:8080 throws). --- README.md | 1 - package.json | 1 - src/ApiClient.js | 41 +++++++++++++++++++++++++++++------------ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3f10bdef..fff6d73c 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,6 @@ This client has the following external dependencies: **Minimum:** * docusign-esign * Axios v1.6.8+ -* @devhigley/parse-proxy v1.0.3+ * Csv-stringify v1.0.0+ * Jsonwebtoken v9.0.0+ * Passport-oauth2 v1.6.1+ diff --git a/package.json b/package.json index 2f3ca40e..86c46dba 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ }, "dependencies": { "axios": "^1.6.8", - "@devhigley/parse-proxy":"^1.0.3", "csv-stringify": "^1.0.0", "jsonwebtoken": "^9.0.0", "passport-oauth2": "^1.6.1", diff --git a/src/ApiClient.js b/src/ApiClient.js index 1e4372cd..d55729e2 100644 --- a/src/ApiClient.js +++ b/src/ApiClient.js @@ -12,23 +12,43 @@ if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module. define(["axios"], factory); - define(["@devhigley/parse-proxy"], factory); - } else if (typeof module === "object" && module.exports) { + } else if (typeof module === "object" && module.exports) { // CommonJS-like environments that support module.exports, like Node. module.exports = factory( - require("axios"), - require("@devhigley/parse-proxy") + require("axios") ); } else { // Browser globals (root is window) if (!root.Docusign) { root.Docusign = {}; } - root.Docusign.ApiClient = factory(root.axios, root.parseProxy, opts); + root.Docusign.ApiClient = factory(root.axios, opts); } -})(this, function (axios, parseProxy, opts) { +})(this, function (axios, opts) { "use strict"; + var DEFAULT_PROXY_PORTS = { "http:": 80, "https:": 443 }; + var parseProxy = function (proxyUri) { + var input = /:\/\//.test(proxyUri) ? proxyUri : "http://" + proxyUri; + var parsed = new URL(input); + // URL strips the default port for the scheme (e.g. http://x:80 -> port ""). + // Restore it from the protocol so axios receives an explicit port. + var proxyConfig = { + host: parsed.hostname, + port: parsed.port + ? parseInt(parsed.port, 10) + : DEFAULT_PROXY_PORTS[parsed.protocol], + protocol: parsed.protocol.replace(":", ""), + }; + if (parsed.username || parsed.password) { + proxyConfig.auth = { + username: decodeURIComponent(parsed.username), + password: decodeURIComponent(parsed.password), + }; + } + return proxyConfig; + }; + /** * The default HTTP headers to be included for all API calls. * @type {Array.} @@ -105,8 +125,7 @@ }; if (proxy) { - const proxyObj = parseProxy(proxy); - requestConfig.proxy = proxyObj[0]; + requestConfig.proxy = parseProxy(proxy); } const oauthRequest = axios.request(requestConfig); @@ -608,8 +627,7 @@ }; if (this.proxy) { - const proxyObj = parseProxy(this.proxy); - requestConfig.proxy = proxyObj[0]; + requestConfig.proxy = parseProxy(this.proxy); } var _formParams = this.normalizeParams(formParams); @@ -977,8 +995,7 @@ headers: headers, }; if (this.proxy) { - const proxyObj = parseProxy(this.proxy); - requestConfig.proxy = proxyObj[0]; + requestConfig.proxy = parseProxy(this.proxy); } const request = axios.request(requestConfig);