@fedify/fedify 2.3.0-dev.1114 → 2.3.0-dev.1131
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-YlEusQth.mjs → builder-DckAhD27.mjs} +2 -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/{context-cSUMk2da.d.ts → context-Cq18Gplu.d.ts} +3 -208
- package/dist/{context-Ch-ZLyTQ.d.cts → context-tc6VOOOL.d.cts} +3 -208
- package/dist/{deno-CF3jMgip.mjs → deno--CS-SBS9.mjs} +1 -1
- package/dist/{docloader-BENj6vQ4.mjs → docloader-k6huZLQL.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.d.mts +2 -0
- package/dist/federation/metrics.test.mjs +335 -0
- package/dist/federation/middleware.test.mjs +444 -6
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -2
- package/dist/federation/mod.d.ts +3 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-CKCgOPkX.cjs → http-CJfvRL7D.cjs} +352 -22
- package/dist/{http-BmOZYc-8.mjs → http-IywnQdiX.mjs} +7 -5
- package/dist/{http-D6LP89UO.d.ts → http-VyDTd4G3.d.cts} +8 -1
- package/dist/{http-CpzZ9zsb.js → http-cqujdCRz.js} +323 -23
- package/dist/{http-D6aw3j2U.d.cts → http-lf8Hsd91.d.ts} +8 -1
- package/dist/{key-B4I8H5Lc.mjs → key-Df3tMleh.mjs} +42 -17
- package/dist/{kv-cache-DY-XWOqM.cjs → kv-cache-L0SMQkcd.cjs} +19 -2
- package/dist/{kv-cache-Wc5ezcVW.js → kv-cache-pEejzYq4.js} +19 -2
- package/dist/{kv-cache-DihufyAQ.mjs → kv-cache-q9Ec2ryS.mjs} +19 -1
- package/dist/{ld-B5D5THhl.mjs → ld-BGwiJpl3.mjs} +3 -3
- package/dist/{metrics-ek3ilf6c.mjs → metrics-BTOMkW8C.mjs} +280 -5
- package/dist/{middleware-EqTYPG4F.cjs → middleware-B2rtdpFV.cjs} +75 -28
- package/dist/{middleware-DlcecZMq.mjs → middleware-BB0IbDow.mjs} +84 -37
- package/dist/{middleware-EI7OU6BR.mjs → middleware-Dnql59Y8.mjs} +1 -1
- package/dist/{middleware-CuZbBw-N.js → middleware-DtOddSVg.js} +75 -28
- package/dist/{mod-BDhgfjP7.d.cts → mod-B0hW12_O.d.cts} +1 -1
- package/dist/{mod-B-Lin9Sy.d.ts → mod-COIAjwRS.d.ts} +1 -1
- package/dist/{mod-C6E8rkcz.d.ts → mod-CajNYYkt.d.ts} +1 -1
- package/dist/{mod-DLrRb0dx.d.ts → mod-DFvNJcNb.d.ts} +54 -3
- package/dist/{mod-P9tE2WmM.d.cts → mod-DnzgcPcy.d.cts} +1 -1
- package/dist/{mod-BR_BB0bh.d.cts → mod-yvIXFAEi.d.cts} +54 -3
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +6 -5
- package/dist/mod.d.ts +6 -5
- package/dist/mod.js +4 -4
- package/dist/mq-D-nlpY04.d.ts +208 -0
- package/dist/mq-D8uSFzxe.d.cts +208 -0
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-DO810N24.mjs → owner-CIt4hvmM.mjs} +2 -2
- package/dist/{proof-DIoqrKnX.cjs → proof-B1_u25UV.cjs} +1 -1
- package/dist/{proof-BgfyWv7b.mjs → proof-BYlrRSmZ.mjs} +3 -3
- package/dist/{proof-Vd8-1EWh.js → proof-DMGIjHYH.js} +1 -1
- package/dist/{send-CAYXdUTk.mjs → send-DJFpze7B.mjs} +3 -3
- package/dist/sig/http.test.mjs +6 -2
- package/dist/sig/key.test.mjs +99 -2
- package/dist/sig/ld.test.mjs +2 -2
- 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/proof.test.mjs +1 -1
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +67 -2
- 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/package.json +6 -6
|
@@ -2,25 +2,25 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { n as RouterError } from "./router-BT_F5748.mjs";
|
|
5
|
-
import { n as version, t as name } from "./deno-
|
|
6
|
-
import { i as
|
|
5
|
+
import { n as version, t as name } from "./deno--CS-SBS9.mjs";
|
|
6
|
+
import { a as instrumentDocumentLoader, d as recordInboxActivity, i as getRemoteHost, m as recordOutboxEnqueue, n as getDurationMs, o as isAbortError, p as recordOutboxActivity, r as getFederationMetrics, u as recordFanoutRecipients } from "./metrics-BTOMkW8C.mjs";
|
|
7
7
|
import { t as formatAcceptSignature } from "./accept-CgDcxvjV.mjs";
|
|
8
|
-
import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-
|
|
9
|
-
import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-
|
|
10
|
-
import { t as getAuthenticatedDocumentLoader } from "./docloader-
|
|
11
|
-
import { n as kvCache } from "./kv-cache-
|
|
12
|
-
import { a as signJsonLd, i as hasSignatureLike, o as verifyJsonLd, r as detachSignature } from "./ld-
|
|
13
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-
|
|
8
|
+
import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-Df3tMleh.mjs";
|
|
9
|
+
import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-IywnQdiX.mjs";
|
|
10
|
+
import { t as getAuthenticatedDocumentLoader } from "./docloader-k6huZLQL.mjs";
|
|
11
|
+
import { n as kvCache } from "./kv-cache-q9Ec2ryS.mjs";
|
|
12
|
+
import { a as signJsonLd, i as hasSignatureLike, o as verifyJsonLd, r as detachSignature } from "./ld-BGwiJpl3.mjs";
|
|
13
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-CIt4hvmM.mjs";
|
|
14
14
|
import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-BNL8AC14.mjs";
|
|
15
|
-
import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-
|
|
15
|
+
import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-BYlrRSmZ.mjs";
|
|
16
16
|
import { t as getNodeInfo } from "./client-Bneh_DYR.mjs";
|
|
17
17
|
import { t as nodeInfoToJson } from "./types-D09GN0uZ.mjs";
|
|
18
|
-
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-
|
|
18
|
+
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-DckAhD27.mjs";
|
|
19
19
|
import { t as buildCollectionSynchronizationHeader } from "./collection-Cc3DVAhE.mjs";
|
|
20
20
|
import { t as KvKeyCache } from "./keycache-BeU0LCII.mjs";
|
|
21
21
|
import { t as acceptsJsonLd } from "./negotiation-DDstyBvc.mjs";
|
|
22
22
|
import { t as createExponentialBackoffPolicy } from "./retry-_VvV0h9f.mjs";
|
|
23
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-
|
|
23
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-DJFpze7B.mjs";
|
|
24
24
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
25
25
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
26
26
|
import { lookupWebFinger } from "@fedify/webfinger";
|
|
@@ -192,6 +192,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
192
192
|
code: SpanStatusCode.UNSET,
|
|
193
193
|
message: `Activity ${activity.id?.href} has already been processed.`
|
|
194
194
|
});
|
|
195
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
195
196
|
return "alreadyProcessed";
|
|
196
197
|
}
|
|
197
198
|
}
|
|
@@ -201,6 +202,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
201
202
|
code: SpanStatusCode.ERROR,
|
|
202
203
|
message: "Missing actor."
|
|
203
204
|
});
|
|
205
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
204
206
|
return "missingActor";
|
|
205
207
|
}
|
|
206
208
|
span.setAttribute("activitypub.actor.id", activity.actorId.href);
|
|
@@ -236,6 +238,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
236
238
|
queue,
|
|
237
239
|
activityType: getTypeId(activity).href
|
|
238
240
|
}, 0);
|
|
241
|
+
recordInboxActivity(meterProvider, "queued", getTypeId(activity).href);
|
|
239
242
|
logger.info("Activity {activityId} is enqueued.", {
|
|
240
243
|
activityId: activity.id?.href,
|
|
241
244
|
activity: json,
|
|
@@ -255,6 +258,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
255
258
|
code: SpanStatusCode.UNSET,
|
|
256
259
|
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
257
260
|
});
|
|
261
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
258
262
|
span.end();
|
|
259
263
|
return "unsupportedActivity";
|
|
260
264
|
}
|
|
@@ -264,7 +268,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
264
268
|
const activityType = getTypeId(activity).href;
|
|
265
269
|
const started = performance.now();
|
|
266
270
|
try {
|
|
267
|
-
await listener(inboxContextFactory(recipient, json, activity
|
|
271
|
+
await listener(inboxContextFactory(recipient, json, activity.id?.href, activityType), activity);
|
|
268
272
|
} finally {
|
|
269
273
|
getFederationMetrics(meterProvider).recordInboxProcessingDuration(activityType, getDurationMs(started));
|
|
270
274
|
}
|
|
@@ -289,9 +293,11 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
289
293
|
code: SpanStatusCode.ERROR,
|
|
290
294
|
message: String(error)
|
|
291
295
|
});
|
|
296
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
292
297
|
span.end();
|
|
293
298
|
return "error";
|
|
294
299
|
}
|
|
300
|
+
recordInboxActivity(meterProvider, "processed", getTypeId(activity).href);
|
|
295
301
|
if (cacheKey != null) await kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
296
302
|
logger.info("Activity {activityId} has been processed.", {
|
|
297
303
|
activityId: activity.id?.href,
|
|
@@ -1809,23 +1815,50 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1809
1815
|
}
|
|
1810
1816
|
const { allowPrivateAddress, userAgent } = options;
|
|
1811
1817
|
this.allowPrivateAddress = allowPrivateAddress ?? false;
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1818
|
+
const userDocumentLoaderFactory = options.documentLoaderFactory;
|
|
1819
|
+
const userContextLoaderFactory = options.contextLoaderFactory;
|
|
1820
|
+
const userAuthFactory = options.authenticatedDocumentLoaderFactory;
|
|
1821
|
+
const builtinDocumentLoaderFactory = (opts) => kvCache({
|
|
1822
|
+
loader: getDocumentLoader({
|
|
1823
|
+
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
1824
|
+
userAgent: opts?.userAgent ?? userAgent
|
|
1825
|
+
}),
|
|
1826
|
+
kv: options.kv,
|
|
1827
|
+
prefix: this.kvPrefixes.remoteDocument,
|
|
1828
|
+
meterProvider: this._meterProvider,
|
|
1829
|
+
kind: "object"
|
|
1830
|
+
});
|
|
1831
|
+
const builtinContextLoaderFactory = (opts) => kvCache({
|
|
1832
|
+
loader: getDocumentLoader({
|
|
1833
|
+
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
1834
|
+
userAgent: opts?.userAgent ?? userAgent
|
|
1835
|
+
}),
|
|
1836
|
+
kv: options.kv,
|
|
1837
|
+
prefix: this.kvPrefixes.remoteDocument,
|
|
1838
|
+
meterProvider: this._meterProvider,
|
|
1839
|
+
kind: "context"
|
|
1840
|
+
});
|
|
1841
|
+
this.documentLoaderFactory = (opts) => instrumentDocumentLoader((userDocumentLoaderFactory ?? builtinDocumentLoaderFactory)(opts), {
|
|
1842
|
+
meterProvider: this._meterProvider,
|
|
1843
|
+
kind: "object",
|
|
1844
|
+
cacheEnabled: userDocumentLoaderFactory == null ? true : void 0
|
|
1845
|
+
});
|
|
1846
|
+
const resolvedContextLoaderFactory = userContextLoaderFactory ?? userDocumentLoaderFactory ?? builtinContextLoaderFactory;
|
|
1847
|
+
this.contextLoaderFactory = (opts) => instrumentDocumentLoader(resolvedContextLoaderFactory(opts), {
|
|
1848
|
+
meterProvider: this._meterProvider,
|
|
1849
|
+
kind: "context",
|
|
1850
|
+
cacheEnabled: userContextLoaderFactory == null && userDocumentLoaderFactory == null ? true : void 0
|
|
1851
|
+
});
|
|
1852
|
+
this.authenticatedDocumentLoaderFactory = (identity, factoryOpts) => instrumentDocumentLoader(userAuthFactory != null ? userAuthFactory(identity, factoryOpts) : getAuthenticatedDocumentLoader(identity, {
|
|
1853
|
+
allowPrivateAddress: factoryOpts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
1854
|
+
userAgent: factoryOpts?.userAgent ?? userAgent,
|
|
1826
1855
|
specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, options.firstKnock),
|
|
1827
1856
|
tracerProvider: this.tracerProvider
|
|
1828
|
-
})
|
|
1857
|
+
}), {
|
|
1858
|
+
meterProvider: this._meterProvider,
|
|
1859
|
+
kind: "object",
|
|
1860
|
+
cacheEnabled: userAuthFactory == null ? false : void 0
|
|
1861
|
+
});
|
|
1829
1862
|
this.userAgent = userAgent;
|
|
1830
1863
|
this.onOutboxError = options.onOutboxError;
|
|
1831
1864
|
this.permanentFailureStatusCodes = options.permanentFailureStatusCodes ?? [404, 410];
|
|
@@ -2135,6 +2168,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2135
2168
|
});
|
|
2136
2169
|
}
|
|
2137
2170
|
}
|
|
2171
|
+
recordOutboxActivity(this.meterProvider, "abandoned", message.activityType);
|
|
2138
2172
|
return;
|
|
2139
2173
|
}
|
|
2140
2174
|
if (this.outboxQueue?.nativeRetrial) {
|
|
@@ -2165,11 +2199,15 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2165
2199
|
queue: outboxQueue,
|
|
2166
2200
|
activityType: retryMessage.activityType
|
|
2167
2201
|
}, retryMessage.attempt);
|
|
2202
|
+
recordOutboxActivity(this.meterProvider, "retried", retryMessage.activityType);
|
|
2168
2203
|
}
|
|
2169
|
-
} else
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2204
|
+
} else {
|
|
2205
|
+
logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
2206
|
+
...logData,
|
|
2207
|
+
error
|
|
2208
|
+
});
|
|
2209
|
+
recordOutboxActivity(this.meterProvider, "abandoned", message.activityType);
|
|
2210
|
+
}
|
|
2173
2211
|
return;
|
|
2174
2212
|
}
|
|
2175
2213
|
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
@@ -2204,6 +2242,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2204
2242
|
activity: message.activity,
|
|
2205
2243
|
recipient: message.identifier
|
|
2206
2244
|
});
|
|
2245
|
+
recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
2207
2246
|
return;
|
|
2208
2247
|
}
|
|
2209
2248
|
}
|
|
@@ -2220,6 +2259,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2220
2259
|
code: SpanStatusCode.ERROR,
|
|
2221
2260
|
message: `Unsupported activity type: ${activityType}`
|
|
2222
2261
|
});
|
|
2262
|
+
recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
2223
2263
|
span.end();
|
|
2224
2264
|
return;
|
|
2225
2265
|
}
|
|
@@ -2232,6 +2272,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2232
2272
|
} finally {
|
|
2233
2273
|
getFederationMetrics(this.meterProvider).recordInboxProcessingDuration(activityType, getDurationMs(started));
|
|
2234
2274
|
}
|
|
2275
|
+
recordInboxActivity(this.meterProvider, "processed", activityType);
|
|
2235
2276
|
} catch (error) {
|
|
2236
2277
|
try {
|
|
2237
2278
|
await this.inboxErrorHandler?.(context, error);
|
|
@@ -2282,13 +2323,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2282
2323
|
queue: inboxQueue,
|
|
2283
2324
|
activityType
|
|
2284
2325
|
}, retryMessage.attempt);
|
|
2326
|
+
recordInboxActivity(this.meterProvider, "retried", activityType);
|
|
2285
2327
|
}
|
|
2286
|
-
} else
|
|
2287
|
-
error,
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2328
|
+
} else {
|
|
2329
|
+
logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
2330
|
+
error,
|
|
2331
|
+
activityId: activity.id?.href,
|
|
2332
|
+
activity: message.activity,
|
|
2333
|
+
recipient: message.identifier
|
|
2334
|
+
});
|
|
2335
|
+
recordInboxActivity(this.meterProvider, "abandoned", activityType);
|
|
2336
|
+
}
|
|
2292
2337
|
span.setStatus({
|
|
2293
2338
|
code: SpanStatusCode.ERROR,
|
|
2294
2339
|
message: String(error)
|
|
@@ -3128,6 +3173,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3128
3173
|
contextLoader: options.contextLoader ?? this.contextLoader,
|
|
3129
3174
|
userAgent: options.userAgent ?? this.federation.userAgent,
|
|
3130
3175
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
3176
|
+
meterProvider: options.meterProvider ?? this.meterProvider,
|
|
3131
3177
|
allowPrivateAddress: this.federation.allowPrivateAddress
|
|
3132
3178
|
});
|
|
3133
3179
|
}
|
|
@@ -3315,6 +3361,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3315
3361
|
queue: this.federation.fanoutQueue,
|
|
3316
3362
|
activityType: message.activityType
|
|
3317
3363
|
}, 0);
|
|
3364
|
+
recordFanoutRecipients(this.federation.meterProvider, globalThis.Object.keys(message.inboxes).length, message.activityType);
|
|
3318
3365
|
return true;
|
|
3319
3366
|
}
|
|
3320
3367
|
async *getFollowers(identifier) {
|
|
@@ -2,10 +2,10 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
import { t as __exportAll } from "./chunk-CRNNMoPX.js";
|
|
4
4
|
import { r as getDefaultActivityTransformers } from "./transformers-BGMIq1cs.js";
|
|
5
|
-
import { C as
|
|
6
|
-
import { c as getKeyOwner, d as detachSignature, f as hasSignatureLike, i as verifyObject, m as verifyJsonLd, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, p as signJsonLd, r as signObject, s as doesActorOwnKey } from "./proof-
|
|
5
|
+
import { C as formatAcceptSignature, D as name, O as version, S as recordOutboxEnqueue, a as verifyRequestDetailed, b as recordInboxActivity, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, x as recordOutboxActivity, y as recordFanoutRecipients } from "./http-cqujdCRz.js";
|
|
6
|
+
import { c as getKeyOwner, d as detachSignature, f as hasSignatureLike, i as verifyObject, m as verifyJsonLd, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, p as signJsonLd, r as signObject, s as doesActorOwnKey } from "./proof-DMGIjHYH.js";
|
|
7
7
|
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-CAY3OdLq.js";
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-pEejzYq4.js";
|
|
9
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
10
10
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
11
11
|
import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
|
|
@@ -817,6 +817,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
817
817
|
code: SpanStatusCode.UNSET,
|
|
818
818
|
message: `Activity ${activity.id?.href} has already been processed.`
|
|
819
819
|
});
|
|
820
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
820
821
|
return "alreadyProcessed";
|
|
821
822
|
}
|
|
822
823
|
}
|
|
@@ -826,6 +827,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
826
827
|
code: SpanStatusCode.ERROR,
|
|
827
828
|
message: "Missing actor."
|
|
828
829
|
});
|
|
830
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
829
831
|
return "missingActor";
|
|
830
832
|
}
|
|
831
833
|
span.setAttribute("activitypub.actor.id", activity.actorId.href);
|
|
@@ -861,6 +863,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
861
863
|
queue,
|
|
862
864
|
activityType: getTypeId(activity).href
|
|
863
865
|
}, 0);
|
|
866
|
+
recordInboxActivity(meterProvider, "queued", getTypeId(activity).href);
|
|
864
867
|
logger.info("Activity {activityId} is enqueued.", {
|
|
865
868
|
activityId: activity.id?.href,
|
|
866
869
|
activity: json,
|
|
@@ -880,6 +883,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
880
883
|
code: SpanStatusCode.UNSET,
|
|
881
884
|
message: `Unsupported activity type: ${getTypeId(activity).href}`
|
|
882
885
|
});
|
|
886
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
883
887
|
span.end();
|
|
884
888
|
return "unsupportedActivity";
|
|
885
889
|
}
|
|
@@ -889,7 +893,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
889
893
|
const activityType = getTypeId(activity).href;
|
|
890
894
|
const started = performance.now();
|
|
891
895
|
try {
|
|
892
|
-
await listener(inboxContextFactory(recipient, json, activity
|
|
896
|
+
await listener(inboxContextFactory(recipient, json, activity.id?.href, activityType), activity);
|
|
893
897
|
} finally {
|
|
894
898
|
getFederationMetrics(meterProvider).recordInboxProcessingDuration(activityType, getDurationMs(started));
|
|
895
899
|
}
|
|
@@ -914,9 +918,11 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
914
918
|
code: SpanStatusCode.ERROR,
|
|
915
919
|
message: String(error)
|
|
916
920
|
});
|
|
921
|
+
recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
|
|
917
922
|
span.end();
|
|
918
923
|
return "error";
|
|
919
924
|
}
|
|
925
|
+
recordInboxActivity(meterProvider, "processed", getTypeId(activity).href);
|
|
920
926
|
if (cacheKey != null) await kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
|
|
921
927
|
logger.info("Activity {activityId} has been processed.", {
|
|
922
928
|
activityId: activity.id?.href,
|
|
@@ -2907,23 +2913,50 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2907
2913
|
}
|
|
2908
2914
|
const { allowPrivateAddress, userAgent } = options;
|
|
2909
2915
|
this.allowPrivateAddress = allowPrivateAddress ?? false;
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2916
|
+
const userDocumentLoaderFactory = options.documentLoaderFactory;
|
|
2917
|
+
const userContextLoaderFactory = options.contextLoaderFactory;
|
|
2918
|
+
const userAuthFactory = options.authenticatedDocumentLoaderFactory;
|
|
2919
|
+
const builtinDocumentLoaderFactory = (opts) => kvCache({
|
|
2920
|
+
loader: getDocumentLoader({
|
|
2921
|
+
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
2922
|
+
userAgent: opts?.userAgent ?? userAgent
|
|
2923
|
+
}),
|
|
2924
|
+
kv: options.kv,
|
|
2925
|
+
prefix: this.kvPrefixes.remoteDocument,
|
|
2926
|
+
meterProvider: this._meterProvider,
|
|
2927
|
+
kind: "object"
|
|
2928
|
+
});
|
|
2929
|
+
const builtinContextLoaderFactory = (opts) => kvCache({
|
|
2930
|
+
loader: getDocumentLoader({
|
|
2931
|
+
allowPrivateAddress: opts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
2932
|
+
userAgent: opts?.userAgent ?? userAgent
|
|
2933
|
+
}),
|
|
2934
|
+
kv: options.kv,
|
|
2935
|
+
prefix: this.kvPrefixes.remoteDocument,
|
|
2936
|
+
meterProvider: this._meterProvider,
|
|
2937
|
+
kind: "context"
|
|
2938
|
+
});
|
|
2939
|
+
this.documentLoaderFactory = (opts) => instrumentDocumentLoader((userDocumentLoaderFactory ?? builtinDocumentLoaderFactory)(opts), {
|
|
2940
|
+
meterProvider: this._meterProvider,
|
|
2941
|
+
kind: "object",
|
|
2942
|
+
cacheEnabled: userDocumentLoaderFactory == null ? true : void 0
|
|
2943
|
+
});
|
|
2944
|
+
const resolvedContextLoaderFactory = userContextLoaderFactory ?? userDocumentLoaderFactory ?? builtinContextLoaderFactory;
|
|
2945
|
+
this.contextLoaderFactory = (opts) => instrumentDocumentLoader(resolvedContextLoaderFactory(opts), {
|
|
2946
|
+
meterProvider: this._meterProvider,
|
|
2947
|
+
kind: "context",
|
|
2948
|
+
cacheEnabled: userContextLoaderFactory == null && userDocumentLoaderFactory == null ? true : void 0
|
|
2919
2949
|
});
|
|
2920
|
-
this.
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
userAgent,
|
|
2950
|
+
this.authenticatedDocumentLoaderFactory = (identity, factoryOpts) => instrumentDocumentLoader(userAuthFactory != null ? userAuthFactory(identity, factoryOpts) : getAuthenticatedDocumentLoader(identity, {
|
|
2951
|
+
allowPrivateAddress: factoryOpts?.allowPrivateAddress ?? allowPrivateAddress,
|
|
2952
|
+
userAgent: factoryOpts?.userAgent ?? userAgent,
|
|
2924
2953
|
specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, options.firstKnock),
|
|
2925
2954
|
tracerProvider: this.tracerProvider
|
|
2926
|
-
})
|
|
2955
|
+
}), {
|
|
2956
|
+
meterProvider: this._meterProvider,
|
|
2957
|
+
kind: "object",
|
|
2958
|
+
cacheEnabled: userAuthFactory == null ? false : void 0
|
|
2959
|
+
});
|
|
2927
2960
|
this.userAgent = userAgent;
|
|
2928
2961
|
this.onOutboxError = options.onOutboxError;
|
|
2929
2962
|
this.permanentFailureStatusCodes = options.permanentFailureStatusCodes ?? [404, 410];
|
|
@@ -3233,6 +3266,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3233
3266
|
});
|
|
3234
3267
|
}
|
|
3235
3268
|
}
|
|
3269
|
+
recordOutboxActivity(this.meterProvider, "abandoned", message.activityType);
|
|
3236
3270
|
return;
|
|
3237
3271
|
}
|
|
3238
3272
|
if (this.outboxQueue?.nativeRetrial) {
|
|
@@ -3263,11 +3297,15 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3263
3297
|
queue: outboxQueue,
|
|
3264
3298
|
activityType: retryMessage.activityType
|
|
3265
3299
|
}, retryMessage.attempt);
|
|
3300
|
+
recordOutboxActivity(this.meterProvider, "retried", retryMessage.activityType);
|
|
3266
3301
|
}
|
|
3267
|
-
} else
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3302
|
+
} else {
|
|
3303
|
+
logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
3304
|
+
...logData,
|
|
3305
|
+
error
|
|
3306
|
+
});
|
|
3307
|
+
recordOutboxActivity(this.meterProvider, "abandoned", message.activityType);
|
|
3308
|
+
}
|
|
3271
3309
|
return;
|
|
3272
3310
|
}
|
|
3273
3311
|
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
@@ -3302,6 +3340,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3302
3340
|
activity: message.activity,
|
|
3303
3341
|
recipient: message.identifier
|
|
3304
3342
|
});
|
|
3343
|
+
recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
3305
3344
|
return;
|
|
3306
3345
|
}
|
|
3307
3346
|
}
|
|
@@ -3318,6 +3357,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3318
3357
|
code: SpanStatusCode.ERROR,
|
|
3319
3358
|
message: `Unsupported activity type: ${activityType}`
|
|
3320
3359
|
});
|
|
3360
|
+
recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
3321
3361
|
span.end();
|
|
3322
3362
|
return;
|
|
3323
3363
|
}
|
|
@@ -3330,6 +3370,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3330
3370
|
} finally {
|
|
3331
3371
|
getFederationMetrics(this.meterProvider).recordInboxProcessingDuration(activityType, getDurationMs(started));
|
|
3332
3372
|
}
|
|
3373
|
+
recordInboxActivity(this.meterProvider, "processed", activityType);
|
|
3333
3374
|
} catch (error) {
|
|
3334
3375
|
try {
|
|
3335
3376
|
await this.inboxErrorHandler?.(context, error);
|
|
@@ -3380,13 +3421,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3380
3421
|
queue: inboxQueue,
|
|
3381
3422
|
activityType
|
|
3382
3423
|
}, retryMessage.attempt);
|
|
3424
|
+
recordInboxActivity(this.meterProvider, "retried", activityType);
|
|
3383
3425
|
}
|
|
3384
|
-
} else
|
|
3385
|
-
error,
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3426
|
+
} else {
|
|
3427
|
+
logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
3428
|
+
error,
|
|
3429
|
+
activityId: activity.id?.href,
|
|
3430
|
+
activity: message.activity,
|
|
3431
|
+
recipient: message.identifier
|
|
3432
|
+
});
|
|
3433
|
+
recordInboxActivity(this.meterProvider, "abandoned", activityType);
|
|
3434
|
+
}
|
|
3390
3435
|
span.setStatus({
|
|
3391
3436
|
code: SpanStatusCode.ERROR,
|
|
3392
3437
|
message: String(error)
|
|
@@ -4226,6 +4271,7 @@ var ContextImpl = class ContextImpl {
|
|
|
4226
4271
|
contextLoader: options.contextLoader ?? this.contextLoader,
|
|
4227
4272
|
userAgent: options.userAgent ?? this.federation.userAgent,
|
|
4228
4273
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
4274
|
+
meterProvider: options.meterProvider ?? this.meterProvider,
|
|
4229
4275
|
allowPrivateAddress: this.federation.allowPrivateAddress
|
|
4230
4276
|
});
|
|
4231
4277
|
}
|
|
@@ -4413,6 +4459,7 @@ var ContextImpl = class ContextImpl {
|
|
|
4413
4459
|
queue: this.federation.fanoutQueue,
|
|
4414
4460
|
activityType: message.activityType
|
|
4415
4461
|
}, 0);
|
|
4462
|
+
recordFanoutRecipients(this.federation.meterProvider, globalThis.Object.keys(message.inboxes).length, message.activityType);
|
|
4416
4463
|
return true;
|
|
4417
4464
|
}
|
|
4418
4465
|
async *getFollowers(identifier) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { S as KeyCache } from "./http-
|
|
2
|
+
import { S as KeyCache } from "./http-VyDTd4G3.cjs";
|
|
3
3
|
import { CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1 } from "@fedify/vocab";
|
|
4
4
|
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
5
5
|
import { MeterProvider, TracerProvider } from "@opentelemetry/api";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { S as KeyCache } from "./http-
|
|
2
|
+
import { S as KeyCache } from "./http-lf8Hsd91.js";
|
|
3
3
|
import { CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1 } from "@fedify/vocab";
|
|
4
4
|
import { MeterProvider, TracerProvider } from "@opentelemetry/api";
|
|
5
5
|
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import {
|
|
2
|
+
import { J as ActorDispatcher, Y as ActorHandleMapper, gt as WebFingerLinksDispatcher, l as RequestContext, q as ActorAliasMapper } from "./context-Cq18Gplu.js";
|
|
3
3
|
import { Span, Tracer } from "@opentelemetry/api";
|
|
4
4
|
|
|
5
5
|
//#region src/federation/webfinger.d.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { n as HttpMessageSignaturesSpecDeterminer } from "./http-
|
|
2
|
+
import { n as HttpMessageSignaturesSpecDeterminer } from "./http-lf8Hsd91.js";
|
|
3
3
|
import { n as KvStore, t as KvKey } from "./kv-D6hNiMTK.js";
|
|
4
|
-
import { TracerProvider } from "@opentelemetry/api";
|
|
4
|
+
import { MeterProvider, TracerProvider } from "@opentelemetry/api";
|
|
5
5
|
import { DocumentLoader, DocumentLoaderFactoryOptions } from "@fedify/vocab-runtime";
|
|
6
6
|
|
|
7
7
|
//#region src/utils/docloader.d.ts
|
|
@@ -48,6 +48,37 @@ declare function getAuthenticatedDocumentLoader(identity: {
|
|
|
48
48
|
tracerProvider
|
|
49
49
|
}?: GetAuthenticatedDocumentLoaderOptions): DocumentLoader;
|
|
50
50
|
//#endregion
|
|
51
|
+
//#region src/federation/metrics.d.ts
|
|
52
|
+
/**
|
|
53
|
+
* The kind of remote ActivityPub lookup, recorded as
|
|
54
|
+
* `activitypub.lookup.kind` on the public-key lookup and remote document
|
|
55
|
+
* fetch metric families.
|
|
56
|
+
*
|
|
57
|
+
* - `public_key`: a public key lookup performed by `fetchKey` /
|
|
58
|
+
* `fetchKeyDetailed` (always recorded on `activitypub.key.lookup*`).
|
|
59
|
+
* - `actor`: a document fetch whose resolved value is an Actor. The
|
|
60
|
+
* bucket exists in the taxonomy for future actor-aware call sites;
|
|
61
|
+
* today, actor documents fetched through Fedify's generic document
|
|
62
|
+
* loader are still classified as `object` because the kind is decided
|
|
63
|
+
* at the loader boundary, before the response is parsed.
|
|
64
|
+
* - `object`: a generic ActivityPub object fetch through Fedify's
|
|
65
|
+
* document loader. This is the default classification for
|
|
66
|
+
* `documentLoader` invocations that do not match a more specific
|
|
67
|
+
* bucket.
|
|
68
|
+
* - `context`: a JSON-LD `@context` document fetch through Fedify's
|
|
69
|
+
* context loader.
|
|
70
|
+
* - `other`: a fetch that does not fit any of the above classifications.
|
|
71
|
+
* @since 2.3.0
|
|
72
|
+
*/
|
|
73
|
+
type LookupKind = "public_key" | "actor" | "object" | "context" | "other";
|
|
74
|
+
/**
|
|
75
|
+
* The {@link LookupKind} values that can appear on remote document fetch
|
|
76
|
+
* metrics. `public_key` lookups are reported on the
|
|
77
|
+
* `activitypub.key.lookup` metric family instead, so it is excluded here.
|
|
78
|
+
* @since 2.3.0
|
|
79
|
+
*/
|
|
80
|
+
type DocumentFetchKind = Exclude<LookupKind, "public_key">;
|
|
81
|
+
//#endregion
|
|
51
82
|
//#region src/utils/kv-cache.d.ts
|
|
52
83
|
/**
|
|
53
84
|
* The parameters for {@link kvCache} function.
|
|
@@ -75,6 +106,24 @@ interface KvCacheParameters {
|
|
|
75
106
|
* By default, 5 minutes for all URLs.
|
|
76
107
|
*/
|
|
77
108
|
readonly rules?: readonly [string | URL | URLPattern, Temporal.Duration | Temporal.DurationLike][];
|
|
109
|
+
/**
|
|
110
|
+
* The OpenTelemetry meter provider used to record
|
|
111
|
+
* `activitypub.document.cache` measurements. When omitted, the wrapper
|
|
112
|
+
* does not emit any metric measurements, preserving the previous
|
|
113
|
+
* unobserved-cache behavior.
|
|
114
|
+
* @since 2.3.0
|
|
115
|
+
*/
|
|
116
|
+
readonly meterProvider?: MeterProvider;
|
|
117
|
+
/**
|
|
118
|
+
* The lookup kind to record on the `activitypub.lookup.kind` attribute of
|
|
119
|
+
* `activitypub.document.cache` measurements. Defaults to `"object"` so
|
|
120
|
+
* the generic document loader case does not require an explicit option.
|
|
121
|
+
* Set to `"context"` for context-loader wrappers; the
|
|
122
|
+
* authenticated-loader path does not use `kvCache()` and is therefore
|
|
123
|
+
* out of scope.
|
|
124
|
+
* @since 2.3.0
|
|
125
|
+
*/
|
|
126
|
+
readonly kind?: DocumentFetchKind;
|
|
78
127
|
}
|
|
79
128
|
/**
|
|
80
129
|
* Decorates a {@link DocumentLoader} with a cache backed by a {@link KvStore}.
|
|
@@ -85,7 +134,9 @@ declare function kvCache({
|
|
|
85
134
|
loader,
|
|
86
135
|
kv,
|
|
87
136
|
prefix,
|
|
88
|
-
rules
|
|
137
|
+
rules,
|
|
138
|
+
meterProvider,
|
|
139
|
+
kind
|
|
89
140
|
}: KvCacheParameters): DocumentLoader;
|
|
90
141
|
//#endregion
|
|
91
142
|
export { getAuthenticatedDocumentLoader as n, kvCache as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import {
|
|
2
|
+
import { J as ActorDispatcher, Y as ActorHandleMapper, gt as WebFingerLinksDispatcher, l as RequestContext, q as ActorAliasMapper } from "./context-tc6VOOOL.cjs";
|
|
3
3
|
import { Span, Tracer } from "@opentelemetry/api";
|
|
4
4
|
|
|
5
5
|
//#region src/federation/webfinger.d.ts
|