@mherod/get-cookie 4.1.0 → 4.2.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.
Files changed (51) hide show
  1. package/.env.example +5 -0
  2. package/.husky/commit-msg +6 -2
  3. package/.husky/pre-commit +6 -4
  4. package/.husky/pre-push +6 -4
  5. package/README.md +76 -117
  6. package/dist/cli.cjs +1 -3
  7. package/dist/cli.cjs.map +1 -1
  8. package/dist/index.cjs +1 -3
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +220 -41
  11. package/dist/index.d.ts +220 -41
  12. package/dist/index.js +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/tsconfig.tsbuildinfo +1 -0
  15. package/eslint.config.js +8 -18
  16. package/examples/README.md +37 -0
  17. package/examples/advanced-usage.ts +56 -0
  18. package/examples/basic-usage.ts +43 -0
  19. package/examples/cli-examples.sh +51 -0
  20. package/package.json +13 -4
  21. package/tsconfig.build.json +2 -2
  22. package/tsconfig.cli.json +12 -0
  23. package/tsconfig.tsup.json +12 -0
  24. package/tsup.cli.ts +1 -0
  25. package/tsup.lib.ts +1 -0
  26. package/dist/chunk-3FVH4L25.js +0 -2
  27. package/dist/chunk-3FVH4L25.js.map +0 -1
  28. package/dist/chunk-56Z35D5R.js +0 -2
  29. package/dist/chunk-56Z35D5R.js.map +0 -1
  30. package/dist/chunk-7XZ7PCDJ.js +0 -2
  31. package/dist/chunk-7XZ7PCDJ.js.map +0 -1
  32. package/dist/chunk-DVWQBWUF.js +0 -4
  33. package/dist/chunk-DVWQBWUF.js.map +0 -1
  34. package/dist/chunk-I6AYGFSQ.js +0 -2
  35. package/dist/chunk-I6AYGFSQ.js.map +0 -1
  36. package/dist/chunk-U27I5BLR.js +0 -2
  37. package/dist/chunk-U27I5BLR.js.map +0 -1
  38. package/dist/chunk-YOZOS2YM.js +0 -2
  39. package/dist/chunk-YOZOS2YM.js.map +0 -1
  40. package/dist/getChromeCookie-2ROVM47V.js +0 -2
  41. package/dist/getChromeCookie-2ROVM47V.js.map +0 -1
  42. package/dist/getChromePassword-O452VQWI.js +0 -2
  43. package/dist/getChromePassword-O452VQWI.js.map +0 -1
  44. package/dist/getCookie-CRE6M3GI.js +0 -2
  45. package/dist/getCookie-CRE6M3GI.js.map +0 -1
  46. package/dist/getFirefoxCookie-5P74VDC7.js +0 -2
  47. package/dist/getFirefoxCookie-5P74VDC7.js.map +0 -1
  48. package/dist/getGroupedRenderedCookies-DFEJTTC6.js +0 -2
  49. package/dist/getGroupedRenderedCookies-DFEJTTC6.js.map +0 -1
  50. package/dist/getMergedRenderedCookies-W5GSSHQQ.js +0 -2
  51. package/dist/getMergedRenderedCookies-W5GSSHQQ.js.map +0 -1
package/eslint.config.js CHANGED
@@ -6,7 +6,12 @@ import globals from "globals";
6
6
 
