@mherod/get-cookie 4.0.2 → 4.0.4

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 (50) hide show
  1. package/.husky/commit-msg +0 -0
  2. package/.husky/pre-commit +0 -0
  3. package/.husky/pre-push +0 -0
  4. package/.idea/prettier.xml +2 -1
  5. package/dist/chunk-A6MIB6FP.js +2 -0
  6. package/dist/chunk-A6MIB6FP.js.map +1 -0
  7. package/dist/chunk-CFMK2YSL.js +2 -0
  8. package/dist/chunk-CFMK2YSL.js.map +1 -0
  9. package/dist/chunk-IRERRCUF.js +2 -0
  10. package/dist/chunk-IRERRCUF.js.map +1 -0
  11. package/dist/chunk-UPNW543B.js +2 -0
  12. package/dist/chunk-UPNW543B.js.map +1 -0
  13. package/dist/cli.cjs +3 -4
  14. package/dist/cli.cjs.map +1 -1
  15. package/dist/{getChromeCookie-4ZWACG6M.js → getChromeCookie-CL3SRRWX.js} +2 -2
  16. package/dist/getChromeCookie-CL3SRRWX.js.map +1 -0
  17. package/dist/getCookie-WV5KDZN7.js +2 -0
  18. package/dist/getFirefoxCookie-BXQ2GXAW.js +2 -0
  19. package/dist/getFirefoxCookie-BXQ2GXAW.js.map +1 -0
  20. package/dist/getGroupedRenderedCookies-FNJ6FQVQ.js +2 -0
  21. package/dist/getGroupedRenderedCookies-FNJ6FQVQ.js.map +1 -0
  22. package/dist/getMergedRenderedCookies-PNC2LHSD.js +2 -0
  23. package/dist/getMergedRenderedCookies-PNC2LHSD.js.map +1 -0
  24. package/dist/index.cjs +3 -3
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +164 -152
  27. package/dist/index.d.ts +164 -152
  28. package/dist/index.js +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/eslint.config.js +2 -1
  31. package/package.json +23 -19
  32. package/typedoc.json +3 -8
  33. package/dist/chunk-5ZT2G45S.js +0 -2
  34. package/dist/chunk-5ZT2G45S.js.map +0 -1
  35. package/dist/chunk-FR2MKDHT.js +0 -2
  36. package/dist/chunk-FR2MKDHT.js.map +0 -1
  37. package/dist/chunk-HMKSQBDC.js +0 -2
  38. package/dist/chunk-HMKSQBDC.js.map +0 -1
  39. package/dist/chunk-W3JALMAX.js +0 -2
  40. package/dist/chunk-W3JALMAX.js.map +0 -1
  41. package/dist/getChromeCookie-4ZWACG6M.js.map +0 -1
  42. package/dist/getCookie-43FKMQEZ.js +0 -2
  43. package/dist/getFirefoxCookie-OJYYZFZP.js +0 -2
  44. package/dist/getFirefoxCookie-OJYYZFZP.js.map +0 -1
  45. package/dist/getGroupedRenderedCookies-P5VZXZUC.js +0 -2
  46. package/dist/getGroupedRenderedCookies-P5VZXZUC.js.map +0 -1
  47. package/dist/getMergedRenderedCookies-C6TXK2I4.js +0 -2
  48. package/dist/getMergedRenderedCookies-C6TXK2I4.js.map +0 -1
  49. package/tsup.config.ts +0 -27
  50. /package/dist/{getCookie-43FKMQEZ.js.map → getCookie-WV5KDZN7.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,189 +1,201 @@
1
+ import { z } from 'zod';
2
+
1
3
  /**
2
- * Type guard to check if an object matches the CookieRenderOptions interface.
3
- * Used to validate render options before processing cookie output.
4
- * @param obj - The object to check.
5
- * @returns True if the object contains valid render options.
4
+ * Schema for cookie specification parameters
5
+ * Defines the required fields for identifying a cookie
6
6
  * @example
7
7
  * ```typescript
8
- * import { isCookieRenderOptions } from 'get-cookie';
9
- *
10
- * // Valid render options
11
- * console.log(isCookieRenderOptions({ format: "json" })); // true
12
- * console.log(isCookieRenderOptions({
13
- * format: "text",
14
- * separator: "\n",
15
- * showFilePaths: true
16
- * })); // true
8
+ * // Validate a cookie specification
9
+ * const spec = {
10
+ * name: 'session',
11
+ * domain: 'example.com'
12
+ * };
13
+ * const result = CookieSpecSchema.safeParse(spec);
14
+ * if (result.success) {
15
+ * console.log('Valid cookie spec:', result.data);
16
+ * } else {
17
+ * console.error('Invalid cookie spec:', result.error);
18
+ * }
17
19
  *
18
- * // Invalid examples
19
- * console.log(isCookieRenderOptions({ format: "csv" })); // false - invalid format
20
- * console.log(isCookieRenderOptions({ separator: "\n" })); // false - missing format
21
- * console.log(isCookieRenderOptions(null)); // false
20
+ * // Invalid spec (empty name)
21
+ * const invalidSpec = {
22
+ * name: '',
23
+ * domain: 'example.com'
24
+ * };
25
+ * // Throws: "Cookie name cannot be empty"
26
+ * CookieSpecSchema.parse(invalidSpec);
22
27
  * ```
23
28
  */
24
- type RenderFormat = "merged" | "grouped";
29
+ declare const CookieSpecSchema: z.ZodObject<{
30
+ name: z.ZodString;
31
+ domain: z.ZodString;
32
+ }, "strict", z.ZodTypeAny, {
33
+ name: string;
34
+ domain: string;
35
+ }, {
36
+ name: string;
37
+ domain: string;
38
+ }>;
25
39
  /**
26
- * Options for rendering cookies.
40
+ * Type definition for cookie specification
41
+ * Used for specifying which cookie to query
27
42
  * @example
28
43
  * ```typescript
29
- * import { RenderOptions } from 'get-cookie';
30
- *
31
- * // Basic rendering options
32
- * const basicOptions: RenderOptions = {
33
- * format: 'merged',
34
- * separator: '; ',
35
- * showFilePaths: false
44
+ * // Basic cookie spec
45
+ * const spec: CookieSpec = {
46
+ * name: 'auth',
47
+ * domain: 'api.example.com'
36
48
  * };
37
49
  *
38
- * // Grouped format with file paths
39
- * const groupedOptions: RenderOptions = {
40
- * format: 'grouped',
41
- * separator: '; ',
42
- * showFilePaths: true
43
- * };
50
+ * // Use in function parameters
51
+ * function queryCookie(spec: CookieSpec): Promise<ExportedCookie[]> {
52
+ * return getCookie(spec);
53
+ * }
44
54
  *
45
- * // Custom separator
46
- * const customOptions: RenderOptions = {
47
- * format: 'merged',
48
- * separator: ' && ',
49
- * showFilePaths: false
50
- * };
55
+ * // Array of specs
56
+ * const specs: CookieSpec[] = [
57
+ * { name: 'session', domain: 'app.example.com' },
58
+ * { name: 'theme', domain: 'example.com' }
59
+ * ];
51
60
  * ```
52
61
  */
53
- interface RenderOptions {
54
- /** The format to use when rendering cookies. */
55
- format?: RenderFormat;
56
- /** The separator to use between cookies. */
57
- separator?: string;
58
- /** Whether to show file paths in the output. */
59
- showFilePaths?: boolean;
60
- }
61
-
62
+ type CookieSpec = z.infer<typeof CookieSpecSchema>;
62
63
  /**
63
- * Specification for identifying a cookie by its domain and name.
64
- * Used to query specific cookies from browser storage.
65
- * @remarks
66
- * - Domain matching is exact unless using wildcards.
67
- * - Name can be "*" to match all cookies for a domain.
68
- * - Leading dots in domains match all subdomains.
64
+ * Schema for exported cookie data
65
+ * Represents a cookie with all its properties and metadata
69
66
  * @example
70
67
  * ```typescript
71
- * import { CookieSpec } from 'get-cookie';
72
- *
73
- * // Basic cookie specification
74
- * const cookieSpec: CookieSpec = {
75
- * domain: "example.com",
76
- * name: "sessionId"
77
- * };
78
- *
79
- * // Using wildcards to match all cookies
80
- * const allCookies: CookieSpec = {
81
- * domain: "example.com",
82
- * name: "*" // Match all cookies for example.com
83
- * };
84
- *
85
- * // Subdomain specification
86
- * const apiCookies: CookieSpec = {
87
- * domain: "api.example.com",
88
- * name: "auth"
89
- * };
90
- *
91
- * // Match cookies across all subdomains
92
- * const allSubdomainCookies: CookieSpec = {
93
- * domain: ".example.com", // Note the leading dot
94
- * name: "tracking"
68
+ * // Validate an exported cookie
69
+ * const cookie = {
70
+ * domain: 'example.com',
71
+ * name: 'session',
72
+ * value: 'abc123',
73
+ * expiry: new Date('2024-12-31'),
74
+ * meta: {
75
+ * file: '/path/to/cookies.db'
76
+ * }
95
77
  * };
78
+ * const result = ExportedCookieSchema.safeParse(cookie);
79
+ * if (result.success) {
80
+ * console.log('Valid cookie:', result.data);
81
+ * } else {
82
+ * console.error('Invalid cookie:', result.error);
83
+ * }
96
84
  *
97
- * // Multiple domain levels
98
- * const deepSubdomainCookie: CookieSpec = {
99
- * domain: "dev.api.example.com",
100
- * name: "debug"
85
+ * // Cookie with infinite expiry
86
+ * const infiniteCookie = {
87
+ * ...cookie,
88
+ * expiry: "Infinity"
101
89
  * };
90
+ * ExportedCookieSchema.parse(infiniteCookie); // OK
102
91
  * ```
103
92
  */
104
- interface CookieSpec {
105
- /** The domain the cookie belongs to. */
93
+ declare const ExportedCookieSchema: z.ZodObject<{
94
+ domain: z.ZodString;
95
+ name: z.ZodString;
96
+ value: z.ZodString;
97
+ expiry: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"Infinity">, z.ZodDate, z.ZodNumber]>>;
98
+ meta: z.ZodOptional<z.ZodObject<{
99
+ file: z.ZodOptional<z.ZodString>;
100
+ browser: z.ZodOptional<z.ZodString>;
101
+ decrypted: z.ZodOptional<z.ZodBoolean>;
102
+ secure: z.ZodOptional<z.ZodBoolean>;
103
+ httpOnly: z.ZodOptional<z.ZodBoolean>;
104
+ path: z.ZodOptional<z.ZodString>;
105
+ }, "strict", z.ZodUnknown, z.objectOutputType<{
106
+ file: z.ZodOptional<z.ZodString>;
107
+ browser: z.ZodOptional<z.ZodString>;
108
+ decrypted: z.ZodOptional<z.ZodBoolean>;
109
+ secure: z.ZodOptional<z.ZodBoolean>;
110
+ httpOnly: z.ZodOptional<z.ZodBoolean>;
111
+ path: z.ZodOptional<z.ZodString>;
112
+ }, z.ZodUnknown, "strict">, z.objectInputType<{
113
+ file: z.ZodOptional<z.ZodString>;
114
+ browser: z.ZodOptional<z.ZodString>;
115
+ decrypted: z.ZodOptional<z.ZodBoolean>;
116
+ secure: z.ZodOptional<z.ZodBoolean>;
117
+ httpOnly: z.ZodOptional<z.ZodBoolean>;
118
+ path: z.ZodOptional<z.ZodString>;
119
+ }, z.ZodUnknown, "strict">>>;
120
+ }, "strict", z.ZodTypeAny, {
121
+ name: string;
106
122
  domain: string;
107
- /** The name of the cookie. */
123
+ value: string;
124
+ expiry?: number | Date | "Infinity" | undefined;
125
+ meta?: z.objectOutputType<{
126
+ file: z.ZodOptional<z.ZodString>;
127
+ browser: z.ZodOptional<z.ZodString>;
128
+ decrypted: z.ZodOptional<z.ZodBoolean>;
129
+ secure: z.ZodOptional<z.ZodBoolean>;
130
+ httpOnly: z.ZodOptional<z.ZodBoolean>;
131
+ path: z.ZodOptional<z.ZodString>;
132
+ }, z.ZodUnknown, "strict"> | undefined;
133
+ }, {
108
134
  name: string;
109
- }
110
-
135
+ domain: string;
136
+ value: string;
137
+ expiry?: number | Date | "Infinity" | undefined;
138
+ meta?: z.objectInputType<{
139
+ file: z.ZodOptional<z.ZodString>;
140
+ browser: z.ZodOptional<z.ZodString>;
141
+ decrypted: z.ZodOptional<z.ZodBoolean>;
142
+ secure: z.ZodOptional<z.ZodBoolean>;
143
+ httpOnly: z.ZodOptional<z.ZodBoolean>;
144
+ path: z.ZodOptional<z.ZodString>;
145
+ }, z.ZodUnknown, "strict"> | undefined;
146
+ }>;
111
147
  /**
112
- * Interface representing a cookie that has been exported from a browser's storage.
113
- * This is the core data structure used to represent cookies after they have been
114
- * retrieved from various browser storage mechanisms (Chrome, Firefox, etc.).
115
- * @remarks
116
- * - All cookies must have domain, name, and value properties.
117
- * - Expiry is optional and can be a Date, "Infinity", or undefined.
118
- * - Meta information is useful for tracking the cookie's origin and state.
148
+ * Type definition for exported cookie data
149
+ * Represents the structure of a cookie after it has been retrieved
119
150
  * @example
120
151
  * ```typescript
121
- * import { ExportedCookie } from 'get-cookie';
122
- *
123
- * // Basic cookie with required fields
124
- * const basicCookie: ExportedCookie = {
125
- * domain: "example.com",
126
- * name: "sessionId",
127
- * value: "abc123"
128
- * };
129
- *
130
- * // Cookie with expiry and metadata
131
- * const detailedCookie: ExportedCookie = {
132
- * domain: "api.example.com",
133
- * name: "authToken",
134
- * value: "xyz789",
135
- * expiry: new Date("2024-12-31"),
152
+ * // Basic exported cookie
153
+ * const cookie: ExportedCookie = {
154
+ * domain: 'example.com',
155
+ * name: 'session',
156
+ * value: 'abc123',
157
+ * expiry: new Date('2024-12-31'),
136
158
  * meta: {
137
- * file: "Cookies.sqlite",
138
- * browser: "Firefox",
139
- * decrypted: true,
140
- * secure: true,
141
- * httpOnly: true,
142
- * path: "/"
159
+ * file: '/path/to/cookies.db'
143
160
  * }
144
161
  * };
145
162
  *
146
- * // Cookie with infinite expiry (session cookie)
147
- * const persistentCookie: ExportedCookie = {
148
- * domain: "app.example.com",
149
- * name: "preferences",
150
- * value: "theme=dark",
151
- * expiry: "Infinity"
152
- * };
163
+ * // Process exported cookies
164
+ * function processCookies(cookies: ExportedCookie[]): string[] {
165
+ * return cookies.map(cookie => `${cookie.name}=${cookie.value}`);
166
+ * }
153
167
  *
154
- * // Subdomain cookie example
155
- * const subdomainCookie: ExportedCookie = {
156
- * domain: ".example.com", // Note the leading dot for all subdomains
157
- * name: "tracking",
158
- * value: "user123",
159
- * meta: {
160
- * browser: "Chrome",
161
- * decrypted: true
162
- * }
163
- * };
168
+ * // Filter expired cookies
169
+ * function filterExpired(cookies: ExportedCookie[]): ExportedCookie[] {
170
+ * const now = new Date();
171
+ * return cookies.filter(cookie =>
172
+ * cookie.expiry === "Infinity" ||
173
+ * (cookie.expiry instanceof Date && cookie.expiry > now)
174
+ * );
175
+ * }
164
176
  * ```
165
177
  */
