@mherod/get-cookie 2.0.0-rc.18 → 2.0.0-rc.19

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mherod/get-cookie",
3
- "version": "2.0.0-rc.18",
3
+ "version": "2.0.0-rc.19",
4
4
  "description": "Node.js module for querying a local user's Chrome cookie",
5
5
  "source": "src/index.ts",
6
6
  "bin": "dist/cli.js",
@@ -12,23 +12,22 @@
12
12
  },
13
13
  "scripts": {
14
14
  "clean": "git clean -fdX && rm -rf node_modules dist && yarn install",
15
- "build": "parcel build",
16
- "postbuild": "npm run check",
15
+ "build": "tsc && parcel build",
17
16
  "prepare": "npm run build && npm run prettier",
18
17
  "test": "jest",
19
18
  "prepublish": "npm run build",
20
- "install:global": "npm run build && npm install --force --global .",
21
- "prettier": "prettier --write 'src/{**/*,*}.{js,json,ts}'",
22
- "check": "tsc --noEmit"
19
+ "install:global": "npm run build && npm install --global .",
20
+ "prettier": "prettier --write ."
23
21
  },
24
22
  "targets": {
23
+ "types": {},
25
24
  "main": {},
26
25
  "library": {
27
26
  "source": "src/index.ts",
28
27
  "distDir": "dist",
29
28
  "isLibrary": true,
30
29
  "engines": {
31
- "node": "16"
30
+ "node": ">= 16"
32
31
  },
33
32
  "sourceMap": true,
34
33
  "includeNodeModules": false
@@ -38,9 +37,10 @@
38
37
  "distDir": "dist",
39
38
  "isLibrary": false,
40
39
  "engines": {
41
- "node": "16"
40
+ "node": ">= 16"
42
41
  },
43
42
  "sourceMap": false,
43
+ "optimize": false,
44
44
  "includeNodeModules": [
45
45
  "colorette"
46
46
  ]
@@ -51,7 +51,7 @@
51
51
  "inlineEnvironment": true
52
52
  },
53
53
  "engines": {
54
- "node": "16"
54
+ "node": ">= 16"
55
55
  },
56
56
  "keywords": [],
57
57
  "author": "Matthew Herod",
@@ -62,11 +62,11 @@
62
62
  "destr": "^1.2.0",
63
63
  "jsonwebtoken": "^8.5.1",
64
64
  "lodash": "^4.17.21",
65
+ "lodash-es": "^4.17.21",
65
66
  "lru-cache": "^7.14.0",
66
67
  "minimist": "^1.2.7",
67
68
  "sqlite3": "^5.1.2",
68
69
  "tough-cookie": "^4.1.2",
69
- "tough-cookie-file-store": "^2.0.3",
70
70
  "user-agents": "^1.0.1178"
71
71
  },
