@fedify/fedify 2.4.0-dev.2027 → 2.4.0-dev.2030
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-BM255b90.mjs → builder-BYJ5otJa.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-CPvNisT2.mjs → compound-proof-BIvUoJxm.mjs} +74 -2
- package/dist/{deno-BcZNXlJn.mjs → deno-Vj_9wePq.mjs} +1 -1
- package/dist/{docloader-iHi0-9mK.mjs → docloader-qUudHZVH.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 +5 -5
- package/dist/federation/idempotency.test.mjs +2 -2
- 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.js +1 -1
- package/dist/federation/outgoing-proof.test.d.mts +2 -0
- package/dist/federation/outgoing-proof.test.mjs +396 -0
- 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-C0ijTwhx.cjs → federation-CTnaljmy.cjs} +200 -50
- package/dist/{http-CWXKwHPv.cjs → http-B5F1JMh0.cjs} +1 -1
- package/dist/{http-KZWtR1H8.js → http-By8tnmEr.js} +1 -1
- package/dist/{http-fIK5D83n.mjs → http-D4WPcJUe.mjs} +3 -3
- package/dist/{key-Xb1hVVZO.mjs → key-B_Zc5Jbd.mjs} +2 -2
- package/dist/{kv-cache-Dos4tOWb.cjs → kv-cache-8K70pjtX.cjs} +1 -1
- package/dist/{kv-cache-CU1rmQFB.mjs → kv-cache-BXdT7pJQ.mjs} +1 -1
- package/dist/{kv-cache-HOO6BsuW.js → kv-cache-BswMKQjC.js} +1 -1
- package/dist/{ld-DFHvxLtx.mjs → ld-B16KUSIQ.mjs} +3 -3
- package/dist/{metrics-D7RydU_p.mjs → metrics-DpQqUAmh.mjs} +1 -1
- package/dist/{middleware-DgU5bJnn.mjs → middleware-BL5HFFVU.mjs} +1 -1
- package/dist/{middleware-BsYD_ufs.mjs → middleware-C7_hqDnl.mjs} +139 -61
- package/dist/{middleware-iffqYoTV.js → middleware-Cxto6Bq2.js} +201 -51
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-D53bUI-n.mjs → owner-BIOIhZoM.mjs} +2 -2
- package/dist/{owner-B7lgRMdU.js → owner-D-E0bT2O.js} +1 -1
- package/dist/{owner-DffLVeYC.cjs → owner-WUYke16i.cjs} +1 -1
- package/dist/{proof-4ADU3qy0.mjs → proof-BVxJu5vv.mjs} +4 -4
- package/dist/{send-n-W6bG7y.mjs → send-Cr5FJ7iu.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.d.mts +2 -0
- package/dist/sig/compound-proof-producer.test.mjs +107 -0
- package/dist/sig/compound-proof-verification.test.mjs +2 -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/mod.cjs +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/{temporal-BFUyXrYg.mjs → temporal-CCf0lZV3.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- 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.js +1 -1
- package/package.json +6 -6
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
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-
|
|
4
|
+
import { n as version, t as name } from "./deno-Vj_9wePq.mjs";
|
|
5
|
+
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-DpQqUAmh.mjs";
|
|
6
6
|
import { t as formatAcceptSignature } from "./accept-CPVqki78.mjs";
|
|
7
|
-
import { o as importJwk, s as validateCryptoKey, t as exportJwk } from "./key-
|
|
8
|
-
import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-
|
|
9
|
-
import { t as getAuthenticatedDocumentLoader } from "./docloader-
|
|
10
|
-
import { n as kvCache } from "./kv-cache-
|
|
7
|
+
import { o as importJwk, s as validateCryptoKey, t as exportJwk } from "./key-B_Zc5Jbd.mjs";
|
|
8
|
+
import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-D4WPcJUe.mjs";
|
|
9
|
+
import { t as getAuthenticatedDocumentLoader } from "./docloader-qUudHZVH.mjs";
|
|
10
|
+
import { n as kvCache } from "./kv-cache-BXdT7pJQ.mjs";
|
|
11
11
|
import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-4IJqPYos.mjs";
|
|
12
12
|
import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-DpnpgjyX.mjs";
|
|
13
13
|
import { t as nodeInfoToJson } from "./types-DE_LV1JB.mjs";
|
|
14
|
-
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-
|
|
15
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-
|
|
16
|
-
import { a as verifyObject, n as hasProofLike, r as signObject } from "./proof-
|
|
17
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-
|
|
18
|
-
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-
|
|
14
|
+
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-B16KUSIQ.mjs";
|
|
15
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-BIOIhZoM.mjs";
|
|
16
|
+
import { a as verifyObject, n as hasProofLike, r as signObject } from "./proof-BVxJu5vv.mjs";
|
|
17
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-Cr5FJ7iu.mjs";
|
|
18
|
+
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-BYJ5otJa.mjs";
|
|
19
19
|
import { t as CircuitBreaker } from "./circuit-breaker-C5NqoLBJ.mjs";
|
|
20
20
|
import { t as buildCollectionSynchronizationHeader } from "./collection-CnnP1UAv.mjs";
|
|
21
|
-
import {
|
|
21
|
+
import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, t as containsCompoundPortableObject } from "./compound-proof-BIvUoJxm.mjs";
|
|
22
22
|
import { t as KvKeyCache } from "./keycache-BUDHB5rY.mjs";
|
|
23
23
|
import { t as acceptsJsonLd } from "./negotiation-CCocWT_N.mjs";
|
|
24
|
-
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-
|
|
24
|
+
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-CCf0lZV3.mjs";
|
|
25
25
|
import { t as createExponentialBackoffPolicy } from "./retry-zX5xw5e0.mjs";
|
|
26
26
|
import { t as TaskCodec } from "./codec-C6rTrpIp.mjs";
|
|
27
27
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
@@ -30,7 +30,7 @@ import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey,
|
|
|
30
30
|
import { lookupWebFinger } from "@fedify/webfinger";
|
|
31
31
|
import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
|
|
32
32
|
import { uniq } from "es-toolkit";
|
|
33
|
-
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
33
|
+
import { FetchError, getDocumentLoader, getFe34Origin, haveSameFe34Origin } from "@fedify/vocab-runtime";
|
|
34
34
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
35
35
|
import { DataPointType, MeterProvider as MeterProvider$1, MetricReader } from "@opentelemetry/sdk-metrics";
|
|
36
36
|
import { domainToASCII } from "node:url";
|
|
@@ -2326,6 +2326,102 @@ const MIN_COMPONENTS = [
|
|
|
2326
2326
|
"@authority"
|
|
2327
2327
|
];
|
|
2328
2328
|
//#endregion
|
|
2329
|
+
//#region src/federation/outgoing-proof.ts
|
|
2330
|
+
function isPortableUrl(url) {
|
|
2331
|
+
return url.protocol === "ap:" || url.protocol === "ap+ef61:";
|
|
2332
|
+
}
|
|
2333
|
+
function formatKeyIds(candidates) {
|
|
2334
|
+
return candidates.map((c) => c.verificationMethod.href).join(", ");
|
|
2335
|
+
}
|
|
2336
|
+
/**
|
|
2337
|
+
* Creates the Object Integrity Proofs Fedify attaches to an outgoing activity.
|
|
2338
|
+
*
|
|
2339
|
+
* Outside the map-local compound-proof profile, i.e., when the activity
|
|
2340
|
+
* embeds no portable object, every Ed25519 key signs the activity, as it
|
|
2341
|
+
* always has. Inside the profile, which accepts exactly one direct proof per
|
|
2342
|
+
* map, Fedify creates at most one proof:
|
|
2343
|
+
*
|
|
2344
|
+
* - An activity that already carries a proof is kept as is.
|
|
2345
|
+
* - A single Ed25519 key signs the activity.
|
|
2346
|
+
* - With several Ed25519 keys, a portable activity is signed by the one key
|
|
2347
|
+
* whose verification method is a DID URL for the activity's DID, the only
|
|
2348
|
+
* proof the FEP-ef61 policy can accept. If no key or more than one key
|
|
2349
|
+
* qualifies, or the activity is not portable itself, the choice is
|
|
2350
|
+
* ambiguous and this function throws.
|
|
2351
|
+
*
|
|
2352
|
+
* @throws {TypeError} If a single proof key cannot be chosen.
|
|
2353
|
+
* @internal
|
|
2354
|
+
*/
|
|
2355
|
+
async function signOutgoingActivity(activity, candidates, options) {
|
|
2356
|
+
const { contextLoader, tracerProvider } = options;
|
|
2357
|
+
let hasProof = false;
|
|
2358
|
+
for await (const _ of activity.getProofs({ contextLoader })) {
|
|
2359
|
+
hasProof = true;
|
|
2360
|
+
break;
|
|
2361
|
+
}
|
|
2362
|
+
const keys = candidates.filter((c) => c.privateKey.algorithm.name === "Ed25519");
|
|
2363
|
+
if (keys.length < 1 || hasProof && !options.appendToExistingProofs) return {
|
|
2364
|
+
activity,
|
|
2365
|
+
hasProof,
|
|
2366
|
+
proofCreated: false
|
|
2367
|
+
};
|
|
2368
|
+
const sign = async (selected) => {
|
|
2369
|
+
for (const { verificationMethod, privateKey } of selected) activity = await signObject(activity, privateKey, verificationMethod, {
|
|
2370
|
+
contextLoader,
|
|
2371
|
+
tracerProvider
|
|
2372
|
+
});
|
|
2373
|
+
return {
|
|
2374
|
+
activity,
|
|
2375
|
+
hasProof: true,
|
|
2376
|
+
proofCreated: true
|
|
2377
|
+
};
|
|
2378
|
+
};
|
|
2379
|
+
if (keys.length < 2 && !hasProof) return await sign(keys);
|
|
2380
|
+
if (!containsCompoundPortableObject(await activity.toJsonLd({
|
|
2381
|
+
format: "compact",
|
|
2382
|
+
contextLoader
|
|
2383
|
+
}))) return await sign(keys);
|
|
2384
|
+
const logger = getLogger([
|
|
2385
|
+
"fedify",
|
|
2386
|
+
"federation",
|
|
2387
|
+
"outbox"
|
|
2388
|
+
]);
|
|
2389
|
+
const activityId = activity.id?.href;
|
|
2390
|
+
if (hasProof) {
|
|
2391
|
+
logger.debug("The activity {activityId} embeds portable objects and already carries a proof, so no further proof is added; the map-local compound-proof profile accepts exactly one direct proof per map.", { activityId });
|
|
2392
|
+
return {
|
|
2393
|
+
activity,
|
|
2394
|
+
hasProof,
|
|
2395
|
+
proofCreated: false
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
if (activity.id == null || !isPortableUrl(activity.id)) throw new TypeError(`Cannot choose an Object Integrity Proof key for the activity ${activityId}: it embeds portable objects, so it falls under the map-local compound-proof profile, which accepts exactly one direct proof per map, but ${keys.length} Ed25519 keys were supplied (${formatKeyIds(keys)}). Send it with explicit sender keys that contain exactly one Ed25519 key (RSA keys for HTTP Signatures may stay), or sign it with signObject() before sending it.`);
|
|
2399
|
+
const activityDid = getFe34Origin(activity.id);
|
|
2400
|
+
const eligible = keys.filter((c) => c.verificationMethod.protocol === "did:" && haveSameFe34Origin(activity.id, c.verificationMethod));
|
|
2401
|
+
if (eligible.length !== 1) throw new TypeError(`Cannot choose an Object Integrity Proof key for the portable activity ${activityId}: ` + (eligible.length < 1 ? `none of its ${keys.length} Ed25519 keys (${formatKeyIds(keys)}) ` : `${eligible.length} of its Ed25519 keys (${formatKeyIds(eligible)}) `) + `${eligible.length < 1 ? "is" : "are"} a DID URL verification method for ${activityDid}. The map-local compound-proof profile accepts exactly one direct proof per map, and FEP-ef61 requires that proof's verification method to be a DID URL for the activity's DID. Supply exactly one Ed25519 key whose key ID is a DID URL for ${activityDid}, or sign the activity with signObject() before sending it.`);
|
|
2402
|
+
logger.debug("The portable activity {activityId} is signed only by {keyId}, the one Ed25519 key whose verification method matches its DID; the map-local compound-proof profile accepts exactly one direct proof per map.", {
|
|
2403
|
+
activityId,
|
|
2404
|
+
keyId: eligible[0].verificationMethod.href
|
|
2405
|
+
});
|
|
2406
|
+
return await sign(eligible);
|
|
2407
|
+
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Rejects an outgoing activity whose proofs Fedify's own inbox would reject
|
|
2410
|
+
* as unsupported: a document with portable objects in which some map carries
|
|
2411
|
+
* a proof set or another value that is not a single proof map.
|
|
2412
|
+
*
|
|
2413
|
+
* @param jsonLd The compact JSON-LD document about to be delivered.
|
|
2414
|
+
* @param activityId The activity ID, for the error message.
|
|
2415
|
+
* @throws {TypeError} If the document has an unsupported proof shape.
|
|
2416
|
+
* @internal
|
|
2417
|
+
*/
|
|
2418
|
+
function assertSupportedCompoundProofShape(jsonLd, activityId) {
|
|
2419
|
+
if (!containsCompoundPortableObject(jsonLd)) return;
|
|
2420
|
+
const path = findUnsupportedCompoundProofShape(jsonLd);
|
|
2421
|
+
if (path == null) return;
|
|
2422
|
+
throw new TypeError(`Cannot send the activity ${activityId}: it embeds portable objects, but its proof at the JSON Pointer ${JSON.stringify(path)} is not a single proof map. The map-local compound-proof profile accepts exactly one direct proof per map, so Fedify inboxes would reject the activity. Sign each object with exactly one key.`);
|
|
2423
|
+
}
|
|
2424
|
+
//#endregion
|
|
2329
2425
|
//#region src/federation/tasks/enqueue.ts
|
|
2330
2426
|
/**
|
|
2331
2427
|
* The enqueue pipeline for custom background tasks. `ContextImpl.enqueueTask`
|
|
@@ -3954,8 +4050,6 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3954
4050
|
else if (keys.length < 1) throw new TypeError("The keys must not be empty.");
|
|
3955
4051
|
const contextLoader = this.contextLoaderFactory(this.#getLoaderOptions(ctx.origin));
|
|
3956
4052
|
const activityId = activity.id.href;
|
|
3957
|
-
let hasProof = false;
|
|
3958
|
-
let proofCreated = false;
|
|
3959
4053
|
let rsaKey = null;
|
|
3960
4054
|
for (const { keyId, privateKey } of keys) {
|
|
3961
4055
|
validateCryptoKey(privateKey, "private");
|
|
@@ -3964,25 +4058,22 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3964
4058
|
privateKey
|
|
3965
4059
|
};
|
|
3966
4060
|
}
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
}
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
hasProof = true;
|
|
3978
|
-
proofCreated = true;
|
|
3979
|
-
}
|
|
3980
|
-
}
|
|
4061
|
+
const signed = await signOutgoingActivity(activity, keys.map(({ keyId, privateKey }) => ({
|
|
4062
|
+
verificationMethod: keyId,
|
|
4063
|
+
privateKey
|
|
4064
|
+
})), {
|
|
4065
|
+
contextLoader,
|
|
4066
|
+
tracerProvider: this.tracerProvider,
|
|
4067
|
+
appendToExistingProofs: false
|
|
4068
|
+
});
|
|
4069
|
+
activity = signed.activity;
|
|
4070
|
+
const { hasProof, proofCreated } = signed;
|
|
3981
4071
|
let jsonLd = !proofCreated && options.activityJsonLd != null ? options.activityJsonLd : await activity.toJsonLd({
|
|
3982
4072
|
format: "compact",
|
|
3983
4073
|
contextLoader
|
|
3984
4074
|
});
|
|
3985
4075
|
if (proofCreated || !hasProof || options.normalizeExistingProofs) jsonLd = await normalizeOutgoingActivityJsonLd(jsonLd, contextLoader, { preserveNestedSecuredDocuments: true });
|
|
4076
|
+
assertSupportedCompoundProofShape(jsonLd, activityId);
|
|
3986
4077
|
if (rsaKey == null) logger.warn("No supported key found to create a Linked Data signature for the activity {activityId}. The activity will be sent without a Linked Data signature. In order to create a Linked Data signature, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
|
|
3987
4078
|
activityId,
|
|
3988
4079
|
keys: keys.map((pair) => ({
|
|
@@ -4954,33 +5045,18 @@ var ContextImpl = class ContextImpl {
|
|
|
4954
5045
|
});
|
|
4955
5046
|
throw new TypeError("The activity to send must have at least one actor property.");
|
|
4956
5047
|
}
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
const contextLoader = this.contextLoader;
|
|
4970
|
-
let hasProof = false;
|
|
4971
|
-
for await (const _ of activity.getProofs({ contextLoader })) {
|
|
4972
|
-
hasProof = true;
|
|
4973
|
-
break;
|
|
4974
|
-
}
|
|
4975
|
-
if (!hasProof) for (const { keyId, privateKey } of keys) {
|
|
4976
|
-
if (privateKey.algorithm.name !== "Ed25519") continue;
|
|
4977
|
-
activity = await signObject(activity, privateKey, keyId, {
|
|
4978
|
-
contextLoader,
|
|
4979
|
-
tracerProvider: this.tracerProvider
|
|
4980
|
-
});
|
|
4981
|
-
proofCreated = true;
|
|
4982
|
-
}
|
|
4983
|
-
}
|
|
5048
|
+
const { activity: signedActivity, proofCreated } = await signOutgoingActivity(activity, actorKeyPairs == null ? keys.map(({ keyId, privateKey }) => ({
|
|
5049
|
+
verificationMethod: keyId,
|
|
5050
|
+
privateKey
|
|
5051
|
+
})) : actorKeyPairs.flatMap((kp) => kp.multikey.id == null ? [] : [{
|
|
5052
|
+
verificationMethod: kp.multikey.id,
|
|
5053
|
+
privateKey: kp.privateKey
|
|
5054
|
+
}]), {
|
|
5055
|
+
contextLoader: this.contextLoader,
|
|
5056
|
+
tracerProvider: this.tracerProvider,
|
|
5057
|
+
appendToExistingProofs: actorKeyPairs != null
|
|
5058
|
+
});
|
|
5059
|
+
activity = signedActivity;
|
|
4984
5060
|
const inboxes = extractInboxes({
|
|
4985
5061
|
recipients: expandedRecipients,
|
|
4986
5062
|
preferSharedInbox: options.preferSharedInbox,
|
|
@@ -5005,6 +5081,11 @@ var ContextImpl = class ContextImpl {
|
|
|
5005
5081
|
});
|
|
5006
5082
|
return true;
|
|
5007
5083
|
}
|
|
5084
|
+
const activityJsonLd = await activity.toJsonLd({
|
|
5085
|
+
format: "compact",
|
|
5086
|
+
contextLoader: this.contextLoader
|
|
5087
|
+
});
|
|
5088
|
+
assertSupportedCompoundProofShape(activityJsonLd, activity.id?.href);
|
|
5008
5089
|
const keyJwkPairs = await Promise.all(keys.map(async ({ keyId, privateKey }) => ({
|
|
5009
5090
|
keyId: keyId.href,
|
|
5010
5091
|
privateKey: await exportJwk(privateKey)
|
|
@@ -5020,10 +5101,7 @@ var ContextImpl = class ContextImpl {
|
|
|
5020
5101
|
actorIds: [...actorIds],
|
|
5021
5102
|
sharedInbox
|
|
5022
5103
|
}])),
|
|
5023
|
-
activity:
|
|
5024
|
-
format: "compact",
|
|
5025
|
-
contextLoader: this.contextLoader
|
|
5026
|
-
}),
|
|
5104
|
+
activity: activityJsonLd,
|
|
5027
5105
|
activityId: activity.id?.href,
|
|
5028
5106
|
activityType: getTypeId(activity).href,
|
|
5029
5107
|
collectionSync: opts.collectionSync,
|
|
@@ -2,16 +2,16 @@ import { Temporal } from "temporal-polyfill";
|
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
import { t as __exportAll } from "./rolldown-runtime-BC-Eo5Mj.js";
|
|
4
4
|
import { r as getDefaultActivityTransformers } from "./transformers-DAtXl_Kc.js";
|
|
5
|
-
import { A as recordWebFingerHandle, C as recordCollectionRequest, D as recordInboxActivity, E as recordFanoutRecipients, I as name, L as version, M as formatAcceptSignature, O as recordOutboxActivity, S as recordCollectionPageItems, _ as instrumentDocumentLoader, a as verifyRequestDetailed, b as recordCircuitBreakerStateChange, d as importJwk, f as validateCryptoKey, g as getRemoteHost, h as getFederationMetrics, i as verifyRequest, j as registerQueueDepthGauge, k as recordOutboxEnqueue, m as getDurationMs, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, v as isAbortError, w as recordCollectionTotalItems, x as recordCollectionDispatchDuration } from "./http-
|
|
5
|
+
import { A as recordWebFingerHandle, C as recordCollectionRequest, D as recordInboxActivity, E as recordFanoutRecipients, I as name, L as version, M as formatAcceptSignature, O as recordOutboxActivity, S as recordCollectionPageItems, _ as instrumentDocumentLoader, a as verifyRequestDetailed, b as recordCircuitBreakerStateChange, d as importJwk, f as validateCryptoKey, g as getRemoteHost, h as getFederationMetrics, i as verifyRequest, j as registerQueueDepthGauge, k as recordOutboxEnqueue, m as getDurationMs, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, v as isAbortError, w as recordCollectionTotalItems, x as recordCollectionDispatchDuration } from "./http-By8tnmEr.js";
|
|
6
6
|
import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-C_cNlNVK.js";
|
|
7
|
-
import { C as verifyCompactJsonLd, D as normalizeOutgoingActivityJsonLd, E as wrapContextLoaderForJsonLd, S as signJsonLd, _ as getNormalizationContextLoader, a as signObject, b as isClearlyMalformedContextReference, d as InvalidContextReferenceError, f as assertSafeJsonLd, g as detachSignature, i as hasProofLike, l as verifyPortableObjectProofPolicy, m as compactJsonLd, n as getKeyOwner, o as verifyMapLocalProof, s as verifyObject, t as doesActorOwnKey, v as hasSignature, x as isInvalidUrlTypeError, y as hasSignatureLike } from "./owner-
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
7
|
+
import { C as verifyCompactJsonLd, D as normalizeOutgoingActivityJsonLd, E as wrapContextLoaderForJsonLd, S as signJsonLd, _ as getNormalizationContextLoader, a as signObject, b as isClearlyMalformedContextReference, d as InvalidContextReferenceError, f as assertSafeJsonLd, g as detachSignature, i as hasProofLike, l as verifyPortableObjectProofPolicy, m as compactJsonLd, n as getKeyOwner, o as verifyMapLocalProof, s as verifyObject, t as doesActorOwnKey, v as hasSignature, x as isInvalidUrlTypeError, y as hasSignatureLike } from "./owner-D-E0bT2O.js";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-BswMKQjC.js";
|
|
9
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
10
10
|
import { Router, RouterError, assertPath } from "@fedify/uri-template";
|
|
11
11
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
12
12
|
import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
|
|
13
13
|
import { encodeHex } from "byte-encodings/hex";
|
|
14
|
-
import { FetchError, UrlError, getDocumentLoader, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
14
|
+
import { FetchError, UrlError, getDocumentLoader, getFe34Origin, haveSameFe34Origin, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
15
15
|
import { uniq } from "es-toolkit";
|
|
16
16
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
17
17
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
@@ -1643,6 +1643,78 @@ function inspectCompoundPortableObjectApplicability(json, limits) {
|
|
|
1643
1643
|
return "absent";
|
|
1644
1644
|
}
|
|
1645
1645
|
/**
|
|
1646
|
+
* Walks every JSON map in a finite, already-materialized JSON tree, depth
|
|
1647
|
+
* first in insertion order, skipping the values of `proof` and `@context`
|
|
1648
|
+
* members. A map reached a second time through a repeated reference is not
|
|
1649
|
+
* visited again, so a cyclic input terminates. The walk stops as soon as
|
|
1650
|
+
* the visitor returns a value other than `undefined`.
|
|
1651
|
+
*/
|
|
1652
|
+
function findInJsonMaps(json, visit) {
|
|
1653
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1654
|
+
const pending = [{
|
|
1655
|
+
value: json,
|
|
1656
|
+
path: ""
|
|
1657
|
+
}];
|
|
1658
|
+
while (pending.length > 0) {
|
|
1659
|
+
const { value, path } = pending.pop();
|
|
1660
|
+
if (typeof value !== "object" || value == null || seen.has(value)) continue;
|
|
1661
|
+
seen.add(value);
|
|
1662
|
+
if (Array.isArray(value)) {
|
|
1663
|
+
for (let index = value.length - 1; index >= 0; index--) pending.push({
|
|
1664
|
+
value: value[index],
|
|
1665
|
+
path: childPath(path, String(index))
|
|
1666
|
+
});
|
|
1667
|
+
continue;
|
|
1668
|
+
}
|
|
1669
|
+
const map = value;
|
|
1670
|
+
const result = visit(map, path);
|
|
1671
|
+
if (result !== void 0) return result;
|
|
1672
|
+
const keys = Object.keys(map);
|
|
1673
|
+
for (let index = keys.length - 1; index >= 0; index--) {
|
|
1674
|
+
const key = keys[index];
|
|
1675
|
+
if (key === "proof" || key === "@context") continue;
|
|
1676
|
+
pending.push({
|
|
1677
|
+
value: map[key],
|
|
1678
|
+
path: childPath(path, key)
|
|
1679
|
+
});
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* Determines whether an outgoing JSON tree contains portable content that
|
|
1685
|
+
* requires producer-side proof-shape checks: a map, outside proof and context
|
|
1686
|
+
* values, whose direct `id` or `@id` is a portable ActivityPub URI.
|
|
1687
|
+
*
|
|
1688
|
+
* This deliberately differs from
|
|
1689
|
+
* {@link inspectCompoundPortableObjectApplicability}: it applies no resource
|
|
1690
|
+
* limits, so a portable map or an unsupported proof beyond the inbox limits
|
|
1691
|
+
* is still found, and a large document without portable maps stays outside
|
|
1692
|
+
* the compound-proof profile. The input must be a finite JSON tree that has
|
|
1693
|
+
* already been materialized, such as a compact JSON-LD document about to be
|
|
1694
|
+
* sent.
|
|
1695
|
+
*
|
|
1696
|
+
* @internal
|
|
1697
|
+
*/
|
|
1698
|
+
function containsCompoundPortableObject(json) {
|
|
1699
|
+
return findInJsonMaps(json, (map) => [map.id, map["@id"]].some((id) => typeof id === "string" && PORTABLE_OBJECT_ID_PATTERN.test(id)) ? true : void 0) ?? false;
|
|
1700
|
+
}
|
|
1701
|
+
/**
|
|
1702
|
+
* Finds the first direct `proof` member whose value the map-local
|
|
1703
|
+
* compound-proof profile does not accept, i.e., anything other than a single
|
|
1704
|
+
* JSON map: a proof set, `null`, or a scalar. Like the inbox discovery, it
|
|
1705
|
+
* does not look inside proof or context values.
|
|
1706
|
+
*
|
|
1707
|
+
* The input must be a finite, already-materialized JSON tree; see
|
|
1708
|
+
* {@link containsCompoundPortableObject}.
|
|
1709
|
+
*
|
|
1710
|
+
* @returns The RFC 6901 JSON Pointer to the unsupported `proof` member, or
|
|
1711
|
+
* `null` if every direct proof is a single JSON map.
|
|
1712
|
+
* @internal
|
|
1713
|
+
*/
|
|
1714
|
+
function findUnsupportedCompoundProofShape(json) {
|
|
1715
|
+
return findInJsonMaps(json, (map, path) => Object.hasOwn(map, "proof") && !isJsonMap(map.proof) ? childPath(path, "proof") : void 0) ?? null;
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1646
1718
|
* Discovers direct literal proof-bearing maps in an immutable JSON snapshot.
|
|
1647
1719
|
*
|
|
1648
1720
|
* Discovery is bounded and atomic. Unsupported proof shapes, non-JSON input,
|
|
@@ -4535,6 +4607,102 @@ function serializeDataPointType(dataPointType) {
|
|
|
4535
4607
|
}
|
|
4536
4608
|
}
|
|
4537
4609
|
//#endregion
|
|
4610
|
+
//#region src/federation/outgoing-proof.ts
|
|
4611
|
+
function isPortableUrl(url) {
|
|
4612
|
+
return url.protocol === "ap:" || url.protocol === "ap+ef61:";
|
|
4613
|
+
}
|
|
4614
|
+
function formatKeyIds(candidates) {
|
|
4615
|
+
return candidates.map((c) => c.verificationMethod.href).join(", ");
|
|
4616
|
+
}
|
|
4617
|
+
/**
|
|
4618
|
+
* Creates the Object Integrity Proofs Fedify attaches to an outgoing activity.
|
|
4619
|
+
*
|
|
4620
|
+
* Outside the map-local compound-proof profile, i.e., when the activity
|
|
4621
|
+
* embeds no portable object, every Ed25519 key signs the activity, as it
|
|
4622
|
+
* always has. Inside the profile, which accepts exactly one direct proof per
|
|
4623
|
+
* map, Fedify creates at most one proof:
|
|
4624
|
+
*
|
|
4625
|
+
* - An activity that already carries a proof is kept as is.
|
|
4626
|
+
* - A single Ed25519 key signs the activity.
|
|
4627
|
+
* - With several Ed25519 keys, a portable activity is signed by the one key
|
|
4628
|
+
* whose verification method is a DID URL for the activity's DID, the only
|
|
4629
|
+
* proof the FEP-ef61 policy can accept. If no key or more than one key
|
|
4630
|
+
* qualifies, or the activity is not portable itself, the choice is
|
|
4631
|
+
* ambiguous and this function throws.
|
|
4632
|
+
*
|
|
4633
|
+
* @throws {TypeError} If a single proof key cannot be chosen.
|
|
4634
|
+
* @internal
|
|
4635
|
+
*/
|
|
4636
|
+
async function signOutgoingActivity(activity, candidates, options) {
|
|
4637
|
+
const { contextLoader, tracerProvider } = options;
|
|
4638
|
+
let hasProof = false;
|
|
4639
|
+
for await (const _ of activity.getProofs({ contextLoader })) {
|
|
4640
|
+
hasProof = true;
|
|
4641
|
+
break;
|
|
4642
|
+
}
|
|
4643
|
+
const keys = candidates.filter((c) => c.privateKey.algorithm.name === "Ed25519");
|
|
4644
|
+
if (keys.length < 1 || hasProof && !options.appendToExistingProofs) return {
|
|
4645
|
+
activity,
|
|
4646
|
+
hasProof,
|
|
4647
|
+
proofCreated: false
|
|
4648
|
+
};
|
|
4649
|
+
const sign = async (selected) => {
|
|
4650
|
+
for (const { verificationMethod, privateKey } of selected) activity = await signObject(activity, privateKey, verificationMethod, {
|
|
4651
|
+
contextLoader,
|
|
4652
|
+
tracerProvider
|
|
4653
|
+
});
|
|
4654
|
+
return {
|
|
4655
|
+
activity,
|
|
4656
|
+
hasProof: true,
|
|
4657
|
+
proofCreated: true
|
|
4658
|
+
};
|
|
4659
|
+
};
|
|
4660
|
+
if (keys.length < 2 && !hasProof) return await sign(keys);
|
|
4661
|
+
if (!containsCompoundPortableObject(await activity.toJsonLd({
|
|
4662
|
+
format: "compact",
|
|
4663
|
+
contextLoader
|
|
4664
|
+
}))) return await sign(keys);
|
|
4665
|
+
const logger = getLogger([
|
|
4666
|
+
"fedify",
|
|
4667
|
+
"federation",
|
|
4668
|
+
"outbox"
|
|
4669
|
+
]);
|
|
4670
|
+
const activityId = activity.id?.href;
|
|
4671
|
+
if (hasProof) {
|
|
4672
|
+
logger.debug("The activity {activityId} embeds portable objects and already carries a proof, so no further proof is added; the map-local compound-proof profile accepts exactly one direct proof per map.", { activityId });
|
|
4673
|
+
return {
|
|
4674
|
+
activity,
|
|
4675
|
+
hasProof,
|
|
4676
|
+
proofCreated: false
|
|
4677
|
+
};
|
|
4678
|
+
}
|
|
4679
|
+
if (activity.id == null || !isPortableUrl(activity.id)) throw new TypeError(`Cannot choose an Object Integrity Proof key for the activity ${activityId}: it embeds portable objects, so it falls under the map-local compound-proof profile, which accepts exactly one direct proof per map, but ${keys.length} Ed25519 keys were supplied (${formatKeyIds(keys)}). Send it with explicit sender keys that contain exactly one Ed25519 key (RSA keys for HTTP Signatures may stay), or sign it with signObject() before sending it.`);
|
|
4680
|
+
const activityDid = getFe34Origin(activity.id);
|
|
4681
|
+
const eligible = keys.filter((c) => c.verificationMethod.protocol === "did:" && haveSameFe34Origin(activity.id, c.verificationMethod));
|
|
4682
|
+
if (eligible.length !== 1) throw new TypeError(`Cannot choose an Object Integrity Proof key for the portable activity ${activityId}: ` + (eligible.length < 1 ? `none of its ${keys.length} Ed25519 keys (${formatKeyIds(keys)}) ` : `${eligible.length} of its Ed25519 keys (${formatKeyIds(eligible)}) `) + `${eligible.length < 1 ? "is" : "are"} a DID URL verification method for ${activityDid}. The map-local compound-proof profile accepts exactly one direct proof per map, and FEP-ef61 requires that proof's verification method to be a DID URL for the activity's DID. Supply exactly one Ed25519 key whose key ID is a DID URL for ${activityDid}, or sign the activity with signObject() before sending it.`);
|
|
4683
|
+
logger.debug("The portable activity {activityId} is signed only by {keyId}, the one Ed25519 key whose verification method matches its DID; the map-local compound-proof profile accepts exactly one direct proof per map.", {
|
|
4684
|
+
activityId,
|
|
4685
|
+
keyId: eligible[0].verificationMethod.href
|
|
4686
|
+
});
|
|
4687
|
+
return await sign(eligible);
|
|
4688
|
+
}
|
|
4689
|
+
/**
|
|
4690
|
+
* Rejects an outgoing activity whose proofs Fedify's own inbox would reject
|
|
4691
|
+
* as unsupported: a document with portable objects in which some map carries
|
|
4692
|
+
* a proof set or another value that is not a single proof map.
|
|
4693
|
+
*
|
|
4694
|
+
* @param jsonLd The compact JSON-LD document about to be delivered.
|
|
4695
|
+
* @param activityId The activity ID, for the error message.
|
|
4696
|
+
* @throws {TypeError} If the document has an unsupported proof shape.
|
|
4697
|
+
* @internal
|
|
4698
|
+
*/
|
|
4699
|
+
function assertSupportedCompoundProofShape(jsonLd, activityId) {
|
|
4700
|
+
if (!containsCompoundPortableObject(jsonLd)) return;
|
|
4701
|
+
const path = findUnsupportedCompoundProofShape(jsonLd);
|
|
4702
|
+
if (path == null) return;
|
|
4703
|
+
throw new TypeError(`Cannot send the activity ${activityId}: it embeds portable objects, but its proof at the JSON Pointer ${JSON.stringify(path)} is not a single proof map. The map-local compound-proof profile accepts exactly one direct proof per map, so Fedify inboxes would reject the activity. Sign each object with exactly one key.`);
|
|
4704
|
+
}
|
|
4705
|
+
//#endregion
|
|
4538
4706
|
//#region src/federation/retry.ts
|
|
4539
4707
|
/**
|
|
4540
4708
|
* Creates an exponential backoff retry policy. The delay between retries
|
|
@@ -6342,8 +6510,6 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6342
6510
|
else if (keys.length < 1) throw new TypeError("The keys must not be empty.");
|
|
6343
6511
|
const contextLoader = this.contextLoaderFactory(this.#getLoaderOptions(ctx.origin));
|
|
6344
6512
|
const activityId = activity.id.href;
|
|
6345
|
-
let hasProof = false;
|
|
6346
|
-
let proofCreated = false;
|
|
6347
6513
|
let rsaKey = null;
|
|
6348
6514
|
for (const { keyId, privateKey } of keys) {
|
|
6349
6515
|
validateCryptoKey(privateKey, "private");
|
|
@@ -6352,25 +6518,22 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
6352
6518
|
privateKey
|
|
6353
6519
|
};
|
|
6354
6520
|
}
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
}
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
hasProof = true;
|
|
6366
|
-
proofCreated = true;
|
|
6367
|
-
}
|
|
6368
|
-
}
|
|
6521
|
+
const signed = await signOutgoingActivity(activity, keys.map(({ keyId, privateKey }) => ({
|
|
6522
|
+
verificationMethod: keyId,
|
|
6523
|
+
privateKey
|
|
6524
|
+
})), {
|
|
6525
|
+
contextLoader,
|
|
6526
|
+
tracerProvider: this.tracerProvider,
|
|
6527
|
+
appendToExistingProofs: false
|
|
6528
|
+
});
|
|
6529
|
+
activity = signed.activity;
|
|
6530
|
+
const { hasProof, proofCreated } = signed;
|
|
6369
6531
|
let jsonLd = !proofCreated && options.activityJsonLd != null ? options.activityJsonLd : await activity.toJsonLd({
|
|
6370
6532
|
format: "compact",
|
|
6371
6533
|
contextLoader
|
|
6372
6534
|
});
|
|
6373
6535
|
if (proofCreated || !hasProof || options.normalizeExistingProofs) jsonLd = await normalizeOutgoingActivityJsonLd(jsonLd, contextLoader, { preserveNestedSecuredDocuments: true });
|
|
6536
|
+
assertSupportedCompoundProofShape(jsonLd, activityId);
|
|
6374
6537
|
if (rsaKey == null) logger.warn("No supported key found to create a Linked Data signature for the activity {activityId}. The activity will be sent without a Linked Data signature. In order to create a Linked Data signature, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
|
|
6375
6538
|
activityId,
|
|
6376
6539
|
keys: keys.map((pair) => ({
|
|
@@ -7342,33 +7505,18 @@ var ContextImpl = class ContextImpl {
|
|
|
7342
7505
|
});
|
|
7343
7506
|
throw new TypeError("The activity to send must have at least one actor property.");
|
|
7344
7507
|
}
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
const contextLoader = this.contextLoader;
|
|
7358
|
-
let hasProof = false;
|
|
7359
|
-
for await (const _ of activity.getProofs({ contextLoader })) {
|
|
7360
|
-
hasProof = true;
|
|
7361
|
-
break;
|
|
7362
|
-
}
|
|
7363
|
-
if (!hasProof) for (const { keyId, privateKey } of keys) {
|
|
7364
|
-
if (privateKey.algorithm.name !== "Ed25519") continue;
|
|
7365
|
-
activity = await signObject(activity, privateKey, keyId, {
|
|
7366
|
-
contextLoader,
|
|
7367
|
-
tracerProvider: this.tracerProvider
|
|
7368
|
-
});
|
|
7369
|
-
proofCreated = true;
|
|
7370
|
-
}
|
|
7371
|
-
}
|
|
7508
|
+
const { activity: signedActivity, proofCreated } = await signOutgoingActivity(activity, actorKeyPairs == null ? keys.map(({ keyId, privateKey }) => ({
|
|
7509
|
+
verificationMethod: keyId,
|
|
7510
|
+
privateKey
|
|
7511
|
+
})) : actorKeyPairs.flatMap((kp) => kp.multikey.id == null ? [] : [{
|
|
7512
|
+
verificationMethod: kp.multikey.id,
|
|
7513
|
+
privateKey: kp.privateKey
|
|
7514
|
+
}]), {
|
|
7515
|
+
contextLoader: this.contextLoader,
|
|
7516
|
+
tracerProvider: this.tracerProvider,
|
|
7517
|
+
appendToExistingProofs: actorKeyPairs != null
|
|
7518
|
+
});
|
|
7519
|
+
activity = signedActivity;
|
|
7372
7520
|
const inboxes = extractInboxes({
|
|
7373
7521
|
recipients: expandedRecipients,
|
|
7374
7522
|
preferSharedInbox: options.preferSharedInbox,
|
|
@@ -7393,6 +7541,11 @@ var ContextImpl = class ContextImpl {
|
|
|
7393
7541
|
});
|
|
7394
7542
|
return true;
|
|
7395
7543
|
}
|
|
7544
|
+
const activityJsonLd = await activity.toJsonLd({
|
|
7545
|
+
format: "compact",
|
|
7546
|
+
contextLoader: this.contextLoader
|
|
7547
|
+
});
|
|
7548
|
+
assertSupportedCompoundProofShape(activityJsonLd, activity.id?.href);
|
|
7396
7549
|
const keyJwkPairs = await Promise.all(keys.map(async ({ keyId, privateKey }) => ({
|
|
7397
7550
|
keyId: keyId.href,
|
|
7398
7551
|
privateKey: await exportJwk(privateKey)
|
|
@@ -7408,10 +7561,7 @@ var ContextImpl = class ContextImpl {
|
|
|
7408
7561
|
actorIds: [...actorIds],
|
|
7409
7562
|
sharedInbox
|
|
7410
7563
|
}])),
|
|
7411
|
-
activity:
|
|
7412
|
-
format: "compact",
|
|
7413
|
-
contextLoader: this.contextLoader
|
|
7414
|
-
}),
|
|
7564
|
+
activity: activityJsonLd,
|
|
7415
7565
|
activityId: activity.id?.href,
|
|
7416
7566
|
activityType: getTypeId(activity).href,
|
|
7417
7567
|
collectionSync: opts.collectionSync,
|
package/dist/mod.cjs
CHANGED
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
require("./rolldown-runtime-Dmm3t92W.cjs");
|
|
4
4
|
const require_transformers = require("./transformers-BalCrSsr.cjs");
|
|
5
5
|
require("./compat/mod.cjs");
|
|
6
|
-
const require_http = require("./http-
|
|
7
|
-
const require_federation = require("./federation-
|
|
6
|
+
const require_http = require("./http-B5F1JMh0.cjs");
|
|
7
|
+
const require_federation = require("./federation-CTnaljmy.cjs");
|
|
8
8
|
const require_types = require("./types-Be2zbyeG.cjs");
|
|
9
|
-
const require_owner = require("./owner-
|
|
10
|
-
const require_kv_cache = require("./kv-cache-
|
|
9
|
+
const require_owner = require("./owner-WUYke16i.cjs");
|
|
10
|
+
const require_kv_cache = require("./kv-cache-8K70pjtX.cjs");
|
|
11
11
|
require("./nodeinfo/mod.cjs");
|
|
12
12
|
require("./runtime/mod.cjs");
|
|
13
13
|
require("./sig/mod.cjs");
|
package/dist/mod.js
CHANGED
|
@@ -3,11 +3,11 @@ import { URLPattern } from "urlpattern-polyfill";
|
|
|
3
3
|
import "./rolldown-runtime-BC-Eo5Mj.js";
|
|
4
4
|
import { n as autoIdAssigner, r as getDefaultActivityTransformers, t as actorDehydrator } from "./transformers-DAtXl_Kc.js";
|
|
5
5
|
import "./compat/mod.js";
|
|
6
|
-
import { F as validateAcceptSignature, M as formatAcceptSignature, N as fulfillAcceptSignature, P as parseAcceptSignature, a as verifyRequestDetailed, c as fetchKey, d as importJwk, i as verifyRequest, l as fetchKeyDetailed, o as exportJwk, r as signRequest, u as generateCryptoKeyPair } from "./http-
|
|
7
|
-
import { a as respondWithObject, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as SendActivityError, l as CircuitBreaker, n as handleWebFinger, o as respondWithObjectIfAcceptable, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "./middleware-
|
|
6
|
+
import { F as validateAcceptSignature, M as formatAcceptSignature, N as fulfillAcceptSignature, P as parseAcceptSignature, a as verifyRequestDetailed, c as fetchKey, d as importJwk, i as verifyRequest, l as fetchKeyDetailed, o as exportJwk, r as signRequest, u as generateCryptoKeyPair } from "./http-By8tnmEr.js";
|
|
7
|
+
import { a as respondWithObject, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as SendActivityError, l as CircuitBreaker, n as handleWebFinger, o as respondWithObjectIfAcceptable, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "./middleware-Cxto6Bq2.js";
|
|
8
8
|
import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "./types-C_cNlNVK.js";
|
|
9
|
-
import { S as signJsonLd, T as verifySignature, a as signObject, c as verifyPortableObjectProof, g as detachSignature, h as createSignature, i as hasProofLike, n as getKeyOwner, p as attachSignature, r as createProof, s as verifyObject, t as doesActorOwnKey, u as verifyProof, w as verifyJsonLd, y as hasSignatureLike } from "./owner-
|
|
10
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
9
|
+
import { S as signJsonLd, T as verifySignature, a as signObject, c as verifyPortableObjectProof, g as detachSignature, h as createSignature, i as hasProofLike, n as getKeyOwner, p as attachSignature, r as createProof, s as verifyObject, t as doesActorOwnKey, u as verifyProof, w as verifyJsonLd, y as hasSignatureLike } from "./owner-D-E0bT2O.js";
|
|
10
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-BswMKQjC.js";
|
|
11
11
|
import { InProcessMessageQueue, MemoryKvStore, ParallelMessageQueue, Router, RouterError } from "./federation/mod.js";
|
|
12
12
|
import "./nodeinfo/mod.js";
|
|
13
13
|
import "./runtime/mod.js";
|
|
@@ -5,7 +5,7 @@ import { r as createRequestContext } from "../context-CbS35fLr.mjs";
|
|
|
5
5
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
|
-
import { _ as handleNodeInfo, o as createFederation, v as handleNodeInfoJrd } from "../middleware-
|
|
8
|
+
import { _ as handleNodeInfo, o as createFederation, v as handleNodeInfoJrd } from "../middleware-C7_hqDnl.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
//#region src/nodeinfo/handler.test.ts
|
|
11
11
|
test("handleNodeInfo()", async () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { c as verifyKeyOwnership, n as fetchActorDocument, t as exportJwk } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-Vj_9wePq.mjs";
|
|
5
|
+
import { c as verifyKeyOwnership, n as fetchActorDocument, t as exportJwk } from "./key-B_Zc5Jbd.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|