Sweet Cookie

repository·main·Indexed 41 days ago

https://github.com/steipete/sweet-cookie

A TypeScript library and CLI for extracting browser cookies from local profiles (Chrome, Edge, Firefox, Safari) or inline payloads without native Node.js addons. It includes a Manifest V3 Chrome extension for exporting cookies and provides utilities like getCookies() for retrieval and toCookieHeader() for HTTP header transformation. Supports Node.js 22+ and Bun.

Tokens
12.4K
Snippets
37
Records
49
Agent score
51%

What's inside Sweet Cookie

  1. Understand the cookie extraction provider order

    main

    Sweet Cookie follows a specific priority order when searching for cookies. This ensures that explicit, provided data is preferred over local browser data.

    1. Inline Sources: If inlineCookiesJson, inlineCookiesBase64, or inlineCookiesFile are provided, they are checked first. The first non-empty source wins. If an inline source is found, local browser stores are skipped. Note: If an inline source is provided but fails due to unsupported isolation, the library returns no cookies rather than falling back to local browsers.

    2. Local Browsers: If no inline source is valid, the library queries local browsers in the order declared in the browsers option:

      • Chrome: Uses node:sqlite or bun:sqlite to query a copy of the DB. Decryption methods vary by OS (macOS Keychain, Windows DPAPI, Linux v10/v11 keyring).
      • Edge: Follows the Chromium decryption path for the current OS.
      • Firefox: Uses node:sqlite or bun:sqlite to query cookies.sqlite.
      • Safari: Parses Cookies.binarycookies files directly.
  2. Handle cookie scope and deduplication

    main

    Sweet Cookie preserves the distinction between hostOnly cookies (matching exactly one hostname) and domain cookies (matching subdomains). Because scope is part of deduplication, a single name might appear multiple times if the scopes differ.

    • Default behavior: toCookieHeader() retains both scoped versions.
    • Deduplication: If your target requires exactly one value per cookie name, pass { dedupeByName: true } to toCookieHeader().

    Exclusions: The library excludes Chromium partitioned cookies and Firefox partitioned/container-scoped cookies from local reads because their isolation context cannot be preserved during replay.

  3. Select specific browser profiles

    main

    When using the browsers option, you can target specific profiles using profile selectors. A selector can be a display name, a profile directory, or a cookie database path.

    To read every local profile supported by a backend, use the ALL_PROFILES constant.

    Browser Defaults:

    • Chrome/Edge: Uses the default profile if no selector is provided.
    • Firefox: Prefers default-release.
    • Safari: Uses a cookie-file override instead of a profile selector.

    Linux Specifics:

    • Chrome: Searches native and Flatpak Google Chrome roots by default. Use chromiumBrowser to target specific Chromium or Brave roots.
    • Firefox: Searches native, Snap, and Flatpak profile roots.
    import { ALL_PROFILES, getCookies } from "@steipete/sweet-cookie";
    
    const { cookies } = await getCookies({
    	url: "https://example.com/",
    	browsers: ["chrome"],
    	chromeProfile: ALL_PROFILES,
    });
  4. How inline sources and browser backends work together

    main

    Sweet Cookie follows a specific execution order to optimize performance and avoid system prompts:

    1. Inline Sources: These run first in the order of JSON, then base64, then file. If an inline source yields cookies, Sweet Cookie returns immediately and does not attempt to read local browser stores. This avoids database locks and OS credential prompts.
    2. Browser Backends: If no inline source yields cookies, the configured browser backends run in order. The default order is Chrome, Safari, then Firefox.

    Modes of operation:

    • mode: "merge": Combines results from all backends. If a cookie with the same name, domain, host-only scope, and path exists in multiple backends, the value from the first backend encountered is preserved.
    • mode: "first": Returns the result from the very first backend that contains any cookies.
  5. Select browser profiles for extraction

    main

    When using the library, you can target specific browser profiles for Chrome, Edge, and Firefox.

    Chromium (Chrome & Edge)

    • Default: If no profile is specified, the library uses the default Chromium profile (Default).
    • Selectors: You can provide a profile directory (e.g., Default, Profile 2), a display name found in Chromium's Local State (e.g., Work), a full directory path, or a direct path to the Cookies database.
    • Multiple Profiles: Pass a string array to read multiple selected profiles.
    • All Profiles: Use the ALL_PROFILES sentinel to discover and read every local profile for that backend.
    • Edge Specific: Use edgeProfile. If unset, it falls back to the value of SWEET_COOKIE_CHROME_PROFILE.

    Firefox

    • Default: Uses default-release if present; otherwise, the first discovered profile.
    • Selectors: Accepts a profile name, a profile directory path, or a path to cookies.sqlite.
    • Multiple Profiles: Pass a string array to read multiple selected profiles.
    • All Profiles: Use the ALL_PROFILES sentinel to discover every local Firefox profile.

    Safari

    • Safari does not support profile selection. Use safariCookiesFile to provide an override path to a Cookies.binarycookies file or an array of paths.
  6. Select browser profiles for Chrome, Edge, and Firefox

    main

    You can specify which profile to use for different browsers to target specific user data.

    Chrome and Edge selectors accept:

    • A profile directory name (e.g., Default, Profile 2).
    • A display name from Chromium's Local State (e.g., Work).
    • A full profile directory path.
    • A direct path to a Network/Cookies or Cookies database.
    • An array of selectors.
    • The ALL_PROFILES sentinel.

    Firefox selectors accept:

    • A profile name or directory.
    • A cookies.sqlite path.
    • An array of selectors.
    • The ALL_PROFILES sentinel.
    • Note: If omitted, Firefox uses default-release or the first discovered profile.

    Safari:

    • Has no profile selector. Use safariCookiesFile to provide explicit Cookies.binarycookies paths.

    Example:

    import { ALL_PROFILES, getCookies } from "@steipete/sweet-cookie";
    
    // Target specific Chrome profiles
    await getCookies({
    	url: "https://example.com/",
    	browsers: ["chrome"],
    	chromeProfile: ["Default", "Profile 2"],
    });
    
    // Target all Firefox profiles
    await getCookies({
    	url: "https://example.com/",
    	browsers: ["firefox"],
    	firefoxProfile: ALL_PROFILES,
    });
    import { ALL_PROFILES, getCookies } from "@steipete/sweet-cookie";
    
    await getCookies({
    	url: "https://example.com/",
    	browsers: ["chrome"],
    	chromeProfile: ["Default", "Profile 2"],
    });
    
    await getCookies({
    	url: "https://example.com/",
    	browsers: ["firefox"],
    	firefoxProfile: ALL_PROFILES,
    });
  7. Use the Chrome Extension for cookie export

    main

    If local database access is blocked (e.g., by app-bound encryption, keychain prompts, or remote execution requirements), use the Manifest V3 extension located in apps/extension.

    1. Build the extension.
    2. Load the generated apps/extension/dist directory in Chrome.
    3. Use the extension to export cookies as JSON, base64, or a file.
    4. Pass the exported payload to Sweet Cookie using inlineCookiesJson, inlineCookiesBase64, or inlineCookiesFile.
  8. Use the Sweet Cookie Chrome Extension export formats

    main

    The apps/extension (Chrome MV3) provides an "escape hatch" for cases where local library reads fail (e.g., app-bound cookies or locked-down OS). It supports two export formats:

    1. JSON (Preferred)

    Exports a JSON file containing metadata and a cookies array compatible with CDP-ish shapes.

    Example JSON Structure:

    {
    	"version": 1,
    	"generatedAt": "2025-12-27T18:00:00.000Z",
    	"source": "sweet-cookie",
    	"browser": "chrome",
    	"targetUrl": "https://chatgpt.com/",
    	"origins": ["https://chatgpt.com/"],
    	"cookies": [
    		{
    			"name": "__Secure-next-auth.session-token",
    			"value": "…",
    			"domain": "chatgpt.com",
    			"path": "/",
    			"secure": true,
    			"httpOnly": true,
    			"sameSite": "Lax",
    			"expires": 1767225600
    		}
    	]
    }

    2. Base64 Payload

    This is the exact same JSON structure as above, but the entire JSON string is Base64-encoded to make it clipboard-friendly.

    Note on expires: The field uses Unix seconds when available; it is omitted for session cookies.

  9. Build and load the Sweet Cookie Chrome extension

    main

    The sweet-cookie-extension (located in apps/extension) allows you to export cookies from your current Chrome profile. It supports target URLs, extra origins, and cookie-name allowlists, with outputs in JSON, base64, or file formats.

    Build Steps

    From the repository root, run:

    pnpm install --frozen-lockfile
    pnpm --filter sweet-cookie-extension build

    The build outputs an unpacked extension directory at apps/extension/dist/ containing manifest.json, popup.html, popup.css, and popup.js.

    Loading in Chrome

    1. Open chrome://extensions in Chrome.
    2. Enable Developer mode.
    3. Click Load unpacked.
    4. Select the apps/extension/dist directory.
    5. Open the extension from the toolbar's Extensions menu in the profile you wish to export from.

    Important: Do not load apps/extension or apps/extension/src directly. You must load the dist directory produced by the build command to ensure all compiled assets are present. If you change the source code, run the build command again and click Reload on the extension card in chrome://extensions.

  10. Install @steipete/sweet-cookie

    main

    You can run the Sweet Cookie CLI without installing it using npx, or add the library to your project via npm.

    Requirements:

    • Node.js 22 or newer.
    • Bun is supported via bun:sqlite.

    CLI (no install):

    npx @steipete/sweet-cookie --help

    Library (npm):

    npm install @steipete/sweet-cookie
  11. Configure Sweet Cookie via Environment Variables

    main

    You can configure the default behavior of Sweet Cookie using environment variables. Note that explicit function options take precedence over these variables.

    VariablePurpose
    SWEET_COOKIE_BROWSERSDefault browser order as a comma- or space-separated list.
    SWEET_COOKIE_SOURCESDefault browser order as a comma- or space-separated list.
    SWEET_COOKIE_MODEDefault merge or first mode.
    SWEET_COOKIE_CHROME_PROFILEDefault Chrome profile selector; also the Edge fallback when its own variable is unset.
    SWEET_COOKIE_EDGE_PROFILEDefault Edge profile selector.
    SWEET_COOKIE_FIREFOX_PROFILEDefault Firefox profile selector.
    SWEET_COOKIE_LINUX_KEYRINGLinux keyring mode: gnome, kwallet, or basic.
    SWEET_COOKIE_CHROME_SAFE_STORAGE_PASSWORDLinux Chrome safe-storage password override.
    SWEET_COOKIE_CHROMIUM_SAFE_STORAGE_PASSWORDLinux Chromium safe-storage password override.
    SWEET_COOKIE_EDGE_SAFE_STORAGE_PASSWORDLinux Edge safe-storage password override.
    SWEET_COOKIE_BRAVE_SAFE_STORAGE_PASSWORDLinux Brave safe-storage password override.