166
- interface ExportedCookie {
167
- /** The domain the cookie belongs to. */
168
- domain: string;
169
- /** The name of the cookie. */
170
- name: string;
171
- /** The value of the cookie. */
172
- value: string;
173
- /** When the cookie expires (Date object, "Infinity", or undefined). */
174
- expiry?: Date | "Infinity";
175
- /** Additional metadata about the cookie. */
176
- meta?: {
177
- /** Path to the file the cookie was exported from. */
178
- file?: string;
179
- /** Browser the cookie was exported from. */
180
- browser?: string;
181
- /** Whether the cookie value was decrypted. */
182
- decrypted?: boolean;
183
- /** Any additional metadata. */
184
- [key: string]: unknown;
185
- };
186
- }
178
+ type ExportedCookie = z.infer<typeof ExportedCookieSchema>;
179
+ /**
180
+ * Schema for cookie render options
181
+ */
182
+ declare const RenderOptionsSchema: z.ZodObject<{
183
+ format: z.ZodOptional<z.ZodEnum<["merged", "grouped"]>>;
184
+ separator: z.ZodOptional<z.ZodString>;
185
+ showFilePaths: z.ZodOptional<z.ZodBoolean>;
186
+ }, "strict", z.ZodTypeAny, {
187
+ format?: "merged" | "grouped" | undefined;
188
+ separator?: string | undefined;
189
+ showFilePaths?: boolean | undefined;
190
+ }, {
191
+ format?: "merged" | "grouped" | undefined;
192
+ separator?: string | undefined;
193
+ showFilePaths?: boolean | undefined;
194
+ }>;
195
+ /**
196
+ * Type definition for render options
197
+ */
198
+ type RenderOptions = z.infer<typeof RenderOptionsSchema>;
187
199
 
