keri-ts 2.2.4 → 2.2.5
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/esm/keri/npm/src/_dnt.polyfills.js +14 -14
- package/esm/keri/npm/src/acdc/registering.js +19 -0
- package/esm/keri/npm/src/acdc/salting.js +4 -0
- package/esm/keri/npm/src/app/bootstrap/authenticating.js +32 -10
- package/esm/keri/npm/src/app/bootstrap/oobiery.js +363 -30
- package/esm/keri/npm/src/app/credentials/credential-importing.js +33 -4
- package/esm/keri/npm/src/app/credentials/root-replicator.js +27 -15
- package/esm/keri/npm/src/app/credentials/schema-resolving.js +5 -1
- package/esm/keri/npm/src/app/credentials/tel-publishing.js +16 -7
- package/esm/keri/npm/src/app/delivery/forwarding.js +177 -43
- package/esm/keri/npm/src/app/delivery/relaying.js +232 -0
- package/esm/keri/npm/src/app/delivery/respondant.js +8 -5
- package/esm/keri/npm/src/app/exchanges/exchange-messaging.js +1 -1
- package/esm/keri/npm/src/app/exchanges/exchanging.js +65 -9
- package/esm/keri/npm/src/app/identity/delegating.js +66 -9
- package/esm/keri/npm/src/app/identity/habbing.js +190 -71
- package/esm/keri/npm/src/app/identity/keeping.js +111 -39
- package/esm/keri/npm/src/app/identity/retire-identifier.js +98 -0
- package/esm/keri/npm/src/app/ipex/disclosure-replaying.js +116 -0
- package/esm/keri/npm/src/app/ipex/group-ipex.js +122 -25
- package/esm/keri/npm/src/app/ipex/group-issuance.js +109 -23
- package/esm/keri/npm/src/app/ipex/ipex-discloser.js +36 -22
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +53 -3
- package/esm/keri/npm/src/app/ipex/ipex-v2.js +7 -2
- package/esm/keri/npm/src/app/ipex/issuance.js +131 -35
- package/esm/keri/npm/src/app/ipex/pending-presentations.js +4 -2
- package/esm/keri/npm/src/app/ipex/presenting.js +3 -18
- package/esm/keri/npm/src/app/ipex/receive-issuance.js +2 -1
- package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +16 -3
- package/esm/keri/npm/src/app/mailbox/agent-inbox.js +292 -0
- package/esm/keri/npm/src/app/mailbox/forward-handler.js +298 -52
- package/esm/keri/npm/src/app/mailbox/kel-publisher.js +26 -31
- package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +70 -62
- package/esm/keri/npm/src/app/mailbox/mailboxing.js +20 -4
- package/esm/keri/npm/src/app/multisig/counseling.js +71 -27
- package/esm/keri/npm/src/app/multisig/group-members.js +41 -5
- package/esm/keri/npm/src/app/multisig/grouping.js +50 -2
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +3 -18
- package/esm/keri/npm/src/app/multisig/proposing.js +1 -16
- package/esm/keri/npm/src/app/multisig/rejoin-group.js +99 -0
- package/esm/keri/npm/src/app/multisig/replace-member.js +29 -8
- package/esm/keri/npm/src/app/protocol/parsering.js +45 -17
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +47 -21
- package/esm/keri/npm/src/app/queries/query-replies.js +0 -22
- package/esm/keri/npm/src/app/queries/relay-refresh.js +81 -0
- package/esm/keri/npm/src/app/queries/witness-inquisitor.js +180 -34
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +41 -72
- package/esm/keri/npm/src/app/runtime/cue-runtime.js +45 -5
- package/esm/keri/npm/src/app/runtime/operation-owners.js +26 -56
- package/esm/keri/npm/src/app/runtime/workflow-contract.js +7 -4
- package/esm/keri/npm/src/app/transport/http-client.js +20 -2
- package/esm/keri/npm/src/app/transport/message-source.js +2 -1
- package/esm/keri/npm/src/app/transport/messengering.js +39 -8
- package/esm/keri/npm/src/app/witness/ingress.js +7 -0
- package/esm/keri/npm/src/app/witness/receipt-client.js +43 -16
- package/esm/keri/npm/src/app/witness/receipting.js +62 -20
- package/esm/keri/npm/src/cli/messaging/multisig.js +4 -3
- package/esm/keri/npm/src/core/errors.js +73 -0
- package/esm/keri/npm/src/core/kel/delegation-ancestry.js +11 -2
- package/esm/keri/npm/src/core/kel/eventing.js +25 -28
- package/esm/keri/npm/src/core/kel/kever.js +15 -9
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +8 -0
- package/esm/keri/npm/src/core/mailbox/kram-pruning.js +25 -6
- package/esm/keri/npm/src/core/mailbox/kram-time.js +34 -6
- package/esm/keri/npm/src/core/mailbox/kraming.js +58 -2
- package/esm/keri/npm/src/core/routing.js +18 -25
- package/esm/keri/npm/src/core/scheming.js +12 -5
- package/esm/keri/npm/src/core/wire-fields.js +126 -0
- package/esm/keri/npm/src/db/basing.js +4 -13
- package/esm/keri/npm/src/db/core/indexeddb-persistence.js +3 -2
- package/esm/keri/npm/src/db/core/webdber.js +85 -27
- package/esm/keri/npm/src/db/mailbox/mailboxing.js +13 -0
- package/esm/keri/npm/src/db/subing.js +4 -0
- package/esm/keri/npm/src/runtime/index.js +11 -5
- package/esm/keri/npm/src/time/mod.js +5 -0
- package/esm/keri/npm/src/vdr/credential-tsn-record.js +2 -7
- package/esm/keri/npm/src/vdr/eventing.js +28 -19
- package/esm/keri/npm/src/vdr/registry-tsn-record.js +3 -13
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +1 -1
- package/types/_dnt.polyfills.d.ts +9 -9
- package/types/_dnt.polyfills.d.ts.map +1 -1
- package/types/acdc/registering.d.ts +6 -0
- package/types/acdc/registering.d.ts.map +1 -1
- package/types/acdc/salting.d.ts.map +1 -1
- package/types/app/bootstrap/authenticating.d.ts +12 -2
- package/types/app/bootstrap/authenticating.d.ts.map +1 -1
- package/types/app/bootstrap/oobiery.d.ts +144 -7
- package/types/app/bootstrap/oobiery.d.ts.map +1 -1
- package/types/app/credentials/credential-importing.d.ts +8 -0
- package/types/app/credentials/credential-importing.d.ts.map +1 -1
- package/types/app/credentials/root-replicator.d.ts +19 -8
- package/types/app/credentials/root-replicator.d.ts.map +1 -1
- package/types/app/credentials/schema-resolving.d.ts.map +1 -1
- package/types/app/credentials/tel-publishing.d.ts +4 -2
- package/types/app/credentials/tel-publishing.d.ts.map +1 -1
- package/types/app/delivery/forwarding.d.ts +69 -5
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- package/types/app/delivery/relaying.d.ts +144 -0
- package/types/app/delivery/relaying.d.ts.map +1 -0
- package/types/app/delivery/respondant.d.ts +9 -2
- package/types/app/delivery/respondant.d.ts.map +1 -1
- package/types/app/exchanges/exchanging.d.ts +36 -0
- package/types/app/exchanges/exchanging.d.ts.map +1 -1
- package/types/app/identity/delegating.d.ts +6 -0
- package/types/app/identity/delegating.d.ts.map +1 -1
- package/types/app/identity/habbing.d.ts +106 -19
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +54 -19
- package/types/app/identity/keeping.d.ts.map +1 -1
- package/types/app/identity/retire-identifier.d.ts +24 -0
- package/types/app/identity/retire-identifier.d.ts.map +1 -0
- package/types/app/ipex/disclosure-replaying.d.ts +61 -0
- package/types/app/ipex/disclosure-replaying.d.ts.map +1 -0
- package/types/app/ipex/group-ipex.d.ts +60 -14
- package/types/app/ipex/group-ipex.d.ts.map +1 -1
- package/types/app/ipex/group-issuance.d.ts +48 -6
- package/types/app/ipex/group-issuance.d.ts.map +1 -1
- package/types/app/ipex/ipex-discloser.d.ts +14 -2
- package/types/app/ipex/ipex-discloser.d.ts.map +1 -1
- package/types/app/ipex/ipex-grouping.d.ts +23 -2
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex/ipex-v2.d.ts +5 -2
- package/types/app/ipex/ipex-v2.d.ts.map +1 -1
- package/types/app/ipex/issuance.d.ts +35 -11
- package/types/app/ipex/issuance.d.ts.map +1 -1
- package/types/app/ipex/pending-presentations.d.ts +4 -2
- package/types/app/ipex/pending-presentations.d.ts.map +1 -1
- package/types/app/ipex/presenting.d.ts.map +1 -1
- package/types/app/ipex/receive-issuance.d.ts +2 -1
- package/types/app/ipex/receive-issuance.d.ts.map +1 -1
- package/types/app/ipex/unblinding-workflow.d.ts +4 -1
- package/types/app/ipex/unblinding-workflow.d.ts.map +1 -1
- package/types/app/mailbox/agent-inbox.d.ts +126 -0
- package/types/app/mailbox/agent-inbox.d.ts.map +1 -0
- package/types/app/mailbox/forward-handler.d.ts +114 -14
- package/types/app/mailbox/forward-handler.d.ts.map +1 -1
- package/types/app/mailbox/kel-publisher.d.ts +12 -22
- package/types/app/mailbox/kel-publisher.d.ts.map +1 -1
- package/types/app/mailbox/mailbox-poller.d.ts +40 -24
- package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
- package/types/app/mailbox/mailboxing.d.ts +19 -5
- package/types/app/mailbox/mailboxing.d.ts.map +1 -1
- package/types/app/multisig/counseling.d.ts +32 -11
- package/types/app/multisig/counseling.d.ts.map +1 -1
- package/types/app/multisig/group-members.d.ts +17 -1
- package/types/app/multisig/group-members.d.ts.map +1 -1
- package/types/app/multisig/grouping.d.ts +17 -1
- package/types/app/multisig/grouping.d.ts.map +1 -1
- package/types/app/multisig/multisig-workflows.d.ts +0 -8
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
- package/types/app/multisig/proposing.d.ts +4 -19
- package/types/app/multisig/proposing.d.ts.map +1 -1
- package/types/app/multisig/rejoin-group.d.ts +119 -0
- package/types/app/multisig/rejoin-group.d.ts.map +1 -0
- package/types/app/multisig/replace-member.d.ts +15 -1
- package/types/app/multisig/replace-member.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +21 -2
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +25 -5
- package/types/app/protocol/protocol-processing.d.ts.map +1 -1
- package/types/app/queries/query-replies.d.ts +4 -8
- package/types/app/queries/query-replies.d.ts.map +1 -1
- package/types/app/queries/relay-refresh.d.ts +26 -0
- package/types/app/queries/relay-refresh.d.ts.map +1 -0
- package/types/app/queries/witness-inquisitor.d.ts +56 -5
- package/types/app/queries/witness-inquisitor.d.ts.map +1 -1
- package/types/app/runtime/agent-runtime.d.ts +34 -3
- package/types/app/runtime/agent-runtime.d.ts.map +1 -1
- package/types/app/runtime/cue-runtime.d.ts +15 -3
- package/types/app/runtime/cue-runtime.d.ts.map +1 -1
- package/types/app/runtime/operation-owners.d.ts +16 -26
- package/types/app/runtime/operation-owners.d.ts.map +1 -1
- package/types/app/runtime/workflow-contract.d.ts +21 -6
- package/types/app/runtime/workflow-contract.d.ts.map +1 -1
- package/types/app/transport/http-client.d.ts +9 -0
- package/types/app/transport/http-client.d.ts.map +1 -1
- package/types/app/transport/message-source.d.ts +6 -3
- package/types/app/transport/message-source.d.ts.map +1 -1
- package/types/app/transport/messengering.d.ts +10 -1
- package/types/app/transport/messengering.d.ts.map +1 -1
- package/types/app/witness/ingress.d.ts +1 -0
- package/types/app/witness/ingress.d.ts.map +1 -1
- package/types/app/witness/receipt-client.d.ts +19 -1
- package/types/app/witness/receipt-client.d.ts.map +1 -1
- package/types/app/witness/receipting.d.ts +24 -1
- package/types/app/witness/receipting.d.ts.map +1 -1
- package/types/cli/messaging/multisig.d.ts.map +1 -1
- package/types/core/cues.d.ts +53 -1
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/errors.d.ts +32 -0
- package/types/core/errors.d.ts.map +1 -1
- package/types/core/kel/delegation-ancestry.d.ts.map +1 -1
- package/types/core/kel/eventing.d.ts.map +1 -1
- package/types/core/kel/kever-decisions.d.ts +3 -1
- package/types/core/kel/kever-decisions.d.ts.map +1 -1
- package/types/core/kel/kever.d.ts +7 -1
- package/types/core/kel/kever.d.ts.map +1 -1
- package/types/core/mailbox/kram-policy.d.ts +6 -0
- package/types/core/mailbox/kram-policy.d.ts.map +1 -1
- package/types/core/mailbox/kram-pruning.d.ts +5 -1
- package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
- package/types/core/mailbox/kram-time.d.ts +26 -2
- package/types/core/mailbox/kram-time.d.ts.map +1 -1
- package/types/core/mailbox/kraming.d.ts +14 -1
- package/types/core/mailbox/kraming.d.ts.map +1 -1
- package/types/core/routing.d.ts +3 -7
- package/types/core/routing.d.ts.map +1 -1
- package/types/core/scheming.d.ts.map +1 -1
- package/types/core/wire-fields.d.ts +56 -0
- package/types/core/wire-fields.d.ts.map +1 -0
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/indexeddb-persistence.d.ts +3 -2
- package/types/db/core/indexeddb-persistence.d.ts.map +1 -1
- package/types/db/core/webdber.d.ts +32 -6
- package/types/db/core/webdber.d.ts.map +1 -1
- package/types/db/exchange/exchange-records.d.ts +4 -0
- package/types/db/exchange/exchange-records.d.ts.map +1 -1
- package/types/db/mailbox/mailboxing.d.ts +10 -1
- package/types/db/mailbox/mailboxing.d.ts.map +1 -1
- package/types/db/subing.d.ts +2 -0
- package/types/db/subing.d.ts.map +1 -1
- package/types/runtime/index.d.ts +20 -14
- package/types/runtime/index.d.ts.map +1 -1
- package/types/time/mod.d.ts +2 -0
- package/types/time/mod.d.ts.map +1 -1
- package/types/vdr/credential-tsn-record.d.ts.map +1 -1
- package/types/vdr/eventing.d.ts.map +1 -1
- package/types/vdr/registry-tsn-record.d.ts.map +1 -1
- package/types/version.d.ts +2 -2
- package/esm/keri/npm/src/app/runtime/signer-conditions.js +0 -51
- package/types/app/runtime/signer-conditions.d.ts +0 -32
- package/types/app/runtime/signer-conditions.d.ts.map +0 -1
|
@@ -186,14 +186,16 @@ export class UnblindingOperations {
|
|
|
186
186
|
}
|
|
187
187
|
/**
|
|
188
188
|
* Whether a pass has work: a live operation, or an owner holds an authenticated peer query whose reply is
|
|
189
|
-
* owed (an in-memory walk of the owners, no store read).
|
|
189
|
+
* owed (an in-memory walk of the owners, no store read). Finding what is owed reprocesses held queries, which
|
|
190
|
+
* answers them (signs), so an owner whose habitat cannot sign yet is skipped here as it is in `adopt`.
|
|
190
191
|
*/
|
|
191
192
|
active() {
|
|
192
193
|
if (this.live.size > 0)
|
|
193
194
|
return true;
|
|
194
|
-
for (const owner of this.deps.unblinds.unblindOwners())
|
|
195
|
-
if (owner.awaitingReply().length)
|
|
195
|
+
for (const owner of this.deps.unblinds.unblindOwners()) {
|
|
196
|
+
if (owner.hab.canSign() && owner.awaitingReply().length)
|
|
196
197
|
return true;
|
|
198
|
+
}
|
|
197
199
|
return false;
|
|
198
200
|
}
|
|
199
201
|
/** Advance every live operation by one pass, each bounded by its Grant deadline. */
|
|
@@ -208,6 +210,9 @@ export class UnblindingOperations {
|
|
|
208
210
|
const left = op.expires - BigInt(deps.clock.now()) * 1000n;
|
|
209
211
|
if (left <= 0n)
|
|
210
212
|
this.end(op, "expired", this.expiry(op));
|
|
213
|
+
// A habitat that cannot sign yet waits for its signer; only its Grant deadline ends the operation meanwhile.
|
|
214
|
+
else if (!op.hab.canSign())
|
|
215
|
+
continue;
|
|
211
216
|
else if ((yield* race([this.advance(op), this.timer(Number(left) / 1000)])) === "expired") {
|
|
212
217
|
this.end(op, "expired", this.expiry(op));
|
|
213
218
|
}
|
|
@@ -233,6 +238,10 @@ export class UnblindingOperations {
|
|
|
233
238
|
adopt() {
|
|
234
239
|
const { deps } = this;
|
|
235
240
|
for (const owner of deps.unblinds.unblindOwners()) {
|
|
241
|
+
// Finding what is owed reprocesses held queries, which answers them (signs); an owner whose habitat cannot
|
|
242
|
+
// sign yet is asked on a later pass.
|
|
243
|
+
if (!owner.hab.canSign())
|
|
244
|
+
continue;
|
|
236
245
|
for (const { xid, grant } of owner.awaitingReply()) {
|
|
237
246
|
if (this.live.has(unblindingKey(grant, "responder")))
|
|
238
247
|
continue;
|
|
@@ -297,6 +306,10 @@ export class UnblindingOperations {
|
|
|
297
306
|
this.end(op, "abandoned", reason);
|
|
298
307
|
return bound.map(op => op.grant);
|
|
299
308
|
}
|
|
309
|
+
/** Grants of the live Unblind operations whose habitat is `pre`. */
|
|
310
|
+
grantsOf(pre) {
|
|
311
|
+
return [...new Set([...this.live.values()].filter(op => op.hab.pre === pre).map(op => op.grant))];
|
|
312
|
+
}
|
|
300
313
|
/** Drop the live entry and the owner's approval and frozen messages; delivered bytes stay the peer's. */
|
|
301
314
|
release(op) {
|
|
302
315
|
this.live.delete(unblindingKey(op.grant, op.role));
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host's inbox rules: what a host keeps for pickup by an identifier that runs elsewhere, under the storing roles
|
|
3
|
+
* it honours (`mailbox` and `agent`), and which raw arrivals it keeps for an identifier that authorized it as `agent`.
|
|
4
|
+
*
|
|
5
|
+
* A KERIpy or KERIA sender reaches an agent with `sendDirect`: one bare signed message per request, no `/fwd`, no
|
|
6
|
+
* topic and often no recipient (keripy forwarding.py `Poster.deliverDo`; keria indirecting.py `HttpEnd.on_post`).
|
|
7
|
+
* The agent processes that message as its own input (dispatch is the single ingest). For an identifier that runs
|
|
8
|
+
* elsewhere (an edge) and authorized this host as its agent, the host also keeps one copy in the edge's mailbox
|
|
9
|
+
* topic, where the edge polls it. This module decides that copy and writes it; it owns no store and no registry and
|
|
10
|
+
* reads only accepted `ends.` rows, local habitats and accepted key state.
|
|
11
|
+
*
|
|
12
|
+
* A `/fwd` names its recipient and topic; the forward handler stores it under {@link keepsForPickup} and
|
|
13
|
+
* {@link ownTraffic}. A raw arrival is kept only under the `agent` role: a sender reaches a `mailbox` with `/fwd`.
|
|
14
|
+
*
|
|
15
|
+
* Raw-arrival rules:
|
|
16
|
+
* - Principal: an identifier with an allowed or enabled `ends.[cid, agent, host]` row.
|
|
17
|
+
* - With a named recipient R, the one principal is R when it authorized the host as agent and
|
|
18
|
+
* {@link keepsForPickup}; otherwise nothing is kept.
|
|
19
|
+
* - With no named recipient, every principal that is not a local habitat (a local group is processed by its hosted
|
|
20
|
+
* co-member through dispatch, so the edge receives one copy under its member AID).
|
|
21
|
+
* - Never kept: {@link ownTraffic}, a message whose originator is a local habitat, a principal of the host, or a
|
|
22
|
+
* member of the recipient group (an edge's own traffic, or a local group's own events); and a message whose topic,
|
|
23
|
+
* derived from its remote route, the mailbox store cannot key.
|
|
24
|
+
* - Kept only when the body verifies its SAID, carries attached authentication, and the agent's own processor
|
|
25
|
+
* decided it ({@link keptDecision}). The edge is the verifier of signatures and state and re-verifies everything,
|
|
26
|
+
* so a decision that waits on state is kept: `accept`, `escrow`, KRAM `pending`/`missing` and an `unverified`
|
|
27
|
+
* reply. The agent never keeps what it could not decode: dispatch refuses malformed field values as a typed
|
|
28
|
+
* `reject` or `drop` before any escrow decision (`core/wire-fields.ts`), and those are not kept; nor is a message
|
|
29
|
+
* no processor decided, except a receipt, whose processor decodes it and reports none.
|
|
30
|
+
*/
|
|
31
|
+
import { collectPayload, framePayload, Ilks, SerderACDC, SerderKERI, } from "cesr-ts";
|
|
32
|
+
import { CREDENTIAL_MAILBOX_TOPIC, DELEGATE_MAILBOX_TOPIC, RECEIPT_MAILBOX_TOPIC, REPLAY_MAILBOX_TOPIC, REPLY_MAILBOX_TOPIC, } from "../../core/mailbox/mailbox-topics.js";
|
|
33
|
+
import { Roles } from "../../core/roles.js";
|
|
34
|
+
import { storableTopic } from "../../db/mailbox/mailboxing.js";
|
|
35
|
+
import { isAcceptedGroupMember } from "../multisig/group-members.js";
|
|
36
|
+
import { envelopeFromFrame } from "../protocol/parsering.js";
|
|
37
|
+
import { abortable } from "../runtime/abortable.js";
|
|
38
|
+
import { mailboxTopicKey } from "./mailboxing.js";
|
|
39
|
+
import { mailboxTopicForRoute } from "./topic-routing.js";
|
|
40
|
+
/**
|
|
41
|
+
* Whether `cid` authorized `hostAid` under a storing role: row `ends.[cid, mailbox, hostAid]` or
|
|
42
|
+
* `ends.[cid, agent, hostAid]`, allowed or enabled. Witness membership is not a storing role here.
|
|
43
|
+
*
|
|
44
|
+
* @param hby Borrowed local habitat collection and accepted-state database.
|
|
45
|
+
* @param cid Identifier whose end-role authorization is read.
|
|
46
|
+
* @param hostAid Endpoint AID the role must name.
|
|
47
|
+
* @returns True when either row authorizes the host.
|
|
48
|
+
*/
|
|
49
|
+
export function authorizedStoringHost(hby, cid, hostAid) {
|
|
50
|
+
return [Roles.mailbox, Roles.agent].some((role) => {
|
|
51
|
+
const end = hby.db.ends.get([cid, role, hostAid]);
|
|
52
|
+
return !!(end?.allowed || end?.enabled);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Whether `cid` authorized `hostAid` as its agent: row `ends.[cid, agent, hostAid]`, allowed or enabled.
|
|
57
|
+
*
|
|
58
|
+
* @param hby Borrowed local habitat collection and accepted-state database.
|
|
59
|
+
* @param cid Identifier whose end-role authorization is read.
|
|
60
|
+
* @param hostAid Local endpoint AID the role must name.
|
|
61
|
+
* @returns True when the accepted row authorizes the host.
|
|
62
|
+
*/
|
|
63
|
+
export function authorizedAgent(hby, cid, hostAid) {
|
|
64
|
+
const end = hby.db.ends.get([cid, Roles.agent, hostAid]);
|
|
65
|
+
return !!(end?.allowed || end?.enabled);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Whether this host keeps mail for pickup for `recipient`: the recipient authorized it under a storing role
|
|
69
|
+
* ({@link authorizedStoringHost}) and is either remote (an edge) or a local group (whose remote members poll the
|
|
70
|
+
* group's mailbox). A local single-sig habitat processes its own mail here and has nobody to pick it up.
|
|
71
|
+
*
|
|
72
|
+
* @param hby Borrowed local habitat collection and accepted-state database.
|
|
73
|
+
* @param recipient Identifier the message is addressed to.
|
|
74
|
+
* @param hostAid Local endpoint AID that received the message.
|
|
75
|
+
* @returns True when the host keeps a copy in the recipient's mailbox.
|
|
76
|
+
*/
|
|
77
|
+
export function keepsForPickup(hby, recipient, hostAid) {
|
|
78
|
+
return authorizedStoringHost(hby, recipient, hostAid) && (!hby.habs.has(recipient) || hby.db.groups.has(recipient));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether a message is traffic of the very identifiers that would pick it up, which is never kept: its originator
|
|
82
|
+
* is a local habitat, authorized `hostAid` as agent, or is an accepted member of the recipient group (the edge
|
|
83
|
+
* member that polls the group's mailbox). An edge does not pick up what it sent, and a local group's own events
|
|
84
|
+
* reach its remote members through their own exchanges.
|
|
85
|
+
*
|
|
86
|
+
* @param hby Borrowed local habitat collection and accepted-state database.
|
|
87
|
+
* @param originator The message's own `i` (an ACDC's issuer), or null when it names none.
|
|
88
|
+
* @param recipient Named recipient, or null when the message names none.
|
|
89
|
+
* @param hostAid Local endpoint AID that received the message.
|
|
90
|
+
* @returns True when the message must not be kept.
|
|
91
|
+
*/
|
|
92
|
+
export function ownTraffic(hby, originator, recipient, hostAid) {
|
|
93
|
+
if (!originator)
|
|
94
|
+
return false;
|
|
95
|
+
if (hby.habs.has(originator) || authorizedAgent(hby, originator, hostAid))
|
|
96
|
+
return true;
|
|
97
|
+
return recipient !== null && hby.db.groups.has(recipient) && isAcceptedGroupMember(hby.db, recipient, originator);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The recipient a raw message names, or null when it names none.
|
|
101
|
+
*
|
|
102
|
+
* An exn or xip names it in `rp` (v1) or `ri` (v2) when non-empty. A delegated event is addressed to its delegator:
|
|
103
|
+
* a `dip` carries it in `di`; a `drt` carries no `di`, so its delegator is read from the delegate's accepted key
|
|
104
|
+
* state (dispatch has already run, so a `drt` the agent accepted or escrowed has its `dip` behind it).
|
|
105
|
+
*
|
|
106
|
+
* @param hby Borrowed accepted-state database, read only for a `drt`'s delegator.
|
|
107
|
+
* @param serder Raw message body.
|
|
108
|
+
* @returns Named recipient AID, or null.
|
|
109
|
+
*/
|
|
110
|
+
export function rawRecipient(hby, serder) {
|
|
111
|
+
switch (serder.ilk) {
|
|
112
|
+
case Ilks.exn:
|
|
113
|
+
case Ilks.xip: {
|
|
114
|
+
const named = serder.ked?.rp ?? serder.ked?.ri;
|
|
115
|
+
return typeof named === "string" && named.length > 0 ? named : null;
|
|
116
|
+
}
|
|
117
|
+
case Ilks.dip:
|
|
118
|
+
return serder.delpre;
|
|
119
|
+
case Ilks.drt:
|
|
120
|
+
return serder.pre ? hby.db.getKever(serder.pre)?.delpre ?? null : null;
|
|
121
|
+
default:
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Mailbox topic for a raw message; null means it is never kept.
|
|
127
|
+
*
|
|
128
|
+
* | body | topic |
|
|
129
|
+
* | --- | --- |
|
|
130
|
+
* | exn/xip | `mailboxTopicForRoute(route)` |
|
|
131
|
+
* | exn `/fwd`, qry, other ilks | null (host-addressed transport or nothing to pick up) |
|
|
132
|
+
* | dip/drt addressed to its delegator | `/delegate` |
|
|
133
|
+
* | other KEL events | `/replay` |
|
|
134
|
+
* | rct | `/receipt` |
|
|
135
|
+
* | rpy | `/reply` |
|
|
136
|
+
* | TEL events and ACDC bodies | `/credential` |
|
|
137
|
+
*
|
|
138
|
+
* @param body Raw message body.
|
|
139
|
+
* @param recipient Recipient from {@link rawRecipient}; for a dip/drt, its delegator.
|
|
140
|
+
* @returns Mailbox topic, or null.
|
|
141
|
+
*/
|
|
142
|
+
export function rawMailboxTopic(body, recipient) {
|
|
143
|
+
if (body instanceof SerderACDC)
|
|
144
|
+
return CREDENTIAL_MAILBOX_TOPIC;
|
|
145
|
+
switch (body.ilk) {
|
|
146
|
+
case Ilks.exn:
|
|
147
|
+
case Ilks.xip: {
|
|
148
|
+
if (body.route === "/fwd")
|
|
149
|
+
return null;
|
|
150
|
+
const topic = mailboxTopicForRoute(body.route ?? "");
|
|
151
|
+
return topic.length > 0 ? topic : null;
|
|
152
|
+
}
|
|
153
|
+
case Ilks.dip:
|
|
154
|
+
case Ilks.drt:
|
|
155
|
+
return recipient !== null ? DELEGATE_MAILBOX_TOPIC : REPLAY_MAILBOX_TOPIC;
|
|
156
|
+
case Ilks.icp:
|
|
157
|
+
case Ilks.rot:
|
|
158
|
+
case Ilks.ixn:
|
|
159
|
+
return REPLAY_MAILBOX_TOPIC;
|
|
160
|
+
case Ilks.rct:
|
|
161
|
+
return RECEIPT_MAILBOX_TOPIC;
|
|
162
|
+
case Ilks.rpy:
|
|
163
|
+
return REPLY_MAILBOX_TOPIC;
|
|
164
|
+
case Ilks.vcp:
|
|
165
|
+
case Ilks.vrt:
|
|
166
|
+
case Ilks.iss:
|
|
167
|
+
case Ilks.rev:
|
|
168
|
+
case Ilks.bis:
|
|
169
|
+
case Ilks.brv:
|
|
170
|
+
return CREDENTIAL_MAILBOX_TOPIC;
|
|
171
|
+
default:
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Store one dispatched raw arrival once for each of its principals (see the module rules).
|
|
177
|
+
*
|
|
178
|
+
* @param director Borrowed mailbox owner; a host without a mailbox store keeps nothing.
|
|
179
|
+
* @param arrival The dispatched frame, its host and the agent's decision.
|
|
180
|
+
* @returns Number of mailbox entries written.
|
|
181
|
+
*/
|
|
182
|
+
export function* keepRawArrival(director, arrival) {
|
|
183
|
+
const hby = director.hby;
|
|
184
|
+
const body = arrival.frame.body;
|
|
185
|
+
if (!director.mailboxer || !(body instanceof SerderKERI || body instanceof SerderACDC))
|
|
186
|
+
return 0;
|
|
187
|
+
if (!keptDecision(body, arrival.decision) || !saidVerifies(body))
|
|
188
|
+
return 0;
|
|
189
|
+
const recipient = body instanceof SerderKERI ? rawRecipient(hby, body) : null;
|
|
190
|
+
const topic = rawMailboxTopic(body, recipient);
|
|
191
|
+
if (topic === null || !authenticated(arrival.frame))
|
|
192
|
+
return 0;
|
|
193
|
+
const originator = body instanceof SerderKERI ? body.pre : body.issuer;
|
|
194
|
+
if (!rawPrincipals(hby, originator, recipient, arrival.hostAid).length)
|
|
195
|
+
return 0;
|
|
196
|
+
const wire = yield* abortable((signal) => collectPayload(framePayload(arrival.frame), signal));
|
|
197
|
+
// Re-read accepted authority in the same synchronous turn as publication. The topic comes from a remote route; one
|
|
198
|
+
// the mailbox store cannot key is not kept, never a store fault.
|
|
199
|
+
const principals = rawPrincipals(hby, originator, recipient, arrival.hostAid)
|
|
200
|
+
.filter((principal) => storableTopic(mailboxTopicKey(principal, topic)));
|
|
201
|
+
for (const principal of principals)
|
|
202
|
+
director.publish(principal, topic, wire);
|
|
203
|
+
return principals.length;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The principals one raw arrival is kept for, from current accepted state; empty when it is never kept.
|
|
207
|
+
*
|
|
208
|
+
* @param hby Borrowed local habitat collection and accepted-state database.
|
|
209
|
+
* @param originator The message's own `i` (an ACDC's issuer), or null.
|
|
210
|
+
* @param recipient Named recipient from {@link rawRecipient}, or null.
|
|
211
|
+
* @param hostAid Local endpoint AID that received the message.
|
|
212
|
+
* @returns Principals to publish under, in a stable order.
|
|
213
|
+
*/
|
|
214
|
+
function rawPrincipals(hby, originator, recipient, hostAid) {
|
|
215
|
+
if (ownTraffic(hby, originator, recipient, hostAid))
|
|
216
|
+
return [];
|
|
217
|
+
if (recipient !== null) {
|
|
218
|
+
return authorizedAgent(hby, recipient, hostAid) && keepsForPickup(hby, recipient, hostAid) ? [recipient] : [];
|
|
219
|
+
}
|
|
220
|
+
return agentPrincipals(hby, hostAid);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Every remote identifier that authorized `hostAid` as its agent.
|
|
224
|
+
*
|
|
225
|
+
* `ends.` is keyed cid-first with no reverse index, so this scans every row; it runs only for a message that names
|
|
226
|
+
* no recipient. One Habery serves one account downstream, so the table is that account's contacts' roles.
|
|
227
|
+
*
|
|
228
|
+
* @param hby Borrowed local habitat collection and accepted-state database.
|
|
229
|
+
* @param hostAid Local endpoint AID.
|
|
230
|
+
* @returns Principals in stored key order.
|
|
231
|
+
*/
|
|
232
|
+
function agentPrincipals(hby, hostAid) {
|
|
233
|
+
const cids = [];
|
|
234
|
+
for (const [[cid, role, eid], end] of hby.db.ends.getTopItemIter()) {
|
|
235
|
+
if (role === Roles.agent && eid === hostAid && (end.allowed || end.enabled) && !hby.habs.has(cid))
|
|
236
|
+
cids.push(cid);
|
|
237
|
+
}
|
|
238
|
+
return cids;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Whether the agent's decision shows it decoded the message and leaves it worth delivering: decided by a processor,
|
|
242
|
+
* not refused, and not a repeat of what it holds. See the module rules.
|
|
243
|
+
*
|
|
244
|
+
* Malformed fields are the dispatch processors' typed `reject` or `drop`; this reads only the decision they return.
|
|
245
|
+
*
|
|
246
|
+
* @param body Dispatched message body.
|
|
247
|
+
* @param decision Dispatch decision; undefined when no processor reported one.
|
|
248
|
+
* @returns True for `accept`, `escrow`, `pending`, `missing` and `unverified`, and for a receipt with no decision;
|
|
249
|
+
* false otherwise.
|
|
250
|
+
*/
|
|
251
|
+
function keptDecision(body, decision) {
|
|
252
|
+
if (!decision)
|
|
253
|
+
return body instanceof SerderKERI && body.ilk === Ilks.rct;
|
|
254
|
+
switch (decision.kind) {
|
|
255
|
+
case "accept":
|
|
256
|
+
case "escrow":
|
|
257
|
+
case "pending":
|
|
258
|
+
case "missing":
|
|
259
|
+
case "unverified":
|
|
260
|
+
return true;
|
|
261
|
+
default:
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/** Whether the body's SAID matches its content. */
|
|
266
|
+
function saidVerifies(body) {
|
|
267
|
+
try {
|
|
268
|
+
return body.verify();
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Whether the frame carries any attached signature, receipt or seal-source authentication.
|
|
276
|
+
*
|
|
277
|
+
* @param frame Dispatched frame.
|
|
278
|
+
* @returns True when the normalized attachments include authentication material.
|
|
279
|
+
*/
|
|
280
|
+
function authenticated(frame) {
|
|
281
|
+
const envelope = envelopeFromFrame(frame);
|
|
282
|
+
return [
|
|
283
|
+
envelope.sigers,
|
|
284
|
+
envelope.wigers,
|
|
285
|
+
envelope.cigars,
|
|
286
|
+
envelope.trqs,
|
|
287
|
+
envelope.tsgs,
|
|
288
|
+
envelope.ssgs,
|
|
289
|
+
envelope.sscs,
|
|
290
|
+
envelope.ssts,
|
|
291
|
+
].some((material) => material.length > 0);
|
|
292
|
+
}
|