@mherod/get-cookie 2.1.3 → 4.0.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/.husky/commit-msg +2 -0
- package/.husky/pre-commit +4 -0
- package/.husky/pre-push +4 -0
- package/README.md +163 -18
- package/commitlint.config.js +12 -0
- package/dist/chunk-56Z35D5R.js +2 -0
- package/dist/chunk-56Z35D5R.js.map +1 -0
- package/dist/chunk-5FUMK7M3.js +4 -0
- package/dist/chunk-5FUMK7M3.js.map +1 -0
- package/dist/chunk-5ZT2G45S.js +2 -0
- package/dist/chunk-5ZT2G45S.js.map +1 -0
- package/dist/chunk-FR2MKDHT.js +2 -0
- package/dist/chunk-FR2MKDHT.js.map +1 -0
- package/dist/chunk-HMKSQBDC.js +2 -0
- package/dist/chunk-HMKSQBDC.js.map +1 -0
- package/dist/chunk-VMBA4NVU.js +2 -0
- package/dist/chunk-VMBA4NVU.js.map +1 -0
- package/dist/chunk-W3JALMAX.js +2 -0
- package/dist/chunk-W3JALMAX.js.map +1 -0
- package/dist/cli.cjs +19 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/getChromeCookie-4ZWACG6M.js +2 -0
- package/dist/getChromeCookie-4ZWACG6M.js.map +1 -0
- package/dist/getChromePassword-GTIXL733.js +2 -0
- package/dist/getChromePassword-GTIXL733.js.map +1 -0
- package/dist/getCookie-43FKMQEZ.js +2 -0
- package/dist/getCookie-43FKMQEZ.js.map +1 -0
- package/dist/getFirefoxCookie-OJYYZFZP.js +2 -0
- package/dist/getFirefoxCookie-OJYYZFZP.js.map +1 -0
- package/dist/getGroupedRenderedCookies-P5VZXZUC.js +2 -0
- package/dist/getGroupedRenderedCookies-P5VZXZUC.js.map +1 -0
- package/dist/getMergedRenderedCookies-C6TXK2I4.js +2 -0
- package/dist/getMergedRenderedCookies-C6TXK2I4.js.map +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +252 -0
- package/dist/index.d.ts +252 -0
- package/dist/index.js +2 -24712
- package/dist/index.js.map +1 -0
- package/eslint.config.js +243 -0
- package/jest.setup.js +11 -0
- package/package.json +87 -36
- package/tsconfig.build.json +9 -0
- package/tsup.cli.ts +27 -0
- package/tsup.config.ts +27 -0
- package/tsup.lib.ts +27 -0
- package/typedoc.json +22 -0
- package/.parcelrc +0 -7
- package/.prettierignore +0 -5
- package/.prettierrc +0 -12
- package/.terserrc +0 -26
- package/build-indexes.ts +0 -108
- package/bun.lockb +0 -0
- package/dist/cli.js +0 -18319
- package/dist/types.d.ts +0 -361
- package/jest.config.ts +0 -14
- package/package-lock.json +0 -5608
- package/src/CookieRow.ts +0 -43
- package/src/CookieSpec.ts +0 -42
- package/src/ExportedCookie.ts +0 -19
- package/src/FetchResponse.ts +0 -13
- package/src/SpecialCases.ts +0 -15
- package/src/StringToRegex.ts +0 -16
- package/src/argv.ts +0 -30
- package/src/browsers/CompositeCookieQueryStrategy.ts +0 -76
- package/src/browsers/CookieQueryStrategy.ts +0 -7
- package/src/browsers/CookieStoreQueryStrategy.ts +0 -115
- package/src/browsers/QuerySqliteThenTransform.ts +0 -48
- package/src/browsers/chrome/ChromeApplicationSupport.ts +0 -14
- package/src/browsers/chrome/ChromeCookieQueryStrategy.ts +0 -158
- package/src/browsers/chrome/decrypt.ts +0 -154
- package/src/browsers/chrome/getChromePassword.ts +0 -28
- package/src/browsers/firefox/FirefoxCookieQueryStrategy.ts +0 -109
- package/src/browsers/getEncryptedChromeCookie.ts +0 -122
- package/src/browsers/index.ts +0 -12
- package/src/browsers/mock/MockCookieQueryStrategy.ts +0 -22
- package/src/browsers/safari/SafariCookieQueryStrategy.ts +0 -42
- package/src/cli.ts +0 -94
- package/src/cliQueryCookies.ts +0 -65
- package/src/comboQueryCookieSpec.test.ts +0 -92
- package/src/comboQueryCookieSpec.ts +0 -26
- package/src/cookieQueryOptions.ts +0 -27
- package/src/cookieSpecsFromUrl.test.ts +0 -65
- package/src/cookieSpecsFromUrl.ts +0 -73
- package/src/decodeBinaryCookies.ts +0 -72
- package/src/execSimple.ts +0 -12
- package/src/fetchWithCookies.test.ts +0 -32
- package/src/fetchWithCookies.ts +0 -217
- package/src/findAllFiles.ts +0 -48
- package/src/getChromeCookie.ts +0 -19
- package/src/getCookie.ts +0 -22
- package/src/getFirefoxCookie.ts +0 -25
- package/src/getGroupedRenderedCookies.ts +0 -42
- package/src/getMergedRenderedCookies.test.ts +0 -43
- package/src/getMergedRenderedCookies.ts +0 -19
- package/src/global.ts +0 -8
- package/src/index.ts +0 -16
- package/src/isValidJwt.ts +0 -26
- package/src/listChromeProfiles.ts +0 -53
- package/src/logger.ts +0 -12
- package/src/processBeforeReturn.ts +0 -29
- package/src/queryCookies.ts +0 -41
- package/src/resultsRendered.ts +0 -24
- package/src/unpackHeaders.ts +0 -18
- package/src/util/flatMapAsync.test.ts +0 -55
- package/src/util/flatMapAsync.ts +0 -41
- package/src/util/index.ts +0 -1
- package/tsconfig.json +0 -26
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { MultiCookieSpec } from "./CookieSpec";
|
|
2
|
-
import CookieQueryStrategy from "./browsers/CookieQueryStrategy";
|
|
3
|
-
import MockCookieQueryStrategy from "./browsers/mock/MockCookieQueryStrategy";
|
|
4
|
-
import { comboQueryCookieSpec } from "./comboQueryCookieSpec";
|
|
5
|
-
import { CookieQueryOptions } from "./cookieQueryOptions";
|
|
6
|
-
|
|
7
|
-
describe("comboQueryCookieSpec", () => {
|
|
8
|
-
let cookieSpec: MultiCookieSpec;
|
|
9
|
-
let options: CookieQueryOptions<CookieQueryStrategy>;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
cookieSpec = {
|
|
13
|
-
domain: "example.com",
|
|
14
|
-
name: "test",
|
|
15
|
-
};
|
|
16
|
-
options = {
|
|
17
|
-
strategy: new MockCookieQueryStrategy([
|
|
18
|
-
// mock available cookies here
|
|
19
|
-
{
|
|
20
|
-
name: "test",
|
|
21
|
-
value: "test",
|
|
22
|
-
domain: "example.com",
|
|
23
|
-
expiry: "Infinity",
|
|
24
|
-
},
|
|
25
|
-
]),
|
|
26
|
-
limit: 10,
|
|
27
|
-
removeExpired: true,
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("should return an array of cookies", async () => {
|
|
32
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
33
|
-
expect(result).toBeInstanceOf(Array);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("should limit the number of cookies returned", async () => {
|
|
37
|
-
options.limit = 5;
|
|
38
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
39
|
-
expect(result.length).toBeLessThanOrEqual(5);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("should return cookies with the correct domain", async () => {
|
|
43
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
44
|
-
expect(result[0].domain).toBe("example.com");
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("should return cookies with the correct name", async () => {
|
|
48
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
49
|
-
expect(result[0].name).toBe("test");
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("should return cookies with the correct value", async () => {
|
|
53
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
54
|
-
expect(result[0].value).toBe("test");
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("should return cookies with the correct expiry", async () => {
|
|
58
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
59
|
-
expect(result[0].expiry).toBe("Infinity");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("should return cookies with the correct meta", async () => {
|
|
63
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
64
|
-
expect(result[0].meta).toBeUndefined();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it("should return cookies when limit is undefined", async () => {
|
|
68
|
-
options.limit = undefined;
|
|
69
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
70
|
-
expect(result.length).toBe(1);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("should return cookies when removeExpired is false", async () => {
|
|
74
|
-
options.removeExpired = false;
|
|
75
|
-
const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
76
|
-
expect(result.length).toBe(1);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// it('should not return cookies when removeExpired is true and expiry is past', async () => {
|
|
80
|
-
// options.removeExpired = true;
|
|
81
|
-
// cookieSpec.expiry = new Date('2000-01-01');
|
|
82
|
-
// const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
83
|
-
// expect(result.length).toBe(0);
|
|
84
|
-
// });
|
|
85
|
-
|
|
86
|
-
// it('should return cookies when removeExpired is true and expiry is future', async () => {
|
|
87
|
-
// options.removeExpired = true;
|
|
88
|
-
// cookieSpec.expiry = new Date('3000-01-01');
|
|
89
|
-
// const result = await comboQueryCookieSpec(cookieSpec, options);
|
|
90
|
-
// expect(result.length).toBe(1);
|
|
91
|
-
// });
|
|
92
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import CookieSpec, { MultiCookieSpec } from "./CookieSpec";
|
|
2
|
-
import ExportedCookie from "./ExportedCookie";
|
|
3
|
-
import { queryCookies } from "./queryCookies";
|
|
4
|
-
import { flatMapAsync } from "./util";
|
|
5
|
-
import CookieQueryStrategy from "./browsers/CookieQueryStrategy";
|
|
6
|
-
import { CookieQueryOptions, mergedWithDefaults } from "./cookieQueryOptions";
|
|
7
|
-
import { processBeforeReturn } from "./processBeforeReturn";
|
|
8
|
-
|
|
9
|
-
export async function comboQueryCookieSpec(
|
|
10
|
-
cookieSpec: MultiCookieSpec,
|
|
11
|
-
options?: CookieQueryOptions<CookieQueryStrategy>,
|
|
12
|
-
): Promise<ExportedCookie[]> {
|
|
13
|
-
const optsWithDefaults: CookieQueryOptions<CookieQueryStrategy> =
|
|
14
|
-
mergedWithDefaults(options);
|
|
15
|
-
const queryFn = async (cs: CookieSpec): Promise<ExportedCookie[]> =>
|
|
16
|
-
queryCookies(cs, optsWithDefaults);
|
|
17
|
-
|
|
18
|
-
let cookies: ExportedCookie[];
|
|
19
|
-
if (Array.isArray(cookieSpec)) {
|
|
20
|
-
cookies = await flatMapAsync(cookieSpec, queryFn);
|
|
21
|
-
} else {
|
|
22
|
-
cookies = await queryFn(cookieSpec);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return processBeforeReturn(cookies, options);
|
|
26
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import CookieQueryStrategy from "./browsers/CookieQueryStrategy";
|
|
2
|
-
import CompositeCookieQueryStrategy from "./browsers/CompositeCookieQueryStrategy";
|
|
3
|
-
import { merge } from "lodash";
|
|
4
|
-
|
|
5
|
-
export type CookieQueryOptions<T extends CookieQueryStrategy> = {
|
|
6
|
-
strategy?: T;
|
|
7
|
-
limit?: number;
|
|
8
|
-
removeExpired?: boolean;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const defaultCookieQueryOptions: CookieQueryOptions<CookieQueryStrategy> =
|
|
12
|
-
{
|
|
13
|
-
strategy: new CompositeCookieQueryStrategy(),
|
|
14
|
-
limit: undefined,
|
|
15
|
-
removeExpired: undefined,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export function mergedWithDefaults<T extends CookieQueryStrategy>(
|
|
19
|
-
options?: CookieQueryOptions<T>,
|
|
20
|
-
): CookieQueryOptions<T> {
|
|
21
|
-
const mergedOptions: CookieQueryOptions<T> = merge(
|
|
22
|
-
{},
|
|
23
|
-
defaultCookieQueryOptions,
|
|
24
|
-
options,
|
|
25
|
-
);
|
|
26
|
-
return mergedOptions;
|
|
27
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { cookieSpecsFromUrl } from "./cookieSpecsFromUrl";
|
|
2
|
-
import { isCookieSpec } from "./CookieSpec";
|
|
3
|
-
import { uniqBy } from "lodash";
|
|
4
|
-
|
|
5
|
-
describe("cookieSpecsFromUrl", () => {
|
|
6
|
-
it("should return an array of cookie specs", () => {
|
|
7
|
-
const url = "https://example.com/";
|
|
8
|
-
const result = cookieSpecsFromUrl(url);
|
|
9
|
-
expect(result).toBeInstanceOf(Array);
|
|
10
|
-
expect(isCookieSpec(result[0])).toBe(true);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it("should handle string URLs", () => {
|
|
14
|
-
const url = "https://example.com/";
|
|
15
|
-
const result = cookieSpecsFromUrl(url);
|
|
16
|
-
expect(result[0].domain).toContain("example.com");
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("should handle URL objects", () => {
|
|
20
|
-
const url = new URL("https://example.com/");
|
|
21
|
-
const result = cookieSpecsFromUrl(url);
|
|
22
|
-
expect(result[0].domain).toContain("example.com");
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("should handle empty string URL", () => {
|
|
26
|
-
const url = "";
|
|
27
|
-
const result = cookieSpecsFromUrl(url);
|
|
28
|
-
expect(result).toEqual([]);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("should handle invalid URL", () => {
|
|
32
|
-
const url = "invalid_url";
|
|
33
|
-
try {
|
|
34
|
-
const result = cookieSpecsFromUrl(url);
|
|
35
|
-
} catch (error: any) {
|
|
36
|
-
expect(error.message).toContain("Invalid URL");
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("should return unique cookie specs", () => {
|
|
41
|
-
const url = "https://example.com/";
|
|
42
|
-
const result = cookieSpecsFromUrl(url);
|
|
43
|
-
const uniqueResults = uniqBy(result, JSON.stringify);
|
|
44
|
-
expect(result.length).toEqual(uniqueResults.length);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("should return correct cookie specs for URL with subdomain", () => {
|
|
48
|
-
const url = "https://sub.example.com/";
|
|
49
|
-
const result = cookieSpecsFromUrl(url);
|
|
50
|
-
expect(result).toContainEqual({ name: "%", domain: "sub.example.com" });
|
|
51
|
-
expect(result).toContainEqual({ name: "%", domain: "%.example.com" });
|
|
52
|
-
expect(result).toContainEqual({ name: "%", domain: "example.com" });
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should return correct cookie specs for URL with multiple subdomains", () => {
|
|
56
|
-
const url = "https://sub.sub2.example.com/";
|
|
57
|
-
const result = cookieSpecsFromUrl(url);
|
|
58
|
-
expect(result).toContainEqual({
|
|
59
|
-
name: "%",
|
|
60
|
-
domain: "sub.sub2.example.com",
|
|
61
|
-
});
|
|
62
|
-
expect(result).toContainEqual({ name: "%", domain: "%.example.com" });
|
|
63
|
-
expect(result).toContainEqual({ name: "%", domain: "example.com" });
|
|
64
|
-
});
|
|
65
|
-
});
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import CookieSpec from "./CookieSpec";
|
|
2
|
-
import { uniqBy } from "lodash";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generates a list of cookie specifications from a given URL.
|
|
6
|
-
* Each cookie spec consists of a domain and a name, where the name is a wildcard.
|
|
7
|
-
* The domain is formatted to enable querying against the cookie store for matching cookies.
|
|
8
|
-
* @param url - The URL to generate cookie specs from.
|
|
9
|
-
* @returns An array of unique cookie specifications.
|
|
10
|
-
*/
|
|
11
|
-
export function cookieSpecsFromUrl(url: URL | string): CookieSpec[] {
|
|
12
|
-
if (!url || url === "") {
|
|
13
|
-
return [];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const urlObj: URL = parseUrl(url);
|
|
17
|
-
const hostnameParts: string[] = splitHostname(urlObj.hostname);
|
|
18
|
-
const topLevelDomain: string = getTopLevelDomain(hostnameParts);
|
|
19
|
-
|
|
20
|
-
const cookieSpecs: CookieSpec[] = createCookieSpecs(
|
|
21
|
-
urlObj.hostname,
|
|
22
|
-
topLevelDomain,
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
return uniqBy(
|
|
26
|
-
cookieSpecs,
|
|
27
|
-
(spec: CookieSpec) => `${spec.name}:${spec.domain}`,
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Parses the input URL string or URL object and returns a URL object.
|
|
33
|
-
* @param url - The URL to parse.
|
|
34
|
-
* @returns A URL object.
|
|
35
|
-
*/
|
|
36
|
-
function parseUrl(url: URL | string): URL {
|
|
37
|
-
return typeof url === "string" ? new URL(url) : url;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Splits the hostname into its constituent parts.
|
|
42
|
-
* @param hostname - The hostname to split.
|
|
43
|
-
* @returns An array of strings representing the parts of the hostname.
|
|
44
|
-
*/
|
|
45
|
-
function splitHostname(hostname: string): string[] {
|
|
46
|
-
return hostname.split(".");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Extracts the top-level domain from the hostname parts.
|
|
51
|
-
* @param hostnameParts - The parts of the hostname.
|
|
52
|
-
* @returns A string representing the top-level domain.
|
|
53
|
-
*/
|
|
54
|
-
function getTopLevelDomain(hostnameParts: string[]): string {
|
|
55
|
-
return hostnameParts.slice(-2).join(".");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Creates cookie specifications based on the hostname and top-level domain.
|
|
60
|
-
* @param hostname - The full hostname.
|
|
61
|
-
* @param topLevelDomain - The top-level domain.
|
|
62
|
-
* @returns An array of CookieSpec objects.
|
|
63
|
-
*/
|
|
64
|
-
function createCookieSpecs(
|
|
65
|
-
hostname: string,
|
|
66
|
-
topLevelDomain: string,
|
|
67
|
-
): CookieSpec[] {
|
|
68
|
-
return [
|
|
69
|
-
{ name: "%", domain: `%.${topLevelDomain}` },
|
|
70
|
-
{ name: "%", domain: hostname },
|
|
71
|
-
{ name: "%", domain: topLevelDomain },
|
|
72
|
-
];
|
|
73
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import CookieRow from "./CookieRow";
|
|
2
|
-
import fs from "fs/promises";
|
|
3
|
-
|
|
4
|
-
export const decodeBinaryCookies = async (cookieDbPath: string): Promise<CookieRow[]> => {
|
|
5
|
-
try {
|
|
6
|
-
// Check if file exists
|
|
7
|
-
await fs.access(cookieDbPath);
|
|
8
|
-
} catch {
|
|
9
|
-
// If file doesn't exist, return empty array
|
|
10
|
-
return [];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Magic bytes: "COOK" = 0x636F6F6B
|
|
14
|
-
const magicBytes: Buffer = Buffer.from([0x63, 0x6F, 0x6B, 0x6B]);
|
|
15
|
-
const buffer: Buffer = await fs.readFile(cookieDbPath);
|
|
16
|
-
|
|
17
|
-
if (!buffer.slice(0, 4).equals(magicBytes)) {
|
|
18
|
-
throw new Error("Not a cookie file");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const count: number = buffer.readUInt32BE(4);
|
|
22
|
-
const cookies: CookieRow[] = [];
|
|
23
|
-
|
|
24
|
-
let offset: number = 8;
|
|
25
|
-
for (let i: number = 0; i < count; i++) {
|
|
26
|
-
const pageSize: number = buffer.readUInt32BE(offset);
|
|
27
|
-
offset += 4;
|
|
28
|
-
const page: Buffer = buffer.slice(offset, offset + pageSize);
|
|
29
|
-
offset += pageSize;
|
|
30
|
-
|
|
31
|
-
if (!page.slice(0, 4).equals(Buffer.from([0x00, 0x00, 0x01, 0x00]))) {
|
|
32
|
-
throw new Error("Bad page header");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const cookieCount: number = page.readUInt32LE(4);
|
|
36
|
-
let pageOffset: number = 8;
|
|
37
|
-
for (let j: number = 0; j < cookieCount; j++) {
|
|
38
|
-
const cookieOffset: number = page.readUInt32LE(pageOffset);
|
|
39
|
-
pageOffset += 4;
|
|
40
|
-
const cookieLength: number = page.readUInt32LE(cookieOffset);
|
|
41
|
-
const cookie: Buffer = page.slice(cookieOffset, cookieOffset + cookieLength);
|
|
42
|
-
|
|
43
|
-
const flags: number = cookie.readUInt32LE(8);
|
|
44
|
-
const urlOffset: number = cookie.readUInt32LE(16);
|
|
45
|
-
const nameOffset: number = cookie.readUInt32LE(20);
|
|
46
|
-
const valueOffset: number = cookie.readUInt32LE(28);
|
|
47
|
-
const expiry: number = cookie.readDoubleLE(40) + 978307200;
|
|
48
|
-
|
|
49
|
-
const url: string = cookie.slice(urlOffset, nameOffset).toString('utf8').replace(/\0/g, '');
|
|
50
|
-
const name: string = cookie.slice(nameOffset, valueOffset).toString('utf8').replace(/\0/g, '');
|
|
51
|
-
const value: string = cookie.slice(valueOffset, cookie.length).toString('utf8').replace(/\0/g, '');
|
|
52
|
-
|
|
53
|
-
cookies.push({
|
|
54
|
-
domain: url,
|
|
55
|
-
name: name,
|
|
56
|
-
value: Buffer.from(value, 'utf8'),
|
|
57
|
-
expiry: new Date(expiry * 1000).getTime(),
|
|
58
|
-
meta: {
|
|
59
|
-
path: cookie.slice(cookie.readUInt32LE(24), valueOffset).toString('utf8').replace(/\0/g, ''),
|
|
60
|
-
httpOnly: (flags & 0x04) === 0x04,
|
|
61
|
-
secure: (flags & 0x01) === 0x01
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!page.slice(cookieCount * 4 + 8, cookieCount * 4 + 12).equals(Buffer.from([0x00, 0x00, 0x00, 0x00]))) {
|
|
67
|
-
throw new Error("Bad page trailer");
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return cookies;
|
|
72
|
-
};
|
package/src/execSimple.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export async function execSimple(command: string): Promise<string> {
|
|
2
|
-
try {
|
|
3
|
-
const { execSync } = await import("child_process");
|
|
4
|
-
const stdout = execSync(command, {
|
|
5
|
-
encoding: "binary",
|
|
6
|
-
maxBuffer: 5 * 1024,
|
|
7
|
-
});
|
|
8
|
-
return stdout.trim();
|
|
9
|
-
} catch (error) {
|
|
10
|
-
throw error;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { fetchWithCookies } from "./fetchWithCookies";
|
|
2
|
-
import { FetchFn } from "./fetchWithCookies";
|
|
3
|
-
|
|
4
|
-
describe("fetchWithCookies", () => {
|
|
5
|
-
let mockFetch: FetchFn;
|
|
6
|
-
let mockResponse: Response;
|
|
7
|
-
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
mockFetch = jest.fn();
|
|
10
|
-
mockResponse = new Response("mock body", { status: 200 });
|
|
11
|
-
(mockFetch as jest.Mock).mockResolvedValue(mockResponse);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
// it("should call fetch with the correct arguments", async () => {
|
|
15
|
-
// const url = "https://example.com/";
|
|
16
|
-
// const options: RequestInit = {
|
|
17
|
-
// method: "GET",
|
|
18
|
-
// headers: { "User-Agent": userAgent },
|
|
19
|
-
// redirect: "manual"
|
|
20
|
-
// //
|
|
21
|
-
// };
|
|
22
|
-
// await fetchWithCookies(url, options, mockFetch);
|
|
23
|
-
// expect(mockFetch).toBeCalledWith(url, options);
|
|
24
|
-
// });
|
|
25
|
-
|
|
26
|
-
it("should return the response from fetch", async () => {
|
|
27
|
-
const url = "https://example.com/";
|
|
28
|
-
const options = { method: "GET" };
|
|
29
|
-
const response = await fetchWithCookies(url, options, mockFetch);
|
|
30
|
-
expect(response).toBe(mockResponse);
|
|
31
|
-
});
|
|
32
|
-
});
|
package/src/fetchWithCookies.ts
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
// noinspection JSUnusedGlobalSymbols,ExceptionCaughtLocallyJS
|
|
2
|
-
|
|
3
|
-
import { fetch as fetchImpl } from "cross-fetch";
|
|
4
|
-
import { merge } from "lodash";
|
|
5
|
-
import destr from "destr";
|
|
6
|
-
import { getMergedRenderedCookies } from "./getMergedRenderedCookies";
|
|
7
|
-
import { cookieSpecsFromUrl } from "./cookieSpecsFromUrl";
|
|
8
|
-
import CookieSpec from "./CookieSpec";
|
|
9
|
-
|
|
10
|
-
if (typeof fetchImpl !== "function") {
|
|
11
|
-
throw new Error("fetch is not a function");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Class to build a User-Agent string.
|
|
16
|
-
*/
|
|
17
|
-
class UserAgentBuilder {
|
|
18
|
-
private platform: string;
|
|
19
|
-
private engine: string;
|
|
20
|
-
private browser: string;
|
|
21
|
-
private layout: string;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Constructs a UserAgentBuilder instance.
|
|
25
|
-
* @param platform - The platform information.
|
|
26
|
-
* @param engine - The engine information.
|
|
27
|
-
* @param browser - The browser information.
|
|
28
|
-
* @param layout - The layout information.
|
|
29
|
-
*/
|
|
30
|
-
constructor(
|
|
31
|
-
platform: string = "Macintosh; Intel Mac OS X 10_15_7",
|
|
32
|
-
engine: string = "AppleWebKit/537.36 (KHTML, like Gecko)",
|
|
33
|
-
browser: string = "Chrome/118.0.0.0",
|
|
34
|
-
layout: string = "Safari/537.36",
|
|
35
|
-
) {
|
|
36
|
-
this.platform = platform;
|
|
37
|
-
this.engine = engine;
|
|
38
|
-
this.browser = browser;
|
|
39
|
-
this.layout = layout;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Builds the User-Agent string.
|
|
44
|
-
* @returns The User-Agent string.
|
|
45
|
-
*/
|
|
46
|
-
build(): string {
|
|
47
|
-
return `${this.platform} ${this.engine} ${this.browser} ${this.layout}`;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const userAgent: string = new UserAgentBuilder().build();
|
|
52
|
-
|
|
53
|
-
interface FetchRequestInit {
|
|
54
|
-
url: RequestInfo | URL | string;
|
|
55
|
-
options?: RequestInit;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export type FetchFn =
|
|
59
|
-
| typeof fetchImpl
|
|
60
|
-
| ((url: URL, options?: RequestInit) => Promise<Response>);
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Class to handle fetch requests with cookies.
|
|
64
|
-
*/
|
|
65
|
-
class FetchWithCookies {
|
|
66
|
-
private fetch: FetchFn;
|
|
67
|
-
private userAgent: string;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Constructs a FetchWithCookies instance.
|
|
71
|
-
* @param fetch - The fetch function to use.
|
|
72
|
-
* @param userAgent - The User-Agent string to use.
|
|
73
|
-
*/
|
|
74
|
-
constructor(fetch: FetchFn, userAgent: string) {
|
|
75
|
-
if (typeof fetch !== "function") {
|
|
76
|
-
throw new Error("fetch is not a function");
|
|
77
|
-
}
|
|
78
|
-
this.fetch = fetch;
|
|
79
|
-
this.userAgent = userAgent;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Gets the headers for a given URL.
|
|
84
|
-
* @param url - The URL to get headers for.
|
|
85
|
-
* @returns A promise that resolves to the headers.
|
|
86
|
-
*/
|
|
87
|
-
private async getHeaders(url: URL): Promise<HeadersInit> {
|
|
88
|
-
const headers: HeadersInit = { "User-Agent": this.userAgent };
|
|
89
|
-
const cookieSpecs: CookieSpec[] = cookieSpecsFromUrl(url);
|
|
90
|
-
const renderedCookie: string = await getMergedRenderedCookies(
|
|
91
|
-
cookieSpecs,
|
|
92
|
-
).catch(() => "");
|
|
93
|
-
|
|
94
|
-
if (renderedCookie) {
|
|
95
|
-
headers["Cookie"] = renderedCookie;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return headers;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Handles redirects for a given response.
|
|
103
|
-
* @param res - The response to handle redirects for.
|
|
104
|
-
* @param url - The original URL.
|
|
105
|
-
* @param options - The request options.
|
|
106
|
-
* @param originalRequest - The original request information.
|
|
107
|
-
* @returns A promise that resolves to the final response.
|
|
108
|
-
*/
|
|
109
|
-
private async handleRedirects(
|
|
110
|
-
res: Response,
|
|
111
|
-
url: URL,
|
|
112
|
-
options: RequestInit,
|
|
113
|
-
originalRequest: FetchRequestInit,
|
|
114
|
-
): Promise<Response> {
|
|
115
|
-
const newUrl: string = res.headers.get("location") ?? res.url;
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
[301, 302].includes(res.status) &&
|
|
119
|
-
newUrl &&
|
|
120
|
-
newUrl !== url.toString()
|
|
121
|
-
) {
|
|
122
|
-
return this.fetchWithCookies(newUrl, options, originalRequest);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (res.status === 303 && newUrl && newUrl !== url.toString()) {
|
|
126
|
-
const newOptions: RequestInit = {
|
|
127
|
-
...options,
|
|
128
|
-
method: "GET",
|
|
129
|
-
body: undefined,
|
|
130
|
-
};
|
|
131
|
-
return this.fetchWithCookies(newUrl, newOptions, originalRequest);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return res;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Enhances the response with additional methods.
|
|
139
|
-
* @param res - The response to enhance.
|
|
140
|
-
* @returns A promise that resolves to the enhanced response.
|
|
141
|
-
*/
|
|
142
|
-
private async enhanceResponse(res: Response): Promise<Response> {
|
|
143
|
-
const originalArrayBuffer: ArrayBuffer = await res.arrayBuffer();
|
|
144
|
-
const originalBuffer: Buffer = Buffer.from(originalArrayBuffer);
|
|
145
|
-
const originalText: string = originalBuffer.toString("utf8");
|
|
146
|
-
|
|
147
|
-
const arrayBuffer = async (): Promise<ArrayBuffer> => originalArrayBuffer;
|
|
148
|
-
const buffer = async (): Promise<Buffer> => originalBuffer;
|
|
149
|
-
const text = async (): Promise<string> => originalText;
|
|
150
|
-
const json = async (): Promise<any> => destr(originalText);
|
|
151
|
-
const formData = async (): Promise<FormData> => {
|
|
152
|
-
const urlSearchParams: URLSearchParams = new URLSearchParams(
|
|
153
|
-
originalText,
|
|
154
|
-
);
|
|
155
|
-
const formData: FormData = new FormData();
|
|
156
|
-
for (const [key, value] of urlSearchParams.entries()) {
|
|
157
|
-
formData.append(key, value);
|
|
158
|
-
}
|
|
159
|
-
return formData;
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
return merge(res, { arrayBuffer, text, json, buffer, formData });
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Fetches a URL with cookies.
|
|
167
|
-
* @param url - The URL to fetch.
|
|
168
|
-
* @param options - The request options.
|
|
169
|
-
* @param originalRequest - The original request information.
|
|
170
|
-
* @returns A promise that resolves to the response.
|
|
171
|
-
*/
|
|
172
|
-
public async fetchWithCookies(
|
|
173
|
-
url: RequestInfo | URL | string,
|
|
174
|
-
options: RequestInit | undefined = {},
|
|
175
|
-
originalRequest?: FetchRequestInit,
|
|
176
|
-
): Promise<Response> {
|
|
177
|
-
const originalRequest1: FetchRequestInit = originalRequest || {
|
|
178
|
-
url,
|
|
179
|
-
options,
|
|
180
|
-
};
|
|
181
|
-
const url1: URL = new URL(`${url}`);
|
|
182
|
-
const headers: HeadersInit = await this.getHeaders(url1);
|
|
183
|
-
const defaultOptions: RequestInit = { headers, redirect: "manual" };
|
|
184
|
-
const newOptions: RequestInit = merge(defaultOptions, { headers }, options);
|
|
185
|
-
|
|
186
|
-
try {
|
|
187
|
-
const res: Response = await this.fetch(url1, newOptions);
|
|
188
|
-
const redirectedRes: Response = await this.handleRedirects(
|
|
189
|
-
res,
|
|
190
|
-
url1,
|
|
191
|
-
newOptions,
|
|
192
|
-
originalRequest1,
|
|
193
|
-
);
|
|
194
|
-
return this.enhanceResponse(redirectedRes);
|
|
195
|
-
} catch (e) {
|
|
196
|
-
throw e;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Fetches a URL with cookies.
|
|
203
|
-
* @param url - The URL to fetch.
|
|
204
|
-
* @param options - The request options.
|
|
205
|
-
* @param fetch - The fetch function to use.
|
|
206
|
-
* @param originalRequest - The original request information.
|
|
207
|
-
* @returns A promise that resolves to the response.
|
|
208
|
-
*/
|
|
209
|
-
export async function fetchWithCookies(
|
|
210
|
-
url: RequestInfo | URL | string,
|
|
211
|
-
options: RequestInit | undefined = {},
|
|
212
|
-
fetch: FetchFn = fetchImpl as FetchFn,
|
|
213
|
-
originalRequest?: FetchRequestInit,
|
|
214
|
-
): Promise<Response> {
|
|
215
|
-
const fetcher = new FetchWithCookies(fetch, userAgent);
|
|
216
|
-
return fetcher.fetchWithCookies(url, options, originalRequest);
|
|
217
|
-
}
|
package/src/findAllFiles.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "fs";
|
|
2
|
-
import { parsedArgs } from "./argv";
|
|
3
|
-
import consola from "consola";
|
|
4
|
-
import { sync } from "fast-glob";
|
|
5
|
-
|
|
6
|
-
type FindFilesOptions = {
|
|
7
|
-
path: string;
|
|
8
|
-
name: string;
|
|
9
|
-
maxDepth?: number;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Finds all files matching the specified name within a given path and depth.
|
|
14
|
-
*
|
|
15
|
-
* @param {FindFilesOptions} options - The options for finding files.
|
|
16
|
-
* @param {string} options.path - The path to search within.
|
|
17
|
-
* @param {string} options.name - The name of the files to search for.
|
|
18
|
-
* @param {number} [options.maxDepth=2] - The maximum depth to search within.
|
|
19
|
-
* @returns {string[]} An array of file paths that match the search criteria.
|
|
20
|
-
* @throws Will throw an error if the specified path does not exist.
|
|
21
|
-
*/
|
|
22
|
-
export function findAllFiles({
|
|
23
|
-
path,
|
|
24
|
-
name,
|
|
25
|
-
maxDepth = 2,
|
|
26
|
-
}: FindFilesOptions): string[] {
|
|
27
|
-
if (!existsSync(path)) {
|
|
28
|
-
throw new Error(`Path ${path} does not exist`);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (parsedArgs.verbose) {
|
|
32
|
-
consola.start(`Searching for ${name} files in ${path}`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const files: string[] = sync(`${path}/**/${name}`, {
|
|
36
|
-
onlyFiles: true,
|
|
37
|
-
deep: maxDepth,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (parsedArgs.verbose) {
|
|
41
|
-
if (files.length > 0) {
|
|
42
|
-
consola.success(`Found ${files.length} ${name} files`);
|
|
43
|
-
consola.info(files);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return files;
|
|
48
|
-
}
|
package/src/getChromeCookie.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import CookieSpec from "./CookieSpec";
|
|
2
|
-
import ExportedCookie from "./ExportedCookie";
|
|
3
|
-
import { queryCookies } from "./queryCookies";
|
|
4
|
-
import ChromeCookieQueryStrategy from "./browsers/chrome/ChromeCookieQueryStrategy";
|
|
5
|
-
import { isExportedCookie } from "./ExportedCookie";
|
|
6
|
-
|
|
7
|
-
export async function getChromeCookie(
|
|
8
|
-
params: CookieSpec,
|
|
9
|
-
): Promise<ExportedCookie | undefined> {
|
|
10
|
-
const cookies: ExportedCookie[] = await queryCookies(params, {
|
|
11
|
-
strategy: new ChromeCookieQueryStrategy(),
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
if (cookies.length === 0) {
|
|
15
|
-
throw new Error("Cookie not found");
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return cookies.find(isExportedCookie);
|
|
19
|
-
}
|