@mherod/get-cookie 2.0.0-rc.1 → 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.
Files changed (42) hide show
  1. package/dist/index.js +377 -145
  2. package/package-lock.json +12295 -0
  3. package/package.json +10 -7
  4. package/src/CookieRow.ts +2 -1
  5. package/src/CookieSpec.ts +2 -2
  6. package/src/CookieStore.ts +10 -0
  7. package/src/ExportedCookie.ts +2 -1
  8. package/src/FetchResponse.ts +2 -0
  9. package/src/IsCookieRow.ts +1 -1
  10. package/src/IsExportedCookie.ts +1 -1
  11. package/src/SpecialCases.ts +1 -1
  12. package/src/StringToRegex.ts +6 -0
  13. package/src/argv.ts +4 -0
  14. package/src/browsers/ChromeCookieQueryStrategy.ts +92 -22
  15. package/src/browsers/CompositeCookieQueryStrategy.ts +32 -8
  16. package/src/browsers/CookieQueryStrategy.ts +2 -1
  17. package/src/browsers/CookieStoreQueryStrategy.ts +94 -0
  18. package/src/browsers/FirefoxCookieQueryStrategy.ts +5 -3
  19. package/src/browsers/SafariCookieQueryStrategy.ts +3 -1
  20. package/src/cli.ts +84 -91
  21. package/src/doSqliteQuery1.ts +4 -8
  22. package/src/doSqliteQuery1Params.ts +7 -0
  23. package/src/fetchWithCookies.ts +78 -27
  24. package/src/findAllFiles.ts +5 -9
  25. package/src/getChromeCookie.ts +19 -0
  26. package/src/getCookie.ts +19 -0
  27. package/src/getFirefoxCookie.ts +19 -0
  28. package/src/getGroupedRenderedCookies.ts +19 -22
  29. package/src/getMergedRenderedCookies.ts +25 -0
  30. package/src/index.ts +13 -52
  31. package/src/isValidJwt.ts +2 -2
  32. package/src/queryCookies.ts +16 -12
  33. package/src/resultsRendered.ts +7 -4
  34. package/src/unpackHeaders.ts +7 -4
  35. package/src/utils.ts +0 -25
  36. package/dist/cli.js +0 -3
  37. package/dist/cli.js.map +0 -1
  38. package/dist/index.js.map +0 -1
  39. package/dist/module.js +0 -586
  40. package/dist/module.js.map +0 -1
  41. package/dist/types.d.ts +0 -35
  42. package/dist/types.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mherod/get-cookie",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0-rc.10",
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",
@@ -11,7 +11,7 @@
11
11
  "access": "public"
12
12
  },
13
13
  "scripts": {
14
- "clean": "git clean -fXd && yarn",
14
+ "clean": "git clean -fdX && rm -rf node_modules dist && yarn install",
15
15
  "build": "parcel build",
16
16
  "prepare": "npm run build && npm run prettier",
17
17
  "test": "jest",
@@ -27,14 +27,13 @@
27
27
  "main": {},
28
28
  "types": {},
29
29
  "library": {
30
- "source": [
31
- "src/index.ts"
32
- ],
30
+ "source": "src/index.ts",
33
31
  "distDir": "dist",
34
32
  "isLibrary": true,
35
33
  "engines": {
36
34
  "node": "16"
37
- }
35
+ },
36
+ "includeNodeModules": false
38
37
  },
39
38
  "cli": {
40
39
  "source": "src/cli.ts",
@@ -66,7 +65,10 @@
66
65
  "lodash": "^4.17.21",
67
66
  "lru-cache": "^7.14.0",
68
67
  "minimist": "^1.2.6",
69
- "sqlite3": "^5.1.1"
68
+ "sqlite3": "^5.1.1",
69
+ "tough-cookie": "^4.1.2",
70
+ "tough-cookie-file-store": "^2.0.3",
71
+ "user-agents": "^1.0.1165"
70
72
  },
