chrome-tools 1.1.11 → 1.1.12

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.
@@ -1,4 +1,13 @@
1
1
  import { type BrowserDescriptor } from "./browsers.js";
2
+ /**
3
+ * Resolves the Cookies database for a Chromium profile.
4
+ *
5
+ * Current Chromium releases keep it under `Network/Cookies`; older releases
6
+ * and a few Chromium-based browsers used `<profile>/Cookies`. Prefer the
7
+ * current location when both exist, while retaining compatibility with the
8
+ * legacy layout.
9
+ */
10
+ export declare function resolveCookiesDatabasePath(profilePath: string): string;
2
11
  export interface DiscoveredProfile {
3
12
  name: string;
4
13
  path: string;
@@ -12,9 +12,22 @@ const PROFILE_INDICATORS = [
12
12
  "Local Storage",
13
13
  "Preferences",
14
14
  ];
15
+ /**
16
+ * Resolves the Cookies database for a Chromium profile.
17
+ *
18
+ * Current Chromium releases keep it under `Network/Cookies`; older releases
19
+ * and a few Chromium-based browsers used `<profile>/Cookies`. Prefer the
20
+ * current location when both exist, while retaining compatibility with the
21
+ * legacy layout.
22
+ */
23
+ export function resolveCookiesDatabasePath(profilePath) {
24
+ const networkPath = join(profilePath, "Network", "Cookies");
25
+ return existsSync(networkPath) ? networkPath : join(profilePath, "Cookies");
26
+ }
15
27
  /** True when `dir` looks like a Chromium profile (has at least one indicator). */
16
28
  function isProfileDirectory(dir) {
17
- return PROFILE_INDICATORS.some((file) => existsSync(join(dir, file)));
29
+ return PROFILE_INDICATORS.some((file) => existsSync(join(dir, file))) ||
30
+ existsSync(resolveCookiesDatabasePath(dir));
18
31
  }
19
32
  /**
20
33
  * Returns the default Chrome User Data directory for the current OS.
@@ -70,6 +83,11 @@ export function discoverProfiles(chromeDir) {
70
83
  for (const entry of entries) {
71
84
  if (!entry.isDirectory())
72
85
  continue;
86
+ // `Network` belongs to its containing profile. Because it may hold a
87
+ // legacy-looking `Cookies` indicator directly, treating it as a profile
88
+ // would return `<profile>/Network` instead of the actual profile root.
89
+ if (entry.name === "Network")
90
+ continue;
73
91
  const profilePath = join(dir, entry.name);
74
92
  if (isProfileDirectory(profilePath)) {
75
93
  profiles.push({ name: entry.name, path: profilePath });
@@ -149,6 +167,7 @@ export function getProfileStates(chromeDir) {
149
167
  for (const file of PROFILE_INDICATORS) {
150
168
  dataFiles[file.replace(/\s+/g, "_").toLowerCase()] = existsSync(join(profilePath, file));
151
169
  }
170
+ dataFiles.cookies = existsSync(resolveCookiesDatabasePath(profilePath));
152
171
  // Additional files
153
172
  dataFiles.top_sites = existsSync(join(profilePath, "Top Sites"));
154
173
  dataFiles.extensions = existsSync(join(profilePath, "Extensions"));
@@ -1,6 +1,6 @@
1
- import { join } from "node:path";
1
+ import { existsSync } from "node:fs";
2
2
  import { createHash } from "node:crypto";
3
- import { resolveTargetProfiles } from "../core/chrome.js";
3
+ import { resolveCookiesDatabasePath, resolveTargetProfiles, } from "../core/chrome.js";
4
4
  import { deriveEncryptionKey, decryptValueBuffer } from "../core/platform/index.js";
5
5
  import { chromeTimeToDate } from "../core/crypto.js";
6
6
  import { queryDatabase } from "../core/db.js";
@@ -88,8 +88,11 @@ export function getCookies({ chromeDir, profilePath, profile, browser, domain, u
88
88
  const results = [];
89
89
  const parsedUrl = parseURL(url);
90
90
  const rowLimit = normalizeLimit(limit);
91
+ let firstReadError;
91
92
  for (const p of profiles) {
92
- const dbPath = join(p.path, "Cookies");
93
+ const dbPath = resolveCookiesDatabasePath(p.path);
94
+ if (!existsSync(dbPath))
95
+ continue;
93
96
  try {
94
97
  let sql = `SELECT host_key, name, value, encrypted_value, path,
95
98
  expires_utc, is_secure, is_httponly, samesite,
@@ -143,10 +146,13 @@ export function getCookies({ chromeDir, profilePath, profile, browser, domain, u
143
146
  });
144
147
  }
145
148
  }
146
- catch {
147
- // Skip profiles with errors
149
+ catch (error) {
150
+ firstReadError ??= new Error(`Could not read cookies for profile "${p.name}" at ${dbPath}: ` +
151
+ (error instanceof Error ? error.message : String(error)));
148
152
  }
149
153
  }
154
+ if (results.length === 0 && firstReadError)
155
+ throw firstReadError;
150
156
  return limitResults(results, limit);
151
157
  }
152
158
  export const _test = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-tools",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "CLI & Node.js library for chrome",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",