188
200
  /**
189
201
  * Dynamic import for the getCookie function.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import"./chunk-VMBA4NVU.js";var o=()=>import("./getCookie-43FKMQEZ.js").then(e=>e.getCookie),i=()=>import("./getChromeCookie-4ZWACG6M.js").then(e=>e.getChromeCookie),t=()=>import("./getFirefoxCookie-OJYYZFZP.js").then(e=>e.getFirefoxCookie),r=()=>import("./getGroupedRenderedCookies-P5VZXZUC.js").then(e=>e.getGroupedRenderedCookies),p=()=>import("./getMergedRenderedCookies-C6TXK2I4.js").then(e=>e.getMergedRenderedCookies);export{i as getChromeCookie,o as getCookie,t as getFirefoxCookie,r as getGroupedRenderedCookies,p as getMergedRenderedCookies};
1
+ import"./chunk-VMBA4NVU.js";var o=()=>import("./getCookie-WV5KDZN7.js").then(e=>e.getCookie),i=()=>import("./getChromeCookie-CL3SRRWX.js").then(e=>e.getChromeCookie),r=()=>import("./getFirefoxCookie-BXQ2GXAW.js").then(e=>e.getFirefoxCookie),t=()=>import("./getGroupedRenderedCookies-FNJ6FQVQ.js").then(e=>e.getGroupedRenderedCookies),p=()=>import("./getMergedRenderedCookies-PNC2LHSD.js").then(e=>e.getMergedRenderedCookies);export{i as getChromeCookie,o as getCookie,r as getFirefoxCookie,t as getGroupedRenderedCookies,p as getMergedRenderedCookies};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/cookies/dynamicImports.ts"],"sourcesContent":["import type { RenderOptions } from \"../../types/CookieRender\";\nimport type { CookieSpec } from \"../../types/CookieSpec\";\nimport type { ExportedCookie } from \"../../types/ExportedCookie\";\n\n/**\n * Dynamic import for the getCookie function.\n * @internal\n * @returns Promise resolving to the getCookie function\n * @example\n * ```typescript\n * const getCookieFn = await getCookie();\n * const cookies = await getCookieFn({ domain: 'example.com' });\n * // Returns: [{ name: 'sessionId', value: 'abc123', domain: 'example.com' }, ...]\n * ```\n */\nexport const getCookie = (): Promise<\n (cookieSpec: CookieSpec) => Promise<ExportedCookie[]>\n> => import(\"./getCookie\").then((module) => module.getCookie);\n\n/**\n * Dynamic import for Chrome-specific cookie retrieval.\n * @internal\n * @returns Promise resolving to the getChromeCookie function\n * @example\n * ```typescript\n * const chromeCookieFn = await getChromeCookie();\n * const cookies = await chromeCookieFn({ domain: 'example.com', secure: true });\n * // Returns Chrome-format cookies: [{ name: 'auth', value: 'xyz789', secure: true }, ...]\n * ```\n */\nexport const getChromeCookie = (): Promise<\n (cookieSpec: CookieSpec) => Promise<ExportedCookie[]>\n> => import(\"./getChromeCookie\").then((module) => module.getChromeCookie);\n\n/**\n * Dynamic import for Firefox-specific cookie retrieval.\n * @internal\n * @returns Promise resolving to the getFirefoxCookie function\n * @example\n * ```typescript\n * const firefoxCookieFn = await getFirefoxCookie();\n * const cookies = await firefoxCookieFn({ path: '/api' });\n * // Returns Firefox-format cookies: [{ name: 'token', value: 'def456', path: '/api' }, ...]\n * ```\n */\nexport const getFirefoxCookie = (): Promise<\n (cookieSpec: CookieSpec) => Promise<ExportedCookie[]>\n> => import(\"./getFirefoxCookie\").then((module) => module.getFirefoxCookie);\n\n/**\n * Dynamic import for retrieving grouped and rendered cookies.\n * @internal\n * @returns Promise resolving to the getGroupedRenderedCookies function\n * @example\n * ```typescript\n * const groupedCookiesFn = await getGroupedRenderedCookies();\n * const cookieStrings = await groupedCookiesFn({ domain: 'example.com' });\n * // Returns: ['sessionId=abc123; Domain=example.com', 'auth=xyz789; Domain=example.com']\n * ```\n */\nexport const getGroupedRenderedCookies = (): Promise<\n (cookieSpec: CookieSpec) => Promise<string[]>\n> =>\n import(\"./getGroupedRenderedCookies\").then(\n (module) => module.getGroupedRenderedCookies,\n );\n\n/**\n * Dynamic import for retrieving merged and rendered cookies.\n * @internal\n * @returns Promise resolving to the getMergedRenderedCookies function\n * @example\n * ```typescript\n * const mergedCookiesFn = await getMergedRenderedCookies();\n * const cookieString = await mergedCookiesFn(\n * { domain: 'example.com' },\n * { separator: '; ' }\n * );\n * // Returns: \"sessionId=abc123; auth=xyz789\"\n * ```\n */\nexport const getMergedRenderedCookies = (): Promise<\n (\n cookieSpec: CookieSpec,\n options?: Omit<RenderOptions, \"format\">,\n ) => Promise<string>\n> =>\n import(\"./getMergedRenderedCookies\").then(\n (module) => module.getMergedRenderedCookies,\n );\n"],"mappings":"4BAeO,IAAMA,EAAY,IAEpB,OAAO,yBAAa,EAAE,KAAMC,GAAWA,EAAO,SAAS,EAa/CC,EAAkB,IAE1B,OAAO,+BAAmB,EAAE,KAAMD,GAAWA,EAAO,eAAe,EAa3DE,EAAmB,IAE3B,OAAO,gCAAoB,EAAE,KAAMF,GAAWA,EAAO,gBAAgB,EAa7DG,EAA4B,IAGvC,OAAO,yCAA6B,EAAE,KACnCH,GAAWA,EAAO,yBACrB,EAgBWI,EAA2B,IAMtC,OAAO,wCAA4B,EAAE,KAClCJ,GAAWA,EAAO,wBACrB","names":["getCookie","module","getChromeCookie","getFirefoxCookie","getGroupedRenderedCookies","getMergedRenderedCookies"]}
1
+ {"version":3,"sources":["../src/core/cookies/dynamicImports.ts"],"sourcesContent":["import type {\n RenderOptions,\n CookieSpec,\n ExportedCookie,\n} from \"../../types/schemas\";\n\n/**\n * Dynamic import for the getCookie function.\n * @internal\n * @returns Promise resolving to the getCookie function\n * @example\n * ```typescript\n * const getCookieFn = await getCookie();\n * const cookies = await getCookieFn({ domain: 'example.com' });\n * // Returns: [{ name: 'sessionId', value: 'abc123', domain: 'example.com' }, ...]\n * ```\n */\nexport const getCookie = (): Promise<\n (cookieSpec: CookieSpec) => Promise<ExportedCookie[]>\n> => import(\"./getCookie\").then((module) => module.getCookie);\n\n/**\n * Dynamic import for Chrome-specific cookie retrieval.\n * @internal\n * @returns Promise resolving to the getChromeCookie function\n * @example\n * ```typescript\n * const chromeCookieFn = await getChromeCookie();\n * const cookies = await chromeCookieFn({ domain: 'example.com', secure: true });\n * // Returns Chrome-format cookies: [{ name: 'auth', value: 'xyz789', secure: true }, ...]\n * ```\n */\nexport const getChromeCookie = (): Promise<\n (cookieSpec: CookieSpec) => Promise<ExportedCookie[]>\n> => import(\"./getChromeCookie\").then((module) => module.getChromeCookie);\n\n/**\n * Dynamic import for Firefox-specific cookie retrieval.\n * @internal\n * @returns Promise resolving to the getFirefoxCookie function\n * @example\n * ```typescript\n * const firefoxCookieFn = await getFirefoxCookie();\n * const cookies = await firefoxCookieFn({ path: '/api' });\n * // Returns Firefox-format cookies: [{ name: 'token', value: 'def456', path: '/api' }, ...]\n * ```\n */\nexport const getFirefoxCookie = (): Promise<\n (cookieSpec: CookieSpec) => Promise<ExportedCookie[]>\n> => import(\"./getFirefoxCookie\").then((module) => module.getFirefoxCookie);\n\n/**\n * Dynamic import for retrieving grouped and rendered cookies.\n * @internal\n * @returns Promise resolving to the getGroupedRenderedCookies function\n * @example\n * ```typescript\n * const groupedCookiesFn = await getGroupedRenderedCookies();\n * const cookieStrings = await groupedCookiesFn({ domain: 'example.com' });\n * // Returns: ['sessionId=abc123; Domain=example.com', 'auth=xyz789; Domain=example.com']\n * ```\n */\nexport const getGroupedRenderedCookies = (): Promise<\n (cookieSpec: CookieSpec) => Promise<string[]>\n> =>\n import(\"./getGroupedRenderedCookies\").then(\n (module) => module.getGroupedRenderedCookies,\n );\n\n/**\n * Dynamic import for retrieving merged and rendered cookies.\n * @internal\n * @returns Promise resolving to the getMergedRenderedCookies function\n * @example\n * ```typescript\n * const mergedCookiesFn = await getMergedRenderedCookies();\n * const cookieString = await mergedCookiesFn(\n * { domain: 'example.com' },\n * { separator: '; ' }\n * );\n * // Returns: \"sessionId=abc123; auth=xyz789\"\n * ```\n */\nexport const getMergedRenderedCookies = (): Promise<\n (\n cookieSpec: CookieSpec,\n options?: Omit<RenderOptions, \"format\">,\n ) => Promise<string>\n> =>\n import(\"./getMergedRenderedCookies\").then(\n (module) => module.getMergedRenderedCookies,\n );\n"],"mappings":"4BAiBO,IAAMA,EAAY,IAEpB,OAAO,yBAAa,EAAE,KAAMC,GAAWA,EAAO,SAAS,EAa/CC,EAAkB,IAE1B,OAAO,+BAAmB,EAAE,KAAMD,GAAWA,EAAO,eAAe,EAa3DE,EAAmB,IAE3B,OAAO,gCAAoB,EAAE,KAAMF,GAAWA,EAAO,gBAAgB,EAa7DG,EAA4B,IAGvC,OAAO,yCAA6B,EAAE,KACnCH,GAAWA,EAAO,yBACrB,EAgBWI,EAA2B,IAMtC,OAAO,wCAA4B,EAAE,KAClCJ,GAAWA,EAAO,wBACrB","names":["getCookie","module","getChromeCookie","getFirefoxCookie","getGroupedRenderedCookies","getMergedRenderedCookies"]}
package/eslint.config.js CHANGED
@@ -6,7 +6,7 @@ import globals from "globals";
6
6
 