72
72
  "devDependencies": {
@@ -2,13 +2,26 @@ import { env } from "./global";
2
2
  import { parsedArgs } from "./argv";
3
3
  import { CookieJar, MemoryCookieStore, Store } from "tough-cookie";
4
4
 
5
- const { FileCookieStore } = require("tough-cookie-file-store");
5
+ import { FileCookieStore } from "./FileCookieStore";
6
6
 
7
- export let cookieStore: Store;
8
- if (parsedArgs["cs"] == "memory") {
9
- cookieStore = new MemoryCookieStore();
10
- } else {
11
- cookieStore = new FileCookieStore(`${env["HOME"]}/cookie-star.json`);
7
+ const memoryCookieStore = new MemoryCookieStore();
8
+
9
+ async function getCookieStore(): Promise<Store> {
10
+ if (parsedArgs["cs"] == "memory") {
11
+ return memoryCookieStore;
12
+ }
13
+ const fileCookieStore = new FileCookieStore(
14
+ `${env["HOME"]}/cookie-star.json`,
15
+ memoryCookieStore
16
+ );
17
+ await fileCookieStore.waitUntilIdle();
18
+ return fileCookieStore;
12
19
  }
13
20
 
14
- export const cookieJar = new CookieJar(cookieStore);
21
+ export const cookieStorePromise: Promise<Store> = new Promise((resolve) => {
22
+ getCookieStore().then(resolve);
23
+ });
24
+
25
+ export const cookieJarPromise: Promise<CookieJar> = new Promise((resolve) => {
26
+ cookieStorePromise.then((store) => new CookieJar(store)).then(resolve);
27
+ });
@@ -0,0 +1,170 @@
1
+ import { Cookie, MemoryCookieStore, Store } from "tough-cookie";
2
+ import { existsSync, readFileSync, writeFile } from "fs";
3
+ import destr from "destr";
4
+ import { merge } from "lodash";
5
+
6
+ export class FileCookieStore extends Store {
7
+ private readonly internalStore: Store;
8
+
9
+ synchronous: boolean = false;
10
+ filePath: string;
11
+
12
+ private tasks: Promise<any>[] = [];
13
+
14
+ constructor(
15
+ filePath: string,
16
+ internalStore: Store = new MemoryCookieStore()
17
+ ) {
18
+ super();
19
+
20
+ this.filePath = filePath;
21
+ this.internalStore = internalStore ?? new MemoryCookieStore();
22
+
23
+ console.log("Importing cookies from", filePath, internalStore);
24
+
25
+ this.tasks.push(
26
+ this.importSaved(filePath, internalStore).then(console.log, console.error)
27
+ );
28
+ }
29
+
30
+ private async importSaved(filePath: string, store: Store): Promise<Cookie[]> {
31
+ const cookies: Cookie[] = [];
32
+ if (existsSync(filePath)) {
33
+ const data = readFileSync(filePath, "utf8");
34
+ const cookies: any[] = Object.values(destr(data))
35
+ .flatMap((domainCookies: any) => Object.values(domainCookies))
36
+ .flatMap((domainCookies: any) => Object.values(domainCookies));
37
+ console.log("Importing", cookies.length, "cookies");
38
+ const array = Array.isArray(cookies) ? cookies : Object.values(cookies);
39
+ const put = await Promise.all(
40
+ array.map((cookie) => {
41
+ const fromJSON = Cookie.fromJSON(cookie);
42
+ if (fromJSON) {
43
+ return this.putCookieInternal(fromJSON, store);
44
+ }
45
+ })
46
+ );
47
+ cookies.push(...put);
48
+ }
49
+ return cookies;
50
+ }
51
+
52
+ findCookie(
53
+ domain: string,
54
+ path: string,
55
+ key: string,
56
+ cb: (err: Error | null, cookie: Cookie | null) => void
57
+ ) {
58
+ this.waitUntilIdle().finally(() => {
59
+ this.internalStore.findCookie(domain, path, key, cb);
60
+ });
61
+ }
62
+
63
+ findCookies(
64
+ domain: string,
65
+ path: string,
66
+ allowSpecialUseDomain: boolean,
67
+ cb: (err: Error | null, cookie: Cookie[]) => void
68
+ ) {
69
+ this.waitUntilIdle().finally(() => {
70
+ this.internalStore.findCookies(domain, path, allowSpecialUseDomain, cb);
71
+ });
72
+ }
73
+
74
+ putCookie(cookie: Cookie, cb: (err: Error | null) => void) {
75
+ this.internalStore.putCookie(cookie, cb);
76
+ this.internalStore.getAllCookies((err, cookies) => {
77
+ this.serializeCallback(err, cookies);
78
+ });
79
+ }
80
+
81
+ updateCookie(
82
+ oldCookie: Cookie,
83
+ newCookie: Cookie,
84
+ cb: (err: Error | null) => void
85
+ ) {
86
+ this.internalStore.updateCookie(oldCookie, newCookie, cb);
87
+ this.internalStore.getAllCookies((err, cookies) => {
88
+ this.serializeCallback(err, cookies);
89
+ });
90
+ }
91
+
92
+ removeCookie(
93
+ domain: string,
94
+ path: string,
95
+ key: string,
96
+ cb: (err: Error | null) => void
97
+ ) {
98
+ this.internalStore.removeCookie(domain, path, key, cb);
99
+ this.internalStore.getAllCookies((err, cookies) => {
100
+ this.serializeCallback(err, cookies);
101
+ });
102
+ }
103
+
104
+ removeCookies(domain: string, path: string, cb: (err: Error | null) => void) {
105
+ this.internalStore.removeCookies(domain, path, cb);
106
+ this.internalStore.getAllCookies((err, cookies) => {
107
+ this.serializeCallback(err, cookies);
108
+ });
109
+ }
110
+
111
+ getAllCookies(cb: (err: Error | null, cookie: Cookie[]) => void) {
112
+ this.waitUntilIdle().finally(() => {
113
+ this.internalStore.getAllCookies(cb);
114
+ });
115
+ }
116
+
117
+ waitUntilIdle() {
118
+ return Promise.allSettled(this.tasks).catch(console.error);
119
+ }
120
+
121
+ private async putCookieInternal(
122
+ cookie: Cookie,
123
+ store: Store
124
+ ): Promise<Cookie> {
125
+ await this.waitUntilIdle();
126
+ return await new Promise<Cookie>(
127
+ (
128
+ resolve: (value: PromiseLike<Cookie> | Cookie) => void,
129
+ reject: (reason?: any) => void
130
+ ) => {
131
+ store.putCookie(cookie, (err: Error | null) => {
132
+ if (err) {
133
+ reject(err);
134
+ } else {
135
+ resolve(cookie);
136
+ }
137
+ });
138
+ }
139
+ );
140
+ }
141
+
142
+ private serializeCallback(err: Error | null, cookies: Cookie[]) {
143
+ if (err) {
144
+ console.error(err);
145
+ return;
146
+ }
147
+ const cookieObjs = cookies.map((cookie: Cookie) => cookie);
148
+ const idx: any = {};
149
+ for (const cookie of cookieObjs) {
150
+ const domain = cookie.domain;
151
+ if (typeof domain === "string") {
152
+ const path: string = cookie.path ?? "/";
153
+ const key: string = cookie.key;
154
+ merge(idx, {
155
+ [domain]: {
156
+ [path]: {
157
+ [key]: cookie.toJSON(),
158
+ },
159
+ },
160
+ });
161
+ }
162
+ }
163
+ const stringify = JSON.stringify(idx, null, 2);
164
+ writeFile(this.filePath, stringify, (err) => {
165
+ if (err) {
166
+ console.error(err);
167
+ }
168
+ });
169
+ }
170
+ }
@@ -1,8 +1,8 @@
1
1
  import CookieQueryStrategy from "./CookieQueryStrategy";
2
2
  import CookieSpec from "../CookieSpec";
3
3
  import ExportedCookie from "../ExportedCookie";
4
- import { Cookie } from "tough-cookie";
5
- import { cookieJar, cookieStore } from "../CookieStore";
4
+ import { Cookie, Store } from "tough-cookie";
5
+ import { cookieJarPromise, cookieStorePromise } from "../CookieStore";
6
6
  import { stringToRegex } from "../StringToRegex";
7
7
 
8
8
  export default class CookieStoreQueryStrategy implements CookieQueryStrategy {
@@ -66,29 +66,34 @@ export default class CookieStoreQueryStrategy implements CookieQueryStrategy {
66
66
  };
67
67
  }
68
68
 
69
- #getCookies(url: string): Promise<Cookie[]> {
69
+ async #getCookies(url: string): Promise<Cookie[]> {
70
+ const cookieJar = await cookieJarPromise;
70
71
  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 ?? []);
72
+ return cookieJar.getCookies(
73
+ url,
74
+ (err: Error | null, cookies: Cookie[]) => {
75
+ if (err) {
76
+ reject(err);
77
+ } else {
78
+ resolve(cookies ?? []);
79
+ }
77
80
  }
78
- });
81
+ );
79
82
  });
