@wenathlan/extension 1.1.48 → 1.1.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +467 -4
- package/dist/index.js.map +4 -4
- package/dist/memory.d.ts +46 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +29 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +30 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/sessions.d.ts +79 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/types.d.ts +142 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +843 -7
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +2 -2
- package/extension/dist/pagebridge.js.map +2 -2
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +12 -2
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +215 -2
- package/extension/dist/sidepanel.js.map +3 -3
- package/extension/dist/style.css +2 -0
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1331,6 +1331,212 @@ function expireprofilerecords(input) {
|
|
|
1331
1331
|
};
|
|
1332
1332
|
}
|
|
1333
1333
|
|
|
1334
|
+
// sessions.ts
|
|
1335
|
+
var sessionkinds = ["persiststate", "capturesession", "restoresession", "namedsessions", "diffsessions", "searchsessions", "exportsessions", "importsessions"];
|
|
1336
|
+
var sessionfileversion = 1;
|
|
1337
|
+
var snapshotsections = ["tabs", "scroll", "forms", "storage", "cookies"];
|
|
1338
|
+
var searchfields = ["urls", "titles", "names", "text"];
|
|
1339
|
+
function checksumtext(payload) {
|
|
1340
|
+
let hash = 2166136261;
|
|
1341
|
+
for (let index = 0; index < payload.length; index += 1) {
|
|
1342
|
+
hash ^= payload.charCodeAt(index);
|
|
1343
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
1344
|
+
}
|
|
1345
|
+
return hash.toString(16).padStart(8, "0");
|
|
1346
|
+
}
|
|
1347
|
+
function taskstatechecksum(runid, stepcursor, outputs) {
|
|
1348
|
+
return checksumtext(`${runid}:${stepcursor}:${outputs.length}:${outputs.map((output) => `${output.stepid}:${output.ok}:${output.summary.length}`).join("|")}`);
|
|
1349
|
+
}
|
|
1350
|
+
function taskstateof(input) {
|
|
1351
|
+
return { runid: input.runid, stepcursor: input.stepcursor, outputs: input.outputs, checkpointat: input.checkpointat, checksum: taskstatechecksum(input.runid, input.stepcursor, input.outputs) };
|
|
1352
|
+
}
|
|
1353
|
+
function taskstatevalid(state) {
|
|
1354
|
+
if (!state || typeof state.runid !== "string" || !state.runid.trim()) return false;
|
|
1355
|
+
if (typeof state.stepcursor !== "number" || !Number.isInteger(state.stepcursor) || state.stepcursor < 0) return false;
|
|
1356
|
+
if (typeof state.checkpointat !== "number" || !Number.isFinite(state.checkpointat)) return false;
|
|
1357
|
+
if (!Array.isArray(state.outputs)) return false;
|
|
1358
|
+
return state.checksum === taskstatechecksum(state.runid, state.stepcursor, state.outputs);
|
|
1359
|
+
}
|
|
1360
|
+
function sessiontabof(value) {
|
|
1361
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1362
|
+
const candidate = value;
|
|
1363
|
+
if (typeof candidate.url !== "string" || !candidate.url.trim()) return void 0;
|
|
1364
|
+
if (typeof candidate.title !== "string") return void 0;
|
|
1365
|
+
if (typeof candidate.index !== "number" || !Number.isInteger(candidate.index) || candidate.index < 0) return void 0;
|
|
1366
|
+
const scrollx = typeof candidate.scrollx === "number" && Number.isFinite(candidate.scrollx) ? candidate.scrollx : 0;
|
|
1367
|
+
const scrolly = typeof candidate.scrolly === "number" && Number.isFinite(candidate.scrolly) ? candidate.scrolly : 0;
|
|
1368
|
+
const forms = Array.isArray(candidate.forms) ? candidate.forms.flatMap((entry) => {
|
|
1369
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
|
|
1370
|
+
const form = entry;
|
|
1371
|
+
if (typeof form.selector !== "string" || !form.selector.trim()) return [];
|
|
1372
|
+
return [{ selector: form.selector, value: typeof form.value === "string" ? form.value : "" }];
|
|
1373
|
+
}) : [];
|
|
1374
|
+
return { url: candidate.url, title: candidate.title, index: candidate.index, scrollx, scrolly, forms };
|
|
1375
|
+
}
|
|
1376
|
+
function autointervalof(value) {
|
|
1377
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1378
|
+
const candidate = value;
|
|
1379
|
+
if (typeof candidate.period !== "number" || !Number.isFinite(candidate.period) || candidate.period <= 0) return void 0;
|
|
1380
|
+
if (typeof candidate.maxsnapshots !== "number" || !Number.isInteger(candidate.maxsnapshots) || candidate.maxsnapshots < 1) return void 0;
|
|
1381
|
+
if (typeof candidate.expiry !== "number" || !Number.isFinite(candidate.expiry) || candidate.expiry < 0) return void 0;
|
|
1382
|
+
return { period: candidate.period, maxsnapshots: candidate.maxsnapshots, expiry: candidate.expiry };
|
|
1383
|
+
}
|
|
1384
|
+
function snapshotplanof(value) {
|
|
1385
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1386
|
+
const candidate = value;
|
|
1387
|
+
if (candidate.scope !== "tab" && candidate.scope !== "run" && candidate.scope !== "all") return void 0;
|
|
1388
|
+
const sections = Array.isArray(candidate.sections) ? candidate.sections.flatMap((section) => typeof section === "string" && snapshotsections.includes(section) ? [section] : []) : [];
|
|
1389
|
+
if (sections.length === 0) return void 0;
|
|
1390
|
+
if (typeof candidate.captures !== "boolean") return void 0;
|
|
1391
|
+
const auto = candidate.auto === void 0 ? void 0 : autointervalof(candidate.auto);
|
|
1392
|
+
if (candidate.auto !== void 0 && auto === void 0) return void 0;
|
|
1393
|
+
return { scope: candidate.scope, sections, captures: candidate.captures, ...auto !== void 0 ? { auto } : {} };
|
|
1394
|
+
}
|
|
1395
|
+
function restoreplanof(value) {
|
|
1396
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1397
|
+
const candidate = value;
|
|
1398
|
+
if (candidate.tabpolicy !== "reopen" && candidate.tabpolicy !== "skip") return void 0;
|
|
1399
|
+
if (candidate.formpolicy !== "restore" && candidate.formpolicy !== "skip") return void 0;
|
|
1400
|
+
if (candidate.capturepolicy !== "link" && candidate.capturepolicy !== "skip") return void 0;
|
|
1401
|
+
return { tabpolicy: candidate.tabpolicy, formpolicy: candidate.formpolicy, capturepolicy: candidate.capturepolicy };
|
|
1402
|
+
}
|
|
1403
|
+
function searchqueryof(value) {
|
|
1404
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1405
|
+
const candidate = value;
|
|
1406
|
+
const terms = Array.isArray(candidate.terms) ? candidate.terms.flatMap((term) => typeof term === "string" && term.trim() ? [term.trim()] : []) : [];
|
|
1407
|
+
if (terms.length === 0) return void 0;
|
|
1408
|
+
const fields = Array.isArray(candidate.fields) ? candidate.fields.flatMap((field) => typeof field === "string" && searchfields.includes(field) ? [field] : []) : [...searchfields];
|
|
1409
|
+
if (fields.length === 0) return void 0;
|
|
1410
|
+
const from = typeof candidate.from === "number" && Number.isFinite(candidate.from) ? candidate.from : void 0;
|
|
1411
|
+
const to = typeof candidate.to === "number" && Number.isFinite(candidate.to) ? candidate.to : void 0;
|
|
1412
|
+
if (from !== void 0 && to !== void 0 && from > to) return void 0;
|
|
1413
|
+
return { terms, fields, ...from !== void 0 ? { from } : {}, ...to !== void 0 ? { to } : {} };
|
|
1414
|
+
}
|
|
1415
|
+
function sessionfolderof(value) {
|
|
1416
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1417
|
+
const candidate = value;
|
|
1418
|
+
if (typeof candidate.name !== "string" || !candidate.name.trim()) return void 0;
|
|
1419
|
+
const parent = typeof candidate.parent === "string" && candidate.parent.trim() ? candidate.parent : void 0;
|
|
1420
|
+
const tags = Array.isArray(candidate.tags) ? candidate.tags.flatMap((tag) => typeof tag === "string" && tag.trim() ? [tag] : []) : [];
|
|
1421
|
+
return { name: candidate.name, ...parent !== void 0 ? { parent } : {}, tags };
|
|
1422
|
+
}
|
|
1423
|
+
function newsessionrecord(input) {
|
|
1424
|
+
return { id: input.id, name: input.name, createdat: input.createdat, tabs: input.tabs, captures: input.captures, storage: input.storage, cookies: input.cookies, ...input.folder !== void 0 ? { folder: input.folder } : {}, tags: input.tags ?? [], ...input.auto === true ? { auto: true } : {} };
|
|
1425
|
+
}
|
|
1426
|
+
function diffsessionrecords(left, right) {
|
|
1427
|
+
const changes = [];
|
|
1428
|
+
const leftbyindex = new Map(left.tabs.map((tab) => [tab.index, tab]));
|
|
1429
|
+
const rightbyindex = new Map(right.tabs.map((tab) => [tab.index, tab]));
|
|
1430
|
+
for (const tab of right.tabs) {
|
|
1431
|
+
const prior = leftbyindex.get(tab.index);
|
|
1432
|
+
if (!prior) {
|
|
1433
|
+
changes.push({ class: "added", subject: "tab", detail: `Tab ${tab.index} added: ${tab.url}` });
|
|
1434
|
+
continue;
|
|
1435
|
+
}
|
|
1436
|
+
if (prior.url !== tab.url) changes.push({ class: "changed", subject: "url", detail: `Tab ${tab.index} moved from ${prior.url} to ${tab.url}` });
|
|
1437
|
+
if (prior.title !== tab.title) changes.push({ class: "changed", subject: "tab", detail: `Tab ${tab.index} title changed from "${prior.title}" to "${tab.title}"` });
|
|
1438
|
+
const priorforms = new Map(prior.forms.map((form) => [form.selector, form.value]));
|
|
1439
|
+
for (const form of tab.forms) {
|
|
1440
|
+
const before = priorforms.get(form.selector);
|
|
1441
|
+
if (before === void 0) {
|
|
1442
|
+
changes.push({ class: "added", subject: "form", detail: `Form field ${form.selector} of tab ${tab.index} added with a value` });
|
|
1443
|
+
continue;
|
|
1444
|
+
}
|
|
1445
|
+
if (before !== form.value) changes.push({ class: "changed", subject: "form", detail: `Form field ${form.selector} of tab ${tab.index} changed its captured value` });
|
|
1446
|
+
}
|
|
1447
|
+
for (const form of prior.forms) if (!tab.forms.some((entry) => entry.selector === form.selector)) changes.push({ class: "removed", subject: "form", detail: `Form field ${form.selector} of tab ${tab.index} removed` });
|
|
1448
|
+
}
|
|
1449
|
+
for (const tab of left.tabs) if (!rightbyindex.has(tab.index)) changes.push({ class: "removed", subject: "tab", detail: `Tab ${tab.index} removed: ${tab.url}` });
|
|
1450
|
+
const leftstorage = new Map(left.storage.map((entry) => [entry.origin, entry]));
|
|
1451
|
+
for (const entry of right.storage) {
|
|
1452
|
+
const prior = leftstorage.get(entry.origin);
|
|
1453
|
+
if (!prior) {
|
|
1454
|
+
changes.push({ class: "added", subject: "storage", detail: `Local storage of ${entry.origin} captured with ${entry.keys.length} keys` });
|
|
1455
|
+
continue;
|
|
1456
|
+
}
|
|
1457
|
+
if (prior.keys.join("|") !== entry.keys.join("|") || prior.values.join("|") !== entry.values.join("|")) changes.push({ class: "changed", subject: "storage", detail: `Local storage of ${entry.origin} changed its captured keys or values` });
|
|
1458
|
+
}
|
|
1459
|
+
for (const entry of left.storage) if (!right.storage.some((candidate) => candidate.origin === entry.origin)) changes.push({ class: "removed", subject: "storage", detail: `Local storage of ${entry.origin} left the capture` });
|
|
1460
|
+
return changes;
|
|
1461
|
+
}
|
|
1462
|
+
function newsessiondiff(input) {
|
|
1463
|
+
return { id: input.id, leftid: input.left.id, rightid: input.right.id, changes: diffsessionrecords(input.left, input.right), at: input.at };
|
|
1464
|
+
}
|
|
1465
|
+
function searchsessionrecords(query, records) {
|
|
1466
|
+
const matches = [];
|
|
1467
|
+
for (const record2 of records) {
|
|
1468
|
+
if (query.from !== void 0 && record2.createdat < query.from) continue;
|
|
1469
|
+
if (query.to !== void 0 && record2.createdat > query.to) continue;
|
|
1470
|
+
const haystacks = [
|
|
1471
|
+
{ field: "urls", text: record2.tabs.map((tab) => tab.url).join(" ") },
|
|
1472
|
+
{ field: "titles", text: record2.tabs.map((tab) => tab.title).join(" ") },
|
|
1473
|
+
{ field: "names", text: [record2.name, record2.folder ?? "", ...record2.tags].join(" ") },
|
|
1474
|
+
{ field: "text", text: record2.tabs.flatMap((tab) => tab.forms.map((form) => form.value)).join(" ") }
|
|
1475
|
+
];
|
|
1476
|
+
for (const haystack of haystacks) {
|
|
1477
|
+
if (!query.fields.includes(haystack.field)) continue;
|
|
1478
|
+
const lower = haystack.text.toLowerCase();
|
|
1479
|
+
for (const term of query.terms) {
|
|
1480
|
+
const at = lower.indexOf(term.toLowerCase());
|
|
1481
|
+
if (at < 0) continue;
|
|
1482
|
+
const start = Math.max(0, at - 30);
|
|
1483
|
+
matches.push({ sessionid: record2.id, field: haystack.field, term, at: record2.createdat, excerpt: haystack.text.slice(start, start + 80).trim() });
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
return matches;
|
|
1488
|
+
}
|
|
1489
|
+
function exportsessionfile(records, now) {
|
|
1490
|
+
const recordids = records.map((record2) => record2.id);
|
|
1491
|
+
const payload = JSON.stringify(records);
|
|
1492
|
+
return { formatversion: sessionfileversion, records, recordids, bytesize: payload.length, checksum: checksumtext(`${sessionfileversion}:${recordids.join(",")}:${payload.length}`), exportedat: now };
|
|
1493
|
+
}
|
|
1494
|
+
function importsessionfile(value) {
|
|
1495
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
1496
|
+
const candidate = value;
|
|
1497
|
+
if (candidate.formatversion !== sessionfileversion) return void 0;
|
|
1498
|
+
const records = Array.isArray(candidate.records) ? candidate.records.flatMap((record2) => sessionrecordvalid(record2) ? [record2] : []) : [];
|
|
1499
|
+
if (records.length === 0) return void 0;
|
|
1500
|
+
if (!Array.isArray(candidate.recordids) || candidate.recordids.length !== records.length || !candidate.recordids.every((id, index) => id === records[index]?.id)) return void 0;
|
|
1501
|
+
const bytesize = typeof candidate.bytesize === "number" && Number.isFinite(candidate.bytesize) ? candidate.bytesize : -1;
|
|
1502
|
+
if (bytesize < 0) return void 0;
|
|
1503
|
+
const checksum = typeof candidate.checksum === "string" ? candidate.checksum : "";
|
|
1504
|
+
if (checksum !== checksumtext(`${sessionfileversion}:${candidate.recordids.join(",")}:${bytesize}`)) return void 0;
|
|
1505
|
+
return { formatversion: sessionfileversion, records, recordids: candidate.recordids, bytesize, checksum, exportedat: typeof candidate.exportedat === "number" && Number.isFinite(candidate.exportedat) ? candidate.exportedat : 0 };
|
|
1506
|
+
}
|
|
1507
|
+
function sessionrecordvalid(value) {
|
|
1508
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1509
|
+
const candidate = value;
|
|
1510
|
+
if (typeof candidate.id !== "string" || !candidate.id.trim()) return false;
|
|
1511
|
+
if (typeof candidate.name !== "string" || !candidate.name.trim()) return false;
|
|
1512
|
+
if (typeof candidate.createdat !== "number" || !Number.isFinite(candidate.createdat)) return false;
|
|
1513
|
+
if (!Array.isArray(candidate.tabs) || !candidate.tabs.every((tab) => sessiontabof(tab) !== void 0)) return false;
|
|
1514
|
+
if (!Array.isArray(candidate.captures) || !candidate.captures.every((id) => typeof id === "string")) return false;
|
|
1515
|
+
if (!Array.isArray(candidate.tags) || !candidate.tags.every((tag) => typeof tag === "string")) return false;
|
|
1516
|
+
return true;
|
|
1517
|
+
}
|
|
1518
|
+
function expiresessions(records, retention, now) {
|
|
1519
|
+
if (retention === void 0 || !Number.isFinite(retention)) return records;
|
|
1520
|
+
return records.map((record2) => {
|
|
1521
|
+
if (record2.sectionsexpired || now - record2.createdat < retention) return record2;
|
|
1522
|
+
return { id: record2.id, name: record2.name, createdat: record2.createdat, tabs: [], captures: record2.captures, storage: [], cookies: [], ...record2.folder !== void 0 ? { folder: record2.folder } : {}, tags: record2.tags, ...record2.auto === true ? { auto: true } : {}, ...record2.restoredat !== void 0 ? { restoredat: record2.restoredat } : {}, sectionsexpired: true };
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
function filteredsessions(records, filter) {
|
|
1526
|
+
return records.filter((record2) => {
|
|
1527
|
+
if (filter.name !== void 0 && !record2.name.toLowerCase().includes(filter.name.toLowerCase())) return false;
|
|
1528
|
+
if (filter.folder !== void 0 && record2.folder !== filter.folder) return false;
|
|
1529
|
+
if (filter.from !== void 0 && record2.createdat < filter.from) return false;
|
|
1530
|
+
if (filter.to !== void 0 && record2.createdat > filter.to) return false;
|
|
1531
|
+
return true;
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
function crashinterrupted(state, plansteps, now) {
|
|
1535
|
+
if (!state) return void 0;
|
|
1536
|
+
if (state.stepcursor >= plansteps) return state;
|
|
1537
|
+
return { ...state, interrupted: true, crashat: state.crashat ?? now };
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1334
1540
|
// memory.ts
|
|
1335
1541
|
var sessionmemory = class {
|
|
1336
1542
|
constructor(adapter) {
|
|
@@ -2778,6 +2984,92 @@ var sessionmemory = class {
|
|
|
2778
2984
|
async getlocationconsents() {
|
|
2779
2985
|
return await this.adapter.get("locationconsents") ?? [];
|
|
2780
2986
|
}
|
|
2987
|
+
/** Returns the persisted task state checkpoint of one run so the run resumes after a service worker restart. */
|
|
2988
|
+
async gettaskstate(runid) {
|
|
2989
|
+
return this.adapter.get(`taskstate${runid}`);
|
|
2990
|
+
}
|
|
2991
|
+
/** Persists one task state checkpoint per run with its corruption checksum. */
|
|
2992
|
+
async settaskstate(state) {
|
|
2993
|
+
return this.adapter.set(`taskstate${state.runid}`, state);
|
|
2994
|
+
}
|
|
2995
|
+
/** Returns the session event history with timestamps, newest first. */
|
|
2996
|
+
async getsessionevents() {
|
|
2997
|
+
return await this.adapter.get("sessionevents") ?? [];
|
|
2998
|
+
}
|
|
2999
|
+
/** Records one session event of the run with its timestamp and detail. */
|
|
3000
|
+
async addsessionevent(event) {
|
|
3001
|
+
const records = await this.getsessionevents();
|
|
3002
|
+
await this.adapter.set("sessionevents", [event, ...records]);
|
|
3003
|
+
}
|
|
3004
|
+
/** Returns every saved session record with its sections, newest first. */
|
|
3005
|
+
async getsessionrecords() {
|
|
3006
|
+
return await this.adapter.get("sessionrecords") ?? [];
|
|
3007
|
+
}
|
|
3008
|
+
/** Adds one saved session record to the library. */
|
|
3009
|
+
async addsessionrecord(record2) {
|
|
3010
|
+
const records = await this.getsessionrecords();
|
|
3011
|
+
await this.adapter.set("sessionrecords", [record2, ...records]);
|
|
3012
|
+
}
|
|
3013
|
+
/** Replaces one saved session record by its id after a filing or restore touches it. */
|
|
3014
|
+
async updatesessionrecord(record2) {
|
|
3015
|
+
const records = await this.getsessionrecords();
|
|
3016
|
+
await this.adapter.set("sessionrecords", records.map((item) => item.id === record2.id ? record2 : item));
|
|
3017
|
+
}
|
|
3018
|
+
/** Lists saved sessions filtered by name substring, folder and time window; the filter stays a user choice with no result cap. */
|
|
3019
|
+
async listsessions(filter) {
|
|
3020
|
+
return filteredsessions(await this.getsessionrecords(), filter);
|
|
3021
|
+
}
|
|
3022
|
+
/** Returns one saved session with every section; an expired record carries its metadata only. */
|
|
3023
|
+
async getsessionrecord(id) {
|
|
3024
|
+
return (await this.getsessionrecords()).find((record2) => record2.id === id);
|
|
3025
|
+
}
|
|
3026
|
+
/** Runs the reviewed search query across every stored session and returns the matches with their session ids and time windows. */
|
|
3027
|
+
async searchmemory(query) {
|
|
3028
|
+
return searchsessionrecords(query, await this.getsessionrecords());
|
|
3029
|
+
}
|
|
3030
|
+
/** Returns the folder tree of the session library. */
|
|
3031
|
+
async getsessionfolders() {
|
|
3032
|
+
return await this.adapter.get("sessionfolders") ?? [];
|
|
3033
|
+
}
|
|
3034
|
+
/** Replaces the folder tree after a reviewed filing adds or moves one folder. */
|
|
3035
|
+
async setsessionfolders(folders) {
|
|
3036
|
+
return this.adapter.set("sessionfolders", folders);
|
|
3037
|
+
}
|
|
3038
|
+
/** Returns every stored session diff result, newest first. */
|
|
3039
|
+
async getsessiondiffs() {
|
|
3040
|
+
return await this.adapter.get("sessiondiffs") ?? [];
|
|
3041
|
+
}
|
|
3042
|
+
/** Stores one session diff result for later review. */
|
|
3043
|
+
async addsessiondiff(diff) {
|
|
3044
|
+
const records = await this.getsessiondiffs();
|
|
3045
|
+
await this.adapter.set("sessiondiffs", [diff, ...records]);
|
|
3046
|
+
}
|
|
3047
|
+
/** Returns the persisted auto snapshot state with the reviewed interval, the last snapshot time and the snapshot count. */
|
|
3048
|
+
async getautosnapshot() {
|
|
3049
|
+
return await this.adapter.get("autosnapshot") ?? void 0;
|
|
3050
|
+
}
|
|
3051
|
+
/** Stores the auto snapshot state of the reviewed interval. */
|
|
3052
|
+
async setautosnapshot(state) {
|
|
3053
|
+
return this.adapter.set("autosnapshot", state);
|
|
3054
|
+
}
|
|
3055
|
+
/** Clears the auto snapshot interval so on demand captures stay the only source of records. */
|
|
3056
|
+
async clearautosnapshot() {
|
|
3057
|
+
return this.adapter.set("autosnapshot", null);
|
|
3058
|
+
}
|
|
3059
|
+
/** Expires the heavy sections of saved sessions after the reviewed retention window while the record metadata survives. */
|
|
3060
|
+
async applysessionexpiry(retention, now) {
|
|
3061
|
+
const records = expiresessions(await this.getsessionrecords(), retention, now);
|
|
3062
|
+
await this.adapter.set("sessionrecords", records);
|
|
3063
|
+
return records;
|
|
3064
|
+
}
|
|
3065
|
+
/** Returns the crash marker of a run interrupted by a browser restart. */
|
|
3066
|
+
async getcrashflag() {
|
|
3067
|
+
return await this.adapter.get("crashed") ?? false;
|
|
3068
|
+
}
|
|
3069
|
+
/** Sets the crash marker so the sessions view offers the crash restore inside the consent model. */
|
|
3070
|
+
async setcrashflag(value) {
|
|
3071
|
+
return this.adapter.set("crashed", value);
|
|
3072
|
+
}
|
|
2781
3073
|
};
|
|
2782
3074
|
function mediakindof(record2) {
|
|
2783
3075
|
if ("pages" in record2) return "pdf";
|
|
@@ -3724,9 +4016,9 @@ function polldecision(input) {
|
|
|
3724
4016
|
}
|
|
3725
4017
|
|
|
3726
4018
|
// policy.ts
|
|
3727
|
-
var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles", "attachcdp", "detachcdp", "cdpcmd", "overridescript", "heapshot", "profilecpu", "capturesourcemaps", "emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission"]);
|
|
4019
|
+
var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages", "callrest", "callgraphql", "sendmessage", "blockrequest", "mockresponse", "rewriteheaders", "setcookies", "clearcookies", "authflow", "saveapikey", "routeproxy", "postform", "postfiles", "attachcdp", "detachcdp", "cdpcmd", "overridescript", "heapshot", "profilecpu", "capturesourcemaps", "emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "restoresession", "exportsessions", "importsessions"]);
|
|
3728
4020
|
var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction", "capturebodies", "setbreakpoint", "stepcode", "watchexpr"]);
|
|
3729
|
-
var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace", "blackboxscripts"]);
|
|
4021
|
+
var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs", "fetchurl", "parsejson", "parsehtml", "opensocket", "waitmessage", "watchrequests", "readheaders", "mapapi", "subscribesse", "longpoll", "extractapi", "readcookies", "watchconsole", "watcherrors", "watchtasks", "watchcdp", "measureflow", "trackmemory", "watchshifts", "traceload", "annotatetrace", "replaytrace", "blackboxscripts", "persiststate", "capturesession", "namedsessions", "diffsessions", "searchsessions"]);
|
|
3730
4022
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
3731
4023
|
var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
|
|
3732
4024
|
var targetactions = /* @__PURE__ */ new Set(["inspect", "focus", "click", "type", "scroll", "select", "hover", "clickdeep", "rightclick", "doubleclick", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "highlight", "setattribute", "removeattribute", "waitfor", "shiftclick", "typetime", "appendtext", "setvalue", "typeedit", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "expanddetails", "verifyvisible", "verifyenabled", "pierceshadow", "deriveselector", "fingerprintsection", "submitform", "retryform", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword", "scrapetable", "paginateextract", "shotelement", "captureframe", "shotcanvas"]);
|
|
@@ -3746,6 +4038,7 @@ var debugactions = /* @__PURE__ */ new Set(["watchconsole", "watcherrors", "watc
|
|
|
3746
4038
|
var cdpactions = /* @__PURE__ */ new Set(["attachcdp", "detachcdp", "cdpcmd", "watchcdp", "setbreakpoint", "stepcode", "watchexpr", "overridescript"]);
|
|
3747
4039
|
var profileractions = /* @__PURE__ */ new Set(["measureflow", "heapshot", "trackmemory", "profilecpu", "watchshifts", "traceload", "annotatetrace", "replaytrace", "capturesourcemaps"]);
|
|
3748
4040
|
var emulationactions = /* @__PURE__ */ new Set(["emulatedevice", "emulatenetwork", "emulatelocate", "setuseragent", "overridepermission", "blackboxscripts"]);
|
|
4041
|
+
var sessionactions = /* @__PURE__ */ new Set(["persiststate", "capturesession", "restoresession", "namedsessions", "diffsessions", "searchsessions", "exportsessions", "importsessions"]);
|
|
3749
4042
|
var credentialheaders = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2", "set-cookie", "api-key", "x-api-key", "x-auth-token", "x-session-token", "proxy-authorization"]);
|
|
3750
4043
|
var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
|
|
3751
4044
|
var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
|
|
@@ -3761,6 +4054,9 @@ function hostpattern(origin) {
|
|
|
3761
4054
|
if (parsed.protocol !== "https:") throw new Error("Only HTTPS origins can be granted.");
|
|
3762
4055
|
return `${parsed.origin}/*`;
|
|
3763
4056
|
}
|
|
4057
|
+
function issessionkind(kind) {
|
|
4058
|
+
return sessionactions.has(kind);
|
|
4059
|
+
}
|
|
3764
4060
|
function iswatchkind(kind) {
|
|
3765
4061
|
return watchactions.has(kind);
|
|
3766
4062
|
}
|
|
@@ -5135,6 +5431,97 @@ function permissionnamevalid(name) {
|
|
|
5135
5431
|
if (!browserpermissions.includes(name)) return { allowed: false, reason: `The permission ${name} stays outside the reviewed browser permission set: ${browserpermissions.join(", ")}.` };
|
|
5136
5432
|
return { allowed: true };
|
|
5137
5433
|
}
|
|
5434
|
+
function validatesessiongrammar(step, options) {
|
|
5435
|
+
const kind = step.kind;
|
|
5436
|
+
if (kind === "persiststate") {
|
|
5437
|
+
if (options.resume !== void 0 && typeof options.resume !== "boolean") return { allowed: false, reason: "The reviewed resume flag must be a boolean." };
|
|
5438
|
+
return { allowed: true };
|
|
5439
|
+
}
|
|
5440
|
+
if (kind === "capturesession") {
|
|
5441
|
+
const plan = snapshotplanof(options.snapshot);
|
|
5442
|
+
if (!plan) return { allowed: false, reason: "The session capture needs a reviewed snapshot plan with its scope, a non-empty section list of the reviewed grammar (tabs, scroll, forms, storage, cookies) and the capture link flag." };
|
|
5443
|
+
if (plan.auto !== void 0) {
|
|
5444
|
+
const interval = autointervalof(options.snapshot.auto);
|
|
5445
|
+
if (interval === void 0) return { allowed: false, reason: "The reviewed auto snapshot interval needs a positive period, a positive maximum snapshot count and a zero or positive expiry window with no code ceiling." };
|
|
5446
|
+
}
|
|
5447
|
+
return { allowed: true };
|
|
5448
|
+
}
|
|
5449
|
+
if (kind === "restoresession") {
|
|
5450
|
+
if (typeof options.sessionid !== "string" || !options.sessionid.trim()) return { allowed: false, reason: "The session restore needs the reviewed session id of the saved record." };
|
|
5451
|
+
if (restoreplanof(options.restore) === void 0) return { allowed: false, reason: "The session restore needs a reviewed restore plan with its tab, form and capture policies." };
|
|
5452
|
+
if (options.reviewed !== true) return { allowed: false, reason: "Every session restore needs the explicit restore review with its tabs, form state and captures listed before it reopens anything." };
|
|
5453
|
+
return { allowed: true };
|
|
5454
|
+
}
|
|
5455
|
+
if (kind === "namedsessions") {
|
|
5456
|
+
if (typeof options.sessionid !== "string" || !options.sessionid.trim()) return { allowed: false, reason: "The session filing needs the reviewed session id of the saved record." };
|
|
5457
|
+
if (typeof options.name !== "string" || !options.name.trim()) return { allowed: false, reason: "The session filing needs a reviewed non-empty session name." };
|
|
5458
|
+
if (options.folder !== void 0 && (typeof options.folder !== "string" || !options.folder.trim())) return { allowed: false, reason: "The reviewed folder name must be a non-empty string." };
|
|
5459
|
+
if (options.tags !== void 0 && (!Array.isArray(options.tags) || !options.tags.every((tag) => typeof tag === "string" && tag.trim()))) return { allowed: false, reason: "The reviewed tag list must be a list of non-empty strings." };
|
|
5460
|
+
return { allowed: true };
|
|
5461
|
+
}
|
|
5462
|
+
if (kind === "diffsessions") {
|
|
5463
|
+
if (typeof options.left !== "string" || !options.left.trim() || typeof options.right !== "string" || !options.right.trim()) return { allowed: false, reason: "The session diff needs the reviewed ids of both saved sessions." };
|
|
5464
|
+
return { allowed: true };
|
|
5465
|
+
}
|
|
5466
|
+
if (kind === "searchsessions") {
|
|
5467
|
+
if (searchqueryof(options.query) === void 0) return { allowed: false, reason: "The session search needs a reviewed query with a non-empty term list, fields of the reviewed grammar (urls, titles, names, text) and an optional time window." };
|
|
5468
|
+
return { allowed: true };
|
|
5469
|
+
}
|
|
5470
|
+
if (kind === "exportsessions") {
|
|
5471
|
+
if (options.reviewed !== true) return { allowed: false, reason: "Session exports need the explicit export review before any session file leaves the device." };
|
|
5472
|
+
if (options.ids !== void 0 && (!Array.isArray(options.ids) || options.ids.length === 0 || !options.ids.every((id) => typeof id === "string" && id.trim()))) return { allowed: false, reason: "The reviewed export id list must be a non-empty list of saved session ids." };
|
|
5473
|
+
return { allowed: true };
|
|
5474
|
+
}
|
|
5475
|
+
if (kind === "importsessions") {
|
|
5476
|
+
if (options.reviewed !== true) return { allowed: false, reason: "Session imports need the explicit full record review before any record joins the library." };
|
|
5477
|
+
if (importsessionfile(options.file) === void 0) return { allowed: false, reason: "The session import needs a reviewed file of the known format version with an intact checksum." };
|
|
5478
|
+
return { allowed: true };
|
|
5479
|
+
}
|
|
5480
|
+
return { allowed: true };
|
|
5481
|
+
}
|
|
5482
|
+
function restorereviewgranted(step) {
|
|
5483
|
+
let options = {};
|
|
5484
|
+
try {
|
|
5485
|
+
options = parseoptions(step);
|
|
5486
|
+
} catch {
|
|
5487
|
+
options = {};
|
|
5488
|
+
}
|
|
5489
|
+
if (restoreplanof(options.restore) === void 0) return { allowed: false, reason: "Every session restore needs a reviewed restore plan with its tab, form and capture policies." };
|
|
5490
|
+
if (options.reviewed !== true) return { allowed: false, reason: "The session restore needs the explicit restore review of its tabs, form state and captures before it reopens anything." };
|
|
5491
|
+
return { allowed: true };
|
|
5492
|
+
}
|
|
5493
|
+
function sessionrestoregate(input) {
|
|
5494
|
+
const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now: input.now, action: "run the session memory step" });
|
|
5495
|
+
if (!gate.allowed) return gate;
|
|
5496
|
+
if (!input.plan || input.plan.state !== "approved") return { allowed: false, reason: "Session memory steps need an approved plan before they run." };
|
|
5497
|
+
if (input.step.kind === "restoresession") return restorereviewgranted(input.step);
|
|
5498
|
+
return { allowed: true };
|
|
5499
|
+
}
|
|
5500
|
+
function restoreoriginsgranted(urls, grants) {
|
|
5501
|
+
const covered = new Set(grants);
|
|
5502
|
+
const skippedorigins = [];
|
|
5503
|
+
for (const url of urls) {
|
|
5504
|
+
let origin = "";
|
|
5505
|
+
try {
|
|
5506
|
+
origin = new URL(url).origin;
|
|
5507
|
+
} catch {
|
|
5508
|
+
origin = "";
|
|
5509
|
+
}
|
|
5510
|
+
if (!origin || !covered.has(origin)) skippedorigins.push(origin || url);
|
|
5511
|
+
}
|
|
5512
|
+
return { allowed: skippedorigins.length === 0, skippedorigins: [...new Set(skippedorigins)] };
|
|
5513
|
+
}
|
|
5514
|
+
function sessionnameunique(name, records, recordid) {
|
|
5515
|
+
if (records.some((record2) => record2.name === name && record2.id !== recordid)) return { allowed: false, reason: `The session name ${name} already exists in the library; review a unique name.` };
|
|
5516
|
+
return { allowed: true };
|
|
5517
|
+
}
|
|
5518
|
+
function sessionfolderunique(name, folders) {
|
|
5519
|
+
if (folders.some((folder) => folder.name === name)) return { allowed: false, reason: `The folder name ${name} already exists in the library; review a unique folder name.` };
|
|
5520
|
+
return { allowed: true };
|
|
5521
|
+
}
|
|
5522
|
+
function snapshotretentionwindow(settings) {
|
|
5523
|
+
return settings?.sessionretention;
|
|
5524
|
+
}
|
|
5138
5525
|
function permissionstatevalid(state) {
|
|
5139
5526
|
if (!permissionstates.includes(state)) return { allowed: false, reason: `The reviewed permission state must be one of ${permissionstates.join(", ")}.` };
|
|
5140
5527
|
return { allowed: true };
|
|
@@ -5700,6 +6087,10 @@ function validatestep(step, origin) {
|
|
|
5700
6087
|
const emulationcheck = validateemulationgrammar(step, options);
|
|
5701
6088
|
if (!emulationcheck.allowed) return emulationcheck;
|
|
5702
6089
|
}
|
|
6090
|
+
if (issessionkind(step.kind)) {
|
|
6091
|
+
const sessioncheck = validatesessiongrammar(step, options);
|
|
6092
|
+
if (!sessioncheck.allowed) return sessioncheck;
|
|
6093
|
+
}
|
|
5703
6094
|
if (step.kind === "tabcreate") {
|
|
5704
6095
|
if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
|
|
5705
6096
|
if (options.window !== void 0 && (typeof options.window !== "number" || !Number.isInteger(options.window) || options.window < 0)) return { allowed: false, reason: "The reviewed target window id must be a non-negative integer." };
|
|
@@ -5873,6 +6264,23 @@ function canexecute(input) {
|
|
|
5873
6264
|
const emugatecheck = emugate({ session: input.session, plan: input.plan, step: input.step, tabid: input.tabid, origin: input.origin, now });
|
|
5874
6265
|
if (!emugatecheck.allowed) return emugatecheck;
|
|
5875
6266
|
}
|
|
6267
|
+
if (issessionkind(input.step.kind)) {
|
|
6268
|
+
const sessiongatecheck = sessionrestoregate({ session: input.session, plan: input.plan, step: input.step, tabid: input.tabid, origin: input.origin, now });
|
|
6269
|
+
if (!sessiongatecheck.allowed) return sessiongatecheck;
|
|
6270
|
+
if (input.step.kind === "restoresession") {
|
|
6271
|
+
let restoreoptions = {};
|
|
6272
|
+
try {
|
|
6273
|
+
restoreoptions = parseoptions(input.step);
|
|
6274
|
+
} catch {
|
|
6275
|
+
restoreoptions = {};
|
|
6276
|
+
}
|
|
6277
|
+
for (const url of Array.isArray(restoreoptions.origins) ? restoreoptions.origins : []) {
|
|
6278
|
+
if (typeof url !== "string" || !url) continue;
|
|
6279
|
+
const origingate = origincheck(input.session, url);
|
|
6280
|
+
if (!origingate.allowed) return { allowed: false, reason: `The session restore reopens ${url} outside the session origin grants; review the restore record or grant the origin.` };
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
}
|
|
5876
6284
|
if (iscontrolkind(input.step.kind)) {
|
|
5877
6285
|
const controlgate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: "control the network" });
|
|
5878
6286
|
if (!controlgate.allowed) return controlgate;
|
|
@@ -5956,7 +6364,7 @@ function canexecute(input) {
|
|
|
5956
6364
|
}
|
|
5957
6365
|
|
|
5958
6366
|
// version.ts
|
|
5959
|
-
var packageversion = "1.1.
|
|
6367
|
+
var packageversion = "1.1.49";
|
|
5960
6368
|
|
|
5961
6369
|
// types.ts
|
|
5962
6370
|
var protocolversion = packageversion;
|
|
@@ -6150,6 +6558,28 @@ function parseproposal(value, origin, grants) {
|
|
|
6150
6558
|
}
|
|
6151
6559
|
if (step.kind === "overridepermission" && permissiongrantof(emulationoptions.permission) === void 0) throw new Error("Permission overrides of unknown permission names are refused.");
|
|
6152
6560
|
}
|
|
6561
|
+
if (issessionkind(step.kind)) {
|
|
6562
|
+
let sessionoptions = {};
|
|
6563
|
+
try {
|
|
6564
|
+
sessionoptions = parseoptions(step);
|
|
6565
|
+
} catch {
|
|
6566
|
+
sessionoptions = {};
|
|
6567
|
+
}
|
|
6568
|
+
if (step.kind === "restoresession") {
|
|
6569
|
+
for (const url of Array.isArray(sessionoptions.origins) ? sessionoptions.origins : []) {
|
|
6570
|
+
if (typeof url !== "string" || !url) continue;
|
|
6571
|
+
const granted = covered.some((pattern) => {
|
|
6572
|
+
try {
|
|
6573
|
+
return new URL(url).origin === new URL(pattern).origin;
|
|
6574
|
+
} catch {
|
|
6575
|
+
return false;
|
|
6576
|
+
}
|
|
6577
|
+
});
|
|
6578
|
+
if (!granted) throw new Error(`The session restore reopens ${url} outside the grants.`);
|
|
6579
|
+
}
|
|
6580
|
+
}
|
|
6581
|
+
if (step.kind === "importsessions" && importsessionfile(sessionoptions.file) === void 0) throw new Error("Session import files of unknown format versions are refused.");
|
|
6582
|
+
}
|
|
6153
6583
|
const evaluation = validatestep(step, origin);
|
|
6154
6584
|
if (!evaluation.allowed) throw new Error(evaluation.reason);
|
|
6155
6585
|
const target = outboundtarget(step);
|
|
@@ -6224,7 +6654,7 @@ function requestbody(input) {
|
|
|
6224
6654
|
return JSON.stringify({ version: protocolversion, objective: input.objective, session: input.session, observation: input.observation, capabilities: input.capabilities });
|
|
6225
6655
|
}
|
|
6226
6656
|
function outcomeresponse(input) {
|
|
6227
|
-
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {}, ...input.cdp ? { cdp: input.cdp } : {}, ...input.profile ? { profile: input.profile } : {}, ...input.emulation ? { emulation: input.emulation } : {} });
|
|
6657
|
+
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, outcome: input.outcome, ...input.resolvedtarget ? { resolvedtarget: input.resolvedtarget } : {}, ...input.capture ? { capture: input.capture } : {}, ...input.media ? { media: input.media } : {}, ...input.transport ? { transport: input.transport } : {}, ...input.network ? { network: input.network } : {}, ...input.control ? { control: input.control } : {}, ...input.timeline ? { timeline: input.timeline } : {}, ...input.cdp ? { cdp: input.cdp } : {}, ...input.profile ? { profile: input.profile } : {}, ...input.emulation ? { emulation: input.emulation } : {}, ...input.session ? { session: input.session } : {} });
|
|
6228
6658
|
}
|
|
6229
6659
|
function mapresponse(input) {
|
|
6230
6660
|
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, map: input.map });
|
|
@@ -6370,6 +6800,9 @@ function emulationreport(input) {
|
|
|
6370
6800
|
});
|
|
6371
6801
|
return { version: protocolversion, ...input.state !== void 0 ? { state: input.state } : {}, layers: input.state?.layers ?? [], devices: input.devices, networks: input.networks, locations: input.locations, agents: input.agents, blackbox: input.blackbox, permissions: input.permissions, consents };
|
|
6372
6802
|
}
|
|
6803
|
+
function sessionreport(input) {
|
|
6804
|
+
return { version: protocolversion, records: input.records, events: input.events, folders: input.folders, diffs: input.diffs, ...input.auto !== void 0 ? { auto: input.auto } : {}, ...input.crashed === true ? { crashed: true } : {} };
|
|
6805
|
+
}
|
|
6373
6806
|
export {
|
|
6374
6807
|
activelayers,
|
|
6375
6808
|
agentgrammarvalid,
|
|
@@ -6391,6 +6824,7 @@ export {
|
|
|
6391
6824
|
authconsentgranted,
|
|
6392
6825
|
authorizeurl,
|
|
6393
6826
|
authreport,
|
|
6827
|
+
autointervalof,
|
|
6394
6828
|
blackboxedurls,
|
|
6395
6829
|
blackboxmatches,
|
|
6396
6830
|
blackboxruleof,
|
|
@@ -6449,6 +6883,7 @@ export {
|
|
|
6449
6883
|
cookierecordof,
|
|
6450
6884
|
correlationid,
|
|
6451
6885
|
cpusnap,
|
|
6886
|
+
crashinterrupted,
|
|
6452
6887
|
croprect,
|
|
6453
6888
|
crossesviewport,
|
|
6454
6889
|
cursorfrom,
|
|
@@ -6462,6 +6897,7 @@ export {
|
|
|
6462
6897
|
devicepresetof,
|
|
6463
6898
|
diffresponse,
|
|
6464
6899
|
diffreviewgrade,
|
|
6900
|
+
diffsessionrecords,
|
|
6465
6901
|
downloadreport,
|
|
6466
6902
|
emugate,
|
|
6467
6903
|
emulationkinds,
|
|
@@ -6475,13 +6911,16 @@ export {
|
|
|
6475
6911
|
exchangesreport,
|
|
6476
6912
|
expirelayers,
|
|
6477
6913
|
expireprofilerecords,
|
|
6914
|
+
expiresessions,
|
|
6478
6915
|
exportpresetlibrary,
|
|
6916
|
+
exportsessionfile,
|
|
6479
6917
|
extractionreport,
|
|
6480
6918
|
extractvalues,
|
|
6481
6919
|
failureclass,
|
|
6482
6920
|
familyofkind,
|
|
6483
6921
|
fetchoptionsof,
|
|
6484
6922
|
fetchrequestof,
|
|
6923
|
+
filteredsessions,
|
|
6485
6924
|
filterentries,
|
|
6486
6925
|
filterexchanges,
|
|
6487
6926
|
finishrecording,
|
|
@@ -6509,6 +6948,7 @@ export {
|
|
|
6509
6948
|
imagematches,
|
|
6510
6949
|
imagenames,
|
|
6511
6950
|
importpresetlibrary,
|
|
6951
|
+
importsessionfile,
|
|
6512
6952
|
iscdpkind,
|
|
6513
6953
|
iscontrolkind,
|
|
6514
6954
|
isdebugkind,
|
|
@@ -6516,6 +6956,7 @@ export {
|
|
|
6516
6956
|
isformkind,
|
|
6517
6957
|
isnetwatchkind,
|
|
6518
6958
|
isprofilekind,
|
|
6959
|
+
issessionkind,
|
|
6519
6960
|
issocketkind,
|
|
6520
6961
|
iswatchkind,
|
|
6521
6962
|
jsonpathrulesof,
|
|
@@ -6556,6 +6997,8 @@ export {
|
|
|
6556
6997
|
newlayer,
|
|
6557
6998
|
newmockspec,
|
|
6558
6999
|
newrecording,
|
|
7000
|
+
newsessiondiff,
|
|
7001
|
+
newsessionrecord,
|
|
6559
7002
|
normalizeendpoint,
|
|
6560
7003
|
oauthflowof,
|
|
6561
7004
|
observationmodeof,
|
|
@@ -6621,6 +7064,9 @@ export {
|
|
|
6621
7064
|
resolutionverdict,
|
|
6622
7065
|
resolvedrisk,
|
|
6623
7066
|
resourcefacts,
|
|
7067
|
+
restoreoriginsgranted,
|
|
7068
|
+
restoreplanof,
|
|
7069
|
+
restorereviewgranted,
|
|
6624
7070
|
retryafterof,
|
|
6625
7071
|
revertalllayers,
|
|
6626
7072
|
revertlayer,
|
|
@@ -6633,15 +7079,29 @@ export {
|
|
|
6633
7079
|
safetyresponse,
|
|
6634
7080
|
scaledrect,
|
|
6635
7081
|
seamweights,
|
|
7082
|
+
searchfields,
|
|
7083
|
+
searchqueryof,
|
|
7084
|
+
searchsessionrecords,
|
|
6636
7085
|
selectorresponse,
|
|
6637
7086
|
sendcdpcommand,
|
|
6638
7087
|
sendfetch,
|
|
6639
7088
|
sequenceintegrity,
|
|
6640
7089
|
serializearg,
|
|
6641
7090
|
serializecdpcommand,
|
|
7091
|
+
sessionfileversion,
|
|
7092
|
+
sessionfolderof,
|
|
7093
|
+
sessionfolderunique,
|
|
7094
|
+
sessionkinds,
|
|
6642
7095
|
sessionmemory,
|
|
7096
|
+
sessionnameunique,
|
|
7097
|
+
sessionreport,
|
|
7098
|
+
sessionrestoregate,
|
|
7099
|
+
sessiontabof,
|
|
6643
7100
|
shiftentryof,
|
|
6644
7101
|
signalsreport,
|
|
7102
|
+
snapshotplanof,
|
|
7103
|
+
snapshotretentionwindow,
|
|
7104
|
+
snapshotsections,
|
|
6645
7105
|
socketgate,
|
|
6646
7106
|
socketkinds,
|
|
6647
7107
|
sourcemapconsentcovers,
|
|
@@ -6660,6 +7120,9 @@ export {
|
|
|
6660
7120
|
subscriptionoptionsof,
|
|
6661
7121
|
tabreportresponse,
|
|
6662
7122
|
targetgate,
|
|
7123
|
+
taskstatechecksum,
|
|
7124
|
+
taskstateof,
|
|
7125
|
+
taskstatevalid,
|
|
6663
7126
|
teardowncdpsession,
|
|
6664
7127
|
teardownplanof,
|
|
6665
7128
|
templateurl,
|