Path: blob/main/core/injected-scripts/domStorage.ts
1028 views
import { IDomStorageForOrigin } from '@secret-agent/interfaces/IDomStorage';1import { IIndexedDB } from '@secret-agent/interfaces/IIndexedDB';23function dumpStorage(storage: Storage) {4const store: [string, string][] = [];5for (let i = 0; i < storage.length; i += 1) {6const key = storage.key(i);7store.push([key, storage.getItem(key)]);8}9return store;10}1112async function exportIndexedDbs(dbNames: string[]) {13if (!dbNames || !dbNames.length) return [];1415return await Promise.all(16dbNames.map(async name => {17const openDBRequest = window.indexedDB.open(name);1819const idbDatabase = await new Promise<IDBDatabase>(resolve => {20openDBRequest.onsuccess = event => {21resolve((event.target as IDBRequest).result as IDBDatabase);22};23});24const objectStoreNames = Array.from(idbDatabase.objectStoreNames);25if (!objectStoreNames.length) return;2627const transaction = idbDatabase.transaction(objectStoreNames, 'readonly');28// eslint-disable-next-line promise/param-names29const rejectPromise = new Promise<void>(30(_, reject) => (transaction.onerror = () => reject()),31);3233const db: IIndexedDB = {34name,35version: idbDatabase.version,36objectStores: [],37data: {},38};3940for (const objectStoreName of objectStoreNames) {41const store = transaction.objectStore(objectStoreName);42db.objectStores.push({43name: objectStoreName,44indexes: Array.from(store.indexNames).map(idxName => {45const index = store.index(idxName);46return {47name: index.name,48keyPath: index.keyPath,49unique: index.unique,50multiEntry: index.multiEntry,51};52}),53keyPath: store.keyPath,54autoIncrement: store.autoIncrement,55});5657db.data[objectStoreName] = (await Promise.race([58readStoreData(store),59rejectPromise,60])) as string[];61}62return db;63}),64);65}6667async function readStoreData(store: IDBObjectStore) {68const data: string[] = [];69await new Promise<void>(resolve => {70const cursorQuery = store.openCursor();71cursorQuery.onsuccess = event => {72const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;73if (cursor) {74const key = store.keyPath === null ? cursor.key : undefined;75const value = cursor.value;76data.push(TypeSerializer.stringify({ key, value }));77cursor.continue();78} else {79resolve();80}81};82cursorQuery.onerror = () => resolve();83});84return data;85}8687// @ts-ignore88window.exportDomStorage = async (dbNames: string[]) => {89return {90localStorage: dumpStorage(localStorage),91sessionStorage: dumpStorage(sessionStorage),92indexedDB: await exportIndexedDbs(dbNames),93} as IDomStorageForOrigin;94};959697