puppeteer-extra-plugin-session
Version:
A puppeteer plugin to dump and inject session data.
98 lines (96 loc) • 3.47 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDatabaseNames = exports.setIndexedDB = exports.IndexedDBStorageProvider = void 0;
const storage_provider_1 = require("../classes/storage-provider");
const dexie_1 = require("../constants/dexie");
const schemas_1 = require("../schemas");
class IndexedDBStorageProvider extends storage_provider_1.StorageProvider {
get name() {
return storage_provider_1.StorageProviderName.IndexedDB;
}
async get(page) {
const securityOrigin = await page.evaluate(() => location.origin);
const dbNames = await getDatabaseNames(page, securityOrigin);
const indexedDBs = await Promise.all(dbNames.map((db) => getIndexedDB(page, db)));
return JSON.stringify(dbNames.map((db, index) => {
return {
name: db,
data: indexedDBs[index],
securityOrigin,
};
}));
}
async set(page, data) {
const databases = schemas_1.IndexedDBDatabaseSchema.array().parse(JSON.parse(data));
for (const db of databases) {
if (!page.url().includes(db.securityOrigin)) {
await page.goto(db.securityOrigin);
}
await setIndexedDB(page, db.data);
}
}
}
exports.IndexedDBStorageProvider = IndexedDBStorageProvider;
function generateSetContentScript(data) {
return `(async() => {
// note(clouedoc): required for some websites
// see https://stackoverflow.com/a/48690342/4564097
define = undefined;
exports = undefined;
if (window.module) module.exports = undefined;
${dexie_1.dexieCore}
${dexie_1.dexieExportImport}
const importBlob = new Blob([\`${data}\`], { type: "text/json" });
const importDB = await Dexie.import(importBlob, { overwriteValues: true });
return importDB.backendDB();
})()`;
}
// STEALTH: isolated worlds
// TODO: investigate database versions
async function setIndexedDB(page, data) {
await page.evaluate(generateSetContentScript(data));
}
exports.setIndexedDB = setIndexedDB;
// TODO: change this to an appropriate name
async function getDatabaseNames(page, securityOrigin) {
const session = await page.target().createCDPSession();
let dbNames;
try {
const resp = schemas_1.CDPIndexedDBDatabaseNames.parse(await session.send('IndexedDB.requestDatabaseNames', {
securityOrigin,
}));
dbNames = resp.databaseNames;
}
catch (err) {
if (err.message.includes('No document for given frame found')) {
dbNames = [];
}
else {
throw err;
}
}
await session.detach();
return dbNames;
}
exports.getDatabaseNames = getDatabaseNames;
function generateGetContentScript(dbName) {
return `
(async() => {
// note(clouedoc): required for some websites
// see https://stackoverflow.com/a/48690342/4564097
define = undefined;
exports = undefined;
if (window.module) module.exports = undefined;
${dexie_1.dexieCore}
${dexie_1.dexieExportImport}
const db = await new Dexie("${dbName}").open();
const blob = await db.export();
return blob.text();
})()`;
}
// STEALTH: isolated worlds
async function getIndexedDB(page, dbName) {
const result = await page.evaluate(generateGetContentScript(dbName));
return schemas_1.IndexedDBSchema.parse(result);
}
//# sourceMappingURL=indexedDb.js.map