chrome-tools 1.1.9 → 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,7 +47,14 @@ export function queryDatabase(dbFilePath, sql, params = []) {
47
47
  sourceDb = new Database(dbFilePath, {
48
48
  readonly: true,
49
49
  fileMustExist: true,
50
- timeout: 5000,
50
+ // No wait. A running Chrome holds these stores in `locking_mode =
51
+ // EXCLUSIVE` for as long as it is open, so a busy timeout here buys
52
+ // nothing that waiting longer would win — the lock is not transient, and
53
+ // the copy below is the answer to it either way. Five seconds *per store*
54
+ // was the whole cost of reading a saved login while the browser was up:
55
+ // two stores, ten seconds, spent to arrive at the fallback that then
56
+ // succeeded instantly.
57
+ timeout: 0,
51
58
  });
52
59
  sourceDb.prepare("VACUUM INTO ?").run(tmpDb);
53
60
  }
@@ -160,7 +160,21 @@ export function getPasswords({ chromeDir, profilePath, profile, search, browser,
160
160
  const rows = queryDatabase(dbPath, `SELECT origin_url, username_value, password_value, date_last_used
161
161
  FROM logins ORDER BY origin_url`);
162
162
  for (const row of rows) {
163
- const entry = {
163
+ // Matched before anything is decrypted. Both columns the search
164
+ // looks at — the origin and the username — are stored in the clear,
165
+ // so a row that cannot match never needs its password read at all.
166
+ //
167
+ // Decrypting first cost one platform decryption per stored login on
168
+ // the way to finding one: a store with a few hundred entries spent
169
+ // upwards of ten seconds answering "what is the password for this
170
+ // one site", and every one of those decryptions was thrown away by
171
+ // the filter immediately below.
172
+ if (term &&
173
+ !(row.origin_url && row.origin_url.toLowerCase().includes(term)) &&
174
+ !(row.username_value && row.username_value.toLowerCase().includes(term))) {
175
+ continue;
176
+ }
177
+ results.push({
164
178
  profile: p.name,
165
179
  source: store.source,
166
180
  url: row.origin_url,
@@ -169,14 +183,7 @@ export function getPasswords({ chromeDir, profilePath, profile, search, browser,
169
183
  ? decryptValue(row.password_value, derivedKey ??= deriveEncryptionKey(root, browser))
170
184
  : "",
171
185
  lastUsed: chromeTimeToDate(row.date_last_used || 0),
172
- };
173
- if (term) {
174
- if (!(entry.url && entry.url.toLowerCase().includes(term)) &&
175
- !(entry.username && entry.username.toLowerCase().includes(term))) {
176
- continue;
177
- }
178
- }
179
- results.push(entry);
186
+ });
180
187
  }
181
188
  }
182
189
  catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-tools",
3
- "version": "1.1.9",
3
+ "version": "1.1.10",
4
4
  "description": "CLI & Node.js library for chrome",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",