@7h3/protocol 0.6.0 → 0.6.2

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.
Files changed (3) hide show
  1. package/index.js +23 -6
  2. package/keyInfra.d.ts +31 -1
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -2432,6 +2432,7 @@ async function Gn(e, t) {
2432
2432
  let e = await t.replayCache.consume(n.envelope, r);
2433
2433
  if (!e.ok) throw Error(e.reason ?? "Queue message replay detected");
2434
2434
  }
2435
+ if ((typeof n.payload == "string" ? n.payload : JSON.stringify(n.payload)) !== n.envelope.body.content) throw Error("Queue message payload does not match the signed content — the payload field was modified in transit");
2435
2436
  return {
2436
2437
  payload: n.payload,
2437
2438
  envelope: n.envelope
@@ -2987,6 +2988,10 @@ var Cr = class {
2987
2988
  reason: t
2988
2989
  });
2989
2990
  }
2991
+ isEnvelopeRevoked(e) {
2992
+ let t = e?.header?.sender, n = e?.signature?.keyId;
2993
+ return t !== void 0 && this.isRevoked(t) || n !== void 0 && this.isRevoked(n);
2994
+ }
2990
2995
  isRevoked(e) {
2991
2996
  return this.revoked.has(e);
2992
2997
  }
@@ -3022,12 +3027,24 @@ var Cr = class {
3022
3027
  }
3023
3028
  consume(e, t, n = Date.now()) {
3024
3029
  let r = n - t.windowMs, i = (this.windows.get(e) ?? []).filter((e) => e > r), a = i.length < t.requests;
3025
- if (a && i.push(n), i.length > 0) for (this.windows.delete(e), this.windows.set(e, i); this.windows.size > this.maxKeys;) {
3026
- let e = this.windows.keys().next().value;
3027
- if (e === void 0) break;
3028
- this.windows.delete(e);
3029
- }
3030
- else this.windows.delete(e);
3030
+ if (a && i.push(n), i.length > 0) {
3031
+ if (this.windows.delete(e), this.windows.set(e, i), this.windows.size > this.maxKeys) {
3032
+ let r = n - t.windowMs;
3033
+ for (let [t, n] of this.windows) {
3034
+ if (this.windows.size <= this.maxKeys) break;
3035
+ t !== e && (n.length === 0 || n[n.length - 1] <= r) && this.windows.delete(t);
3036
+ }
3037
+ for (let [n, r] of this.windows) {
3038
+ if (this.windows.size <= this.maxKeys) break;
3039
+ n !== e && r.length < t.requests && this.windows.delete(n);
3040
+ }
3041
+ for (; this.windows.size > this.maxKeys;) {
3042
+ let e = this.windows.keys().next().value;
3043
+ if (e === void 0) break;
3044
+ this.windows.delete(e);
3045
+ }
3046
+ }
3047
+ } else this.windows.delete(e);
3031
3048
  return {
3032
3049
  allowed: a,
3033
3050
  remaining: Math.max(0, t.requests - i.length),
package/keyInfra.d.ts CHANGED
@@ -56,7 +56,37 @@ export interface RevocationList {
56
56
  }
57
57
  export declare class RevocationRegistry {
58
58
  private revoked;
59
- revoke(keyId: string, reason?: string): void;
59
+ /**
60
+ * Revoke an identifier — either a sender identity or a keyId.
61
+ *
62
+ * Which one you pass matters, and the difference used to be silent. A
63
+ * registry lookup is keyed by *sender*, so `wrapRegistry().getPublicKey()`
64
+ * can only ever compare against a sender id. Revoking a bare keyId therefore
65
+ * blocked the HMAC path (which receives both identifiers) while leaving the
66
+ * Ed25519 path fully open — a revoked, compromised key kept authenticating.
67
+ *
68
+ * Use {@link isEnvelopeRevoked} on the verification path to enforce a keyId
69
+ * revocation for Ed25519, or revoke the sender identity as well. For
70
+ * fleet-wide `(sender, keyId)` revocation, use `RevocationStore` from
71
+ * `./revocation` instead.
72
+ */
73
+ revoke(senderOrKeyId: string, reason?: string): void;
74
+ /**
75
+ * True if either the envelope's sender or the keyId it was signed under has
76
+ * been revoked.
77
+ *
78
+ * This is the check that actually enforces a keyId revocation for Ed25519,
79
+ * because unlike a registry lookup it can see `signature.keyId`. Call it on
80
+ * the verification path alongside signature checking.
81
+ */
82
+ isEnvelopeRevoked(envelope: {
83
+ header?: {
84
+ sender?: string;
85
+ };
86
+ signature?: {
87
+ keyId?: string;
88
+ };
89
+ }): boolean;
60
90
  isRevoked(keyId: string): boolean;
61
91
  getList(): RevocationList;
62
92
  importList(list: RevocationList): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7h3/protocol",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "7h3 Protocol: deterministic, signed, replay-safe AI-to-AI message envelopes (wire 7h3/0.1).",
5
5
  "type": "module",
6
6
  "main": "./index.js",