@mherod/get-cookie 2.0.0-rc.18 → 2.0.0-rc.19
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.
- package/.fleet/settings.json +2 -2
- package/.idea/runConfigurations/build.xml +12 -0
- package/.prettierignore +5 -0
- package/.prettierrc.json +1 -1
- package/README.md +2 -2
- package/dist/index.js +304 -185
- package/package.json +10 -10
- package/src/CookieStore.ts +20 -7
- package/src/FileCookieStore.ts +170 -0
- package/src/browsers/CookieStoreQueryStrategy.ts +23 -18
- package/src/fetchWithCookies.ts +7 -5
- package/tsconfig.json +9 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mherod/get-cookie",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.19",
|
|
4
4
|
"description": "Node.js module for querying a local user's Chrome cookie",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"bin": "dist/cli.js",
|
|
@@ -12,23 +12,22 @@
|
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"clean": "git clean -fdX && rm -rf node_modules dist && yarn install",
|
|
15
|
-
"build": "parcel build",
|
|
16
|
-
"postbuild": "npm run check",
|
|
15
|
+
"build": "tsc && parcel build",
|
|
17
16
|
"prepare": "npm run build && npm run prettier",
|
|
18
17
|
"test": "jest",
|
|
19
18
|
"prepublish": "npm run build",
|
|
20
|
-
"install:global": "npm run build && npm install --
|
|
21
|
-
"prettier": "prettier --write
|
|
22
|
-
"check": "tsc --noEmit"
|
|
19
|
+
"install:global": "npm run build && npm install --global .",
|
|
20
|
+
"prettier": "prettier --write ."
|
|
23
21
|
},
|
|
24
22
|
"targets": {
|
|
23
|
+
"types": {},
|
|
25
24
|
"main": {},
|
|
26
25
|
"library": {
|
|
27
26
|
"source": "src/index.ts",
|
|
28
27
|
"distDir": "dist",
|
|
29
28
|
"isLibrary": true,
|
|
30
29
|
"engines": {
|
|
31
|
-
"node": "16"
|
|
30
|
+
"node": ">= 16"
|
|
32
31
|
},
|
|
33
32
|
"sourceMap": true,
|
|
34
33
|
"includeNodeModules": false
|
|
@@ -38,9 +37,10 @@
|
|
|
38
37
|
"distDir": "dist",
|
|
39
38
|
"isLibrary": false,
|
|
40
39
|
"engines": {
|
|
41
|
-
"node": "16"
|
|
40
|
+
"node": ">= 16"
|
|
42
41
|
},
|
|
43
42
|
"sourceMap": false,
|
|
43
|
+
"optimize": false,
|
|
44
44
|
"includeNodeModules": [
|
|
45
45
|
"colorette"
|
|
46
46
|
]
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"inlineEnvironment": true
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
|
-
"node": "16"
|
|
54
|
+
"node": ">= 16"
|
|
55
55
|
},
|
|
56
56
|
"keywords": [],
|
|
57
57
|
"author": "Matthew Herod",
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
"destr": "^1.2.0",
|
|
63
63
|
"jsonwebtoken": "^8.5.1",
|
|
64
64
|
"lodash": "^4.17.21",
|
|
65
|
+
"lodash-es": "^4.17.21",
|
|
65
66
|
"lru-cache": "^7.14.0",
|
|
66
67
|
"minimist": "^1.2.7",
|
|
67
68
|
"sqlite3": "^5.1.2",
|
|
68
69
|
"tough-cookie": "^4.1.2",
|
|
69
|
-
"tough-cookie-file-store": "^2.0.3",
|
|
70
70
|
"user-agents": "^1.0.1178"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
package/src/CookieStore.ts
CHANGED
|
@@ -2,13 +2,26 @@ import { env } from "./global";
|
|
|
2
2
|
import { parsedArgs } from "./argv";
|
|
3
3
|
import { CookieJar, MemoryCookieStore, Store } from "tough-cookie";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import { FileCookieStore } from "./FileCookieStore";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const memoryCookieStore = new MemoryCookieStore();
|
|
8
|
+
|
|
9
|
+
async function getCookieStore(): Promise<Store> {
|
|
10
|
+
if (parsedArgs["cs"] == "memory") {
|
|
11
|
+
return memoryCookieStore;
|
|
12
|
+
}
|
|
13
|
+
const fileCookieStore = new FileCookieStore(
|
|
14
|
+
`${env["HOME"]}/cookie-star.json`,
|
|
15
|
+
memoryCookieStore
|
|
16
|
+
);
|
|
17
|
+
await fileCookieStore.waitUntilIdle();
|
|
18
|
+
return fileCookieStore;
|
|
12
19
|
}
|
|
13
20
|
|
|
14
|
-
export const
|
|
21
|
+
export const cookieStorePromise: Promise<Store> = new Promise((resolve) => {
|
|
22
|
+
getCookieStore().then(resolve);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const cookieJarPromise: Promise<CookieJar> = new Promise((resolve) => {
|
|
26
|
+
cookieStorePromise.then((store) => new CookieJar(store)).then(resolve);
|
|
27
|
+
});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Cookie, MemoryCookieStore, Store } from "tough-cookie";
|
|
2
|
+
import { existsSync, readFileSync, writeFile } from "fs";
|
|
3
|
+
import destr from "destr";
|
|
4
|
+
import { merge } from "lodash";
|
|
5
|
+
|
|
6
|
+
export class FileCookieStore extends Store {
|
|
7
|
+
private readonly internalStore: Store;
|
|
8
|
+
|
|
9
|
+
synchronous: boolean = false;
|
|
10
|
+
filePath: string;
|
|
11
|
+
|
|
12
|
+
private tasks: Promise<any>[] = [];
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
filePath: string,
|
|
16
|
+
internalStore: Store = new MemoryCookieStore()
|
|
17
|
+
) {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.filePath = filePath;
|
|
21
|
+
this.internalStore = internalStore ?? new MemoryCookieStore();
|
|
22
|
+
|
|
23
|
+
console.log("Importing cookies from", filePath, internalStore);
|
|
24
|
+
|
|
25
|
+
this.tasks.push(
|
|
26
|
+
this.importSaved(filePath, internalStore).then(console.log, console.error)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private async importSaved(filePath: string, store: Store): Promise<Cookie[]> {
|
|
31
|
+
const cookies: Cookie[] = [];
|
|
32
|
+
if (existsSync(filePath)) {
|
|
33
|
+
const data = readFileSync(filePath, "utf8");
|
|
34
|
+
const cookies: any[] = Object.values(destr(data))
|
|
35
|
+
.flatMap((domainCookies: any) => Object.values(domainCookies))
|
|
36
|
+
.flatMap((domainCookies: any) => Object.values(domainCookies));
|
|
37
|
+
console.log("Importing", cookies.length, "cookies");
|
|
38
|
+
const array = Array.isArray(cookies) ? cookies : Object.values(cookies);
|
|
39
|
+
const put = await Promise.all(
|
|
40
|
+
array.map((cookie) => {
|
|
41
|
+
const fromJSON = Cookie.fromJSON(cookie);
|
|
42
|
+
if (fromJSON) {
|
|
43
|
+
return this.putCookieInternal(fromJSON, store);
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
cookies.push(...put);
|
|
48
|
+
}
|
|
49
|
+
return cookies;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
findCookie(
|
|
53
|
+
domain: string,
|
|
54
|
+
path: string,
|
|
55
|
+
key: string,
|
|
56
|
+
cb: (err: Error | null, cookie: Cookie | null) => void
|
|
57
|
+
) {
|
|
58
|
+
this.waitUntilIdle().finally(() => {
|
|
59
|
+
this.internalStore.findCookie(domain, path, key, cb);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
findCookies(
|
|
64
|
+
domain: string,
|
|
65
|
+
path: string,
|
|
66
|
+
allowSpecialUseDomain: boolean,
|
|
67
|
+
cb: (err: Error | null, cookie: Cookie[]) => void
|
|
68
|
+
) {
|
|
69
|
+
this.waitUntilIdle().finally(() => {
|
|
70
|
+
this.internalStore.findCookies(domain, path, allowSpecialUseDomain, cb);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
putCookie(cookie: Cookie, cb: (err: Error | null) => void) {
|
|
75
|
+
this.internalStore.putCookie(cookie, cb);
|
|
76
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
77
|
+
this.serializeCallback(err, cookies);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
updateCookie(
|
|
82
|
+
oldCookie: Cookie,
|
|
83
|
+
newCookie: Cookie,
|
|
84
|
+
cb: (err: Error | null) => void
|
|
85
|
+
) {
|
|
86
|
+
this.internalStore.updateCookie(oldCookie, newCookie, cb);
|
|
87
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
88
|
+
this.serializeCallback(err, cookies);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
removeCookie(
|
|
93
|
+
domain: string,
|
|
94
|
+
path: string,
|
|
95
|
+
key: string,
|
|
96
|
+
cb: (err: Error | null) => void
|
|
97
|
+
) {
|
|
98
|
+
this.internalStore.removeCookie(domain, path, key, cb);
|
|
99
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
100
|
+
this.serializeCallback(err, cookies);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
removeCookies(domain: string, path: string, cb: (err: Error | null) => void) {
|
|
105
|
+
this.internalStore.removeCookies(domain, path, cb);
|
|
106
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
107
|
+
this.serializeCallback(err, cookies);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getAllCookies(cb: (err: Error | null, cookie: Cookie[]) => void) {
|
|
112
|
+
this.waitUntilIdle().finally(() => {
|
|
113
|
+
this.internalStore.getAllCookies(cb);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
waitUntilIdle() {
|
|
118
|
+
return Promise.allSettled(this.tasks).catch(console.error);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private async putCookieInternal(
|
|
122
|
+
cookie: Cookie,
|
|
123
|
+
store: Store
|
|
124
|
+
): Promise<Cookie> {
|
|
125
|
+
await this.waitUntilIdle();
|
|
126
|
+
return await new Promise<Cookie>(
|
|
127
|
+
(
|
|
128
|
+
resolve: (value: PromiseLike<Cookie> | Cookie) => void,
|
|
129
|
+
reject: (reason?: any) => void
|
|
130
|
+
) => {
|
|
131
|
+
store.putCookie(cookie, (err: Error | null) => {
|
|
132
|
+
if (err) {
|
|
133
|
+
reject(err);
|
|
134
|
+
} else {
|
|
135
|
+
resolve(cookie);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private serializeCallback(err: Error | null, cookies: Cookie[]) {
|
|
143
|
+
if (err) {
|
|
144
|
+
console.error(err);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const cookieObjs = cookies.map((cookie: Cookie) => cookie);
|
|
148
|
+
const idx: any = {};
|
|
149
|
+
for (const cookie of cookieObjs) {
|
|
150
|
+
const domain = cookie.domain;
|
|
151
|
+
if (typeof domain === "string") {
|
|
152
|
+
const path: string = cookie.path ?? "/";
|
|
153
|
+
const key: string = cookie.key;
|
|
154
|
+
merge(idx, {
|
|
155
|
+
[domain]: {
|
|
156
|
+
[path]: {
|
|
157
|
+
[key]: cookie.toJSON(),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const stringify = JSON.stringify(idx, null, 2);
|
|
164
|
+
writeFile(this.filePath, stringify, (err) => {
|
|
165
|
+
if (err) {
|
|
166
|
+
console.error(err);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import CookieQueryStrategy from "./CookieQueryStrategy";
|
|
2
2
|
import CookieSpec from "../CookieSpec";
|
|
3
3
|
import ExportedCookie from "../ExportedCookie";
|
|
4
|
-
import { Cookie } from "tough-cookie";
|
|
5
|
-
import {
|
|
4
|
+
import { Cookie, Store } from "tough-cookie";
|
|
5
|
+
import { cookieJarPromise, cookieStorePromise } from "../CookieStore";
|
|
6
6
|
import { stringToRegex } from "../StringToRegex";
|
|
7
7
|
|
|
8
8
|
export default class CookieStoreQueryStrategy implements CookieQueryStrategy {
|
|
@@ -66,29 +66,34 @@ export default class CookieStoreQueryStrategy implements CookieQueryStrategy {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
#getCookies(url: string): Promise<Cookie[]> {
|
|
69
|
+
async #getCookies(url: string): Promise<Cookie[]> {
|
|
70
|
+
const cookieJar = await cookieJarPromise;
|
|
70
71
|
return new Promise((resolve, reject) => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
return cookieJar.getCookies(
|
|
73
|
+
url,
|
|
74
|
+
(err: Error | null, cookies: Cookie[]) => {
|
|
75
|
+
if (err) {
|
|
76
|
+
reject(err);
|
|
77
|
+
} else {
|
|
78
|
+
resolve(cookies ?? []);
|
|
79
|
+
}
|
|
77
80
|
}
|
|
78
|
-
|
|
81
|
+
);
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
#getAllCookies(): Promise<Cookie[]> {
|
|
85
|
+
async #getAllCookies(): Promise<Cookie[]> {
|
|
86
|
+
const cookieStore: Store = await cookieStorePromise;
|
|
83
87
|
return new Promise((resolve, reject) => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
return cookieStore.getAllCookies(
|
|
89
|
+
(err: Error | null, cookies: Cookie[]) => {
|
|
90
|
+
if (err) {
|
|
91
|
+
reject(err);
|
|
92
|
+
} else {
|
|
93
|
+
resolve(cookies ?? []);
|
|
94
|
+
}
|
|
90
95
|
}
|
|
91
|
-
|
|
96
|
+
);
|
|
92
97
|
});
|
|
93
98
|
}
|
|
94
99
|
}
|
package/src/fetchWithCookies.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { fetch as fetchImpl } from "cross-fetch";
|
|
|
4
4
|
import { merge } from "lodash";
|
|
5
5
|
// noinspection SpellCheckingInspection
|
|
6
6
|
import destr from "destr";
|
|
7
|
-
import {
|
|
7
|
+
import { cookieJarPromise } from "./CookieStore";
|
|
8
8
|
import UserAgent from "user-agents";
|
|
9
9
|
import { parsedArgs } from "./argv";
|
|
10
|
-
import { blue, yellow } from "colorette";
|
|
10
|
+
import { blue, redBright, yellow } from "colorette";
|
|
11
11
|
import { getMergedRenderedCookies } from "./getMergedRenderedCookies";
|
|
12
12
|
import { cookieSpecsFromUrl } from "./cookieSpecsFromUrl";
|
|
13
13
|
import CookieSpec from "./CookieSpec";
|
|
@@ -40,6 +40,7 @@ export async function fetchWithCookies(
|
|
|
40
40
|
() => ""
|
|
41
41
|
);
|
|
42
42
|
if (parsedArgs["dump-request-headers"]) {
|
|
43
|
+
console.log(redBright("Request URL:"), url1.href);
|
|
43
44
|
console.log(blue("Request headers:"), headers);
|
|
44
45
|
}
|
|
45
46
|
const newOptions1: RequestInit = merge(defaultOptions, { headers }, options);
|
|
@@ -51,7 +52,8 @@ export async function fetchWithCookies(
|
|
|
51
52
|
});
|
|
52
53
|
for (const [key, value] of headers) {
|
|
53
54
|
if (key === "set-cookie") {
|
|
54
|
-
await
|
|
55
|
+
const cookieJar1 = await cookieJarPromise;
|
|
56
|
+
await cookieJar1.setCookie(value, url2);
|
|
55
57
|
if (parsedArgs.verbose) {
|
|
56
58
|
console.log(blue(`Set-Cookie:`), yellow(value), yellow(url2));
|
|
57
59
|
}
|
|
@@ -59,11 +61,11 @@ export async function fetchWithCookies(
|
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
const newUrl: string = res.headers.get("location") ?? res.url;
|
|
62
|
-
const sameHost = new URL(newUrl).host === url1.host;
|
|
64
|
+
// const sameHost = new URL(newUrl).host === url1.host;
|
|
63
65
|
if (res.status == 301 || res.status == 302) {
|
|
64
66
|
// follow the redirect
|
|
65
67
|
if (newUrl && newUrl !== url2) {
|
|
66
|
-
if (parsedArgs.verbose) {
|
|
68
|
+
if (parsedArgs.verbose || parsedArgs["dump-response-headers"]) {
|
|
67
69
|
console.log(blue(`Redirected to `), yellow(newUrl));
|
|
68
70
|
}
|
|
69
71
|
return fetchWithCookies(
|
package/tsconfig.json
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"include": [
|
|
3
|
-
"src/**.ts",
|
|
4
|
-
"src/**.tsx",
|
|
5
|
-
"src/**.js",
|
|
6
|
-
"src/**.jsx"
|
|
7
|
-
],
|
|
2
|
+
"include": ["src/**.ts", "src/**.tsx", "src/**.js", "src/**.jsx"],
|
|
8
3
|
"compilerOptions": {
|
|
9
4
|
"moduleResolution": "node",
|
|
10
5
|
"target": "es2021",
|
|
11
|
-
"types": [
|
|
12
|
-
|
|
13
|
-
],
|
|
14
|
-
"lib": [
|
|
15
|
-
"es2015",
|
|
16
|
-
"es2017",
|
|
17
|
-
"es2021",
|
|
18
|
-
"dom"
|
|
19
|
-
],
|
|
6
|
+
"types": ["node"],
|
|
7
|
+
"lib": ["es2015", "es2017", "es2021", "dom"],
|
|
20
8
|
"strict": true,
|
|
21
9
|
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"emitDeclarationOnly": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"module": "commonjs",
|
|
14
|
+
"outDir": "dist",
|
|
15
|
+
"outFile": "dist/types.d.ts"
|
|
22
16
|
}
|
|
23
17
|
}
|