@wenathlan/extension 1.1.35 → 1.1.37
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 +7 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +490 -7
- package/dist/index.js.map +3 -3
- package/dist/memory.d.ts +77 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +29 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +38 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/types.d.ts +221 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +1494 -15
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +585 -5
- package/extension/dist/pagebridge.js.map +4 -4
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +36 -2
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +390 -2
- package/extension/dist/sidepanel.js.map +3 -3
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -352,19 +352,192 @@ var sessionmemory = class {
|
|
|
352
352
|
async setnavstate(tabid, state) {
|
|
353
353
|
return this.adapter.set(`navstate${tabid}`, state);
|
|
354
354
|
}
|
|
355
|
+
/** Stores one named tab layout with its window bounds and group states, replacing the previous layout of that name. */
|
|
356
|
+
async setlayout(layout) {
|
|
357
|
+
const records = (await this.getlayouts()).filter((item) => item.name !== layout.name);
|
|
358
|
+
await this.adapter.set("layouts", [layout, ...records]);
|
|
359
|
+
}
|
|
360
|
+
/** Returns one saved tab layout by name with its timestamp. */
|
|
361
|
+
async getlayout(name) {
|
|
362
|
+
return (await this.getlayouts()).find((item) => item.name === name);
|
|
363
|
+
}
|
|
364
|
+
/** Returns every saved tab layout with its window bounds and group states. */
|
|
365
|
+
async getlayouts() {
|
|
366
|
+
return await this.adapter.get("layouts") ?? [];
|
|
367
|
+
}
|
|
368
|
+
/** Stores one tab group definition with its color choice and member tabs, replacing the previous definition of that name. */
|
|
369
|
+
async settabgroup(group) {
|
|
370
|
+
const records = (await this.gettabgroups()).filter((item) => item.name !== group.name);
|
|
371
|
+
await this.adapter.set("tabgroups", [...records, group]);
|
|
372
|
+
}
|
|
373
|
+
/** Returns every stored tab group definition with its color choice, newest first. */
|
|
374
|
+
async gettabgroups() {
|
|
375
|
+
return await this.adapter.get("tabgroups") ?? [];
|
|
376
|
+
}
|
|
377
|
+
/** Records one tabmeta record with task provenance, replacing the previous metadata of that tab. */
|
|
378
|
+
async settabmeta(meta) {
|
|
379
|
+
const records = (await this.gettabmetas()).filter((item) => item.tabid !== meta.tabid);
|
|
380
|
+
await this.adapter.set("tabmetas", [...records, meta]);
|
|
381
|
+
}
|
|
382
|
+
/** Returns every stored tabmeta record with task provenance. */
|
|
383
|
+
async gettabmetas() {
|
|
384
|
+
return await this.adapter.get("tabmetas") ?? [];
|
|
385
|
+
}
|
|
386
|
+
/** Records one session snapshot of tabs and windows for later restore. */
|
|
387
|
+
async addsnapshot(snapshot) {
|
|
388
|
+
const records = await this.getsnapshots();
|
|
389
|
+
await this.adapter.set("snapshots", [snapshot, ...records]);
|
|
390
|
+
}
|
|
391
|
+
/** Returns every stored session snapshot, newest first. */
|
|
392
|
+
async getsnapshots() {
|
|
393
|
+
return await this.adapter.get("snapshots") ?? [];
|
|
394
|
+
}
|
|
395
|
+
/** Records one closed tab in the history kept for restoretab and reopenrun. */
|
|
396
|
+
async addclosedtab(tab) {
|
|
397
|
+
const records = await this.getclosedtabs();
|
|
398
|
+
await this.adapter.set("closedtabs", [tab, ...records]);
|
|
399
|
+
}
|
|
400
|
+
/** Returns the closed tab history, newest first. */
|
|
401
|
+
async getclosedtabs() {
|
|
402
|
+
return await this.adapter.get("closedtabs") ?? [];
|
|
403
|
+
}
|
|
404
|
+
/** Stores one badge state per task, replacing the previous badge of that task. */
|
|
405
|
+
async setbadge(badge) {
|
|
406
|
+
const records = (await this.getbadges()).filter((item) => item.taskid !== badge.taskid);
|
|
407
|
+
await this.adapter.set("badges", [...records, badge]);
|
|
408
|
+
}
|
|
409
|
+
/** Returns every stored badge state per task. */
|
|
410
|
+
async getbadges() {
|
|
411
|
+
return await this.adapter.get("badges") ?? [];
|
|
412
|
+
}
|
|
413
|
+
/** Records one tab event observed inside a reviewed watchtab registration. */
|
|
414
|
+
async addtabwatchevent(event) {
|
|
415
|
+
const records = await this.gettabwatchevents();
|
|
416
|
+
await this.adapter.set("tabwatchevents", [event, ...records]);
|
|
417
|
+
}
|
|
418
|
+
/** Returns the tab event stream of every reviewed watchtab registration, newest first. */
|
|
419
|
+
async gettabwatchevents() {
|
|
420
|
+
return await this.adapter.get("tabwatchevents") ?? [];
|
|
421
|
+
}
|
|
422
|
+
/** Returns the ids of the scratch windows opened for split work. */
|
|
423
|
+
async getscratchwindows() {
|
|
424
|
+
return await this.adapter.get("scratchwindows") ?? [];
|
|
425
|
+
}
|
|
426
|
+
/** Replaces the scratch window id list after one scratch window opens or closes. */
|
|
427
|
+
async setscratchwindows(ids) {
|
|
428
|
+
return this.adapter.set("scratchwindows", ids);
|
|
429
|
+
}
|
|
430
|
+
/** Returns the pinned control tab state with the live task feed. */
|
|
431
|
+
async getcontroltab() {
|
|
432
|
+
return this.adapter.get("controltab");
|
|
433
|
+
}
|
|
434
|
+
/** Replaces the pinned control tab state. */
|
|
435
|
+
async setcontroltab(state) {
|
|
436
|
+
return this.adapter.set("controltab", state);
|
|
437
|
+
}
|
|
438
|
+
/** Stores one saved form profile under its reviewed name, replacing the previous profile of that name. */
|
|
439
|
+
async setprofile(profile) {
|
|
440
|
+
const records = (await this.getprofiles()).filter((item) => item.name !== profile.name);
|
|
441
|
+
await this.adapter.set("formprofiles", [profile, ...records]);
|
|
442
|
+
}
|
|
443
|
+
/** Returns one saved form profile by its reviewed name. */
|
|
444
|
+
async getprofile(name) {
|
|
445
|
+
return (await this.getprofiles()).find((item) => item.name === name);
|
|
446
|
+
}
|
|
447
|
+
/** Returns every saved form profile with its origin grants, newest first. */
|
|
448
|
+
async getprofiles() {
|
|
449
|
+
return await this.adapter.get("formprofiles") ?? [];
|
|
450
|
+
}
|
|
451
|
+
/** Removes one saved form profile by its reviewed name. */
|
|
452
|
+
async removeprofile(name) {
|
|
453
|
+
const records = (await this.getprofiles()).filter((item) => item.name !== name);
|
|
454
|
+
await this.adapter.set("formprofiles", records);
|
|
455
|
+
}
|
|
456
|
+
/** Records one wizard state with its step history. */
|
|
457
|
+
async addwizard(state) {
|
|
458
|
+
const records = await this.getwizards();
|
|
459
|
+
await this.adapter.set("wizards", [state, ...records]);
|
|
460
|
+
}
|
|
461
|
+
/** Returns every stored wizard state with its step history, newest first. */
|
|
462
|
+
async getwizards() {
|
|
463
|
+
return await this.adapter.get("wizards") ?? [];
|
|
464
|
+
}
|
|
465
|
+
/** Stores one submission ticket with its values hash, replacing the previous ticket of that id. */
|
|
466
|
+
async setticket(ticket) {
|
|
467
|
+
const records = (await this.gettickets()).filter((item) => item.id !== ticket.id);
|
|
468
|
+
await this.adapter.set("submittickets", [ticket, ...records]);
|
|
469
|
+
}
|
|
470
|
+
/** Returns every stored submission ticket with its values hash, newest first. */
|
|
471
|
+
async gettickets() {
|
|
472
|
+
return await this.adapter.get("submittickets") ?? [];
|
|
473
|
+
}
|
|
474
|
+
/** Records one collected error report for correction loops. */
|
|
475
|
+
async adderrorreport(report) {
|
|
476
|
+
const records = await this.geterrorreports();
|
|
477
|
+
await this.adapter.set("errorreports", [report, ...records]);
|
|
478
|
+
}
|
|
479
|
+
/** Returns every stored error report, newest first. */
|
|
480
|
+
async geterrorreports() {
|
|
481
|
+
return await this.adapter.get("errorreports") ?? [];
|
|
482
|
+
}
|
|
483
|
+
/** Records one typeahead pick observed when a reviewed suggestion entry was chosen. */
|
|
484
|
+
async addpick(pick) {
|
|
485
|
+
const records = await this.getpicks();
|
|
486
|
+
await this.adapter.set("typeaheadpicks", [pick, ...records]);
|
|
487
|
+
}
|
|
488
|
+
/** Returns every recorded typeahead pick, newest first. */
|
|
489
|
+
async getpicks() {
|
|
490
|
+
return await this.adapter.get("typeaheadpicks") ?? [];
|
|
491
|
+
}
|
|
492
|
+
/** Records one captcha handoff while the plan waits for the user. */
|
|
493
|
+
async addcaptcha(handoff) {
|
|
494
|
+
const records = await this.getcaptchas();
|
|
495
|
+
await this.adapter.set("captchas", [handoff, ...records]);
|
|
496
|
+
}
|
|
497
|
+
/** Returns every captcha handoff record with its resolution state, newest first. */
|
|
498
|
+
async getcaptchas() {
|
|
499
|
+
return await this.adapter.get("captchas") ?? [];
|
|
500
|
+
}
|
|
501
|
+
/** Resolves one captcha handoff by id once the user finished it. */
|
|
502
|
+
async resolvecaptcha(id, resolvedat) {
|
|
503
|
+
const records = await this.getcaptchas();
|
|
504
|
+
await this.adapter.set("captchas", records.map((handoff) => handoff.id === id && !handoff.resolved ? { ...handoff, resolved: true, resolvedat } : handoff));
|
|
505
|
+
}
|
|
506
|
+
/** Records one login or template detection for its origin. */
|
|
507
|
+
async adddetection(record2) {
|
|
508
|
+
const records = await this.getdetections();
|
|
509
|
+
await this.adapter.set("detections", [record2, ...records]);
|
|
510
|
+
}
|
|
511
|
+
/** Returns every stored login and template detection per origin, newest first. */
|
|
512
|
+
async getdetections() {
|
|
513
|
+
return await this.adapter.get("detections") ?? [];
|
|
514
|
+
}
|
|
515
|
+
/** Stores the reviewed one time code behind the consent gate of an active session. */
|
|
516
|
+
async setcodevalue(value) {
|
|
517
|
+
return this.adapter.set("codevalue", value);
|
|
518
|
+
}
|
|
519
|
+
/** Returns the reviewed one time code, if the user stored one behind the consent gate. */
|
|
520
|
+
async getcodevalue() {
|
|
521
|
+
return this.adapter.get("codevalue");
|
|
522
|
+
}
|
|
355
523
|
};
|
|
356
524
|
function randomid() {
|
|
357
525
|
return crypto.randomUUID();
|
|
358
526
|
}
|
|
359
527
|
|
|
360
528
|
// policy.ts
|
|
361
|
-
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"]);
|
|
529
|
+
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"]);
|
|
362
530
|
var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction"]);
|
|
363
|
-
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"]);
|
|
531
|
+
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"]);
|
|
364
532
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
365
|
-
var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus"]);
|
|
366
|
-
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"]);
|
|
367
|
-
var valueactions = /* @__PURE__ */ new Set(["presskey", "drag", "drop", "upload", "readattribute", "removeattribute", "waittext", "evaluate", "zoomset", "tabactivate", "tabclose", "tabreload", "windowclose", "windowresize", "tabcreate", "windowcreate", "downloadfile", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "chooseradio", "setslider", "setdate", "setcolor", "followlink", "setfragment", "handleauth", "navintent", "openclipboard", "checksafe", "reopentab", "spanav"]);
|
|
533
|
+
var watchactions = /* @__PURE__ */ new Set(["watchmutate", "watchbanner", "watchfocus", "watchtab"]);
|
|
534
|
+
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"]);
|
|
535
|
+
var valueactions = /* @__PURE__ */ new Set(["presskey", "drag", "drop", "upload", "readattribute", "removeattribute", "waittext", "evaluate", "zoomset", "tabactivate", "tabclose", "tabreload", "windowclose", "windowresize", "tabcreate", "windowcreate", "downloadfile", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "chooseradio", "setslider", "setdate", "setcolor", "followlink", "setfragment", "handleauth", "navintent", "openclipboard", "checksafe", "reopentab", "spanav", "duplicatetab", "pintab", "mutetab", "movetab", "movetabwindow", "searchtabs", "badgetab", "attachmeta", "focuswindow", "maximizewindow", "minimizewindow", "restorewindow", "incognitowindow", "asksubmit", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcode", "consentpassword"]);
|
|
536
|
+
var tabscommandactions = /* @__PURE__ */ new Set(["querytabs", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "watchtab", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "savelayout", "restorelayout", "findclones", "searchtabs", "badgetab", "attachmeta", "listaudio", "reopenrun", "snapshotsession"]);
|
|
537
|
+
var formactions = /* @__PURE__ */ new Set(["fillform", "filllabel", "fillplaceholder", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "submitform", "readerrors", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "handoffcaptcha", "fillcard", "fillcode", "consentpassword", "skiphoneypot", "detectlogin", "detecttemplate"]);
|
|
538
|
+
var fieldkinds = ["text", "email", "phone", "date", "number", "select", "check", "radio", "file", "password", "card", "code"];
|
|
539
|
+
var layoutmutationactions = /* @__PURE__ */ new Set(["grouptabs", "colorgroup", "collapsegroup", "savelayout", "restorelayout"]);
|
|
540
|
+
var groupcolors = ["grey", "blue", "red", "yellow", "green", "pink", "purple", "cyan", "orange"];
|
|
368
541
|
function normalizeendpoint(value) {
|
|
369
542
|
const endpoint = new URL(value.trim());
|
|
370
543
|
if (endpoint.protocol !== "https:") throw new Error("Devthink accepts HTTPS endpoints only.");
|
|
@@ -400,6 +573,157 @@ function parseoptions(step) {
|
|
|
400
573
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("Step options must be a JSON object.");
|
|
401
574
|
return parsed;
|
|
402
575
|
}
|
|
576
|
+
function istabscommandkind(kind) {
|
|
577
|
+
return tabscommandactions.has(kind);
|
|
578
|
+
}
|
|
579
|
+
function islayoutkind(kind) {
|
|
580
|
+
return layoutmutationactions.has(kind);
|
|
581
|
+
}
|
|
582
|
+
function isformkind(kind) {
|
|
583
|
+
return formactions.has(kind);
|
|
584
|
+
}
|
|
585
|
+
function validatefieldmatch(value) {
|
|
586
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return { allowed: false, reason: "A reviewed field match is required in options." };
|
|
587
|
+
const match = value;
|
|
588
|
+
if (match.mode !== "label" && match.mode !== "placeholder" && match.mode !== "arialabel" && match.mode !== "name") return { allowed: false, reason: "The reviewed field match mode must be label, placeholder, arialabel or name." };
|
|
589
|
+
const key = match.mode === "label" ? "label" : match.mode === "placeholder" ? "placeholder" : match.mode === "arialabel" ? "arialabel" : "name";
|
|
590
|
+
if (!isnonempty(match[key])) return { allowed: false, reason: `The reviewed ${match.mode} field match needs a non-empty ${key}.` };
|
|
591
|
+
return { allowed: true };
|
|
592
|
+
}
|
|
593
|
+
function validateformrecord(value) {
|
|
594
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return { allowed: false, reason: "A reviewed form record with entries is required in options." };
|
|
595
|
+
const record2 = value;
|
|
596
|
+
if (record2.form !== void 0 && !isnonempty(record2.form)) return { allowed: false, reason: "The reviewed form record form selector must be a non-empty string." };
|
|
597
|
+
if (!Array.isArray(record2.entries) || record2.entries.length === 0) return { allowed: false, reason: "The reviewed form record needs a non-empty list of entries." };
|
|
598
|
+
for (const item of record2.entries) {
|
|
599
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return { allowed: false, reason: "Every reviewed form record entry must be an object." };
|
|
600
|
+
const entry = item;
|
|
601
|
+
const matchcheck = validatefieldmatch(entry.match);
|
|
602
|
+
if (!matchcheck.allowed) return matchcheck;
|
|
603
|
+
if (typeof entry.kind !== "string" || !fieldkinds.includes(entry.kind)) return { allowed: false, reason: "Every reviewed form record entry needs a known field kind." };
|
|
604
|
+
if (typeof entry.value !== "string") return { allowed: false, reason: "Every reviewed form record entry needs a string value." };
|
|
605
|
+
if (entry.kind === "password") return { allowed: false, reason: "Password entries are refused inside form records; use consentpassword with a reviewed consent ref." };
|
|
606
|
+
}
|
|
607
|
+
return { allowed: true };
|
|
608
|
+
}
|
|
609
|
+
function validatevaluegen(value) {
|
|
610
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return { allowed: false, reason: "A reviewed valuegen rule with a field kind is required in options." };
|
|
611
|
+
const rule = value;
|
|
612
|
+
if (typeof rule.kind !== "string" || !fieldkinds.includes(rule.kind)) return { allowed: false, reason: "The reviewed valuegen kind must be a known field kind." };
|
|
613
|
+
if (rule.locale !== void 0 && !isnonempty(rule.locale)) return { allowed: false, reason: "The reviewed valuegen locale must be a non-empty string." };
|
|
614
|
+
if (rule.seed !== void 0 && (typeof rule.seed !== "number" || !Number.isFinite(rule.seed))) return { allowed: false, reason: "The reviewed valuegen seed must be a finite number." };
|
|
615
|
+
return { allowed: true };
|
|
616
|
+
}
|
|
617
|
+
function validatefieldpairs(options, mode) {
|
|
618
|
+
const pairs = options.fields;
|
|
619
|
+
if (!Array.isArray(pairs) || pairs.length === 0) return { allowed: false, reason: "A reviewed non-empty list of field pairs is required in options." };
|
|
620
|
+
for (const item of pairs) {
|
|
621
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return { allowed: false, reason: "Every reviewed field pair must be an object." };
|
|
622
|
+
const pair = item;
|
|
623
|
+
if (!isnonempty(pair[mode])) return { allowed: false, reason: `Every reviewed field pair needs a non-empty ${mode}.` };
|
|
624
|
+
if (typeof pair.value !== "string" || !pair.value.trim()) return { allowed: false, reason: "Every reviewed field pair needs a non-empty value." };
|
|
625
|
+
}
|
|
626
|
+
return { allowed: true };
|
|
627
|
+
}
|
|
628
|
+
function validatecardsegments(value) {
|
|
629
|
+
if (!Array.isArray(value) || value.length === 0) return { allowed: false, reason: "A reviewed non-empty list of card segments is required in options." };
|
|
630
|
+
for (const item of value) {
|
|
631
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return { allowed: false, reason: "Every reviewed card segment must be an object." };
|
|
632
|
+
const segment = item;
|
|
633
|
+
const matchcheck = validatefieldmatch(segment.match);
|
|
634
|
+
if (!matchcheck.allowed) return matchcheck;
|
|
635
|
+
if (typeof segment.value !== "string" || !segment.value.trim()) return { allowed: false, reason: "Every reviewed card segment needs a non-empty value." };
|
|
636
|
+
}
|
|
637
|
+
return { allowed: true };
|
|
638
|
+
}
|
|
639
|
+
function validateformgrammar(step, options) {
|
|
640
|
+
const kind = step.kind;
|
|
641
|
+
if (kind === "fillform" || kind === "saveprofiles" && options.formrecord !== void 0) {
|
|
642
|
+
const recordcheck = validateformrecord(options.formrecord);
|
|
643
|
+
if (!recordcheck.allowed) return recordcheck;
|
|
644
|
+
}
|
|
645
|
+
if (kind === "filllabel" || kind === "fillplaceholder") {
|
|
646
|
+
const paircheck = validatefieldpairs(options, kind === "filllabel" ? "label" : "placeholder");
|
|
647
|
+
if (!paircheck.allowed) return paircheck;
|
|
648
|
+
}
|
|
649
|
+
if (kind === "generatevalues" && options.valuegen !== void 0) {
|
|
650
|
+
const rulecheck = validatevaluegen(options.valuegen);
|
|
651
|
+
if (!rulecheck.allowed) return rulecheck;
|
|
652
|
+
}
|
|
653
|
+
if (kind === "saveprofiles" && !isnonempty(options.name)) return { allowed: false, reason: "A reviewed profile name is required in options." };
|
|
654
|
+
if (kind === "submitform" && !isnonempty(options.consentref)) return { allowed: false, reason: "A reviewed consent ref of an approved asksubmit ticket is required in options." };
|
|
655
|
+
if (kind === "retryform") {
|
|
656
|
+
const backoff = options.backoff;
|
|
657
|
+
if (!backoff || typeof backoff !== "object" || Array.isArray(backoff)) return { allowed: false, reason: "A reviewed backoff rule with wait and factor is required in options." };
|
|
658
|
+
const rule = backoff;
|
|
659
|
+
if (typeof rule.wait !== "number" || !Number.isFinite(rule.wait) || rule.wait <= 0) return { allowed: false, reason: "The reviewed retry backoff wait must be a positive number of milliseconds with no code ceiling." };
|
|
660
|
+
if (typeof rule.factor !== "number" || !Number.isFinite(rule.factor) || rule.factor < 1) return { allowed: false, reason: "The reviewed retry backoff factor must be one or greater with no code ceiling." };
|
|
661
|
+
if (options.attempts !== void 0 && (typeof options.attempts !== "number" || !Number.isInteger(options.attempts) || options.attempts < 1)) return { allowed: false, reason: "The reviewed retry attempts must be a positive integer with no code ceiling." };
|
|
662
|
+
}
|
|
663
|
+
if (kind === "runwizard" && options.steps !== void 0 && (typeof options.steps !== "number" || !Number.isInteger(options.steps) || options.steps < 1)) return { allowed: false, reason: "The reviewed wizard step count must be a positive integer with no code ceiling." };
|
|
664
|
+
if (kind === "selectchain") {
|
|
665
|
+
if (!isnonempty(options.child)) return { allowed: false, reason: "A reviewed child selector of the dependent control is required in options." };
|
|
666
|
+
if (!nonnegativeoption(options, "wait")) return { allowed: false, reason: "The reviewed dependent wait must be zero or a positive number of milliseconds." };
|
|
667
|
+
}
|
|
668
|
+
if (kind === "picktypeahead") {
|
|
669
|
+
if (!isnonempty(options.pick)) return { allowed: false, reason: "A reviewed suggestion entry to pick is required in options." };
|
|
670
|
+
if (!nonnegativeoption(options, "timeout")) return { allowed: false, reason: "The reviewed typeahead timeout must be zero or a positive number of milliseconds." };
|
|
671
|
+
}
|
|
672
|
+
if (kind === "pickdate" && !/^\d{4}-\d{2}-\d{2}$/.test(step.value ?? "")) return { allowed: false, reason: "The reviewed date must use the yyyy-mm-dd form." };
|
|
673
|
+
if (kind === "fillcard") {
|
|
674
|
+
const segmentcheck = validatecardsegments(options.segments);
|
|
675
|
+
if (!segmentcheck.allowed) return segmentcheck;
|
|
676
|
+
if (!nonnegativeoption(options, "pause")) return { allowed: false, reason: "The reviewed card typing pause must be zero or a positive number of milliseconds." };
|
|
677
|
+
}
|
|
678
|
+
if (kind === "fillcode" && !isnonempty(options.source)) return { allowed: false, reason: "A reviewed one time code source is required in options." };
|
|
679
|
+
if (kind === "consentpassword" && !isnonempty(options.consentref)) return { allowed: false, reason: "A reviewed consent ref is required in options before any password is filled." };
|
|
680
|
+
return { allowed: true };
|
|
681
|
+
}
|
|
682
|
+
function submitreviewgranted(steps, submitid) {
|
|
683
|
+
const position = steps.findIndex((candidate) => candidate.id === submitid);
|
|
684
|
+
const asked = steps.some((candidate, index) => candidate.kind === "asksubmit" && (position === -1 || index < position));
|
|
685
|
+
return asked ? { allowed: true } : { allowed: false, reason: "Form submission requires an asksubmit review step before it." };
|
|
686
|
+
}
|
|
687
|
+
function passwordconsentgranted(step) {
|
|
688
|
+
let options = {};
|
|
689
|
+
try {
|
|
690
|
+
options = parseoptions(step);
|
|
691
|
+
} catch {
|
|
692
|
+
options = {};
|
|
693
|
+
}
|
|
694
|
+
const consentref = options.consentref;
|
|
695
|
+
if (typeof consentref !== "string" || !consentref.trim()) return { allowed: false, reason: "A password fill requires a reviewed consent ref in options." };
|
|
696
|
+
return { allowed: true };
|
|
697
|
+
}
|
|
698
|
+
function luhnvalid(digits) {
|
|
699
|
+
let sum = 0;
|
|
700
|
+
let double = false;
|
|
701
|
+
for (let index = digits.length - 1; index >= 0; index -= 1) {
|
|
702
|
+
let value = Number.parseInt(digits[index] ?? "", 10);
|
|
703
|
+
if (!Number.isFinite(value)) return false;
|
|
704
|
+
if (double) {
|
|
705
|
+
value *= 2;
|
|
706
|
+
if (value > 9) value -= 9;
|
|
707
|
+
}
|
|
708
|
+
sum += value;
|
|
709
|
+
double = !double;
|
|
710
|
+
}
|
|
711
|
+
return sum % 10 === 0;
|
|
712
|
+
}
|
|
713
|
+
function generatedvalueallowed(value) {
|
|
714
|
+
const compact = value.replace(/[\s-]/g, "");
|
|
715
|
+
if (/^\d{13,19}$/.test(compact) && luhnvalid(compact) && !compact.startsWith("4111")) return { allowed: false, reason: "The generated value looks like a real card number and is refused; generated card values use the 4111 test prefix." };
|
|
716
|
+
if (/^\d{3}-\d{2}-\d{4}$/.test(value.trim())) return { allowed: false, reason: "The generated value looks like a personal identifier and is refused." };
|
|
717
|
+
return { allowed: true };
|
|
718
|
+
}
|
|
719
|
+
function profilegrantgranted(profile, origin) {
|
|
720
|
+
if (!profile.grants.includes(origin)) return { allowed: false, reason: `The saved profile ${profile.name} is not granted to ${origin}; add the origin to the profile grants first.` };
|
|
721
|
+
return { allowed: true };
|
|
722
|
+
}
|
|
723
|
+
function layoutmutationgranted(session, now) {
|
|
724
|
+
if (!session || session.stoppedat || session.expiresat <= now) return { allowed: false, reason: "Group and layout mutations stay inside the active session." };
|
|
725
|
+
return { allowed: true };
|
|
726
|
+
}
|
|
403
727
|
function waitduration(step) {
|
|
404
728
|
const requested = step.value ? Number.parseInt(step.value, 10) : 250;
|
|
405
729
|
if (!Number.isFinite(requested) || requested < 0) throw new Error("Wait duration must be zero or a positive number of milliseconds.");
|
|
@@ -566,6 +890,104 @@ function validateratelimit(value) {
|
|
|
566
890
|
if (typeof limit.ceiling !== "number" || !Number.isInteger(limit.ceiling) || limit.ceiling < 1) return { allowed: false, reason: "The reviewed ratelimit ceiling must be a positive integer with no code ceiling." };
|
|
567
891
|
return { allowed: true };
|
|
568
892
|
}
|
|
893
|
+
function validatetabquery(value) {
|
|
894
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return { allowed: false, reason: "A reviewed tabquery with at least one matcher is required in options." };
|
|
895
|
+
const query = value;
|
|
896
|
+
const hasmatcher = query.url !== void 0 || query.title !== void 0 || query.id !== void 0 || query.pattern !== void 0;
|
|
897
|
+
if (!hasmatcher) return { allowed: false, reason: "The reviewed tabquery needs a url, title, id or pattern matcher." };
|
|
898
|
+
if (query.url !== void 0 && !isnonempty(query.url)) return { allowed: false, reason: "The reviewed tabquery url matcher must be a non-empty string." };
|
|
899
|
+
if (query.title !== void 0 && !isnonempty(query.title)) return { allowed: false, reason: "The reviewed tabquery title matcher must be a non-empty string." };
|
|
900
|
+
if (query.pattern !== void 0 && !isnonempty(query.pattern)) return { allowed: false, reason: "The reviewed tabquery pattern matcher must be a non-empty string." };
|
|
901
|
+
if (query.id !== void 0 && (typeof query.id !== "number" || !Number.isInteger(query.id) || query.id < 0)) return { allowed: false, reason: "The reviewed tabquery id matcher must be a non-negative integer tab id." };
|
|
902
|
+
return { allowed: true };
|
|
903
|
+
}
|
|
904
|
+
function validategroupcolor(value) {
|
|
905
|
+
return typeof value === "string" && groupcolors.includes(value);
|
|
906
|
+
}
|
|
907
|
+
function validateidlist(options, key) {
|
|
908
|
+
const ids = options[key];
|
|
909
|
+
return Array.isArray(ids) && ids.length > 0 && ids.every((id) => typeof id === "number" && Number.isInteger(id) && id >= 0);
|
|
910
|
+
}
|
|
911
|
+
function validatetabsgrammar(step, options) {
|
|
912
|
+
const kind = step.kind;
|
|
913
|
+
if (kind === "querytabs" || kind === "closepattern") {
|
|
914
|
+
const querycheck = validatetabquery(options.tabquery);
|
|
915
|
+
if (!querycheck.allowed) return querycheck;
|
|
916
|
+
if (kind === "closepattern" && options.reviewed !== true) return { allowed: false, reason: "The close pattern needs the explicit reviewed flag before any tab closes." };
|
|
917
|
+
}
|
|
918
|
+
if (kind === "duplicatetab" || kind === "pintab" || kind === "mutetab" || kind === "movetab" || kind === "movetabwindow" || kind === "badgetab" || kind === "attachmeta") {
|
|
919
|
+
if (!isnumericid(step.value)) return { allowed: false, reason: "A numeric browser tab id is required." };
|
|
920
|
+
}
|
|
921
|
+
if (kind === "focuswindow" || kind === "maximizewindow" || kind === "minimizewindow" || kind === "restorewindow") {
|
|
922
|
+
if (!isnumericid(step.value)) return { allowed: false, reason: "A numeric browser window id is required." };
|
|
923
|
+
}
|
|
924
|
+
if (kind === "pintab" && typeof options.pinned !== "boolean") return { allowed: false, reason: "A reviewed pinned flag is required in options." };
|
|
925
|
+
if (kind === "mutetab" && typeof options.muted !== "boolean") return { allowed: false, reason: "A reviewed muted flag is required in options." };
|
|
926
|
+
if (kind === "movetab") {
|
|
927
|
+
if (typeof options.index !== "number" || !Number.isInteger(options.index) || options.index < 0) return { allowed: false, reason: "A reviewed non-negative target index is required in options." };
|
|
928
|
+
}
|
|
929
|
+
if (kind === "movetabwindow") {
|
|
930
|
+
if (typeof options.windowid !== "number" || !Number.isInteger(options.windowid) || options.windowid < 0) return { allowed: false, reason: "A reviewed target window id is required in options." };
|
|
931
|
+
}
|
|
932
|
+
if (kind === "grouptabs") {
|
|
933
|
+
const group = options.group;
|
|
934
|
+
if (!group || typeof group !== "object" || Array.isArray(group)) return { allowed: false, reason: "A reviewed group with a name is required in options." };
|
|
935
|
+
const spec = group;
|
|
936
|
+
if (!isnonempty(spec.name)) return { allowed: false, reason: "The reviewed group needs a non-empty name." };
|
|
937
|
+
if (!validategroupcolor(spec.color)) return { allowed: false, reason: "The reviewed group color must be a Chromium tab group color." };
|
|
938
|
+
if (!validateidlist(spec, "tabids")) return { allowed: false, reason: "The reviewed group needs a non-empty list of member tab ids." };
|
|
939
|
+
}
|
|
940
|
+
if (kind === "colorgroup") {
|
|
941
|
+
if (!isnonempty(options.name)) return { allowed: false, reason: "A reviewed group name is required in options." };
|
|
942
|
+
if (!validategroupcolor(options.color)) return { allowed: false, reason: "The reviewed group color must be a Chromium tab group color." };
|
|
943
|
+
}
|
|
944
|
+
if (kind === "collapsegroup") {
|
|
945
|
+
if (!isnonempty(options.name)) return { allowed: false, reason: "A reviewed group name is required in options." };
|
|
946
|
+
if (typeof options.collapsed !== "boolean") return { allowed: false, reason: "A reviewed collapsed flag is required in options." };
|
|
947
|
+
}
|
|
948
|
+
if (kind === "discardtab" || kind === "reloadtabs") {
|
|
949
|
+
if (!isnumericid(step.value) && !validateidlist(options, "tabs")) return { allowed: false, reason: "A numeric tab id or a reviewed list of tab ids is required." };
|
|
950
|
+
}
|
|
951
|
+
if (kind === "zoomin" || kind === "zoomout") {
|
|
952
|
+
if (options.step !== void 0 && (typeof options.step !== "number" || !Number.isFinite(options.step) || options.step <= 0)) return { allowed: false, reason: "The reviewed zoom step must be a positive number with no code ceiling." };
|
|
953
|
+
if (step.value !== void 0 && step.value !== "" && !isnumericid(step.value)) return { allowed: false, reason: "The reviewed zoom target must be a numeric tab id." };
|
|
954
|
+
}
|
|
955
|
+
if (kind === "switchtab") {
|
|
956
|
+
if (options.direction !== "next" && options.direction !== "previous") return { allowed: false, reason: "A reviewed switch direction of next or previous is required in options." };
|
|
957
|
+
}
|
|
958
|
+
if (kind === "restorewindow") {
|
|
959
|
+
const bounds = options.bounds;
|
|
960
|
+
if (bounds !== void 0) {
|
|
961
|
+
if (!bounds || typeof bounds !== "object" || Array.isArray(bounds)) return { allowed: false, reason: "The reviewed window bounds must be an object." };
|
|
962
|
+
const shape = bounds;
|
|
963
|
+
for (const field of ["left", "top", "width", "height"]) {
|
|
964
|
+
if (typeof shape[field] !== "number" || !Number.isFinite(shape[field])) return { allowed: false, reason: "The reviewed window bounds need numeric left, top, width and height." };
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
if (kind === "scratchwindow") {
|
|
969
|
+
if (step.value !== void 0 && step.value !== "" && !ishttpsurl(step.value)) return { allowed: false, reason: "The reviewed scratch window url must use HTTPS." };
|
|
970
|
+
}
|
|
971
|
+
if (kind === "incognitowindow" && !ishttpsurl(step.value)) return { allowed: false, reason: "A reviewed HTTPS url is required to open an incognito window." };
|
|
972
|
+
if (kind === "restoretab" && step.value !== void 0 && step.value !== "" && !ishttpsurl(step.value)) return { allowed: false, reason: "The reviewed restore url must use HTTPS." };
|
|
973
|
+
if (kind === "savelayout" || kind === "restorelayout") {
|
|
974
|
+
if (!isnonempty(options.name)) return { allowed: false, reason: "A reviewed layout name is required in options." };
|
|
975
|
+
}
|
|
976
|
+
if (kind === "badgetab") {
|
|
977
|
+
if (!isnonempty(options.label)) return { allowed: false, reason: "A reviewed badge label is required in options." };
|
|
978
|
+
if (options.taskid !== void 0 && !isnonempty(options.taskid)) return { allowed: false, reason: "The reviewed badge task id must be a non-empty string." };
|
|
979
|
+
}
|
|
980
|
+
if (kind === "attachmeta") {
|
|
981
|
+
const labels = options.labels;
|
|
982
|
+
const taskrefs = options.taskrefs;
|
|
983
|
+
const haslabels = Array.isArray(labels) && labels.length > 0 && labels.every((label) => isnonempty(label));
|
|
984
|
+
const hastaskrefs = Array.isArray(taskrefs) && taskrefs.length > 0 && taskrefs.every((ref) => isnonempty(ref));
|
|
985
|
+
if (!haslabels && !hastaskrefs) return { allowed: false, reason: "Reviewed labels or task refs are required in options to attach metadata." };
|
|
986
|
+
if (options.provenance !== void 0 && !isnonempty(options.provenance)) return { allowed: false, reason: "The reviewed provenance must be a non-empty string." };
|
|
987
|
+
}
|
|
988
|
+
if (kind === "reopenrun" && !isnonempty(options.run)) return { allowed: false, reason: "A reviewed run id is required in options to reopen its tabs." };
|
|
989
|
+
return { allowed: true };
|
|
990
|
+
}
|
|
569
991
|
function validatestep(step, origin) {
|
|
570
992
|
if (!allowedactions.has(step.kind)) return { allowed: false, reason: "Unsupported action kind." };
|
|
571
993
|
if (!step.summary.trim()) return { allowed: false, reason: "A human-readable action summary is required." };
|
|
@@ -767,6 +1189,24 @@ function validatestep(step, origin) {
|
|
|
767
1189
|
const listcheck = validateurllist(options, "urls");
|
|
768
1190
|
if (!listcheck.allowed) return listcheck;
|
|
769
1191
|
}
|
|
1192
|
+
if (istabscommandkind(step.kind)) {
|
|
1193
|
+
const tabscheck = validatetabsgrammar(step, options);
|
|
1194
|
+
if (!tabscheck.allowed) return tabscheck;
|
|
1195
|
+
}
|
|
1196
|
+
if (isformkind(step.kind)) {
|
|
1197
|
+
const formcheck = validateformgrammar(step, options);
|
|
1198
|
+
if (!formcheck.allowed) return formcheck;
|
|
1199
|
+
}
|
|
1200
|
+
if (step.kind === "tabcreate") {
|
|
1201
|
+
if (options.background !== void 0 && typeof options.background !== "boolean") return { allowed: false, reason: "The reviewed background flag must be a boolean." };
|
|
1202
|
+
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." };
|
|
1203
|
+
}
|
|
1204
|
+
if (step.kind === "windowcreate") {
|
|
1205
|
+
for (const field of ["left", "top", "width", "height"]) {
|
|
1206
|
+
if (options[field] !== void 0 && (typeof options[field] !== "number" || !Number.isFinite(options[field]))) return { allowed: false, reason: `The reviewed window ${field} must be a number.` };
|
|
1207
|
+
}
|
|
1208
|
+
if (options.state !== void 0 && !["normal", "maximized", "minimized", "fullscreen"].includes(options.state)) return { allowed: false, reason: "The reviewed window state must be normal, maximized, minimized or fullscreen." };
|
|
1209
|
+
}
|
|
770
1210
|
return { allowed: true };
|
|
771
1211
|
}
|
|
772
1212
|
function sessiongate(input) {
|
|
@@ -797,6 +1237,16 @@ function canexecute(input) {
|
|
|
797
1237
|
if (!navigation.allowed) return navigation;
|
|
798
1238
|
}
|
|
799
1239
|
}
|
|
1240
|
+
if (islayoutkind(input.step.kind) && !layoutmutationgranted(input.session, now).allowed) return { allowed: false, reason: "Group and layout mutations stay inside the active session." };
|
|
1241
|
+
if (input.step.kind === "submitform" || input.step.kind === "retryform") {
|
|
1242
|
+
if (!input.plan) return { allowed: false, reason: "Form submission requires an asksubmit review step before it." };
|
|
1243
|
+
const reviewgate = submitreviewgranted(input.plan.steps, input.step.id);
|
|
1244
|
+
if (!reviewgate.allowed) return reviewgate;
|
|
1245
|
+
}
|
|
1246
|
+
if (input.step.kind === "consentpassword") {
|
|
1247
|
+
const consentgate = passwordconsentgranted(input.step);
|
|
1248
|
+
if (!consentgate.allowed) return consentgate;
|
|
1249
|
+
}
|
|
800
1250
|
if (input.step.kind === "openlink" || input.step.kind === "openprivate" || input.step.kind === "batchopen" || input.step.kind === "prefetch" || input.step.kind === "deeplink" || input.step.kind === "reopentab") {
|
|
801
1251
|
let options = {};
|
|
802
1252
|
try {
|
|
@@ -818,7 +1268,7 @@ function canexecute(input) {
|
|
|
818
1268
|
}
|
|
819
1269
|
|
|
820
1270
|
// version.ts
|
|
821
|
-
var packageversion = "1.1.
|
|
1271
|
+
var packageversion = "1.1.37";
|
|
822
1272
|
|
|
823
1273
|
// types.ts
|
|
824
1274
|
var protocolversion = packageversion;
|
|
@@ -859,6 +1309,11 @@ function parseproposal(value, origin) {
|
|
|
859
1309
|
const options = parseoptions(step);
|
|
860
1310
|
if (typeof options.stepid === "string" && !steps.some((candidate) => candidate.id === options.stepid)) throw new Error("A retry or frame wrapper references an unknown step id.");
|
|
861
1311
|
}
|
|
1312
|
+
for (const step of steps) {
|
|
1313
|
+
if (step.kind !== "submitform" && step.kind !== "retryform") continue;
|
|
1314
|
+
const review = submitreviewgranted(steps, step.id);
|
|
1315
|
+
if (!review.allowed) throw new Error(review.reason);
|
|
1316
|
+
}
|
|
862
1317
|
const createdat = Date.now();
|
|
863
1318
|
const expiresat = typeof planinput.expiresat === "number" ? planinput.expiresat : createdat + 10 * 60 * 1e3;
|
|
864
1319
|
const plan = {
|
|
@@ -916,14 +1371,34 @@ function trailreport(input) {
|
|
|
916
1371
|
function safetyresponse(input) {
|
|
917
1372
|
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, verdicts: input.verdicts });
|
|
918
1373
|
}
|
|
1374
|
+
function tabreportresponse(input) {
|
|
1375
|
+
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, report: input.report });
|
|
1376
|
+
}
|
|
1377
|
+
function layoutreport(input) {
|
|
1378
|
+
return { version: protocolversion, layouts: input.layouts };
|
|
1379
|
+
}
|
|
1380
|
+
function formreportresponse(input) {
|
|
1381
|
+
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, report: input.report });
|
|
1382
|
+
}
|
|
1383
|
+
function errorreportresponse(input) {
|
|
1384
|
+
return JSON.stringify({ version: protocolversion, planid: input.plan.id, planstate: input.plan.state, report: input.report });
|
|
1385
|
+
}
|
|
1386
|
+
function wizardreport(input) {
|
|
1387
|
+
return { version: protocolversion, ...input.sessionid ? { sessionid: input.sessionid } : {}, wizards: input.wizards, picks: input.picks };
|
|
1388
|
+
}
|
|
919
1389
|
export {
|
|
920
1390
|
canexecute,
|
|
921
1391
|
actionrisk as deriveactionrisk,
|
|
922
1392
|
diffresponse,
|
|
1393
|
+
errorreportresponse,
|
|
923
1394
|
eventresponse,
|
|
1395
|
+
formreportresponse,
|
|
1396
|
+
generatedvalueallowed,
|
|
924
1397
|
heldkeysreport,
|
|
925
1398
|
hostpattern,
|
|
1399
|
+
isformkind,
|
|
926
1400
|
iswatchkind,
|
|
1401
|
+
layoutreport,
|
|
927
1402
|
mapresponse,
|
|
928
1403
|
navstateresponse,
|
|
929
1404
|
normalizeendpoint,
|
|
@@ -931,6 +1406,8 @@ export {
|
|
|
931
1406
|
observationresponse,
|
|
932
1407
|
outcomeresponse,
|
|
933
1408
|
parseproposal,
|
|
1409
|
+
passwordconsentgranted,
|
|
1410
|
+
profilegrantgranted,
|
|
934
1411
|
protocolversion,
|
|
935
1412
|
randomid,
|
|
936
1413
|
requestbody,
|
|
@@ -939,8 +1416,14 @@ export {
|
|
|
939
1416
|
selectorresponse,
|
|
940
1417
|
sessionmemory,
|
|
941
1418
|
signalsreport,
|
|
1419
|
+
submitreviewgranted,
|
|
1420
|
+
tabreportresponse,
|
|
942
1421
|
trailreport,
|
|
1422
|
+
validatefieldmatch,
|
|
1423
|
+
validateformrecord,
|
|
943
1424
|
validatestep,
|
|
944
|
-
validatetargetref
|
|
1425
|
+
validatetargetref,
|
|
1426
|
+
validatevaluegen,
|
|
1427
|
+
wizardreport
|
|
945
1428
|
};
|
|
946
1429
|
//# sourceMappingURL=index.js.map
|