80
83
  }
81
84
 
82
- #getAllCookies(): Promise<Cookie[]> {
85
+ async #getAllCookies(): Promise<Cookie[]> {
86
+ const cookieStore: Store = await cookieStorePromise;
83
87
  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 ?? []);
88
+ return cookieStore.getAllCookies(
89
+ (err: Error | null, cookies: Cookie[]) => {
90
+ if (err) {
91
+ reject(err);
92
+ } else {
93
+ resolve(cookies ?? []);
94
+ }
90
95
  }
91
- });
96
+ );
92
97
  });
93
98
  }
94
99
  }
@@ -4,10 +4,10 @@ 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 { cookieJar } from "./CookieStore";
7
+ import { cookieJarPromise } from "./CookieStore";
8
8
  import UserAgent from "user-agents";
9
9
  import { parsedArgs } from "./argv";
10
- import { blue, yellow } from "colorette";
10
+ import { blue, redBright, yellow } from "colorette";
11
11
  import { getMergedRenderedCookies } from "./getMergedRenderedCookies";
12
12
  import { cookieSpecsFromUrl } from "./cookieSpecsFromUrl";
13
13
  import CookieSpec from "./CookieSpec";
@@ -40,6 +40,7 @@ export async function fetchWithCookies(
40
40
  () => ""
41
41
  );
