@mherod/get-cookie 2.0.0-beta.9 → 2.0.0-rc.10
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/index.js +459 -174
- package/package-lock.json +12295 -0
- package/package.json +16 -9
- package/src/CookieRow.ts +2 -1
- package/src/CookieSpec.ts +4 -0
- package/src/CookieStore.ts +10 -0
- package/src/ExportedCookie.ts +2 -1
- package/src/{fetchResponse.ts → FetchResponse.ts} +5 -1
- package/src/IsCookieRow.ts +6 -2
- package/src/IsExportedCookie.ts +6 -2
- package/src/SpecialCases.ts +14 -0
- package/src/StringToRegex.ts +6 -0
- package/src/argv.ts +4 -0
- package/src/browsers/ChromeCookieQueryStrategy.ts +190 -106
- package/src/browsers/CompositeCookieQueryStrategy.ts +49 -7
- package/src/browsers/CookieQueryStrategy.ts +3 -2
- package/src/browsers/CookieStoreQueryStrategy.ts +94 -0
- package/src/browsers/FirefoxCookieQueryStrategy.ts +54 -46
- package/src/browsers/SafariCookieQueryStrategy.ts +3 -1
- package/src/cli.ts +90 -61
- package/src/doSqliteQuery1.ts +17 -11
- package/src/doSqliteQuery1Params.ts +7 -0
- package/src/fetchWithCookies.ts +84 -31
- package/src/findAllFiles.ts +16 -22
- package/src/getChromeCookie.ts +19 -0
- package/src/getCookie.ts +19 -0
- package/src/getFirefoxCookie.ts +19 -0
- package/src/getGroupedRenderedCookies.ts +19 -22
- package/src/getMergedRenderedCookies.ts +25 -0
- package/src/global.ts +2 -1
- package/src/index.ts +10 -46
- package/src/isValidJwt.ts +13 -3
- package/src/queryCookies.ts +17 -16
- package/src/resultsRendered.ts +7 -4
- package/src/unpackHeaders.ts +16 -0
- package/src/utils.ts +1 -32
- package/dist/cli.js +0 -3
- package/dist/cli.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/module.js +0 -533
- package/dist/module.js.map +0 -1
- package/dist/types.d.ts +0 -35
- package/dist/types.d.ts.map +0 -1
- package/src/CookieRequest.ts +0 -4
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import CookieQueryStrategy from "./CookieQueryStrategy";
|
|
2
|
+
import CookieSpec from "../CookieSpec";
|
|
3
|
+
import ExportedCookie from "../ExportedCookie";
|
|
4
|
+
import { Cookie } from "tough-cookie";
|
|
5
|
+
import { cookieStore, cookieJar } from "../CookieStore";
|
|
6
|
+
import { stringToRegex } from "../StringToRegex";
|
|
7
|
+
|
|
8
|
+
export default class CookieStoreQueryStrategy implements CookieQueryStrategy {
|
|
9
|
+
browserName = "internal";
|
|
10
|
+
|
|
11
|
+
async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
|
|
12
|
+
const exportedCookies: ExportedCookie[] = [];
|
|
13
|
+
|
|
14
|
+
// if (name.match(/[%*]/) || domain.match(/[%*]/)) {
|
|
15
|
+
const cookies: Cookie[] = await this.#getAllCookies();
|
|
16
|
+
const allExportedCookies = cookies.map((cookie: Cookie) => {
|
|
17
|
+
return this.#extracted(cookie, { name, domain });
|
|
18
|
+
});
|
|
19
|
+
exportedCookies.push(...allExportedCookies);
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
const wildcardRegexp = /^([*%])$/i;
|
|
23
|
+
if (name.match(wildcardRegexp) && domain.match(wildcardRegexp)) {
|
|
24
|
+
return exportedCookies;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const path = "/";
|
|
28
|
+
|
|
29
|
+
if (domain != "%") {
|
|
30
|
+
const domain1 = domain.match(/(\w+.+\w+)/gi)?.pop() ?? domain;
|
|
31
|
+
const url = new URL("https://" + domain1);
|
|
32
|
+
url.pathname = path;
|
|
33
|
+
const cookies: Cookie[] = await this.#getCookies(url.href);
|
|
34
|
+
const domainCookies = cookies.map((cookie: Cookie) => {
|
|
35
|
+
return this.#extracted(cookie, {
|
|
36
|
+
domain,
|
|
37
|
+
name,
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
exportedCookies.push(...domainCookies);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (name == "%") {
|
|
44
|
+
return exportedCookies.filter((cookie: ExportedCookie) => {
|
|
45
|
+
return cookie.domain.match(stringToRegex(domain));
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return exportedCookies.filter((cookie: ExportedCookie) => {
|
|
50
|
+
return (
|
|
51
|
+
cookie.name.match(stringToRegex(name)) &&
|
|
52
|
+
cookie.domain.match(stringToRegex(domain))
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#extracted(cookie: Cookie, cookieSpec: CookieSpec): ExportedCookie {
|
|
58
|
+
return {
|
|
59
|
+
domain: cookie.domain ?? cookieSpec.domain,
|
|
60
|
+
name: cookie.key ?? cookieSpec.name,
|
|
61
|
+
value: cookie.value,
|
|
62
|
+
expiry: cookie.expires ?? Infinity,
|
|
63
|
+
meta: {
|
|
64
|
+
file: "tough-cookie",
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#getCookies(url: string): Promise<Cookie[]> {
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
return cookieJar.getCookies(url, (err, cookies) => {
|
|
73
|
+
if (err) {
|
|
74
|
+
reject(err);
|
|
75
|
+
} else {
|
|
76
|
+
resolve(cookies ?? []);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#getAllCookies(): Promise<Cookie[]> {
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
return cookieStore.getAllCookies((err, cookies) => {
|
|
86
|
+
if (err) {
|
|
87
|
+
reject(err);
|
|
88
|
+
} else {
|
|
89
|
+
resolve(cookies ?? []);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -1,13 +1,17 @@
|
|
|
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
|
-
import
|
|
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 {
|
|
13
|
+
browserName = "Firefox";
|
|
14
|
+
|
|
11
15
|
async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
|
|
12
16
|
if (process.platform !== "darwin") {
|
|
13
17
|
throw new Error("This only works on macOS");
|
|
@@ -16,26 +20,21 @@ export default class FirefoxCookieQueryStrategy implements CookieQueryStrategy {
|
|
|
16
20
|
return [];
|
|
17
21
|
}
|
|
18
22
|
const cookies = await this.#getFirefoxCookie({ name, domain });
|
|
19
|
-
|
|
23
|
+
if (Array.isArray(cookies)) {
|
|
24
|
+
return cookies.map((cookie: CookieRow) => {
|
|
25
|
+
return {
|
|
26
|
+
domain: cookie.domain,
|
|
27
|
+
name: cookie.name,
|
|
28
|
+
value: cookie.value.toString("utf8"),
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
20
34
|
}
|
|
21
35
|
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* @param name
|
|
25
|
-
* @param domain
|
|
26
|
-
* @returns {Promise<Buffer>}
|
|
27
|
-
*/
|
|
28
36
|
async #getFirefoxCookie(
|
|
29
|
-
//
|
|
30
|
-
{
|
|
31
|
-
name,
|
|
32
|
-
domain
|
|
33
|
-
}: {
|
|
34
|
-
name: string,
|
|
35
|
-
domain: string
|
|
36
|
-
//
|
|
37
|
-
}
|
|
38
|
-
//
|
|
37
|
+
{ name, domain }: CookieSpec //
|
|
39
38
|
) {
|
|
40
39
|
const files: string[] = await findAllFiles({
|
|
41
40
|
path: path.join(
|
|
@@ -45,48 +44,57 @@ export default class FirefoxCookieQueryStrategy implements CookieQueryStrategy {
|
|
|
45
44
|
"Firefox",
|
|
46
45
|
"Profiles"
|
|
47
46
|
),
|
|
48
|
-
name: "cookies.sqlite"
|
|
47
|
+
name: "cookies.sqlite",
|
|
49
48
|
});
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
49
|
+
const fn: (file: string) => Promise<CookieRow[]> = async (file: string) => {
|
|
50
|
+
return await this.#queryCookiesDb(file, name, domain);
|
|
51
|
+
};
|
|
52
|
+
const all: Awaited<CookieRow[]>[] = await Promise.all(files.map(fn));
|
|
55
53
|
return all.flat();
|
|
56
54
|
}
|
|
57
55
|
|
|
58
|
-
#queryCookiesDb(
|
|
56
|
+
async #queryCookiesDb(
|
|
57
|
+
file: string,
|
|
58
|
+
name: string,
|
|
59
|
+
domain: string
|
|
60
|
+
): Promise<CookieRow[]> {
|
|
59
61
|
if (file && !existsSync(file)) {
|
|
60
62
|
throw new Error(`File ${file} does not exist`);
|
|
61
63
|
}
|
|
62
|
-
if (env.VERBOSE) {
|
|
63
|
-
console.log(`Trying Firefox cookie ${name} for domain ${domain}`);
|
|
64
|
-
}
|
|
65
64
|
let sql;
|
|
66
65
|
//language=SQL
|
|
67
|
-
sql = "SELECT value FROM moz_cookies";
|
|
68
|
-
|
|
66
|
+
sql = "SELECT value, name, host FROM moz_cookies";
|
|
67
|
+
const { specifiedName, specifiedDomain } = specialCases({ name, domain });
|
|
68
|
+
if (specifiedName || specifiedDomain) {
|
|
69
69
|
sql += ` WHERE `;
|
|
70
|
-
if (
|
|
70
|
+
if (specifiedName) {
|
|
71
71
|
sql += `name = '${name}'`;
|
|
72
|
-
if (
|
|
72
|
+
if (specifiedDomain) {
|
|
73
73
|
sql += ` AND `;
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
if (
|
|
76
|
+
if (specifiedDomain) {
|
|
77
77
|
sql += `host LIKE '${domain}';`;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
const rowTransform = (row: any) => {
|
|
81
|
+
// row is object key by column name
|
|
82
|
+
const value = row.value as string;
|
|
83
|
+
return {
|
|
84
|
+
domain: row.domain as string,
|
|
85
|
+
name: row.name as string,
|
|
86
|
+
value: Buffer.from(value, "utf8"),
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
try {
|
|
90
|
+
return await doSqliteQuery1({
|
|
91
|
+
file,
|
|
92
|
+
sql,
|
|
93
|
+
rowTransform,
|
|
94
|
+
});
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.error(`Error querying ${file}`, e);
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
91
99
|
}
|
|
92
100
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import CookieQueryStrategy from "./CookieQueryStrategy";
|
|
2
|
-
import
|
|
2
|
+
import ExportedCookie from "../ExportedCookie";
|
|
3
3
|
|
|
4
4
|
export default class SafariCookieQueryStrategy implements CookieQueryStrategy {
|
|
5
|
+
browserName = "Safari";
|
|
6
|
+
|
|
5
7
|
async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
|
|
6
8
|
return [];
|
|
7
9
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,82 +1,111 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { argv, parsedArgs } from "./argv";
|
|
4
4
|
import { queryCookies } from "./queryCookies";
|
|
5
|
-
import { argv } from "./argv";
|
|
6
5
|
import { groupBy } from "lodash";
|
|
7
|
-
import {
|
|
6
|
+
import { green, red, yellow } from "colorette";
|
|
8
7
|
import { resultsRendered } from "./resultsRendered";
|
|
9
|
-
import {
|
|
8
|
+
import { fetchWithCookies } from "./fetchWithCookies";
|
|
9
|
+
import { unpackHeaders } from "./unpackHeaders";
|
|
10
|
+
import CookieSpec from "./CookieSpec";
|
|
10
11
|
|
|
11
|
-
function
|
|
12
|
-
return blue(resultsRendered(results));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function cliQueryCookies(name: string, domain: string) {
|
|
12
|
+
async function cliQueryCookies({ name, domain }: CookieSpec) {
|
|
16
13
|
try {
|
|
17
14
|
const results = await queryCookies({ name, domain });
|
|
18
|
-
if (results.length
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
15
|
+
if (results == null || results.length == 0) {
|
|
16
|
+
console.error(red("No results"));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (parsedArgs["dump"] || parsedArgs["d"]) {
|
|
20
|
+
console.log(results);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (parsedArgs["dump-grouped"] || parsedArgs["D"]) {
|
|
24
|
+
const groupedByFile = groupBy(results, (r) => r.meta?.file);
|
|
25
|
+
console.log(green(JSON.stringify(groupedByFile, null, 2)));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (
|
|
29
|
+
parsedArgs["render"] ||
|
|
30
|
+
parsedArgs["render-merged"] ||
|
|
31
|
+
parsedArgs["r"]
|
|
32
|
+
) {
|
|
33
|
+
console.log(yellow(resultsRendered(results)));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (parsedArgs["render-grouped"] || parsedArgs["R"]) {
|
|
37
|
+
const groupedByFile = groupBy(results, (r) => r.meta?.file);
|
|
38
|
+
for (const file of Object.keys(groupedByFile)) {
|
|
39
|
+
let results = groupedByFile[file];
|
|
40
|
+
console.log(green(file) + ": ", yellow(resultsRendered(results)));
|
|
36
41
|
}
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
for (const result of results) {
|
|
45
|
+
console.log(result.value);
|
|
39
46
|
}
|
|
40
47
|
} catch (e) {
|
|
41
48
|
console.error(e);
|
|
42
49
|
}
|
|
43
50
|
}
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
function main() {
|
|
53
|
+
if (parsedArgs["help"] || parsedArgs["h"]) {
|
|
54
|
+
console.log(`Usage: ${argv[1]} [name] [domain] [options] `);
|
|
55
|
+
console.log(`Options:`);
|
|
56
|
+
console.log(` -h, --help: Show this help`);
|
|
57
|
+
console.log(` -v, --verbose: Show verbose output`);
|
|
58
|
+
console.log(` -d, --dump: Dump all results`);
|
|
59
|
+
console.log(` -D, --dump-grouped: Dump all results, grouped by profile`);
|
|
60
|
+
console.log(` -r, --render: Render all results`);
|
|
61
|
+
return;
|
|
53
62
|
}
|
|
54
63
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
const fetchUrl: string = parsedArgs["fetch"] || parsedArgs["F"];
|
|
65
|
+
if (fetchUrl) {
|
|
66
|
+
let url: URL;
|
|
67
|
+
try {
|
|
68
|
+
url = new URL(<string>fetchUrl);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
console.error("Invalid URL", fetchUrl);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const headerArgs: string[] | string = parsedArgs["H"];
|
|
74
|
+
const headers = unpackHeaders(headerArgs);
|
|
75
|
+
const onfulfilled = (res: Response) => {
|
|
76
|
+
if (parsedArgs["dump-response-headers"]) {
|
|
77
|
+
res.headers.forEach((value: string, key: string) => {
|
|
78
|
+
console.log(`${key}: ${value}`);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (parsedArgs["dump-response-body"]) {
|
|
82
|
+
res.text().then((r) => {
|
|
83
|
+
console.log(r);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
};
|
|
88
|
+
fetchWithCookies(
|
|
89
|
+
url,
|
|
90
|
+
{
|
|
91
|
+
//
|
|
92
|
+
headers,
|
|
93
|
+
}
|
|
94
|
+
//
|
|
95
|
+
).then(
|
|
96
|
+
onfulfilled,
|
|
97
|
+
console.error
|
|
98
|
+
//
|
|
99
|
+
);
|
|
100
|
+
return;
|
|
75
101
|
}
|
|
76
102
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
103
|
+
const cookieSpec: CookieSpec = {
|
|
104
|
+
name: parsedArgs["name"] || parsedArgs["_"][0] || "%",
|
|
105
|
+
domain: parsedArgs["domain"] || parsedArgs["_"][1] || "%",
|
|
106
|
+
};
|
|
80
107
|
|
|
81
|
-
cliQueryCookies(
|
|
108
|
+
cliQueryCookies(cookieSpec).catch(console.error);
|
|
82
109
|
}
|
|
110
|
+
|
|
111
|
+
main();
|
package/src/doSqliteQuery1.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as sqlite3 from "sqlite3";
|
|
3
|
-
import
|
|
3
|
+
import CookieRow from "./CookieRow";
|
|
4
|
+
import { merge } from "lodash";
|
|
5
|
+
import { parsedArgs } from "./argv";
|
|
6
|
+
import { DoSqliteQuery1Params } from "./doSqliteQuery1Params";
|
|
4
7
|
|
|
5
|
-
export async function doSqliteQuery1(
|
|
6
|
-
|
|
8
|
+
export async function doSqliteQuery1({
|
|
9
|
+
file,
|
|
10
|
+
sql,
|
|
11
|
+
rowTransform,
|
|
12
|
+
}: DoSqliteQuery1Params): Promise<CookieRow[]> {
|
|
13
|
+
if (!file || (file && !fs.existsSync(file))) {
|
|
7
14
|
throw new Error(`doSqliteQuery1: file ${file} does not exist`);
|
|
8
15
|
}
|
|
9
16
|
const db = new sqlite3.Database(file);
|
|
@@ -19,20 +26,19 @@ export async function doSqliteQuery1(file: string, sql: string): Promise<CookieR
|
|
|
19
26
|
return;
|
|
20
27
|
}
|
|
21
28
|
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"],
|
|
29
|
+
const cookieRows: CookieRow[] = rows1.map((row: any) => {
|
|
30
|
+
const newVar = {
|
|
27
31
|
meta: {
|
|
28
|
-
file: file
|
|
29
|
-
}
|
|
32
|
+
file: file,
|
|
33
|
+
},
|
|
30
34
|
};
|
|
35
|
+
const cookieRow: CookieRow = rowTransform(row);
|
|
36
|
+
return merge(newVar, cookieRow);
|
|
31
37
|
});
|
|
32
38
|
resolve(cookieRows);
|
|
33
39
|
return;
|
|
34
40
|
}
|
|
35
|
-
if (
|
|
41
|
+
if (parsedArgs.verbose) {
|
|
36
42
|
console.log(`doSqliteQuery1: rows ${JSON.stringify(rows1)}`);
|
|
37
43
|
}
|
|
38
44
|
resolve([rows1]);
|
package/src/fetchWithCookies.ts
CHANGED
|
@@ -1,61 +1,114 @@
|
|
|
1
1
|
// noinspection JSUnusedGlobalSymbols
|
|
2
2
|
|
|
3
|
-
import { fetch } from "cross-fetch";
|
|
3
|
+
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
|
|
8
|
-
import {
|
|
7
|
+
import CookieSpec from "./CookieSpec";
|
|
8
|
+
import { cookieJar } from "./CookieStore";
|
|
9
|
+
import UserAgent from "user-agents";
|
|
10
|
+
import { parsedArgs } from "./argv";
|
|
11
|
+
import { blue, yellow } from "colorette";
|
|
12
|
+
import { getMergedRenderedCookies } from "./getMergedRenderedCookies";
|
|
9
13
|
|
|
10
14
|
export async function fetchWithCookies(
|
|
11
15
|
url: RequestInfo | URL,
|
|
12
|
-
options: RequestInit | undefined = {}
|
|
13
|
-
|
|
16
|
+
options: RequestInit | undefined = {},
|
|
17
|
+
fetch: Function = fetchImpl
|
|
18
|
+
): Promise<Response> {
|
|
14
19
|
const defaultOptions: RequestInit = {
|
|
15
20
|
headers: {
|
|
16
|
-
"User-Agent":
|
|
21
|
+
"User-Agent": new UserAgent().toString(),
|
|
17
22
|
},
|
|
18
|
-
redirect: "manual"
|
|
23
|
+
redirect: "manual",
|
|
19
24
|
};
|
|
20
25
|
const url2: string = `${url}`;
|
|
21
26
|
const url1: URL = new URL(url2);
|
|
22
27
|
const domain = url1.hostname.replace(/^.*(\.\w+\.\w+)$/, (match, p1) => {
|
|
23
28
|
return `%${p1}`;
|
|
24
29
|
});
|
|
25
|
-
const
|
|
30
|
+
const cookieSpec: CookieSpec = {
|
|
26
31
|
name: "%",
|
|
27
|
-
domain: domain
|
|
28
|
-
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
32
|
+
domain: domain,
|
|
33
|
+
};
|
|
34
|
+
// const cookies: string[] = await getGroupedRenderedCookies(cookieSpec).catch(
|
|
35
|
+
// () => []
|
|
36
|
+
// );
|
|
37
|
+
// const cookie = cookies.pop();
|
|
38
|
+
const cookie = await getMergedRenderedCookies(cookieSpec).catch(() => "");
|
|
39
|
+
const headers = {};
|
|
40
|
+
if (cookie.length > 0) {
|
|
41
|
+
merge(headers, {
|
|
42
|
+
Cookie: cookie,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const newOptions1: RequestInit = merge(defaultOptions, options, { headers });
|
|
35
46
|
try {
|
|
36
|
-
const res = await fetch(url2, newOptions1);
|
|
37
|
-
const
|
|
38
|
-
|
|
47
|
+
const res: Response = await fetch(url2, newOptions1);
|
|
48
|
+
const headers: [string, string][] = [];
|
|
49
|
+
res.headers.forEach((value, key) => {
|
|
50
|
+
headers.push([key, value]);
|
|
51
|
+
});
|
|
52
|
+
for (const [key, value] of headers) {
|
|
53
|
+
if (key === "set-cookie") {
|
|
54
|
+
await cookieJar.setCookie(value, url2);
|
|
55
|
+
if (parsedArgs.verbose) {
|
|
56
|
+
console.log(blue(`Set-Cookie: ${yellow(value)} ${yellow(url2)}`));
|
|
57
|
+
}
|
|
58
|
+
// const cookie = tough.parse(value);
|
|
59
|
+
// if (cookie instanceof Cookie) {
|
|
60
|
+
// await memoryCookieStore.putCookie(cookie);
|
|
61
|
+
// }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const newUrl: string = res.headers.get("location") as string;
|
|
66
|
+
if (res.redirected || (newUrl && newUrl !== url2)) {
|
|
67
|
+
if (parsedArgs.verbose) {
|
|
68
|
+
console.log(blue(`Redirected to `), yellow(newUrl));
|
|
69
|
+
}
|
|
39
70
|
return fetchWithCookies(newUrl, newOptions1);
|
|
40
71
|
}
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
72
|
+
|
|
73
|
+
const arrayBuffer1: Promise<ArrayBuffer> = res.arrayBuffer();
|
|
74
|
+
|
|
75
|
+
async function arrayBuffer(): Promise<ArrayBuffer> {
|
|
76
|
+
return arrayBuffer1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function buffer(): Promise<Buffer> {
|
|
80
|
+
return arrayBuffer().then(Buffer.from);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function text(): Promise<string> {
|
|
84
|
+
return buffer().then((buffer) => buffer.toString("utf8"));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function json(): Promise<any> {
|
|
88
|
+
return text().then((text) => destr(text));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function formData(): Promise<FormData> {
|
|
92
|
+
const urlSearchParams: URLSearchParams = await text().then(
|
|
93
|
+
(text) => new URLSearchParams(text)
|
|
94
|
+
);
|
|
95
|
+
const formData = new FormData();
|
|
96
|
+
for (const [key, value] of urlSearchParams.entries()) {
|
|
97
|
+
formData.append(key, value);
|
|
98
|
+
}
|
|
99
|
+
return formData;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const res1: Response = res;
|
|
47
103
|
const source2 = {
|
|
48
|
-
status: res.status,
|
|
49
|
-
statusText: res.statusText,
|
|
50
|
-
headers: res.headers,
|
|
51
104
|
arrayBuffer,
|
|
52
|
-
buffer,
|
|
53
105
|
text,
|
|
54
106
|
json,
|
|
55
|
-
|
|
107
|
+
buffer,
|
|
108
|
+
formData,
|
|
56
109
|
//
|
|
57
110
|
};
|
|
58
|
-
return merge(
|
|
111
|
+
return merge(res1, source2);
|
|
59
112
|
} catch (e) {
|
|
60
113
|
throw e;
|
|
61
114
|
}
|