7
7
  export default [
8
8
  {
9
- ignores: ["dist/**/*", "node_modules/**/*"],
9
+ ignores: ["dist/**/*", "node_modules/**/*", "coverage/**/*"],
10
10
  },
11
11
  {
12
12
  files: ["**/*.js", "**/*.mjs"],
@@ -238,6 +238,7 @@ export default [
238
238
  rules: {
239
239
  "jsdoc/require-example": "off",
240
240
  "jsdoc/require-description": "off",
241
+ "max-lines-per-function": ["error", { max: 100 }],
241
242
  },
242
243
  },
243
244
  ];
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@mherod/get-cookie",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "Node.js module for querying a local user's Chrome cookie",
5
+ "packageManager": "pnpm@9.15.2",
5
6
  "type": "module",
6
7
  "source": "src/index.ts",
7
8
  "bin": {
@@ -24,6 +25,26 @@
24
25
  "publishConfig": {
25
26
  "access": "public"
26
27
  },
28
+ "scripts": {
29
+ "clean": "rm -rf dist",
30
+ "build:lib": "tsup --config tsup.lib.ts",
31
+ "build:cli": "tsup --config tsup.cli.ts",
32
+ "build": "pnpm run build:lib && pnpm run build:cli",
33
+ "test": "jest",
34
+ "type-check": "tsc --noEmit",
35
+ "lint": "eslint . --format=codeframe",
36
+ "lint:fix": "eslint . --format=codeframe --fix",
37
+ "validate": "pnpm run type-check && pnpm run lint && pnpm run test",
38
+ "prepack": "pnpm run validate",
39
+ "prepublishOnly": "pnpm run clean && pnpm run validate && pnpm run build",
40
+ "format": "prettier --write .",
41
+ "dev": "tsc -w -p tsconfig.json & tsc-alias -w -p tsconfig.json",
42
+ "read-github": "NODE_OPTIONS=\"-r tsconfig-paths/register\" tsx scripts/read-github-cookies.ts",
43
+ "prepare": "husky install",
44
+ "docs": "typedoc && ./scripts/fix-typedoc.sh && vitepress build docs",
45
+ "docs:dev": "vitepress dev docs",
46
+ "docs:preview": "vitepress preview docs"
47
+ },
27
48
  "engines": {
28
49
  "node": "^20.0.0 || ^22.0.0"
29
50
  },
@@ -86,22 +107,5 @@
86
107
  "*.{json,md,yml,yaml}": [
87
108
  "prettier --write"
88
109
  ]
89
- },
90
- "scripts": {
91
- "clean": "rm -rf dist",
92
- "build:lib": "tsup --config tsup.lib.ts",
93
- "build:cli": "tsup --config tsup.cli.ts",
94
- "build": "pnpm run build:lib && pnpm run build:cli",
95
- "test": "jest",
96
- "type-check": "tsc --noEmit",
97
- "lint": "eslint . --format=codeframe",
98
- "lint:fix": "eslint . --format=codeframe --fix",
99
- "validate": "pnpm run type-check && pnpm run lint && pnpm run test",
100
- "format": "prettier --write .",
101
- "dev": "tsc -w -p tsconfig.json & tsc-alias -w -p tsconfig.json",
102
- "read-github": "NODE_OPTIONS=\"-r tsconfig-paths/register\" tsx scripts/readGithubCookies.ts",
103
- "docs": "typedoc && ./scripts/fix-typedoc.sh && vitepress build docs",
104
- "docs:dev": "vitepress dev docs",
105
- "docs:preview": "vitepress preview docs"
106
110
  }
107
- }
111
+ }
package/typedoc.json CHANGED
@@ -1,12 +1,6 @@
1
1
  {
2
2
  "$schema": "https://typedoc.org/schema.json",
3
- "entryPoints": [
4
- "src/index.ts",
5
- "src/cli/cli.ts",
6
- "src/types/ExportedCookie.ts",
7
- "src/types/CookieSpec.ts",
8
- "src/types/CookieRender.ts"
9
- ],
3
+ "entryPoints": ["src/index.ts", "src/cli/cli.ts"],
10
4
  "out": "docs/reference",
11
5
  "plugin": ["typedoc-plugin-markdown"],
12
6
  "readme": "none",
@@ -18,5 +12,6 @@
18
12
  "excludeExternals": true,
19
13
  "includeVersion": true,
20
14
  "categorizeByGroup": true,
21
- "categoryOrder": ["Core", "Browsers", "CLI", "*"]
15
+ "categoryOrder": ["Core", "Browsers", "CLI", "*"],
16
+ "tsconfig": "tsconfig.json"
22
17
  }
