### JavaScript IndexedDB Database Setup Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_test_indexeddb.html Sets up an IndexedDB database named 'MyTestDatabase' with version 1. It defines an object store named 'store' with 'id' as the key path. This function handles database opening, success, error, and upgrade scenarios. ```javascript var setupDb = async () =>{ console.log("setupDb entered"); let db; let request = indexedDB.open("MyTestDatabase", 1); request.onerror = function(event) { console.log(event.target); }; request.onsuccess = function(event) { db = event.target.result; console.log("setupDb>request.onsuccess"); }; request.onupgradeneeded = function(event) { console.log("setupDb>request.onupgradeneeded"); let db = event.target.result; let objectStore = db.createObjectStore("store", { keyPath: "id" }); } } ``` -------------------------------- ### CLI Usage for ccl_chromium_cache Module Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md This example shows the command-line interface usage for the `ccl_chromium_cache.py` script. It is designed to dump cache data (both block file and simple formats) and collate metadata into a CSV file. ```shell USAGE: ccl_chromium_cache.py ``` -------------------------------- ### Setup IndexedDB Databases and Object Stores Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_many_indexeddb_databases.html Initializes multiple IndexedDB databases and creates object stores within them. The first database is populated with numerous object stores, while subsequent databases receive a single object store. Handles database opening errors and upgrade events. ```javascript const databaseCount = 260; const objectStoreCount = 260; var setupDb = async () => { console.log("setupDb entered"); let db; let request; for (let i = 0; i < databaseCount; i++) { request = indexedDB.open(`MyTestDatabase${i}`, 1); request.onerror = function(event) { console.log(event.target); }; request.onsuccess = function(event) { db = event.target.result; console.log("setupDb>request.onsuccess"); }; request.onupgradeneeded = function(event) { console.log("setupDb>request.onupgradeneeded"); let db = event.target.result; if (i == 0) { for (let j = 0; j < objectStoreCount; j++) { let objectStore = db.createObjectStore(`store${j}`, { keyPath: "id" }); } } else { let objectStore = db.createObjectStore("store", { keyPath: "id" }); } }; } } ``` -------------------------------- ### Reading Chromium Session Storage Records Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md This Python code snippet shows how to read Session Storage data from a Chromium profile folder. It initializes the SessionStorage reader and provides a starting point for iterating through session storage keys and their associated records. ```python import sys import pathlib from ccl_chromium_reader import ccl_chromium_sessionstorage level_db_in_dir = pathlib.Path(sys.argv[1]) # The following code would be used to initialize and iterate session storage data # with ccl_chromium_sessionstorage.SessionStorageDb(level_db_in_dir) as session_storage: # for storage_key in session_storage.iter_storage_keys(): # print(f"Getting records for {storage_key}") # for record in session_storage.iter_records_for_storage_key(storage_key): # print(record.leveldb_seq_number, record.script_key, record.value, sep="\t") ``` -------------------------------- ### Clear IndexedDB Store Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_test_indexeddb.html This function clears all records from a specified IndexedDB object store. It opens the database, starts a read-write transaction, and then calls the clear() method on the object store. Error handling is included for the database opening process. ```javascript var clearStore = async () =>{ let db; let tx; let objectStore; console.log("clearStore entered"); let request = indexedDB.open("MyTestDatabase", 1); request.onerror = function(event) { console.log(event.target); }; request.onsuccess = function(event) { db = event.target.result; tx = db.transaction("store", "readwrite"); objectStore = tx.objectStore("store"); objectStore.clear(); }; } ``` -------------------------------- ### Initialize and Use ChromiumProfileFolder Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md Demonstrates how to initialize the ChromiumProfileFolder class and use it as a context manager to access Chromium profile data. It highlights the near-zero startup cost and the advantages of its integrated searching and filtering. ```python import pathlib from ccl_chromium_reader import ChromiumProfileFolder profile_path = pathlib.Path("profile path goes here") with ChromiumProfileFolder(profile_path) as profile: ... # do things with the profile ``` -------------------------------- ### Accessing and Iterating Chromium IndexedDB Records Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md Demonstrates how to open an IndexedDB, iterate through its databases and object stores, and access individual records. It also shows how to retrieve associated blob data and handle deserialization errors gracefully by logging them instead of crashing. ```python import sys from ccl_chromium_reader import ccl_chromium_indexeddb # assuming command line arguments are paths to the .leveldb and .blob folders leveldb_folder_path = sys.argv[1] blob_folder_path = sys.argv[2] # open the database: db = ccl_chromium_indexeddb.IndexedDb(leveldb_folder_path, blob_folder_path) # there can be multiple databases, so we need to iterate through them (NB # DatabaseID objects contain additional metadata, they aren't just ints): for db_id_meta in db.global_metadata.db_ids: # and within each database, there will be multiple object stores so we # will need to know the maximum object store number (this process will be # cleaned up in future releases): max_objstore_id = db.get_database_metadata( db_id_meta.dbid_no, ccl_chromium_indexeddb.DatabaseMetadataType.MaximumObjectStoreId) # if the above returns None, then there are no stores in this db if max_objstore_id is None: continue # there may be multiple object stores, so again, we iterate through them # this time based on the id number. Object stores start at id 1 and the # max_objstore_id is inclusive: for obj_store_id in range(1, max_objstore_id + 1): # now we can ask the indexeddb wrapper for all records for this db # and object store: for record in db.iterate_records(db_id_meta.dbid_no, obj_store_id): print(f"key: {record.user_key}") print(f"key: {record.value}") # if this record contained a FileInfo object somewhere linking # to data stored in the blob dir, we could access that data like # so (assume the "file" key in the record value is our FileInfo): with record.get_blob_stream(record.value["file"]) as f: file_data = f.read() ``` ```python # Accessing object store using id number obj_store = db[1] # accessing object store using name obj_store = db["store"] # Records can then be accessed by iterating the object store in a for-loop for record in obj_store.iterate_records(): print(record.user_key) print(record.value) # if this record contained a FileInfo object somewhere linking # to data stored in the blob dir, we could access that data like # so (assume the "file" key in the record value is our FileInfo): with record.get_blob_stream(record.value["file"]) as f: file_data = f.read() # By default, any errors in decoding records will bubble an exception # which might be painful when iterating records in a for-loop, so either # passing True into the errors_to_stdout argument and/or by passing in an # error handler function to bad_deserialization_data_handler, you can # perform logging rather than crashing: for record in obj_store.iterate_records( errors_to_stdout=True, bad_deserializer_data_handler= lambda k,v: print(f"error: {k}, {v}")): print(record.user_key) print(record.value) ``` -------------------------------- ### Reading Chromium Local Storage Records Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md Provides a Python snippet to read Local Storage data from a Chromium profile folder. It demonstrates how to open the Local Store database, iterate through storage keys (hosts), and then iterate through records associated with each key, including retrieving approximate timestamps. ```python import sys import pathlib from ccl_chromium_reader import ccl_chromium_localstorage level_db_in_dir = pathlib.Path(sys.argv[1]) # Create the LocalStoreDb object which is used to access the data with ccl_chromium_localstorage.LocalStoreDb(level_db_in_dir) as local_storage: for storage_key in local_storage.iter_storage_keys(): print(f"Getting records for {storage_key}") for record in local_storage.iter_records_for_storage_key(storage_key): # we can attempt to associate this record with a batch, which may # provide an approximate timestamp (withing 5-60 seconds) for this # record. batch = local_storage.find_batch(record.leveldb_seq_number) timestamp = batch.timestamp if batch else None print(record.leveldb_seq_number, record.script_key, record.value, sep="\t") ``` -------------------------------- ### Filter Chromium Profile Data with KeySearch Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md Illustrates advanced data retrieval from Chromium profile using the KeySearch interface for filtering. This includes exact string matching, matching against a collection of strings, using regular expressions, and applying custom filter functions. ```python import re import pathlib from ccl_chromium_reader import ChromiumProfileFolder profile_path = pathlib.Path("profile path goes here") with ChromiumProfileFolder(profile_path) as profile: # Match one of two possible hosts exactly, then a regular expression for the key for ls_rec in profile.iter_local_storage( storage_key=["http://not-a-real-url1.com", "http://not-a-real-url2.com"], script_key=re.compile(r"message\d{1,3}?-text")): print(ls_rec.value) # Match all urls which end with "&read=1" for hist_rec in profile.iterate_history_records(url=lambda x: x.endswith("&read=1")): print(hist_rec.title, hist_rec.url) ``` -------------------------------- ### Access IndexedDB Data with Wrapper API Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md Shows how to use the WrappedIndexDB class to access IndexedDB data from Chromium. It covers initializing the wrapper with LevelDB and blob folder paths, checking available databases, and accessing specific databases by ID, name, or name and origin. ```python import sys from ccl_chromium_reader import ccl_chromium_indexeddb # assuming command line arguments are paths to the .leveldb and .blob folders leveldb_folder_path = sys.argv[1] blob_folder_path = sys.argv[2] # open the indexedDB: wrapper = ccl_chromium_indexeddb.WrappedIndexDB(leveldb_folder_path, blob_folder_path) # You can check the databases present using `wrapper.database_ids` # Databases can be accessed from the wrapper in a number of ways: db = wrapper[2] # accessing database using id number db = wrapper["MyTestDatabase"] # accessing database using name (only valid for single origin indexedDB instances) db = wrapper["MyTestDatabase", "file__0@1"] # accessing the database using name and origin # NB using name and origin is likely the preferred option in most cases # The wrapper object also supports checking for databases using `in` ``` -------------------------------- ### Access Chromium Profile Data with ChromiumProfileFolder (Python) Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt Demonstrates how to use the `ChromiumProfileFolder` class to access various data stores within a Chromium profile. This includes searching Local Storage with regex patterns, iterating through history records filtered by URL, and searching cache entries by URL. It utilizes context manager support for resource management and supports on-demand loading and advanced filtering. ```python import pathlib import re from ccl_chromium_reader import ChromiumProfileFolder # Open a Chrome profile folder profile_path = pathlib.Path("/path/to/Chrome/Profile/Default") with ChromiumProfileFolder(profile_path) as profile: # Search Local Storage with exact host match and regex key pattern for ls_rec in profile.iter_local_storage( storage_key="http://example.com", script_key=re.compile(r"message\d{1,3}-text")): print(f"Key: {ls_rec.script_key}") print(f"Value: {ls_rec.value}") print(f"LevelDB Seq: {ls_rec.leveldb_seq_number}\n") # Search history with lambda function for URLs ending with specific parameter for hist_rec in profile.iterate_history_records( url=lambda x: x.endswith("&read=1")): print(f"Title: {hist_rec.title}") print(f"URL: {hist_rec.url}") print(f"Visit Count: {hist_rec.visit_count}") print(f"Last Visit: {hist_rec.last_visit_time}\n") # Search cache entries by URL pattern for cache_entry in profile.iter_cache(url=re.compile(r"\.js$")): print(f"URL: {cache_entry.key}") print(f"Data Size: {len(cache_entry.data)} bytes") print(f"HTTP Response Code: {cache_entry.metadata.response_code}") ``` -------------------------------- ### Iterate Chromium Session Storage Records Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/README.md This Python snippet demonstrates how to create a SessionStoreDb object to access Chromium session storage data. It iterates through all hosts and then through each record for a given host, printing the leveldb sequence number, key, and value. ```python import ccl_chromium_sessionstorage # Assume level_db_in_dir is defined and points to the session storage directory with ccl_chromium_sessionstorage.SessionStoreDb(level_db_in_dir) as session_storage: for host in session_storage.iter_hosts(): print(f"Getting records for {host}") for record in session_storage.iter_records_for_host(host): print(record.leveldb_sequence_number, record.key, record.value) ``` -------------------------------- ### JavaScript Data Structure Initialization Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_test_indexeddb.html Initializes various JavaScript data structures including strings, objects, linked lists, sparse arrays, and ArrayBuffers. It sets up different types of keys and objects for potential use in the application. ```javascript let aRepeatedString = "this string literal is repeated"; let aRepeatedStringObject = new String("this string object is repeated"); let parent = {"parent": null, "children": []}; let child = {"parent": parent, children: []}; parent.children.push(child); let linked_one = {} let linked_two = {"prev2": linked_one} let linked_three = {"prev3": linked_two, "next3": linked_one} linked_one["prev1"] = linked_three; linked_one["next1"] = linked_two; let sparse = Array(100); sparse[32] = "ELEMENT AT INDEX 32"; sparse[92] = "ELEMENT AT INDEX 92" let ab = new ArrayBuffer(128); let int32buff = new Int32Array(ab); int32buff.set([1, 2, 3, 4, 5, 6], 0); ``` -------------------------------- ### Access IndexedDB Data with WrappedIndexDB (Python) Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt Illustrates how to use the `WrappedIndexDB` class to read IndexedDB data from Chromium profiles. This snippet shows opening an IndexedDB, accessing specific databases and object stores, iterating through records with custom error handling for deserialization issues, and retrieving blob data associated with records. It requires paths to both the LevelDB and blob storage folders. ```python import sys from ccl_chromium_reader import ccl_chromium_indexeddb # Paths to IndexedDB LevelDB and blob storage leveldb_folder_path = "/path/to/profile/IndexedDB/example.com.indexeddb.leveldb" blob_folder_path = "/path/to/profile/IndexedDB/example.com.indexeddb.blob" # Open the IndexedDB wrapper = ccl_chromium_indexeddb.WrappedIndexDB(leveldb_folder_path, blob_folder_path) try: # Access database by name and origin db = wrapper["MyDatabase", "https_example_com_0"] # Check available object stores print(f"Object stores: {db.object_store_names}") # Access object store by name obj_store = db["users"] # Iterate records with error handling for record in obj_store.iterate_records( errors_to_stdout=True, bad_deserializer_data_handler=lambda k, v: print(f"Decode error: {k}")): print(f"User Key: {record.user_key}") print(f"Value: {record.value}") # If record contains FileInfo objects linking to blob storage if "avatar" in record.value and hasattr(record.value["avatar"], "name"): with record.get_blob_stream(record.value["avatar"]) as f: blob_data = f.read() print(f"Blob size: {len(blob_data)} bytes") finally: wrapper.close() ``` -------------------------------- ### Query Chromium History Database Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt This Python snippet shows how to access Chromium's history database to search for URLs matching a given pattern. It retrieves detailed information for each matching URL, including visit counts and last visit times. It also demonstrates how to fetch visit details for a specific URL and iterate through download records, displaying their properties. ```python from ccl_chromium_reader import ccl_chromium_history import pathlib import re history_db_path = pathlib.Path("/path/to/profile/History") # Replace with actual history DB path with ccl_chromium_history.HistoryDatabase(history_db_path) as history: # Search URLs by pattern pattern = re.compile(r"github\.com") for record in history.search_url(pattern): print(f"ID: {record.rec_id}") print(f"URL: {record.url}") print(f"Title: {record.title}") print(f"Visit Count: {record.visit_count}") print(f"Last Visit: {record.last_visit_time}") print(f"Typed Count: {record.typed_count}") print(f"Hidden: {record.hidden}") # Get visit details for visit in history.get_visits_for_url(record.rec_id): print(f" Visit Time: {visit.visit_time}") print(f" From URL ID: {visit.from_visit}") transition = visit.transition print(f" Transition Core: {transition.core.name}") print(f" Transition Qualifiers: {transition.qualifier.name}") print("-" * 60) # Get downloads for download in history.iterate_downloads(): print(f"Download ID: {download.id}") print(f"Target Path: {download.target_path}") print(f"URL: {download.url}") print(f"Start Time: {download.start_time}") print(f"End Time: {download.end_time}") print(f"Total Bytes: {download.total_bytes}") print(f"State: {download.state.name}") ``` -------------------------------- ### Cache Dump - Command Line Usage - Bash Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt Allows dumping entire cache folders (Block File and Simple Cache formats) to an output directory, exporting all HTTP headers and metadata to a CSV file. This command-line utility provides a straightforward way to extract cache contents. ```bash # Dump cache to output directory with metadata CSV python -m ccl_chromium_reader.ccl_chromium_cache \ /path/to/Chrome/Profile/Default/Cache/Cache_Data \ /output/directory # Output structure: # /output/directory/ # ├── cache_metadata.csv # HTTP headers, URLs, timestamps # ├── 00001_example.com.html # ├── 00002_script.js # └── ... ``` -------------------------------- ### Access Chromium File System API Data (Python) Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt This Python snippet demonstrates how to use the FileSystem class from ccl_chromium_reader to access data stored through the Chromium File System API. It shows how to iterate through different origins, list persistent and temporary files, retrieve file metadata, and access the local file path for locally stored files. Error handling is included for closing the filesystem resources. ```python from ccl_chromium_reader import ccl_chromium_filesystem import pathlib fs_base_path = pathlib.Path("/path/to/profile/File System") filesystem = ccl_chromium_filesystem.FileSystem(fs_base_path) try: # Iterate all origins with File System API data for origin_storage in filesystem.iter_origins(): print(f"Origin: {origin_storage.origin}") print(f"Folder ID: {origin_storage.folder_id}") # Get persistent files for file_info in origin_storage.iter_persistent_files(): print(f" Persistent File: {file_info.name}") print(f" File ID: {file_info.file_id}") print(f" Parent ID: {file_info.parent_id}") print(f" Timestamp: {file_info.timestamp}") print(f" Stored Locally: {file_info.is_stored_locally}") # Get actual file path if stored locally if file_info.is_stored_locally: local_path = file_info.get_local_storage_path() print(f" Local Path: {local_path}") with open(local_path, "rb") as f: data = f.read() print(f" File Size: {len(data)} bytes") # Get temporary files for file_info in origin_storage.iter_temporary_files(): print(f" Temporary File: {file_info.name}") # Get deleted file IDs deleted_persistent = origin_storage.get_deleted_persistent_file_ids() deleted_temporary = origin_storage.get_deleted_temporary_file_ids() print(f" Deleted Persistent: {deleted_persistent}") print(f" Deleted Temporary: {deleted_temporary}") finally: filesystem.close() ``` -------------------------------- ### Detect and Open Chromium Cache Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt This snippet demonstrates how to detect the type of Chromium cache (Simple or BlockFile) based on its path and then open it to iterate through cache entries. It retrieves metadata and data for each entry, printing details like URL, response code, content type, and headers. Includes error handling for individual entries and ensures the cache is closed. ```python from ccl_chromium_reader import ccl_chromium_cache import pathlib cache_path = pathlib.Path("/path/to/cache") # Replace with actual cache path cache = None try: cache_type = ccl_chromium_cache.detect_cache_type(cache_path) print(f"Cache type: {cache_type}") if cache_type == ccl_chromium_cache.CacheType.SIMPLE: cache = ccl_chromium_cache.SimpleCacheFolder(cache_path) elif cache_type == ccl_chromium_cache.CacheType.BLOCKFILE: cache = ccl_chromium_cache.BlockfileCacheFolder(cache_path) else: raise ValueError("Unknown cache type") # Iterate all cache entries for cache_address in cache.iter_addresses(): try: # Get metadata and data metadata = cache.get_metadata(cache_address) data = cache.get_data(cache_address) print(f"URL: {metadata.url}") print(f"Response Code: {metadata.response_code}") print(f"Content Type: {metadata.content_type}") print(f"Data Size: {len(data)} bytes") # Access HTTP headers for header_name, header_value in metadata.headers.items(): print(f" {header_name}: {header_value}") except Exception as e: print(f"Error processing cache entry: {e}") finally: if cache: cache.close() ``` -------------------------------- ### Write Record to IndexedDB Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_test_indexeddb.html This function opens an IndexedDB database, begins a read-write transaction, and adds records to an object store. It handles adding both simple objects and files, with error logging for each add operation. Dependencies include the IndexedDB API and DOM elements for file inputs. ```javascript let db; let tx; let objectStore; let addRequest; console.log("writeRecord entered"); let request = indexedDB.open("MyTestDatabase", 1); request.onerror = function(event) { console.log(event.target); }; request.onsuccess = function(event) { db = event.target.result; tx = db.transaction("store", "readwrite"); objectStore = tx.objectStore("store"); for(let obj of _objects){ addRequest = objectStore.add(obj); addRequest.onsuccess = (ev) => console.log(`record added ${obj}`); addRequest.onerror = (ev) => console.log(`failed to add record ${ev.target.errorCode}\n${obj}`); } let fileInput1 = document.querySelector("#myfiles1"); let files1 = fileInput1.files; let file1 = files1[0]; let fileInput2 = document.querySelector("#myfiles2"); let files2 = fileInput2.files; let file2 = files2[0]; addRequest = objectStore.add({ "id": "the one with files", "one file": file1, "two file": file2, "the first file again": file1 }); addRequest.onsuccess = (ev) => console.log(`file record added`); addRequest.onerror = (ev) => console.log(`failed to file record ${ev.target.errorCode}`); addRequest = objectStore.add({ "id": "a_big_record_to_test_kIDBWrapThreshold_in_chrome_plus_a_file_to_check_how_mozilla_does_that", "big_array": [...Array(65536).keys()], "a_file": file1 }); }; ``` -------------------------------- ### JavaScript Asynchronous Key Generation using Web Crypto API Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_test_indexeddb.html Generates various cryptographic key pairs and keys using the Web Crypto API. This includes RSA, ECDSA, HMAC, and AES keys, asynchronously. The generated keys are stored in corresponding variables. ```javascript let _objects; let rsaKeyPair; let ecdsaKeyPair; let hmacKey; let aesKey; Promise.all([ window.crypto.subtle.generateKey( { name: "RSA-OAEP", modulusLength: 4096, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, true, ["encrypt", "decrypt"] ).then(x => rsaKeyPair = x), window.crypto.subtle.generateKey( { name: "ECDSA", namedCurve: "P-384" }, true, ["sign", "verify"] ).then(x => ecdsaKeyPair = x), window.crypto.subtle.generateKey( { name: "HMAC", hash: {name: "SHA-512"} }, true, ["sign", "verify"] ).then(x => hmacKey = x), window.crypto.subtle.generateKey( { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"] ).then(x => aesKey = x) ]).then(x =>{ _objects = [ { "id": "basics", "true": true, "false": false, "null": null, "undefined": undefined, "string_1a": aRepeatedString, "string_1b": aRepeatedString, "string_2a": aRepeatedStringObject, "string_2b": aRepeatedStringObject, "the_number_100": 100, "the_number_1000000000": 1000000000, "the_number_1.5": 1.5, "aRegex": /[A-z]{3}/, "date": new Date(2022, 10, 21, 17, 0, 0) }, { "id": "the_one_with_bigints", "a_BigInt": BigInt("1000"), "a_neg_bigInt": BigInt("-1000"), "a_hugeInt": BigInt("100000000000000000000000"), "beeegInt": 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2fn, }, { "id": "the_one_with_collections", "dense_array": ["one", "two", "three", "four"], "sparse_array": sparse, "inner_object": {"key1": "value1", "key2": "value2", "key3": "value3"}, "map": new Map([["map_key1", "map_value1"], ["map_key2", "map_value2"], ["map_key3", "map_value3"]]), "set": new Set(["set_value1", "set_value2", "set_value3", "set_value4"]) }, { "id": "the_one_with_array_buffers", "array_buffer": ab, "int32_buffer": int32buff }, { "id": "the_one_with_cyclic_references", "one_layer": parent, "three_item_cyclic_linked_list": linked_one, }, { "id": "the_one_with_unicode", "all_ascii": "hello world", "ascii_plus_latin1": "hélló wórld", "ascii_plus_emoji": "hell😮 world", "all_unicode": "😛😫😋😎" }, { "id": "the_one_with_primitives_and_objects", "string_primitive": "hello primitive", "string_object": new String("hello object"), "bool_primitive_true": true, "bool_object_true" : new Boolean(1), "number_primitive_1000": 1000, "number_object_1000": new Number("1000"), "bigint_primitive_abcdefabcdefabcdefabcdef": 0xabcdefabcdefabcdefabcdefn, "bigint_object_abcdefabcdefabcdefabcdef": BigInt("0xabcdefabcdefabcdefabcdef") }, { "id": ["an", "array", "of", "text"], "text": "primary key is an array of text" }, { "id": 1000, "text": "primary key is the integer 1000" }, { "id": ["an", "array", "of", "text", "and", "an", "integer", 1000], "text": "primary is an array of text with a number at the end" }, { "id": "a_big_record_to_test_kIDBWrapThreshold_in_chrome", "big_array": [...Array(65536).keys()] }, { "id": "the_one_with_crypto_objects", "rsa": rsaKeyPair, "ecdsa": ecdsaKeyPair, "hmac": hmacKey, "aes": aesKey }, { "id": "the_one_with_a_blob", "blob": new Blob( ["here is a blob, a lovely lovely blob, which is different to a file, but also somewhat similar", "This is the second item in the blob which is used to construct the blob" ], {type: "text/plain"} ) }, { "id": [[ "foo" ]], "desc": "key is [[ \"foo\" ]]" }, { "id": [[ ]], "desc": "key is [[ ]]" }, { "id": new Date(2024, 4, 1), "desc": "key is new Date(2024, 4, 1)" }, { "id": [[[1,2], 3, [[4], 5, 6], [7, [8, 9]]], 10], "desc": "key is [[[1,2], 3, [[4], 5, 6], [7, [8, 9]]], 10]" } ]; }); ``` -------------------------------- ### IndexedDB Raw Access API - Python Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt Provides low-level access to IndexedDB internals for forensic analysis. It allows inspection of metadata, manual iteration through database structures, object stores, and records. Requires paths to LevelDB and blob folders. ```python from ccl_chromium_indexeddb import ccl_chromium_indexeddb leveldb_folder_path = "/path/to/leveldb" blob_folder_path = "/path/to/blobs" db = ccl_chromium_indexeddb.IndexedDb(leveldb_folder_path, blob_folder_path) try: # Iterate through all databases for db_id_meta in db.global_metadata.db_ids: print(f"Database ID: {db_id_meta.dbid_no}") print(f"Database Name: {db_id_meta.name}") print(f"Origin: {db_id_meta.origin}") # Get maximum object store ID max_objstore_id = db.get_database_metadata( db_id_meta.dbid_no, ccl_chromium_indexeddb.DatabaseMetadataType.MaximumObjectStoreId) if max_objstore_id is None: continue # Iterate object stores for obj_store_id in range(1, max_objstore_id + 1): print(f" Object Store ID: {obj_store_id}") # Get object store records for record in db.iterate_records(db_id_meta.dbid_no, obj_store_id): print(f" Record Key: {record.user_key}") print(f" Record Value Type: {type(record.value)}") # Access blob data if present if hasattr(record.value, "get") and "file" in record.value: with record.get_blob_stream(record.value["file"]) as f: file_data = f.read() print(f" File Data: {len(file_data)} bytes") finally: db.close() ``` -------------------------------- ### Local Storage Access - Python Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt Provides access to Chromium Local Storage data, automatically decoding string encodings and reconstructing timestamps. It allows iteration by storage keys (origins). Requires the path to the LevelDB directory for Local Storage. ```python import pathlib from ccl_chromium_reader import ccl_chromium_localstorage level_db_in_dir = pathlib.Path("/path/to/profile/Local Storage/leveldb") # Create LocalStoreDb object with context manager with ccl_chromium_localstorage.LocalStoreDb(level_db_in_dir) as local_storage: # Iterate through all storage keys (origins/hosts) for storage_key in local_storage.iter_storage_keys(): print(f"\n=== Storage Key: {storage_key} ===") # Get all records for this storage key for record in local_storage.iter_records_for_storage_key(storage_key): # Attempt to find associated batch for timestamp batch = local_storage.find_batch(record.leveldb_seq_number) timestamp = batch.timestamp if batch else None print(f"Seq#: {record.leveldb_seq_number}") print(f"Script Key: {record.script_key}") print(f"Value: {record.value}") print(f"Approximate Time: {timestamp}") print(f"State: {'Deleted' if record.is_deleted else 'Live'}") print("-" * 40) ``` -------------------------------- ### Session Storage Access - Python Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt Provides access to Chromium Session Storage data, supporting multiple browser tabs, host-based grouping, and recovery of deleted records. It allows iteration by host and provides details like sequence number, key, value, and deletion status. Requires the path to the Session Storage directory. ```python import pathlib from ccl_chromium_reader import ccl_chromium_sessionstorage level_db_in_dir = pathlib.Path("/path/to/profile/Session Storage") # Open Session Storage database with ccl_chromium_sessionstorage.SessionStoreDb(level_db_in_dir) as session_storage: # Iterate all hosts that have session storage data for host in session_storage.iter_hosts(): print(f"\n=== Host: {host} ===") # Get all records for this host across all sessions for record in session_storage.iter_records_for_host(host): print(f"LevelDB Seq: {record.leveldb_sequence_number}") print(f"Key: {record.key}") print(f"Value: {record.value}") print(f"Is Deleted: {record.is_deleted}") print(f"Location: {record.record_location}") print("-" * 40) ``` -------------------------------- ### Low-Level Chromium LevelDB Access Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt This Python code provides low-level access to Chromium's LevelDB databases. It allows iteration over all records, including those marked as deleted, and displays their sequence number, key, value, state, origin file, and offset. It also shows how to find specific records by their key. ```python from ccl_chromium_reader.storage_formats import ccl_leveldb import pathlib leveldb_path = pathlib.Path("/path/to/any.leveldb") # Replace with actual LevelDB path with ccl_leveldb.RawLevelDb(leveldb_path) as db: # Iterate all records (including deleted) for record in db.iterate_records_raw(): print(f"Sequence Number: {record.seq}") print(f"Key: {record.user_key}") print(f"Value: {record.value}") print(f"State: {record.state.name}") # Live or Deleted print(f"Origin File: {record.origin_file}") print(f"Offset: {record.offset}") print("-" * 40) # Access specific records by key key = b"my_key" records = list(db.iterate_records_raw()) matching = [r for r in records if r.user_key == key] for match in matching: print(f"Found record with key: {match.user_key}") print(f"Value: {match.value}") ``` -------------------------------- ### Set Local Storage Data Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_webstorage.html Initializes local storage with various data types and encodings. It sets a known key and demonstrates storing ASCII, Latin-1, Greek, emoji, UTF-16 characters, and a long repeated string. This function logs the timestamp of the operation. ```javascript const KNOWN_LS_KEY = "ls_a_known_key"; const KNOWN_SS_KEY = "ss_a_known_key"; function makeLs() { const tsNow = Date.now().toString(); localStorage.setItem(KNOWN_LS_KEY, `initial value set at ${tsNow}`); localStorage.setItem(`ls_property_with_ascii_${tsNow}`, "just ascii"); localStorage.setItem(`ls_property_with_latin1_${tsNow}`, "latin-1 in a café"); localStorage.setItem(`ls_property_in_greek_${tsNow}`, "τοπική αποθήκευση"); localStorage.setItem(`ls_property_with_emoji_${tsNow}`, "😎🆒"); localStorage.setItem(`ls_property_which_whould_be_shorter_as_utf_16_${tsNow}`, "\uff11\uff12\uff13\uff14") localStorage.setItem(`ls_property_which_is_long_${tsNow}`, "here is some long data which contains this string repeated a thousand times |".repeat(1000)); console.log(`localstorage set with timestamp: ${tsNow}`); } ``` -------------------------------- ### Cache Programmatic Access - Python Source: https://context7.com/cclgroupltd/ccl_chromium_reader/llms.txt Provides programmatic access to cached resources within Chromium profiles. It automatically detects cache formats, extracts HTTP headers, and decompresses content like gzip/brotli. Requires the path to the cache data directory. ```python from ccl_chromium_reader import ccl_chromium_cache import pathlib cache_path = pathlib.Path("/path/to/Cache/Cache_Data") ``` -------------------------------- ### Set Session Storage Data Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_webstorage.html Initializes session storage with various data types and encodings. It sets a known key and demonstrates storing ASCII, Latin-1, Greek, emoji, UTF-16 characters, and a long repeated string. This function logs the timestamp of the operation. ```javascript const KNOWN_LS_KEY = "ls_a_known_key"; const KNOWN_SS_KEY = "ss_a_known_key"; function makeSs() { const tsNow = Date.now().toString(); sessionStorage.setItem(KNOWN_SS_KEY, `initial value set at ${tsNow}`); sessionStorage.setItem(`ss_property_with_ascii_${tsNow}`, "just ascii"); sessionStorage.setItem(`ss_property_with_latin1_${tsNow}`, "latin-1 in a café"); sessionStorage.setItem(`ss_property_in_greek_${tsNow}`, "τοπική αποθήκευση"); sessionStorage.setItem(`ss_property_with_emoji_${tsNow}`, "😎🆒"); sessionStorage.setItem(`ss_property_which_whould_be_shorter_as_utf_16_${tsNow}`, "\uff11\uff12\uff13\uff14") sessionStorage.setItem(`ss_property_which_is_long_${tsNow}`, "here is some long data which contains this string repeated a thousand times |".repeat(1000)); console.log(`sessionstorage set with timestamp: ${tsNow}`); } ``` -------------------------------- ### Write Records to IndexedDB Stores Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_many_indexeddb_databases.html Writes records to object stores across multiple IndexedDB databases. It iterates through databases and their respective object stores, adding data with a predefined ID and test record content. Includes error handling for record addition. ```javascript var writeRecord = async () => { console.log("writeRecord entered"); for (let i = 0; i < databaseCount; i++) { let request = indexedDB.open(`MyTestDatabase${i}`, 1); request.onerror = function(event) { console.log(event.target); }; request.onsuccess = function(event) { let db = event.target.result; if (i == 0) { for (let j = 0; j < objectStoreCount; j++) { let tx = db.transaction(`store${j}`, "readwrite"); let objectStore = tx.objectStore(`store${j}`); let addRequest = objectStore.add({ "id": "the id", "test_record": `record in db ${i}, store ${j}` }); addRequest.onsuccess = (ev) => console.log(`record added`); addRequest.onerror = (ev) => console.log(`failed to add record ${ev.target.errorCode}`); } } else { let tx = db.transaction("store", "readwrite"); let objectStore = tx.objectStore("store"); let addRequest = objectStore.add({ "id": "the id", "test_record": `record in db ${i}` }); addRequest.onsuccess = (ev) => console.log(`record added`); addRequest.onerror = (ev) => console.log(`failed to add record ${ev.target}`); } }; } } ``` -------------------------------- ### Update Local Storage Data Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_webstorage.html Updates the value associated with a known local storage key. It overwrites the existing value with a new string that includes the current timestamp. The function logs the timestamp of the update operation. ```javascript const KNOWN_LS_KEY = "ls_a_known_key"; function updateLs() { const tsNow = Date.now().toString(); localStorage.setItem(KNOWN_LS_KEY, `updated value set at ${tsNow}`); console.log(`localstorage updated with timestamp: ${tsNow}`); } ``` -------------------------------- ### Clear IndexedDB Stores Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_many_indexeddb_databases.html Clears all records from object stores within multiple IndexedDB databases. It iterates through each database and its object stores, executing the `clear()` method. Includes basic error handling for database opening. ```javascript var clearStore = async () => { let db; let tx; let objectStore; console.log("clearStore entered"); for (let i = 0; i < databaseCount; i++) { let request = indexedDB.open(`MyTestDatabase${i}`, 1); request.onerror = function(event) { console.log(event.target); }; request.onsuccess = function(event) { db = event.target.result; if (i == 0) { for (let j = 0; j < objectStoreCount; j++) { let tx = db.transaction(`store${j}`, "readwrite"); objectStore = tx.objectStore(`store${j}`); objectStore.clear(); } } else { tx = db.transaction("store", "readwrite"); objectStore = tx.objectStore("store"); objectStore.clear() } } } } ``` -------------------------------- ### Read Local Storage Data Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_webstorage.html Retrieves the value associated with a known local storage key. It logs the retrieved value along with the timestamp of the read operation. This function is useful for verifying data stored in local storage. ```javascript const KNOWN_LS_KEY = "ls_a_known_key"; function readLs() { const tsNow = Date.now().toString(); let lsVal = localStorage.getItem(KNOWN_LS_KEY); console.log(`Got local storage value ${KNOWN_LS_KEY} at ${tsNow}`); } ``` -------------------------------- ### Update Session Storage Data Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_webstorage.html Updates the value associated with a known session storage key. It overwrites the existing value with a new string that includes the current timestamp. The function logs the timestamp of the update operation. ```javascript const KNOWN_SS_KEY = "ss_a_known_key"; function updateSs() { const tsNow = Date.now().toString(); sessionStorage.setItem(KNOWN_SS_KEY, `updated value set at ${tsNow}`); console.log(`sessionstorage updated with timestamp: ${tsNow}`); } ``` -------------------------------- ### Read Session Storage Data Source: https://github.com/cclgroupltd/ccl_chromium_reader/blob/master/tools_and_utilities/extras/make_webstorage.html Retrieves the value associated with a known session storage key. It logs the retrieved value along with the timestamp of the read operation. This function is useful for verifying data stored in session storage. ```javascript const KNOWN_SS_KEY = "ss_a_known_key"; function readSs() { const tsNow = Date.now().toString(); let ssVal = sessionStorage.getItem(KNOWN_SS_KEY); console.log(`Got session storage value ${KNOWN_SS_KEY} at ${tsNow}`); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.