@orangecheck/agent-core 1.2.0 → 2.1.0
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/dist/canonical.js.map +1 -1
- package/dist/canonical.mjs.map +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +38 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +38 -2
- package/dist/index.mjs.map +1 -1
- package/dist/scope.js +7 -2
- package/dist/scope.js.map +1 -1
- package/dist/scope.mjs +7 -2
- package/dist/scope.mjs.map +1 -1
- package/package.json +4 -4
- package/src/federation.test.ts +1 -0
- package/src/private-scope.test.ts +4 -3
- package/src/revocation-failclosed.test.ts +78 -0
- package/src/scope.test.ts +44 -0
- package/src/scope.ts +17 -2
- package/src/test-vectors.test.ts +5 -0
- package/src/verify.ts +56 -6
package/dist/index.mjs
CHANGED
|
@@ -223,10 +223,15 @@ function rangeSubset(ex, g) {
|
|
|
223
223
|
if (!exRange || !gRange) return false;
|
|
224
224
|
return gRange.lo <= exRange.lo && exRange.hi <= gRange.hi;
|
|
225
225
|
}
|
|
226
|
+
function parseDecimalInteger(value) {
|
|
227
|
+
if (!/^-?\d+$/.test(value)) return null;
|
|
228
|
+
const n = Number(value);
|
|
229
|
+
return Number.isSafeInteger(n) ? n : null;
|
|
230
|
+
}
|
|
226
231
|
function opToRange(c) {
|
|
227
232
|
if (c.value === void 0) return null;
|
|
228
|
-
const n =
|
|
229
|
-
if (
|
|
233
|
+
const n = parseDecimalInteger(c.value);
|
|
234
|
+
if (n === null) return null;
|
|
230
235
|
switch (c.op) {
|
|
231
236
|
case "=":
|
|
232
237
|
return { lo: n, hi: n };
|
|
@@ -496,6 +501,25 @@ async function verifyDelegation(input) {
|
|
|
496
501
|
const ok = await input.verifyBip322(env.id, env.sig.value, env.principal.address);
|
|
497
502
|
if (!ok) return err("E_BAD_SIG", "BIP-322 signature did not verify");
|
|
498
503
|
}
|
|
504
|
+
if (!input.skipRevocationCheck && !input.revocations) {
|
|
505
|
+
return err(
|
|
506
|
+
"E_MALFORMED",
|
|
507
|
+
"verifyDelegation requires `revocations` (fetch kind-30085 by #delegation) or an explicit skipRevocationCheck:true to state that revocation is not being checked"
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
if (input.revocations) {
|
|
511
|
+
for (const rev of input.revocations) {
|
|
512
|
+
if (rev.delegation_id !== env.id) continue;
|
|
513
|
+
const rr = await verifyRevocation({
|
|
514
|
+
envelope: rev,
|
|
515
|
+
delegation: env,
|
|
516
|
+
verifyBip322: input.verifyBip322,
|
|
517
|
+
skipSignatureVerification: input.skipSignatureVerification
|
|
518
|
+
});
|
|
519
|
+
if (!rr.ok) continue;
|
|
520
|
+
return err("E_REVOKED", `delegation ${env.id} was revoked by ${rev.id}`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
499
523
|
if (!input.skipTemporalCheck) {
|
|
500
524
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
501
525
|
const issued = new Date(env.issued_at);
|
|
@@ -530,6 +554,12 @@ async function verifyAction(input) {
|
|
|
530
554
|
scopeMode: input.scopeMode,
|
|
531
555
|
skipTemporalCheck: true,
|
|
532
556
|
// action window check dominates
|
|
557
|
+
// Revocation is evaluated ONCE, below, across every link in the chain
|
|
558
|
+
// (root + subdelegations) against the action's effective time — a
|
|
559
|
+
// per-link check here would use the wrong clock and would also
|
|
560
|
+
// double-report. Forward the caller's decision so this inner call does
|
|
561
|
+
// not trip the fail-closed guard.
|
|
562
|
+
skipRevocationCheck: true,
|
|
533
563
|
...input.decryptScopesWith ? { decryptScopesWith: input.decryptScopesWith } : {}
|
|
534
564
|
});
|
|
535
565
|
if (!dr.ok) return dr;
|
|
@@ -599,6 +629,12 @@ async function verifyAction(input) {
|
|
|
599
629
|
return err("E_BAD_SCOPE_GRAMMAR", msg);
|
|
600
630
|
}
|
|
601
631
|
if (!accepted) return err("E_SCOPE_DENIED", `scope_exercised (${exercised}) not a sub-scope of any granted scope`);
|
|
632
|
+
if (!input.skipRevocationCheck && !input.revocations) {
|
|
633
|
+
return err(
|
|
634
|
+
"E_MALFORMED",
|
|
635
|
+
"verifyAction requires `revocations` (fetch kind-30085 by #delegation for every link in the chain) or an explicit skipRevocationCheck:true"
|
|
636
|
+
);
|
|
637
|
+
}
|
|
602
638
|
if (input.revocations && input.revocations.length > 0) {
|
|
603
639
|
const allLinks = [rootHydrated, ...hydratedChain];
|
|
604
640
|
for (const link of allLinks) {
|