71
73
  "devDependencies": {
72
74
  "@parcel/packager-ts": "^2.7.0",
@@ -75,6 +77,7 @@
75
77
  "@types/lodash": "^4.14.186",
76
78
  "@types/minimist": "^1.2.2",
77
79
  "@types/node": "^18.8.2",
80
+ "@types/tough-cookie": "^4.0.2",
78
81
  "@types/user-agents": "^1.0.2",
79
82
  "jest": "^29.0.3",
80
83
  "parcel": "^2.7.0",
package/src/CookieRow.ts CHANGED
@@ -1,4 +1,5 @@
1
- export interface CookieRow {
1
+ export default interface CookieRow {
2
+ expiry?: number;
2
3
  domain: string;
3
4
  name: string;
4
5
  value: Buffer;
package/src/CookieSpec.ts CHANGED
@@ -1,4 +1,4 @@
1
- export interface CookieSpec {
2
- name: string;
1
+ export default interface CookieSpec {
3
2
  domain: string;
3
+ name: string;
4
4
  }
@@ -0,0 +1,10 @@
1
+ import { CookieJar } from "tough-cookie";
2
+ import { env } from "./global";
3
+ const { FileCookieStore } = require("tough-cookie-file-store");
4
+
5
+ export const cookieStore = new FileCookieStore(
6
+ `${env["HOME"]}/cookie-star.json`
7
+ );
8
+ // export const cookieStore = new MemoryCookieStore();
9
+
10
+ export const cookieJar = new CookieJar(cookieStore);
@@ -1,6 +1,7 @@
1
- export interface ExportedCookie {
1
+ export default interface ExportedCookie {
2
2
  domain: string;
3
3
  name: string;
4
4
  value: string;
5
+ expiry?: Date | "Infinity";
5
6
  meta?: any;
6
7
  }
@@ -1,3 +1,5 @@
1
+ // noinspection JSUnusedGlobalSymbols
2
+
1
3
  import { Response } from "cross-fetch";
2
4
 
3
5
  export default interface FetchResponse extends Response {
@@ -1,4 +1,4 @@
1
- import { CookieRow } from "./CookieRow";
1
+ import CookieRow from "./CookieRow";
2
2
 
3
3
  export function isCookieRow(obj: any): obj is CookieRow {
4
4
  return (
@@ -1,4 +1,4 @@
1
- import { ExportedCookie } from "./ExportedCookie";
1
+ import ExportedCookie from "./ExportedCookie";
2
2
 
3
3
  export function isExportedCookie(obj: any): obj is ExportedCookie {
4
4
  return (
@@ -1,4 +1,4 @@
1
- import { CookieSpec } from "./CookieSpec";
1
+ import CookieSpec from "./CookieSpec";
2
2
 
3
3
  export function specialCases({ name, domain }: CookieSpec): {
4
4
  specifiedName: boolean;
@@ -0,0 +1,6 @@
1
+ export function stringToRegex(s: string): RegExp {
2
+ const s1 = s.replaceAll(/\./gi, ".");
3
+ const s2 = s1.replace(/%/g, ".*");
4
+ const s3 = s2.replace(/\*/g, ".*");
5
+ return new RegExp(s3);
6
+ }
package/src/argv.ts CHANGED
@@ -1 +1,5 @@
1
+ import minimist from "minimist";
2
+
1
3
  export const argv: string[] = process.argv ?? [];
4
+
5
+ export const parsedArgs: minimist.ParsedArgs = minimist(argv.slice(2));
@@ -9,10 +9,17 @@ import { doSqliteQuery1 } from "../doSqliteQuery1";
9
9
  import { merge } from "lodash";
10
10
  import { isCookieRow } from "../IsCookieRow";
11
11
  import { isExportedCookie } from "../IsExportedCookie";
12
- import { CookieRow } from "../CookieRow";
13
- import { ExportedCookie } from "../ExportedCookie";
12
+ import CookieRow from "../CookieRow";
13
+ import ExportedCookie from "../ExportedCookie";
14
+ import { stringToRegex } from "../StringToRegex";
15
+ import { parsedArgs } from "../argv";
16
+ import fs from "fs";
17
+ import * as sqlite3 from "sqlite3";
18
+ import { DoSqliteQuery1Params } from "../doSqliteQuery1Params";
14
19
 
15
20
  export default class ChromeCookieQueryStrategy implements CookieQueryStrategy {
21
+ browserName = "Chrome";
22
+
16
23
  async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
17
24
  if (process.platform !== "darwin") {
18
25
  throw new Error("This only works on macOS");
@@ -40,7 +47,7 @@ async function getPromise1(
40
47
  file: file,
41
48
  });
42
49
  } catch (e) {
43
- if (env.VERBOSE) {
50
+ if (parsedArgs.verbose) {
44
51
  console.log("Error getting encrypted cookie", e);
45
52
  }
46
53
  return [];
@@ -56,10 +63,10 @@ async function getPromise(name: string, domain: string): Promise<CookieRow[]> {
56
63
  const promises: Promise<CookieRow[]>[] = files.map((file) =>
57
64
  getPromise1(name, domain, file)
58
65
  );
59
- const results1: Awaited<CookieRow[]>[] = await Promise.all(promises);
66
+ const results1: CookieRow[][] = await Promise.all(promises);
60
67
  return results1.flat().filter(isCookieRow);
61
68
  } catch (error) {
62
- if (env.VERBOSE) {
69
+ if (parsedArgs.verbose) {
63
70
  console.log("error", error);
64
71
  }
65
72
  return [];
@@ -71,7 +78,7 @@ async function decryptValue(password: string, encryptedValue: Buffer) {
71
78
  try {
72
79
  d = await decrypt(password, encryptedValue);
73
80
  } catch (e) {
74
- if (env.VERBOSE) {
81
+ if (parsedArgs.verbose) {
75
82
  console.log("Error decrypting cookie", e);
76
83
  }
77
84
  d = null;
@@ -99,17 +106,24 @@ Promise<ExportedCookie[]> {
99
106
  const decryptedValue = await decryptValue(password, encryptedValue);
100
107
  const meta = {};
101
108
  merge(meta, cookieRow.meta ?? {});
102
- return {
109
+ const exportedCookie: ExportedCookie = {
103
110
  domain: cookieRow.domain,
104
111
  name: cookieRow.name,
105
112
  value: decryptedValue,
106
113
  meta: meta,
107
114
  };
115
+ const expiry = cookieRow.expiry;
116
+ if (expiry) {
117
+ merge(exportedCookie, {
118
+ expiry: new Date(expiry),
119
+ });
120
+ }
121
+ return exportedCookie;
108
122
  });
109
123
  const results: ExportedCookie[] = (await Promise.all(decrypted)).filter(
110
124
  isExportedCookie
111
125
  );
112
- if (env.VERBOSE) {
126
+ if (parsedArgs.verbose) {
113
127
  console.log("results", results);
114
128
  }
115
129
  return results;
@@ -136,39 +150,54 @@ async function getEncryptedChromeCookie({
136
150
  if (!existsSync(file)) {
137
151
  throw new Error(`File ${file} does not exist`);
138
152
  }
139
- if (env.VERBOSE) {
153
+ if (parsedArgs.verbose) {
140
154
  const s = file.split("/").slice(-3).join("/");
141
155
  console.log(`Trying Chrome (at ${s}) cookie ${name} for domain ${domain}`);
142
156
  }
143
157
  let sql;
144
158
  //language=SQL
145
- sql = "SELECT encrypted_value, name, host_key FROM cookies";
159
+ sql = "SELECT * FROM cookies";
160
+ // sql = "SELECT encrypted_value, name, host_key FROM cookies";
161
+
146
162
  const wildcardRegexp = /^([*%])$/i;
147
163
  const specifiedName = name.match(wildcardRegexp) == null;
148
164
  const specifiedDomain = domain.match(wildcardRegexp) == null;
149
- if (specifiedName || specifiedDomain) {
165
+ const wildcardDomain = domain.match(/[%*]/) != null;
166
+ const queryDomain = specifiedDomain && !wildcardDomain;
167
+ // if we have a wildcard domain, we need to use a regexp
168
+ if (specifiedName || queryDomain) {
150
169
  sql += ` WHERE `;
151
170
  if (specifiedName) {
152
171
  sql += `name = '${name}'`;
153
- if (specifiedDomain) {
172
+ if (queryDomain) {
154
173
  sql += ` AND `;
155
174
  }
156
175
  }
157
- if (specifiedDomain) {
158
- sql += `host_key LIKE '${domain}';`;
176
+ if (queryDomain) {
177
+ // leading dot replaced with % to match subdomains
178
+ const sqlEmbedDomain = domain.replace(/^[.%]?/, "%");
179
+ sql += `host_key LIKE '${sqlEmbedDomain}';`;
159
180
  }
160
181
  }
161
- return doSqliteQuery1({
182
+ const sqliteQuery1: CookieRow[] = await doChromeSqliteQuery1({
162
183
  file: file,
163
184
  sql: sql,
164
185
  rowTransform: (row) => {
165
- return {
186
+ const cookieRow = {
187
+ expiry: (row["expires_utc"] / 1000000 - 11644473600) * 1000,
166
188
  domain: row["host_key"],
167
189
  name: row["name"],
168
190
  value: row["encrypted_value"],
169
191
  };
192
+ if (parsedArgs.verbose) {
193
+ console.log("CookieRow", cookieRow);
194
+ }
195
+ return cookieRow;
170
196
  },
171
197
  });
198
+ return sqliteQuery1.filter((row) => {
199
+ return row.domain.match(stringToRegex(domain)) != null;
200
+ });
172
201
  }
173
202
 
174
203
  async function getChromePassword(): Promise<string> {
@@ -192,7 +221,7 @@ async function decrypt(
192
221
  if (!(encryptedData1 instanceof Buffer)) {
193
222
  if (Array.isArray(encryptedData1) && encryptedData1[0] instanceof Buffer) {
194
223
  [encryptedData1] = encryptedData1;
195
- if (env.VERBOSE) {
224
+ if (parsedArgs.verbose) {
196
225
  console.log(
197
226
  `encryptedData is an array of buffers, selected first: ${encryptedData1}`
198
227
  );
@@ -202,14 +231,14 @@ async function decrypt(
202
231
  }
203
232
  encryptedData1 = Buffer.from(encryptedData1);
204
233
  }
205
- if (env.VERBOSE) {
234
+ if (parsedArgs.verbose) {
206
235
  console.log(`Trying to decrypt with password ${password}`);
207
236
  }
208
237
  return new Promise((resolve, reject) => {
209
238
  crypto.pbkdf2(password, "saltysalt", 1003, 16, "sha1", (error, buffer) => {
210
239
  try {
211
240
  if (error) {
212
- if (env.VERBOSE) {
241
+ if (parsedArgs.verbose) {
213
242
  console.log("Error doing pbkdf2", error);
214
243
  }
215
244
  reject(error);
@@ -217,7 +246,7 @@ async function decrypt(
217
246
  }
218
247
 
219
248
  if (buffer.length !== 16) {
220
- if (env.VERBOSE) {
249
+ if (parsedArgs.verbose) {
221
250
  console.log(
222
251
  "Error doing pbkdf2, buffer length is not 16",
223
252
  buffer.length
@@ -237,7 +266,7 @@ async function decrypt(
237
266
  }
238
267
 
239
268
  if (encryptedData1.length % 16 !== 0) {
240
- if (env.VERBOSE) {
269
+ if (parsedArgs.verbose) {
241
270
  console.log(
242
271
  "Error doing pbkdf2, encryptedData length is not a multiple of 16",
243
272
  encryptedData1.length
@@ -251,7 +280,7 @@ async function decrypt(
251
280
  try {
252
281
  decipher.final("utf-8");
253
282
  } catch (e) {
254
- if (env.VERBOSE) {
283
+ if (parsedArgs.verbose) {
255
284
  console.log("Error doing decipher.final()", e);
256
285
  }
257
286
  reject(e);
@@ -271,3 +300,44 @@ async function decrypt(
271
300
  });
272
301
  });
273
302
  }
303
+
304
+ export async function doChromeSqliteQuery1({
305
+ file,
306
+ sql,
307
+ rowTransform,
308
+ }: DoSqliteQuery1Params): Promise<CookieRow[]> {
309
+ if (!file || (file && !fs.existsSync(file))) {
310
+ throw new Error(`doSqliteQuery1: file ${file} does not exist`);
311
+ }
312
+ const db = new sqlite3.Database(file);
313
+ return new Promise((resolve, reject) => {
314
+ db.all(sql, (err: Error, rows: any[]) => {
315
+ if (err) {
316
+ reject(err);
317
+ return;
318
+ }
319
+ const rows1: any[] = rows;
320
+ if (rows1 == null || rows1.length === 0) {
321
+ resolve([]);
322
+ return;
323
+ }
324
+ if (Array.isArray(rows1)) {
325
+ const cookieRows: CookieRow[] = rows1.map((row: any) => {
326
+ const newVar = {
327
+ meta: {
328
+ file: file,
329
+ },
330
+ };
331
+ const cookieRow: CookieRow = rowTransform(row);
332
+ return merge(newVar, cookieRow);
333
+ });
334
+ resolve(cookieRows);
335
+ return;
336
+ }
337
+ if (parsedArgs.verbose) {
338
+ console.log(`doSqliteQuery1: rows ${JSON.stringify(rows1)}`);
339
+ }
340
+ resolve([rows1]);
341
+ });
342
+ });
343
+ }
@@ -2,8 +2,12 @@ import ChromeCookieQueryStrategy from "./ChromeCookieQueryStrategy";
2
2
  import FirefoxCookieQueryStrategy from "./FirefoxCookieQueryStrategy";
3
3
  import SafariCookieQueryStrategy from "./SafariCookieQueryStrategy";
4
4
  import CookieQueryStrategy from "./CookieQueryStrategy";
5
- import { ExportedCookie } from "../ExportedCookie";
5
+ import ExportedCookie from "../ExportedCookie";
6
6
  import LRUCache from "lru-cache";
7
+ import CookieStoreQueryStrategy from "./CookieStoreQueryStrategy";
8
+ import { red } from "colorette";
9
+ import { merge } from "lodash";
10
+ import { parsedArgs } from "../argv";
7
11
 
8
12
  const cache = new LRUCache<string, ExportedCookie[]>({
9
13
  ttl: 1000 * 2,
@@ -13,10 +17,13 @@ const cache = new LRUCache<string, ExportedCookie[]>({
13
17
  export default class CompositeCookieQueryStrategy
14
18
  implements CookieQueryStrategy
15
19
  {
20
+ browserName = "all";
21
+
16
22
  #strategies;
17
23
 
18
24
  constructor() {
19
25
  this.#strategies = [
26
+ CookieStoreQueryStrategy,
20
27
  ChromeCookieQueryStrategy,
21
28
  FirefoxCookieQueryStrategy,
22
29
  SafariCookieQueryStrategy,
@@ -26,19 +33,36 @@ export default class CompositeCookieQueryStrategy
26
33
  }
27
34
 
28
35
  async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
36
+ // domain = domain.match(/(\w+.+\w+)/gi)?.pop() ?? domain;
29
37
  const key = `${name}:${domain}`;
30
38
  const cached = cache.get(key);
31
39
  if (cached) {
32
40
  return cached;
33
41
  }
34
- const results = await Promise.all(
35
- this.#strategies.map(async (strategy) => {
42
+ if (parsedArgs.verbose) {
43
+ console.log("Querying cookies:", name, domain);
44
+ }
45
+ const results: ExportedCookie[][] = await Promise.all(
46
+ this.#strategies.map(async (strategy: CookieQueryStrategy) => {
36
47
  // @ts-ignore
37
- const cookies: Promise<ExportedCookie[]> = strategy.queryCookies(
38
- name,
39
- domain
40
- );
41
- return cookies.catch(() => []);
48
+ return strategy
49
+ .queryCookies(name, domain)
50
+ .then((cookies: ExportedCookie[]) => {
51
+ return cookies.map((cookie: ExportedCookie) => {
52
+ return merge(cookie, {
53
+ meta: {
54
+ browser: strategy.browserName,
55
+ },
56
+ });
57
+ });
58
+ })
59
+ .catch((e) => {
60
+ console.log(
61
+ red(`Error querying ${strategy.browserName} cookies`),
62
+ e
63
+ );
64
+ return [];
65
+ });
42
66
  })
43
67
  );
44
68
  const flat: ExportedCookie[] = results.flat();
@@ -1,5 +1,6 @@
1
- import { ExportedCookie } from "../ExportedCookie";
1
+ import ExportedCookie from "../ExportedCookie";
2
2
 
3
3
  export default interface CookieQueryStrategy {
4
+ browserName: string;
4
5
  queryCookies(name: string, domain: string): Promise<ExportedCookie[]>;
5
6
  }
@@ -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
+ }
@@ -4,12 +4,14 @@ import { env, HOME } from "../global";
4
4
  import { existsSync } from "fs";
5
5
  import { findAllFiles } from "../findAllFiles";
6
6
  import { doSqliteQuery1 } from "../doSqliteQuery1";
7
- import { ExportedCookie } from "../ExportedCookie";
8
- import { CookieRow } from "../CookieRow";
9
- import { CookieSpec } from "../CookieSpec";
7
+ import ExportedCookie from "../ExportedCookie";
8
+ import CookieRow from "../CookieRow";
9
+ import CookieSpec from "../CookieSpec";
10
10
  import { specialCases } from "../SpecialCases";
11
11
 
12
12
  export default class FirefoxCookieQueryStrategy implements CookieQueryStrategy {
13
+ browserName = "Firefox";
14
+
13
15
  async queryCookies(name: string, domain: string): Promise<ExportedCookie[]> {
14
16
  if (process.platform !== "darwin") {
15
17
  throw new Error("This only works on macOS");
@@ -1,7 +1,9 @@
1
1
  import CookieQueryStrategy from "./CookieQueryStrategy";
2
- import { ExportedCookie } from "../ExportedCookie";
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
  }