@@ -1,2 +0,0 @@
1
- import{a as C,b as w}from"./chunk-5FUMK7M3.js";import{a as d,b as p,c,d as l,e as y}from"./chunk-56Z35D5R.js";async function k(r,e,o=[]){return r.length===0?o:(await Promise.all(r.map(async i=>{try{return await e(i)}catch(n){return o}}))).flat()}import{existsSync as T}from"fs";import{join as h}from"path";import L from"fast-glob";import{join as q}from"path";import{merge as D}from"lodash-es";var E={};D(E,process.env);var u=E.HOME;if(typeof u!="string"||u.length===0)throw new Error("HOME environment variable is not set or empty");var x,m=q((x=u)!=null?x:"","Library","Application Support","Google","Chrome");function M(r){if(typeof r!="string")return!1;let e=r.trim();return e.length===0?!1:T(e)}async function Q(){let r=[h(m,"Default/Cookies"),h(m,"Profile */Cookies"),h(m,"Profile Default/Cookies")],e=[];for(let o of r){let t=await L(o);e.push(...t)}return l("ChromeCookies","Found cookie files",{count:e.length,files:e}),e}function A(r,e){let o=r==="%",t=o?"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=o?[`%${e}%`]:[r,`%${e}%`];return{sql:t,params:i}}async function I(r,e,o){try{let{sql:t,params:i}=A(e,o);l("ChromeCookies","Executing query",{sql:t,params:i});let n=await C({file:r,sql:t,params:i,rowTransform:s=>({name:s.name,domain:s.host_key,value:s.encrypted_value,expiry:s.expires_utc})});return p("QueryCookies",!0,{file:r,count:n.length}),n}catch(t){return c("Failed to read cookie file",t,{file:r}),[]}}async function P({name:r,domain:e,file:o}){let t=typeof o=="string"&&o.length>0?[o]:await Q();if(t.length===0)return l("ChromeCookies","No cookie files found"),[];let i=[];for(let n of t){if(!M(n)){l("ChromeCookies","Cookie file missing or invalid",{file:n});continue}let s=await I(n,r,e);i.push(...s)}return l("ChromeCookies","Query complete",{totalCookies:i.length}),i}import{readFileSync as lr}from"fs";import{join as fr}from"path";var N=d.withTag("listChromeProfiles");function _(){let r=w("./**/Cookies",{cwd:m,absolute:!0});return N.debug("Found cookie files:",r),r}import{createDecipheriv as H,pbkdf2 as $}from"crypto";import{memoize as S}from"lodash-es";var U=S(r=>r.length>=3&&r[0]===118&&r[1]===49&&r[2]===48?r.slice(3):r,r=>r.toString("hex")),z=S(r=>{let e=r[r.length-1];return e&&e<=16?r.slice(0,-e):r},r=>r.toString("hex"));function G(r){var o;let e=[/.*?0t(.+)$/,/.*?1e`(.+)$/,/.*?[`'](.+)$/,/[^\x20-\x7E]*([\x20-\x7E].+)$/];for(let t of e){let i=r.match(t),n=(o=i==null?void 0:i[1])!=null?o:"";if(n.length>0)return n}return r}async function v(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((o,t)=>{$(e,"saltysalt",1003,16,"sha1",(i,n)=>{try{if(i){t(new Error("Failed to derive key: "+i.message));return}let s=U(r);if(s.length%16!==0){t(new Error("Encrypted data length is not a multiple of 16"));return}let f=Buffer.alloc(16," "),a=H("aes-128-cbc",n,f);a.setAutoPadding(!1);let g=a.update(s);try{a.final()}catch(O){t(new Error("Failed to finalize decryption: "+O.message));return}g=z(g);let B=g.toString("utf8");o(G(B))}catch(s){t(new Error("Decryption failed: "+s.message))}})})}import{memoize as W}from"lodash-es";var b=W(async()=>{if(process.platform!=="darwin")throw c("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-GTIXL733.js"),e=await r();return l("ChromePassword","Retrieved password successfully",{platform:"macOS"}),e}catch(r){throw c("Chrome password retrieval failed",r,{platform:"macOS"}),r}});function K(r){return typeof r!="number"||r<=0?"Infinity":new Date(r)}function R(r,e,o,t,i,n){return{domain:r,name:e,value:o,expiry:K(t),meta:{file:i,browser:"Chrome",decrypted:n}}}var F=class{constructor(){this.logger=y("ChromeCookieQueryStrategy");this.browserName="Chrome"}async queryCookies(e,o){try{if(this.logger.info("Querying cookies",{name:e,domain:o}),process.platform!=="darwin")return this.logger.warn("Platform not supported",{platform:process.platform}),[];let i=_().map(f=>f),n=await b(),s=await k(i,f=>this.processFile(f,e,o,n),[]);return p("Cookie query",!0,{count:s.length}),s}catch(t){return c("Failed to query cookies",t,{name:e,domain:o}),[]}}async processFile(e,o,t,i){try{let n=await P({name:o,domain:t,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 this.logger.error("Failed to process cookie file",{error:n,file:e}),[]}}async processCookie(e,o){try{let t=Buffer.isBuffer(e.value)?e.value:Buffer.from(String(e.value)),i=await v(t,o.password);return R(e.domain,e.name,i,e.expiry,o.file,!0)}catch(t){return this.logger.warn("Failed to decrypt cookie",{error:t}),R(e.domain,e.name,e.value.toString("utf-8"),e.expiry,o.file,!1)}}};export{F as a};
2
- //# sourceMappingURL=chunk-5ZT2G45S.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/flatMapAsync.ts","../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":["/**\n * Asynchronously maps over an array and flattens the result.\n * Similar to Array.prototype.flatMap but for async operations.\n * @param array - The input array to map over\n * @param callback - The async mapping function to apply to each element\n * @param defaultValue - The default value to return if the array is empty\n * @returns A flattened array of results\n * @example\n * // Basic usage with number arrays\n * const numbers = [1, 2, 3];\n * const result = await flatMapAsync(\n * numbers,\n * async (num) => [num, num * 2]\n * );\n * console.log(result); // [1, 2, 2, 4, 3, 6]\n * @example\n * // Error handling with default value\n * const data = ['valid', 'invalid'];\n * const result = await flatMapAsync(\n * data,\n * async (item) => {\n * if (item === 'invalid') throw new Error();\n * return [item.toUpperCase()];\n * },\n * ['DEFAULT']\n * );\n * console.log(result); // ['VALID', 'DEFAULT']\n */\nexport async function flatMapAsync<T, U>(\n array: T[],\n callback: (item: T) => Promise<U[]>,\n defaultValue: U[] = [],\n): Promise<U[]> {\n if (array.length === 0) {\n return defaultValue;\n }\n\n const results = await Promise.all(\n array.map(async (item) => {\n try {\n return await callback(item);\n } catch (_error) {\n return defaultValue;\n }\n }),\n );\n return results.flat();\n}\n","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/CookieRow\";\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 { flatMapAsync } from \"@utils/flatMapAsync\";\nimport {\n createTaggedLogger,\n logOperationResult,\n logError,\n} from \"@utils/logHelpers\";\n\nimport type { BrowserName } from \"../../../types/BrowserName\";\nimport type { CookieQueryStrategy } from \"../../../types/CookieQueryStrategy\";\nimport type { CookieRow } from \"../../../types/CookieRow\";\nimport type { ExportedCookie } from \"../../../types/ExportedCookie\";\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 */\nexport class ChromeCookieQueryStrategy implements CookieQueryStrategy {\n private readonly logger = createTaggedLogger(\"ChromeCookieQueryStrategy\");\n\n /**\n *\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 */\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 profilePaths = listChromeProfilePaths();\n const cookieFiles = profilePaths.map((path) => path);\n const password = await getChromePassword();\n\n const cookies = await flatMapAsync(\n cookieFiles,\n (file) => this.processFile(file, name, domain, password),\n [],\n );\n logOperationResult(\"Cookie query\", true, { count: cookies.length });\n return cookies;\n } catch (error) {\n logError(\"Failed to query cookies\", error, { name, domain });\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 this.logger.error(\"Failed to process cookie file\", { error, file });\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 this.logger.warn(\"Failed to decrypt cookie\", { error });\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":"8GA4BA,eAAsBA,EACpBC,EACAC,EACAC,EAAoB,CAAC,EACP,CACd,OAAIF,EAAM,SAAW,EACZE,GAGO,MAAM,QAAQ,IAC5BF,EAAM,IAAI,MAAOG,GAAS,CACxB,GAAI,CACF,OAAO,MAAMF,EAASE,CAAI,CAC5B,OAASC,EAAQ,CACf,OAAOF,CACT,CACF,CAAC,CACH,GACe,KAAK,CACtB,CC/CA,OAAS,cAAAG,MAAkB,KAC3B,OAAS,QAAAC,MAAY,OAErB,OAAOC,MAAU,YCHjB,OAAS,QAAAC,MAAY,OCArB,OAAS,SAAAC,MAAa,YAiBf,IAAMC,EAA6C,CAAC,EAC3DD,EAAMC,EAAK,QAAQ,GAAG,EAmBf,IAAMC,EAA2BD,EAAI,KAC5C,GAAI,OAAOC,GAAS,UAAYA,EAAK,SAAW,EAC9C,MAAM,IAAI,MAAM,+CAA+C,EDvCjE,IAAAC,EASaC,EAA2BC,GACtCF,EAAAG,IAAA,KAAAH,EAAQ,GACR,UACA,sBACA,SACA,QACF,EDoBA,SAASI,EAAgBC,EAA+B,CACtD,GAAI,OAAOA,GAAS,SAClB,MAAO,GAGT,IAAMC,EAAcD,EAAK,KAAK,EAC9B,OAAIC,EAAY,SAAW,EAClB,GAGFC,EAAWD,CAAW,CAC/B,CAMA,eAAeE,GAAoC,CACjD,IAAMC,EAAW,CACfC,EAAKC,EAA0B,iBAAiB,EAChDD,EAAKC,EAA0B,mBAAmB,EAClDD,EAAKC,EAA0B,yBAAyB,CAC1D,EAEMC,EAAkB,CAAC,EACzB,QAAWC,KAAWJ,EAAU,CAC9B,IAAMK,EAAU,MAAMC,EAAKF,CAAO,EAClCD,EAAM,KAAK,GAAGE,CAAO,CACvB,CAEA,OAAAE,EAAS,gBAAiB,qBAAsB,CAC9C,MAAOJ,EAAM,OACb,MAAAA,CACF,CAAC,EACMA,CACT,CAQA,SAASK,EAAcC,EAAcC,EAA0B,CAC7D,IAAMC,EAAaF,IAAS,IACtBG,EAAMD,EACR,yFACA,sGACEE,EAASF,EAAa,CAAC,IAAID,CAAM,GAAG,EAAI,CAACD,EAAM,IAAIC,CAAM,GAAG,EAElE,MAAO,CAAE,IAAAE,EAAK,OAAAC,CAAO,CACvB,CASA,eAAeC,EACbC,EACAN,EACAC,EACsB,CACtB,GAAI,CACF,GAAM,CAAE,IAAAE,EAAK,OAAAC,CAAO,EAAIL,EAAcC,EAAMC,CAAM,EAClDH,EAAS,gBAAiB,kBAAmB,CAAE,IAAAK,EAAK,OAAAC,CAAO,CAAC,EAE5D,IAAMG,EAAO,MAAMC,EAAqD,CACtE,KAAMF,EACN,IAAAH,EACA,OAAAC,EACA,aAAeK,IAAqC,CAClD,KAAMA,EAAI,KACV,OAAQA,EAAI,SACZ,MAAOA,EAAI,gBACX,OAAQA,EAAI,WACd,EACF,CAAC,EAED,OAAAC,EAAmB,eAAgB,GAAM,CACvC,KAAMJ,EACN,MAAOC,EAAK,MACd,CAAC,EACMA,CACT,OAASI,EAAO,CACd,OAAAC,EAAS,6BAA8BD,EAAO,CAAE,KAAML,CAAW,CAAC,EAC3D,CAAC,CACV,CACF,CAUA,eAAsBO,EAAyB,CAC7C,KAAAb,EACA,OAAAC,EACA,KAAAa,CACF,EAAoD,CAClD,IAAMC,EACJ,OAAOD,GAAS,UAAYA,EAAK,OAAS,EACtC,CAACA,CAAI,EACL,MAAMxB,EAAe,EAE3B,GAAIyB,EAAY,SAAW,EACzB,OAAAjB,EAAS,gBAAiB,uBAAuB,EAC1C,CAAC,EAGV,IAAMkB,EAAuB,CAAC,EAC9B,QAAWV,KAAcS,EAAa,CACpC,GAAI,CAAC7B,EAAgBoB,CAAU,EAAG,CAChCR,EAAS,gBAAiB,iCAAkC,CAC1D,KAAMQ,CACR,CAAC,EACD,QACF,CAEA,IAAMW,EAAU,MAAMZ,EAAkBC,EAAYN,EAAMC,CAAM,EAChEe,EAAQ,KAAK,GAAGC,CAAO,CACzB,CAEA,OAAAnB,EAAS,gBAAiB,iBAAkB,CAAE,aAAckB,EAAQ,MAAO,CAAC,EACrEA,CACT,CGpKA,OAAS,gBAAAE,OAAoB,KAC7B,OAAS,QAAAC,OAAY,OASrB,IAAMC,EAAUC,EAAO,QAAQ,oBAAoB,EAwB5C,SAASC,GAAmC,CACjD,IAAMC,EAAkBC,EAAK,eAAgB,CAC3C,IAAKC,EACL,SAAU,EACZ,CAAC,EAED,OAAAL,EAAQ,MAAM,sBAAuBG,CAAK,EACnCA,CACT,CC1CA,OAAS,oBAAAG,EAAkB,UAAAC,MAAc,SAEzC,OAAS,WAAAC,MAAe,YAOxB,IAAMC,EAAkBD,EACrBE,GAEGA,EAAM,QAAU,GAChBA,EAAM,CAAC,IAAM,KACbA,EAAM,CAAC,IAAM,IACbA,EAAM,CAAC,IAAM,GAGNA,EAAM,MAAM,CAAC,EAEfA,EAERA,GAAkBA,EAAM,SAAS,KAAK,CACzC,EAOMC,EAAgBH,EACnBI,GAA8B,CAC7B,IAAMC,EAAUD,EAAUA,EAAU,OAAS,CAAC,EAC9C,OAAIC,GAAWA,GAAW,GACjBD,EAAU,MAAM,EAAG,CAACC,CAAO,EAE7BD,CACT,EACCA,GAAsBA,EAAU,SAAS,KAAK,CACjD,EAOA,SAASE,EAAaC,EAA+B,CA/CrD,IAAAC,EAgDE,IAAMC,EAAkB,CACtB,aACA,cACA,eACA,+BACF,EAEA,QAAWC,KAAWD,EAAiB,CACrC,IAAME,EAAQJ,EAAc,MAAMG,CAAO,EACnCR,GAAQM,EAAAG,GAAA,YAAAA,EAAQ,KAAR,KAAAH,EAAc,GAC5B,GAAIN,EAAM,OAAS,EACjB,OAAOA,CAEX,CACA,OAAOK,CACT,CAUA,eAAsBK,EACpBC,EACAC,EACiB,CACjB,GAAI,OAAOA,GAAa,SACtB,MAAM,IAAI,MAAM,2BAA2B,EAE7C,GAAI,CAAC,OAAO,SAASD,CAAc,EACjC,MAAM,IAAI,MAAM,gCAAgC,EAGlD,OAAO,IAAI,QAAQ,CAACE,EAASC,IAAW,CACtCjB,EAAOe,EAAU,YAAa,KAAM,GAAI,OAAQ,CAACG,EAAOC,IAAQ,CAC9D,GAAI,CACF,GAAID,EAAO,CACTD,EAAO,IAAI,MAAM,yBAA2BC,EAAM,OAAO,CAAC,EAC1D,MACF,CAEA,IAAMf,EAAQD,EAAgBY,CAAc,EAC5C,GAAIX,EAAM,OAAS,KAAO,EAAG,CAC3Bc,EAAO,IAAI,MAAM,+CAA+C,CAAC,EACjE,MACF,CAGA,IAAMG,EAAK,OAAO,MAAM,GAAI,GAAG,EACzBC,EAAWtB,EAAiB,cAAeoB,EAAKC,CAAE,EACxDC,EAAS,eAAe,EAAK,EAG7B,IAAIhB,EAAYgB,EAAS,OAAOlB,CAAK,EACrC,GAAI,CACFkB,EAAS,MAAM,CACjB,OAASC,EAAG,CACVL,EACE,IAAI,MAAM,kCAAqCK,EAAY,OAAO,CACpE,EACA,MACF,CAEAjB,EAAYD,EAAcC,CAAS,EACnC,IAAMG,EAAgBH,EAAU,SAAS,MAAM,EAC/CW,EAAQT,EAAaC,CAAa,CAAC,CACrC,OAASc,EAAG,CACVL,EAAO,IAAI,MAAM,sBAAyBK,EAAY,OAAO,CAAC,CAChE,CACF,CAAC,CACH,CAAC,CACH,CC1HA,OAAS,WAAAC,MAAe,YAWjB,IAAMC,EAA2CC,EAAQ,SAAY,CAC1E,GAAI,QAAQ,WAAa,SACvB,MAAAC,EACE,mCACA,IAAI,MAAM,0BAA0B,EACpC,CACE,SAAU,QAAQ,QACpB,CACF,EACM,IAAI,MAAM,0BAA0B,EAG5C,GAAI,CACF,GAAM,CAAE,kBAAmBC,CAAiB,EAAI,KAAM,QACpD,iCACF,EACMC,EAAW,MAAMD,EAAiB,EACxC,OAAAE,EAAS,iBAAkB,kCAAmC,CAC5D,SAAU,OACZ,CAAC,EACMD,CACT,OAASE,EAAO,CACd,MAAAJ,EAAS,mCAAoCI,EAAO,CAAE,SAAU,OAAQ,CAAC,EACnEA,CACR,CACF,CAAC,ECdD,SAASC,EAAcC,EAAsD,CAC3E,OAAI,OAAOA,GAAW,UAAYA,GAAU,EACnC,WAEF,IAAI,KAAKA,CAAM,CACxB,CAEA,SAASC,EACPC,EACAC,EACAC,EACAJ,EACAK,EACAC,EACgB,CAChB,MAAO,CACL,OAAAJ,EACA,KAAAC,EACA,MAAAC,EACA,OAAQL,EAAcC,CAAM,EAC5B,KAAM,CACJ,KAAAK,EACA,QAAS,SACT,UAAAC,CACF,CACF,CACF,CAMO,IAAMC,EAAN,KAA+D,CAA/D,cACL,KAAiB,OAASC,EAAmB,2BAA2B,EAKxE,KAAgB,YAA2B,SAQ3C,MAAa,aACXL,EACAD,EAC2B,CAC3B,GAAI,CAGF,GAFA,KAAK,OAAO,KAAK,mBAAoB,CAAE,KAAAC,EAAM,OAAAD,CAAO,CAAC,EAEjD,QAAQ,WAAa,SACvB,YAAK,OAAO,KAAK,yBAA0B,CACzC,SAAU,QAAQ,QACpB,CAAC,EACM,CAAC,EAIV,IAAMO,EADeC,EAAuB,EACX,IAAKC,GAASA,CAAI,EAC7CC,EAAW,MAAMC,EAAkB,EAEnCC,EAAU,MAAMC,EACpBN,EACCJ,GAAS,KAAK,YAAYA,EAAMF,EAAMD,EAAQU,CAAQ,EACvD,CAAC,CACH,EACA,OAAAI,EAAmB,eAAgB,GAAM,CAAE,MAAOF,EAAQ,MAAO,CAAC,EAC3DA,CACT,OAASG,EAAO,CACd,OAAAC,EAAS,0BAA2BD,EAAO,CAAE,KAAAd,EAAM,OAAAD,CAAO,CAAC,EACpD,CAAC,CACV,CACF,CAEA,MAAc,YACZG,EACAF,EACAD,EACAU,EAC2B,CAC3B,GAAI,CACF,IAAMO,EAAmB,MAAMC,EAAyB,CACtD,KAAAjB,EACA,OAAAD,EACA,KAAAG,CACF,CAAC,EAEKgB,EAA6B,CAAE,KAAAhB,EAAM,SAAAO,CAAS,EAKpD,OAJgB,MAAM,QAAQ,WAC5BO,EAAiB,IAAKG,GAAW,KAAK,cAAcA,EAAQD,CAAO,CAAC,CACtE,GAGG,IAAKE,GAAYA,EAAO,SAAW,YAAcA,EAAO,MAAQ,IAAK,EACrE,OAAQD,GAAqCA,IAAW,IAAI,CACjE,OAASL,EAAO,CACd,YAAK,OAAO,MAAM,gCAAiC,CAAE,MAAAA,EAAO,KAAAZ,CAAK,CAAC,EAC3D,CAAC,CACV,CACF,CAEA,MAAc,cACZiB,EACAD,EACyB,CACzB,GAAI,CACF,IAAMjB,EAAQ,OAAO,SAASkB,EAAO,KAAK,EACtCA,EAAO,MACP,OAAO,KAAK,OAAOA,EAAO,KAAK,CAAC,EAE9BE,EAAiB,MAAMC,EAAQrB,EAAOiB,EAAQ,QAAQ,EAC5D,OAAOpB,EACLqB,EAAO,OACPA,EAAO,KACPE,EACAF,EAAO,OACPD,EAAQ,KACR,EACF,CACF,OAASJ,EAAO,CACd,YAAK,OAAO,KAAK,2BAA4B,CAAE,MAAAA,CAAM,CAAC,EAC/ChB,EACLqB,EAAO,OACPA,EAAO,KACPA,EAAO,MAAM,SAAS,OAAO,EAC7BA,EAAO,OACPD,EAAQ,KACR,EACF,CACF,CACF,CACF","names":["flatMapAsync","array","callback","defaultValue","item","_error","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","path","password","getChromePassword","cookies","flatMapAsync","logOperationResult","error","logError","encryptedCookies","getEncryptedChromeCookie","context","cookie","result","decryptedValue","decrypt"]}
@@ -1,2 +0,0 @@
1
- import{groupBy as a}from"lodash-es";function f(o,p={}){let{format:n="merged",showFilePaths:m=!0,separator:i="; "}=p;if(o.length===0)return n==="merged"?"":[];if(n==="merged")return o.map(e=>e.value).join(i);let s=a(o,e=>{var t,r;return(r=(t=e.meta)==null?void 0:t.file)!=null?r:"unknown"});return Object.entries(s).map(([e,t])=>{let r=t.map(u=>u.value).join(i);return m?`${e}: ${r}`:r})}export{f as a};
2
- //# sourceMappingURL=chunk-FR2MKDHT.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/cookies/renderCookies.ts"],"sourcesContent":["import { groupBy } from \"lodash-es\";\n\nimport type { RenderOptions } from \"../../types/CookieRender\";\nimport type { ExportedCookie } from \"../../types/ExportedCookie\";\n\n/**\n * Renders cookies as a string or array of strings based on the provided format option.\n * Supports merged format for single string output or grouped format for file-based grouping.\n * @param cookies - The cookies to render\n * @param options - Options for rendering\n * @param options.format - The output format ('merged' or 'grouped')\n * @param options.showFilePaths - Whether to include file paths in grouped output\n * @param options.separator - Custom separator for cookie values\n * @returns A string for merged format, or array of strings for grouped format\n * @example\n * ```typescript\n * // Merged format (default)\n * const cookies = [\n * { value: 'sessionId=abc123' },\n * { value: 'theme=dark' }\n * ];\n * renderCookies(cookies);\n * // Returns: \"sessionId=abc123; theme=dark\"\n *\n * // Grouped format with file paths\n * const groupedCookies = [\n * { value: 'sessionId=abc123', meta: { file: 'auth.ts' } },\n * { value: 'theme=dark', meta: { file: 'preferences.ts' } }\n * ];\n * renderCookies(groupedCookies, { format: 'grouped', showFilePaths: true });\n * // Returns: [\"auth.ts: sessionId=abc123\", \"preferences.ts: theme=dark\"]\n * ```\n */\nexport function renderCookies(\n cookies: ExportedCookie[],\n options: RenderOptions = {},\n): string | string[] {\n const { format = \"merged\", showFilePaths = true, separator = \"; \" } = options;\n\n if (cookies.length === 0) {\n return format === \"merged\" ? \"\" : [];\n }\n\n if (format === \"merged\") {\n return cookies.map((c) => c.value).join(separator);\n }\n\n const groupedByFile = groupBy(cookies, (c) => c.meta?.file ?? \"unknown\");\n return Object.entries(groupedByFile).map(([file, fileCookies]) => {\n const values = fileCookies.map((c) => c.value).join(separator);\n return showFilePaths ? `${file}: ${values}` : values;\n });\n}\n"],"mappings":"AAAA,OAAS,WAAAA,MAAe,YAiCjB,SAASC,EACdC,EACAC,EAAyB,CAAC,EACP,CACnB,GAAM,CAAE,OAAAC,EAAS,SAAU,cAAAC,EAAgB,GAAM,UAAAC,EAAY,IAAK,EAAIH,EAEtE,GAAID,EAAQ,SAAW,EACrB,OAAOE,IAAW,SAAW,GAAK,CAAC,EAGrC,GAAIA,IAAW,SACb,OAAOF,EAAQ,IAAKK,GAAMA,EAAE,KAAK,EAAE,KAAKD,CAAS,EAGnD,IAAME,EAAgBR,EAAQE,EAAUK,GAAG,CA/C7C,IAAAE,EAAAC,EA+CgD,OAAAA,GAAAD,EAAAF,EAAE,OAAF,YAAAE,EAAQ,OAAR,KAAAC,EAAgB,UAAS,EACvE,OAAO,OAAO,QAAQF,CAAa,EAAE,IAAI,CAAC,CAACG,EAAMC,CAAW,IAAM,CAChE,IAAMC,EAASD,EAAY,IAAKL,GAAMA,EAAE,KAAK,EAAE,KAAKD,CAAS,EAC7D,OAAOD,EAAgB,GAAGM,CAAI,KAAKE,CAAM,GAAKA,CAChD,CAAC,CACH","names":["groupBy","renderCookies","cookies","options","format","showFilePaths","separator","c","groupedByFile","_a","_b","file","fileCookies","values"]}
@@ -1,2 +0,0 @@
1
- import{a as p,b as l}from"./chunk-5FUMK7M3.js";import{d as m,f as n}from"./chunk-56Z35D5R.js";import{join as c}from"path";function u(){let o=[],e=process.env.HOME;if(typeof e!="string"||e.length===0)return n("FirefoxCookieQuery","HOME environment variable not set"),o;let a=[c(e,"Library/Application Support/Firefox/Profiles/*/cookies.sqlite"),c(e,".mozilla/firefox/*/cookies.sqlite")];for(let f of a){let i=l(f);o.push(...i)}return m("FirefoxCookieQuery","Found Firefox cookie files",{files:o}),o}var y=class{constructor(){this.browserName="Firefox"}async queryCookies(e,a){let f=u(),i=[];for(let t of f)try{let s=await p({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(...s)}catch(s){s instanceof Error?n("FirefoxCookieQuery",`Error reading Firefox cookie file ${t}`,{error:s.message}):n("FirefoxCookieQuery",`Error reading Firefox cookie file ${t}`)}return i}};export{y as a};
2
- //# sourceMappingURL=chunk-HMKSQBDC.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 type { BrowserName } from \"../../../types/BrowserName\";\nimport type { CookieQueryStrategy } from \"../../../types/CookieQueryStrategy\";\nimport type { ExportedCookie } from \"../../../types/ExportedCookie\";\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,OAsBrB,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{a as i}from"./chunk-5ZT2G45S.js";import{a as p}from"./chunk-HMKSQBDC.js";import{a as t}from"./chunk-56Z35D5R.js";async function s(r){let o=[new i,new p];return(await Promise.allSettled(o.map(e=>e.queryCookies(r.name,r.domain)))).filter(e=>e.status==="fulfilled").flatMap(e=>e.value)}async function m(r){try{return await s(r)}catch(o){return t.warn("Error querying cookies:",o instanceof Error?o.message:String(o)),[]}}var l=m;export{m as a,l as b};
2
- //# sourceMappingURL=chunk-W3JALMAX.js.map