@orangecheck/agent-core 2.5.0 → 2.6.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/README.md +39 -17
- package/dist/index.js +16 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/delegation-window.test.ts +82 -0
- package/src/federation.test.ts +24 -2
- package/src/federation.ts +5 -3
- package/src/private-scope.test.ts +4 -2
- package/src/revocation-failclosed.test.ts +46 -10
- package/src/scope.test.ts +20 -0
- package/src/test-vectors.test.ts +21 -0
- package/src/verify.ts +25 -10
package/dist/index.mjs
CHANGED
|
@@ -512,7 +512,7 @@ async function verifyDelegation(input) {
|
|
|
512
512
|
if (!input.skipRevocationCheck && !input.revocations) {
|
|
513
513
|
return err(
|
|
514
514
|
"E_MALFORMED",
|
|
515
|
-
|
|
515
|
+
'verifyDelegation requires `revocations` (query kind 30085 with "#t": [delegation id], SPEC \xA79.4) or an explicit skipRevocationCheck:true to state that revocation is not being checked'
|
|
516
516
|
);
|
|
517
517
|
}
|
|
518
518
|
if (input.revocations) {
|
|
@@ -532,7 +532,6 @@ async function verifyDelegation(input) {
|
|
|
532
532
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
533
533
|
const issued = new Date(env.issued_at);
|
|
534
534
|
const expires = new Date(env.expires_at);
|
|
535
|
-
if (expires <= issued) return err("E_MALFORMED", "expires_at <= issued_at");
|
|
536
535
|
if (now < issued) return err("E_NOT_YET_VALID", `delegation not valid until ${env.issued_at}`);
|
|
537
536
|
if (now >= expires) return err("E_EXPIRED", `delegation expired at ${env.expires_at}`);
|
|
538
537
|
}
|
|
@@ -640,7 +639,7 @@ async function verifyAction(input) {
|
|
|
640
639
|
if (!input.skipRevocationCheck && !input.revocations) {
|
|
641
640
|
return err(
|
|
642
641
|
"E_MALFORMED",
|
|
643
|
-
|
|
642
|
+
'verifyAction requires `revocations` (query kind 30085 with "#t": [id of every link in the chain], SPEC \xA79.4) or an explicit skipRevocationCheck:true'
|
|
644
643
|
);
|
|
645
644
|
}
|
|
646
645
|
let actionAnchor;
|
|
@@ -797,11 +796,22 @@ function checkDelegationShape(env) {
|
|
|
797
796
|
}
|
|
798
797
|
if (!isIsoUtc(env.issued_at)) return err("E_MALFORMED", "issued_at must be ISO 8601 UTC");
|
|
799
798
|
if (!isIsoUtc(env.expires_at)) return err("E_MALFORMED", "expires_at must be ISO 8601 UTC");
|
|
799
|
+
const windowError = delegationWindowError(env.issued_at, env.expires_at);
|
|
800
|
+
if (windowError) return err("E_MALFORMED", windowError);
|
|
800
801
|
if (!/^[0-9a-f]{32}$/.test(env.nonce)) return err("E_MALFORMED", "nonce must be 32 lowercase hex chars");
|
|
801
802
|
if (env.sig?.alg !== "bip322" || typeof env.sig.value !== "string") return err("E_MALFORMED", "sig invalid");
|
|
802
803
|
if (env.sig.pubkey !== env.principal.address) return err("E_MALFORMED", "sig.pubkey must equal principal.address");
|
|
803
804
|
return null;
|
|
804
805
|
}
|
|
806
|
+
var MAX_DELEGATION_MS = 365 * 864e5;
|
|
807
|
+
function delegationWindowError(issuedAt, expiresAt) {
|
|
808
|
+
const issued = Date.parse(issuedAt);
|
|
809
|
+
const expires = Date.parse(expiresAt);
|
|
810
|
+
if (Number.isNaN(issued) || Number.isNaN(expires)) return "issued_at / expires_at must be real UTC times";
|
|
811
|
+
if (expires <= issued) return "expires_at must be after issued_at";
|
|
812
|
+
if (expires - issued > MAX_DELEGATION_MS) return "expires_at is more than 365 days after issued_at (SPEC \xA74.4)";
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
805
815
|
function checkActionShape(a) {
|
|
806
816
|
if (a.kind !== "agent-action") return err("E_MALFORMED", 'kind must be "agent-action"');
|
|
807
817
|
if (!isHex64(a.id)) return err("E_MALFORMED", "id must be 64 lowercase hex chars");
|
|
@@ -1073,6 +1083,8 @@ async function verifyFederationDelegation(input) {
|
|
|
1073
1083
|
if (!ISO_UTC.test(env.issued_at) || !ISO_UTC.test(env.expires_at)) {
|
|
1074
1084
|
return fail("E_MALFORMED", "issued_at / expires_at must be ISO 8601 UTC");
|
|
1075
1085
|
}
|
|
1086
|
+
const windowError = delegationWindowError(env.issued_at, env.expires_at);
|
|
1087
|
+
if (windowError) return fail("E_MALFORMED", windowError);
|
|
1076
1088
|
if (!/^[0-9a-f]{32}$/.test(env.nonce)) return fail("E_MALFORMED", "nonce must be 32 hex chars");
|
|
1077
1089
|
let canonicalScopes;
|
|
1078
1090
|
try {
|
|
@@ -1104,7 +1116,7 @@ async function verifyFederationDelegation(input) {
|
|
|
1104
1116
|
if (!input.skipRevocationCheck && !input.revocations) {
|
|
1105
1117
|
return fail(
|
|
1106
1118
|
"E_MALFORMED",
|
|
1107
|
-
|
|
1119
|
+
'verifyFederationDelegation requires `revocations` (query kind 30085 with "#t": [delegation id], SPEC \xA79.4) or an explicit skipRevocationCheck:true to state that revocation is not being checked'
|
|
1108
1120
|
);
|
|
1109
1121
|
}
|
|
1110
1122
|
for (const rev of input.revocations ?? []) {
|
|
@@ -1117,7 +1129,6 @@ async function verifyFederationDelegation(input) {
|
|
|
1117
1129
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
1118
1130
|
const issued = new Date(env.issued_at);
|
|
1119
1131
|
const expires = new Date(env.expires_at);
|
|
1120
|
-
if (expires <= issued) return fail("E_MALFORMED", "expires_at <= issued_at");
|
|
1121
1132
|
if (now < issued) return fail("E_NOT_YET_VALID", `delegation not valid until ${env.issued_at}`);
|
|
1122
1133
|
if (now >= expires) return fail("E_EXPIRED", `delegation expired at ${env.expires_at}`);
|
|
1123
1134
|
}
|