chainlesschain 0.166.65 → 0.166.69
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 +20 -12
- package/package.json +4 -4
- package/src/assets/web-panel/assets/{AIOps-Byz17CTN.js → AIOps-FhevRfL6.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C5LiW2-J.js → ActionButton-rOeOykx5.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D1INcvZF.js → Analytics-BK_wYlfz.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DZzHO1VV.js → AppLayout-_2cCtZKV.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-WfYQL6Ia.js → Artifacts-D5MSvVzk.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DohBoGWO.js → Audit-yd-Ah-A3.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Chtk-Hde.js → BackgroundAgents-yCaw_Gu_.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-B813PuMz.js → Backup-G3ADD4N-.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DaDdWWgK.js → BaseInput-ByDhkLbF.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D4pJ6oZ7.js → Chat-BMrc7qjz.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-nA7n0I6S.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Clo9TvO6.js → Checkbox-BHYgyZWA.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-uejLg8Ih.js → Codegen-DJfcy0jC.js} +1 -1
- package/src/assets/web-panel/assets/{Col-B7nbx-iJ.js → Col-C27zROxc.js} +1 -1
- package/src/assets/web-panel/assets/{Community-FEyjPK1j.js → Community-CuS5tq_1.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B6Fk0Kn6.js → Compact-BrYJNe7Q.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BQG8goUl.js → Compliance-8hfahYHT.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CbBeEfHp.js → Cowork-DdE0n2lp.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DPzlFcEZ.js → Cron-CUq3aSiX.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B8pWJrbg.js → Crosschain-BM4XSPWG.js} +1 -1
- package/src/assets/web-panel/assets/{DID-gGQHUlFN.js → DID-CdaBY57N.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-C2TMFHrn.js → Dashboard-Cwtd52So.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BVPxGbll.js → Dropdown-BvlObh6U.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CNPxs0hd.js → EmailListRenderer-e3fLhjnX.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-_XTiB7q1.js → EvolutionSettings-CTtk1Zo8.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-UyE3VWtI.js → FamilyGuardDashboard-BpPJUnCU.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CLt6FHK-.js → Federation-vzjZ6_nQ.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CdNQPRPw.js → FormItemContext-DEDNLhkE.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BJ0AMhrh.js → GenericCardRenderer-DEl2Te5f.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CQnvMfOM.js → Git-BzsYQnCq.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-deYsHC-o.js → Governance-zxJs6Y8s.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-qaSck43z.js → Inference-5JUsrmF1.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-De0aJ3Ls.js → KnowledgeGraph-Br8b5Htz.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-ZtS98jCm.js → Logs-D-tubDMJ.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-In4itZX2.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Byz3xCBN.js → Marketplace-s8MmWkS9.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DOZUUW6z.js → McpTools-Wu-WRg4M.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-C33wC2hA.js → Memory-B_i-eX9w.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-zZe-T_6M.js → MobileBridge-Ca64kjVx.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CRnUIume.js → MobileProjects-Cq9AFiO4.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-C1xlRVAN.js → Mtc-DKvGmG3y.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-D0U07bIi.js → MtcAudit-BVvWx8pF.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DF8uvV3h.js → Multisig-wqeJ2O9x.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-bBPGAFlt.js → NLProgramming-DX87ysYu.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BHAaOsgg.js → Notes-ChenGdu0.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-Cl0fG_rA.js → NotificationSettings-BZRa68-x.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BEPAs8Zv.js → OrderTableRenderer-DZ6xG1M6.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BAxSwgk5.js → Organization-BWJp4VPX.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-D68KubAu.js → Overflow-BoM4bYt5.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-bhdT17zk.js → P2P-Cvi8YV09.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DqaO6wgH.js → PdhVaultBrowser-CNVC1NIj.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-Bq8fvkak.js → Permissions-DNd1MRjW.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BYd2JEic.js → PersonalDataHub-DGSBYZ5-.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-Csg_ja69.js → Pipeline-DkcoGMBo.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-lwxwLj4M.js → Privacy-DltwvMAW.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BdBZkH8z.js → ProjectInit-ChYbpHg8.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-ClWgFy-K.js → ProjectSettings-B8FWiHTJ.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Bu-qj8N1.js → Projects-DuyhtSm4.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DEjxrxw3.js → Providers-Bo18Tx_6.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-eccy-8Vi.js → QrScannerModal-6W85KlsG.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Vx3uDvFg.js → QuickAsk-DznRUedP.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CfUivNps.js → Recommend-CQDN3_p-.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BU4gk7GI.js → RemoteSession-CiJgokEj.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-CbPzdZ0C.js → Reputation-DexzGH7E.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CYLrgfKA.js → Row-BgZOIvSi.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DbY1oyuv.js → RssFeed-BWIZJ_Jr.js} +3 -3
- package/src/assets/web-panel/assets/{Search-QeW41K5r.js → Search-B376EwWJ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CJxf1kLZ.js → Security-92mUR5OD.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CFO9ySZc.js → Services-ClSEAOHk.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CQFjeQN0.js → Skeleton-DVhLbv99.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CLLB4INW.js → Skills-JTcXs_xI.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DxeLIJk0.js → Sla-DnKY9zy9.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-D4FA9KYI.js → SpeechSettings-GO1JefAH.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-C6NOkcQK.js → SyncSettings-jX5tB2St.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-LmVPWDfQ.js → Tasks-BxRBzhUc.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BdEfUoVB.js → Templates-CAVkbTG1.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-IUlESacN.js → Tenant-5Y7sHBkz.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B9pDe7sn.js → Terminal-CbbLShYb.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-ZCwB-Pki.js → TimelineRenderer-2HptWihL.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-4qk16LX1.js → Tokens-B-jGxzHl.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-jXNyargn.js → Trigger-9DGa90DT.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-D13PydtT.js → Trust-BSJEkEOO.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-yPgws6mS.js → UkeySign-C807So5R.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B329WjpG.js → VideoEditing-ByiieAv-.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-T8VM-Ttm.js → Wallet-BixbIOUv.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-XuRibrpP.js → WebAuthn-z7akhor4.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-D1Gwz3YR.js → WorkflowEditor-KvijuUuR.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DjydtnT-.js → chat-BYKoh0YG.js} +1 -1
- package/src/assets/web-panel/assets/{colors-gFtBvPrr.js → colors-CLT8IYBt.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CndxhGfx.js → compact-item-DlBIyYHF.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DnfGpd0L.js → createContext-5XmAnNLr.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BmcCIHwY.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CmT5hRVW.js → hasIn-rPdRhm7K.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoBKSzqu.js → index-8un-eUDI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGbKeg8G.js → index-B-0nAxf5.js} +1 -1
- package/src/assets/web-panel/assets/{index-DreYqebI.js → index-B1VfBUPB.js} +1 -1
- package/src/assets/web-panel/assets/{index-zQf599Uq.js → index-BBt2CSAx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlTcxT_L.js → index-BDtlwjSr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqpR0Des.js → index-BIRl2Ii5.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3HvYeA3.js → index-BgevTkUv.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0WFjxWs.js → index-Bve7Wsgf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNHdO6Jr.js → index-Bzd0sFkp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DV2PR3Fa.js → index-C2sFDVb_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2d7358Y.js → index-CErvHCDe.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaEPE2DC.js → index-CM_a9spK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKyuE_Y2.js → index-CY6TMc2m.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVM_w30N.js → index-ChlzaTV3.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZLDbPTa.js → index-CsnbOKdI.js} +1 -1
- package/src/assets/web-panel/assets/{index-HHP1zzo7.js → index-D3-NL-x-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFif4Cev.js → index-D3f9Jzx2.js} +1 -1
- package/src/assets/web-panel/assets/{index-C14jryXi.js → index-DCDSycWo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CB27echm.js → index-DIVrVGvf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGlmPbl_.js → index-DI_tYFBe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsRKmb6k.js → index-DPS4mWnI.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXNUTiW8.js → index-DTslLzPJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbpk75MO.js → index-DW8vozBS.js} +1 -1
- package/src/assets/web-panel/assets/index-DY8rmd6x.js +1 -0
- package/src/assets/web-panel/assets/{index-DjY-3sMA.js → index-DZiSMYoD.js} +3 -3
- package/src/assets/web-panel/assets/{index-DV6NrfJx.js → index-DZjGcIGU.js} +1 -1
- package/src/assets/web-panel/assets/{index-ktN-K1Tf.js → index-Dea32nOK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjcR-CwS.js → index-Djd7uqwM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CuOx4Pbe.js → index-Dntid6oj.js} +1 -1
- package/src/assets/web-panel/assets/{index-BW3nWiu0.js → index-DqZU4_7J.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4Mqhmas.js → index-DuvweiCz.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRqz8TtI.js → index-DzExCCLS.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5na0B7G.js → index-LKT-Ol0A.js} +1 -1
- package/src/assets/web-panel/assets/{index-_-wGLtAg.js → index-akwXS-FF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgMKElUh.js → index-b-rQCMkx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUlubR4l.js → index-eHbr3f5I.js} +1 -1
- package/src/assets/web-panel/assets/{index-D88-8bsB.js → index-kx6zDWew.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuAvYTmY.js → index-rRuCGdKW.js} +1 -1
- package/src/assets/web-panel/assets/index-sbwcUeRS.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-KV3V-PNH.js → initDefaultProps-a8411LiK.js} +1 -1
- package/src/assets/web-panel/assets/{motion-PFGQg7_X.js → motion-oVcQdpCm.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dnl79wq4.js → move-B-eyzzzL.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-Bwl5JH9V.js → mtc-parser-BCYIxuG7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DCcTtM1l.js → omit-DuFtWiYh.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Cl6BjjDf.js → pickAttrs-CVAoJhGu.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-fdqhyo42.js → placementArrow-Y2iub2bO.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DYQpmcDW.js → responsiveObserve-BHenWIVD.js} +1 -1
- package/src/assets/web-panel/assets/{slide-C4l-VfO4.js → slide-CKrMaL29.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DYDw_dyZ.js → statusUtils-w8eb_1da.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BEsubSMu.js → styleChecker-CCVi_Ww3.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Cj82ggQ_.js → useFlexGapSupport-BsmR_q0r.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-B7L1eJ0V.js → useFs-a8GMBjnc.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DVlJVD4d.js → usePersonalDataHub-BMUYSPn-.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BBAbRN_Y.js → vnode-DL2pI31V.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BYn48q-I.js → zoom-Cbi8fISi.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/data/changelog.json +33 -7
- package/src/lib/dependency-install-policy.js +1 -1
- package/src/lib/evolution/browser-download-action-authority.js +747 -0
- package/src/lib/evolution/browser-download-artifact-disposal-authority.js +436 -0
- package/src/lib/evolution/browser-filesystem-quarantine-custody.js +2453 -0
- package/src/lib/evolution/browser-filesystem-quarantine-disposal.js +36 -0
- package/src/lib/evolution/browser-keyboard-action-authority.js +560 -0
- package/src/lib/evolution/browser-navigation-action-authority.js +546 -0
- package/src/lib/evolution/browser-quarantine-lock-maintenance-authority.js +573 -0
- package/src/lib/evolution/browser-quarantine-operator-revocation-authority.js +442 -0
- package/src/lib/evolution/browser-quarantine-retention-authority.js +503 -0
- package/src/lib/evolution/browser-quarantine-retention-scheduler.js +207 -0
- package/src/lib/evolution/browser-quarantined-download-executor.js +525 -0
- package/src/lib/evolution/browser-tab-open-action-authority.js +491 -0
- package/src/lib/evolution/browser-vision-action-authority.js +444 -0
- package/src/lib/evolution/browser-vision-observation-authority.js +304 -0
- package/src/lib/evolution/evolution-deployment-loader.js +241 -1
- package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +5 -0
- package/src/lib/evolution/evolution-eval-gate.js +2 -1
- package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +71 -9
- package/src/lib/evolution/evolution-eval-process-supervisor.js +276 -9
- package/src/lib/evolution/evolution-workbench-metrics.js +81 -21
- package/src/lib/evolution/pm-exploration-benchmark.js +747 -0
- package/src/lib/evolution/pm-exploration-budget-executor.js +106 -9
- package/src/lib/evolution/pm-exploration-egress-authority.js +382 -0
- package/src/lib/evolution/pm-exploration-evidence-bundle.js +149 -44
- package/src/lib/evolution/pm-exploration-execution-host.js +1254 -8
- package/src/lib/evolution/pm-exploration-process-grader.js +458 -0
- package/src/lib/evolution/pm-exploration-process-reviewer.js +456 -0
- package/src/lib/evolution/pm-exploration-process-runner.js +500 -0
- package/src/lib/evolution/pm-exploration-receipts.js +211 -11
- package/src/lib/evolution/pm-exploration-recovery-snapshot-store.js +465 -46
- package/src/lib/evolution/pm-exploration-transition-committer.js +185 -34
- package/src/lib/evolution/skill-outcome-index-authority.js +7 -3
- package/src/lib/evolution/skill-writer-inventory-manifest.js +0 -39
- package/src/lib/evolution/volcengine-function-execution-authority.js +2949 -0
- package/src/lib/evolution/volcengine-function-process-executor.js +615 -0
- package/src/lib/evolution/volcengine-function-replay-store.js +836 -0
- package/src/lib/evolution/volcengine-function-revocation-status-floor-store.js +480 -0
- package/src/lib/governance-coverage.js +1 -1
- package/src/lib/headless-manifest.js +1 -1
- package/src/lib/protocol-replay.js +1 -1
- package/src/lib/skill-outcome-transcript-authority.js +45 -5
- package/src/runtime/agent-core.js +17 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-Cf3LLgDc.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-CTsYo9NN.js +0 -1
- package/src/assets/web-panel/assets/devWarning-D60SbiD-.js +0 -1
- package/src/assets/web-panel/assets/index-C0yR4_7h.js +0 -1
- package/src/assets/web-panel/assets/index-D4xuvo03.js +0 -1
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { types } from "node:util";
|
|
3
|
+
|
|
4
|
+
export const BROWSER_TAB_OPEN_ACTION_AUTHORITY_DESCRIPTOR_SCHEMA =
|
|
5
|
+
"chainlesschain.browser-tab-open-action-authority-descriptor/v1";
|
|
6
|
+
export const BROWSER_TAB_OPEN_ACTION_REQUEST_SCHEMA =
|
|
7
|
+
"chainlesschain.browser-tab-open-action-request/v1";
|
|
8
|
+
export const BROWSER_TAB_OPEN_ACTION_RECEIPT_SCHEMA =
|
|
9
|
+
"chainlesschain.browser-tab-open-action-receipt/v1";
|
|
10
|
+
export const BROWSER_TAB_OPEN_ACTION_OUTCOME_REQUEST_SCHEMA =
|
|
11
|
+
"chainlesschain.browser-tab-open-action-outcome-request/v1";
|
|
12
|
+
export const BROWSER_TAB_OPEN_ACTION_OUTCOME_ACK_SCHEMA =
|
|
13
|
+
"chainlesschain.browser-tab-open-action-outcome-ack/v1";
|
|
14
|
+
|
|
15
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
16
|
+
const ID = /^[A-Za-z0-9._:-]{1,128}$/u;
|
|
17
|
+
const PROFILE = /^[A-Za-z0-9._-]{1,128}$/u;
|
|
18
|
+
const WAIT_UNTIL = new Set(["load", "domcontentloaded", "networkidle"]);
|
|
19
|
+
const authorities = new WeakMap();
|
|
20
|
+
|
|
21
|
+
function canonical(value) {
|
|
22
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
23
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
24
|
+
return `{${Object.keys(value)
|
|
25
|
+
.sort()
|
|
26
|
+
.map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
|
|
27
|
+
.join(",")}}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function digest(domain, value) {
|
|
31
|
+
return `sha256:${createHash("sha256")
|
|
32
|
+
.update(`${domain}\0`)
|
|
33
|
+
.update(canonical(value))
|
|
34
|
+
.digest("hex")}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function exact(value, keys, label) {
|
|
38
|
+
if (
|
|
39
|
+
!value ||
|
|
40
|
+
typeof value !== "object" ||
|
|
41
|
+
Array.isArray(value) ||
|
|
42
|
+
types.isProxy(value) ||
|
|
43
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
|
|
44
|
+
Reflect.ownKeys(value).length !== keys.length ||
|
|
45
|
+
keys.some((key) => {
|
|
46
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
47
|
+
return !descriptor?.enumerable || !("value" in descriptor);
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
throw new TypeError(`${label} has an invalid shape`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function snapshotJson(value, label) {
|
|
54
|
+
let nodes = 0;
|
|
55
|
+
const visit = (entry, depth) => {
|
|
56
|
+
if (++nodes > 2048 || depth > 12)
|
|
57
|
+
throw new TypeError(`${label} exceeds its structure budget`);
|
|
58
|
+
if (
|
|
59
|
+
entry === null ||
|
|
60
|
+
typeof entry === "boolean" ||
|
|
61
|
+
(typeof entry === "number" && Number.isFinite(entry)) ||
|
|
62
|
+
typeof entry === "string"
|
|
63
|
+
)
|
|
64
|
+
return entry;
|
|
65
|
+
if (
|
|
66
|
+
!entry ||
|
|
67
|
+
typeof entry !== "object" ||
|
|
68
|
+
types.isProxy(entry) ||
|
|
69
|
+
![Object.prototype, null, Array.prototype].includes(
|
|
70
|
+
Object.getPrototypeOf(entry),
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
throw new TypeError(`${label} must be finite plain JSON data`);
|
|
74
|
+
if (Array.isArray(entry))
|
|
75
|
+
return Object.freeze(entry.map((item) => visit(item, depth + 1)));
|
|
76
|
+
const output = {};
|
|
77
|
+
for (const key of Object.keys(entry)) {
|
|
78
|
+
const descriptor = Object.getOwnPropertyDescriptor(entry, key);
|
|
79
|
+
if (!descriptor?.enumerable || !("value" in descriptor))
|
|
80
|
+
throw new TypeError(`${label} must contain plain data`);
|
|
81
|
+
output[key] = visit(descriptor.value, depth + 1);
|
|
82
|
+
}
|
|
83
|
+
return Object.freeze(output);
|
|
84
|
+
};
|
|
85
|
+
const result = visit(value, 0);
|
|
86
|
+
if (Buffer.byteLength(canonical(result), "utf8") > 16 * 1024)
|
|
87
|
+
throw new TypeError(`${label} exceeds its byte budget`);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function normalizeUrl(value) {
|
|
92
|
+
if (typeof value !== "string" || value.length < 1 || value.length > 16 * 1024)
|
|
93
|
+
throw new TypeError("browser tab open destination is invalid");
|
|
94
|
+
let parsed;
|
|
95
|
+
try {
|
|
96
|
+
parsed = new URL(value);
|
|
97
|
+
} catch {
|
|
98
|
+
throw new TypeError("browser tab open destination is invalid");
|
|
99
|
+
}
|
|
100
|
+
if (
|
|
101
|
+
!["http:", "https:"].includes(parsed.protocol) ||
|
|
102
|
+
parsed.username !== "" ||
|
|
103
|
+
parsed.password !== "" ||
|
|
104
|
+
parsed.href.length > 16 * 1024
|
|
105
|
+
)
|
|
106
|
+
throw new TypeError("browser tab open destination is invalid");
|
|
107
|
+
return parsed.href;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function normalizeRedirectOrigins(value, destinationUrl) {
|
|
111
|
+
if (
|
|
112
|
+
!Array.isArray(value) ||
|
|
113
|
+
types.isProxy(value) ||
|
|
114
|
+
value.length < 1 ||
|
|
115
|
+
value.length > 16
|
|
116
|
+
)
|
|
117
|
+
throw new TypeError("browser tab open redirect origins are invalid");
|
|
118
|
+
const origins = value.map((entry) => {
|
|
119
|
+
if (typeof entry !== "string" || entry.length > 2048)
|
|
120
|
+
throw new TypeError("browser tab open redirect origins are invalid");
|
|
121
|
+
let parsed;
|
|
122
|
+
try {
|
|
123
|
+
parsed = new URL(entry);
|
|
124
|
+
} catch {
|
|
125
|
+
throw new TypeError("browser tab open redirect origins are invalid");
|
|
126
|
+
}
|
|
127
|
+
if (
|
|
128
|
+
!["http:", "https:"].includes(parsed.protocol) ||
|
|
129
|
+
parsed.username !== "" ||
|
|
130
|
+
parsed.password !== "" ||
|
|
131
|
+
entry !== parsed.origin
|
|
132
|
+
)
|
|
133
|
+
throw new TypeError("browser tab open redirect origins are invalid");
|
|
134
|
+
return parsed.origin;
|
|
135
|
+
});
|
|
136
|
+
const normalized = [...new Set(origins)].sort();
|
|
137
|
+
if (
|
|
138
|
+
normalized.length !== origins.length ||
|
|
139
|
+
!normalized.includes(new URL(destinationUrl).origin)
|
|
140
|
+
)
|
|
141
|
+
throw new TypeError("browser tab open redirect origins are invalid");
|
|
142
|
+
return Object.freeze(normalized);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function normalizeDescriptor(value) {
|
|
146
|
+
exact(
|
|
147
|
+
value,
|
|
148
|
+
[
|
|
149
|
+
"schema",
|
|
150
|
+
"authorityId",
|
|
151
|
+
"tenantId",
|
|
152
|
+
"handlerArtifactDigest",
|
|
153
|
+
"policyRevision",
|
|
154
|
+
"maxGrantTtlMs",
|
|
155
|
+
"approvalMode",
|
|
156
|
+
"auditMode",
|
|
157
|
+
],
|
|
158
|
+
"browser tab open authority descriptor",
|
|
159
|
+
);
|
|
160
|
+
if (
|
|
161
|
+
value.schema !== BROWSER_TAB_OPEN_ACTION_AUTHORITY_DESCRIPTOR_SCHEMA ||
|
|
162
|
+
!ID.test(value.authorityId) ||
|
|
163
|
+
!ID.test(value.tenantId) ||
|
|
164
|
+
!DIGEST.test(value.handlerArtifactDigest) ||
|
|
165
|
+
!ID.test(value.policyRevision) ||
|
|
166
|
+
!Number.isSafeInteger(value.maxGrantTtlMs) ||
|
|
167
|
+
value.maxGrantTtlMs < 1 ||
|
|
168
|
+
value.maxGrantTtlMs > 30_000 ||
|
|
169
|
+
value.approvalMode !== "interactive" ||
|
|
170
|
+
value.auditMode !== "authenticated-durable-readback"
|
|
171
|
+
)
|
|
172
|
+
throw new TypeError("browser tab open authority descriptor is invalid");
|
|
173
|
+
return Object.freeze({ ...value });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function normalizeRequest(value) {
|
|
177
|
+
exact(
|
|
178
|
+
value,
|
|
179
|
+
[
|
|
180
|
+
"schema",
|
|
181
|
+
"requestId",
|
|
182
|
+
"profileName",
|
|
183
|
+
"operation",
|
|
184
|
+
"senderId",
|
|
185
|
+
"frameUrlDigest",
|
|
186
|
+
"destinationUrl",
|
|
187
|
+
"allowedRedirectOrigins",
|
|
188
|
+
"waitUntil",
|
|
189
|
+
"timeout",
|
|
190
|
+
"inputDigest",
|
|
191
|
+
"authorization",
|
|
192
|
+
"requestedAt",
|
|
193
|
+
],
|
|
194
|
+
"browser tab open request",
|
|
195
|
+
);
|
|
196
|
+
const destinationUrl = normalizeUrl(value.destinationUrl);
|
|
197
|
+
const allowedRedirectOrigins = normalizeRedirectOrigins(
|
|
198
|
+
value.allowedRedirectOrigins,
|
|
199
|
+
destinationUrl,
|
|
200
|
+
);
|
|
201
|
+
const inputCore = Object.freeze({
|
|
202
|
+
profileName: value.profileName,
|
|
203
|
+
operation: value.operation,
|
|
204
|
+
destinationUrl,
|
|
205
|
+
allowedRedirectOrigins,
|
|
206
|
+
waitUntil: value.waitUntil,
|
|
207
|
+
timeout: value.timeout,
|
|
208
|
+
});
|
|
209
|
+
if (
|
|
210
|
+
value.schema !== BROWSER_TAB_OPEN_ACTION_REQUEST_SCHEMA ||
|
|
211
|
+
!ID.test(value.requestId) ||
|
|
212
|
+
typeof value.profileName !== "string" ||
|
|
213
|
+
!PROFILE.test(value.profileName) ||
|
|
214
|
+
value.operation !== "open-tab" ||
|
|
215
|
+
!Number.isSafeInteger(value.senderId) ||
|
|
216
|
+
value.senderId < 1 ||
|
|
217
|
+
!DIGEST.test(value.frameUrlDigest) ||
|
|
218
|
+
!WAIT_UNTIL.has(value.waitUntil) ||
|
|
219
|
+
!Number.isSafeInteger(value.timeout) ||
|
|
220
|
+
value.timeout < 1 ||
|
|
221
|
+
value.timeout > 120_000 ||
|
|
222
|
+
value.inputDigest !==
|
|
223
|
+
digest("chainlesschain.browser-tab-open-action-input/v1", inputCore) ||
|
|
224
|
+
!Number.isFinite(Date.parse(value.requestedAt))
|
|
225
|
+
)
|
|
226
|
+
throw new TypeError("browser tab open request is invalid");
|
|
227
|
+
return Object.freeze({
|
|
228
|
+
...value,
|
|
229
|
+
destinationUrl,
|
|
230
|
+
allowedRedirectOrigins,
|
|
231
|
+
authorization: snapshotJson(
|
|
232
|
+
value.authorization,
|
|
233
|
+
"browser tab open authorization",
|
|
234
|
+
),
|
|
235
|
+
inputCore,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function requestEvidence(request) {
|
|
240
|
+
const core = {
|
|
241
|
+
schema: request.schema,
|
|
242
|
+
requestId: request.requestId,
|
|
243
|
+
profileName: request.profileName,
|
|
244
|
+
operation: request.operation,
|
|
245
|
+
senderId: request.senderId,
|
|
246
|
+
frameUrlDigest: request.frameUrlDigest,
|
|
247
|
+
destinationDigest: digest(
|
|
248
|
+
"chainlesschain.browser-tab-open-action-destination/v1",
|
|
249
|
+
request.destinationUrl,
|
|
250
|
+
),
|
|
251
|
+
redirectOriginsDigest: digest(
|
|
252
|
+
"chainlesschain.browser-tab-open-action-redirect-origins/v1",
|
|
253
|
+
request.allowedRedirectOrigins,
|
|
254
|
+
),
|
|
255
|
+
waitUntil: request.waitUntil,
|
|
256
|
+
timeout: request.timeout,
|
|
257
|
+
inputDigest: request.inputDigest,
|
|
258
|
+
authorizationDigest: digest(
|
|
259
|
+
"chainlesschain.browser-tab-open-action-authorization/v1",
|
|
260
|
+
request.authorization,
|
|
261
|
+
),
|
|
262
|
+
requestedAt: request.requestedAt,
|
|
263
|
+
};
|
|
264
|
+
return Object.freeze({
|
|
265
|
+
...core,
|
|
266
|
+
requestDigest: digest(BROWSER_TAB_OPEN_ACTION_REQUEST_SCHEMA, core),
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function normalizeDecision(value) {
|
|
271
|
+
if (!value || typeof value !== "object" || types.isProxy(value))
|
|
272
|
+
throw new TypeError("browser tab open decision is invalid");
|
|
273
|
+
if (value.decision === "deny") {
|
|
274
|
+
exact(
|
|
275
|
+
value,
|
|
276
|
+
Object.hasOwn(value, "reason") ? ["decision", "reason"] : ["decision"],
|
|
277
|
+
"browser tab open decision",
|
|
278
|
+
);
|
|
279
|
+
if (
|
|
280
|
+
value.reason !== undefined &&
|
|
281
|
+
(typeof value.reason !== "string" || value.reason.length > 512)
|
|
282
|
+
)
|
|
283
|
+
throw new TypeError("browser tab open denial reason is invalid");
|
|
284
|
+
return Object.freeze({ decision: "deny", reason: value.reason ?? null });
|
|
285
|
+
}
|
|
286
|
+
exact(
|
|
287
|
+
value,
|
|
288
|
+
["decision", "approvalEvidenceRef", "validUntil"],
|
|
289
|
+
"browser tab open decision",
|
|
290
|
+
);
|
|
291
|
+
if (value.decision !== "allow")
|
|
292
|
+
throw new TypeError("browser tab open decision is invalid");
|
|
293
|
+
return Object.freeze({ ...value });
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function normalizeOutcome(value) {
|
|
297
|
+
exact(
|
|
298
|
+
value,
|
|
299
|
+
[
|
|
300
|
+
"schema",
|
|
301
|
+
"actionReceiptDigest",
|
|
302
|
+
"requestDigest",
|
|
303
|
+
"profileName",
|
|
304
|
+
"operation",
|
|
305
|
+
"inputDigest",
|
|
306
|
+
"status",
|
|
307
|
+
"resultDigest",
|
|
308
|
+
"recordedAt",
|
|
309
|
+
],
|
|
310
|
+
"browser tab open outcome request",
|
|
311
|
+
);
|
|
312
|
+
if (
|
|
313
|
+
value.schema !== BROWSER_TAB_OPEN_ACTION_OUTCOME_REQUEST_SCHEMA ||
|
|
314
|
+
!DIGEST.test(value.actionReceiptDigest) ||
|
|
315
|
+
!DIGEST.test(value.requestDigest) ||
|
|
316
|
+
typeof value.profileName !== "string" ||
|
|
317
|
+
!PROFILE.test(value.profileName) ||
|
|
318
|
+
value.operation !== "open-tab" ||
|
|
319
|
+
!DIGEST.test(value.inputDigest) ||
|
|
320
|
+
!["succeeded", "failed"].includes(value.status) ||
|
|
321
|
+
!DIGEST.test(value.resultDigest) ||
|
|
322
|
+
!Number.isFinite(Date.parse(value.recordedAt))
|
|
323
|
+
)
|
|
324
|
+
throw new TypeError("browser tab open outcome request is invalid");
|
|
325
|
+
const core = Object.freeze({ ...value });
|
|
326
|
+
return Object.freeze({
|
|
327
|
+
...core,
|
|
328
|
+
outcomeRequestDigest: digest(
|
|
329
|
+
BROWSER_TAB_OPEN_ACTION_OUTCOME_REQUEST_SCHEMA,
|
|
330
|
+
core,
|
|
331
|
+
),
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function normalizeAck(value, descriptor, request) {
|
|
336
|
+
exact(
|
|
337
|
+
value,
|
|
338
|
+
[
|
|
339
|
+
"schema",
|
|
340
|
+
"authorityId",
|
|
341
|
+
"tenantId",
|
|
342
|
+
"handlerArtifactDigest",
|
|
343
|
+
"actionReceiptDigest",
|
|
344
|
+
"outcomeRequestDigest",
|
|
345
|
+
"auditEventDigest",
|
|
346
|
+
"durabilityReceiptDigest",
|
|
347
|
+
"authenticated",
|
|
348
|
+
"durable",
|
|
349
|
+
"readbackVerified",
|
|
350
|
+
"qualifiesForPromotion",
|
|
351
|
+
],
|
|
352
|
+
"browser tab open outcome acknowledgement",
|
|
353
|
+
);
|
|
354
|
+
if (
|
|
355
|
+
value.schema !== BROWSER_TAB_OPEN_ACTION_OUTCOME_ACK_SCHEMA ||
|
|
356
|
+
value.authorityId !== descriptor.authorityId ||
|
|
357
|
+
value.tenantId !== descriptor.tenantId ||
|
|
358
|
+
value.handlerArtifactDigest !== descriptor.handlerArtifactDigest ||
|
|
359
|
+
value.actionReceiptDigest !== request.actionReceiptDigest ||
|
|
360
|
+
value.outcomeRequestDigest !== request.outcomeRequestDigest ||
|
|
361
|
+
!DIGEST.test(value.auditEventDigest) ||
|
|
362
|
+
!DIGEST.test(value.durabilityReceiptDigest) ||
|
|
363
|
+
value.authenticated !== true ||
|
|
364
|
+
value.durable !== true ||
|
|
365
|
+
value.readbackVerified !== true ||
|
|
366
|
+
value.qualifiesForPromotion !== false
|
|
367
|
+
)
|
|
368
|
+
throw new Error("browser tab open acknowledgement is invalid");
|
|
369
|
+
return Object.freeze({ ...value });
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export function createBrowserTabOpenActionAuthority({
|
|
373
|
+
descriptor,
|
|
374
|
+
authorize,
|
|
375
|
+
recordOutcome,
|
|
376
|
+
now = Date.now,
|
|
377
|
+
} = {}) {
|
|
378
|
+
const normalizedDescriptor = normalizeDescriptor(descriptor);
|
|
379
|
+
if (
|
|
380
|
+
typeof authorize !== "function" ||
|
|
381
|
+
types.isProxy(authorize) ||
|
|
382
|
+
typeof recordOutcome !== "function" ||
|
|
383
|
+
types.isProxy(recordOutcome) ||
|
|
384
|
+
typeof now !== "function" ||
|
|
385
|
+
types.isProxy(now)
|
|
386
|
+
)
|
|
387
|
+
throw new TypeError("browser tab open authority ports are invalid");
|
|
388
|
+
const authority = Object.freeze({});
|
|
389
|
+
authorities.set(authority, {
|
|
390
|
+
descriptor: normalizedDescriptor,
|
|
391
|
+
authorize,
|
|
392
|
+
recordOutcome,
|
|
393
|
+
now,
|
|
394
|
+
issued: new Map(),
|
|
395
|
+
});
|
|
396
|
+
return authority;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export function captureBrowserTabOpenActionAuthority(value) {
|
|
400
|
+
const captured = authorities.get(value);
|
|
401
|
+
if (!captured)
|
|
402
|
+
throw new TypeError("A branded browser tab open authority is required");
|
|
403
|
+
return Object.freeze({
|
|
404
|
+
descriptor: captured.descriptor,
|
|
405
|
+
authorizeAction: async (input) => {
|
|
406
|
+
const request = normalizeRequest(input);
|
|
407
|
+
const evidence = requestEvidence(request);
|
|
408
|
+
const decision = normalizeDecision(
|
|
409
|
+
await captured.authorize(
|
|
410
|
+
Object.freeze({ ...request, requestDigest: evidence.requestDigest }),
|
|
411
|
+
),
|
|
412
|
+
);
|
|
413
|
+
if (decision.decision !== "allow") {
|
|
414
|
+
const error = new Error(
|
|
415
|
+
decision.reason ?? "Browser tab open was denied",
|
|
416
|
+
);
|
|
417
|
+
error.code = "BROWSER_TAB_OPEN_ACTION_DENIED";
|
|
418
|
+
throw error;
|
|
419
|
+
}
|
|
420
|
+
const nowMs = captured.now();
|
|
421
|
+
const validUntilMs = Date.parse(decision.validUntil);
|
|
422
|
+
if (
|
|
423
|
+
typeof decision.approvalEvidenceRef !== "string" ||
|
|
424
|
+
decision.approvalEvidenceRef.length < 1 ||
|
|
425
|
+
decision.approvalEvidenceRef.length > 512 ||
|
|
426
|
+
!Number.isFinite(nowMs) ||
|
|
427
|
+
!Number.isFinite(validUntilMs) ||
|
|
428
|
+
validUntilMs <= nowMs ||
|
|
429
|
+
validUntilMs > nowMs + captured.descriptor.maxGrantTtlMs
|
|
430
|
+
)
|
|
431
|
+
throw new Error("Browser tab open decision is invalid");
|
|
432
|
+
const core = {
|
|
433
|
+
schema: BROWSER_TAB_OPEN_ACTION_RECEIPT_SCHEMA,
|
|
434
|
+
authorityId: captured.descriptor.authorityId,
|
|
435
|
+
tenantId: captured.descriptor.tenantId,
|
|
436
|
+
policyRevision: captured.descriptor.policyRevision,
|
|
437
|
+
handlerArtifactDigest: captured.descriptor.handlerArtifactDigest,
|
|
438
|
+
approvalMode: captured.descriptor.approvalMode,
|
|
439
|
+
requestId: request.requestId,
|
|
440
|
+
profileName: request.profileName,
|
|
441
|
+
operation: request.operation,
|
|
442
|
+
senderId: request.senderId,
|
|
443
|
+
frameUrlDigest: request.frameUrlDigest,
|
|
444
|
+
destinationDigest: evidence.destinationDigest,
|
|
445
|
+
redirectOriginsDigest: evidence.redirectOriginsDigest,
|
|
446
|
+
waitUntil: request.waitUntil,
|
|
447
|
+
timeout: request.timeout,
|
|
448
|
+
inputDigest: request.inputDigest,
|
|
449
|
+
authorizationDigest: evidence.authorizationDigest,
|
|
450
|
+
requestDigest: evidence.requestDigest,
|
|
451
|
+
approvalEvidenceRef: decision.approvalEvidenceRef,
|
|
452
|
+
authorizedAt: new Date(nowMs).toISOString(),
|
|
453
|
+
validUntil: new Date(validUntilMs).toISOString(),
|
|
454
|
+
};
|
|
455
|
+
const receipt = Object.freeze({
|
|
456
|
+
...core,
|
|
457
|
+
receiptDigest: digest(BROWSER_TAB_OPEN_ACTION_RECEIPT_SCHEMA, core),
|
|
458
|
+
});
|
|
459
|
+
captured.issued.set(receipt.receiptDigest, {
|
|
460
|
+
requestDigest: receipt.requestDigest,
|
|
461
|
+
profileName: receipt.profileName,
|
|
462
|
+
operation: receipt.operation,
|
|
463
|
+
inputDigest: receipt.inputDigest,
|
|
464
|
+
outcomeRequestDigest: null,
|
|
465
|
+
});
|
|
466
|
+
return receipt;
|
|
467
|
+
},
|
|
468
|
+
recordActionOutcome: async (input) => {
|
|
469
|
+
const request = normalizeOutcome(input);
|
|
470
|
+
const issued = captured.issued.get(request.actionReceiptDigest);
|
|
471
|
+
if (
|
|
472
|
+
!issued ||
|
|
473
|
+
issued.requestDigest !== request.requestDigest ||
|
|
474
|
+
issued.profileName !== request.profileName ||
|
|
475
|
+
issued.operation !== request.operation ||
|
|
476
|
+
issued.inputDigest !== request.inputDigest ||
|
|
477
|
+
(issued.outcomeRequestDigest !== null &&
|
|
478
|
+
issued.outcomeRequestDigest !== request.outcomeRequestDigest)
|
|
479
|
+
)
|
|
480
|
+
throw new Error("browser tab open outcome differs from authorization");
|
|
481
|
+
issued.outcomeRequestDigest = request.outcomeRequestDigest;
|
|
482
|
+
const acknowledgement = normalizeAck(
|
|
483
|
+
await captured.recordOutcome(request),
|
|
484
|
+
captured.descriptor,
|
|
485
|
+
request,
|
|
486
|
+
);
|
|
487
|
+
captured.issued.delete(request.actionReceiptDigest);
|
|
488
|
+
return acknowledgement;
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
}
|