@fedify/fedify 2.4.0-dev.2253 → 2.4.0-dev.2259
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/{builder-DdUWFCwL.mjs → builder-CBNa1Uw2.mjs} +8 -2
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-CcWDD5VB.mjs → compound-proof-CMPv4UK0.mjs} +20 -3
- package/dist/{context-CtI307_A.d.ts → context-7NyiqIcg.d.ts} +111 -2
- package/dist/{context-B6X-t8gI.d.cts → context-tsYPJ2Ew.d.cts} +111 -2
- package/dist/{deno-D9uhdIuD.mjs → deno-C8XaXmPB.mjs} +1 -1
- package/dist/{docloader-fbmPhCdS.mjs → docloader-CpdFLwAg.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +76 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox-report.test.d.mts +2 -0
- package/dist/federation/inbox-report.test.mjs +475 -0
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +7 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +4 -3
- package/dist/federation/mod.d.ts +4 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +5 -5
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +4 -4
- package/dist/federation/portable-delivery.test.mjs +2 -2
- package/dist/federation/portable-gateway-keys.test.mjs +4 -4
- package/dist/federation/portable-inbox.test.mjs +67 -6
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-B858-Ylk.cjs → federation-D6giSGUT.cjs} +524 -118
- package/dist/{http-CUyBaVsQ.mjs → http-BqSbUEiQ.mjs} +141 -98
- package/dist/{http-Bp0MKAK3.cjs → http-Cki-npuA.cjs} +456 -116
- package/dist/{http-BoGE-nk7.js → http-OMtKlbx1.js} +439 -117
- package/dist/{http-DGx0KOws.d.ts → key-C1nv7_jD.d.ts} +638 -229
- package/dist/{http-BrwKINQn.d.cts → key-DYxuyd-s.d.cts} +638 -229
- package/dist/{key-BlTaKABr.mjs → key-DecAtABm.mjs} +30 -3
- package/dist/{kv-cache-Dmqd7s2a.mjs → kv-cache-CWWlMv-s.mjs} +1 -1
- package/dist/{kv-cache-BnWemxH2.cjs → kv-cache-D73yVcE5.cjs} +1 -1
- package/dist/{kv-cache-DhMzUXEE.js → kv-cache-J0v3UbUn.js} +1 -1
- package/dist/{ld-Dx8r_qJU.mjs → ld-UsN-TIPh.mjs} +40 -5
- package/dist/{metrics-DFkZkLrO.mjs → metrics-DWCn4VXX.mjs} +2 -1
- package/dist/{middleware-DC018B4u.js → middleware-BqzfIlUO.js} +524 -118
- package/dist/{middleware-B0RRI88k.mjs → middleware-CkjwiEBd.mjs} +512 -127
- package/dist/{middleware-BNhF-Ayx.mjs → middleware-DHn2q0L1.mjs} +1 -1
- package/dist/{mod-C7_2j7VT.d.cts → mod-BojP2Bw3.d.cts} +1 -1
- package/dist/{mod-Cy9VNHVw.d.ts → mod-CavhAgLw.d.cts} +5 -253
- package/dist/{mod-DoTWIc7F.d.cts → mod-CtpF2BU5.d.ts} +5 -253
- package/dist/{mod-B8MI1mpi.d.ts → mod-DEZXwV6J.d.ts} +1 -1
- package/dist/{mod-DFL6IxYQ.d.cts → mod-Dw-nPxQh.d.cts} +1 -1
- package/dist/{mod-BhTaDR5H.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +7 -7
- package/dist/mod.d.ts +7 -7
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-B61jjp5K.mjs → owner-CEBn81LD.mjs} +3 -3
- package/dist/{portable-collection-DhEA_nWT.cjs → portable-collection-DqTUBKY7.cjs} +1 -1
- package/dist/{portable-collection-BnktjQ04.js → portable-collection-ZkUNjtb7.js} +1 -1
- package/dist/{portable-collection-CyBJDEzs.mjs → portable-collection-qFSYw4TG.mjs} +2 -2
- package/dist/{portable-key-CPN0QZSA.mjs → portable-key-LlMkP-vz.mjs} +1 -1
- package/dist/{proof-CZrjvoJ3.mjs → proof-BHRf_jMG.mjs} +142 -22
- package/dist/{send-enxOnmZo.mjs → send-DjG8DDU_.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +19 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mitra-receive-interop.test.d.mts +2 -0
- package/dist/sig/mitra-receive-interop.test.mjs +260 -0
- package/dist/sig/mitra-send-interop.test.d.mts +2 -0
- package/dist/sig/mitra-send-interop.test.mjs +461 -0
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-interop.test.d.mts +2 -0
- package/dist/sig/portable-interop.test.mjs +156 -0
- package/dist/sig/portable-key.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +161 -3
- package/dist/sig/tootik-request-interop.test.d.mts +2 -0
- package/dist/sig/tootik-request-interop.test.mjs +190 -0
- package/dist/sig/tootik-send-interop.test.d.mts +2 -0
- package/dist/sig/tootik-send-interop.test.mjs +331 -0
- package/dist/sig/verification.test.d.mts +2 -0
- package/dist/sig/verification.test.mjs +310 -0
- package/dist/{temporal-CBVv0xRB.mjs → temporal-BRFH_dte.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +315 -28
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/dist/verification-C3954hQh.mjs +5 -0
- package/dist/verification-Dpfcw8ml.mjs +105 -0
- package/package.json +6 -6
|
@@ -3,28 +3,29 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { d as isPortableUri, f as isSameObjectId, i as getPortableDid, l as isPortableId, n as getCanonicalPortableId, o as hasPortableActor, r as getGatewayKeyBase, s as isCompatibleKeyId, t as getAuthenticationOrigin, u as isPortableKeyId } from "./portable-key-id-Ca30-hOa.mjs";
|
|
5
5
|
import { n as isPubliclyAddressedNode, t as isInAudience } from "./audience-CHQ-FlLD.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { a as verificationObservation, r as snapshotKey, t as observeAttempt } from "./verification-Dpfcw8ml.mjs";
|
|
7
|
+
import { n as version, t as name } from "./deno-C8XaXmPB.mjs";
|
|
8
|
+
import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-DWCn4VXX.mjs";
|
|
8
9
|
import { t as formatAcceptSignature } from "./accept-CPVqki78.mjs";
|
|
9
|
-
import { c as validateCryptoKey, n as exportJwk, s as importJwk } from "./key-
|
|
10
|
+
import { c as validateCryptoKey, n as exportJwk, s as importJwk } from "./key-DecAtABm.mjs";
|
|
10
11
|
import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-4IJqPYos.mjs";
|
|
11
|
-
import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-
|
|
12
|
-
import { a as signObject, c as verifyPortableObjectProof, i as hasProofLike, s as verifyObject, t as InvalidPortableObjectIdError, u as verifyPortableObjectProofWithRoot } from "./proof-
|
|
13
|
-
import { a as listRequestSignatures, c as selectRequestSignature, d as validateMaxSignatures, f as verifyRequest, p as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-
|
|
14
|
-
import { t as getAuthenticatedDocumentLoader } from "./docloader-
|
|
15
|
-
import { n as kvCache } from "./kv-cache-
|
|
12
|
+
import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-UsN-TIPh.mjs";
|
|
13
|
+
import { a as signObject, c as verifyPortableObjectProof, i as hasProofLike, s as verifyObject, t as InvalidPortableObjectIdError, u as verifyPortableObjectProofWithRoot } from "./proof-BHRf_jMG.mjs";
|
|
14
|
+
import { a as listRequestSignatures, c as selectRequestSignature, d as validateMaxSignatures, f as verifyRequest, p as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-BqSbUEiQ.mjs";
|
|
15
|
+
import { t as getAuthenticatedDocumentLoader } from "./docloader-CpdFLwAg.mjs";
|
|
16
|
+
import { n as kvCache } from "./kv-cache-CWWlMv-s.mjs";
|
|
16
17
|
import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-CEnNz8O7.mjs";
|
|
17
18
|
import { t as nodeInfoToJson } from "./types-DE_LV1JB.mjs";
|
|
18
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-
|
|
19
|
-
import { t as verifyPortableObject } from "./portable-collection-
|
|
20
|
-
import { a as getOrderingDestination, i as sendActivityThroughGateways, n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-
|
|
21
|
-
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-
|
|
19
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-CEBn81LD.mjs";
|
|
20
|
+
import { t as verifyPortableObject } from "./portable-collection-qFSYw4TG.mjs";
|
|
21
|
+
import { a as getOrderingDestination, i as sendActivityThroughGateways, n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-DjG8DDU_.mjs";
|
|
22
|
+
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-CBNa1Uw2.mjs";
|
|
22
23
|
import { t as CircuitBreaker } from "./circuit-breaker-XJ53md4S.mjs";
|
|
23
24
|
import { t as buildCollectionSynchronizationHeader } from "./collection-CnnP1UAv.mjs";
|
|
24
|
-
import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, s as verifyServedPortableObjects, t as containsCompoundPortableObject } from "./compound-proof-
|
|
25
|
+
import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, s as verifyServedPortableObjects, t as containsCompoundPortableObject } from "./compound-proof-CMPv4UK0.mjs";
|
|
25
26
|
import { t as KvKeyCache } from "./keycache-Da8A8mZa.mjs";
|
|
26
27
|
import { t as acceptsJsonLd } from "./negotiation-CCocWT_N.mjs";
|
|
27
|
-
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-
|
|
28
|
+
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-BRFH_dte.mjs";
|
|
28
29
|
import { t as createExponentialBackoffPolicy } from "./retry-zX5xw5e0.mjs";
|
|
29
30
|
import { t as TaskCodec } from "./codec-C6rTrpIp.mjs";
|
|
30
31
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
@@ -39,6 +40,111 @@ import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_
|
|
|
39
40
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
40
41
|
import { DataPointType, MeterProvider as MeterProvider$1, MetricReader } from "@opentelemetry/sdk-metrics";
|
|
41
42
|
import { domainToASCII } from "node:url";
|
|
43
|
+
//#region src/federation/inbox-observation.ts
|
|
44
|
+
/** Internal state owned by the ingress boundary, never serialized into queues. */
|
|
45
|
+
var InboxObservation = class {
|
|
46
|
+
inbox;
|
|
47
|
+
payload = { status: "unavailable" };
|
|
48
|
+
activity = null;
|
|
49
|
+
authentication = { status: "notDetermined" };
|
|
50
|
+
hasException = false;
|
|
51
|
+
stage = "prepare";
|
|
52
|
+
result = {
|
|
53
|
+
disposition: "rejected",
|
|
54
|
+
reason: "recipientNotFound"
|
|
55
|
+
};
|
|
56
|
+
verification = {
|
|
57
|
+
attempts: [],
|
|
58
|
+
subject: {
|
|
59
|
+
id: null,
|
|
60
|
+
pointer: ""
|
|
61
|
+
},
|
|
62
|
+
parsedObject: (object) => {
|
|
63
|
+
if (object instanceof Activity) {
|
|
64
|
+
this.activity = object;
|
|
65
|
+
this.verification.subject.id = object.id == null ? null : new URL(object.id.href);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
constructor(inbox) {
|
|
70
|
+
this.inbox = inbox;
|
|
71
|
+
}
|
|
72
|
+
/** Run an ingress operation and project telemetry; fetch owns completion. */
|
|
73
|
+
async run(operation, span) {
|
|
74
|
+
let response;
|
|
75
|
+
let outcome;
|
|
76
|
+
let threw = false;
|
|
77
|
+
let originalError;
|
|
78
|
+
try {
|
|
79
|
+
response = await operation();
|
|
80
|
+
outcome = {
|
|
81
|
+
type: "response",
|
|
82
|
+
status: response.status,
|
|
83
|
+
...this.result
|
|
84
|
+
};
|
|
85
|
+
} catch (error) {
|
|
86
|
+
threw = true;
|
|
87
|
+
this.hasException = true;
|
|
88
|
+
originalError = error;
|
|
89
|
+
outcome = {
|
|
90
|
+
type: "exception",
|
|
91
|
+
stage: this.stage,
|
|
92
|
+
error
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (span != null) this.project(span, outcome);
|
|
96
|
+
if (threw) throw originalError;
|
|
97
|
+
return response;
|
|
98
|
+
}
|
|
99
|
+
/** Complete standalone handler calls that have no enclosing fetch boundary. */
|
|
100
|
+
async runAndFinish(getContext, handler, operation) {
|
|
101
|
+
let response;
|
|
102
|
+
try {
|
|
103
|
+
response = await this.run(operation);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
await this.finish(getContext(), handler, {
|
|
106
|
+
type: "exception",
|
|
107
|
+
stage: this.stage,
|
|
108
|
+
error
|
|
109
|
+
});
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
await this.finish(getContext(), handler, {
|
|
113
|
+
type: "response",
|
|
114
|
+
status: response.status,
|
|
115
|
+
...this.result
|
|
116
|
+
});
|
|
117
|
+
return response;
|
|
118
|
+
}
|
|
119
|
+
project(span, outcome) {
|
|
120
|
+
span.setAttribute("activitypub.authentication.status", this.authentication.status);
|
|
121
|
+
if (this.authentication.status === "rejected") span.setAttribute("activitypub.verification.failure_reason", this.authentication.reason.type);
|
|
122
|
+
span.setAttribute("activitypub.inbox.disposition", outcome?.type === "exception" || this.hasException ? "exception" : this.result.disposition);
|
|
123
|
+
}
|
|
124
|
+
async finish(context, handler, outcome) {
|
|
125
|
+
if (handler == null) return;
|
|
126
|
+
const report = {
|
|
127
|
+
inbox: this.inbox,
|
|
128
|
+
payload: this.payload,
|
|
129
|
+
activity: this.activity,
|
|
130
|
+
attempts: this.verification.attempts,
|
|
131
|
+
authentication: this.authentication,
|
|
132
|
+
outcome
|
|
133
|
+
};
|
|
134
|
+
try {
|
|
135
|
+
await handler(context, report);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
try {
|
|
138
|
+
getLogger([
|
|
139
|
+
"fedify",
|
|
140
|
+
"federation",
|
|
141
|
+
"inbox"
|
|
142
|
+
]).error("An unexpected error occurred in inbox request finished handler:\n{error}", { error });
|
|
143
|
+
} catch {}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
//#endregion
|
|
42
148
|
//#region src/compat/transformers.ts
|
|
43
149
|
const logger$2 = getLogger([
|
|
44
150
|
"fedify",
|
|
@@ -1620,13 +1726,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
|
|
|
1620
1726
|
* @param parameters The parameters for handling the collection.
|
|
1621
1727
|
* @returns A promise that resolves to an HTTP response.
|
|
1622
1728
|
*/
|
|
1623
|
-
async function handleCollection(request, { name: name$
|
|
1624
|
-
const spanName = name$
|
|
1729
|
+
async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, portable, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
|
|
1730
|
+
const spanName = name$2.trim().replace(/\s+/g, "_");
|
|
1625
1731
|
tracerProvider = tracerProvider ?? trace.getTracerProvider();
|
|
1626
1732
|
const tracer = tracerProvider.getTracer(name, version);
|
|
1627
1733
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
1628
1734
|
const metricBase = {
|
|
1629
|
-
kind: getCollectionMetricKind(name$
|
|
1735
|
+
kind: getCollectionMetricKind(name$2),
|
|
1630
1736
|
page: cursor != null,
|
|
1631
1737
|
dispatcher: "built_in"
|
|
1632
1738
|
};
|
|
@@ -1672,7 +1778,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
|
|
|
1672
1778
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1673
1779
|
return await onNotFound(request);
|
|
1674
1780
|
}
|
|
1675
|
-
const items = filterCollectionItems(page.items, name$
|
|
1781
|
+
const items = filterCollectionItems(page.items, name$2, filterPredicate);
|
|
1676
1782
|
itemCount = items.length;
|
|
1677
1783
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
1678
1784
|
return items;
|
|
@@ -1714,7 +1820,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
|
|
|
1714
1820
|
} else {
|
|
1715
1821
|
const uri = new URL(portable == null ? baseUri : pageBase);
|
|
1716
1822
|
uri.searchParams.set("cursor", cursor);
|
|
1717
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$
|
|
1823
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
|
|
1718
1824
|
kind: SpanKind.SERVER,
|
|
1719
1825
|
attributes: {
|
|
1720
1826
|
"activitypub.collection.id": uri.href,
|
|
@@ -1730,7 +1836,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
|
|
|
1730
1836
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1731
1837
|
return await onNotFound(request);
|
|
1732
1838
|
}
|
|
1733
|
-
const items = filterCollectionItems(page.items, name$
|
|
1839
|
+
const items = filterCollectionItems(page.items, name$2, filterPredicate);
|
|
1734
1840
|
itemCount = items.length;
|
|
1735
1841
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
1736
1842
|
return {
|
|
@@ -2211,6 +2317,16 @@ async function handleMediaUpload(request, { identifier, context: ctx, mediaUploa
|
|
|
2211
2317
|
* @returns A promise that resolves to an HTTP response.
|
|
2212
2318
|
*/
|
|
2213
2319
|
async function handleInbox(request, options) {
|
|
2320
|
+
if (options.observation == null) {
|
|
2321
|
+
const observation = new InboxObservation({
|
|
2322
|
+
kind: options.portableInbox != null ? "portable" : options.recipient == null ? "shared" : "personal",
|
|
2323
|
+
recipient: options.recipient
|
|
2324
|
+
});
|
|
2325
|
+
return await observation.runAndFinish(() => options.context, options.inboxRequestFinishedHandler, () => handleInbox(request, {
|
|
2326
|
+
...options,
|
|
2327
|
+
observation
|
|
2328
|
+
}));
|
|
2329
|
+
}
|
|
2214
2330
|
return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("activitypub.inbox", {
|
|
2215
2331
|
kind: options.queue == null ? SpanKind.SERVER : SpanKind.PRODUCER,
|
|
2216
2332
|
attributes: { "activitypub.shared_inbox": options.recipient == null }
|
|
@@ -2219,12 +2335,14 @@ async function handleInbox(request, options) {
|
|
|
2219
2335
|
try {
|
|
2220
2336
|
return await handleInboxInternal(request, options, span);
|
|
2221
2337
|
} catch (e) {
|
|
2338
|
+
options.observation.hasException = true;
|
|
2222
2339
|
span.setStatus({
|
|
2223
2340
|
code: SpanStatusCode.ERROR,
|
|
2224
2341
|
message: String(e)
|
|
2225
2342
|
});
|
|
2226
2343
|
throw e;
|
|
2227
2344
|
} finally {
|
|
2345
|
+
options.observation.project(span);
|
|
2228
2346
|
span.end();
|
|
2229
2347
|
}
|
|
2230
2348
|
});
|
|
@@ -2239,6 +2357,8 @@ async function handleInbox(request, options) {
|
|
|
2239
2357
|
*/
|
|
2240
2358
|
async function handleInboxInternal(request, parameters, span) {
|
|
2241
2359
|
const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, publicKeyTtl, queue, actorDispatcher, inboxListeners, inboxErrorHandler, unverifiedActivityHandler, onNotFound, signatureTimeWindow, maxHttpSignatures, skipSignatureVerification, inboxChallengePolicy, meterProvider, tracerProvider, portableInbox } = parameters;
|
|
2360
|
+
const observation = parameters.observation;
|
|
2361
|
+
const signatureObservation = { [verificationObservation]: observation.verification };
|
|
2242
2362
|
const logger = getLogger([
|
|
2243
2363
|
"fedify",
|
|
2244
2364
|
"federation",
|
|
@@ -2263,6 +2383,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2263
2383
|
}
|
|
2264
2384
|
}
|
|
2265
2385
|
if (request.bodyUsed) {
|
|
2386
|
+
observation.result = {
|
|
2387
|
+
disposition: "failed",
|
|
2388
|
+
reason: "bodyUnavailable"
|
|
2389
|
+
};
|
|
2266
2390
|
logger.error("Request body has already been read.", { recipient });
|
|
2267
2391
|
span.setStatus({
|
|
2268
2392
|
code: SpanStatusCode.ERROR,
|
|
@@ -2273,6 +2397,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2273
2397
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2274
2398
|
});
|
|
2275
2399
|
} else if (request.body?.locked) {
|
|
2400
|
+
observation.result = {
|
|
2401
|
+
disposition: "failed",
|
|
2402
|
+
reason: "bodyUnavailable"
|
|
2403
|
+
};
|
|
2276
2404
|
logger.error("Request body is locked.", { recipient });
|
|
2277
2405
|
span.setStatus({
|
|
2278
2406
|
code: SpanStatusCode.ERROR,
|
|
@@ -2283,11 +2411,20 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2283
2411
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2284
2412
|
});
|
|
2285
2413
|
}
|
|
2414
|
+
observation.stage = "parse";
|
|
2415
|
+
observation.result = {
|
|
2416
|
+
disposition: "rejected",
|
|
2417
|
+
reason: "invalidJson"
|
|
2418
|
+
};
|
|
2286
2419
|
let json;
|
|
2287
2420
|
try {
|
|
2288
2421
|
json = JSON.parse(await readBoundedText(request.clone(), MAX_BODY_SIZE, request.url));
|
|
2289
2422
|
} catch (error) {
|
|
2290
2423
|
if (error instanceof BodyTooLargeError) {
|
|
2424
|
+
observation.result = {
|
|
2425
|
+
disposition: "rejected",
|
|
2426
|
+
reason: "bodyTooLarge"
|
|
2427
|
+
};
|
|
2291
2428
|
request.body?.cancel(error).catch(() => {});
|
|
2292
2429
|
span.setStatus({
|
|
2293
2430
|
code: SpanStatusCode.ERROR,
|
|
@@ -2317,6 +2454,15 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2317
2454
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2318
2455
|
});
|
|
2319
2456
|
}
|
|
2457
|
+
observation.payload = {
|
|
2458
|
+
status: "parsed",
|
|
2459
|
+
value: structuredClone(json)
|
|
2460
|
+
};
|
|
2461
|
+
observation.result = {
|
|
2462
|
+
disposition: "rejected",
|
|
2463
|
+
reason: "invalidActivity"
|
|
2464
|
+
};
|
|
2465
|
+
observation.stage = "verify";
|
|
2320
2466
|
const keyCache = new KvKeyCache(kv, kvPrefixes.publicKey, {
|
|
2321
2467
|
documentLoader: ctx.documentLoader,
|
|
2322
2468
|
contextLoader: ctx.contextLoader,
|
|
@@ -2346,6 +2492,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2346
2492
|
code: SpanStatusCode.ERROR,
|
|
2347
2493
|
message: `Failed to parse activity:\n${error}`
|
|
2348
2494
|
});
|
|
2495
|
+
observation.result = {
|
|
2496
|
+
disposition: "rejected",
|
|
2497
|
+
reason: "invalidActivity"
|
|
2498
|
+
};
|
|
2349
2499
|
return new Response("Invalid activity.", {
|
|
2350
2500
|
status: 400,
|
|
2351
2501
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
@@ -2363,11 +2513,25 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2363
2513
|
recipient,
|
|
2364
2514
|
error
|
|
2365
2515
|
});
|
|
2516
|
+
observation.result = {
|
|
2517
|
+
disposition: "rejected",
|
|
2518
|
+
reason: "invalidJsonLd"
|
|
2519
|
+
};
|
|
2366
2520
|
return new Response("Invalid JSON-LD.", {
|
|
2367
2521
|
status: 400,
|
|
2368
2522
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2369
2523
|
});
|
|
2370
2524
|
}
|
|
2525
|
+
observation.verification.attempts.push({
|
|
2526
|
+
mechanism: "linkedData",
|
|
2527
|
+
subject: {
|
|
2528
|
+
id: null,
|
|
2529
|
+
pointer: ""
|
|
2530
|
+
},
|
|
2531
|
+
checks: [],
|
|
2532
|
+
status: "error",
|
|
2533
|
+
error
|
|
2534
|
+
});
|
|
2371
2535
|
if (!canAttemptAlternateAuthAfterLdSignatureFailure) throw error;
|
|
2372
2536
|
if (!skipSignatureVerification) deferredLdSignatureError = error;
|
|
2373
2537
|
logger.debug("Failed to normalize JSON-LD for Linked Data Signatures; deferring to another authentication path only if it verifies:\n{error}", {
|
|
@@ -2379,6 +2543,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2379
2543
|
compactedJsonWithoutSig = detachSignature(compactedJson);
|
|
2380
2544
|
try {
|
|
2381
2545
|
ldSigVerified = await verifyCompactJsonLd(compactedJson, {
|
|
2546
|
+
...signatureObservation,
|
|
2382
2547
|
contextLoader: ctx.contextLoader,
|
|
2383
2548
|
documentLoader: ctx.documentLoader,
|
|
2384
2549
|
keyCache,
|
|
@@ -2392,6 +2557,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2392
2557
|
recipient,
|
|
2393
2558
|
error
|
|
2394
2559
|
});
|
|
2560
|
+
observation.result = {
|
|
2561
|
+
disposition: "rejected",
|
|
2562
|
+
reason: "invalidJsonLd"
|
|
2563
|
+
};
|
|
2395
2564
|
return new Response("Invalid JSON-LD.", {
|
|
2396
2565
|
status: 400,
|
|
2397
2566
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
@@ -2411,6 +2580,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2411
2580
|
recipient,
|
|
2412
2581
|
error: parseError
|
|
2413
2582
|
});
|
|
2583
|
+
observation.result = {
|
|
2584
|
+
disposition: "rejected",
|
|
2585
|
+
reason: "invalidJsonLd"
|
|
2586
|
+
};
|
|
2414
2587
|
return new Response("Invalid JSON-LD.", {
|
|
2415
2588
|
status: 400,
|
|
2416
2589
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
@@ -2431,7 +2604,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2431
2604
|
json
|
|
2432
2605
|
});
|
|
2433
2606
|
try {
|
|
2434
|
-
activity = await Activity.fromJsonLd(compactedJsonWithoutSig, {
|
|
2607
|
+
activity = observation.activity = await Activity.fromJsonLd(compactedJsonWithoutSig, {
|
|
2435
2608
|
...ctx,
|
|
2436
2609
|
contextLoader: getNormalizationContextLoader(ctx.contextLoader)
|
|
2437
2610
|
});
|
|
@@ -2443,6 +2616,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2443
2616
|
activityVerified = true;
|
|
2444
2617
|
if (!skipSignatureVerification && isPortableActivity(activity)) try {
|
|
2445
2618
|
proofVerified = await verifyObject(Activity, jsonWithoutSig, {
|
|
2619
|
+
...signatureObservation,
|
|
2446
2620
|
contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader),
|
|
2447
2621
|
documentLoader: ctx.documentLoader,
|
|
2448
2622
|
keyCache,
|
|
@@ -2463,6 +2637,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2463
2637
|
});
|
|
2464
2638
|
try {
|
|
2465
2639
|
activity = await verifyObject(Activity, jsonWithoutSig, {
|
|
2640
|
+
...signatureObservation,
|
|
2466
2641
|
contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader),
|
|
2467
2642
|
documentLoader: ctx.documentLoader,
|
|
2468
2643
|
keyCache,
|
|
@@ -2498,6 +2673,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2498
2673
|
code: SpanStatusCode.ERROR,
|
|
2499
2674
|
message: `Failed to parse activity:\n${error}`
|
|
2500
2675
|
});
|
|
2676
|
+
observation.result = {
|
|
2677
|
+
disposition: "rejected",
|
|
2678
|
+
reason: "invalidActivity"
|
|
2679
|
+
};
|
|
2501
2680
|
return new Response("Invalid activity.", {
|
|
2502
2681
|
status: 400,
|
|
2503
2682
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
@@ -2521,6 +2700,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2521
2700
|
if (activity == null) {
|
|
2522
2701
|
if (!skipSignatureVerification) {
|
|
2523
2702
|
const verification = await verifyRequestDetailed(request, {
|
|
2703
|
+
...signatureObservation,
|
|
2524
2704
|
contextLoader: ctx.contextLoader,
|
|
2525
2705
|
documentLoader: ctx.documentLoader,
|
|
2526
2706
|
timeWindow: signatureTimeWindow,
|
|
@@ -2531,6 +2711,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2531
2711
|
});
|
|
2532
2712
|
if (verification.verified === false) {
|
|
2533
2713
|
if (deferredLdSignatureError != null) throw deferredLdSignatureError;
|
|
2714
|
+
observation.authentication = {
|
|
2715
|
+
status: "rejected",
|
|
2716
|
+
reason: { type: "verificationFailed" }
|
|
2717
|
+
};
|
|
2718
|
+
observation.result = {
|
|
2719
|
+
disposition: "rejected",
|
|
2720
|
+
reason: "authentication"
|
|
2721
|
+
};
|
|
2534
2722
|
const reason = verification.reason;
|
|
2535
2723
|
const remoteHost = "keyId" in reason && reason.keyId != null ? getRemoteHost(reason.keyId) : void 0;
|
|
2536
2724
|
getFederationMetrics(parameters.meterProvider).recordSignatureVerificationFailure(reason.type, remoteHost);
|
|
@@ -2545,7 +2733,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2545
2733
|
});
|
|
2546
2734
|
if (unverifiedActivityHandler == null) return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
2547
2735
|
try {
|
|
2548
|
-
activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
2736
|
+
activity = observation.activity = await Activity.fromJsonLd(jsonWithoutSig, ctx);
|
|
2549
2737
|
} catch (error) {
|
|
2550
2738
|
logger.error("Failed to parse activity:\n{error}", {
|
|
2551
2739
|
recipient,
|
|
@@ -2561,6 +2749,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2561
2749
|
recipient
|
|
2562
2750
|
});
|
|
2563
2751
|
}
|
|
2752
|
+
observation.result = {
|
|
2753
|
+
disposition: "rejected",
|
|
2754
|
+
reason: "invalidActivity"
|
|
2755
|
+
};
|
|
2564
2756
|
return new Response("Invalid activity.", {
|
|
2565
2757
|
status: 400,
|
|
2566
2758
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
@@ -2583,6 +2775,11 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2583
2775
|
try {
|
|
2584
2776
|
response = await unverifiedActivityHandler(ctx, activity, reason);
|
|
2585
2777
|
} catch (error) {
|
|
2778
|
+
observation.result = {
|
|
2779
|
+
disposition: "failed",
|
|
2780
|
+
reason: "listenerError",
|
|
2781
|
+
error
|
|
2782
|
+
};
|
|
2586
2783
|
logger.error("An unexpected error occurred in unverified activity handler:\n{error}", {
|
|
2587
2784
|
error,
|
|
2588
2785
|
activity: json,
|
|
@@ -2599,7 +2796,10 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2599
2796
|
}
|
|
2600
2797
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
2601
2798
|
}
|
|
2602
|
-
if (response instanceof Response)
|
|
2799
|
+
if (response instanceof Response) {
|
|
2800
|
+
observation.result = { disposition: "customResponse" };
|
|
2801
|
+
return response;
|
|
2802
|
+
}
|
|
2603
2803
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
2604
2804
|
} else {
|
|
2605
2805
|
if (inboxChallengePolicy?.enabled && inboxChallengePolicy.requestNonce) pendingNonceLabel = verification.signatureLabel;
|
|
@@ -2609,7 +2809,7 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2609
2809
|
httpSigKey = verification.key;
|
|
2610
2810
|
}
|
|
2611
2811
|
try {
|
|
2612
|
-
activity = await Activity.fromJsonLd(jsonWithoutSig, {
|
|
2812
|
+
activity = observation.activity = await Activity.fromJsonLd(jsonWithoutSig, {
|
|
2613
2813
|
...ctx,
|
|
2614
2814
|
contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader)
|
|
2615
2815
|
});
|
|
@@ -2618,6 +2818,12 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2618
2818
|
return await respondInvalidActivity(error);
|
|
2619
2819
|
}
|
|
2620
2820
|
}
|
|
2821
|
+
observation.activity = activity;
|
|
2822
|
+
observation.stage = "policy";
|
|
2823
|
+
observation.result = {
|
|
2824
|
+
disposition: "rejected",
|
|
2825
|
+
reason: "authentication"
|
|
2826
|
+
};
|
|
2621
2827
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2622
2828
|
span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
|
|
2623
2829
|
span.addEvent("activitypub.activity.received", {
|
|
@@ -2629,6 +2835,13 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2629
2835
|
});
|
|
2630
2836
|
if (!skipSignatureVerification && !proofVerified && (isPortableActivity(activity) || isPortableActorKey(httpSigKey))) {
|
|
2631
2837
|
if (deferredLdSignatureError != null) throw deferredLdSignatureError;
|
|
2838
|
+
observation.authentication = {
|
|
2839
|
+
status: "rejected",
|
|
2840
|
+
reason: {
|
|
2841
|
+
type: "proofPolicy",
|
|
2842
|
+
policy: "portableActor"
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2632
2845
|
logger.error("The activity {activityId} of the portable actor {actorId} is not authenticated by a valid Object Integrity Proof.", {
|
|
2633
2846
|
activity: json,
|
|
2634
2847
|
recipient,
|
|
@@ -2646,20 +2859,36 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2646
2859
|
});
|
|
2647
2860
|
}
|
|
2648
2861
|
if (!skipSignatureVerification && activity.id != null && isPortableId(activity.id)) {
|
|
2649
|
-
const rejection = await
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2862
|
+
const rejection = await observeAttempt(signatureObservation, "objectIntegrity", async (verification) => {
|
|
2863
|
+
const rejection = await verifyPortableActivityId(activity.id, jsonWithoutSig, {
|
|
2864
|
+
[verificationObservation]: verification,
|
|
2865
|
+
contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader),
|
|
2866
|
+
documentLoader: ctx.documentLoader,
|
|
2867
|
+
keyCache,
|
|
2868
|
+
meterProvider,
|
|
2869
|
+
tracerProvider
|
|
2870
|
+
});
|
|
2871
|
+
if (rejection != null) verification.attempt.reason = {
|
|
2872
|
+
type: "proofPolicy",
|
|
2873
|
+
reason: rejection
|
|
2874
|
+
};
|
|
2875
|
+
return rejection;
|
|
2876
|
+
}, (value) => value == null);
|
|
2656
2877
|
if (rejection != null) {
|
|
2657
2878
|
if (deferredLdSignatureError != null) throw deferredLdSignatureError;
|
|
2879
|
+
observation.authentication = {
|
|
2880
|
+
status: "rejected",
|
|
2881
|
+
reason: {
|
|
2882
|
+
type: "proofPolicy",
|
|
2883
|
+
policy: "portableActivity",
|
|
2884
|
+
detail: rejection
|
|
2885
|
+
}
|
|
2886
|
+
};
|
|
2658
2887
|
logger.error("The portable activity {activityId} is not authenticated by an Object Integrity Proof of its own DID: {reason}", {
|
|
2659
2888
|
activity: json,
|
|
2660
2889
|
recipient,
|
|
2661
2890
|
activityId: activity.id.href,
|
|
2662
|
-
reason: rejection
|
|
2891
|
+
reason: rejection.type
|
|
2663
2892
|
});
|
|
2664
2893
|
span.setStatus({
|
|
2665
2894
|
code: SpanStatusCode.ERROR,
|
|
@@ -2673,6 +2902,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2673
2902
|
}
|
|
2674
2903
|
if (httpSigKey != null && !await doesActorOwnKey(activity, httpSigKey, ctx)) {
|
|
2675
2904
|
if (deferredLdSignatureError != null) throw deferredLdSignatureError;
|
|
2905
|
+
observation.authentication = {
|
|
2906
|
+
status: "rejected",
|
|
2907
|
+
reason: {
|
|
2908
|
+
type: "actorKeyMismatch",
|
|
2909
|
+
key: snapshotKey(httpSigKey),
|
|
2910
|
+
actorIds: activity.actorIds.map((id) => new URL(id.href))
|
|
2911
|
+
}
|
|
2912
|
+
};
|
|
2676
2913
|
getFederationMetrics(parameters.meterProvider).recordSignatureVerificationFailure("actorKeyMismatch", httpSigKey.id == null ? void 0 : getRemoteHost(httpSigKey.id));
|
|
2677
2914
|
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
|
2678
2915
|
activity: json,
|
|
@@ -2692,13 +2929,35 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2692
2929
|
if (!skipSignatureVerification) {
|
|
2693
2930
|
const compoundJson = Array.isArray(json) ? json : jsonWithoutSig;
|
|
2694
2931
|
if (inspectCompoundPortableObjectApplicability(compoundJson, INBOX_COMPOUND_PROOF_LIMITS) !== "absent") {
|
|
2695
|
-
const compoundProof = await
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2932
|
+
const compoundProof = await observeAttempt(signatureObservation, "objectIntegrity", async (verification) => {
|
|
2933
|
+
const result = await verifyCompoundPortableObjectProofs(compoundJson, INBOX_COMPOUND_PROOF_LIMITS, {
|
|
2934
|
+
[verificationObservation]: verification,
|
|
2935
|
+
documentLoader: ctx.documentLoader,
|
|
2936
|
+
keyCache,
|
|
2937
|
+
meterProvider,
|
|
2938
|
+
tracerProvider
|
|
2939
|
+
});
|
|
2940
|
+
if (result.status === "unsupported") verification.attempt.reason = {
|
|
2941
|
+
type: "proofPolicy",
|
|
2942
|
+
reason: result.reason
|
|
2943
|
+
};
|
|
2944
|
+
else if (!result.verified) {
|
|
2945
|
+
const failed = result.portableObjects.find((object) => !object.verified);
|
|
2946
|
+
verification.attempt.reason = {
|
|
2947
|
+
type: "proofPolicy",
|
|
2948
|
+
reason: failed?.verified === false ? failed.reason : { type: "invalidProof" }
|
|
2949
|
+
};
|
|
2950
|
+
}
|
|
2951
|
+
return result;
|
|
2952
|
+
}, (result) => result.status === "ok" && result.verified);
|
|
2701
2953
|
if (compoundProof.status !== "ok" || !compoundProof.verified) {
|
|
2954
|
+
observation.authentication = {
|
|
2955
|
+
status: "rejected",
|
|
2956
|
+
reason: {
|
|
2957
|
+
type: "proofPolicy",
|
|
2958
|
+
policy: "compound"
|
|
2959
|
+
}
|
|
2960
|
+
};
|
|
2702
2961
|
logger.error("Failed to verify compound portable Object Integrity Proofs.", {
|
|
2703
2962
|
recipient,
|
|
2704
2963
|
activity: json,
|
|
@@ -2717,11 +2976,20 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2717
2976
|
}
|
|
2718
2977
|
if (pendingNonceLabel != null) {
|
|
2719
2978
|
if (!await verifySignatureNonce(request, kv, kvPrefixes.acceptSignatureNonce, pendingNonceLabel)) {
|
|
2979
|
+
observation.authentication = {
|
|
2980
|
+
status: "rejected",
|
|
2981
|
+
reason: { type: "invalidNonce" }
|
|
2982
|
+
};
|
|
2720
2983
|
getFederationMetrics(parameters.meterProvider).recordSignatureVerificationFailure("invalidNonce", httpSigKey?.id == null ? void 0 : getRemoteHost(httpSigKey.id));
|
|
2721
2984
|
logger.error("Signature nonce verification failed (missing, expired, or replayed).", { recipient });
|
|
2722
2985
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
2723
2986
|
}
|
|
2724
2987
|
}
|
|
2988
|
+
observation.authentication = skipSignatureVerification ? { status: "skipped" } : {
|
|
2989
|
+
status: "verified",
|
|
2990
|
+
attempts: observation.verification.attempts.filter((attempt) => attempt.status === "verified")
|
|
2991
|
+
};
|
|
2992
|
+
observation.stage = "dispatch";
|
|
2725
2993
|
const routeResult = await routeActivity({
|
|
2726
2994
|
context: ctx,
|
|
2727
2995
|
json,
|
|
@@ -2733,7 +3001,14 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2733
3001
|
inboxListeners,
|
|
2734
3002
|
inboxContextFactory,
|
|
2735
3003
|
listenerInboxContextFactory: ldSigVerified ? inboxContextFactory[rawInboxContextFactorySymbol] : void 0,
|
|
2736
|
-
inboxErrorHandler,
|
|
3004
|
+
inboxErrorHandler: async (context, error) => {
|
|
3005
|
+
observation.result = {
|
|
3006
|
+
disposition: "failed",
|
|
3007
|
+
reason: "listenerError",
|
|
3008
|
+
error
|
|
3009
|
+
};
|
|
3010
|
+
await inboxErrorHandler?.(context, error);
|
|
3011
|
+
},
|
|
2737
3012
|
kv,
|
|
2738
3013
|
kvPrefixes,
|
|
2739
3014
|
queue,
|
|
@@ -2769,30 +3044,44 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
2769
3044
|
error
|
|
2770
3045
|
});
|
|
2771
3046
|
}
|
|
2772
|
-
if (routeResult === "alreadyProcessed")
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
})
|
|
2788
|
-
|
|
3047
|
+
if (routeResult === "alreadyProcessed") {
|
|
3048
|
+
observation.result = { disposition: "duplicate" };
|
|
3049
|
+
return new Response(`Activity <${activity.id}> has already been processed.`, {
|
|
3050
|
+
status: 202,
|
|
3051
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
3052
|
+
});
|
|
3053
|
+
} else if (routeResult === "missingActor") {
|
|
3054
|
+
observation.result = {
|
|
3055
|
+
disposition: "rejected",
|
|
3056
|
+
reason: "missingActor"
|
|
3057
|
+
};
|
|
3058
|
+
return new Response("Missing actor.", {
|
|
3059
|
+
status: 400,
|
|
3060
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
3061
|
+
});
|
|
3062
|
+
} else if (routeResult === "enqueued") {
|
|
3063
|
+
observation.result = { disposition: "enqueued" };
|
|
3064
|
+
return new Response("Activity is enqueued.", {
|
|
3065
|
+
status: 202,
|
|
3066
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
3067
|
+
});
|
|
3068
|
+
} else if (routeResult === "unsupportedActivity") {
|
|
3069
|
+
observation.result = { disposition: "unhandled" };
|
|
3070
|
+
return new Response("", {
|
|
3071
|
+
status: 202,
|
|
3072
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
3073
|
+
});
|
|
3074
|
+
} else if (routeResult === "error") return new Response("Internal server error.", {
|
|
2789
3075
|
status: 500,
|
|
2790
3076
|
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
2791
3077
|
});
|
|
2792
|
-
else
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
3078
|
+
else {
|
|
3079
|
+
observation.result = { disposition: "processed" };
|
|
3080
|
+
return new Response("", {
|
|
3081
|
+
status: 202,
|
|
3082
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
3083
|
+
});
|
|
3084
|
+
}
|
|
2796
3085
|
}
|
|
2797
3086
|
const PORTABLE_INBOX_FORWARDABLE_RESULTS = /* @__PURE__ */ new Set([
|
|
2798
3087
|
"success",
|
|
@@ -2921,8 +3210,8 @@ var CustomCollectionHandler = class {
|
|
|
2921
3210
|
* @param CollectionPage The CollectionPage constructor.
|
|
2922
3211
|
* @param filterPredicate Optional filter predicate for items.
|
|
2923
3212
|
*/
|
|
2924
|
-
constructor(name$
|
|
2925
|
-
this.name = name$
|
|
3213
|
+
constructor(name$1, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate, portable) {
|
|
3214
|
+
this.name = name$1;
|
|
2926
3215
|
this.values = values;
|
|
2927
3216
|
this.context = context;
|
|
2928
3217
|
this.callbacks = callbacks;
|
|
@@ -3458,19 +3747,19 @@ function isPortableActivity(activity) {
|
|
|
3458
3747
|
*/
|
|
3459
3748
|
async function verifyPortableActivityId(activityId, jsonLd, options) {
|
|
3460
3749
|
const expectedId = getCanonicalPortableId(activityId);
|
|
3461
|
-
if (expectedId == null) return
|
|
3750
|
+
if (expectedId == null) return { type: "invalidObjectId" };
|
|
3462
3751
|
let verification;
|
|
3463
3752
|
try {
|
|
3464
3753
|
verification = await verifyPortableObjectProofWithRoot(jsonLd, options);
|
|
3465
3754
|
} catch (error) {
|
|
3466
|
-
if (error instanceof InvalidPortableObjectIdError) return
|
|
3755
|
+
if (error instanceof InvalidPortableObjectIdError) return { type: "invalidObjectId" };
|
|
3467
3756
|
if (!isPermanentActivityParseError(error)) throw error;
|
|
3468
|
-
return "
|
|
3757
|
+
return { type: "invalidDocument" };
|
|
3469
3758
|
}
|
|
3470
3759
|
const { result, root } = verification;
|
|
3471
|
-
if (!result.verified) return result.reason
|
|
3760
|
+
if (!result.verified) return result.reason;
|
|
3472
3761
|
const rootId = root?.["@id"];
|
|
3473
|
-
if (typeof rootId !== "string" || getCanonicalPortableId(parseIri(rootId)) !== expectedId) return
|
|
3762
|
+
if (typeof rootId !== "string" || getCanonicalPortableId(parseIri(rootId)) !== expectedId) return { type: "subjectMismatch" };
|
|
3474
3763
|
return null;
|
|
3475
3764
|
}
|
|
3476
3765
|
//#endregion
|
|
@@ -5950,7 +6239,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
5950
6239
|
return await withContext({
|
|
5951
6240
|
traceId: spanCtx.traceId,
|
|
5952
6241
|
spanId: spanCtx.spanId
|
|
5953
|
-
}, async () => {
|
|
6242
|
+
}, () => this.#observeInboxFetch(metricState, async () => {
|
|
5954
6243
|
const logger = getLogger([
|
|
5955
6244
|
"fedify",
|
|
5956
6245
|
"federation",
|
|
@@ -5965,8 +6254,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
5965
6254
|
tracer,
|
|
5966
6255
|
metricState
|
|
5967
6256
|
});
|
|
6257
|
+
if (metricState.inboxCompletion != null) metricState.inboxCompletion.observation.stage = "respond";
|
|
5968
6258
|
if (metricState.endpoint !== "hashlink_media" && acceptsJsonLd(request)) response.headers.set("Vary", "Accept");
|
|
5969
6259
|
} catch (error) {
|
|
6260
|
+
metricState.inboxCompletion?.observation.project(span, {
|
|
6261
|
+
type: "exception",
|
|
6262
|
+
stage: metricState.inboxCompletion.observation.stage,
|
|
6263
|
+
error
|
|
6264
|
+
});
|
|
5970
6265
|
this.metrics.recordHttpServerRequest(request.method, metricState.endpoint ?? "error", getDurationMs(metricStart), { routeTemplate: metricState.routeTemplate });
|
|
5971
6266
|
span.setStatus({
|
|
5972
6267
|
code: SpanStatusCode.ERROR,
|
|
@@ -6005,7 +6300,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6005
6300
|
else if (response.status >= 400) logger.warn(logTpl, values);
|
|
6006
6301
|
else logger.info(logTpl, values);
|
|
6007
6302
|
return response;
|
|
6008
|
-
});
|
|
6303
|
+
}));
|
|
6009
6304
|
});
|
|
6010
6305
|
});
|
|
6011
6306
|
}
|
|
@@ -6047,8 +6342,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6047
6342
|
metricState.routeTemplate = route.template;
|
|
6048
6343
|
metricState.endpoint = getEndpointCategory(route.name);
|
|
6049
6344
|
span.updateName(`${request.method} ${route.template}`);
|
|
6050
|
-
let context = this.#createContext(request, contextData);
|
|
6051
6345
|
const routeName = route.name.replace(/:.*$/, "");
|
|
6346
|
+
let context;
|
|
6347
|
+
try {
|
|
6348
|
+
context = this.#createContext(request, contextData);
|
|
6349
|
+
} catch (error) {
|
|
6350
|
+
if (request.method !== "POST" || routeName !== "inbox" && routeName !== "sharedInbox") throw error;
|
|
6351
|
+
return await this.#reportInboxPreparationError(request, contextData, {
|
|
6352
|
+
kind: routeName === "inbox" ? "personal" : "shared",
|
|
6353
|
+
recipient: route.values.identifier ?? null
|
|
6354
|
+
}, error, span, metricState);
|
|
6355
|
+
}
|
|
6052
6356
|
switch (routeName) {
|
|
6053
6357
|
case "webfinger": return await handleWebFinger(request, {
|
|
6054
6358
|
context,
|
|
@@ -6107,6 +6411,28 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6107
6411
|
});
|
|
6108
6412
|
return response;
|
|
6109
6413
|
}
|
|
6414
|
+
if (request.method === "POST" && (routeName === "inbox" || routeName === "sharedInbox")) {
|
|
6415
|
+
const recipient = route.values.identifier ?? null;
|
|
6416
|
+
const observation = new InboxObservation({
|
|
6417
|
+
kind: routeName === "inbox" ? "personal" : "shared",
|
|
6418
|
+
recipient
|
|
6419
|
+
});
|
|
6420
|
+
this.#setInboxCompletion(metricState, observation, () => context);
|
|
6421
|
+
return await observation.run(async () => {
|
|
6422
|
+
if (routeName === "inbox") context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier: recipient }) });
|
|
6423
|
+
else if (this.sharedInboxKeyDispatcher != null) {
|
|
6424
|
+
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
6425
|
+
if (identity != null) context = this.#createContext(request, contextData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
6426
|
+
}
|
|
6427
|
+
return await this.#handleInbox(request, {
|
|
6428
|
+
recipient,
|
|
6429
|
+
context,
|
|
6430
|
+
contextData,
|
|
6431
|
+
onNotFound,
|
|
6432
|
+
observation
|
|
6433
|
+
});
|
|
6434
|
+
}, span);
|
|
6435
|
+
}
|
|
6110
6436
|
switch (routeName) {
|
|
6111
6437
|
case "actor":
|
|
6112
6438
|
case "actorAlias": {
|
|
@@ -6182,9 +6508,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6182
6508
|
onUnauthorized,
|
|
6183
6509
|
onNotFound
|
|
6184
6510
|
});
|
|
6185
|
-
|
|
6511
|
+
throw new Error("Unreachable inbox delivery.");
|
|
6186
6512
|
case "sharedInbox":
|
|
6187
|
-
if (
|
|
6513
|
+
if (this.sharedInboxKeyDispatcher != null) {
|
|
6188
6514
|
const identity = await this.sharedInboxKeyDispatcher(context);
|
|
6189
6515
|
if (identity != null) context = this.#createContext(request, contextData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
6190
6516
|
}
|
|
@@ -6477,7 +6803,49 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6477
6803
|
}
|
|
6478
6804
|
return await onNotFound(request);
|
|
6479
6805
|
}
|
|
6480
|
-
|
|
6806
|
+
#setInboxCompletion(metricState, observation, getContext) {
|
|
6807
|
+
const handler = this.inboxRequestFinishedHandler;
|
|
6808
|
+
metricState.inboxCompletion = {
|
|
6809
|
+
observation,
|
|
6810
|
+
finish: (outcome) => observation.finish(getContext(), handler, outcome)
|
|
6811
|
+
};
|
|
6812
|
+
}
|
|
6813
|
+
async #observeInboxFetch(metricState, operation) {
|
|
6814
|
+
let response;
|
|
6815
|
+
try {
|
|
6816
|
+
response = await operation();
|
|
6817
|
+
} catch (error) {
|
|
6818
|
+
const completion = metricState.inboxCompletion;
|
|
6819
|
+
if (completion != null) await completion.finish({
|
|
6820
|
+
type: "exception",
|
|
6821
|
+
stage: completion.observation.stage,
|
|
6822
|
+
error
|
|
6823
|
+
});
|
|
6824
|
+
throw error;
|
|
6825
|
+
}
|
|
6826
|
+
const completion = metricState.inboxCompletion;
|
|
6827
|
+
if (completion != null) await completion.finish({
|
|
6828
|
+
type: "response",
|
|
6829
|
+
status: response.status,
|
|
6830
|
+
...completion.observation.result
|
|
6831
|
+
});
|
|
6832
|
+
return response;
|
|
6833
|
+
}
|
|
6834
|
+
async #reportInboxPreparationError(request, contextData, inbox, error, span, metricState) {
|
|
6835
|
+
const unavailableLoader = () => Promise.reject(error);
|
|
6836
|
+
const context = new RequestContextImpl({
|
|
6837
|
+
url: new URL(request.url),
|
|
6838
|
+
request,
|
|
6839
|
+
federation: this,
|
|
6840
|
+
data: contextData,
|
|
6841
|
+
documentLoader: unavailableLoader,
|
|
6842
|
+
contextLoader: unavailableLoader
|
|
6843
|
+
});
|
|
6844
|
+
const observation = new InboxObservation(inbox);
|
|
6845
|
+
this.#setInboxCompletion(metricState, observation, () => context);
|
|
6846
|
+
return await observation.run(() => Promise.reject(error), span);
|
|
6847
|
+
}
|
|
6848
|
+
async #handleInbox(request, { recipient, context, contextData, onNotFound, portableInbox, observation }) {
|
|
6481
6849
|
if (!this.manuallyStartQueue) this._startQueueInternal(contextData);
|
|
6482
6850
|
const inboxContextFactory = context.toInboxContext.bind(context);
|
|
6483
6851
|
inboxContextFactory[rawInboxContextFactorySymbol] = context.toInboxContext.bind(context);
|
|
@@ -6501,7 +6869,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6501
6869
|
meterProvider: this.meterProvider,
|
|
6502
6870
|
tracerProvider: this.tracerProvider,
|
|
6503
6871
|
idempotencyStrategy: this.idempotencyStrategy,
|
|
6504
|
-
portableInbox
|
|
6872
|
+
portableInbox,
|
|
6873
|
+
observation
|
|
6505
6874
|
});
|
|
6506
6875
|
}
|
|
6507
6876
|
async #fetchPortableInbox(request, portable, { onNotFound, contextData, span, metricState }) {
|
|
@@ -6530,63 +6899,79 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6530
6899
|
metricState.endpoint = "inbox";
|
|
6531
6900
|
span.updateName(`${request.method} ${metricState.routeTemplate}`);
|
|
6532
6901
|
const identifier = route.values.identifier;
|
|
6533
|
-
let context
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
if (resolution.status === "rejected") {
|
|
6542
|
-
logger.debug("Not accepting a delivery to the portable inbox {inbox} on behalf of the actor {identifier}: {reason}.", {
|
|
6543
|
-
inbox: portable.canonicalId,
|
|
6544
|
-
identifier,
|
|
6545
|
-
reason: resolution.reason
|
|
6546
|
-
});
|
|
6547
|
-
return await onNotFound(request);
|
|
6902
|
+
let context;
|
|
6903
|
+
try {
|
|
6904
|
+
context = this.#createContext(request, contextData);
|
|
6905
|
+
} catch (error) {
|
|
6906
|
+
return await this.#reportInboxPreparationError(request, contextData, {
|
|
6907
|
+
kind: "portable",
|
|
6908
|
+
recipient: identifier
|
|
6909
|
+
}, error, span, metricState);
|
|
6548
6910
|
}
|
|
6549
|
-
const
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6911
|
+
const observation = new InboxObservation({
|
|
6912
|
+
kind: "portable",
|
|
6913
|
+
recipient: identifier
|
|
6914
|
+
});
|
|
6915
|
+
this.#setInboxCompletion(metricState, observation, () => context);
|
|
6916
|
+
return await observation.run(async () => {
|
|
6917
|
+
const actor = this.actorCallbacks?.dispatcher == null ? null : await this.actorCallbacks.dispatcher(context, identifier);
|
|
6918
|
+
const localOrigin = context.canonicalOrigin;
|
|
6919
|
+
const resolution = resolvePortableInboxRecipient(actor == null || actor instanceof Tombstone ? null : actor, {
|
|
6920
|
+
authority: portable.portableRequest.authority,
|
|
6921
|
+
canonicalInboxId: portable.canonicalId,
|
|
6922
|
+
localOrigin
|
|
6923
|
+
});
|
|
6924
|
+
if (resolution.status === "rejected") {
|
|
6925
|
+
logger.debug("Not accepting a delivery to the portable inbox {inbox} on behalf of the actor {identifier}: {reason}.", {
|
|
6926
|
+
inbox: portable.canonicalId,
|
|
6927
|
+
identifier,
|
|
6928
|
+
reason: resolution.reason
|
|
6929
|
+
});
|
|
6930
|
+
return await onNotFound(request);
|
|
6931
|
+
}
|
|
6932
|
+
const { recipient } = resolution;
|
|
6933
|
+
if (this.actorCallbacks?.keyPairsDispatcher != null) context = this.#createContext(request, contextData, { documentLoader: await context.getDocumentLoader({ identifier }) });
|
|
6934
|
+
const excludedOrigins = [localOrigin, new URL(request.url).origin];
|
|
6935
|
+
return await this.#handleInbox(request, {
|
|
6936
|
+
recipient: identifier,
|
|
6937
|
+
observation,
|
|
6938
|
+
context,
|
|
6939
|
+
contextData,
|
|
6940
|
+
onNotFound,
|
|
6941
|
+
portableInbox: {
|
|
6942
|
+
recipient,
|
|
6943
|
+
forward: async (activity, activityId, activityType, signatures) => {
|
|
6944
|
+
if (this.portableInboxForwarding.maxTargets < 1) return;
|
|
6945
|
+
if (this.kv.cas == null) {
|
|
6946
|
+
if (!this.#portableInboxForwardingWarned) {
|
|
6947
|
+
this.#portableInboxForwardingWarned = true;
|
|
6948
|
+
logger.warn("Activities delivered to FEP-ef61 portable inboxes are not forwarded to the other gateways, as the key–value store does not support compare-and-swap (KvStore.cas()), which is needed to forward each activity at most once.");
|
|
6949
|
+
}
|
|
6950
|
+
return;
|
|
6565
6951
|
}
|
|
6566
|
-
|
|
6952
|
+
await forwardPortableInboxActivity({
|
|
6953
|
+
recipient,
|
|
6954
|
+
activity,
|
|
6955
|
+
activityId,
|
|
6956
|
+
activityType,
|
|
6957
|
+
excludedOrigins,
|
|
6958
|
+
baseUrl: context.origin,
|
|
6959
|
+
kv: this.kv,
|
|
6960
|
+
kvPrefix: this.kvPrefixes.portableInboxForwarding,
|
|
6961
|
+
outboxQueue: this.outboxQueue,
|
|
6962
|
+
startQueue: this.manuallyStartQueue ? void 0 : () => this._startQueueInternal(contextData),
|
|
6963
|
+
allowPrivateAddress: this.allowPrivateAddress,
|
|
6964
|
+
getKeys: () => this.#getPortableGatewayKeyPairs(context, identifier, recipient),
|
|
6965
|
+
specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, this.firstKnock, { specTtl: this.httpMessageSignaturesSpecTtl }),
|
|
6966
|
+
signatures,
|
|
6967
|
+
options: this.portableInboxForwarding,
|
|
6968
|
+
meterProvider: this.meterProvider,
|
|
6969
|
+
tracerProvider: this.tracerProvider
|
|
6970
|
+
});
|
|
6567
6971
|
}
|
|
6568
|
-
await forwardPortableInboxActivity({
|
|
6569
|
-
recipient,
|
|
6570
|
-
activity,
|
|
6571
|
-
activityId,
|
|
6572
|
-
activityType,
|
|
6573
|
-
excludedOrigins,
|
|
6574
|
-
baseUrl: context.origin,
|
|
6575
|
-
kv: this.kv,
|
|
6576
|
-
kvPrefix: this.kvPrefixes.portableInboxForwarding,
|
|
6577
|
-
outboxQueue: this.outboxQueue,
|
|
6578
|
-
startQueue: this.manuallyStartQueue ? void 0 : () => this._startQueueInternal(contextData),
|
|
6579
|
-
allowPrivateAddress: this.allowPrivateAddress,
|
|
6580
|
-
getKeys: () => this.#getPortableGatewayKeyPairs(context, identifier, recipient),
|
|
6581
|
-
specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, this.firstKnock, { specTtl: this.httpMessageSignaturesSpecTtl }),
|
|
6582
|
-
signatures,
|
|
6583
|
-
options: this.portableInboxForwarding,
|
|
6584
|
-
meterProvider: this.meterProvider,
|
|
6585
|
-
tracerProvider: this.tracerProvider
|
|
6586
|
-
});
|
|
6587
6972
|
}
|
|
6588
|
-
}
|
|
6589
|
-
});
|
|
6973
|
+
});
|
|
6974
|
+
}, span);
|
|
6590
6975
|
}
|
|
6591
6976
|
/**
|
|
6592
6977
|
* Gets this server's gateway key pairs for the portable actor that owns
|