chrome-tools 1.1.2 → 1.1.3
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.
package/README.md
CHANGED
package/dist/bin/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{readFileSync as o,existsSync as e}from"node:fs";import{join as r}from"node:path";import{Command as t}from"commander";import s from"chalk";import i from"cli-table3";import{discoverProfiles as n,getProfileMetadata as l,getProfileStates as a,getDirectorySize as c,detectInstalledBrowsers as d}from"../src/core/chrome.js";import{setActiveBrowser as m,getActiveBrowser as p}from"../src/core/platform/index.js";import{getPasswords as f}from"../src/modules/passwords.js";import{getBookmarks as h}from"../src/modules/bookmarks.js";import{getHistory as u,getSearchTerms as g}from"../src/modules/history.js";import{getCookies as w}from"../src/modules/cookies.js";import{getAutofillEntries as b,getCreditCards as y,getAddresses as S}from"../src/modules/autofill.js";import{getDownloads as v}from"../src/modules/downloads.js";import{getExtensions as k}from"../src/modules/extensions.js";import{getSearchEngines as L}from"../src/modules/search-engines.js";import{getTopSites as P}from"../src/modules/top-sites.js";const D=function(){const t={...process.env},s=r(process.cwd(),".env");if(e(s))try{const e=o(s,"utf8");for(const o of e.split(/\r?\n/)){const e=o.trim();if(!e||e.startsWith("#"))continue;const r=e.indexOf("=");if(-1!==r){const o=e.substring(0,r).trim();let s=e.substring(r+1).trim();(s.startsWith('"')&&s.endsWith('"')||s.startsWith("'")&&s.endsWith("'"))&&(s=s.slice(1,-1)),t[o]=s}}}catch{}return t}(),j=D.PROFILE_PATH||void 0,B=D.PROFILE_NAME||void 0,C=D.BROWSER||D.CHROME_BROWSER||void 0;function N(o){console.log(JSON.stringify(o,null,2))}function R(o,e){return new i({head:o.map(o=>s.bold.white(o)),colWidths:e,wordWrap:!0,style:{border:["grey"],head:[]}})}function U(o,e){0===e?console.log(s.yellow(`\n⚠ No ${o} found.\n`)):console.log(s.green(`\n✔ Found ${e} ${o}.\n`))}let $=null;function E(o,e){return $?($.push({browser:p().name,results:e}),!0):!!o.json&&(N(e),!0)}function O(o){const e=o.optsWithGlobals(),r=Boolean(e.browser)||Boolean(e.allBrowsers)||Boolean(C);return e.browser=e.browser||C||void 0,e.profilePath||(e.profilePath=r?void 0:j),e.profile||(e.profile=r?void 0:B),e}function x(o,e){e.allBrowsers?function(o,e){const r=d();if(0===r.length)return e.json?N([]):void console.log(s.yellow("\n⚠ No supported Chromium browsers found on this machine.\n"));const t={...e,profilePath:void 0};if(e.json){$=[];try{for(const e of r){m(e.browser.id);try{o(t)}catch(o){$.push({browser:e.browser.name,results:{error:o?.message??String(o)}})}}N($)}finally{$=null}}else for(const e of r){m(e.browser.id),console.log(s.bold.magenta(`\n══════════ ${e.browser.name} ══════════`));try{o(t)}catch(o){console.log(s.red(` ⚠ Skipped: ${o?.message??String(o)}`))}}}(o,e):(m(e.browser),o(e))}function F(o){const e=d({includeMissing:!0});if(o.json)return N(e.map(o=>({id:o.browser.id,name:o.browser.name,installed:o.installed,profileCount:o.profileCount,path:o.chromeDir,safeStorageLabel:o.browser.safeStorageLabel})));const r=e.filter(o=>o.installed);console.log(s.bold(`\n🌐 Supported browsers (${r.length} installed):\n`));const t=R(["Browser","Id","Installed","Profiles","Path"],[20,14,11,9,50]);for(const o of e)t.push([s.white(o.browser.name),s.cyan(o.browser.id),o.installed?s.green("✓"):s.dim("✗"),o.installed?s.yellow(String(o.profileCount)):s.dim("—"),s.dim(o.chromeDir)]);console.log(t.toString())}function W(o){return o.option("--profile-path <path>","Custom browser User Data Path (overrides --browser)").option("--profile <name>","Target a specific profile").option("--browser <name>","Browser to read (chrome, edge, brave, comet, vivaldi, opera, chromium…)").option("--all-browsers","Read from every installed Chromium browser").option("--json","Output as JSON")}function M(o){return o.option("--search <term>","Filter results (case-insensitive)")}function T(o,e=100){return o.option("--limit <n>","Limit number of results",String(e))}const A=new t,I=JSON.parse(o(new URL("../../package.json",import.meta.url),"utf8"));A.name("chrome-tools").description(s.bold.cyan("Chrome Data Toolkit")+s.dim(" — Extract passwords, bookmarks, history, cookies, and more from Chrome on macOS, Windows, and Linux")).version(I.version).option("--passwords","Shortcut: list saved passwords").option("--bookmarks","Shortcut: list bookmarks").option("--profiles","Shortcut: list profiles").option("--browsers","Shortcut: list supported / installed browsers").option("--size","Show each profile's size on disk when listing profiles (slower)").option("--profile-path <path>","Custom browser User Data Path (overrides --browser)").option("--profile <name>","Target a specific profile").option("--browser <name>","Browser to read (chrome, edge, brave, comet, vivaldi, opera, chromium…)").option("--all-browsers","Read from every installed Chromium browser").option("--json","Output as JSON").option("--search <term>","Filter results (for shortcut flags)").option("--limit <n>","Limit results (for shortcut flags)").action((o,e)=>{const r=O(e);r.browsers?F(r):r.passwords?x(H,r):r.bookmarks?x(G,r):x(V,r)});const z=A.command("profiles").description("List Chrome profiles");W(z).option("--size","Compute and show each profile's size on disk (slower)").action((o,e)=>{x(V,O(e))});W(z.command("states").description("Show detailed profile states with available data files")).action((o,e)=>x(J,O(e)));function V(o){const e=n(o.profilePath),r=l(o.profilePath),t=Boolean(o.size);if(o.json){const s=new Map(r.map(o=>[o.directory,o]));return void E(o,e.map(o=>({...o,...s.get(o.name)||{},...t?{sizeBytes:c(o.path)}:{}})))}if(0===e.length)return void console.log(s.yellow("\n⚠ No Chrome profiles found.\n"));const i=new Map(r.map(o=>[o.directory,o]));console.log(s.bold(`\n📁 Discovered ${e.length} profile(s):\n`));const a=R(t?["Directory","Display Name","Email","Size","Path"]:["Directory","Display Name","Email","Path"],t?[16,22,30,10,42]:[16,22,30,50]);for(const o of e){const e=i.get(o.name)||{},r=[s.cyan(o.name),s.white(e.name||o.name),s.dim(e.email||"—")];t&&r.push(s.yellow(_(c(o.path)))),r.push(s.dim(o.path)),a.push(r)}console.log(a.toString()),U("profile(s)",e.length)}function J(o){const e=a(o.profilePath);if(o.json)E(o,e);else if(0!==e.length){console.log(s.bold(`\n📊 Profile States (${e.length} profile(s)):\n`));for(const o of e){console.log(s.bold.cyan(` ${o.displayName}`)+s.dim(` (${o.directory})`)),o.email&&console.log(s.dim(` Email: ${o.email}`)),console.log(s.dim(` Path: ${o.path}`));const e=o.dataFiles,r=Object.entries(e).filter(([,o])=>o).map(([o])=>o),t=Object.entries(e).filter(([,o])=>!o).map(([o])=>o);console.log(` Available: ${r.map(o=>s.green(o)).join(", ")||s.dim("none")}`),t.length>0&&console.log(` Missing: ${t.map(o=>s.dim(o)).join(", ")}`),console.log()}}else console.log(s.yellow("\n⚠ No Chrome profiles found.\n"))}A.command("browsers").description("List supported browsers and detect which are installed").option("--json","Output as JSON").action((o,e)=>F(O(e)));function H(o){const e=f({chromeDir:o.profilePath,profile:o.profile,search:o.search});if(E(o,e))return;if(0===e.length)return U("passwords",0);console.log(s.bold("\n🔑 Saved Passwords:\n"));const r=new Set(e.map(o=>o.profile)).size>1,t=R(r?["Profile","URL","Username","Password","Last Used"]:["URL","Username","Password","Last Used"],r?[12,40,24,22,20]:[45,28,25,22]);for(const o of e){const e=[s.cyan(o.url),s.green(o.username||"<empty>"),s.yellow(o.password||"<empty>"),s.dim(o.lastUsed)];r&&e.unshift(s.magenta(o.profile)),t.push(e)}console.log(t.toString()),U("password(s)",e.length)}M(W(A.command("passwords").description("List saved passwords"))).action((o,e)=>x(H,O(e)));function G(o){const e=h({chromeDir:o.profilePath,profile:o.profile,folder:o.folder,search:o.search});if(E(o,e))return;if(0===e.length)return U("bookmarks",0);console.log(s.bold("\n📚 Bookmarks:\n"));const r=R(["Title","URL","Folder","Date Added"],[30,50,25,20]);for(const o of e)r.push([s.white(o.title),s.cyan(o.url),s.dim(o.folder||"/"),s.dim(o.dateAdded)]);console.log(r.toString()),U("bookmark(s)",e.length)}M(W(A.command("bookmarks").description("List bookmarks"))).option("--folder <name>","Filter by folder name").action((o,e)=>x(G,O(e)));M(T(W(A.command("history").description("List browsing history")))).action((o,e)=>x(o=>{const e=u({chromeDir:o.profilePath,profile:o.profile,search:o.search,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return U("history entries",0);console.log(s.bold("\n🕐 Browsing History:\n"));const r=R(["URL","Title","Visits","Last Visit"],[50,30,8,22]);for(const o of e)r.push([s.cyan(o.url),s.white(o.title||"—"),s.yellow(String(o.visitCount)),s.dim(o.lastVisit)]);console.log(r.toString()),U("history entry(ies)",e.length)},O(e)));T(W(A.command("search-terms").description("List search terms from history"))).action((o,e)=>x(o=>{const e=g({chromeDir:o.profilePath,profile:o.profile,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return U("search terms",0);console.log(s.bold("\n🔍 Search Terms:\n"));const r=R(["Term","URL"],[40,80]);for(const o of e)r.push([s.white(o.term),s.dim(o.url)]);console.log(r.toString()),U("search term(s)",e.length)},O(e)));T(W(A.command("cookies").description("List cookies (encrypted values decrypted)"))).option("--domain <domain>","Filter by domain").option("--url <url>","Filter by URL with path").option("--no-decrypt","Skip decryption of encrypted values").action((o,e)=>x(o=>{const e=w({chromeDir:o.profilePath,profile:o.profile,domain:o.domain,url:o.url,decrypt:!1!==o.decrypt,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return U("cookies",0);console.log(s.bold("\n🍪 Cookies:\n"));const r=R(["Domain","Name","Value","Secure","Expires"],[30,25,30,8,22]);for(const o of e)r.push([s.cyan(o.domain),s.white(o.name),s.dim(o.value?o.value.substring(0,50)+(o.value.length>50?"…":""):"—"),o.secure?s.green("✓"):s.dim("✗"),s.dim(o.expires)]);console.log(r.toString()),U("cookie(s)",e.length)},O(e)));M(T(W(A.command("autofill").description("List autofill entries")))).action((o,e)=>x(o=>{const e=b({chromeDir:o.profilePath,profile:o.profile,search:o.search,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return U("autofill entries",0);console.log(s.bold("\n📝 Autofill Entries:\n"));const r=R(["Field Name","Value","Count","Last Used"],[25,40,8,22]);for(const o of e)r.push([s.cyan(o.name),s.white(o.value),s.yellow(String(o.count)),s.dim(o.dateLastUsed)]);console.log(r.toString()),U("autofill entry(ies)",e.length)},O(e)));W(A.command("credit-cards").description("List saved credit cards")).action((o,e)=>x(o=>{const e=y({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return U("credit cards",0);console.log(s.bold("\n💳 Saved Credit Cards:\n"));const r=R(["Name on Card","Card Number","Expires","Nickname"],[25,25,14,20]);for(const o of e)r.push([s.white(o.nameOnCard||"—"),s.yellow(o.cardNumber||"—"),s.dim(`${o.expirationMonth}/${o.expirationYear}`),s.dim(o.nickname||"—")]);console.log(r.toString()),U("credit card(s)",e.length)},O(e)));W(A.command("addresses").description("List saved addresses")).action((o,e)=>x(o=>{const e=S({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return U("addresses",0);console.log(s.bold("\n🏠 Saved Addresses:\n"));const r=R(["Name","Email","Phone","Address","City/State/Zip"],[20,25,16,30,25]);for(const o of e)r.push([s.white(o.fullName||"—"),s.cyan(o.email||"—"),s.dim(o.phone||"—"),s.white(o.streetAddress||"—"),s.dim([o.city,o.state,o.zipcode].filter(Boolean).join(", ")||"—")]);console.log(r.toString()),U("address(es)",e.length)},O(e)));M(T(W(A.command("downloads").description("List download history")))).action((o,e)=>x(o=>{const e=v({chromeDir:o.profilePath,profile:o.profile,search:o.search,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return U("downloads",0);console.log(s.bold("\n⬇️ Download History:\n"));const r=R(["File","URL","Size","State","Date"],[35,40,12,12,20]);for(const o of e){const e=o.targetPath?o.targetPath.split("/").pop():"—",t=o.totalBytes>0?_(o.totalBytes):"—";r.push([s.white(e||""),s.cyan(o.url?o.url.substring(0,60):"—"),s.dim(t),"complete"===o.state?s.green(o.state):s.yellow(o.state),s.dim(o.startTime)])}console.log(r.toString()),U("download(s)",e.length)},O(e)));M(W(A.command("extensions").description("List installed extensions"))).action((o,e)=>x(o=>{const e=k({chromeDir:o.profilePath,profile:o.profile,search:o.search});if(E(o,e))return;if(0===e.length)return U("extensions",0);console.log(s.bold("\n🧩 Installed Extensions:\n"));const r=R(["Name","Version","ID","Enabled","Webstore"],[30,12,36,9,9]);for(const o of e)r.push([s.white(o.name),s.dim(o.version),s.dim(o.id),o.enabled?s.green("✓"):s.red("✗"),o.fromWebstore?s.green("✓"):s.dim("✗")]);console.log(r.toString()),U("extension(s)",e.length)},O(e)));W(A.command("search-engines").description("List configured search engines")).action((o,e)=>x(o=>{const e=L({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return U("search engines",0);console.log(s.bold("\n🔎 Search Engines:\n"));const r=R(["Name","Keyword","URL","Active"],[20,16,60,8]);for(const o of e)r.push([s.white(o.name),s.cyan(o.keyword),s.dim(o.url?o.url.substring(0,80):"—"),o.isActive?s.green("✓"):s.dim("✗")]);console.log(r.toString()),U("search engine(s)",e.length)},O(e)));function _(o){if(0===o)return"0 B";const e=Math.floor(Math.log(o)/Math.log(1024));return`${(o/Math.pow(1024,e)).toFixed(1)} ${["B","KB","MB","GB","TB"][e]}`}W(A.command("top-sites").description("List top sites")).action((o,e)=>x(o=>{const e=P({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return U("top sites",0);console.log(s.bold("\n⭐ Top Sites:\n"));const r=R(["Rank","Title","URL"],[8,30,80]);for(const o of e)r.push([s.yellow(String(o.rank+1)),s.white(o.title||"—"),s.cyan(o.url)]);console.log(r.toString()),U("top site(s)",e.length)},O(e)));try{A.parse()}catch(o){console.error(s.red(`\n✖ ${o?.message??String(o)}\n`)),process.env.DEBUG&&console.error(o),process.exit(1)}
|
|
2
|
+
import{readFileSync as o,existsSync as e}from"node:fs";import{join as r}from"node:path";import{Command as t}from"commander";import i from"chalk";import s from"cli-table3";import{discoverProfiles as n,getProfileMetadata as l,getProfileStates as a,getDirectorySize as c,detectInstalledBrowsers as d}from"../src/core/chrome.js";import{setActiveBrowser as m,getActiveBrowser as p}from"../src/core/platform/index.js";import{getPasswords as f}from"../src/modules/passwords.js";import{getBookmarks as h}from"../src/modules/bookmarks.js";import{getHistory as u,getSearchTerms as g}from"../src/modules/history.js";import{getCookies as w}from"../src/modules/cookies.js";import{getLocalStorage as b}from"../src/modules/local-storage.js";import{getAutofillEntries as y,getCreditCards as S,getAddresses as v}from"../src/modules/autofill.js";import{getDownloads as k}from"../src/modules/downloads.js";import{getExtensions as L}from"../src/modules/extensions.js";import{getSearchEngines as P}from"../src/modules/search-engines.js";import{getTopSites as D}from"../src/modules/top-sites.js";const j=function(){const t={...process.env},i=r(process.cwd(),".env");if(e(i))try{const e=o(i,"utf8");for(const o of e.split(/\r?\n/)){const e=o.trim();if(!e||e.startsWith("#"))continue;const r=e.indexOf("=");if(-1!==r){const o=e.substring(0,r).trim();let i=e.substring(r+1).trim();(i.startsWith('"')&&i.endsWith('"')||i.startsWith("'")&&i.endsWith("'"))&&(i=i.slice(1,-1)),t[o]=i}}}catch{}return t}(),B=j.PROFILE_PATH||void 0,C=j.PROFILE_NAME||void 0,N=j.BROWSER||j.CHROME_BROWSER||void 0;function R(o){console.log(JSON.stringify(o,null,2))}function U(o,e){return new s({head:o.map(o=>i.bold.white(o)),colWidths:e,wordWrap:!0,style:{border:["grey"],head:[]}})}function O(o,e){0===e?console.log(i.yellow(`\n⚠ No ${o} found.\n`)):console.log(i.green(`\n✔ Found ${e} ${o}.\n`))}let $=null;function E(o,e){return $?($.push({browser:p().name,results:e}),!0):!!o.json&&(R(e),!0)}function x(o){const e=o.optsWithGlobals(),r=Boolean(e.browser)||Boolean(e.allBrowsers)||Boolean(N);return e.browser=e.browser||N||void 0,e.profilePath||(e.profilePath=r?void 0:B),e.profile||(e.profile=r?void 0:C),e}function F(o,e){e.allBrowsers?function(o,e){const r=d();if(0===r.length)return e.json?R([]):void console.log(i.yellow("\n⚠ No supported Chromium browsers found on this machine.\n"));const t={...e,profilePath:void 0};if(e.json){$=[];try{for(const e of r){m(e.browser.id);try{o(t)}catch(o){$.push({browser:e.browser.name,results:{error:o?.message??String(o)}})}}R($)}finally{$=null}}else for(const e of r){m(e.browser.id),console.log(i.bold.magenta(`\n══════════ ${e.browser.name} ══════════`));try{o(t)}catch(o){console.log(i.red(` ⚠ Skipped: ${o?.message??String(o)}`))}}}(o,e):(m(e.browser),o(e))}function W(o){const e=d({includeMissing:!0});if(o.json)return R(e.map(o=>({id:o.browser.id,name:o.browser.name,installed:o.installed,profileCount:o.profileCount,path:o.chromeDir,safeStorageLabel:o.browser.safeStorageLabel})));const r=e.filter(o=>o.installed);console.log(i.bold(`\n🌐 Supported browsers (${r.length} installed):\n`));const t=U(["Browser","Id","Installed","Profiles","Path"],[20,14,11,9,50]);for(const o of e)t.push([i.white(o.browser.name),i.cyan(o.browser.id),o.installed?i.green("✓"):i.dim("✗"),o.installed?i.yellow(String(o.profileCount)):i.dim("—"),i.dim(o.chromeDir)]);console.log(t.toString())}function I(o){return o.option("--profile-path <path>","Custom browser User Data Path (overrides --browser)").option("--profile <name>","Target a specific profile").option("--browser <name>","Browser to read (chrome, edge, brave, comet, vivaldi, opera, chromium…)").option("--all-browsers","Read from every installed Chromium browser").option("--json","Output as JSON")}function M(o){return o.option("--search <term>","Filter results (case-insensitive)")}function T(o,e=100){return o.option("--limit <n>","Limit number of results",String(e))}const A=new t,z=JSON.parse(o(new URL("../../package.json",import.meta.url),"utf8"));A.name("chrome-tools").description(i.bold.cyan("Chrome Data Toolkit")+i.dim(" — Extract passwords, bookmarks, history, cookies, and more from Chrome on macOS, Windows, and Linux")).version(z.version).option("--passwords","Shortcut: list saved passwords").option("--bookmarks","Shortcut: list bookmarks").option("--local-storage","Shortcut: list localStorage entries").option("--profiles","Shortcut: list profiles").option("--browsers","Shortcut: list supported / installed browsers").option("--size","Show each profile's size on disk when listing profiles (slower)").option("--profile-path <path>","Custom browser User Data Path (overrides --browser)").option("--profile <name>","Target a specific profile").option("--browser <name>","Browser to read (chrome, edge, brave, comet, vivaldi, opera, chromium…)").option("--all-browsers","Read from every installed Chromium browser").option("--json","Output as JSON").option("--search <term>","Filter results (for shortcut flags)").option("--limit <n>","Limit results (for shortcut flags)").action((o,e)=>{const r=x(e);r.browsers?W(r):r.passwords?F(G,r):r.bookmarks?F(K,r):r.localStorage?F(_,r):F(J,r)});const V=A.command("profiles").description("List Chrome profiles");I(V).option("--size","Compute and show each profile's size on disk (slower)").action((o,e)=>{F(J,x(e))});I(V.command("states").description("Show detailed profile states with available data files")).action((o,e)=>F(H,x(e)));function J(o){const e=n(o.profilePath),r=l(o.profilePath),t=Boolean(o.size);if(o.json){const i=new Map(r.map(o=>[o.directory,o]));return void E(o,e.map(o=>({...o,...i.get(o.name)||{},...t?{sizeBytes:c(o.path)}:{}})))}if(0===e.length)return void console.log(i.yellow("\n⚠ No Chrome profiles found.\n"));const s=new Map(r.map(o=>[o.directory,o]));console.log(i.bold(`\n📁 Discovered ${e.length} profile(s):\n`));const a=U(t?["Directory","Display Name","Email","Size","Path"]:["Directory","Display Name","Email","Path"],t?[16,22,30,10,42]:[16,22,30,50]);for(const o of e){const e=s.get(o.name)||{},r=[i.cyan(o.name),i.white(e.name||o.name),i.dim(e.email||"—")];t&&r.push(i.yellow(Y(c(o.path)))),r.push(i.dim(o.path)),a.push(r)}console.log(a.toString()),O("profile(s)",e.length)}function H(o){const e=a(o.profilePath);if(o.json)E(o,e);else if(0!==e.length){console.log(i.bold(`\n📊 Profile States (${e.length} profile(s)):\n`));for(const o of e){console.log(i.bold.cyan(` ${o.displayName}`)+i.dim(` (${o.directory})`)),o.email&&console.log(i.dim(` Email: ${o.email}`)),console.log(i.dim(` Path: ${o.path}`));const e=o.dataFiles,r=Object.entries(e).filter(([,o])=>o).map(([o])=>o),t=Object.entries(e).filter(([,o])=>!o).map(([o])=>o);console.log(` Available: ${r.map(o=>i.green(o)).join(", ")||i.dim("none")}`),t.length>0&&console.log(` Missing: ${t.map(o=>i.dim(o)).join(", ")}`),console.log()}}else console.log(i.yellow("\n⚠ No Chrome profiles found.\n"))}A.command("browsers").description("List supported browsers and detect which are installed").option("--json","Output as JSON").action((o,e)=>W(x(e)));function G(o){const e=f({chromeDir:o.profilePath,profile:o.profile,search:o.search});if(E(o,e))return;if(0===e.length)return O("passwords",0);console.log(i.bold("\n🔑 Saved Passwords:\n"));const r=new Set(e.map(o=>o.profile)).size>1,t=U(r?["Profile","URL","Username","Password","Last Used"]:["URL","Username","Password","Last Used"],r?[12,40,24,22,20]:[45,28,25,22]);for(const o of e){const e=[i.cyan(o.url),i.green(o.username||"<empty>"),i.yellow(o.password||"<empty>"),i.dim(o.lastUsed)];r&&e.unshift(i.magenta(o.profile)),t.push(e)}console.log(t.toString()),O("password(s)",e.length)}M(I(A.command("passwords").description("List saved passwords"))).action((o,e)=>F(G,x(e)));function K(o){const e=h({chromeDir:o.profilePath,profile:o.profile,folder:o.folder,search:o.search});if(E(o,e))return;if(0===e.length)return O("bookmarks",0);console.log(i.bold("\n📚 Bookmarks:\n"));const r=U(["Title","URL","Folder","Date Added"],[30,50,25,20]);for(const o of e)r.push([i.white(o.title),i.cyan(o.url),i.dim(o.folder||"/"),i.dim(o.dateAdded)]);console.log(r.toString()),O("bookmark(s)",e.length)}M(I(A.command("bookmarks").description("List bookmarks"))).option("--folder <name>","Filter by folder name").action((o,e)=>F(K,x(e)));M(T(I(A.command("history").description("List browsing history")))).action((o,e)=>F(o=>{const e=u({chromeDir:o.profilePath,profile:o.profile,search:o.search,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return O("history entries",0);console.log(i.bold("\n🕐 Browsing History:\n"));const r=U(["URL","Title","Visits","Last Visit"],[50,30,8,22]);for(const o of e)r.push([i.cyan(o.url),i.white(o.title||"—"),i.yellow(String(o.visitCount)),i.dim(o.lastVisit)]);console.log(r.toString()),O("history entry(ies)",e.length)},x(e)));T(I(A.command("search-terms").description("List search terms from history"))).action((o,e)=>F(o=>{const e=g({chromeDir:o.profilePath,profile:o.profile,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return O("search terms",0);console.log(i.bold("\n🔍 Search Terms:\n"));const r=U(["Term","URL"],[40,80]);for(const o of e)r.push([i.white(o.term),i.dim(o.url)]);console.log(r.toString()),O("search term(s)",e.length)},x(e)));T(I(A.command("cookies").description("List cookies (encrypted values decrypted)"))).option("--domain <domain>","Filter by domain").option("--url <url>","Filter by URL with path").option("--no-decrypt","Skip decryption of encrypted values").action((o,e)=>F(o=>{const e=w({chromeDir:o.profilePath,profile:o.profile,domain:o.domain,url:o.url,decrypt:!1!==o.decrypt,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return O("cookies",0);console.log(i.bold("\n🍪 Cookies:\n"));const r=U(["Domain","Name","Value","Secure","Expires"],[30,25,30,8,22]);for(const o of e)r.push([i.cyan(o.domain),i.white(o.name),i.dim(o.value?o.value.substring(0,50)+(o.value.length>50?"…":""):"—"),o.secure?i.green("✓"):i.dim("✗"),i.dim(o.expires)]);console.log(r.toString()),O("cookie(s)",e.length)},x(e)));function _(o){const e=b({chromeDir:o.profilePath,profile:o.profile,origin:o.origin,url:o.url,key:o.key,search:o.search,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return O("localStorage entries",0);console.log(i.bold("\n💾 localStorage:\n"));const r=U(["Origin","Key","Value"],[36,28,46]);for(const o of e)r.push([i.cyan(o.origin),i.white(o.key),i.dim(o.value?o.value.substring(0,80)+(o.value.length>80?"…":""):"—")]);console.log(r.toString()),O("localStorage entries",e.length)}M(T(I(A.command("local-storage").description("List localStorage entries")))).option("--origin <origin>","Filter by origin").option("--url <url>","Filter by URL origin").option("--key <key>","Filter by localStorage key").action((o,e)=>F(_,x(e)));M(T(I(A.command("autofill").description("List autofill entries")))).action((o,e)=>F(o=>{const e=y({chromeDir:o.profilePath,profile:o.profile,search:o.search,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return O("autofill entries",0);console.log(i.bold("\n📝 Autofill Entries:\n"));const r=U(["Field Name","Value","Count","Last Used"],[25,40,8,22]);for(const o of e)r.push([i.cyan(o.name),i.white(o.value),i.yellow(String(o.count)),i.dim(o.dateLastUsed)]);console.log(r.toString()),O("autofill entry(ies)",e.length)},x(e)));I(A.command("credit-cards").description("List saved credit cards")).action((o,e)=>F(o=>{const e=S({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return O("credit cards",0);console.log(i.bold("\n💳 Saved Credit Cards:\n"));const r=U(["Name on Card","Card Number","Expires","Nickname"],[25,25,14,20]);for(const o of e)r.push([i.white(o.nameOnCard||"—"),i.yellow(o.cardNumber||"—"),i.dim(`${o.expirationMonth}/${o.expirationYear}`),i.dim(o.nickname||"—")]);console.log(r.toString()),O("credit card(s)",e.length)},x(e)));I(A.command("addresses").description("List saved addresses")).action((o,e)=>F(o=>{const e=v({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return O("addresses",0);console.log(i.bold("\n🏠 Saved Addresses:\n"));const r=U(["Name","Email","Phone","Address","City/State/Zip"],[20,25,16,30,25]);for(const o of e)r.push([i.white(o.fullName||"—"),i.cyan(o.email||"—"),i.dim(o.phone||"—"),i.white(o.streetAddress||"—"),i.dim([o.city,o.state,o.zipcode].filter(Boolean).join(", ")||"—")]);console.log(r.toString()),O("address(es)",e.length)},x(e)));M(T(I(A.command("downloads").description("List download history")))).action((o,e)=>F(o=>{const e=k({chromeDir:o.profilePath,profile:o.profile,search:o.search,limit:parseInt(o.limit,10)||100});if(E(o,e))return;if(0===e.length)return O("downloads",0);console.log(i.bold("\n⬇️ Download History:\n"));const r=U(["File","URL","Size","State","Date"],[35,40,12,12,20]);for(const o of e){const e=o.targetPath?o.targetPath.split("/").pop():"—",t=o.totalBytes>0?Y(o.totalBytes):"—";r.push([i.white(e||""),i.cyan(o.url?o.url.substring(0,60):"—"),i.dim(t),"complete"===o.state?i.green(o.state):i.yellow(o.state),i.dim(o.startTime)])}console.log(r.toString()),O("download(s)",e.length)},x(e)));M(I(A.command("extensions").description("List installed extensions"))).action((o,e)=>F(o=>{const e=L({chromeDir:o.profilePath,profile:o.profile,search:o.search});if(E(o,e))return;if(0===e.length)return O("extensions",0);console.log(i.bold("\n🧩 Installed Extensions:\n"));const r=U(["Name","Version","ID","Enabled","Webstore"],[30,12,36,9,9]);for(const o of e)r.push([i.white(o.name),i.dim(o.version),i.dim(o.id),o.enabled?i.green("✓"):i.red("✗"),o.fromWebstore?i.green("✓"):i.dim("✗")]);console.log(r.toString()),O("extension(s)",e.length)},x(e)));I(A.command("search-engines").description("List configured search engines")).action((o,e)=>F(o=>{const e=P({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return O("search engines",0);console.log(i.bold("\n🔎 Search Engines:\n"));const r=U(["Name","Keyword","URL","Active"],[20,16,60,8]);for(const o of e)r.push([i.white(o.name),i.cyan(o.keyword),i.dim(o.url?o.url.substring(0,80):"—"),o.isActive?i.green("✓"):i.dim("✗")]);console.log(r.toString()),O("search engine(s)",e.length)},x(e)));function Y(o){if(0===o)return"0 B";const e=Math.floor(Math.log(o)/Math.log(1024));return`${(o/Math.pow(1024,e)).toFixed(1)} ${["B","KB","MB","GB","TB"][e]}`}I(A.command("top-sites").description("List top sites")).action((o,e)=>F(o=>{const e=D({chromeDir:o.profilePath,profile:o.profile});if(E(o,e))return;if(0===e.length)return O("top sites",0);console.log(i.bold("\n⭐ Top Sites:\n"));const r=U(["Rank","Title","URL"],[8,30,80]);for(const o of e)r.push([i.yellow(String(o.rank+1)),i.white(o.title||"—"),i.cyan(o.url)]);console.log(r.toString()),O("top site(s)",e.length)},x(e)));try{A.parse()}catch(o){console.error(i.red(`\n✖ ${o?.message??String(o)}\n`)),process.env.DEBUG&&console.error(o),process.exit(1)}
|
package/dist/src/core/chrome.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readdirSync as t,readFileSync as r,statSync as o}from"node:fs";import{join as i}from"node:path";import{getPlatformChromeDir as n}from"./platform/index.js";import{listBrowsers as a,getActiveBrowser as s,setActiveBrowser as c}from"./browsers.js";const f=["Login Data","History","Bookmarks","Cookies","Web Data","Preferences"];export function getDefaultChromeDir(){return n()}export function detectInstalledBrowsers({includeMissing:t=!1}={}){const r=s(),o=[];try{for(const r of a()){c(r.id);const i=getDefaultChromeDir(),n=Boolean(i)&&e(i);(n||t)&&o.push({browser:r,chromeDir:i,installed:n,profileCount:n?discoverProfiles(i).length:0})}}finally{c(r.id)}return o}export function discoverProfiles(r){const o=r||getDefaultChromeDir();if(!o||!e(o))return[];try{const r=t(o,{withFileTypes:!0}),n=[];for(const t of r){if(!t.isDirectory())continue;const r=i(o,t.name);f.some(t=>e(i(r,t)))&&n.push({name:t.name,path:r})}return n}catch{return[]}}export function getProfileMetadata(t){const o=t||getDefaultChromeDir(),n=i(o,"Local State");if(!e(n))return[];try{const e=r(n,"utf-8"),t=JSON.parse(e),o=t?.profile?.info_cache;return o&&"object"==typeof o?Object.entries(o).map(([e,t])=>{const r=t;return{directory:e,name:r.name||e,gaiaName:r.gaia_name||"",userName:r.user_name||"",email:r.user_name||"",avatarIcon:r.avatar_icon||"",isUsingDefaultName:r.is_using_default_name??!0,isEphemeral:r.is_ephemeral??!1,activeTime:r.active_time||0}}):[]}catch{return[]}}export function getProfileStates(t){const r=t||getDefaultChromeDir(),o=discoverProfiles(r),n=getProfileMetadata(r),a=new Map;for(const e of n)a.set(e.directory,e);return o.map(t=>{const r=a.get(t.name),o=t.path,n={};for(const t of f)n[t.replace(/\s+/g,"_").toLowerCase()]=e(i(o,t));return n.top_sites=e(i(o,"Top Sites")),n.extensions=e(i(o,"Extensions")),{directory:t.name,path:o,displayName:r?.name||t.name,gaiaName:r?.gaiaName||"",email:r?.email||"",avatarIcon:r?.avatarIcon||"",isEphemeral:r?.isEphemeral??!1,activeTime:r?.activeTime||0,dataFiles:n}})}export function getDirectorySize(r){if(!r||!e(r))return 0;let n,a=0;try{n=t(r,{withFileTypes:!0})}catch{return 0}for(const e of n){const t=i(r,e.name);try{if(e.isSymbolicLink())continue;e.isDirectory()?a+=getDirectorySize(t):e.isFile()&&(a+=o(t).size)}catch{}}return a}export function resolveProfilePath(t,r){const o=t||getDefaultChromeDir(),n=i(o,r);return e(n)?n:null}export function resolveTargetProfiles({profilePath:e,chromeDir:t,profile:r,browser:o}={}){o&&c(o);const i=e||t||getDefaultChromeDir(),n=discoverProfiles(i);if(r){const e=n.filter(e=>e.name===r);if(0===e.length)throw new Error(`Profile "${r}" not found in ${i}`);return e}return n}
|
|
1
|
+
import{existsSync as e,readdirSync as t,readFileSync as r,statSync as o}from"node:fs";import{join as i}from"node:path";import{getPlatformChromeDir as n}from"./platform/index.js";import{listBrowsers as a,getActiveBrowser as s,setActiveBrowser as c}from"./browsers.js";const f=["Login Data","History","Bookmarks","Cookies","Web Data","Local Storage","Preferences"];export function getDefaultChromeDir(){return n()}export function detectInstalledBrowsers({includeMissing:t=!1}={}){const r=s(),o=[];try{for(const r of a()){c(r.id);const i=getDefaultChromeDir(),n=Boolean(i)&&e(i);(n||t)&&o.push({browser:r,chromeDir:i,installed:n,profileCount:n?discoverProfiles(i).length:0})}}finally{c(r.id)}return o}export function discoverProfiles(r){const o=r||getDefaultChromeDir();if(!o||!e(o))return[];try{const r=t(o,{withFileTypes:!0}),n=[];for(const t of r){if(!t.isDirectory())continue;const r=i(o,t.name);f.some(t=>e(i(r,t)))&&n.push({name:t.name,path:r})}return n}catch{return[]}}export function getProfileMetadata(t){const o=t||getDefaultChromeDir(),n=i(o,"Local State");if(!e(n))return[];try{const e=r(n,"utf-8"),t=JSON.parse(e),o=t?.profile?.info_cache;return o&&"object"==typeof o?Object.entries(o).map(([e,t])=>{const r=t;return{directory:e,name:r.name||e,gaiaName:r.gaia_name||"",userName:r.user_name||"",email:r.user_name||"",avatarIcon:r.avatar_icon||"",isUsingDefaultName:r.is_using_default_name??!0,isEphemeral:r.is_ephemeral??!1,activeTime:r.active_time||0}}):[]}catch{return[]}}export function getProfileStates(t){const r=t||getDefaultChromeDir(),o=discoverProfiles(r),n=getProfileMetadata(r),a=new Map;for(const e of n)a.set(e.directory,e);return o.map(t=>{const r=a.get(t.name),o=t.path,n={};for(const t of f)n[t.replace(/\s+/g,"_").toLowerCase()]=e(i(o,t));return n.top_sites=e(i(o,"Top Sites")),n.extensions=e(i(o,"Extensions")),{directory:t.name,path:o,displayName:r?.name||t.name,gaiaName:r?.gaiaName||"",email:r?.email||"",avatarIcon:r?.avatarIcon||"",isEphemeral:r?.isEphemeral??!1,activeTime:r?.activeTime||0,dataFiles:n}})}export function getDirectorySize(r){if(!r||!e(r))return 0;let n,a=0;try{n=t(r,{withFileTypes:!0})}catch{return 0}for(const e of n){const t=i(r,e.name);try{if(e.isSymbolicLink())continue;e.isDirectory()?a+=getDirectorySize(t):e.isFile()&&(a+=o(t).size)}catch{}}return a}export function resolveProfilePath(t,r){const o=t||getDefaultChromeDir(),n=i(o,r);return e(n)?n:null}export function resolveTargetProfiles({profilePath:e,chromeDir:t,profile:r,browser:o}={}){o&&c(o);const i=e||t||getDefaultChromeDir(),n=discoverProfiles(i);if(r){const e=n.filter(e=>e.name===r);if(0===e.length)throw new Error(`Profile "${r}" not found in ${i}`);return e}return n}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export { getPasswords } from "./modules/passwords.js";
|
|
|
20
20
|
export { getBookmarks } from "./modules/bookmarks.js";
|
|
21
21
|
export { getHistory, getSearchTerms } from "./modules/history.js";
|
|
22
22
|
export { getCookies, type CookieEntry, type CookieOptions } from "./modules/cookies.js";
|
|
23
|
+
export { getLocalStorage, type LocalStorageEntry, type LocalStorageOptions } from "./modules/local-storage.js";
|
|
23
24
|
export { getAutofillEntries, getCreditCards, getAddresses } from "./modules/autofill.js";
|
|
24
25
|
export { getDownloads } from "./modules/downloads.js";
|
|
25
26
|
export { getExtensions } from "./modules/extensions.js";
|
package/dist/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{getDefaultChromeDir,discoverProfiles,getProfileMetadata,getProfileStates,resolveProfilePath,resolveTargetProfiles,detectInstalledBrowsers}from"./core/chrome.js";export{BROWSERS,listBrowsers,resolveBrowser,getActiveBrowser,setActiveBrowser}from"./core/browsers.js";export{selectPlatform,getPlatformChromeDir,deriveEncryptionKey,decryptValue,decryptValueBuffer,clearKeyCache}from"./core/platform/index.js";export{getKeychainPassword,getChromeKeychainPassword,clearKeychainCache}from"./core/keychain.js";export{chromeTimeToDate}from"./core/crypto.js";export{queryDatabase,tableExists}from"./core/db.js";export{getPasswords}from"./modules/passwords.js";export{getBookmarks}from"./modules/bookmarks.js";export{getHistory,getSearchTerms}from"./modules/history.js";export{getCookies}from"./modules/cookies.js";export{getAutofillEntries,getCreditCards,getAddresses}from"./modules/autofill.js";export{getDownloads}from"./modules/downloads.js";export{getExtensions}from"./modules/extensions.js";export{getSearchEngines}from"./modules/search-engines.js";export{getTopSites}from"./modules/top-sites.js";
|
|
1
|
+
export{getDefaultChromeDir,discoverProfiles,getProfileMetadata,getProfileStates,resolveProfilePath,resolveTargetProfiles,detectInstalledBrowsers}from"./core/chrome.js";export{BROWSERS,listBrowsers,resolveBrowser,getActiveBrowser,setActiveBrowser}from"./core/browsers.js";export{selectPlatform,getPlatformChromeDir,deriveEncryptionKey,decryptValue,decryptValueBuffer,clearKeyCache}from"./core/platform/index.js";export{getKeychainPassword,getChromeKeychainPassword,clearKeychainCache}from"./core/keychain.js";export{chromeTimeToDate}from"./core/crypto.js";export{queryDatabase,tableExists}from"./core/db.js";export{getPasswords}from"./modules/passwords.js";export{getBookmarks}from"./modules/bookmarks.js";export{getHistory,getSearchTerms}from"./modules/history.js";export{getCookies}from"./modules/cookies.js";export{getLocalStorage}from"./modules/local-storage.js";export{getAutofillEntries,getCreditCards,getAddresses}from"./modules/autofill.js";export{getDownloads}from"./modules/downloads.js";export{getExtensions}from"./modules/extensions.js";export{getSearchEngines}from"./modules/search-engines.js";export{getTopSites}from"./modules/top-sites.js";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface LocalStorageOptions {
|
|
2
|
+
chromeDir?: string;
|
|
3
|
+
profile?: string;
|
|
4
|
+
browser?: string;
|
|
5
|
+
origin?: string;
|
|
6
|
+
url?: string;
|
|
7
|
+
key?: string;
|
|
8
|
+
search?: string;
|
|
9
|
+
limit?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface LocalStorageEntry {
|
|
12
|
+
profile: string;
|
|
13
|
+
origin: string;
|
|
14
|
+
key: string;
|
|
15
|
+
value: string;
|
|
16
|
+
}
|
|
17
|
+
interface RawLevelDBRecord {
|
|
18
|
+
key: Buffer;
|
|
19
|
+
value?: Buffer;
|
|
20
|
+
sequence: bigint;
|
|
21
|
+
deleted: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reads localStorage key/value pairs from Chrome's Local Storage LevelDB store.
|
|
25
|
+
*
|
|
26
|
+
* @param options - Targeting and filtering options.
|
|
27
|
+
* @returns Array of localStorage entries.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getLocalStorage({ chromeDir, profile, browser, origin, url, key, search, limit, }?: LocalStorageOptions): LocalStorageEntry[];
|
|
30
|
+
declare function parseLocalStorageRecord(rawKey: Buffer, rawValue: Buffer): {
|
|
31
|
+
origin: string;
|
|
32
|
+
key: string;
|
|
33
|
+
value: string;
|
|
34
|
+
} | null;
|
|
35
|
+
declare function decodeLocalStorageString(data: Buffer): string;
|
|
36
|
+
declare function parseLogRecords(data: Buffer): RawLevelDBRecord[];
|
|
37
|
+
export declare const _test: {
|
|
38
|
+
decodeLocalStorageString: typeof decodeLocalStorageString;
|
|
39
|
+
parseLocalStorageRecord: typeof parseLocalStorageRecord;
|
|
40
|
+
parseLogRecords: typeof parseLogRecords;
|
|
41
|
+
};
|
|
42
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cpSync as e,existsSync as t,mkdtempSync as n,readdirSync as r,readFileSync as o,rmSync as f}from"node:fs";import{tmpdir as l}from"node:os";import{basename as u,join as i}from"node:path";import{resolveTargetProfiles as s}from"../core/chrome.js";export function getLocalStorage({chromeDir:e,profile:n,browser:r,origin:o,url:l,key:u,search:g,limit:p=100}={}){const y=s({chromeDir:e,profile:n,browser:r}),v=[],d=function(e){if(!e)return;try{return new URL(e).origin.toLowerCase()}catch{return e.toLowerCase()}}(l||o),b=u?.toLowerCase(),m=g?.toLowerCase();for(const e of y){const n=i(e.path,"Local Storage","leveldb");if(!t(n))continue;let r=null;try{r=c(n);const t=a(r);for(const n of t.values()){if(n.deleted||!n.value)continue;const t=h(n.key,n.value);if(!t)continue;const r={profile:e.name,origin:t.origin,key:t.key,value:t.value};if((!d||r.origin.toLowerCase().includes(d))&&(!b||r.key.toLowerCase().includes(b))){if(m){if(!`${r.origin}\n${r.key}\n${r.value}`.toLowerCase().includes(m))continue}v.push(r)}}}catch{}finally{r&&f(r,{recursive:!0,force:!0})}}return v.sort((e,t)=>e.profile.localeCompare(t.profile)||e.origin.localeCompare(t.origin)||e.key.localeCompare(t.key)),p?v.slice(0,parseInt(p,10)):v}function c(t){const r=n(i(l(),"chrome-local-storage-"));return e(t,r,{recursive:!0,force:!0,filter:e=>"LOCK"!==u(e)}),r}function a(e){const t=new Map,n=r(e).filter(e=>/\.(log|ldb|sst)$/i.test(e)).sort();for(const r of n){const n=i(e,r),f=o(n);if(/\.(ldb|sst)$/i.test(r))for(const e of d(f))g(t,e)}for(const r of n){if(!/\.log$/i.test(r))continue;const n=i(e,r),f=o(n);for(const e of y(f))g(t,e)}return t}function g(e,t){const n=t.key.toString("hex"),r=e.get(n);r&&r.sequence>t.sequence||e.set(n,t)}function h(e,t){if(e.length<3||95!==e[0])return null;const n=e.indexOf(0,1);if(-1===n)return null;const r=e.subarray(1,n).toString("utf8"),o=p(e.subarray(n+1)),f=p(t);return r&&o?{origin:r,key:o,value:f}:null}function p(e){if(0===e.length)return"";const t=e[0],n=e.subarray(1);return 0===t&&n.length%2==0?n.toString("utf16le"):1===t?n.toString("latin1"):e.toString("utf8")}function y(e){const t=[];let n=0,r=[];for(;n+7<=e.length;){const o=32768-n%32768;if(o<7){n+=o;continue}const f=e.readUInt16LE(n+4),l=e[n+6];if(n+=7,0===l&&0===f){n+=f;continue}if(f>e.length-n||f>o-7)break;const u=e.subarray(n,n+f);n+=f,1===l?(t.push(...v(u)),r=[]):2===l?r=[Buffer.from(u)]:3===l&&r.length>0?r.push(Buffer.from(u)):4===l&&r.length>0&&(r.push(Buffer.from(u)),t.push(...v(Buffer.concat(r))),r=[])}return t}function v(e){if(e.length<12)return[];const t=[],n=function(e,t){let n=0n;for(let r=0;r<8;r++)n|=BigInt(e[t+r]||0)<<BigInt(8*r);return n}(e,0),r=e.readUInt32LE(8);let o=12,f=0;for(;o<e.length&&f<r;){const r=e[o++],l=k(e,o);if(!l)break;o=l.nextOffset;const u=n+BigInt(f);if(1===r){const n=k(e,o);if(!n)break;o=n.nextOffset,t.push({key:l.value,value:n.value,sequence:u,deleted:!1})}else{if(0!==r)break;t.push({key:l.value,sequence:u,deleted:!0})}f++}return t}function d(e){const t=[];if(e.length<48)return t;if(15800726617472432983n!==e.readBigUInt64LE(e.length-8))return t;const n=e.subarray(e.length-48,e.length-8),r=w(n,0);if(!r)return t;const o=w(n,r.bytesRead);if(!o)return t;const f=b(e,o);if(!f)return t;for(const n of m(f)){const r=w(n.value,0);if(!r)continue;const o=b(e,r);if(o)for(const e of m(o)){if(e.key.length<8)continue;const n=e.key,r=n.length-8,o=n[r],f=L(n.subarray(r)),l=n.subarray(0,r);1===o?t.push({key:l,value:e.value,sequence:f,deleted:!1}):0===o&&t.push({key:l,sequence:f,deleted:!0})}}return t}function b(e,t){const n=t.offset+t.size;if(t.offset<0||t.size<0||n+5>e.length)return null;const r=e.subarray(t.offset,n),o=e[n];if(0===o)return r;if(1===o)try{return function(e){const t=I(e,0);if(!t)throw new Error("Invalid Snappy length");const n=Buffer.alloc(t.value);let r=t.nextOffset,o=0;for(;r<e.length&&o<n.length;){const t=e[r++],f=3&t;if(0===f){let f=t>>2;if(f<60)f+=1;else{const t=f-59;if(r+t>e.length)throw new Error("Invalid Snappy literal");f=1;for(let n=0;n<t;n++)f+=e[r++]<<8*n}if(r+f>e.length||o+f>n.length)throw new Error("Invalid Snappy literal length");e.copy(n,o,r,r+f),r+=f,o+=f;continue}let l,u;if(1===f){if(r>=e.length)throw new Error("Invalid Snappy copy");l=4+(t>>2&7),u=(224&t)<<3|e[r++]}else if(2===f){if(r+2>e.length)throw new Error("Invalid Snappy copy");l=1+(t>>2),u=e.readUInt16LE(r),r+=2}else{if(r+4>e.length)throw new Error("Invalid Snappy copy");l=1+(t>>2),u=e.readUInt32LE(r),r+=4}if(u<=0||u>o||o+l>n.length)throw new Error("Invalid Snappy offset");for(let e=0;e<l;e++)n[o]=n[o-u],o++}if(o!==n.length)throw new Error("Truncated Snappy stream");return n}(r)}catch{return null}return null}function m(e){if(e.length<4)return[];const t=e.readUInt32LE(e.length-4),n=4*t+4;if(t<1||n>e.length)return[];const r=e.length-n,o=[];let f=0,l=Buffer.alloc(0);for(;f<r;){const t=I(e,f);if(!t)break;f=t.nextOffset;const n=I(e,f);if(!n)break;f=n.nextOffset;const u=I(e,f);if(!u)break;if(f=u.nextOffset,t.value>l.length||f+n.value+u.value>r)break;const i=Buffer.concat([l.subarray(0,t.value),e.subarray(f,f+n.value)]);f+=n.value;const s=Buffer.from(e.subarray(f,f+u.value));f+=u.value,o.push({key:i,value:s}),l=i}return o}function w(e,t){const n=E(e,t);if(!n)return null;const r=E(e,n.nextOffset);return r?n.value>BigInt(Number.MAX_SAFE_INTEGER)||r.value>BigInt(Number.MAX_SAFE_INTEGER)?null:{offset:Number(n.value),size:Number(r.value),bytesRead:r.nextOffset-t}:null}function k(e,t){const n=I(e,t);if(!n)return null;const r=n.nextOffset+n.value;return r>e.length?null:{value:Buffer.from(e.subarray(n.nextOffset,r)),nextOffset:r}}function I(e,t){let n=0,r=0;for(let o=t;o<e.length&&o<t+5;o++){const t=e[o];if(n|=(127&t)<<r,!(128&t))return{value:n>>>0,nextOffset:o+1};r+=7}return null}function E(e,t){let n=0n,r=0n;for(let o=t;o<e.length&&o<t+10;o++){const t=e[o];if(n|=BigInt(127&t)<<r,!(128&t))return{value:n,nextOffset:o+1};r+=7n}return null}function L(e){let t=0n;for(let n=1;n<8;n++)t|=BigInt(e[n]||0)<<BigInt(8*(n-1));return t}export const _test={decodeLocalStorageString:p,parseLocalStorageRecord:h,parseLogRecords:y};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-tools",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "CLI & Node.js library for chrome",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"./bookmarks": "./dist/src/modules/bookmarks.js",
|
|
11
11
|
"./history": "./dist/src/modules/history.js",
|
|
12
12
|
"./cookies": "./dist/src/modules/cookies.js",
|
|
13
|
+
"./local-storage": "./dist/src/modules/local-storage.js",
|
|
13
14
|
"./autofill": "./dist/src/modules/autofill.js",
|
|
14
15
|
"./downloads": "./dist/src/modules/downloads.js",
|
|
15
16
|
"./extensions": "./dist/src/modules/extensions.js",
|