@mherod/get-cookie 2.0.0-rc.8 → 2.1.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.
- package/.idea/runConfigurations/build.xml +12 -0
- package/.parcelrc +12 -0
- package/.prettierignore +5 -0
- package/.prettierrc +12 -0
- package/.terserrc +26 -0
- package/README.md +2 -2
- package/build-indexes.ts +108 -0
- package/dist/cli.js +2 -0
- package/dist/index.js +1 -823
- package/dist/index.js.map +1 -0
- package/dist/module.js +1446 -0
- package/dist/module.js.map +1 -0
- package/dist/prompt.2b8c61c0.js +40 -0
- package/dist/prompt.536a2c51.js +40 -0
- package/dist/prompt.fb2c7dad.js.map +1 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/jest.config.ts +14 -0
- package/package-lock.json +3862 -8098
- package/package.json +49 -35
- package/src/CookieRow.ts +8 -0
- package/src/CookieSpec.ts +20 -0
- package/src/CookieStore.ts +24 -7
- package/src/ExportedCookie.ts +12 -0
- package/src/FetchResponse.ts +1 -3
- package/src/FileCookieStore.ts +178 -0
- package/src/StringToRegex.ts +10 -0
- package/src/argv.ts +27 -2
- package/src/browsers/CompositeCookieQueryStrategy.ts +36 -38
- package/src/browsers/CookieQueryStrategy.ts +1 -0
- package/src/browsers/CookieStoreQueryStrategy.ts +29 -22
- package/src/browsers/QuerySqliteThenTransform.ts +85 -0
- package/src/browsers/chrome/ChromeApplicationSupport.ts +10 -0
- package/src/browsers/chrome/ChromeCookieQueryStrategy.ts +131 -0
- package/src/browsers/chrome/decrypt.ts +118 -0
- package/src/browsers/chrome/getChromePassword.ts +11 -0
- package/src/browsers/{FirefoxCookieQueryStrategy.ts → firefox/FirefoxCookieQueryStrategy.ts} +19 -16
- package/src/browsers/getEncryptedChromeCookie.ts +87 -0
- package/src/browsers/index.ts +12 -0
- package/src/browsers/mock/MockCookieQueryStrategy.ts +18 -0
- package/src/browsers/{SafariCookieQueryStrategy.ts → safari/SafariCookieQueryStrategy.ts} +3 -2
- package/src/cli.ts +43 -67
- package/src/cliQueryCookies.ts +55 -0
- package/src/comboQueryCookieSpec.test.ts +92 -0
- package/src/comboQueryCookieSpec.ts +29 -0
- package/src/cookieQueryOptions.ts +20 -0
- package/src/cookieSpecsFromUrl.test.ts +65 -0
- package/src/cookieSpecsFromUrl.ts +27 -0
- package/src/execSimple.ts +13 -0
- package/src/fetchWithCookies.test.ts +32 -0
- package/src/fetchWithCookies.ts +124 -47
- package/src/findAllFiles.ts +25 -49
- package/src/getChromeCookie.ts +6 -4
- package/src/getCookie.ts +6 -3
- package/src/getFirefoxCookie.ts +6 -4
- package/src/getGroupedRenderedCookies.ts +7 -17
- package/src/getMergedRenderedCookies.test.ts +43 -0
- package/src/getMergedRenderedCookies.ts +17 -0
- package/src/global.ts +1 -1
- package/src/index.ts +2 -7
- package/src/isValidJwt.ts +2 -2
- package/src/listChromeProfiles.ts +45 -0
- package/src/logger.ts +13 -0
- package/src/processBeforeReturn.ts +26 -0
- package/src/queryCookies.ts +11 -3
- package/src/util/flatMapAsync.test.ts +55 -0
- package/src/util/flatMapAsync.ts +37 -0
- package/src/util/index.ts +1 -0
- package/tsconfig.json +14 -11
- package/.github/dependabot.yml +0 -6
- package/.prettierrc.json +0 -1
- package/src/IsCookieRow.ts +0 -9
- package/src/IsExportedCookie.ts +0 -9
- package/src/browsers/ChromeCookieQueryStrategy.ts +0 -343
- package/src/doSqliteQuery1.ts +0 -47
- package/src/doSqliteQuery1Params.ts +0 -7
- package/src/utils.ts +0 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mherod/get-cookie",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
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",
|
|
@@ -11,40 +11,44 @@
|
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"clean": "git clean -fdX && rm -rf
|
|
15
|
-
"
|
|
16
|
-
"
|
|
14
|
+
"clean": "git clean -fdX && rm -rf dist && yarn install",
|
|
15
|
+
"lintfix": "prettier --write \"src/**/*.ts\"",
|
|
16
|
+
"prebuild": "npm run lintfix",
|
|
17
|
+
"tsc": "tsc",
|
|
18
|
+
"build": "parcel build --no-cache",
|
|
19
|
+
"prepare": "parcel build --no-cache",
|
|
17
20
|
"test": "jest",
|
|
18
|
-
"postbuild": "npm run check",
|
|
19
21
|
"prepublish": "npm run build",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"postinstall:global": "find $NVM_BIN -exec chmod +x {} \\; || true",
|
|
23
|
-
"prettier": "prettier --write 'src/{**/*,*}.{js,json,ts}'",
|
|
24
|
-
"check": "tsc --noEmit"
|
|
22
|
+
"install:global": "npm run build && npm install --global .",
|
|
23
|
+
"prettier": "prettier --write ."
|
|
25
24
|
},
|
|
26
25
|
"targets": {
|
|
27
|
-
"main": {},
|
|
28
26
|
"types": {},
|
|
29
|
-
"
|
|
27
|
+
"main": {
|
|
30
28
|
"source": "src/index.ts",
|
|
31
29
|
"distDir": "dist",
|
|
32
30
|
"isLibrary": true,
|
|
33
31
|
"engines": {
|
|
34
|
-
"node": "16"
|
|
32
|
+
"node": ">= 16"
|
|
35
33
|
},
|
|
36
|
-
"
|
|
34
|
+
"sourceMap": false,
|
|
35
|
+
"optimize": true,
|
|
36
|
+
"includeNodeModules": {
|
|
37
|
+
"@mapbox/node-pre-gyp": false
|
|
38
|
+
}
|
|
37
39
|
},
|
|
38
40
|
"cli": {
|
|
39
41
|
"source": "src/cli.ts",
|
|
40
42
|
"distDir": "dist",
|
|
41
43
|
"isLibrary": false,
|
|
42
44
|
"engines": {
|
|
43
|
-
"node": "16"
|
|
45
|
+
"node": ">= 16"
|
|
44
46
|
},
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
"sourceMap": false,
|
|
48
|
+
"optimize": true,
|
|
49
|
+
"includeNodeModules": {
|
|
50
|
+
"@mapbox/node-pre-gyp": false
|
|
51
|
+
}
|
|
48
52
|
}
|
|
49
53
|
},
|
|
50
54
|
"@parcel/transformer-js": {
|
|
@@ -52,37 +56,47 @@
|
|
|
52
56
|
"inlineEnvironment": true
|
|
53
57
|
},
|
|
54
58
|
"engines": {
|
|
55
|
-
"node": "16"
|
|
59
|
+
"node": ">= 16"
|
|
56
60
|
},
|
|
57
61
|
"keywords": [],
|
|
58
62
|
"author": "Matthew Herod",
|
|
59
63
|
"license": "ISC",
|
|
60
64
|
"dependencies": {
|
|
61
|
-
"
|
|
62
|
-
"cross-fetch": "^
|
|
63
|
-
"destr": "
|
|
64
|
-
"
|
|
65
|
+
"consola": "3.2.3",
|
|
66
|
+
"cross-fetch": "^4.0.0",
|
|
67
|
+
"destr": "2.0.2",
|
|
68
|
+
"fast-glob": "^3.3.1",
|
|
69
|
+
"jsonwebtoken": "9.0.0",
|
|
65
70
|
"lodash": "^4.17.21",
|
|
71
|
+
"lodash-es": "^4.17.21",
|
|
66
72
|
"lru-cache": "^7.14.0",
|
|
67
|
-
"minimist": "^1.2.
|
|
68
|
-
"sqlite3": "^5.1.
|
|
69
|
-
"tough-cookie": "^4.1.2"
|
|
70
|
-
"tough-cookie-file-store": "^2.0.3",
|
|
71
|
-
"user-agents": "^1.0.1165"
|
|
73
|
+
"minimist": "^1.2.7",
|
|
74
|
+
"sqlite3": "^5.1.6",
|
|
75
|
+
"tough-cookie": "^4.1.2"
|
|
72
76
|
},
|
|
73
77
|
"devDependencies": {
|
|
74
|
-
"@
|
|
75
|
-
"@
|
|
78
|
+
"@jest/globals": "^29.7.0",
|
|
79
|
+
"@mapbox/node-pre-gyp": "^1.0.11",
|
|
80
|
+
"@parcel/packager-ts": "^2.10.1",
|
|
81
|
+
"@parcel/transformer-typescript-tsc": "^2.10.1",
|
|
82
|
+
"@parcel/transformer-typescript-types": "^2.10.1",
|
|
83
|
+
"@types/jest": "^29.5.6",
|
|
76
84
|
"@types/jsonwebtoken": "^8.5.9",
|
|
77
85
|
"@types/lodash": "^4.14.186",
|
|
78
86
|
"@types/minimist": "^1.2.2",
|
|
79
|
-
"@types/node": "^18.
|
|
87
|
+
"@types/node": "^18.11.4",
|
|
80
88
|
"@types/tough-cookie": "^4.0.2",
|
|
81
89
|
"@types/user-agents": "^1.0.2",
|
|
82
|
-
"jest": "^29.0
|
|
83
|
-
"parcel": "^2.
|
|
84
|
-
"prettier": "^
|
|
90
|
+
"jest": "^29.7.0",
|
|
91
|
+
"parcel": "^2.10.1",
|
|
92
|
+
"prettier": "^3.0.3",
|
|
93
|
+
"ts-jest": "^29.1.1",
|
|
85
94
|
"ts-node": "^10.9.1",
|
|
86
|
-
"typescript": "^
|
|
95
|
+
"typescript": "^5.1.6"
|
|
96
|
+
},
|
|
97
|
+
"parcelDependencies": {
|
|
98
|
+
"@parcel/transformer-typescript-tsc": "^2.10.1",
|
|
99
|
+
"@parcel/transformer-typescript-types": "^2.10.1",
|
|
100
|
+
"@parcel/packager-ts": "^2.10.1"
|
|
87
101
|
}
|
|
88
102
|
}
|
package/src/CookieRow.ts
CHANGED
package/src/CookieSpec.ts
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
|
+
// Define the CookieSpec interface with domain and name properties
|
|
1
2
|
export default interface CookieSpec {
|
|
2
3
|
domain: string;
|
|
3
4
|
name: string;
|
|
4
5
|
}
|
|
6
|
+
|
|
7
|
+
// Function to check if an object is of type CookieSpec
|
|
8
|
+
export function isCookieSpec(obj: any): obj is CookieSpec {
|
|
9
|
+
return (
|
|
10
|
+
// Check if domain and name properties are of type string
|
|
11
|
+
typeof obj.domain === "string" && typeof obj.name === "string"
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Define a type that can be either a single CookieSpec or an array of CookieSpecs
|
|
16
|
+
export type MultiCookieSpec = CookieSpec | CookieSpec[];
|
|
17
|
+
|
|
18
|
+
// Function to check if an object is of type MultiCookieSpec
|
|
19
|
+
export function isMultiCookieSpec(obj: any): obj is MultiCookieSpec {
|
|
20
|
+
return (
|
|
21
|
+
// Check if the object is a CookieSpec or an array of CookieSpecs
|
|
22
|
+
isCookieSpec(obj) || (Array.isArray(obj) && obj.every(isCookieSpec))
|
|
23
|
+
);
|
|
24
|
+
}
|
package/src/CookieStore.ts
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
import { CookieJar } from "tough-cookie";
|
|
2
1
|
import { env } from "./global";
|
|
3
|
-
|
|
2
|
+
import { parsedArgs } from "./argv";
|
|
3
|
+
import { CookieJar, MemoryCookieStore, Store } from "tough-cookie";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
`${env["HOME"]}/cookie-star.json`
|
|
7
|
-
);
|
|
8
|
-
// export const cookieStore = new MemoryCookieStore();
|
|
5
|
+
import { FileCookieStore } from "./FileCookieStore";
|
|
9
6
|
|
|
10
|
-
|
|
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;
|
|
19
|
+
}
|
|
20
|
+
|
|
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
|
+
});
|
package/src/ExportedCookie.ts
CHANGED
|
@@ -5,3 +5,15 @@ export default interface ExportedCookie {
|
|
|
5
5
|
expiry?: Date | "Infinity";
|
|
6
6
|
meta?: any;
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
export function isExportedCookie(obj: any): obj is ExportedCookie {
|
|
10
|
+
return (
|
|
11
|
+
typeof obj.domain === "string" &&
|
|
12
|
+
typeof obj.name === "string" &&
|
|
13
|
+
typeof obj.value === "string" &&
|
|
14
|
+
(obj.expiry === undefined ||
|
|
15
|
+
obj.expiry instanceof Date ||
|
|
16
|
+
obj.expiry === "Infinity") &&
|
|
17
|
+
(obj.meta === undefined || typeof obj.meta === "object")
|
|
18
|
+
);
|
|
19
|
+
}
|
package/src/FetchResponse.ts
CHANGED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Cookie, MemoryCookieStore, Store } from "tough-cookie";
|
|
2
|
+
import { existsSync, writeFile } from "fs";
|
|
3
|
+
import destr from "destr";
|
|
4
|
+
import { merge } from "lodash";
|
|
5
|
+
import { readFile } from "fs/promises";
|
|
6
|
+
import logger from "./logger";
|
|
7
|
+
|
|
8
|
+
export class FileCookieStore extends Store {
|
|
9
|
+
private readonly internalStore: Store;
|
|
10
|
+
|
|
11
|
+
synchronous: boolean = false;
|
|
12
|
+
filePath: string;
|
|
13
|
+
|
|
14
|
+
private tasks: Promise<any>[] = [];
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
filePath: string,
|
|
18
|
+
internalStore: Store = new MemoryCookieStore(),
|
|
19
|
+
) {
|
|
20
|
+
super();
|
|
21
|
+
|
|
22
|
+
this.filePath = filePath;
|
|
23
|
+
this.internalStore = internalStore ?? new MemoryCookieStore();
|
|
24
|
+
|
|
25
|
+
logger.debug("Importing cookies from", filePath, internalStore);
|
|
26
|
+
|
|
27
|
+
this.tasks.push(
|
|
28
|
+
this.importSaved(filePath, internalStore).then(
|
|
29
|
+
console.log,
|
|
30
|
+
console.error,
|
|
31
|
+
),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private async importSaved(filePath: string, store: Store): Promise<Cookie[]> {
|
|
36
|
+
const cookies: Cookie[] = [];
|
|
37
|
+
if (existsSync(filePath)) {
|
|
38
|
+
const data: string = await readFile(filePath, "utf8");
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
const cookies: any[] = Object.values(destr(data))
|
|
41
|
+
.flatMap((domainCookies: any) => Object.values(domainCookies))
|
|
42
|
+
.flatMap((domainCookies: any) => Object.values(domainCookies));
|
|
43
|
+
if (process.env["DEBUG"]) {
|
|
44
|
+
logger.start("Importing", cookies.length, "cookies");
|
|
45
|
+
}
|
|
46
|
+
const array = Array.isArray(cookies) ? cookies : Object.values(cookies);
|
|
47
|
+
const put = await Promise.all(
|
|
48
|
+
array.map((cookie) => {
|
|
49
|
+
const fromJSON = Cookie.fromJSON(cookie);
|
|
50
|
+
if (fromJSON) {
|
|
51
|
+
return this.putCookieInternal(fromJSON, store);
|
|
52
|
+
}
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
cookies.push(...put);
|
|
56
|
+
}
|
|
57
|
+
return cookies;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
findCookie(
|
|
61
|
+
domain: string,
|
|
62
|
+
path: string,
|
|
63
|
+
key: string,
|
|
64
|
+
cb: (err: Error | null, cookie: Cookie | null) => void,
|
|
65
|
+
) {
|
|
66
|
+
this.waitUntilIdle().finally(() => {
|
|
67
|
+
this.internalStore.findCookie(domain, path, key, cb);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
findCookies(
|
|
72
|
+
domain: string,
|
|
73
|
+
path: string,
|
|
74
|
+
allowSpecialUseDomain: boolean,
|
|
75
|
+
cb: (err: Error | null, cookie: Cookie[]) => void,
|
|
76
|
+
) {
|
|
77
|
+
this.waitUntilIdle().finally(() => {
|
|
78
|
+
this.internalStore.findCookies(domain, path, allowSpecialUseDomain, cb);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
putCookie(cookie: Cookie, cb: (err: Error | null) => void) {
|
|
83
|
+
this.internalStore.putCookie(cookie, cb);
|
|
84
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
85
|
+
this.serializeCallback(err, cookies);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
updateCookie(
|
|
90
|
+
oldCookie: Cookie,
|
|
91
|
+
newCookie: Cookie,
|
|
92
|
+
cb: (err: Error | null) => void,
|
|
93
|
+
) {
|
|
94
|
+
this.internalStore.updateCookie(oldCookie, newCookie, cb);
|
|
95
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
96
|
+
this.serializeCallback(err, cookies);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
removeCookie(
|
|
101
|
+
domain: string,
|
|
102
|
+
path: string,
|
|
103
|
+
key: string,
|
|
104
|
+
cb: (err: Error | null) => void,
|
|
105
|
+
) {
|
|
106
|
+
this.internalStore.removeCookie(domain, path, key, cb);
|
|
107
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
108
|
+
this.serializeCallback(err, cookies);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
removeCookies(domain: string, path: string, cb: (err: Error | null) => void) {
|
|
113
|
+
this.internalStore.removeCookies(domain, path, cb);
|
|
114
|
+
this.internalStore.getAllCookies((err, cookies) => {
|
|
115
|
+
this.serializeCallback(err, cookies);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getAllCookies(cb: (err: Error | null, cookie: Cookie[]) => void) {
|
|
120
|
+
this.waitUntilIdle().finally(() => {
|
|
121
|
+
this.internalStore.getAllCookies(cb);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
waitUntilIdle() {
|
|
126
|
+
return Promise.allSettled(this.tasks).catch(logger.error);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private async putCookieInternal(
|
|
130
|
+
cookie: Cookie,
|
|
131
|
+
store: Store,
|
|
132
|
+
): Promise<Cookie> {
|
|
133
|
+
await this.waitUntilIdle();
|
|
134
|
+
return await new Promise<Cookie>(
|
|
135
|
+
(
|
|
136
|
+
resolve: (value: PromiseLike<Cookie> | Cookie) => void,
|
|
137
|
+
reject: (reason?: any) => void,
|
|
138
|
+
) => {
|
|
139
|
+
store.putCookie(cookie, (err: Error | null) => {
|
|
140
|
+
if (err) {
|
|
141
|
+
reject(err);
|
|
142
|
+
} else {
|
|
143
|
+
resolve(cookie);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private serializeCallback(err: Error | null, cookies: Cookie[]) {
|
|
151
|
+
if (err) {
|
|
152
|
+
console.error(err);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const cookieObjs = cookies.map((cookie: Cookie) => cookie);
|
|
156
|
+
const idx: any = {};
|
|
157
|
+
for (const cookie of cookieObjs) {
|
|
158
|
+
const domain = cookie.domain;
|
|
159
|
+
if (typeof domain === "string") {
|
|
160
|
+
const path: string = cookie.path ?? "/";
|
|
161
|
+
const key: string = cookie.key;
|
|
162
|
+
merge(idx, {
|
|
163
|
+
[domain]: {
|
|
164
|
+
[path]: {
|
|
165
|
+
[key]: cookie.toJSON(),
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const stringify = JSON.stringify(idx, null, 2);
|
|
172
|
+
writeFile(this.filePath, stringify, (err) => {
|
|
173
|
+
if (err) {
|
|
174
|
+
console.error(err);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
package/src/StringToRegex.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
// This function converts a string into a regular expression
|
|
1
2
|
export function stringToRegex(s: string): RegExp {
|
|
3
|
+
// Replace all occurrences of '.' with a literal '.'
|
|
2
4
|
const s1 = s.replaceAll(/\./gi, ".");
|
|
5
|
+
// Replace all occurrences of '%' with '.*' to match any number of any characters
|
|
3
6
|
const s2 = s1.replace(/%/g, ".*");
|
|
7
|
+
// Replace all occurrences of '*' with '.*' to match any number of any characters
|
|
4
8
|
const s3 = s2.replace(/\*/g, ".*");
|
|
9
|
+
// Return the new string as a RegExp object
|
|
5
10
|
return new RegExp(s3);
|
|
6
11
|
}
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
%.example.com -> .*\.example\.com
|
|
15
|
+
example.com -> example\.com
|
|
16
|
+
*/
|
package/src/argv.ts
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import minimist from "minimist";
|
|
2
|
+
import { merge } from "lodash";
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
+
export interface MyParsedArgs extends minimist.ParsedArgs {
|
|
5
|
+
verbose: boolean;
|
|
6
|
+
render?: string;
|
|
7
|
+
fetch?: string;
|
|
8
|
+
cs?: string;
|
|
9
|
+
dump?: string;
|
|
10
|
+
"dump-request-headers"?: string;
|
|
11
|
+
"dump-response-headers"?: string;
|
|
12
|
+
"dump-response-body"?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
Usage: get-cookie [name] [domain] [options]
|
|
17
|
+
Options:
|
|
18
|
+
-h, --help: Show this help
|
|
19
|
+
-v, --verbose: Show verbose output
|
|
20
|
+
-d, --dump: Dump all results
|
|
21
|
+
-D, --dump-grouped: Dump all results, grouped by profile
|
|
22
|
+
-r, --render: Render all results
|
|
23
|
+
*/
|
|
4
24
|
|
|
5
|
-
export const
|
|
25
|
+
export const argv: string[] = process.argv ?? [];
|
|
26
|
+
const minimistArgs: minimist.ParsedArgs = minimist(argv.slice(2));
|
|
27
|
+
const defaultOptions = {
|
|
28
|
+
verbose: false,
|
|
29
|
+
};
|
|
30
|
+
export const parsedArgs: MyParsedArgs = merge(defaultOptions, minimistArgs);
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import ChromeCookieQueryStrategy from "./ChromeCookieQueryStrategy";
|
|
2
|
-
import FirefoxCookieQueryStrategy from "./FirefoxCookieQueryStrategy";
|
|
3
|
-
import SafariCookieQueryStrategy from "./SafariCookieQueryStrategy";
|
|
1
|
+
import ChromeCookieQueryStrategy from "./chrome/ChromeCookieQueryStrategy";
|
|
2
|
+
import FirefoxCookieQueryStrategy from "./firefox/FirefoxCookieQueryStrategy";
|
|
3
|
+
import SafariCookieQueryStrategy from "./safari/SafariCookieQueryStrategy";
|
|
4
4
|
import CookieQueryStrategy from "./CookieQueryStrategy";
|
|
5
5
|
import ExportedCookie from "../ExportedCookie";
|
|
6
6
|
import LRUCache from "lru-cache";
|
|
7
|
-
import CookieStoreQueryStrategy from "./CookieStoreQueryStrategy";
|
|
8
|
-
import { red } from "colorette";
|
|
9
7
|
import { merge } from "lodash";
|
|
10
8
|
import { parsedArgs } from "../argv";
|
|
9
|
+
import consola from "consola";
|
|
10
|
+
import { flatMapAsync } from "../util/flatMapAsync";
|
|
11
11
|
|
|
12
|
-
const cache
|
|
13
|
-
|
|
12
|
+
const cache: LRUCache<string, ExportedCookie[]> = new LRUCache<
|
|
13
|
+
string,
|
|
14
|
+
ExportedCookie[]
|
|
15
|
+
>({
|
|
16
|
+
ttl: 1000 * 10, // 10 seconds
|
|
14
17
|
max: 10,
|
|
15
18
|
});
|
|
16
19
|
|
|
@@ -19,11 +22,11 @@ export default class CompositeCookieQueryStrategy
|
|
|
19
22
|
{
|
|
20
23
|
browserName = "all";
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
private readonly strategies;
|
|
23
26
|
|
|
24
27
|
constructor() {
|
|
25
|
-
this
|
|
26
|
-
CookieStoreQueryStrategy,
|
|
28
|
+
this.strategies = [
|
|
29
|
+
// CookieStoreQueryStrategy,
|
|
27
30
|
ChromeCookieQueryStrategy,
|
|
28
31
|
FirefoxCookieQueryStrategy,
|
|
29
32
|
SafariCookieQueryStrategy,
|
|
@@ -35,38 +38,33 @@ export default class CompositeCookieQueryStrategy
|
|
|
35
38
|
async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
|
|
36
39
|
// domain = domain.match(/(\w+.+\w+)/gi)?.pop() ?? domain;
|
|
37
40
|
const key = `${name}:${domain}`;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
if (cache.has(key)) {
|
|
42
|
+
const cached = cache.get(key);
|
|
43
|
+
if (cached) {
|
|
44
|
+
return cached;
|
|
45
|
+
}
|
|
41
46
|
}
|
|
42
47
|
if (parsedArgs.verbose) {
|
|
43
|
-
|
|
48
|
+
consola.log("Querying cookies:", name, domain);
|
|
44
49
|
}
|
|
45
|
-
const results
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
browser: strategy.browserName,
|
|
55
|
-
},
|
|
56
|
-
});
|
|
50
|
+
const results = await flatMapAsync(this.strategies, async (strategy) => {
|
|
51
|
+
return strategy
|
|
52
|
+
.queryCookies(name, domain)
|
|
53
|
+
.then((cookies: ExportedCookie[]) => {
|
|
54
|
+
return cookies.map((cookie: ExportedCookie) => {
|
|
55
|
+
return merge(cookie, {
|
|
56
|
+
meta: {
|
|
57
|
+
browser: strategy.browserName,
|
|
58
|
+
},
|
|
57
59
|
});
|
|
58
|
-
})
|
|
59
|
-
.catch((e) => {
|
|
60
|
-
console.log(
|
|
61
|
-
red(`Error querying ${strategy.browserName} cookies`),
|
|
62
|
-
e
|
|
63
|
-
);
|
|
64
|
-
return [];
|
|
65
60
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
})
|
|
62
|
+
.catch((e) => {
|
|
63
|
+
consola.error(`Error querying ${strategy.browserName} cookies`, e);
|
|
64
|
+
return [];
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
cache.set(`${name}:${domain}`, results);
|
|
68
|
+
return results;
|
|
71
69
|
}
|
|
72
70
|
}
|
|
@@ -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 {
|
|
@@ -41,7 +41,9 @@ export default class CookieStoreQueryStrategy implements CookieQueryStrategy {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
if (name == "%") {
|
|
44
|
-
return exportedCookies
|
|
44
|
+
return exportedCookies.filter((cookie: ExportedCookie) => {
|
|
45
|
+
return cookie.domain.match(stringToRegex(domain));
|
|
46
|
+
});
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
return exportedCookies.filter((cookie: ExportedCookie) => {
|
|
@@ -57,36 +59,41 @@ export default class CookieStoreQueryStrategy implements CookieQueryStrategy {
|
|
|
57
59
|
domain: cookie.domain ?? cookieSpec.domain,
|
|
58
60
|
name: cookie.key ?? cookieSpec.name,
|
|
59
61
|
value: cookie.value,
|
|
60
|
-
expiry: cookie.expires ?? Infinity,
|
|
62
|
+
expiry: cookie.expires ?? "Infinity",
|
|
61
63
|
meta: {
|
|
62
64
|
file: "tough-cookie",
|
|
63
65
|
},
|
|
64
66
|
};
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
#getCookies(url: string): Promise<Cookie[]> {
|
|
69
|
+
async #getCookies(url: string): Promise<Cookie[]> {
|
|
70
|
+
const cookieJar = await cookieJarPromise;
|
|
68
71
|
return new Promise((resolve, reject) => {
|
|
69
|
-
|
|
70
|
-
|
|
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
|
+
}
|
|
80
|
+
},
|
|
81
|
+
);
|
|
77
82
|
});
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
#getAllCookies(): Promise<Cookie[]> {
|
|
85
|
+
async #getAllCookies(): Promise<Cookie[]> {
|
|
86
|
+
const cookieStore: Store = await cookieStorePromise;
|
|
81
87
|
return new Promise((resolve, reject) => {
|
|
82
|
-
|
|
83
|
-
|
|
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
|
+
}
|
|
95
|
+
},
|
|
96
|
+
);
|
|
90
97
|
});
|
|
91
98
|
}
|
|
92
99
|
}
|