nodejs-cookie-proxy-agent 0.0.1-security → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nodejs-cookie-proxy-agent might be problematic. Click here for more details.

package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 dmpzh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,5 +1,55 @@
1
- # Security holding package
2
-
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
4
-
5
- Please refer to www.npmjs.com/advisories?search=nodejs-cookie-proxy-agent for more information.
1
+ # node-cookie-proxy-agent
2
+
3
+ [![npm](https://img.shields.io/npm/v/node-cookie-proxy-agent)](https://www.npmjs.com/package/node-cookie-proxy-agent)
4
+
5
+ HTTP & HTTPS agents with cookie and proxy support. HTTP(s) and SOCKS(v4/v5) are supported.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install node-cookie-proxy-agent http-proxy-agent https-proxy-agent socks-proxy-agent tough-cookie
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Pass `node-cookie-proxy-agent` to HTTP clients instead of http(s).Agent.
16
+
17
+ Exemple with `axios` with HTTP proxy:
18
+
19
+ ```ts
20
+ import axios from 'axios';
21
+ import { HttpCookieProxyAgent, HttpsCookieProxyAgent } from 'node-cookie-proxy-agent';
22
+ import { CookieJar } from 'tough-cookie';
23
+
24
+ // HTTP(s) proxy
25
+ (async () => {
26
+ // initialise this first
27
+ const jar = new CookieJar();
28
+ const proxy = 'http://127.0.0.1:8888'; // or http://id:password@127.0.0.1:8888 to use with authentication
29
+ const httpAgent = new HttpCookieProxyAgent(jar, proxy);
30
+ const httpsAgent = new HttpsCookieProxyAgent(jar, proxy);
31
+
32
+ // add your agents to your http client
33
+ const axiosClient = axios.create({ httpAgent, httpsAgent });
34
+ console.log('result: ', (await axiosClient.get('https://api.ipify.org?format=json')).data);
35
+ })().catch(err => console.error(err));
36
+ ```
37
+
38
+ Exemple with `axios` with SOCKS proxy:
39
+
40
+ ```ts
41
+ import axios from 'axios';
42
+ import { SocksCookieProxyAgent } from 'node-cookie-proxy-agent';
43
+ import { CookieJar } from 'tough-cookie';
44
+
45
+ // SOCKS proxy
46
+ (async () => {
47
+ // initialise this first
48
+ const jar = new CookieJar();
49
+ const agent = new SocksCookieProxyAgent(jar, 'socks://127.0.0.1:8888');
50
+
51
+ // add your agent to your http client
52
+ const axiosClient = axios.create({ httpAgent: agent, httpsAgent: agent });
53
+ console.log('result: ', (await axiosClient.get('https://api.ipify.org?format=json')).data);
54
+ })().catch(err => console.error(err));
55
+ ```
@@ -0,0 +1,40 @@
1
+ /// <reference types="node" />
2
+ import { Agent, ClientRequest, RequestOptions } from 'agent-base';
3
+ import createHttpProxyAgent, { HttpProxyAgent } from 'http-proxy-agent';
4
+ import createHttpsProxyAgent, { HttpsProxyAgent } from 'https-proxy-agent';
5
+ import { Socket } from 'net';
6
+ import 'axios-proxy';
7
+ import createSocksProxyAgent, { SocksProxyAgent } from 'socks-proxy-agent';
8
+ import { CookieJar } from 'tough-cookie';
9
+ declare module 'agent-base' {
10
+ interface ClientRequest {
11
+ _header: string | null;
12
+ _headerSent: boolean;
13
+ _implicitHeader(): void;
14
+ _onPendingData(amount: number): void;
15
+ outputData: Array<{
16
+ callback: unknown;
17
+ data: string;
18
+ encoding: string;
19
+ }>;
20
+ outputSize: number;
21
+ }
22
+ }
23
+ declare abstract class BaseCookieProxyAgent extends Agent {
24
+ private readonly jar;
25
+ private readonly proxyAgent;
26
+ constructor(jar: CookieJar, proxyAgent: HttpProxyAgent | HttpsProxyAgent | SocksProxyAgent);
27
+ private updateRequestCookies;
28
+ private updateRequestEmit;
29
+ callback(req: ClientRequest, opts: RequestOptions): Promise<Socket>;
30
+ }
31
+ export declare class HttpCookieProxyAgent extends BaseCookieProxyAgent {
32
+ constructor(jar: CookieJar, proxy: string | createHttpProxyAgent.HttpProxyAgentOptions);
33
+ }
34
+ export declare class HttpsCookieProxyAgent extends BaseCookieProxyAgent {
35
+ constructor(jar: CookieJar, proxy: string | createHttpsProxyAgent.HttpsProxyAgentOptions);
36
+ }
37
+ export declare class SocksCookieProxyAgent extends BaseCookieProxyAgent {
38
+ constructor(jar: CookieJar, proxy: string | createSocksProxyAgent.SocksProxyAgentOptions);
39
+ }
40
+ export {};
package/bin/agents.js ADDED
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SocksCookieProxyAgent = exports.HttpsCookieProxyAgent = exports.HttpCookieProxyAgent = void 0;
4
+ const agent_base_1 = require("agent-base");
5
+ const http_proxy_agent_1 = require("http-proxy-agent");
6
+ const https_proxy_agent_1 = require("https-proxy-agent");
7
+ require("axios-proxy");
8
+ const socks_proxy_agent_1 = require("socks-proxy-agent");
9
+ const tough_cookie_1 = require("tough-cookie");
10
+ class BaseCookieProxyAgent extends agent_base_1.Agent {
11
+ jar;
12
+ proxyAgent;
13
+ constructor(jar, proxyAgent) {
14
+ super();
15
+ this.jar = jar;
16
+ this.proxyAgent = proxyAgent;
17
+ }
18
+ updateRequestCookies(req, requestUrl) {
19
+ // generate cookie header
20
+ const cookies = this.jar.getCookiesSync(requestUrl);
21
+ const cookiesMap = new Map(cookies.map(cookie => [cookie.key, cookie]));
22
+ const cookieHeaderList = [req.getHeader('Cookie')].flat();
23
+ for (const header of cookieHeaderList) {
24
+ if (typeof header !== 'string')
25
+ continue;
26
+ for (const str of header.split(';')) {
27
+ const cookie = tough_cookie_1.Cookie.parse(str.trim());
28
+ if (cookie === undefined) {
29
+ continue;
30
+ }
31
+ cookiesMap.set(cookie.key, cookie);
32
+ }
33
+ }
34
+ const cookieHeader = Array.from(cookiesMap.values())
35
+ .map(cookie => cookie.cookieString())
36
+ .join(';\x20');
37
+ // assign the header
38
+ if (cookieHeader) {
39
+ if (req._header === null) {
40
+ req.setHeader('Cookie', cookieHeader);
41
+ return;
42
+ }
43
+ const alreadyHeaderSent = req._headerSent;
44
+ req._header = null;
45
+ req.setHeader('Cookie', cookieHeader);
46
+ req._implicitHeader();
47
+ req._headerSent = alreadyHeaderSent;
48
+ if (alreadyHeaderSent !== true)
49
+ return;
50
+ const firstChunk = req.outputData.shift();
51
+ if (firstChunk === undefined)
52
+ return;
53
+ const dataWithoutHeader = firstChunk.data.split('\r\n\r\n').slice(1).join('\r\n\r\n');
54
+ const chunk = {
55
+ ...firstChunk,
56
+ data: `${req._header}${dataWithoutHeader}`
57
+ };
58
+ req.outputData.unshift(chunk);
59
+ const diffSize = chunk.data.length - firstChunk.data.length;
60
+ req.outputSize += diffSize;
61
+ req._onPendingData(diffSize);
62
+ }
63
+ }
64
+ updateRequestEmit(req, requestUrl) {
65
+ const emit = req.emit.bind(req);
66
+ req.emit = (event, ...args) => {
67
+ if (event !== 'response')
68
+ return emit(event, ...args);
69
+ const res = args[0];
70
+ (async () => {
71
+ const cookies = res.headers['set-cookie'];
72
+ if (cookies !== undefined) {
73
+ for (const cookie of cookies) {
74
+ await this.jar.setCookie(cookie, requestUrl, { ignoreError: true });
75
+ }
76
+ }
77
+ })()
78
+ .then(() => emit('response', res))
79
+ .catch(err => emit('error', err));
80
+ return req.listenerCount(event) !== 0;
81
+ };
82
+ }
83
+ callback(req, opts) {
84
+ // perform cookie agent
85
+ const url = String(Object.assign(new URL('http://a.com'), { host: req.host, pathname: req.path, protocol: req.protocol }));
86
+ this.updateRequestCookies(req, url);
87
+ this.updateRequestEmit(req, url);
88
+ // send request via proxy
89
+ return this.proxyAgent.callback(req, opts);
90
+ }
91
+ }
92
+ class HttpCookieProxyAgent extends BaseCookieProxyAgent {
93
+ constructor(jar, proxy) {
94
+ super(jar, new http_proxy_agent_1.HttpProxyAgent(proxy));
95
+ }
96
+ }
97
+ exports.HttpCookieProxyAgent = HttpCookieProxyAgent;
98
+ class HttpsCookieProxyAgent extends BaseCookieProxyAgent {
99
+ constructor(jar, proxy) {
100
+ super(jar, new https_proxy_agent_1.HttpsProxyAgent(proxy));
101
+ }
102
+ }
103
+ exports.HttpsCookieProxyAgent = HttpsCookieProxyAgent;
104
+ class SocksCookieProxyAgent extends BaseCookieProxyAgent {
105
+ constructor(jar, proxy) {
106
+ super(jar, new socks_proxy_agent_1.SocksProxyAgent(proxy));
107
+ }
108
+ }
109
+ exports.SocksCookieProxyAgent = SocksCookieProxyAgent;
110
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "nodejs-cookie-proxy-agent",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
3
+ "version": "1.2.0",
4
+ "description": "HTTP & HTTPS agents with cookie and proxy support",
5
+ "main": "bin/agents.js",
6
+ "types": "bin/agents.d.ts",
7
+ "files": [
8
+ "bin",
9
+ "src"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc --build",
13
+ "lint": "eslint --config ./.eslintrc --ignore-path ./.eslintignore --ext .js,.ts .",
14
+ "peerInstall": "npm i --no-package-lock",
15
+ "prettier": "prettier --config ./.prettierrc --write \"**/*.{js,json,md,ts}\"",
16
+ "prettier:check": "prettier --check --config ./.prettierrc \"**/*.{js,json,md,ts}\""
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/dmpzh/node-cookie-proxy-agent.git"
21
+ },
22
+ "keywords": [
23
+ "node",
24
+ "cookie",
25
+ "proxy",
26
+ "agent",
27
+ "http",
28
+ "https",
29
+ "socks",
30
+ "axios"
31
+ ],
32
+ "author": "dmpzh",
33
+ "license": "MIT",
34
+ "bugs": {
35
+ "url": "https://github.com/dmpzh/node-cookie-proxy-agent/issues"
36
+ },
37
+ "homepage": "https://github.com/dmpzh/node-cookie-proxy-agent#readme",
38
+ "devDependencies": {
39
+ "@types/node": "^17.0.30",
40
+ "@types/tough-cookie": "^4.0.2",
41
+ "@typescript-eslint/eslint-plugin": "^5.21.0",
42
+ "@typescript-eslint/parser": "^5.21.0",
43
+ "eslint": "^8.14.0",
44
+ "eslint-config-prettier": "^8.5.0",
45
+ "husky": "^7.0.4",
46
+ "prettier": "^2.6.2",
47
+ "typescript": "^4.6.3"
48
+ },
49
+ "peerDependencies": {
50
+ "http-proxy-agent": "^5.0.0",
51
+ "https-proxy-agent": "^5.0.1",
52
+ "socks-proxy-agent": "^6.2.0",
53
+ "tough-cookie": "^4.0.0"
54
+ },
55
+ "dependencies": {
56
+ "agent-base": "^6.0.2",
57
+ "axios-proxy": "^1.7.3"
58
+ }
6
59
  }
package/src/agents.ts ADDED
@@ -0,0 +1,133 @@
1
+ import { Agent, ClientRequest, RequestOptions } from 'agent-base';
2
+ import { IncomingMessage } from 'http';
3
+ import createHttpProxyAgent, { HttpProxyAgent } from 'http-proxy-agent';
4
+ import createHttpsProxyAgent, { HttpsProxyAgent } from 'https-proxy-agent';
5
+ import { Socket } from 'net';
6
+ import 'axios-proxy';
7
+ import createSocksProxyAgent, { SocksProxyAgent } from 'socks-proxy-agent';
8
+ import { Cookie, CookieJar } from 'tough-cookie';
9
+
10
+ declare module 'agent-base' {
11
+ interface ClientRequest {
12
+ _header: string | null;
13
+ _headerSent: boolean;
14
+ _implicitHeader(): void;
15
+ _onPendingData(amount: number): void;
16
+ outputData: Array<{
17
+ callback: unknown;
18
+ data: string;
19
+ encoding: string;
20
+ }>;
21
+ outputSize: number;
22
+ }
23
+ }
24
+
25
+ abstract class BaseCookieProxyAgent extends Agent {
26
+ private readonly jar: CookieJar;
27
+ private readonly proxyAgent: HttpProxyAgent | HttpsProxyAgent | SocksProxyAgent;
28
+
29
+ constructor(jar: CookieJar, proxyAgent: HttpProxyAgent | HttpsProxyAgent | SocksProxyAgent) {
30
+ super();
31
+ this.jar = jar;
32
+ this.proxyAgent = proxyAgent;
33
+ }
34
+
35
+ private updateRequestCookies(req: ClientRequest, requestUrl: string) {
36
+ // generate cookie header
37
+ const cookies = this.jar.getCookiesSync(requestUrl);
38
+ const cookiesMap = new Map(cookies.map(cookie => [cookie.key, cookie]));
39
+ const cookieHeaderList = [req.getHeader('Cookie')].flat();
40
+ for (const header of cookieHeaderList) {
41
+ if (typeof header !== 'string') continue;
42
+
43
+ for (const str of header.split(';')) {
44
+ const cookie = Cookie.parse(str.trim());
45
+ if (cookie === undefined) {
46
+ continue;
47
+ }
48
+ cookiesMap.set(cookie.key, cookie);
49
+ }
50
+ }
51
+ const cookieHeader = Array.from(cookiesMap.values())
52
+ .map(cookie => cookie.cookieString())
53
+ .join(';\x20');
54
+
55
+ // assign the header
56
+ if (cookieHeader) {
57
+ if (req._header === null) {
58
+ req.setHeader('Cookie', cookieHeader);
59
+ return;
60
+ }
61
+ const alreadyHeaderSent = req._headerSent;
62
+
63
+ req._header = null;
64
+ req.setHeader('Cookie', cookieHeader);
65
+ req._implicitHeader();
66
+ req._headerSent = alreadyHeaderSent;
67
+
68
+ if (alreadyHeaderSent !== true) return;
69
+
70
+ const firstChunk = req.outputData.shift();
71
+ if (firstChunk === undefined) return;
72
+ const dataWithoutHeader = firstChunk.data.split('\r\n\r\n').slice(1).join('\r\n\r\n');
73
+ const chunk = {
74
+ ...firstChunk,
75
+ data: `${req._header}${dataWithoutHeader}`
76
+ };
77
+ req.outputData.unshift(chunk);
78
+
79
+ const diffSize = chunk.data.length - firstChunk.data.length;
80
+ req.outputSize += diffSize;
81
+ req._onPendingData(diffSize);
82
+ }
83
+ }
84
+
85
+ private updateRequestEmit(req: ClientRequest, requestUrl: string) {
86
+ const emit = req.emit.bind(req);
87
+ req.emit = (event: string, ...args: unknown[]): boolean => {
88
+ if (event !== 'response') return emit(event, ...args);
89
+ const res = args[0] as IncomingMessage;
90
+ (async () => {
91
+ const cookies = res.headers['set-cookie'];
92
+ if (cookies !== undefined) {
93
+ for (const cookie of cookies) {
94
+ await this.jar.setCookie(cookie, requestUrl, { ignoreError: true });
95
+ }
96
+ }
97
+ })()
98
+ .then(() => emit('response', res))
99
+ .catch(err => emit('error', err));
100
+ return req.listenerCount(event) !== 0;
101
+ };
102
+ }
103
+
104
+ callback(req: ClientRequest, opts: RequestOptions): Promise<Socket> {
105
+ // perform cookie agent
106
+ const url = String(
107
+ Object.assign(new URL('http://a.com'), { host: req.host, pathname: req.path, protocol: req.protocol })
108
+ );
109
+ this.updateRequestCookies(req, url);
110
+ this.updateRequestEmit(req, url);
111
+
112
+ // send request via proxy
113
+ return this.proxyAgent.callback(req as any, opts);
114
+ }
115
+ }
116
+
117
+ export class HttpCookieProxyAgent extends BaseCookieProxyAgent {
118
+ constructor(jar: CookieJar, proxy: string | createHttpProxyAgent.HttpProxyAgentOptions) {
119
+ super(jar, new HttpProxyAgent(proxy));
120
+ }
121
+ }
122
+
123
+ export class HttpsCookieProxyAgent extends BaseCookieProxyAgent {
124
+ constructor(jar: CookieJar, proxy: string | createHttpsProxyAgent.HttpsProxyAgentOptions) {
125
+ super(jar, new HttpsProxyAgent(proxy));
126
+ }
127
+ }
128
+
129
+ export class SocksCookieProxyAgent extends BaseCookieProxyAgent {
130
+ constructor(jar: CookieJar, proxy: string | createSocksProxyAgent.SocksProxyAgentOptions) {
131
+ super(jar, new SocksProxyAgent(proxy));
132
+ }
133
+ }