@mherod/get-cookie 2.0.0-beta.9 → 2.0.0-rc.2
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/.github/dependabot.yml +6 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.js +93 -40
- package/dist/index.js.map +1 -1
- package/dist/module.js +92 -39
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +6 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -6
- package/src/{CookieRequest.ts → CookieSpec.ts} +1 -1
- package/src/{fetchResponse.ts → FetchResponse.ts} +3 -1
- package/src/IsCookieRow.ts +5 -1
- package/src/IsExportedCookie.ts +5 -1
- package/src/SpecialCases.ts +14 -0
- package/src/browsers/ChromeCookieQueryStrategy.ts +105 -91
- package/src/browsers/CompositeCookieQueryStrategy.ts +21 -3
- package/src/browsers/CookieQueryStrategy.ts +1 -1
- package/src/browsers/FirefoxCookieQueryStrategy.ts +51 -45
- package/src/cli.ts +76 -40
- package/src/doSqliteQuery1.ts +19 -9
- package/src/fetchWithCookies.ts +13 -11
- package/src/findAllFiles.ts +11 -13
- package/src/getGroupedRenderedCookies.ts +6 -6
- package/src/global.ts +2 -1
- package/src/index.ts +12 -9
- package/src/isValidJwt.ts +11 -1
- package/src/queryCookies.ts +2 -5
- package/src/unpackHeaders.ts +13 -0
- package/src/utils.ts +1 -7
|
@@ -23,17 +23,21 @@ export default class ChromeCookieQueryStrategy implements CookieQueryStrategy {
|
|
|
23
23
|
return getChromeCookies({
|
|
24
24
|
requireJwt: false,
|
|
25
25
|
name,
|
|
26
|
-
domain
|
|
26
|
+
domain,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
async function getPromise1(
|
|
31
|
+
async function getPromise1(
|
|
32
|
+
name: string,
|
|
33
|
+
domain: string,
|
|
34
|
+
file: string
|
|
35
|
+
): Promise<CookieRow[]> {
|
|
32
36
|
try {
|
|
33
37
|
return await getEncryptedChromeCookie({
|
|
34
38
|
name: name,
|
|
35
39
|
domain: domain,
|
|
36
|
-
file: file
|
|
40
|
+
file: file,
|
|
37
41
|
});
|
|
38
42
|
} catch (e) {
|
|
39
43
|
if (env.VERBOSE) {
|
|
@@ -47,9 +51,11 @@ async function getPromise(name: string, domain: string): Promise<CookieRow[]> {
|
|
|
47
51
|
try {
|
|
48
52
|
const files: string[] = await findAllFiles({
|
|
49
53
|
path: chromeLocal,
|
|
50
|
-
name: "Cookies"
|
|
54
|
+
name: "Cookies",
|
|
51
55
|
});
|
|
52
|
-
const promises: Promise<CookieRow[]>[] = files.map((file) =>
|
|
56
|
+
const promises: Promise<CookieRow[]>[] = files.map((file) =>
|
|
57
|
+
getPromise1(name, domain, file)
|
|
58
|
+
);
|
|
53
59
|
const results1: Awaited<CookieRow[]>[] = await Promise.all(promises);
|
|
54
60
|
return results1.flat().filter(isCookieRow);
|
|
55
61
|
} catch (error) {
|
|
@@ -73,19 +79,17 @@ async function decryptValue(password: string, encryptedValue: Buffer) {
|
|
|
73
79
|
return d ?? encryptedValue.toString("utf-8");
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
async function getChromeCookies(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
requireJwt: boolean | undefined;
|
|
85
|
-
//
|
|
86
|
-
}
|
|
82
|
+
async function getChromeCookies({
|
|
83
|
+
name,
|
|
84
|
+
domain = "%",
|
|
85
|
+
requireJwt = false,
|
|
86
|
+
}: {
|
|
87
|
+
name: string;
|
|
88
|
+
domain: string;
|
|
89
|
+
requireJwt: boolean | undefined;
|
|
87
90
|
//
|
|
88
|
-
):
|
|
91
|
+
}): //
|
|
92
|
+
Promise<ExportedCookie[]> {
|
|
89
93
|
const encryptedDataItems: CookieRow[] = await getPromise(name, domain);
|
|
90
94
|
const password: string = await getChromePassword();
|
|
91
95
|
const decrypted: Promise<ExportedCookie | null>[] = encryptedDataItems
|
|
@@ -99,10 +103,12 @@ async function getChromeCookies(
|
|
|
99
103
|
domain: cookieRow.domain,
|
|
100
104
|
name: cookieRow.name,
|
|
101
105
|
value: decryptedValue,
|
|
102
|
-
meta: meta
|
|
106
|
+
meta: meta,
|
|
103
107
|
};
|
|
104
108
|
});
|
|
105
|
-
const results: ExportedCookie[] = (await Promise.all(decrypted)).filter(
|
|
109
|
+
const results: ExportedCookie[] = (await Promise.all(decrypted)).filter(
|
|
110
|
+
isExportedCookie
|
|
111
|
+
);
|
|
106
112
|
if (env.VERBOSE) {
|
|
107
113
|
console.log("results", results);
|
|
108
114
|
}
|
|
@@ -117,17 +123,16 @@ const chromeLocal = path.join(
|
|
|
117
123
|
"Chrome"
|
|
118
124
|
);
|
|
119
125
|
|
|
120
|
-
async function getEncryptedChromeCookie(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}): Promise<CookieRow[]> {
|
|
126
|
+
async function getEncryptedChromeCookie({
|
|
127
|
+
name,
|
|
128
|
+
domain,
|
|
129
|
+
file = path.join(chromeLocal, "Default", "Cookies"),
|
|
130
|
+
}: //
|
|
131
|
+
{
|
|
132
|
+
name: string;
|
|
133
|
+
domain: string;
|
|
134
|
+
file: string;
|
|
135
|
+
}): Promise<CookieRow[]> {
|
|
131
136
|
if (!existsSync(file)) {
|
|
132
137
|
throw new Error(`File ${file} does not exist`);
|
|
133
138
|
}
|
|
@@ -136,7 +141,8 @@ async function getEncryptedChromeCookie(
|
|
|
136
141
|
console.log(`Trying Chrome (at ${s}) cookie ${name} for domain ${domain}`);
|
|
137
142
|
}
|
|
138
143
|
let sql;
|
|
139
|
-
|
|
144
|
+
//language=SQL
|
|
145
|
+
sql = "SELECT encrypted_value, name, host_key FROM cookies";
|
|
140
146
|
const wildcardRegexp = /^([*%])$/i;
|
|
141
147
|
const specifiedName = name.match(wildcardRegexp) == null;
|
|
142
148
|
const specifiedDomain = domain.match(wildcardRegexp) == null;
|
|
@@ -152,16 +158,29 @@ async function getEncryptedChromeCookie(
|
|
|
152
158
|
sql += `host_key LIKE '${domain}';`;
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
|
-
return doSqliteQuery1(
|
|
161
|
+
return doSqliteQuery1({
|
|
162
|
+
file: file,
|
|
163
|
+
sql: sql,
|
|
164
|
+
rowTransform: (row) => {
|
|
165
|
+
return {
|
|
166
|
+
domain: row["host_key"],
|
|
167
|
+
name: row["name"],
|
|
168
|
+
value: row["encrypted_value"],
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
});
|
|
156
172
|
}
|
|
157
173
|
|
|
158
174
|
async function getChromePassword(): Promise<string> {
|
|
159
175
|
return execSimple(
|
|
160
|
-
|
|
176
|
+
'security find-generic-password -w -s "Chrome Safe Storage"'
|
|
161
177
|
);
|
|
162
178
|
}
|
|
163
179
|
|
|
164
|
-
async function decrypt(
|
|
180
|
+
async function decrypt(
|
|
181
|
+
password: crypto.BinaryLike,
|
|
182
|
+
encryptedData: Buffer
|
|
183
|
+
): Promise<string> {
|
|
165
184
|
if (typeof password !== "string") {
|
|
166
185
|
throw new Error("password must be a string: " + password);
|
|
167
186
|
}
|
|
@@ -187,73 +206,68 @@ async function decrypt(password: crypto.BinaryLike, encryptedData: Buffer): Prom
|
|
|
187
206
|
console.log(`Trying to decrypt with password ${password}`);
|
|
188
207
|
}
|
|
189
208
|
return new Promise((resolve, reject) => {
|
|
190
|
-
crypto.pbkdf2(password,
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
(error, buffer) => {
|
|
196
|
-
try {
|
|
197
|
-
if (error) {
|
|
198
|
-
if (env.VERBOSE) {
|
|
199
|
-
console.log("Error doing pbkdf2", error);
|
|
200
|
-
}
|
|
201
|
-
reject(error);
|
|
202
|
-
return;
|
|
209
|
+
crypto.pbkdf2(password, "saltysalt", 1003, 16, "sha1", (error, buffer) => {
|
|
210
|
+
try {
|
|
211
|
+
if (error) {
|
|
212
|
+
if (env.VERBOSE) {
|
|
213
|
+
console.log("Error doing pbkdf2", error);
|
|
203
214
|
}
|
|
215
|
+
reject(error);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
204
218
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
reject(new Error("Buffer length is not 16"));
|
|
213
|
-
return;
|
|
219
|
+
if (buffer.length !== 16) {
|
|
220
|
+
if (env.VERBOSE) {
|
|
221
|
+
console.log(
|
|
222
|
+
"Error doing pbkdf2, buffer length is not 16",
|
|
223
|
+
buffer.length
|
|
224
|
+
);
|
|
214
225
|
}
|
|
226
|
+
reject(new Error("Buffer length is not 16"));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
215
229
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (encryptedData1 && encryptedData1.slice) {
|
|
222
|
-
encryptedData1 = encryptedData1.slice(3);
|
|
223
|
-
}
|
|
230
|
+
const str = new Array(17).join(" ");
|
|
231
|
+
const iv = Buffer.from(str, "binary");
|
|
232
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", buffer, iv);
|
|
233
|
+
decipher.setAutoPadding(false);
|
|
224
234
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
"Error doing pbkdf2, encryptedData length is not a multiple of 16",
|
|
229
|
-
encryptedData1.length
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
reject(new Error("encryptedData length is not a multiple of 16"));
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
+
if (encryptedData1 && encryptedData1.slice) {
|
|
236
|
+
encryptedData1 = encryptedData1.slice(3);
|
|
237
|
+
}
|
|
235
238
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
reject(e);
|
|
244
|
-
return;
|
|
239
|
+
if (encryptedData1.length % 16 !== 0) {
|
|
240
|
+
if (env.VERBOSE) {
|
|
241
|
+
console.log(
|
|
242
|
+
"Error doing pbkdf2, encryptedData length is not a multiple of 16",
|
|
243
|
+
encryptedData1.length
|
|
244
|
+
);
|
|
245
245
|
}
|
|
246
|
+
reject(new Error("encryptedData length is not a multiple of 16"));
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
246
249
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
// noinspection JSCheckFunctionSignatures
|
|
252
|
-
const decodedString = decoded.toString("utf8");
|
|
253
|
-
resolve(decodedString);
|
|
250
|
+
let decoded = decipher.update(encryptedData1);
|
|
251
|
+
try {
|
|
252
|
+
decipher.final("utf-8");
|
|
254
253
|
} catch (e) {
|
|
254
|
+
if (env.VERBOSE) {
|
|
255
|
+
console.log("Error doing decipher.final()", e);
|
|
256
|
+
}
|
|
255
257
|
reject(e);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const padding = decoded[decoded.length - 1];
|
|
262
|
+
if (padding) {
|
|
263
|
+
decoded = decoded.slice(0, 0 - padding);
|
|
256
264
|
}
|
|
257
|
-
|
|
265
|
+
// noinspection JSCheckFunctionSignatures
|
|
266
|
+
const decodedString = decoded.toString("utf8");
|
|
267
|
+
resolve(decodedString);
|
|
268
|
+
} catch (e) {
|
|
269
|
+
reject(e);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
258
272
|
});
|
|
259
273
|
}
|
|
@@ -3,8 +3,16 @@ import FirefoxCookieQueryStrategy from "./FirefoxCookieQueryStrategy";
|
|
|
3
3
|
import SafariCookieQueryStrategy from "./SafariCookieQueryStrategy";
|
|
4
4
|
import CookieQueryStrategy from "./CookieQueryStrategy";
|
|
5
5
|
import { ExportedCookie } from "../ExportedCookie";
|
|
6
|
+
import LRUCache from "lru-cache";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
const cache = new LRUCache<string, ExportedCookie[]>({
|
|
9
|
+
ttl: 1000 * 2,
|
|
10
|
+
max: 10,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export default class CompositeCookieQueryStrategy
|
|
14
|
+
implements CookieQueryStrategy
|
|
15
|
+
{
|
|
8
16
|
#strategies;
|
|
9
17
|
|
|
10
18
|
constructor() {
|
|
@@ -18,13 +26,23 @@ export default class CompositeCookieQueryStrategy implements CookieQueryStrategy
|
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
|
|
29
|
+
const key = `${name}:${domain}`;
|
|
30
|
+
const cached = cache.get(key);
|
|
31
|
+
if (cached) {
|
|
32
|
+
return cached;
|
|
33
|
+
}
|
|
21
34
|
const results = await Promise.all(
|
|
22
35
|
this.#strategies.map(async (strategy) => {
|
|
23
36
|
// @ts-ignore
|
|
24
|
-
const cookies: Promise<ExportedCookie[]> = strategy.queryCookies(
|
|
37
|
+
const cookies: Promise<ExportedCookie[]> = strategy.queryCookies(
|
|
38
|
+
name,
|
|
39
|
+
domain
|
|
40
|
+
);
|
|
25
41
|
return cookies.catch(() => []);
|
|
26
42
|
})
|
|
27
43
|
);
|
|
28
|
-
|
|
44
|
+
const flat: ExportedCookie[] = results.flat();
|
|
45
|
+
cache.set(`${name}:${domain}`, flat);
|
|
46
|
+
return flat;
|
|
29
47
|
}
|
|
30
48
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import * as path from "path";
|
|
1
2
|
import CookieQueryStrategy from "./CookieQueryStrategy";
|
|
2
3
|
import { env, HOME } from "../global";
|
|
3
4
|
import { existsSync } from "fs";
|
|
4
|
-
import { toStringOrNull } from "../utils";
|
|
5
5
|
import { findAllFiles } from "../findAllFiles";
|
|
6
|
-
import * as path from "path";
|
|
7
6
|
import { doSqliteQuery1 } from "../doSqliteQuery1";
|
|
8
7
|
import { ExportedCookie } from "../ExportedCookie";
|
|
8
|
+
import { CookieRow } from "../CookieRow";
|
|
9
|
+
import { CookieSpec } from "../CookieSpec";
|
|
10
|
+
import { specialCases } from "../SpecialCases";
|
|
9
11
|
|
|
10
12
|
export default class FirefoxCookieQueryStrategy implements CookieQueryStrategy {
|
|
11
13
|
async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
|
|
@@ -16,26 +18,21 @@ export default class FirefoxCookieQueryStrategy implements CookieQueryStrategy {
|
|
|
16
18
|
return [];
|
|
17
19
|
}
|
|
18
20
|
const cookies = await this.#getFirefoxCookie({ name, domain });
|
|
19
|
-
|
|
21
|
+
if (Array.isArray(cookies)) {
|
|
22
|
+
return cookies.map((cookie: CookieRow) => {
|
|
23
|
+
return {
|
|
24
|
+
domain: cookie.domain,
|
|
25
|
+
name: cookie.name,
|
|
26
|
+
value: cookie.value.toString("utf8"),
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
} else {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
20
32
|
}
|
|
21
33
|
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* @param name
|
|
25
|
-
* @param domain
|
|
26
|
-
* @returns {Promise<Buffer>}
|
|
27
|
-
*/
|
|
28
34
|
async #getFirefoxCookie(
|
|
29
|
-
//
|
|
30
|
-
{
|
|
31
|
-
name,
|
|
32
|
-
domain
|
|
33
|
-
}: {
|
|
34
|
-
name: string,
|
|
35
|
-
domain: string
|
|
36
|
-
//
|
|
37
|
-
}
|
|
38
|
-
//
|
|
35
|
+
{ name, domain }: CookieSpec //
|
|
39
36
|
) {
|
|
40
37
|
const files: string[] = await findAllFiles({
|
|
41
38
|
path: path.join(
|
|
@@ -45,48 +42,57 @@ export default class FirefoxCookieQueryStrategy implements CookieQueryStrategy {
|
|
|
45
42
|
"Firefox",
|
|
46
43
|
"Profiles"
|
|
47
44
|
),
|
|
48
|
-
name: "cookies.sqlite"
|
|
45
|
+
name: "cookies.sqlite",
|
|
49
46
|
});
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
47
|
+
const fn: (file: string) => Promise<CookieRow[]> = async (file: string) => {
|
|
48
|
+
return await this.#queryCookiesDb(file, name, domain);
|
|
49
|
+
};
|
|
50
|
+
const all: Awaited<CookieRow[]>[] = await Promise.all(files.map(fn));
|
|
55
51
|
return all.flat();
|
|
56
52
|
}
|
|
57
53
|
|
|
58
|
-
#queryCookiesDb(
|
|
54
|
+
async #queryCookiesDb(
|
|
55
|
+
file: string,
|
|
56
|
+
name: string,
|
|
57
|
+
domain: string
|
|
58
|
+
): Promise<CookieRow[]> {
|
|
59
59
|
if (file && !existsSync(file)) {
|
|
60
60
|
throw new Error(`File ${file} does not exist`);
|
|
61
61
|
}
|
|
62
|
-
if (env.VERBOSE) {
|
|
63
|
-
console.log(`Trying Firefox cookie ${name} for domain ${domain}`);
|
|
64
|
-
}
|
|
65
62
|
let sql;
|
|
66
63
|
//language=SQL
|
|
67
|
-
sql = "SELECT value FROM moz_cookies";
|
|
68
|
-
|
|
64
|
+
sql = "SELECT value, name, host FROM moz_cookies";
|
|
65
|
+
const { specifiedName, specifiedDomain } = specialCases({ name, domain });
|
|
66
|
+
if (specifiedName || specifiedDomain) {
|
|
69
67
|
sql += ` WHERE `;
|
|
70
|
-
if (
|
|
68
|
+
if (specifiedName) {
|
|
71
69
|
sql += `name = '${name}'`;
|
|
72
|
-
if (
|
|
70
|
+
if (specifiedDomain) {
|
|
73
71
|
sql += ` AND `;
|
|
74
72
|
}
|
|
75
73
|
}
|
|
76
|
-
if (
|
|
74
|
+
if (specifiedDomain) {
|
|
77
75
|
sql += `host LIKE '${domain}';`;
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
78
|
+
const rowTransform = (row: any) => {
|
|
79
|
+
// row is object key by column name
|
|
80
|
+
const value = row.value as string;
|
|
81
|
+
return {
|
|
82
|
+
domain: row.domain as string,
|
|
83
|
+
name: row.name as string,
|
|
84
|
+
value: Buffer.from(value, "utf8"),
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
try {
|
|
88
|
+
return await doSqliteQuery1({
|
|
89
|
+
file,
|
|
90
|
+
sql,
|
|
91
|
+
rowTransform,
|
|
92
|
+
});
|
|
93
|
+
} catch (e) {
|
|
94
|
+
console.error(`Error querying ${file}`, e);
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
91
97
|
}
|
|
92
98
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import minimist from "minimist";
|
|
4
|
+
import { argv } from "./argv";
|
|
3
5
|
import { env } from "./global";
|
|
4
6
|
import { queryCookies } from "./queryCookies";
|
|
5
|
-
import { argv } from "./argv";
|
|
6
7
|
import { groupBy } from "lodash";
|
|
7
|
-
import {
|
|
8
|
+
import { green, yellow } from "colorette";
|
|
8
9
|
import { resultsRendered } from "./resultsRendered";
|
|
9
|
-
import {
|
|
10
|
+
import { fetchWithCookies } from "./fetchWithCookies";
|
|
11
|
+
import { unpackHeaders } from "./unpackHeaders";
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
return blue(resultsRendered(results));
|
|
13
|
-
}
|
|
13
|
+
const parsedArgs: minimist.ParsedArgs = minimist(argv);
|
|
14
14
|
|
|
15
15
|
async function cliQueryCookies(name: string, domain: string) {
|
|
16
16
|
try {
|
|
17
17
|
const results = await queryCookies({ name, domain });
|
|
18
18
|
if (results.length > 0) {
|
|
19
19
|
if (argv.includes("--combined-string")) {
|
|
20
|
-
console.log(
|
|
21
|
-
} else if (argv.includes("--
|
|
20
|
+
console.log(yellow(resultsRendered(results)));
|
|
21
|
+
} else if (argv.includes("--render") || argv.includes("-r")) {
|
|
22
|
+
console.log(yellow(resultsRendered(results)));
|
|
23
|
+
} else if (argv.includes("--dump") || argv.includes("-d")) {
|
|
22
24
|
console.log(results);
|
|
23
25
|
} else if (argv.includes("--dump-grouped")) {
|
|
24
26
|
const groupedByFile = groupBy(results, (r) => r.meta?.file);
|
|
@@ -27,7 +29,7 @@ async function cliQueryCookies(name: string, domain: string) {
|
|
|
27
29
|
const groupedByFile = groupBy(results, (r) => r.meta?.file);
|
|
28
30
|
for (const file of Object.keys(groupedByFile)) {
|
|
29
31
|
let results = groupedByFile[file];
|
|
30
|
-
console.log(green(file) + ": ",
|
|
32
|
+
console.log(green(file) + ": ", yellow(resultsRendered(results)));
|
|
31
33
|
}
|
|
32
34
|
} else {
|
|
33
35
|
for (const result of results) {
|
|
@@ -42,41 +44,75 @@ async function cliQueryCookies(name: string, domain: string) {
|
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
function main() {
|
|
48
|
+
if (argv && argv.length > 2) {
|
|
49
|
+
const arg2 = argv[2];
|
|
50
|
+
const arg3 = argv[3];
|
|
51
|
+
if (arg2 == "--fetch" || arg2 == "-f") {
|
|
52
|
+
const f = parsedArgs["f"];
|
|
53
|
+
let url: URL;
|
|
54
|
+
try {
|
|
55
|
+
url = new URL(f);
|
|
56
|
+
} catch (e) {
|
|
57
|
+
console.error("Invalid URL", arg3);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const headerArgs: string[] | string = parsedArgs["H"];
|
|
61
|
+
const headers = unpackHeaders(headerArgs);
|
|
62
|
+
const onfulfilled = (res: Response) => {
|
|
63
|
+
return res.text().then((r) => {
|
|
64
|
+
console.log(r);
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
fetchWithCookies(
|
|
68
|
+
url,
|
|
69
|
+
{
|
|
70
|
+
//
|
|
71
|
+
headers,
|
|
72
|
+
}
|
|
73
|
+
//
|
|
74
|
+
).then(
|
|
75
|
+
onfulfilled,
|
|
76
|
+
console.error
|
|
77
|
+
//
|
|
78
|
+
);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
let domain;
|
|
82
|
+
if (arg3 != null && arg3.indexOf(".") > -1) {
|
|
83
|
+
domain = arg3;
|
|
84
|
+
} else {
|
|
85
|
+
domain = "%";
|
|
86
|
+
}
|
|
47
87
|
|
|
48
|
-
|
|
49
|
-
if (argv[3] != null && argv[3].indexOf(".") > -1) {
|
|
50
|
-
domain = argv[3];
|
|
51
|
-
} else {
|
|
52
|
-
domain = "%";
|
|
53
|
-
}
|
|
88
|
+
const tru = `${true}`;
|
|
54
89
|
|
|
55
|
-
|
|
90
|
+
if (argv.includes("--require-jwt")) {
|
|
91
|
+
env.REQUIRE_JWT = tru;
|
|
92
|
+
}
|
|
93
|
+
if (argv.includes("--verbose")) {
|
|
94
|
+
env.VERBOSE = tru;
|
|
95
|
+
}
|
|
96
|
+
if (argv.includes("--chrome-only")) {
|
|
97
|
+
env.CHROME_ONLY = tru;
|
|
98
|
+
}
|
|
99
|
+
if (argv.includes("--firefox-only")) {
|
|
100
|
+
env.FIREFOX_ONLY = tru;
|
|
101
|
+
}
|
|
102
|
+
if (argv.includes("--ignore-expired")) {
|
|
103
|
+
env.IGNORE_EXPIRED = tru;
|
|
104
|
+
}
|
|
56
105
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (argv.includes("--verbose")) {
|
|
61
|
-
env.VERBOSE = tru;
|
|
62
|
-
}
|
|
63
|
-
if (argv.includes("--chrome-only")) {
|
|
64
|
-
env.CHROME_ONLY = tru;
|
|
65
|
-
}
|
|
66
|
-
if (argv.includes("--firefox-only")) {
|
|
67
|
-
env.FIREFOX_ONLY = tru;
|
|
68
|
-
}
|
|
69
|
-
if (argv.includes("--ignore-expired")) {
|
|
70
|
-
env.IGNORE_EXPIRED = tru;
|
|
71
|
-
}
|
|
106
|
+
if (argv.includes("--single")) {
|
|
107
|
+
env.SINGLE = tru;
|
|
108
|
+
}
|
|
72
109
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
110
|
+
if (env.VERBOSE) {
|
|
111
|
+
console.log("Verbose mode", argv);
|
|
112
|
+
}
|
|
76
113
|
|
|
77
|
-
|
|
78
|
-
console.log("Verbose mode", argv);
|
|
114
|
+
cliQueryCookies(arg2, domain).catch(console.error);
|
|
79
115
|
}
|
|
80
|
-
|
|
81
|
-
cliQueryCookies(name, domain).catch(console.error);
|
|
82
116
|
}
|
|
117
|
+
|
|
118
|
+
main();
|
package/src/doSqliteQuery1.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as sqlite3 from "sqlite3";
|
|
3
3
|
import { CookieRow } from "./CookieRow";
|
|
4
|
+
import { merge } from "lodash";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
interface DoSqliteQuery1Params {
|
|
7
|
+
file: string;
|
|
8
|
+
sql: string;
|
|
9
|
+
rowTransform: (row: any) => CookieRow;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function doSqliteQuery1({
|
|
13
|
+
file,
|
|
14
|
+
sql,
|
|
15
|
+
rowTransform,
|
|
16
|
+
}: DoSqliteQuery1Params): Promise<CookieRow[]> {
|
|
17
|
+
if (!file || (file && !fs.existsSync(file))) {
|
|
7
18
|
throw new Error(`doSqliteQuery1: file ${file} does not exist`);
|
|
8
19
|
}
|
|
9
20
|
const db = new sqlite3.Database(file);
|
|
@@ -19,15 +30,14 @@ export async function doSqliteQuery1(file: string, sql: string): Promise<CookieR
|
|
|
19
30
|
return;
|
|
20
31
|
}
|
|
21
32
|
if (Array.isArray(rows1)) {
|
|
22
|
-
const cookieRows: CookieRow[] = rows1.map((row) => {
|
|
23
|
-
|
|
24
|
-
domain: row["host_key"],
|
|
25
|
-
name: row["name"],
|
|
26
|
-
value: row["encrypted_value"],
|
|
33
|
+
const cookieRows: CookieRow[] = rows1.map((row: any) => {
|
|
34
|
+
const newVar = {
|
|
27
35
|
meta: {
|
|
28
|
-
file: file
|
|
29
|
-
}
|
|
36
|
+
file: file,
|
|
37
|
+
},
|
|
30
38
|
};
|
|
39
|
+
const cookieRow: CookieRow = rowTransform(row);
|
|
40
|
+
return merge(newVar, cookieRow);
|
|
31
41
|
});
|
|
32
42
|
resolve(cookieRows);
|
|
33
43
|
return;
|