Zig reference
Generated reference for the authgrabber binary.
authgrabber captures the browser’s authenticated state from the active profile and hands it to an automated browser (i.e., obscura). Concretely:
- Session / SSO cookies (
cookies.sqlite): the cookies that keep you signed in across apps (a single sign-on cookie plus per-app session cookies). Opaque cookies at or above 128 characters are flagged as auth candidates. - Stored OAuth tokens (
webappsstore2.sqlite=localStorage): access, refresh and id tokens, classified by key name (access_token,refresh_token,id_token), by JWT shape (eyJ...), or by being a long opaque cookie. JWT payloads are decoded for the claimsexp,iat,iss,sub,aud,scope,name,email,picture. - Fresh tokens on demand: the
logincommand runs the active authorization-code flow (PKCE) to mint a new token instead of reusing what is already stored. - Saved logins (
logins.json/key4.db): the password manager’s stored usernames and passwords, decrypted via theloginscommand using the browser’s NSS library.
It does not handle basic-auth credentials, HTTP auth, client secrets, or anything outside the profile’s SQLite stores.
Security: several commands decrypt real saved secrets, so keep
--values output out of logs and shared files; prefer the default
redacted form.
Global
Section titled “Global”Usage: authgrabber <command> [args...].
Every command targets exactly one profile: the active one by default, or
a specific one passed as [BROWSER:PROFILE] (a Firefox profile name
matching Name=, an absolute path, a bare browser name selecting that
browser’s default profile, or a <browser>:<profile> pair such as
vivaldi:Default).
| Command | Description |
|---|---|
authgrabber discover [BROWSER:PROFILE] |
print the resolved profile directory |
authgrabber user-agent [BROWSER:PROFILE] |
print the user-agent the supported browser profile sends |
authgrabber logins [--values] [BROWSER:PROFILE] |
list saved logins (decrypted via NSS) |
authgrabber login <flags> |
active authorization-code flow (PKCE + localhost callback) |
authgrabber cookies [--values] [--host <s>] [BROWSER:PROFILE] |
list cookies from the selected profile |
authgrabber tokens [--json] [--values] [--host <s>] [BROWSER:PROFILE] |
list classified auth tokens |
authgrabber export-session [--format json|obscura] [--values] [--out <file>] [--host <s>] [BROWSER:PROFILE] |
export session |
authgrabber storage [--values] [--host <s>] [BROWSER:PROFILE] |
list localStorage per origin |
authgrabber history [--values] [--json] [--limit N] [--host <s>] [BROWSER:PROFILE] |
list Firefox browsing history (redacted unless –values) |
authgrabber query <DB> <SQL> |
run a SQL SELECT against a SQLite db |
PROFILE may be a profile name or an absolute path.
The listing commands (cookies, storage, tokens) and
export-session accept --host <substring>, which keeps only entries
whose host or origin contains the substring, case-insensitively. Without
it, every host in the profile is included.
discover
Section titled “discover”Resolve and print the active profile directory.
authgrabber discoverauthgrabber discover vivaldi:Default/Users/you/Library/Application Support/Firefox/Profiles/xxxxxxxx.default-release/Users/you/Library/Application Support/Vivaldi/User Data/DefaultSupported browsers: firefox (default), zen, vivaldi, brave, edge,
chromium, chrome.
logins
Section titled “logins”List saved logins (username/password) from the password manager, decrypted via the browser’s own NSS library.
authgrabber loginsauthgrabber logins --valueshost.example.com username-len=12 password-len=14host.example.com username=alice@example password=correct-horseDefault output is hostname username-len=<n> password-len=<n> (values
redacted); --values prints the decrypted credentials.
history
Section titled “history”List Firefox browsing history, newest visit first. Reads places.sqlite
(moz_historyvisits joined to moz_places); the database is copied with
its WAL sidecars before reading, so a running browser is not disturbed.
Firefox only: Chromium history is not implemented.
authgrabber historyauthgrabber history --values --limit 20authgrabber history --host example.com2026-09-15T21:43:27Z https://app.example.com <redacted, url-len=41, title-len=22>2026-09-15T07:54:10Z https://app.example.com <redacted, url-len=68, title-len=40>Default output is visited-at origin <redacted, url-len=<n>, title-len=<n>>:
the origin is enough to recognise a site while the path, query and page
title stay hidden. --values prints the full URL and title, --host <substring> filters case-insensitively, and --limit <n> caps the row
count (newest first).
cookies
Section titled “cookies”List session and SSO cookies from the cookie store.
authgrabber cookiesauthgrabber cookies --valuesauthgrabber cookies --host example.comsession-token app.example.com 212refresh-token login.example.com 212persistent-auth example.com 1383Opaque cookies at or above 128 characters are flagged as auth candidates. Chromium profiles (Vivaldi, Brave, Edge, Chrome, Chromium) are decrypted with the OS keychain via the os_crypt scheme.
storage
Section titled “storage”List localStorage entries per origin (Firefox webappsstore2.sqlite, Chromium LevelDB log files).
authgrabber storageauthgrabber storage --valuesauthgrabber storage --host example.com[https://example.com]access_token = eyJhbGciOi...refresh_token = eyJhbGciOi...tokens
Section titled “tokens”List classified auth tokens. Tokens are classified by key name
(access_token, refresh_token, id_token), by JWT shape
(eyJ...), or by being a long opaque cookie. JWT payloads are decoded
for the claims exp, iat, iss, sub, aud, scope, name,
email, picture.
Pass --host <substring> to keep only tokens from matching hosts or
origins, and --json for a machine-readable listing.
user-agent
Section titled “user-agent”Print the user-agent (UA) string the supported browser profile sends on
the wire, for passing to obscura’s --user-agent (so the bot presents as
the same browser that was authenticated).
authgrabber user-agentMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36 Vivaldi/8.2.4133.47- A
general.useragent.overridepref in the profile’sprefs.js, if set, is returned verbatim (authoritative). - Otherwise the default UA is reconstructed from the browser version
recorded in the profile’s
compatibility.ini/LastVersionplus the host OS. - For a Chromium profile (
vivaldi:Default, …), theChrome/token uses the Chromium base read at runtime from the profile’sPreferences(extensions.last_chrome_version), so it tracks browser upgrades. - Example use:
obscura fetch <url> --storage-dir <dir> --stealth --user-agent "$(authgrabber user-agent)".
export-session
Section titled “export-session”Emit an obscura session bundle (cookies.json) for the automated browser.
Pass --host <substring> to bundle only the hosts a task needs, instead
of every credential in the profile.
authgrabber export-session --format obscura --values --out ~/.config/authgrabber/session/cookies.jsonauthgrabber export-session --format obscura --values --host example.com --out ~/.config/authgrabber/session/cookies.jsonwrote 12 cookies to /Users/you/.config/authgrabber/session/cookies.json (mode 0600)The session directory lives under the user’s private home location
(~/.config/authgrabber/session), never /tmp.
Run the active OAuth authorization-code flow (PKCE + localhost callback) to mint a fresh token.
authgrabber login --auth-url https://provider.example/authorize --client-id abc123 --token-url https://provider.example/token --scope openidopened the authorization URL in your default browser; waiting for the callback...token response redacted; use --values to print itThe callback binds an OS-assigned ephemeral port (no fixed-port squatting),
the state is compared in constant time, and the token exchange is a POST
with grant_type=authorization_code plus the PKCE code_verifier.
Run a SQL SELECT against any SQLite database.
authgrabber query <DB> <SQL>Output is the result rows, columns separated by <TAB>; the database is
read together with its -wal sidecar. Errors are reported clearly:
OpenFailed, PrepareFailed, database is locked (Firefox running?); retry or close Firefox.
Build the binary with the Zig build system (0.16.0). The package manifest:
.{ .name = .authgrabber, .version = "0.0.0", .fingerprint = 0x94a8b077e1164c1d, .minimum_zig_version = "0.16.0", .paths = .{ "build.zig", "build.zig.zon", "src", },}```
```shzig buildzig build testzig build crossjust releasejust release-crosszig build produces zig-out/bin/authgrabber (a ~1.5 MB
ReleaseSmall binary), zig build cross cross-compiles for x86_64 and
arm64 on Windows, Linux and macOS, and just release runs the optimized
native build.
Exit codes
Section titled “Exit codes”0success.- Non-zero on errors (unrecognized command, missing args, or a command error).
Source API
Section titled “Source API”The public API of every module, parsed from the source at generation
time (including the /// doc comments). pub fn entries show their
signature; pub const entries show the full declaration.
classify.zig
Section titled “classify.zig”pub const Store
Section titled “pub const Store”Where a candidate value was found.
pub const Store = enum { cookie, localStorage };pub const Token
Section titled “pub const Token”A classified token.
pub const Token = struct { store: Store, origin: []const u8, name: []const u8, value: []const u8 = "", kind: []const u8, expiry: ?i64 = null, issued_at: ?i64 = null, scope: ?[]const u8 = null, audience: ?[]const u8 = null, subject: ?[]const u8 = null, issuer: ?[]const u8 = null, name_claim: ?[]const u8 = null, email: ?[]const u8 = null, picture: ?[]const u8 = null,};pub const opaque_min_len
Section titled “pub const opaque_min_len”Opaque session cookies at or above this length are treated as auth candidates even when their name is not a known token key and they are not a JWT.
pub const opaque_min_len: usize = 128;pub fn classifyToken
Section titled “pub fn classifyToken”Classify a candidate value from a cookie or localStorage key.
Returns a Token when the key matches a known token name, the value is a
JWT, or (for cookies) the value is long enough to be an opaque session
token; otherwise null (noise). All strings are owned by allocator.
pub fn classifyToken( allocator: std.mem.Allocator, store: Store, origin: []const u8, name: []const u8, value: []const u8,) !?Tokenstorage.zig
Section titled “storage.zig”pub const Item
Section titled “pub const Item”A single localStorage entry.
pub const Item = struct { key: []const u8, value: []const u8,};pub const Origin
Section titled “pub const Origin”One origin’s extracted web storage.
pub const Origin = struct { name: []const u8, items: []Item,};pub fn extractLocalStorage
Section titled “pub fn extractLocalStorage”Extract localStorage from a Firefox profile.
Enumerates storage/default/<origin>/ and reads each origin’s
ls/data.sqlite (data table) into key/value pairs. The stored value
BLOBs are plain UTF-8 text for localStorage. All returned strings are
owned by allocator (pass an arena so you never free individually).
Container-partitioned origins (name carries a ^userContextId= suffix)
are returned as-is.
pub fn extractLocalStorage( allocator: std.mem.Allocator, io: std.Io, profile_dir: []const u8,) ![]Originhistory.zig
Section titled “history.zig”pub const Entry
Section titled “pub const Entry”One history visit, joined with the visited page.
pub const Entry = struct { url: []const u8, title: []const u8, /// Visit time in microseconds since the Unix epoch (Firefox `visit_date`). visited_at_us: i64, /// Total number of recorded visits for the URL. visit_count: i64,};pub const default_limit
Section titled “pub const default_limit”Rows returned when the caller does not ask for a different limit.
pub const default_limit: usize = 100;pub fn extract
Section titled “pub fn extract”Extract browsing history from a Firefox (or Firefox-based, e.g. Zen) profile.
Reads places.sqlite: moz_historyvisits joined to moz_places, newest
visit first, skipping hidden (internal) places. The live database is locked
while the browser runs, so the main file and its -wal/-shm sidecars are
copied to a temp dir and read from there – the same snapshot approach as
cookies.extract. All returned strings are owned by allocator (pass an
arena so you never free individually).
pub fn extract( allocator: std.mem.Allocator, io: std.Io, env: *const std.process.Environ.Map, profile_dir: []const u8, host_filter: ?[]const u8, limit: usize,) ![]Entrypub fn query
Section titled “pub fn query”Run the history query against an already-readable places.sqlite.
The optional host_filter is applied in SQL, before limit, so a filtered
listing always fills up to the requested row count. Split out from
extract so the SQL and row parsing can be exercised against a fixture
database instead of a live profile.
pub fn query( allocator: std.mem.Allocator, db_path: []const u8, host_filter: ?[]const u8, limit: usize,) ![]Entrypub fn formatUtc
Section titled “pub fn formatUtc”Format a Firefox visit time (microseconds since the Unix epoch) as an
ISO-8601 UTC timestamp. Returns "" for pre-epoch or unrepresentable
values, so a corrupt row cannot poison the whole listing.
pub fn formatUtc(buf: []u8, visited_at_us: i64) []const u8pub fn originOf
Section titled “pub fn originOf”Reduce a URL to its origin (scheme://host[:port]), dropping path, query,
fragment and any userinfo. Returns "" when there is no scheme://.
pub fn originOf(url: []const u8) []const u8cookies.zig
Section titled “cookies.zig”pub const Cookie
Section titled “pub const Cookie”A row from moz_cookies.
pub const Cookie = struct { host: []const u8, name: []const u8, value: []const u8, path: []const u8, expiry: i64, is_secure: bool, is_http_only: bool, same_site: i32,};pub fn extract
Section titled “pub fn extract”Extract cookies from a Firefox profile.
The live cookies.sqlite is locked while Firefox runs, so the main DB and
its -wal/-shm sidecars are copied to a temp dir and read from there.
All returned strings are owned by allocator (pass an arena).
pub fn extract( allocator: std.mem.Allocator, io: std.Io, env: *const std.process.Environ.Map, profile_dir: []const u8,) ![]Cookieoauth_flow.zig
Section titled “oauth_flow.zig”pub const Pkce
Section titled “pub const Pkce”Proof Key for Code Exchange (RFC 7636) values.
pub const Pkce = struct { verifier: []const u8, challenge: []const u8, method: []const u8 = "S256",};pub fn codeVerifier
Section titled “pub fn codeVerifier”Random code verifier: 32 bytes via the Io CSPRNG, base64url (no padding).
pub fn codeVerifier(allocator: std.mem.Allocator, io: std.Io) ![]const u8pub fn codeChallenge
Section titled “pub fn codeChallenge”S256 code challenge = base64url(sha256(verifier)).
pub fn codeChallenge(allocator: std.mem.Allocator, verifier: []const u8) ![]const u8pub fn stateToken
Section titled “pub fn stateToken”Random state token.
pub fn stateToken(allocator: std.mem.Allocator, io: std.Io) ![]const u8pub fn authorizeUrl
Section titled “pub fn authorizeUrl”Build the authorization URL (RFC 6749 section 4.1.1).
pub fn authorizeUrl( allocator: std.mem.Allocator, auth_url: []const u8, client_id: []const u8, redirect_uri: []const u8, scope: ?[]const u8, state: []const u8, pkce: Pkce,) ![]const u8pub const CallbackResult
Section titled “pub const CallbackResult”Result captured from the localhost redirect callback.
pub const CallbackResult = struct { code: ?[]const u8 = null, state: ?[]const u8 = null,};pub fn tokenExchange
Section titled “pub fn tokenExchange”Exchange the authorization code for tokens (RFC 6749 section 4.1.3). Returns the raw response body (JSON). Caller owns it.
pub fn tokenExchange( allocator: std.mem.Allocator, io: std.Io, token_url: []const u8, client_id: []const u8, code: []const u8, verifier: []const u8, redirect_uri: []const u8,) ![]const u8pub fn accessToken
Section titled “pub fn accessToken”Extract an access token from a token-endpoint JSON body (best-effort).
pub fn accessToken(allocator: std.mem.Allocator, body: []const u8) ?[]const u8pub fn secureEq
Section titled “pub fn secureEq”Constant-time equality for byte strings (use for state/token comparisons).
pub fn secureEq(a: []const u8, b: []const u8) boolpub fn listen
Section titled “pub fn listen”Bind a localhost TCP listener. When port is 0 the OS assigns an
ephemeral port; read it back with boundPort. Caller must deinit.
pub fn listen(io: std.Io, port: u16) !std.Io.net.Serverpub fn boundPort
Section titled “pub fn boundPort”The actual port a bound server is listening on (resolved ephemeral).
pub fn boundPort(server: *const std.Io.net.Server) u16pub fn acceptCallback
Section titled “pub fn acceptCallback”Wait for one connection on an already-bound server, read the request, parse the query parameters, and respond. Returns the captured code/state.
pub fn acceptCallback( allocator: std.mem.Allocator, io: std.Io, server: *std.Io.net.Server,) !CallbackResultsqlite.zig
Section titled “sqlite.zig”pub const Table
Section titled “pub const Table”A parsed result set: rows, each a slice of column strings.
pub const Table = [][]const []const u8;pub fn exec
Section titled “pub fn exec”Execute one or more SQL statements (no result rows), e.g. CREATE/INSERT.
pub fn exec( allocator: std.mem.Allocator, db_path: []const u8, sql: []const u8,) !voidpub fn query
Section titled “pub fn query”Run a SQL SELECT against a SQLite database and return the parsed rows.
Uses the vendored SQLite library in-process, which reads the database file
together with its -wal sidecar, so committed-but-uncheckpointed rows are
visible and reads are safe while Firefox is running. All strings are owned
by allocator (pass an arena so you never free individually).
pub fn query( allocator: std.mem.Allocator, db_path: []const u8, sql: []const u8,) !Tablepub fn queryBusy
Section titled “pub fn queryBusy”Like query, but with an explicit lock wait budget in milliseconds.
The 5s default keeps the single cookie/login DBs usable while the browser
holds them; the localStorage scan uses the immutable mode so it never
blocks on the running browser.
pub fn queryBusy( allocator: std.mem.Allocator, db_path: []const u8, sql: []const u8, busy_ms: c_int,) !Tablepub fn queryImmutable
Section titled “pub fn queryImmutable”Like query, but opens with SQLite’s immutable=1 URI flag: file locking
is skipped entirely, so reads never block on the running browser holding
per-origin localStorage databases (a snapshot read; in-flight writes may
be missed for that origin, surfaced as a per-file error the caller skips).
pub fn queryImmutable( allocator: std.mem.Allocator, db_path: []const u8, sql: []const u8,) !Tablepub fn queryBytes
Section titled “pub fn queryBytes”Like query, but reads every column as raw bytes via column_blob so
binary BLOBs (e.g. encrypted cookie values) are not truncated at NUL.
pub fn queryBytes( allocator: std.mem.Allocator, db_path: []const u8, sql: []const u8,) !Tablepub fn queryScalar
Section titled “pub fn queryScalar”Run a scalar query (e.g. SELECT count(*) FROM ...) and return the trimmed
single value, or null if the result set is empty.
pub fn queryScalar( allocator: std.mem.Allocator, db_path: []const u8, sql: []const u8,) !?[]const u8nss.zig
Section titled “nss.zig”pub const Nss
Section titled “pub const Nss”pub const Nss = struct { handle: ?*anyopaque, d_init: NssInit, d_shutdown: NssShutdown, d_slot: Pk11GetSlot, d_checkpw: Pk11CheckPw, d_sdr: Pk11SdrDecrypt, d_free: SecItemFreeItem, slot: ?*anyopaque = null,};pub fn open
Section titled “pub fn open”Load libnss3 and initialize NSS on the given profile directory. Only implemented on macOS; other targets are a compile-time no-op.
pub fn open(allocator: std.mem.Allocator, io: std.Io, profile_dir: []const u8) !Nsspub fn deinit
Section titled “pub fn deinit”pub fn deinit(nss: *Nss) voidpub fn decrypt
Section titled “pub fn decrypt”Decrypt one base64-encoded encrypted value (username or password). The caller owns the returned slice.
pub fn decrypt(nss: *Nss, allocator: std.mem.Allocator, b64: []const u8) ![]u8profile.zig
Section titled “profile.zig”pub const Os
Section titled “pub const Os”Host operating system.
pub const Os = enum { macos, linux, windows,
pub fn label(self: Os) []const u8 { return switch (self) { .macos => "macos", .linux => "linux", .windows => "windows", }; }};pub const ProfileEntry
Section titled “pub const ProfileEntry”A Firefox profile section parsed from profiles.ini.
pub const ProfileEntry = struct { name: ?[]const u8 = null, path: ?[]const u8 = null, is_relative: bool = true, is_default: bool = false,};pub const Profile
Section titled “pub const Profile”A resolved profile directory.
pub const Profile = struct { /// The profile's path as given in `profiles.ini` (possibly relative). raw_path: []const u8, /// Absolute path to the resolved profile directory. dir: []const u8,};pub const Browser
Section titled “pub const Browser”A supported browser backend. Selection stays inside the existing [PROFILE]
argument as a browser:profile prefix (e.g. vivaldi:Default), so no CLI
command or flag changes and Firefox defaults when the prefix is absent.
pub const Browser = enum { firefox, zen, vivaldi, brave, edge, chromium, chrome,
pub fn fromName(name: []const u8) ?Browser { const map = .{ .{ "firefox", Browser.firefox }, .{ "zen", Browser.zen }, .{ "vivaldi", Browser.vivaldi }, .{ "brave", Browser.brave }, .{ "edge", Browser.edge }, .{ "chromium", Browser.chromium }, .{ "chrome", Browser.chrome }, }; inline for (map) |m| { if (std.ascii.eqlIgnoreCase(name, m[0])) return m[1]; } return null; }
/// Chromium data-dir name used under the browser's config root. fn dataDir(self: Browser) []const []const u8 { return switch (self) { .firefox, .zen => &.{}, .vivaldi => &.{"Vivaldi"}, .brave => &.{ "BraveSoftware", "Brave-Browser" }, .edge => &.{"Microsoft Edge"}, .chromium => &.{"Chromium"}, .chrome => &.{ "Google", "Chrome" }, }; }
pub fn isChromium(self: Browser) bool { return switch (self) { .firefox, .zen => false, else => true, }; }};pub fn detectHost
Section titled “pub fn detectHost”Detect the host OS.
Windows sets %OS% = Windows_NT in the environment, which we honour for
hosts that inherit a Windows environment. Otherwise the compile-time target
is used: each shipped cross-compiled binary targets exactly one OS (a
Windows binary cannot run on Linux), so builtin.os.tag is correct for the
running host. (builtin.cpu.arch is the field that must not be trusted,
since the same binary is shipped for both archs.)
pub fn detectHost(env: *const std.process.Environ.Map) !Ospub fn profileRootDir
Section titled “pub fn profileRootDir”Absolute path of the directory that contains profiles.ini (Firefox-family).
pub fn profileRootDir( allocator: std.mem.Allocator, os: Os, browser: Browser, env: *const std.process.Environ.Map,) ![]const u8pub fn chromiumRootDir
Section titled “pub fn chromiumRootDir”Absolute path of the Chromium-family browser’s data root, which contains
the profile subdirs (Default, Profile 1, …).
pub fn chromiumRootDir( allocator: std.mem.Allocator, os: Os, browser: Browser, env: *const std.process.Environ.Map,) ![]const u8pub fn discover
Section titled “pub fn discover”Resolve the active (or requested) profile directory.
override may be a profile name (matched against Name= for Firefox), an
absolute path, or a browser:profile prefix to select another browser
(e.g. vivaldi:Default). When absent, the Firefox active profile is
chosen. The returned Profile.dir is an allocated absolute path (caller
frees it).
pub fn discover( allocator: std.mem.Allocator, io: std.Io, override: ?[]const u8, env: *const std.process.Environ.Map,) !Profilepub fn browserFromOverride
Section titled “pub fn browserFromOverride”Split a browser:profile override; returns the browser (firefox default).
pub fn browserFromOverride(override: ?[]const u8) Browserpub const Parsed
Section titled “pub const Parsed”Parse profiles.ini contents.
pub const Parsed = struct { profiles: std.ArrayList(ProfileEntry) = .empty, /// `Default=` paths from `[Install*]` sections (the profiles Firefox runs). install_defaults: std.ArrayList([]const u8) = .empty,};pub fn userAgent
Section titled “pub fn userAgent”Return the user-agent the active Firefox profile sends on the wire.
A general.useragent.override pref in prefs.js is authoritative and is
returned verbatim. Otherwise the default UA is reconstructed from the
Firefox version (compatibility.ini LastVersion) and the host OS. The
caller owns the returned string.
pub fn userAgent( allocator: std.mem.Allocator, io: std.Io, profile_dir: []const u8,) ![]const u8chromium.zig
Section titled “chromium.zig”pub fn osEncryptedKey
Section titled “pub fn osEncryptedKey”Raw (base64-decoded) os_crypt.encrypted_key bytes from Local State
(or the profile’s Preferences for browsers that keep it there). Caller
owns the result.
pub fn osEncryptedKey( allocator: std.mem.Allocator, io: std.Io, profile_dir: []const u8,) ![]u8pub fn encryptionKey
Section titled “pub fn encryptionKey”Return the actual AES key used for cookie/login encryption, per platform. The caller owns the returned bytes.
pub fn encryptionKey( allocator: std.mem.Allocator, io: std.Io, browser: profile.Browser, profile_dir: []const u8,) ![]const u8pub fn userAgent
Section titled “pub fn userAgent”The user-agent a Chromium-family browser sends, reconstructed from its
version (data root’s Last Version), the Chromium base (the profile’s
Preferences, read at runtime so it tracks upgrades), and the host OS.
Caller owns result.
pub fn userAgent( allocator: std.mem.Allocator, io: std.Io, browser: profile.Browser, profile_dir: []const u8,) ![]const u8pub const LoginInfo
Section titled “pub const LoginInfo”A saved login (username/password) from a Chromium Login Data store.
pub const LoginInfo = struct { origin: []const u8, username: []const u8, password: []const u8,};pub fn extractLogins
Section titled “pub fn extractLogins”Read saved logins from a Chromium Login Data database, decrypting the
password values with the os_crypt key. Caller owns the slice and strings.
pub fn extractLogins( allocator: std.mem.Allocator, io: std.Io, env: *const std.process.Environ.Map, browser: profile.Browser, profile_dir: []const u8,) ![]LoginInfopub const LocalStorageEntry
Section titled “pub const LocalStorageEntry”A localStorage entry from a Chromium profile.
pub const LocalStorageEntry = struct { origin: []const u8, key: []const u8, value: []const u8,};pub fn snappyDecompress
Section titled “pub fn snappyDecompress”Snappy decompression ported line-by-line from golang/snappy decode_other.go. Caller owns the result.
pub fn snappyDecompress(allocator: std.mem.Allocator, src: []const u8) ![]u8pub fn parseSSTable
Section titled “pub fn parseSSTable”Parse a LevelDB SSTable (.ldb): footer -> index block -> data blocks, Snappy-decompressing each block, and append localStorage entries.
pub fn parseSSTable( allocator: std.mem.Allocator, out: *std.ArrayList(LocalStorageEntry), data: []const u8,) !voidpub fn extractLocalStorage
Section titled “pub fn extractLocalStorage”Read localStorage entries from the LevelDB write-ahead logs AND the
SSTables: Local Storage/leveldb/*.log (recent, uncompressed) and
*.ldb (older, Snappy-compressed blocks). Caller owns the slice/strings.
pub fn extractLocalStorage( allocator: std.mem.Allocator, io: std.Io, profile_dir: []const u8,) ![]LocalStorageEntrypub fn decryptCookieValue
Section titled “pub fn decryptCookieValue”Decrypt one Chromium encrypted value (v10 or legacy) with the os_crypt
key. The macOS keychain provider uses AES-128-CBC with the fixed 16-space
IV; newer Chromium prepends a 32-byte SHA256(host) hash to cookie values,
which is stripped here. Also tries the empty-key fallback and AES-GCM
(other providers). The caller owns the result.
pub fn decryptCookieValue(allocator: std.mem.Allocator, key: []const u8, ev: []const u8, strip: usize) ![]u8pub fn extractCookies
Section titled “pub fn extractCookies”Extract cookies from a Chromium profile’s Cookies database, decrypting
values with the os_crypt key. Returns the same cookies.Cookie shape as
the Firefox extractor. Caller owns the slice and its strings.
pub fn extractCookies( allocator: std.mem.Allocator, io: std.Io, env: *const std.process.Environ.Map, browser: profile.Browser, profile_dir: []const u8,) ![]cookies.Cookie