42
42
  if (parsedArgs["dump-request-headers"]) {
43
+ console.log(redBright("Request URL:"), url1.href);
43
44
  console.log(blue("Request headers:"), headers);
44
45
  }
45
46
  const newOptions1: RequestInit = merge(defaultOptions, { headers }, options);
@@ -51,7 +52,8 @@ export async function fetchWithCookies(
51
52
  });
52
53
  for (const [key, value] of headers) {
53
54
  if (key === "set-cookie") {
54
- await cookieJar.setCookie(value, url2);
55
+ const cookieJar1 = await cookieJarPromise;
56
+ await cookieJar1.setCookie(value, url2);
55
57
  if (parsedArgs.verbose) {
56
58
  console.log(blue(`Set-Cookie:`), yellow(value), yellow(url2));
57
59
  }
@@ -59,11 +61,11 @@ export async function fetchWithCookies(
59
61
  }
60
62
 
61
63
  const newUrl: string = res.headers.get("location") ?? res.url;
62
- const sameHost = new URL(newUrl).host === url1.host;
64
+ // const sameHost = new URL(newUrl).host === url1.host;
63
65
  if (res.status == 301 || res.status == 302) {
64
66
  // follow the redirect
65
67
  if (newUrl && newUrl !== url2) {
66
- if (parsedArgs.verbose) {
68
+ if (parsedArgs.verbose || parsedArgs["dump-response-headers"]) {
67
69
  console.log(blue(`Redirected to `), yellow(newUrl));
68
70
  }
69
71
  return fetchWithCookies(
package/tsconfig.json CHANGED
@@ -1,23 +1,17 @@
1
1
  {
2
- "include": [
3
- "src/**.ts",
4
- "src/**.tsx",
5
- "src/**.js",
6
- "src/**.jsx"
7
- ],
2
+ "include": ["src/**.ts", "src/**.tsx", "src/**.js", "src/**.jsx"],
8
3
  "compilerOptions": {
9
4
  "moduleResolution": "node",
10
5
  "target": "es2021",
11
- "types": [
12
- "node"
13
- ],
14
- "lib": [
15
- "es2015",
16
- "es2017",
17
- "es2021",
18
- "dom"
19
- ],
6
+ "types": ["node"],
7
+ "lib": ["es2015", "es2017", "es2021", "dom"],
20
8
  "strict": true,
21
9
  "allowSyntheticDefaultImports": true,
10
+ "emitDeclarationOnly": true,
11
+ "declaration": true,
12
+ "esModuleInterop": true,
13
+ "module": "commonjs",
14
+ "outDir": "dist",
15
+ "outFile": "dist/types.d.ts"
22
16
  }
23
17
  }