7
7
  export default [
8
8
  {
9
- ignores: ["dist/**/*", "node_modules/**/*", "coverage/**/*"],
9
+ ignores: [
10
+ "dist/**/*",
11
+ "node_modules/**/*",
12
+ "coverage/**/*",
13
+ "docs/.vitepress/cache/**/*",
14
+ ],
10
15
  },
11
16
  {
12
17
  files: ["**/*.js", "**/*.mjs"],
@@ -162,23 +167,7 @@ export default [
162
167
  "jsdoc/require-yields": "error",
163
168
  "jsdoc/sort-tags": "error",
164
169
  "jsdoc/check-examples": "off",
165
- "jsdoc/require-example": [
166
- "error",
167
- {
168
- contexts: [
169
- "ExportDefaultDeclaration",
170
- "ExportNamedDeclaration:not(TSTypeAliasDeclaration)",
171
- "ExportNamedDeclaration:not(TSInterfaceDeclaration)",
172
- "FunctionDeclaration",
173
- "MethodDefinition",
174
- ],
175
- exemptedBy: ["internal", "private", "test"],
176
- exemptNoArguments: true,
177
- checkConstructors: true,
178
- checkGetters: true,
179
- checkSetters: true,
180
- },
181
- ],
170
+ "jsdoc/require-example": "off",
182
171
  "jsdoc/check-tag-names": [
183
172
  "error",
184
173
  {
@@ -211,6 +200,7 @@ export default [
211
200
  {
212
201
  checkRestProperty: true,
213
202
  enableFixer: true,
203
+ allowExtraTrailingParamDocs: true,
214
204
  },
215
205
  ],
216
206
  "jsdoc/require-param-description": "error",
@@ -0,0 +1,37 @@
1
+ # get-cookie Examples
2
+
3
+ This directory contains example scripts demonstrating various ways to use get-cookie.
4
+
5
+ ## CLI Examples
6
+
7
+ - `cli-examples.sh`: Shows how to use the command-line interface for common tasks
8
+
9
+ ## TypeScript/Node.js Examples
10
+
11
+ - `basic-usage.ts`: Demonstrates basic Node.js module usage
12
+ - `advanced-usage.ts`: Shows advanced usage with browser-specific strategies
13
+
14
+ ## Running the Examples
15
+
16
+ ### CLI Examples
17
+
18
+ ```bash
19
+ # Make the script executable
20
+ chmod +x cli-examples.sh
21
+
22
+ # Run the examples
23
+ ./cli-examples.sh
24
+ ```
25
+
26
+ ### TypeScript Examples
27
+
28
+ ```bash
29
+ # Install dependencies if you haven't already
30
+ pnpm install
31
+
32
+ # Run TypeScript examples
33
+ ts-node basic-usage.ts
34
+ ts-node advanced-usage.ts
35
+ ```
36
+
37
+ Note: Make sure you have get-cookie installed either globally or as a project dependency before running the examples.
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @module
3
+ * @internal
4
+ */
5
+
6
+ /**
7
+ * @description
8
+ * This example demonstrates advanced usage of the cookie retrieval functions.
9
+ * It shows how to retrieve cookies using different patterns and filters.
10
+ * @internal
11
+ * @example
12
+ * ```typescript
13
+ * import { getCookie } from "@mherod/get-cookie";
14
+ *
15
+ * // Get all cookies for a domain
16
+ * const cookies = await getCookie({
17
+ * name: "*",
18
+ * domain: "github.com"
19
+ * });
20
+ *
21
+ * // Get specific cookies
22
+ * const authCookie = await getCookie({
23
+ * name: "auth",
24
+ * domain: "api.github.com"
25
+ * });
26
+ * ```
27
+ */
28
+
29
+ import { getCookie } from "../src";
30
+
31
+ /**
32
+ * @description
33
+ * Run advanced examples of cookie retrieval.
34
+ * @internal
35
+ * @returns A promise that resolves when all examples have completed.
36
+ */
37
+ export async function runAdvancedExamples(): Promise<void> {
38
+ // Example 1: Get a specific cookie by name and domain
39
+ const cookie = await getCookie({
40
+ name: "session",
41
+ domain: "github.com",
42
+ });
43
+
44
+ console.log("Example 1 - Specific cookie:", cookie);
45
+
46
+ // Example 2: Get all cookies for a domain using wildcard
47
+ const cookies = await getCookie({
48
+ name: "*",
49
+ domain: "github.com",
50
+ });
51
+
52
+ console.log("Example 2 - All domain cookies:", cookies);
53
+ }
54
+
55
+ // Execute the examples
56
+ runAdvancedExamples().catch(console.error);
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @module
3
+ * @internal
4
+ */
5
+
6
+ /**
7
+ * @description
8
+ * This example demonstrates basic usage of the getCookie function.
9
+ * It shows how to retrieve cookies from all supported browsers using a unified interface.
10
+ * @internal
11
+ * @example
12
+ * ```typescript
13
+ * import { getCookie } from "@mherod/get-cookie";
14
+ *
15
+ * // Get a cookie by name and domain
16
+ * const cookie = await getCookie({
17
+ * name: "session",
18
+ * domain: "github.com"
19
+ * });
20
+ *
21
+ * console.log(cookie);
22
+ * ```
23
+ */
24
+
25
+ import { getCookie } from "@mherod/get-cookie";
26
+
27
+ /**
28
+ * @description
29
+ * Basic example showing how to retrieve cookies from browsers.
30
+ * @internal
31
+ */
32
+ async function main(): Promise<void> {
33
+ // Get all session cookies from github.com
34
+ const cookies = await getCookie({
35
+ name: "user_session",
36
+ domain: "github.com",
37
+ });
38
+
39
+ console.log("Found cookies:", cookies);
40
+ }
41
+
42
+ // Run the example
43
+ void main();
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+
3
+ # Set up the get-cookie function to use the source directly
4
+ get-cookie() {
5
+ pnpm tsx src/cli/cli.ts "$@"
6
+ }
7
+
8
+ # Note: Ensure all browser instances are closed before running these examples
9
+ # On macOS, grant "Full Disk Access" to your terminal
10
+
11
+ echo "GitHub Cookie Examples:"
12
+ echo "----------------------"
13
+
14
+ # Get GitHub authentication cookies (useful for API requests)
15
+ echo "\nGetting GitHub authentication cookies:"
16
+ echo "These cookies are needed for authenticated API requests"
17
+ get-cookie user_session github.com --render
18
+ get-cookie __Host-user_session_same_site github.com --render
19
+
20
+ # Get GitHub user preferences
21
+ echo "\nGetting GitHub user preferences:"
22
+ echo "These cookies store user-specific settings"
23
+ get-cookie color_mode github.com --render
24
+ echo "Color mode preferences (light/dark theme settings)"
25
+ get-cookie tz github.com --render
26
+ echo "Timezone setting"
27
+
28
+ # Get GitHub session state
29
+ echo "\nGetting GitHub session state:"
30
+ echo "These cookies indicate login status and user identity"
31
+ get-cookie logged_in github.com --render
32
+ echo "Login status"
33
+ get-cookie dotcom_user github.com --render
34
+ echo "GitHub username"
35
+
36
+ # Get all GitHub cookies in grouped format
37
+ echo "\nGetting all GitHub cookies (grouped by browser):"
38
+ echo "Useful for debugging authentication issues"
39
+ get-cookie % github.com --dump-grouped
40
+
41
+ # Different output formats for automation
42
+ echo "\nOutput format examples:"
43
+ echo "----------------------"
44
+
45
+ # JSON output (useful for scripting)
46
+ echo "\nJSON format (good for scripting):"
47
+ get-cookie user_session github.com --output json
48
+
49
+ # Rendered output (human-readable)
50
+ echo "\nRendered format (good for debugging):"
51
+ get-cookie user_session github.com --render
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mherod/get-cookie",
3
- "version": "4.1.0",
3
+ "version": "4.2.2",
4
4
  "description": "Node.js module for querying a local user's Chrome cookie",
5
5
  "packageManager": "pnpm@9.15.2",
6
6
  "type": "module",
@@ -31,19 +31,21 @@
31
31
  "build:cli": "tsup --config tsup.cli.ts",
32
32
  "build": "pnpm run build:lib && pnpm run build:cli",
33
33
  "test": "jest",
34
- "type-check": "tsc --noEmit",
34
+ "type-check": "tsc --noEmit --skipLibCheck",
35
35
  "lint": "eslint . --format=codeframe",
36
36
  "lint:fix": "eslint . --format=codeframe --fix",
37
- "validate": "pnpm run type-check && pnpm run lint && pnpm run test",
37
+ "validate": "pnpm run type-check && pnpm run lint && pnpm run test && pnpm run check-links && pnpm run format:check",
38
38
  "prepack": "pnpm run validate",
39
39
  "prepublishOnly": "pnpm run clean && pnpm run validate && pnpm run build",
40
40
  "format": "prettier --write .",
41
+ "format:check": "prettier --check \"**/*.{js,ts,json,md,yml,yaml}\" \"docs/**/*.{md,vue}\"",
41
42
  "dev": "tsc -w -p tsconfig.json & tsc-alias -w -p tsconfig.json",
42
43
  "read-github": "NODE_OPTIONS=\"-r tsconfig-paths/register\" tsx scripts/read-github-cookies.ts",
43
44
  "prepare": "husky install",
44
45
  "docs": "typedoc && ./scripts/fix-typedoc.sh && vitepress build docs",
45
46
  "docs:dev": "vitepress dev docs",
46
- "docs:preview": "vitepress preview docs"
47
+ "docs:preview": "vitepress preview docs",
48
+ "check-links": "./scripts/check-vitepress-links.sh"
47
49
  },
48
50
  "engines": {
49
51
  "node": "^20.0.0 || ^22.0.0"
@@ -54,7 +56,9 @@
54
56
  "dependencies": {
55
57
  "better-sqlite3": "^11.7.0",
56
58
  "consola": "^3.3.3",
59
+ "date-fns": "4.1.0",
57
60
  "destr": "^2.0.3",
61
+ "dotenv": "16.4.7",
58
62
  "fast-glob": "^3.3.2",
59
63
  "jsonwebtoken": "^9.0.2",
60
64
  "lodash-es": "^4.17.21",
@@ -85,6 +89,7 @@
85
89
  "jest": "^29.7.0",
86
90
  "lint-staged": "^15.3.0",
87
91
  "lodash": "4.17.21",
92
+ "pnpm": "9.15.2",
88
93
  "prettier": "^3.4.2",
89
94
  "ts-jest": "^29.2.5",
90
95
  "ts-node": "^10.9.2",
@@ -103,6 +108,10 @@
103
108
  ],
104
109
  "*.{json,md,yml,yaml}": [
105
110
  "prettier --write"
111
+ ],
112
+ "docs/**/*.{md,vue}": [
113
+ "prettier --write",
114
+ "./scripts/check-vitepress-links.sh"
106
115
  ]
107
116
  }
108
117
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
- "include": ["jest.config.ts", "tsup.*.ts"],
4
- "exclude": ["node_modules", "dist"],
3
+ "include": ["src/**/*", "jest.config.ts", "tsup.*.ts"],
4
+ "exclude": ["node_modules", "dist", "**/__tests__/**", "**/__mocks__/**"],
5
5
  "compilerOptions": {
6
6
  "module": "ESNext",
7
7
  "moduleResolution": "bundler"
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["src/**/*"],
4
+ "exclude": ["node_modules", "dist", "**/__tests__/**", "**/__mocks__/**"],
5
+ "compilerOptions": {
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "composite": false,
9
+ "declaration": true,
10
+ "declarationMap": true
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["src/**/*"],
4
+ "exclude": ["node_modules", "dist", "**/__tests__/**", "**/__mocks__/**"],
5
+ "compilerOptions": {
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "composite": false,
9
+ "declaration": true,
10
+ "declarationMap": true
11
+ }
12
+ }
package/tsup.cli.ts CHANGED
@@ -18,6 +18,7 @@ export default defineConfig({
18
18
  minify: true,
19
19
  platform: "node",
20
20
  bundle: true,
21
+ tsconfig: "./tsconfig.cli.json",
21
22
  noExternal: ["lodash-es"],
22
23
  esbuildOptions(options) {
23
24
  options.alias = {
package/tsup.lib.ts CHANGED
@@ -18,6 +18,7 @@ export default defineConfig({
18
18
  minify: true,
19
19
  platform: "node",
20
20
  bundle: true,
21
+ tsconfig: "./tsconfig.tsup.json",
21
22
  external: ["fs", "path", "crypto", "os", "child_process"],
22
23
  esbuildOptions(options) {
23
24
  options.alias = {
@@ -1,2 +0,0 @@
1
- import{a as l,b as c}from"./chunk-DVWQBWUF.js";import{d as m,f as s}from"./chunk-56Z35D5R.js";import{join as p}from"path";function x(){let o=[],e=process.env.HOME;if(typeof e!="string"||e.length===0)return s("FirefoxCookieQuery","HOME environment variable not set"),o;let a=[p(e,"Library/Application Support/Firefox/Profiles/*/cookies.sqlite"),p(e,".mozilla/firefox/*/cookies.sqlite")];for(let f of a){let i=c(f);o.push(...i)}return m("FirefoxCookieQuery","Found Firefox cookie files",{files:o}),o}var u=class{constructor(){this.browserName="Firefox"}async queryCookies(e,a){let f=x(),i=[];for(let t of f)try{let n=await l({file:t,sql:"SELECT name, value, host as domain, expiry FROM moz_cookies WHERE name = ? AND host LIKE ?",params:[e,`%${a}%`],rowTransform:r=>({name:r.name,value:r.value,domain:r.domain,expiry:r.expiry>0?new Date(r.expiry*1e3):"Infinity",meta:{file:t,browser:"Firefox",decrypted:!1}})});i.push(...n)}catch(n){n instanceof Error?s("FirefoxCookieQuery",`Error reading Firefox cookie file ${t}`,{error:n.message}):s("FirefoxCookieQuery",`Error reading Firefox cookie file ${t}`)}return i}};export{u as a};
2
- //# sourceMappingURL=chunk-3FVH4L25.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/browsers/firefox/FirefoxCookieQueryStrategy.ts"],"sourcesContent":["import { join } from \"path\";\n\nimport { sync } from \"glob\";\n\nimport { logDebug, logWarn } from \"@utils/logHelpers\";\n\nimport {\n BrowserName,\n CookieQueryStrategy,\n ExportedCookie,\n} from \"../../../types/schemas\";\nimport { querySqliteThenTransform } from \"../QuerySqliteThenTransform\";\n\ninterface FirefoxCookieRow {\n name: string;\n value: string;\n domain: string;\n expiry: number;\n}\n\n/**\n * Find all Firefox cookie database files\n * @returns An array of file paths to Firefox cookie databases\n */\nfunction findFirefoxCookieFiles(): string[] {\n const files: string[] = [];\n const homedir = process.env.HOME;\n\n if (typeof homedir !== \"string\" || homedir.length === 0) {\n logWarn(\"FirefoxCookieQuery\", \"HOME environment variable not set\");\n return files;\n }\n\n const patterns = [\n join(\n homedir,\n \"Library/Application Support/Firefox/Profiles/*/cookies.sqlite\",\n ),\n join(homedir, \".mozilla/firefox/*/cookies.sqlite\"),\n ];\n\n for (const pattern of patterns) {\n const matches = sync(pattern);\n files.push(...matches);\n }\n\n logDebug(\"FirefoxCookieQuery\", \"Found Firefox cookie files\", { files });\n return files;\n}\n\n/**\n * Strategy for querying cookies from Firefox browser\n * @example\n */\nexport class FirefoxCookieQueryStrategy implements CookieQueryStrategy {\n /**\n *\n */\n public readonly browserName: BrowserName = \"Firefox\";\n\n /**\n * Queries cookies from Firefox's cookie store\n * @param name - The name pattern to match cookies against\n * @param domain - The domain pattern to match cookies against\n * @returns A promise that resolves to an array of exported cookies\n */\n public async queryCookies(\n name: string,\n domain: string,\n ): Promise<ExportedCookie[]> {\n const files = findFirefoxCookieFiles();\n const results: ExportedCookie[] = [];\n\n for (const file of files) {\n try {\n const cookies = await querySqliteThenTransform<\n FirefoxCookieRow,\n ExportedCookie\n >({\n file,\n sql: \"SELECT name, value, host as domain, expiry FROM moz_cookies WHERE name = ? AND host LIKE ?\",\n params: [name, `%${domain}%`],\n rowTransform: (row) => ({\n name: row.name,\n value: row.value,\n domain: row.domain,\n expiry: row.expiry > 0 ? new Date(row.expiry * 1000) : \"Infinity\",\n meta: {\n file,\n browser: \"Firefox\",\n decrypted: false,\n },\n }),\n });\n\n results.push(...cookies);\n } catch (error) {\n if (error instanceof Error) {\n logWarn(\n \"FirefoxCookieQuery\",\n `Error reading Firefox cookie file ${file}`,\n { error: error.message },\n );\n } else {\n logWarn(\n \"FirefoxCookieQuery\",\n `Error reading Firefox cookie file ${file}`,\n );\n }\n }\n }\n\n return results;\n }\n}\n"],"mappings":"8FAAA,OAAS,QAAAA,MAAY,OAwBrB,SAASC,GAAmC,CAC1C,IAAMC,EAAkB,CAAC,EACnBC,EAAU,QAAQ,IAAI,KAE5B,GAAI,OAAOA,GAAY,UAAYA,EAAQ,SAAW,EACpD,OAAAC,EAAQ,qBAAsB,mCAAmC,EAC1DF,EAGT,IAAMG,EAAW,CACfC,EACEH,EACA,+DACF,EACAG,EAAKH,EAAS,mCAAmC,CACnD,EAEA,QAAWI,KAAWF,EAAU,CAC9B,IAAMG,EAAUC,EAAKF,CAAO,EAC5BL,EAAM,KAAK,GAAGM,CAAO,CACvB,CAEA,OAAAE,EAAS,qBAAsB,6BAA8B,CAAE,MAAAR,CAAM,CAAC,EAC/DA,CACT,CAMO,IAAMS,EAAN,KAAgE,CAAhE,cAIL,KAAgB,YAA2B,UAQ3C,MAAa,aACXC,EACAC,EAC2B,CAC3B,IAAMX,EAAQD,EAAuB,EAC/Ba,EAA4B,CAAC,EAEnC,QAAWC,KAAQb,EACjB,GAAI,CACF,IAAMc,EAAU,MAAMC,EAGpB,CACA,KAAAF,EACA,IAAK,6FACL,OAAQ,CAACH,EAAM,IAAIC,CAAM,GAAG,EAC5B,aAAeK,IAAS,CACtB,KAAMA,EAAI,KACV,MAAOA,EAAI,MACX,OAAQA,EAAI,OACZ,OAAQA,EAAI,OAAS,EAAI,IAAI,KAAKA,EAAI,OAAS,GAAI,EAAI,WACvD,KAAM,CACJ,KAAAH,EACA,QAAS,UACT,UAAW,EACb,CACF,EACF,CAAC,EAEDD,EAAQ,KAAK,GAAGE,CAAO,CACzB,OAASG,EAAO,CACVA,aAAiB,MACnBf,EACE,qBACA,qCAAqCW,CAAI,GACzC,CAAE,MAAOI,EAAM,OAAQ,CACzB,EAEAf,EACE,qBACA,qCAAqCW,CAAI,EAC3C,CAEJ,CAGF,OAAOD,CACT,CACF","names":["join","findFirefoxCookieFiles","files","homedir","logWarn","patterns","join","pattern","matches","sync","logDebug","FirefoxCookieQueryStrategy","name","domain","results","file","cookies","querySqliteThenTransform","row","error"]}
@@ -1,2 +0,0 @@
1
- import{createConsola as g}from"consola";var a=g({fancy:!0,formatOptions:{showLogLevel:!1,colors:!0,date:!1,compact:!0,columns:typeof process.stdout.columns=="number"?process.stdout.columns:80},level:typeof process.env.LOG_LEVEL=="string"&&process.env.LOG_LEVEL==="debug"?5:2}),t=a;function u(n,o,e){let s=`${o?"\u2705":"\u274C"} ${n} ${o?"succeeded":"failed"}`;o?t.success(s,e):t.error(s,e)}function l(n,o,e){let r={...e!=null?e:{},error:o instanceof Error?{name:o.name,message:o.message,stack:o.stack}:o};t.error(n,r)}function f(n,o,e){t.withTag(n).debug(o,e)}function m(n){return t.withTag(n)}function d(n,o,e){t.withTag(n).warn(o,e)}export{t as a,u as b,l as c,f as d,m as e,d as f};
2
- //# sourceMappingURL=chunk-56Z35D5R.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/logger.ts","../src/utils/logHelpers.ts"],"sourcesContent":["import { createConsola } from \"consola\";\n\n/**\n * Standard log levels and their usage:\n * - debug: Detailed information for debugging\n * - info: General operational information\n * - success: Successful operations\n * - warn: Warning conditions\n * - error: Error conditions that might still allow the app to continue\n * - fatal: Critical errors that prevent the app from continuing\n */\nconst consola = createConsola({\n fancy: true,\n formatOptions: {\n showLogLevel: false,\n colors: true,\n date: false,\n compact: true,\n columns:\n typeof process.stdout.columns === \"number\" ? process.stdout.columns : 80,\n },\n level:\n typeof process.env.LOG_LEVEL === \"string\" &&\n process.env.LOG_LEVEL === \"debug\"\n ? 5\n : 2,\n});\n\n/**\n * Configured consola logger instance with standardized formatting and colored output.\n * Used for consistent logging throughout the application.\n * @example\n * // Basic usage\n * logger.info('Operation started');\n * logger.success('Task completed');\n * logger.error('Failed to process', error);\n *\n * // Tagged logging for module context\n * const moduleLogger = logger.withTag('ModuleName');\n * moduleLogger.info('Module specific log');\n *\n * // Structured logging\n * logger.info('User action', {\n * userId: '123',\n * action: 'login',\n * timestamp: new Date()\n * });\n *\n * // Error logging with full context\n * logger.error('Operation failed', {\n * error: error,\n * context: 'operation name',\n * input: data\n * });\n */\nexport default consola;\n","import logger from \"./logger\";\n\n/**\n * Helper functions for common logging patterns.\n * @module\n * @example\n * ```typescript\n * import { logOperationResult, logError } from './logHelpers';\n *\n * try {\n * const result = await someOperation();\n * logOperationResult('Operation', true, { data: result });\n * } catch (error) {\n * logError('Operation failed', error);\n * }\n * ```\n */\n\ninterface OperationContext {\n [key: string]: unknown;\n}\n\n/**\n * Logs the result of an operation with consistent formatting.\n * @param operation - Name of the operation.\n * @param success - Whether the operation succeeded.\n * @param [context] - Additional context about the operation.\n * @example\n * ```typescript\n * logOperationResult('Database Backup', true, { size: '1.2GB' });\n * // ✅ Database Backup succeeded\n *\n * logOperationResult('File Upload', false, { error: 'Network timeout' });\n * // ❌ File Upload failed\n * ```\n */\nexport function logOperationResult(\n operation: string,\n success: boolean,\n context?: OperationContext,\n): void {\n const icon = success ? \"✅\" : \"❌\";\n const message = `${icon} ${operation} ${success ? \"succeeded\" : \"failed\"}`;\n\n if (success) {\n logger.success(message, context);\n } else {\n logger.error(message, context);\n }\n}\n\n/**\n * Logs an error with consistent formatting and context.\n * @param message - Error message to display.\n * @param error - Error object or error information.\n * @param [context] - Additional context about the error.\n * @example\n * ```typescript\n * try {\n * throw new Error('Connection failed');\n * } catch (error) {\n * logError('Database error', error, { retries: 3 });\n * }\n * ```\n */\nexport function logError(\n message: string,\n error: unknown,\n context?: OperationContext,\n): void {\n const errorContext = {\n ...(context ?? {}),\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n };\n\n logger.error(message, errorContext);\n}\n\n/**\n * Logs debug information with consistent formatting.\n * @param component - Component or module name.\n * @param message - Debug message to log.\n * @param [data] - Optional debug data to include.\n * @example\n * ```typescript\n * logDebug('AuthService', 'Token refresh started', { userId: '123' });\n * ```\n */\nexport function logDebug(\n component: string,\n message: string,\n data?: unknown,\n): void {\n const componentLogger = logger.withTag(component);\n componentLogger.debug(message, data);\n}\n\n/**\n * Creates a tagged logger with consistent naming.\n * @param component - Component or module name.\n * @returns A tagged logger instance.\n * @example\n * ```typescript\n * const dbLogger = createTaggedLogger('Database');\n * dbLogger.info('Connection established');\n * ```\n */\nexport function createTaggedLogger(\n component: string,\n): ReturnType<typeof logger.withTag> {\n return logger.withTag(component);\n}\n\n/**\n * Logs a warning with consistent formatting.\n * @param component - Component or module name.\n * @param message - Warning message to display.\n * @param [context] - Additional context about the warning.\n * @example\n * ```typescript\n * logWarn('Cache', 'Cache miss', { key: 'user-123' });\n * ```\n */\nexport function logWarn(\n component: string,\n message: string,\n context?: OperationContext,\n): void {\n const componentLogger = logger.withTag(component);\n componentLogger.warn(message, context);\n}\n\n// Re-export the base logger for direct usage\n/**\n * Re-export of the base logger for direct usage.\n */\nexport { default as logger } from \"./logger\";\n"],"mappings":"AAAA,OAAS,iBAAAA,MAAqB,UAW9B,IAAMC,EAAUD,EAAc,CAC5B,MAAO,GACP,cAAe,CACb,aAAc,GACd,OAAQ,GACR,KAAM,GACN,QAAS,GACT,QACE,OAAO,QAAQ,OAAO,SAAY,SAAW,QAAQ,OAAO,QAAU,EAC1E,EACA,MACE,OAAO,QAAQ,IAAI,WAAc,UACjC,QAAQ,IAAI,YAAc,QACtB,EACA,CACR,CAAC,EA6BME,EAAQD,ECnBR,SAASE,EACdC,EACAC,EACAC,EACM,CAEN,IAAMC,EAAU,GADHF,EAAU,SAAM,QACN,IAAID,CAAS,IAAIC,EAAU,YAAc,QAAQ,GAEpEA,EACFG,EAAO,QAAQD,EAASD,CAAO,EAE/BE,EAAO,MAAMD,EAASD,CAAO,CAEjC,CAgBO,SAASG,EACdF,EACAG,EACAJ,EACM,CACN,IAAMK,EAAe,CACnB,GAAIL,GAAA,KAAAA,EAAW,CAAC,EAChB,MACEI,aAAiB,MACb,CACE,KAAMA,EAAM,KACZ,QAASA,EAAM,QACf,MAAOA,EAAM,KACf,EACAA,CACR,EAEAF,EAAO,MAAMD,EAASI,CAAY,CACpC,CAYO,SAASC,EACdC,EACAN,EACAO,EACM,CACkBN,EAAO,QAAQK,CAAS,EAChC,MAAMN,EAASO,CAAI,CACrC,CAYO,SAASC,EACdF,EACmC,CACnC,OAAOL,EAAO,QAAQK,CAAS,CACjC,CAYO,SAASG,EACdH,EACAN,EACAD,EACM,CACkBE,EAAO,QAAQK,CAAS,EAChC,KAAKN,EAASD,CAAO,CACvC","names":["createConsola","consola","logger_default","logOperationResult","operation","success","context","message","logger_default","logError","error","errorContext","logDebug","component","data","createTaggedLogger","logWarn"]}
@@ -1,2 +0,0 @@
1
- import{a as C,b as w}from"./chunk-DVWQBWUF.js";import{a as d,b as h,c as l,d as c,e as y}from"./chunk-56Z35D5R.js";import{existsSync as q}from"fs";import{join as p}from"path";import L from"fast-glob";import{join as D}from"path";import{merge as O}from"lodash-es";var k={};O(k,process.env);var m=k.HOME;if(typeof m!="string"||m.length===0)throw new Error("HOME environment variable is not set or empty");var E,f=D((E=m)!=null?E:"","Library","Application Support","Google","Chrome");function T(r){if(typeof r!="string")return!1;let e=r.trim();return e.length===0?!1:q(e)}async function Q(){let r=[p(f,"Default/Cookies"),p(f,"Profile */Cookies"),p(f,"Profile Default/Cookies")],e=[];for(let t of r){let o=await L(t);e.push(...o)}return c("ChromeCookies","Found cookie files",{count:e.length,files:e}),e}function I(r,e){let t=r==="%",o=t?"SELECT name, encrypted_value, host_key, expires_utc FROM cookies WHERE host_key LIKE ?":"SELECT name, encrypted_value, host_key, expires_utc FROM cookies WHERE name = ? AND host_key LIKE ?",i=t?[`%${e}%`]:[r,`%${e}%`];return{sql:o,params:i}}async function M(r,e,t){try{let{sql:o,params:i}=I(e,t);c("ChromeCookies","Executing query",{sql:o,params:i});let n=await C({file:r,sql:o,params:i,rowTransform:s=>({name:s.name,domain:s.host_key,value:s.encrypted_value,expiry:s.expires_utc})});return h("QueryCookies",!0,{file:r,count:n.length}),n}catch(o){return l("Failed to read cookie file",o,{file:r}),[]}}async function x({name:r,domain:e,file:t}){let o=typeof t=="string"&&t.length>0?[t]:await Q();if(o.length===0)return c("ChromeCookies","No cookie files found"),[];let i=[];for(let n of o){if(!T(n)){c("ChromeCookies","Cookie file missing or invalid",{file:n});continue}let s=await M(n,r,e);i.push(...s)}return c("ChromeCookies","Query complete",{totalCookies:i.length}),i}import{readFileSync as sr}from"fs";import{join as lr}from"path";var N=d.withTag("listChromeProfiles");function P(){let r=w("./**/Cookies",{cwd:f,absolute:!0});return N.debug("Found cookie files:",r),r}import{createDecipheriv as A,pbkdf2 as H}from"crypto";import{memoize as _}from"lodash-es";var $=_(r=>r.length>=3&&r[0]===118&&r[1]===49&&r[2]===48?r.slice(3):r,r=>r.toString("hex")),z=_(r=>{let e=r[r.length-1];return e&&e<=16?r.slice(0,-e):r},r=>r.toString("hex"));function G(r){var t;let e=[/.*?0t(.+)$/,/.*?1e`(.+)$/,/.*?[`'](.+)$/,/[^\x20-\x7E]*([\x20-\x7E].+)$/];for(let o of e){let i=r.match(o),n=(t=i==null?void 0:i[1])!=null?t:"";if(n.length>0)return n}return r}async function S(r,e){if(typeof e!="string")throw new Error("password must be a string");if(!Buffer.isBuffer(r))throw new Error("encryptedData must be a Buffer");return new Promise((t,o)=>{H(e,"saltysalt",1003,16,"sha1",(i,n)=>{try{if(i){o(new Error("Failed to derive key: "+i.message));return}let s=$(r);if(s.length%16!==0){o(new Error("Encrypted data length is not a multiple of 16"));return}let g=Buffer.alloc(16," "),a=A("aes-128-cbc",n,g);a.setAutoPadding(!1);let u=a.update(s);try{a.final()}catch(B){o(new Error("Failed to finalize decryption: "+B.message));return}u=z(u);let R=u.toString("utf8");t(G(R))}catch(s){o(new Error("Decryption failed: "+s.message))}})})}import{memoize as V}from"lodash-es";var v=V(async()=>{if(process.platform!=="darwin")throw l("Chrome password retrieval failed",new Error("This only works on macOS"),{platform:process.platform}),new Error("This only works on macOS");try{let{getChromePassword:r}=await import("./getChromePassword-O452VQWI.js"),e=await r();return c("ChromePassword","Retrieved password successfully",{platform:"macOS"}),e}catch(r){throw l("Chrome password retrieval failed",r,{platform:"macOS"}),r}});function W(r){return typeof r!="number"||r<=0?"Infinity":new Date(r)}function b(r,e,t,o,i,n){return{domain:r,name:e,value:t,expiry:W(o),meta:{file:i,browser:"Chrome",decrypted:n}}}var F=class{constructor(){this.logger=y("ChromeCookieQueryStrategy");this.browserName="Chrome"}async queryCookies(e,t){try{if(this.logger.info("Querying cookies",{name:e,domain:t}),process.platform!=="darwin")return this.logger.warn("Platform not supported",{platform:process.platform}),[];let o=P();if(o.length===0)return this.logger.warn("No Chrome cookie files found"),[];let i=await v();return(await Promise.all(o.map(s=>this.processFile(s,e,t,i)))).flat()}catch(o){return o instanceof Error?l("Failed to query cookies",o,{name:e,domain:t}):l("Failed to query cookies",new Error(String(o)),{name:e,domain:t}),[]}}async processFile(e,t,o,i){try{let n=await x({name:t,domain:o,file:e}),s={file:e,password:i};return(await Promise.allSettled(n.map(a=>this.processCookie(a,s)))).map(a=>a.status==="fulfilled"?a.value:null).filter(a=>a!==null)}catch(n){return n instanceof Error?this.logger.error("Failed to process cookie file",{error:n,file:e}):this.logger.error("Failed to process cookie file",{error:String(n),file:e}),[]}}async processCookie(e,t){try{let o=Buffer.isBuffer(e.value)?e.value:Buffer.from(String(e.value)),i=await S(o,t.password);return b(e.domain,e.name,i,e.expiry,t.file,!0)}catch(o){return o instanceof Error?this.logger.warn("Failed to decrypt cookie",{error:o}):this.logger.warn("Failed to decrypt cookie",{error:String(o)}),b(e.domain,e.name,e.value.toString("utf-8"),e.expiry,t.file,!1)}}};export{F as a};
2
- //# sourceMappingURL=chunk-7XZ7PCDJ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/browsers/getEncryptedChromeCookie.ts","../src/core/browsers/chrome/ChromeApplicationSupport.ts","../src/global.ts","../src/core/browsers/listChromeProfiles.ts","../src/core/browsers/chrome/decrypt.ts","../src/core/browsers/chrome/getChromePassword.ts","../src/core/browsers/chrome/ChromeCookieQueryStrategy.ts"],"sourcesContent":["import { existsSync } from \"fs\";\nimport { join } from \"path\";\n\nimport glob from \"fast-glob\";\n\nimport { logError, logDebug, logOperationResult } from \"@utils/logHelpers\";\n\nimport type { CookieRow } from \"../../types/schemas\";\n\nimport { chromeApplicationSupport } from \"./chrome/ChromeApplicationSupport\";\nimport { querySqliteThenTransform } from \"./QuerySqliteThenTransform\";\n\ninterface ChromeCookieRow {\n encrypted_value: Buffer;\n name: string;\n host_key: string;\n expires_utc: number;\n}\n\ninterface GetEncryptedCookieOptions {\n name: string;\n domain: string;\n file?: string;\n}\n\ninterface SqlQuery {\n sql: string;\n params: string[];\n}\n\n/**\n * Validates if a path is a valid, existing file\n * @param path - Path to validate\n * @returns true if path is valid and file exists, false otherwise\n */\nfunction isValidFilePath(path: unknown): path is string {\n if (typeof path !== \"string\") {\n return false;\n }\n\n const trimmedPath = path.trim();\n if (trimmedPath.length === 0) {\n return false;\n }\n\n return existsSync(trimmedPath);\n}\n\n/**\n * Get paths to Chrome cookie files\n * @returns A promise that resolves to an array of file paths\n */\nasync function getCookieFiles(): Promise<string[]> {\n const patterns = [\n join(chromeApplicationSupport, \"Default/Cookies\"),\n join(chromeApplicationSupport, \"Profile */Cookies\"),\n join(chromeApplicationSupport, \"Profile Default/Cookies\"),\n ];\n\n const files: string[] = [];\n for (const pattern of patterns) {\n const matches = await glob(pattern);\n files.push(...matches);\n }\n\n logDebug(\"ChromeCookies\", \"Found cookie files\", {\n count: files.length,\n files,\n });\n return files;\n}\n\n/**\n * Builds the SQL query for retrieving cookies\n * @param name - Cookie name to search for\n * @param domain - Domain to filter by\n * @returns SQL query and parameters\n */\nfunction buildSqlQuery(name: string, domain: string): SqlQuery {\n const isWildcard = name === \"%\";\n const sql = isWildcard\n ? `SELECT name, encrypted_value, host_key, expires_utc FROM cookies WHERE host_key LIKE ?`\n : `SELECT name, encrypted_value, host_key, expires_utc FROM cookies WHERE name = ? AND host_key LIKE ?`;\n const params = isWildcard ? [`%${domain}%`] : [name, `%${domain}%`];\n\n return { sql, params };\n}\n\n/**\n * Processes a single cookie file to extract matching cookies\n * @param cookieFile - Path to the cookie file\n * @param name - Cookie name to search for\n * @param domain - Domain to filter by\n * @returns Array of matching cookies\n */\nasync function processCookieFile(\n cookieFile: string,\n name: string,\n domain: string,\n): Promise<CookieRow[]> {\n try {\n const { sql, params } = buildSqlQuery(name, domain);\n logDebug(\"ChromeCookies\", \"Executing query\", { sql, params });\n\n const rows = await querySqliteThenTransform<ChromeCookieRow, CookieRow>({\n file: cookieFile,\n sql,\n params,\n rowTransform: (row: ChromeCookieRow): CookieRow => ({\n name: row.name,\n domain: row.host_key,\n value: row.encrypted_value,\n expiry: row.expires_utc,\n }),\n });\n\n logOperationResult(\"QueryCookies\", true, {\n file: cookieFile,\n count: rows.length,\n });\n return rows;\n } catch (error) {\n logError(\"Failed to read cookie file\", error, { file: cookieFile });\n return [];\n }\n}\n\n/**\n * Retrieve encrypted cookies from Chrome's cookie store\n * @param options - Options for querying Chrome cookies\n * @param options.name - The name of the cookie to retrieve\n * @param options.domain - The domain to retrieve cookies from\n * @param options.file - Optional specific cookie file to query\n * @returns Promise resolving to array of encrypted cookies\n */\nexport async function getEncryptedChromeCookie({\n name,\n domain,\n file,\n}: GetEncryptedCookieOptions): Promise<CookieRow[]> {\n const cookieFiles =\n typeof file === \"string\" && file.length > 0\n ? [file]\n : await getCookieFiles();\n\n if (cookieFiles.length === 0) {\n logDebug(\"ChromeCookies\", \"No cookie files found\");\n return [];\n }\n\n const results: CookieRow[] = [];\n for (const cookieFile of cookieFiles) {\n if (!isValidFilePath(cookieFile)) {\n logDebug(\"ChromeCookies\", \"Cookie file missing or invalid\", {\n file: cookieFile,\n });\n continue;\n }\n\n const cookies = await processCookieFile(cookieFile, name, domain);\n results.push(...cookies);\n }\n\n logDebug(\"ChromeCookies\", \"Query complete\", { totalCookies: results.length });\n return results;\n}\n","import { join } from \"path\";\n\nimport { HOME } from \"../../../global\";\n\n/**\n * The path to Chrome's application support directory on macOS\n * This constant is used to locate Chrome's profile and cookie storage directories\n * @example\n */\nexport const chromeApplicationSupport = join(\n HOME ?? \"\",\n \"Library\",\n \"Application Support\",\n \"Google\",\n \"Chrome\",\n);\n","import { merge } from \"lodash-es\";\n\n/**\n * Global environment variables object that merges with process.env\n * @example\n * // Access environment variables\n * const nodeEnv = env.NODE_ENV; // 'development'\n * const apiKey = env.API_KEY; // 'abc123'\n *\n * // Check if variable exists\n * if (env.DATABASE_URL) {\n * // Use database URL\n * }\n *\n * // Add new environment variables\n * env.CUSTOM_VAR = 'my-value';\n */\nexport const env: { [key: string]: string | undefined } = {};\nmerge(env, process.env);\n\n/**\n * User's home directory path from environment variables\n * @throws Error if HOME environment variable is not set\n * @example\n * // Access home directory path\n * const homePath = HOME; // '/home/username' or 'C:\\Users\\username'\n *\n * // Use in file path construction\n * const configPath = `${homePath}/.config/app`;\n *\n * // Error handling\n * if (typeof homePath === 'string' && homePath.length > 0) {\n * // Use home path\n * } else {\n * throw new Error('HOME environment variable is not set or empty');\n * }\n */\nexport const HOME: string | undefined = env[\"HOME\"];\nif (typeof HOME !== \"string\" || HOME.length === 0) {\n throw new Error(\"HOME environment variable is not set or empty\");\n}\n","// External imports\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\n\nimport { sync } from \"glob\";\n\n// Internal imports\nimport logger from \"@utils/logger\";\n\nimport { chromeApplicationSupport } from \"./chrome/ChromeApplicationSupport\";\n\nconst consola = logger.withTag(\"listChromeProfiles\");\n\n/**\n * Lists all Chrome profile paths that contain cookie files\n * @internal\n * @returns An array of absolute paths to Chrome cookie files\n * @throws {Error} If Chrome's application support directory cannot be accessed\n * @example\n * ```typescript\n * // Get all Chrome cookie file paths\n * const cookiePaths = listChromeProfilePaths();\n * // Returns: [\n * // '/Users/name/Library/Application Support/Chrome/Profile 1/Cookies',\n * // '/Users/name/Library/Application Support/Chrome/Profile 2/Cookies'\n * // ]\n *\n * // Handle errors\n * try {\n * const paths = listChromeProfilePaths();\n * } catch (error) {\n * console.error('Failed to access Chrome profiles:', error);\n * }\n * ```\n */\nexport function listChromeProfilePaths(): string[] {\n const files: string[] = sync(`./**/Cookies`, {\n cwd: chromeApplicationSupport,\n absolute: true,\n });\n\n consola.debug(\"Found cookie files:\", files);\n return files;\n}\n\n/**\n * Chrome Local State file structure\n * @internal\n */\ninterface ChromeLocalState {\n profile: {\n info_cache: Record<string, ChromeProfileInfo>;\n };\n}\n\n/**\n * Chrome profile information structure\n * @property {string} name - The name of the profile\n * @property {number} active_time - Unix timestamp of last profile activity\n * @property {string} account_id - Unique identifier for the Chrome profile\n * @property {Record<string, unknown>} accountcapabilities - Account feature flags\n * @property {string} email - User's email address\n * @property {string} full_name - User's full name\n * @property {boolean} is_using_default_avatar - Whether using default profile picture\n * @property {boolean} is_using_default_name - Whether using default profile name\n * @property {string} last_downloaded_gaia_picture_url_with_size - Profile picture URL\n * @property {string} local_auth_credentials - Authentication credentials\n * @property {string} shortcut_name - Profile shortcut name\n * @property {string} user_name - Username associated with profile\n */\ninterface ChromeProfileInfo {\n /** The name of the profile */\n name: string;\n /** Unix timestamp of last profile activity */\n active_time: number;\n /** Unique identifier for the Chrome profile */\n account_id: string;\n /** Account feature flags */\n accountcapabilities: Record<string, unknown>;\n /** User's email address */\n email: string;\n /** User's full name */\n full_name: string;\n /** Whether using default profile picture */\n is_using_default_avatar: boolean;\n /** Whether using default profile name */\n is_using_default_name: boolean;\n /** Profile picture URL */\n last_downloaded_gaia_picture_url_with_size: string;\n /** Authentication credentials */\n local_auth_credentials: string;\n /** Profile shortcut name */\n shortcut_name: string;\n /** Username associated with profile */\n user_name: string;\n}\n\n/**\n * Lists all Chrome profiles and their associated information\n * @internal\n * @returns An array of Chrome profile information objects. Returns empty array if profiles cannot be read\n * @throws {Error} If Chrome's application support directory cannot be accessed\n * @example\n * ```typescript\n * // Get all Chrome profiles\n * const profiles = listChromeProfiles();\n * // Returns: [\n * // {\n * // name: \"Default\",\n * // email: \"user@example.com\",\n * // full_name: \"John Doe\",\n * // ...\n * // },\n * // ...\n * // ]\n *\n * // Handle empty or error case\n * const profiles = listChromeProfiles();\n * if (profiles.length === 0) {\n * console.log('No Chrome profiles found or error occurred');\n * }\n * ```\n */\nexport function listChromeProfiles(): ChromeProfileInfo[] {\n try {\n const localStatePath = join(chromeApplicationSupport, \"Local State\");\n const localState = JSON.parse(\n readFileSync(localStatePath, \"utf8\"),\n ) as ChromeLocalState;\n return Object.values(localState.profile.info_cache);\n } catch (error) {\n if (error instanceof Error) {\n consola.error(\"Failed to read Chrome profiles:\", error.message);\n } else {\n consola.error(\"Failed to read Chrome profiles: Unknown error\");\n }\n return [];\n }\n}\n","// External imports\nimport { createDecipheriv, pbkdf2 } from \"crypto\";\n\nimport { memoize } from \"lodash-es\";\n\n/**\n * Removes the v10 prefix from the encrypted value if present\n * @param value - The encrypted value\n * @returns The value without the v10 prefix\n */\nconst removeV10Prefix = memoize(\n (value: Buffer): Buffer => {\n if (\n value.length >= 3 &&\n value[0] === 0x76 && // 'v'\n value[1] === 0x31 && // '1'\n value[2] === 0x30\n ) {\n // '0'\n return value.slice(3);\n }\n return value;\n },\n (value: Buffer) => value.toString(\"hex\"),\n);\n\n/**\n * Removes PKCS7 padding from the decrypted value\n * @param decrypted - The decrypted buffer\n * @returns The buffer without padding\n */\nconst removePadding = memoize(\n (decrypted: Buffer): Buffer => {\n const padding = decrypted[decrypted.length - 1];\n if (padding && padding <= 16) {\n return decrypted.slice(0, -padding);\n }\n return decrypted;\n },\n (decrypted: Buffer) => decrypted.toString(\"hex\"),\n);\n\n/**\n * Extracts the actual value from the decoded string by removing Chrome's prefixes\n * @param decodedString - The decoded string to clean up\n * @returns The cleaned up value\n */\nfunction extractValue(decodedString: string): string {\n const cleanupPatterns = [\n /.*?0t(.+)$/, // Pattern ending in \"0t\" followed by value\n /.*?1e`(.+)$/, // Pattern ending in \"1e`\" followed by value\n /.*?[`'](.+)$/, // Any backtick or quote followed by value\n /[^\\x20-\\x7E]*([\\x20-\\x7E].+)$/, // Non-printable chars followed by printable chars\n ];\n\n for (const pattern of cleanupPatterns) {\n const match = decodedString.match(pattern);\n const value = match?.[1] ?? \"\";\n if (value.length > 0) {\n return value;\n }\n }\n return decodedString;\n}\n\n/**\n * Decrypts Chrome's encrypted cookie values\n * @param encryptedValue - The encrypted cookie value as a Buffer\n * @param password - The Chrome encryption password\n * @returns A promise that resolves to the decrypted cookie value\n * @throws {Error} If decryption fails\n * @example\n */\nexport async function decrypt(\n encryptedValue: Buffer,\n password: string,\n): Promise<string> {\n if (typeof password !== \"string\") {\n throw new Error(\"password must be a string\");\n }\n if (!Buffer.isBuffer(encryptedValue)) {\n throw new Error(\"encryptedData must be a Buffer\");\n }\n\n return new Promise((resolve, reject) => {\n pbkdf2(password, \"saltysalt\", 1003, 16, \"sha1\", (error, key) => {\n try {\n if (error) {\n reject(new Error(\"Failed to derive key: \" + error.message));\n return;\n }\n\n const value = removeV10Prefix(encryptedValue);\n if (value.length % 16 !== 0) {\n reject(new Error(\"Encrypted data length is not a multiple of 16\"));\n return;\n }\n\n // Chrome's encryption parameters\n const iv = Buffer.alloc(16, \" \"); // 16 spaces\n const decipher = createDecipheriv(\"aes-128-cbc\", key, iv);\n decipher.setAutoPadding(false);\n\n // Decrypt the value\n let decrypted = decipher.update(value);\n try {\n decipher.final();\n } catch (e) {\n reject(\n new Error(\"Failed to finalize decryption: \" + (e as Error).message),\n );\n return;\n }\n\n decrypted = removePadding(decrypted);\n const decodedString = decrypted.toString(\"utf8\");\n resolve(extractValue(decodedString));\n } catch (e) {\n reject(new Error(\"Decryption failed: \" + (e as Error).message));\n }\n });\n });\n}\n","import { memoize } from \"lodash-es\";\n\nimport { logError, logDebug } from \"@utils/logHelpers\";\n\n/**\n * Retrieves the Chrome password for decrypting cookies\n * This is only supported on macOS\n * @returns A promise that resolves to the Chrome password\n * @throws {Error} If the platform is not macOS or if password retrieval fails\n * @example\n */\nexport const getChromePassword: () => Promise<string> = memoize(async () => {\n if (process.platform !== \"darwin\") {\n logError(\n \"Chrome password retrieval failed\",\n new Error(\"This only works on macOS\"),\n {\n platform: process.platform,\n },\n );\n throw new Error(\"This only works on macOS\");\n }\n\n try {\n const { getChromePassword: getMacOSPassword } = await import(\n \"./macos/getChromePassword\"\n );\n const password = await getMacOSPassword();\n logDebug(\"ChromePassword\", \"Retrieved password successfully\", {\n platform: \"macOS\",\n });\n return password;\n } catch (error) {\n logError(\"Chrome password retrieval failed\", error, { platform: \"macOS\" });\n throw error;\n }\n});\n","import { createTaggedLogger, logError } from \"@utils/logHelpers\";\n\nimport {\n BrowserName,\n CookieQueryStrategy,\n CookieRow,\n ExportedCookie,\n} from \"../../../types/schemas\";\nimport { getEncryptedChromeCookie } from \"../getEncryptedChromeCookie\";\nimport { listChromeProfilePaths } from \"../listChromeProfiles\";\n\nimport { decrypt } from \"./decrypt\";\nimport { getChromePassword } from \"./getChromePassword\";\n\ninterface DecryptionContext {\n file: string;\n password: string;\n}\n\nfunction getExpiryDate(expiry: number | undefined | null): Date | \"Infinity\" {\n if (typeof expiry !== \"number\" || expiry <= 0) {\n return \"Infinity\";\n }\n return new Date(expiry);\n}\n\nfunction createExportedCookie(\n domain: string,\n name: string,\n value: string,\n expiry: number | undefined | null,\n file: string,\n decrypted: boolean,\n): ExportedCookie {\n return {\n domain,\n name,\n value,\n expiry: getExpiryDate(expiry),\n meta: {\n file,\n browser: \"Chrome\",\n decrypted,\n },\n };\n}\n\n/**\n * Strategy for querying cookies from Chrome browser\n * @example\n * ```typescript\n * const strategy = new ChromeCookieQueryStrategy();\n * const cookies = await strategy.queryCookies('session', 'example.com');\n * ```\n */\nexport class ChromeCookieQueryStrategy implements CookieQueryStrategy {\n private readonly logger = createTaggedLogger(\"ChromeCookieQueryStrategy\");\n\n /**\n * The browser name for this strategy\n */\n public readonly browserName: BrowserName = \"Chrome\";\n\n /**\n * Queries cookies from Chrome's cookie store\n * @param name - The name pattern to match cookies against\n * @param domain - The domain pattern to match cookies against\n * @returns A promise that resolves to an array of exported cookies\n * @example\n * ```typescript\n * const strategy = new ChromeCookieQueryStrategy();\n * const cookies = await strategy.queryCookies('session', 'example.com');\n * console.log(cookies);\n * ```\n */\n public async queryCookies(\n name: string,\n domain: string,\n ): Promise<ExportedCookie[]> {\n try {\n this.logger.info(\"Querying cookies\", { name, domain });\n\n if (process.platform !== \"darwin\") {\n this.logger.warn(\"Platform not supported\", {\n platform: process.platform,\n });\n return [];\n }\n\n const cookieFiles = listChromeProfilePaths();\n if (cookieFiles.length === 0) {\n this.logger.warn(\"No Chrome cookie files found\");\n return [];\n }\n\n const password = await getChromePassword();\n const results = await Promise.all(\n cookieFiles.map((file) =>\n this.processFile(file, name, domain, password),\n ),\n );\n\n return results.flat();\n } catch (error) {\n if (error instanceof Error) {\n logError(\"Failed to query cookies\", error, { name, domain });\n } else {\n logError(\"Failed to query cookies\", new Error(String(error)), {\n name,\n domain,\n });\n }\n return [];\n }\n }\n\n private async processFile(\n file: string,\n name: string,\n domain: string,\n password: string,\n ): Promise<ExportedCookie[]> {\n try {\n const encryptedCookies = await getEncryptedChromeCookie({\n name,\n domain,\n file,\n });\n\n const context: DecryptionContext = { file, password };\n const results = await Promise.allSettled(\n encryptedCookies.map((cookie) => this.processCookie(cookie, context)),\n );\n\n return results\n .map((result) => (result.status === \"fulfilled\" ? result.value : null))\n .filter((cookie): cookie is ExportedCookie => cookie !== null);\n } catch (error) {\n if (error instanceof Error) {\n this.logger.error(\"Failed to process cookie file\", { error, file });\n } else {\n this.logger.error(\"Failed to process cookie file\", {\n error: String(error),\n file,\n });\n }\n return [];\n }\n }\n\n private async processCookie(\n cookie: CookieRow,\n context: DecryptionContext,\n ): Promise<ExportedCookie> {\n try {\n const value = Buffer.isBuffer(cookie.value)\n ? cookie.value\n : Buffer.from(String(cookie.value));\n\n const decryptedValue = await decrypt(value, context.password);\n return createExportedCookie(\n cookie.domain,\n cookie.name,\n decryptedValue,\n cookie.expiry,\n context.file,\n true,\n );\n } catch (error) {\n if (error instanceof Error) {\n this.logger.warn(\"Failed to decrypt cookie\", { error });\n } else {\n this.logger.warn(\"Failed to decrypt cookie\", { error: String(error) });\n }\n return createExportedCookie(\n cookie.domain,\n cookie.name,\n cookie.value.toString(\"utf-8\"),\n cookie.expiry,\n context.file,\n false,\n );\n }\n }\n}\n"],"mappings":"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","names":["existsSync","join","glob","join","merge","env","HOME","_a","chromeApplicationSupport","join","HOME","isValidFilePath","path","trimmedPath","existsSync","getCookieFiles","patterns","join","chromeApplicationSupport","files","pattern","matches","glob","logDebug","buildSqlQuery","name","domain","isWildcard","sql","params","processCookieFile","cookieFile","rows","querySqliteThenTransform","row","logOperationResult","error","logError","getEncryptedChromeCookie","file","cookieFiles","results","cookies","readFileSync","join","consola","logger_default","listChromeProfilePaths","files","sync","chromeApplicationSupport","createDecipheriv","pbkdf2","memoize","removeV10Prefix","value","removePadding","decrypted","padding","extractValue","decodedString","_a","cleanupPatterns","pattern","match","decrypt","encryptedValue","password","resolve","reject","error","key","iv","decipher","e","memoize","getChromePassword","memoize","logError","getMacOSPassword","password","logDebug","error","getExpiryDate","expiry","createExportedCookie","domain","name","value","file","decrypted","ChromeCookieQueryStrategy","createTaggedLogger","cookieFiles","listChromeProfilePaths","password","getChromePassword","error","logError","encryptedCookies","getEncryptedChromeCookie","context","cookie","result","decryptedValue","decrypt"]}