@mherod/get-cookie 1.3.0 → 2.0.0-beta.3
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/codeStyles/Project.xml +59 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/get-cookie.iml +1 -0
- package/.prettierrc.json +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/main.js +335 -288
- package/dist/main.js.map +1 -1
- package/package.json +15 -6
- package/src/CookieRow.ts +21 -0
- package/src/argv.js +1 -0
- package/src/browsers/AbstractCookieQueryStrategy.ts +10 -0
- package/src/browsers/ChromeCookieQueryStrategy.ts +256 -0
- package/src/browsers/CompositeCookieQueryStrategy.ts +31 -0
- package/src/browsers/FirefoxCookieQueryStrategy.ts +92 -0
- package/src/browsers/SafariCookieQueryStrategy.ts +3 -0
- package/src/cli.js +77 -45
- package/src/doSqliteQuery1.ts +47 -0
- package/src/findAllFiles.ts +68 -0
- package/src/global.ts +7 -0
- package/src/index.js +38 -439
- package/src/isValidJwt.ts +14 -0
- package/src/queryCookies.ts +28 -0
- package/src/utils.ts +118 -0
- package/tsconfig.json +23 -0
- package/src/global.js +0 -3
- package/src/utils.js +0 -185
package/src/index.js
CHANGED
|
@@ -1,462 +1,61 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2
3
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
if (process.platform !== "darwin") {
|
|
8
|
-
throw new Error("This script only works on macOS");
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const {
|
|
12
|
-
execSimple,
|
|
13
|
-
toStringOrNull,
|
|
14
|
-
doSqliteQuery1,
|
|
15
|
-
toStringValue,
|
|
16
|
-
} = require("./utils");
|
|
17
|
-
const jsonwebtoken = require("jsonwebtoken");
|
|
18
|
-
|
|
19
|
-
function isValidJwt(token) {
|
|
20
|
-
if (typeof token !== "string") {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
try {
|
|
24
|
-
const result = jsonwebtoken.decode(token, { complete: true });
|
|
25
|
-
if (env.VERBOSE) {
|
|
26
|
-
console.log(result);
|
|
27
|
-
}
|
|
28
|
-
return true;
|
|
29
|
-
} catch (err) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
* @returns {Promise<string>}
|
|
37
|
-
*/
|
|
38
|
-
async function getChromePassword() {
|
|
39
|
-
return execSimple(
|
|
40
|
-
'security find-generic-password -w -s "Chrome Safe Storage"'
|
|
41
|
-
);
|
|
42
|
-
}
|
|
4
|
+
import { queryCookies } from "./queryCookies";
|
|
5
|
+
import FirefoxCookieQueryStrategy from "./browsers/FirefoxCookieQueryStrategy";
|
|
6
|
+
import ChromeCookieQueryStrategy from "./browsers/ChromeCookieQueryStrategy";
|
|
7
|
+
import CompositeCookieQueryStrategy from "./browsers/CompositeCookieQueryStrategy";
|
|
43
8
|
|
|
44
9
|
/**
|
|
45
10
|
*
|
|
46
11
|
* @param params
|
|
47
12
|
* @returns {Promise<string>}
|
|
48
13
|
*/
|
|
49
|
-
async function getCookie(params) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return toStringValue(cookie);
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
.catch((err) => {
|
|
61
|
-
if (env.VERBOSE) {
|
|
62
|
-
console.error(err);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
} else if (env.FIREFOX_ONLY) {
|
|
66
|
-
if (env.VERBOSE) {
|
|
67
|
-
console.log("firefox only");
|
|
68
|
-
}
|
|
69
|
-
return getFirefoxCookie(params)
|
|
70
|
-
.then((b) => b.toString("utf8"))
|
|
71
|
-
.then((cookie) => {
|
|
72
|
-
if (cookie && cookie.length > 0) {
|
|
73
|
-
return toStringValue(cookie);
|
|
74
|
-
} else {
|
|
75
|
-
console.log("No cookie found");
|
|
76
|
-
}
|
|
77
|
-
})
|
|
78
|
-
.catch((err) => {
|
|
79
|
-
if (env.VERBOSE) {
|
|
80
|
-
console.error("Error getting Firefox cookie", err);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
14
|
+
export async function getCookie(params) {
|
|
15
|
+
const cookies = await queryCookies(
|
|
16
|
+
params,
|
|
17
|
+
new CompositeCookieQueryStrategy()
|
|
18
|
+
//
|
|
19
|
+
);
|
|
20
|
+
if (Array.isArray(cookies) && cookies.length > 0) {
|
|
21
|
+
return cookies.find((cookie) => cookie != null);
|
|
83
22
|
} else {
|
|
84
|
-
|
|
85
|
-
.catch((err) => {
|
|
86
|
-
if (env.VERBOSE) {
|
|
87
|
-
console.error("Error getting Chrome cookie", err);
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
.then((r) => {
|
|
91
|
-
if (typeof r === "string" && r.trim().length > 0) {
|
|
92
|
-
return r;
|
|
93
|
-
} else {
|
|
94
|
-
return getFirefoxCookie(params).catch((err) => {
|
|
95
|
-
if (env.VERBOSE) {
|
|
96
|
-
console.error("Error getting Firefox cookie", err);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
.catch((e) => {
|
|
102
|
-
if (env.VERBOSE) {
|
|
103
|
-
console.error("Error getting Chrome or Firefox cookie", e);
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
.then(toStringValue);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
*
|
|
112
|
-
* @param name
|
|
113
|
-
* @param domain
|
|
114
|
-
* @returns {Promise<Buffer>}
|
|
115
|
-
*/
|
|
116
|
-
async function getFirefoxCookie({ name, domain }) {
|
|
117
|
-
if (name && typeof name !== "string") {
|
|
118
|
-
throw new Error("name must be a string");
|
|
119
|
-
}
|
|
120
|
-
if (domain && typeof domain !== "string") {
|
|
121
|
-
throw new Error("domain must be a string");
|
|
122
|
-
}
|
|
123
|
-
const [file] = await findAllFiles({
|
|
124
|
-
path: `${env.HOME}/Library/Application Support/Firefox/Profiles`,
|
|
125
|
-
name: "cookies.sqlite",
|
|
126
|
-
});
|
|
127
|
-
if (file && !fs.existsSync(file)) {
|
|
128
|
-
throw new Error(`File ${file} does not exist`);
|
|
129
|
-
}
|
|
130
|
-
if (env.VERBOSE) {
|
|
131
|
-
console.log(`Trying Firefox cookie ${name} for domain ${domain}`);
|
|
132
|
-
}
|
|
133
|
-
let sql;
|
|
134
|
-
sql = "SELECT value FROM moz_cookies";
|
|
135
|
-
if (typeof name === "string" || typeof domain === "string") {
|
|
136
|
-
sql += ` WHERE `;
|
|
137
|
-
if (typeof name === "string") {
|
|
138
|
-
sql += `name = '${name}'`;
|
|
139
|
-
if (typeof domain === "string") {
|
|
140
|
-
sql += ` AND `;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (typeof domain === "string") {
|
|
144
|
-
sql += `host LIKE '${domain}';`;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return await doSqliteQuery1(file, sql).then((rows) => {
|
|
148
|
-
return rows.map(toStringOrNull).find((v) => v !== null);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const defaultChromeRoot = `${env.HOME}/Library/Application Support/Google/Chrome`;
|
|
153
|
-
const defaultChromeCookies = `${defaultChromeRoot}/Default/Cookies`;
|
|
154
|
-
|
|
155
|
-
async function getEncryptedChromeCookie({
|
|
156
|
-
name,
|
|
157
|
-
domain,
|
|
158
|
-
file = defaultChromeCookies,
|
|
159
|
-
}) {
|
|
160
|
-
if (name && typeof name !== "string") {
|
|
161
|
-
throw new Error("name must be a string");
|
|
162
|
-
}
|
|
163
|
-
if (domain && typeof domain !== "string") {
|
|
164
|
-
throw new Error("domain must be a string");
|
|
165
|
-
}
|
|
166
|
-
if (file && typeof file !== "string") {
|
|
167
|
-
throw new Error("file must be a string");
|
|
168
|
-
}
|
|
169
|
-
if (!fs.existsSync(file)) {
|
|
170
|
-
throw new Error(`File ${file} does not exist`);
|
|
171
|
-
}
|
|
172
|
-
if (env.VERBOSE) {
|
|
173
|
-
console.log(
|
|
174
|
-
`Trying Chrome (at ${file
|
|
175
|
-
.split("/")
|
|
176
|
-
.slice(-3)
|
|
177
|
-
.join("/")}) cookie ${name} for domain ${domain}`
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
let sql;
|
|
181
|
-
sql = `SELECT encrypted_value FROM cookies`;
|
|
182
|
-
if (typeof name === "string" || typeof domain === "string") {
|
|
183
|
-
sql += ` WHERE `;
|
|
184
|
-
if (typeof name === "string") {
|
|
185
|
-
sql += `name = '${name}'`;
|
|
186
|
-
if (typeof domain === "string") {
|
|
187
|
-
sql += ` AND `;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (typeof domain === "string") {
|
|
191
|
-
sql += `host_key LIKE '${domain}';`;
|
|
192
|
-
}
|
|
23
|
+
throw new Error("Cookie not found");
|
|
193
24
|
}
|
|
194
|
-
return await doSqliteQuery1(file, sql);
|
|
195
25
|
}
|
|
196
26
|
|
|
197
27
|
/**
|
|
198
28
|
*
|
|
199
|
-
* @param
|
|
200
|
-
* @
|
|
201
|
-
* @returns {Promise<string>}
|
|
202
|
-
*/
|
|
203
|
-
async function decrypt(password, encryptedData) {
|
|
204
|
-
if (typeof password !== "string") {
|
|
205
|
-
throw new Error("password must be a string: " + password);
|
|
206
|
-
}
|
|
207
|
-
let encryptedData1;
|
|
208
|
-
encryptedData1 = encryptedData;
|
|
209
|
-
if (encryptedData1 == null || typeof encryptedData1 !== "object") {
|
|
210
|
-
throw new Error("encryptedData must be a object: " + encryptedData1);
|
|
211
|
-
}
|
|
212
|
-
if (!(encryptedData1 instanceof Buffer)) {
|
|
213
|
-
if (Array.isArray(encryptedData1) && encryptedData1[0] instanceof Buffer) {
|
|
214
|
-
[encryptedData1] = encryptedData1;
|
|
215
|
-
if (env.VERBOSE) {
|
|
216
|
-
console.log(
|
|
217
|
-
`encryptedData is an array of buffers, selected first: ${encryptedData1}`
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
} else {
|
|
221
|
-
throw new Error("encryptedData must be a Buffer: " + encryptedData1);
|
|
222
|
-
}
|
|
223
|
-
encryptedData1 = Buffer.from(encryptedData1);
|
|
224
|
-
}
|
|
225
|
-
if (env.VERBOSE) {
|
|
226
|
-
console.log(`Trying to decrypt with password ${password}`);
|
|
227
|
-
}
|
|
228
|
-
return new Promise((resolve, reject) => {
|
|
229
|
-
crypto.pbkdf2(password, "saltysalt", 1003, 16, "sha1", (error, buffer) => {
|
|
230
|
-
try {
|
|
231
|
-
if (error) {
|
|
232
|
-
if (env.VERBOSE) {
|
|
233
|
-
console.log("Error doing pbkdf2", error);
|
|
234
|
-
}
|
|
235
|
-
reject(error);
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (buffer.length !== 16) {
|
|
240
|
-
if (env.VERBOSE) {
|
|
241
|
-
console.log(
|
|
242
|
-
"Error doing pbkdf2, buffer length is not 16",
|
|
243
|
-
buffer.length
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
reject(new Error("Buffer length is not 16"));
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const iv = new Buffer.from(new Array(17).join(" "), "binary");
|
|
251
|
-
const decipher = crypto.createDecipheriv("aes-128-cbc", buffer, iv);
|
|
252
|
-
decipher.setAutoPadding(false);
|
|
253
|
-
|
|
254
|
-
if (encryptedData1 && encryptedData1.slice) {
|
|
255
|
-
encryptedData1 = encryptedData1.slice(3);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (encryptedData1.length % 16 !== 0) {
|
|
259
|
-
if (env.VERBOSE) {
|
|
260
|
-
console.log(
|
|
261
|
-
"Error doing pbkdf2, encryptedData length is not a multiple of 16",
|
|
262
|
-
encryptedData1.length
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
reject(new Error("encryptedData length is not a multiple of 16"));
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
let decoded = decipher.update(encryptedData1);
|
|
270
|
-
try {
|
|
271
|
-
decipher.final("utf-8");
|
|
272
|
-
} catch (e) {
|
|
273
|
-
if (env.VERBOSE) {
|
|
274
|
-
console.log("Error doing decipher.final()", e);
|
|
275
|
-
}
|
|
276
|
-
reject(e);
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
let padding = decoded[decoded.length - 1];
|
|
281
|
-
if (padding) {
|
|
282
|
-
decoded = decoded.slice(0, 0 - padding);
|
|
283
|
-
}
|
|
284
|
-
// noinspection JSCheckFunctionSignatures
|
|
285
|
-
decoded = decoded.toString("utf8");
|
|
286
|
-
resolve(decoded);
|
|
287
|
-
} catch (e) {
|
|
288
|
-
reject(e);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
*
|
|
296
|
-
* @param {string|undefined} name
|
|
297
|
-
* @param {string} domain
|
|
298
|
-
* @param {boolean} requireJwt
|
|
299
|
-
* @returns {Promise<string>}
|
|
29
|
+
* @param params
|
|
30
|
+
* @returns {Promise<*>}
|
|
300
31
|
*/
|
|
301
|
-
async function
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
})
|
|
312
|
-
.then((files) => {
|
|
313
|
-
const promises = files.map((file) => {
|
|
314
|
-
return getEncryptedChromeCookie({
|
|
315
|
-
name: name,
|
|
316
|
-
domain: domain,
|
|
317
|
-
file: file,
|
|
318
|
-
}).catch((e) => {
|
|
319
|
-
if (env.VERBOSE) {
|
|
320
|
-
console.log("Error getting encrypted cookie", e);
|
|
321
|
-
}
|
|
322
|
-
return [];
|
|
323
|
-
});
|
|
324
|
-
});
|
|
325
|
-
return Promise.all(promises)
|
|
326
|
-
.then((results) => results.flat())
|
|
327
|
-
.then((results) => {
|
|
328
|
-
if (env.VERBOSE) {
|
|
329
|
-
console.log("getEncryptedChromeCookie results", results);
|
|
330
|
-
}
|
|
331
|
-
return results.filter((result) => {
|
|
332
|
-
return result;
|
|
333
|
-
});
|
|
334
|
-
});
|
|
335
|
-
})
|
|
336
|
-
.catch((error) => {
|
|
337
|
-
if (env.VERBOSE) {
|
|
338
|
-
console.log("error", error);
|
|
339
|
-
}
|
|
340
|
-
return [];
|
|
341
|
-
});
|
|
342
|
-
const password = await getChromePassword();
|
|
343
|
-
if (env.VERBOSE) {
|
|
344
|
-
console.log("encryptedDataItems", encryptedDataItems);
|
|
345
|
-
}
|
|
346
|
-
const decrypted = encryptedDataItems
|
|
347
|
-
.filter((encryptedData) => {
|
|
348
|
-
return encryptedData != null && encryptedData.length > 0;
|
|
349
|
-
})
|
|
350
|
-
.map(async (encryptedData) => {
|
|
351
|
-
if (env.VERBOSE) {
|
|
352
|
-
console.log("Received encrypted", encryptedData);
|
|
353
|
-
}
|
|
354
|
-
let decrypted;
|
|
355
|
-
try {
|
|
356
|
-
decrypted = await decrypt(password, encryptedData);
|
|
357
|
-
} catch (e) {
|
|
358
|
-
if (env.VERBOSE) {
|
|
359
|
-
console.log("Error decrypting cookie", e);
|
|
360
|
-
}
|
|
361
|
-
return null;
|
|
362
|
-
}
|
|
363
|
-
if (decrypted) {
|
|
364
|
-
if (env.VERBOSE) {
|
|
365
|
-
console.log("Decrypted", decrypted);
|
|
366
|
-
}
|
|
367
|
-
return decrypted;
|
|
368
|
-
}
|
|
369
|
-
return null;
|
|
370
|
-
});
|
|
371
|
-
const results = await Promise.all(decrypted);
|
|
372
|
-
if (env.VERBOSE) {
|
|
373
|
-
console.log("results", results);
|
|
32
|
+
export async function getFirefoxCookie(params) {
|
|
33
|
+
const cookies = await queryCookies(
|
|
34
|
+
params,
|
|
35
|
+
new FirefoxCookieQueryStrategy()
|
|
36
|
+
//
|
|
37
|
+
);
|
|
38
|
+
if (Array.isArray(cookies) && cookies.length > 0) {
|
|
39
|
+
return cookies.find((cookie) => cookie != null);
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error("Cookie not found");
|
|
374
42
|
}
|
|
375
|
-
return results.map(toStringOrNull).find((result) => {
|
|
376
|
-
return (
|
|
377
|
-
typeof result === "string" &&
|
|
378
|
-
result.length > 0 &&
|
|
379
|
-
(requireJwt === false || isValidJwt(result))
|
|
380
|
-
);
|
|
381
|
-
});
|
|
382
43
|
}
|
|
383
44
|
|
|
384
45
|
/**
|
|
385
46
|
*
|
|
386
|
-
* @param
|
|
387
|
-
* @
|
|
388
|
-
* @param rootSegments
|
|
389
|
-
* @param maxDepth
|
|
390
|
-
* @returns {Promise<[string]>}
|
|
47
|
+
* @param params
|
|
48
|
+
* @returns {Promise<*>}
|
|
391
49
|
*/
|
|
392
|
-
async function
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
if (env.VERBOSE) {
|
|
403
|
-
console.log(`Searching for ${name} in ${path}`);
|
|
404
|
-
}
|
|
405
|
-
const files = [];
|
|
406
|
-
let readdirSync;
|
|
407
|
-
try {
|
|
408
|
-
readdirSync = fs.readdirSync(path);
|
|
409
|
-
} catch (e) {
|
|
410
|
-
if (env.VERBOSE) {
|
|
411
|
-
console.log(`Error reading ${path}`, e);
|
|
412
|
-
}
|
|
413
|
-
return files;
|
|
414
|
-
}
|
|
415
|
-
for (const file of readdirSync) {
|
|
416
|
-
const filePath = path + "/" + file;
|
|
417
|
-
let stat;
|
|
418
|
-
try {
|
|
419
|
-
stat = fs.statSync(filePath);
|
|
420
|
-
} catch (e) {
|
|
421
|
-
if (env.VERBOSE) {
|
|
422
|
-
console.error(`Error getting stat for ${filePath}`, e);
|
|
423
|
-
}
|
|
424
|
-
continue;
|
|
425
|
-
}
|
|
426
|
-
if (stat.isDirectory()) {
|
|
427
|
-
if (filePath.split("/").length < rootSegments + maxDepth) {
|
|
428
|
-
try {
|
|
429
|
-
const subFiles = await findAllFiles({
|
|
430
|
-
path: filePath,
|
|
431
|
-
name: name,
|
|
432
|
-
rootSegments: rootSegments,
|
|
433
|
-
maxDepth: 2,
|
|
434
|
-
});
|
|
435
|
-
files.push(...subFiles);
|
|
436
|
-
} catch (e) {
|
|
437
|
-
if (env.VERBOSE) {
|
|
438
|
-
console.error(e);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
} else if (file === name) {
|
|
443
|
-
files.push(filePath);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
if (env.VERBOSE) {
|
|
447
|
-
if (files.length > 0) {
|
|
448
|
-
console.log(`Found ${files.length} ${name} files`);
|
|
449
|
-
console.log(files);
|
|
450
|
-
}
|
|
50
|
+
export async function getChromeCookie(params) {
|
|
51
|
+
const cookies = await queryCookies(
|
|
52
|
+
params,
|
|
53
|
+
new ChromeCookieQueryStrategy()
|
|
54
|
+
//
|
|
55
|
+
);
|
|
56
|
+
if (Array.isArray(cookies) && cookies.length > 0) {
|
|
57
|
+
return cookies.find((cookie) => cookie != null);
|
|
58
|
+
} else {
|
|
59
|
+
throw new Error("Cookie not found");
|
|
451
60
|
}
|
|
452
|
-
return files;
|
|
453
61
|
}
|
|
454
|
-
|
|
455
|
-
// noinspection JSUnusedGlobalSymbols
|
|
456
|
-
module.exports = {
|
|
457
|
-
getDecryptedCookie: getChromeCookie,
|
|
458
|
-
getChromeCookie,
|
|
459
|
-
getFirefoxCookie,
|
|
460
|
-
getCookie,
|
|
461
|
-
decrypt,
|
|
462
|
-
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import jsonwebtoken from "jsonwebtoken";
|
|
2
|
+
import { env } from "./global";
|
|
3
|
+
|
|
4
|
+
export default function isValidJwt(token: any) {
|
|
5
|
+
try {
|
|
6
|
+
const result = jsonwebtoken.decode(token, { complete: true });
|
|
7
|
+
if (env.VERBOSE) {
|
|
8
|
+
console.log(result);
|
|
9
|
+
}
|
|
10
|
+
return true;
|
|
11
|
+
} catch (err) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import CompositeCookieQueryStrategy from "./browsers/CompositeCookieQueryStrategy";
|
|
2
|
+
import { uniqBy } from "lodash";
|
|
3
|
+
import { env } from "./global";
|
|
4
|
+
import isValidJwt from "./isValidJwt";
|
|
5
|
+
import { ExportedCookie } from "./CookieRow";
|
|
6
|
+
|
|
7
|
+
export async function queryCookies(
|
|
8
|
+
{
|
|
9
|
+
name,
|
|
10
|
+
domain
|
|
11
|
+
}: {
|
|
12
|
+
name: string;
|
|
13
|
+
domain: string;
|
|
14
|
+
},
|
|
15
|
+
strategy = new CompositeCookieQueryStrategy()
|
|
16
|
+
) {
|
|
17
|
+
const results: ExportedCookie[] = await strategy.queryCookies(name, domain);
|
|
18
|
+
const results1: ExportedCookie[] = uniqBy(results, JSON.stringify);
|
|
19
|
+
const jwtCookies = [];
|
|
20
|
+
for (const result of results1) {
|
|
21
|
+
const value = result.value;
|
|
22
|
+
if (isValidJwt(value)) {
|
|
23
|
+
jwtCookies.push(result);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const resultsUniq = env.REQUIRE_JWT ? jwtCookies : results1;
|
|
27
|
+
return env.SINGLE ? [resultsUniq[0]] : resultsUniq;
|
|
28
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2
|
+
|
|
3
|
+
import {exec, ExecException} from "child_process";
|
|
4
|
+
|
|
5
|
+
export async function execSimple(command: string): Promise<string> {
|
|
6
|
+
if (process.env.VERBOSE) {
|
|
7
|
+
console.log(command);
|
|
8
|
+
}
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
exec(
|
|
11
|
+
command,
|
|
12
|
+
{ encoding: "binary", maxBuffer: 5 * 1024 },
|
|
13
|
+
(error: ExecException | null, stdout: string, stderr: string) => {
|
|
14
|
+
if (error) {
|
|
15
|
+
reject(error);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (stderr) {
|
|
19
|
+
reject(error);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (stdout) {
|
|
23
|
+
resolve(stdout.trim());
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// export async function execAsBuffer(command: string) {
|
|
31
|
+
// if (process.env.VERBOSE) {
|
|
32
|
+
// console.log(command);
|
|
33
|
+
// }
|
|
34
|
+
// return await new Promise((resolve, reject) => {
|
|
35
|
+
// exec(
|
|
36
|
+
// command,
|
|
37
|
+
// { encoding: "binary", maxBuffer: 5 * 1024 },
|
|
38
|
+
// (error: ExecException | null, stdout: string, stderr: string) => {
|
|
39
|
+
// if (error) {
|
|
40
|
+
// reject(error);
|
|
41
|
+
// return;
|
|
42
|
+
// }
|
|
43
|
+
// if (stderr) {
|
|
44
|
+
// reject(error);
|
|
45
|
+
// return;
|
|
46
|
+
// }
|
|
47
|
+
// let stdoutAsBuffer: string = stdout;
|
|
48
|
+
// if (typeof stdoutAsBuffer === "string" && stdoutAsBuffer.length > 0) {
|
|
49
|
+
// // noinspection JSCheckFunctionSignatures
|
|
50
|
+
// stdoutAsBuffer = Buffer.from(stdoutAsBuffer, "binary").slice(0, -1);
|
|
51
|
+
// }
|
|
52
|
+
// if (stdoutAsBuffer && stdoutAsBuffer.length > 0) {
|
|
53
|
+
// resolve(stdoutAsBuffer);
|
|
54
|
+
// }
|
|
55
|
+
// }
|
|
56
|
+
// );
|
|
57
|
+
// });
|
|
58
|
+
// }
|
|
59
|
+
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
export function toStringValue(r: any): string {
|
|
62
|
+
if (process.env.VERBOSE) {
|
|
63
|
+
console.log("Printing value", r);
|
|
64
|
+
}
|
|
65
|
+
if (r) {
|
|
66
|
+
if (typeof r === "string") {
|
|
67
|
+
return r;
|
|
68
|
+
} else if (r.toString) {
|
|
69
|
+
// noinspection JSCheckFunctionSignatures
|
|
70
|
+
return r.toString("utf8");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function printStringValue(r: any) {
|
|
76
|
+
if (process.env.VERBOSE) {
|
|
77
|
+
console.log("Printing value", r);
|
|
78
|
+
}
|
|
79
|
+
if (r) {
|
|
80
|
+
if (typeof r === "string") {
|
|
81
|
+
console.log(r);
|
|
82
|
+
} else if (r.toString) {
|
|
83
|
+
// noinspection JSCheckFunctionSignatures
|
|
84
|
+
console.log(r.toString("utf8"));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
* @param result
|
|
92
|
+
* @returns {string|null}
|
|
93
|
+
*/
|
|
94
|
+
export function toStringOrNull(result: any) {
|
|
95
|
+
if (result == null) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
if (process.env.VERBOSE) {
|
|
99
|
+
console.log("result", result);
|
|
100
|
+
}
|
|
101
|
+
if (typeof result === "string" && result.length > 0) {
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
if (result.slice && result.toString) {
|
|
105
|
+
// noinspection JSCheckFunctionSignatures
|
|
106
|
+
return result.toString("utf8");
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function invalidString(input: any): boolean {
|
|
112
|
+
return typeof input !== "string" || input.length === 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
export function validString(input: any): input is string {
|
|
117
|
+
return typeof input == "string" && input.length > 0;
|
|
118
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": [
|
|
3
|
+
"src/**.ts",
|
|
4
|
+
"src/**.tsx",
|
|
5
|
+
"src/**.js",
|
|
6
|
+
"src/**.jsx"
|
|
7
|
+
],
|
|
8
|
+
"compilerOptions": {
|
|
9
|
+
"moduleResolution": "node",
|
|
10
|
+
"target": "es2021",
|
|
11
|
+
"types": [
|
|
12
|
+
"node"
|
|
13
|
+
],
|
|
14
|
+
"lib": [
|
|
15
|
+
"es2015",
|
|
16
|
+
"es2017",
|
|
17
|
+
"es2021",
|
|
18
|
+
"dom"
|
|
19
|
+
],
|
|
20
|
+
"strict": true,
|
|
21
|
+
"allowSyntheticDefaultImports": true,
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/global.js
DELETED