@fedify/fedify 2.0.36-dev.2530 → 2.0.36-dev.2598
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-BBdPdHYx.mjs → builder-B5hI5Xsn.mjs} +3 -3
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{deno-CtG6TwTB.mjs → deno--OYa_lxj.mjs} +1 -1
- package/dist/{docloader-BxW_P_Rq.mjs → docloader-BXR2f83H.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +8 -8
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +381 -8
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/temporal.test.mjs +2 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-CUOxcDgn.mjs → http-C3d2DXwF.mjs} +2 -2
- package/dist/{http-DMRapH1d.cjs → http-CO_IVq7x.cjs} +1 -1
- package/dist/{http-YAfhvSad.js → http-CfyVeGgF.js} +1 -1
- package/dist/{inbox-DtThTl1D.mjs → inbox-huUE3IP8.mjs} +1 -1
- package/dist/{key-QamJxksu.mjs → key-D5e9c_yV.mjs} +1 -1
- package/dist/{kv-cache-Di_SbH_3.cjs → kv-cache-BMlo_kyv.cjs} +1 -1
- package/dist/{kv-cache-C0MyXzft.js → kv-cache-Zw0soD-7.js} +1 -1
- package/dist/{ld-B0eNy8WK.mjs → ld-9qfz9rP_.mjs} +99 -10
- package/dist/{middleware-D3omYPtg.cjs → middleware-Ad6kTSBf.cjs} +1 -1
- package/dist/{middleware-D1zogq17.js → middleware-BKs_a9P1.js} +111 -15
- package/dist/{middleware-II_yrP7N.mjs → middleware-BhYpLGA_.mjs} +119 -23
- package/dist/{middleware-BKECCXIs.mjs → middleware-CT1Lbohd.mjs} +1 -1
- package/dist/{middleware-CUFw4tT0.cjs → middleware-CXoG7ZAW.cjs} +112 -16
- package/dist/{mod-DVPS4yam.d.cts → mod-BA6vqC2S.d.cts} +19 -7
- package/dist/{mod-BS-jg3Wx.d.ts → mod-CL9Ep0uo.d.ts} +19 -7
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +1 -1
- package/dist/mod.d.ts +1 -1
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-lqq4KXYV.mjs → owner-R4ffU9Ht.mjs} +2 -2
- package/dist/{proof-CqOINd75.cjs → proof-BrreJTRF.cjs} +131 -18
- package/dist/{proof-DMYwiD7d.js → proof-CE8nwTF6.js} +132 -19
- package/dist/{proof-Bf8rYD7r.mjs → proof-CiBs9Q4l.mjs} +36 -12
- package/dist/{send-1tVKmxvT.mjs → send-DpvZgVSA.mjs} +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +2 -2
- package/dist/sig/ld.test.mjs +198 -4
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +1 -1
- package/dist/sig/mod.d.ts +1 -1
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +71 -2
- package/dist/{temporal-D6JQXNOJ.mjs → temporal-Dd-J410Z.mjs} +1 -1
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +5 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno
|
|
4
|
+
import { n as version, t as name } from "./deno--OYa_lxj.mjs";
|
|
5
5
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
6
6
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
7
7
|
import { FetchError, UrlError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
require("./chunk-DDcVe30Y.cjs");
|
|
4
|
-
const require_http = require("./http-
|
|
4
|
+
const require_http = require("./http-CO_IVq7x.cjs");
|
|
5
5
|
let _logtape_logtape = require("@logtape/logtape");
|
|
6
6
|
let es_toolkit = require("es-toolkit");
|
|
7
7
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { l as validateCryptoKey, t as doubleKnockScoped } from "./http-
|
|
3
|
+
import { l as validateCryptoKey, t as doubleKnockScoped } from "./http-CfyVeGgF.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import { curry } from "es-toolkit";
|
|
6
6
|
import { FetchError, UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts } from "@fedify/vocab-runtime";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno
|
|
5
|
-
import { o as validateCryptoKey, r as fetchKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno--OYa_lxj.mjs";
|
|
5
|
+
import { o as validateCryptoKey, r as fetchKey } from "./key-D5e9c_yV.mjs";
|
|
6
6
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
7
7
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
8
|
-
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
8
|
+
import { getDocumentLoader, preloadedContexts } from "@fedify/vocab-runtime";
|
|
9
9
|
import { getLogger } from "@logtape/logtape";
|
|
10
10
|
import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
11
11
|
import { encodeHex } from "byte-encodings/hex";
|
|
@@ -298,24 +298,110 @@ function assertSafeJsonLd(jsonLd) {
|
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
+
const signatureTermDefinition = { "signature": "https://w3id.org/security#signature" };
|
|
302
|
+
const signatureDefiningContexts = new Set(["https://w3id.org/identity/v1", "https://w3id.org/security/v1"]);
|
|
303
|
+
const signatureFreeContexts = getSignatureFreeContexts();
|
|
304
|
+
function getSignatureFreeContexts() {
|
|
305
|
+
const urls = /* @__PURE__ */ new Set();
|
|
306
|
+
for (const [url, document] of globalThis.Object.entries(preloadedContexts)) {
|
|
307
|
+
if (typeof document !== "object" || document == null) continue;
|
|
308
|
+
const context = document["@context"];
|
|
309
|
+
if (typeof context !== "object" || context == null || Array.isArray(context)) continue;
|
|
310
|
+
const record = context;
|
|
311
|
+
if (!globalThis.Object.prototype.hasOwnProperty.call(record, "signature")) urls.add(url);
|
|
312
|
+
}
|
|
313
|
+
return urls;
|
|
314
|
+
}
|
|
315
|
+
function getContextEntryEffect(entry) {
|
|
316
|
+
if (entry == null) return "resets";
|
|
317
|
+
if (typeof entry === "string") {
|
|
318
|
+
if (signatureDefiningContexts.has(entry)) return "defines";
|
|
319
|
+
if (signatureFreeContexts.has(entry)) return "absent";
|
|
320
|
+
return "unknown";
|
|
321
|
+
}
|
|
322
|
+
if (typeof entry !== "object") return "absent";
|
|
323
|
+
const record = entry;
|
|
324
|
+
if (globalThis.Object.prototype.hasOwnProperty.call(record, "signature")) {
|
|
325
|
+
const definition = record["signature"];
|
|
326
|
+
const contextProtected = record["@protected"] === true;
|
|
327
|
+
const imported = globalThis.Object.prototype.hasOwnProperty.call(record, "@import");
|
|
328
|
+
if (definition == null) {
|
|
329
|
+
if (contextProtected) return "defines";
|
|
330
|
+
return imported ? "unknown" : "resets";
|
|
331
|
+
}
|
|
332
|
+
if (typeof definition === "object" && !Array.isArray(definition)) {
|
|
333
|
+
const term = definition;
|
|
334
|
+
const protectedTerm = contextProtected || term["@protected"] === true;
|
|
335
|
+
if (globalThis.Object.prototype.hasOwnProperty.call(term, "@id") && term["@id"] == null) {
|
|
336
|
+
if (protectedTerm) return "defines";
|
|
337
|
+
return imported ? "unknown" : "resets";
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return "defines";
|
|
341
|
+
}
|
|
342
|
+
if (globalThis.Object.prototype.hasOwnProperty.call(record, "@import")) return "unknown";
|
|
343
|
+
return "absent";
|
|
344
|
+
}
|
|
345
|
+
function getSignatureTermState(context) {
|
|
346
|
+
if (context == null) return "absent";
|
|
347
|
+
if (!Array.isArray(context)) {
|
|
348
|
+
const effect = getContextEntryEffect(context);
|
|
349
|
+
return effect === "defines" ? "defined" : effect === "unknown" ? "unknown" : "absent";
|
|
350
|
+
}
|
|
351
|
+
let state = "absent";
|
|
352
|
+
for (const entry of context) {
|
|
353
|
+
const effect = getContextEntryEffect(entry);
|
|
354
|
+
if (effect === "defines") state = "defined";
|
|
355
|
+
else if (effect === "resets") state = "absent";
|
|
356
|
+
else if (effect === "unknown" && state !== "defined") state = "unknown";
|
|
357
|
+
}
|
|
358
|
+
return state;
|
|
359
|
+
}
|
|
360
|
+
function prepareSignatureDocument(jsonLd) {
|
|
361
|
+
if (typeof jsonLd !== "object" || jsonLd == null || Array.isArray(jsonLd)) return jsonLd;
|
|
362
|
+
const document = jsonLd;
|
|
363
|
+
if (document["proof"] != null) return { ...document };
|
|
364
|
+
const context = document["@context"];
|
|
365
|
+
if (getSignatureTermState(context) !== "absent") return { ...document };
|
|
366
|
+
const definition = { ...signatureTermDefinition };
|
|
367
|
+
return {
|
|
368
|
+
...document,
|
|
369
|
+
"@context": context == null ? [definition] : Array.isArray(context) ? [...context, definition] : [context, definition]
|
|
370
|
+
};
|
|
371
|
+
}
|
|
301
372
|
/**
|
|
302
373
|
* Attaches a LD signature to the given JSON-LD document.
|
|
374
|
+
*
|
|
375
|
+
* When the document's context does not already define the `signature`
|
|
376
|
+
* property, the returned document adds a minimal inline context for it.
|
|
377
|
+
* Without that definition, expanding the attached signature would produce a
|
|
378
|
+
* blank node predicate, which is not valid RDF. Documents that already carry
|
|
379
|
+
* a `proof` are left unchanged, since a new context definition would invalidate
|
|
380
|
+
* the proof. Documents whose context includes an unrecognized remote context
|
|
381
|
+
* are also left unchanged, since that context may already define `signature`.
|
|
303
382
|
* @param jsonLd The JSON-LD document to attach the signature to. It is not
|
|
304
383
|
* modified.
|
|
305
384
|
* @param signature The signature to attach.
|
|
306
385
|
* @returns The JSON-LD document with the attached signature.
|
|
307
386
|
* @throws {TypeError} If the input document is not a valid JSON-LD document.
|
|
387
|
+
* Top-level arrays are rejected, since a Linked Data
|
|
388
|
+
* Signature is attached to a single node.
|
|
308
389
|
* @since 1.0.0
|
|
309
390
|
*/
|
|
310
391
|
function attachSignature(jsonLd, signature) {
|
|
311
|
-
if (typeof jsonLd !== "object" || jsonLd == null) throw new TypeError("Failed to attach signature; invalid JSON-LD document.");
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
};
|
|
392
|
+
if (typeof jsonLd !== "object" || jsonLd == null || Array.isArray(jsonLd)) throw new TypeError("Failed to attach signature; invalid JSON-LD document.");
|
|
393
|
+
const output = prepareSignatureDocument(jsonLd);
|
|
394
|
+
output.signature = signature;
|
|
395
|
+
return output;
|
|
316
396
|
}
|
|
317
397
|
/**
|
|
318
398
|
* Creates a LD signature for the given JSON-LD document.
|
|
399
|
+
*
|
|
400
|
+
* If the document's context does not define the `signature` property, the
|
|
401
|
+
* signature is computed over the document with a minimal inline definition
|
|
402
|
+
* added. Use {@link attachSignature} to attach the signature to that exact
|
|
403
|
+
* document. Documents that already carry a `proof`, or whose context includes
|
|
404
|
+
* an unrecognized remote context, are hashed unchanged.
|
|
319
405
|
* @param jsonLd The JSON-LD document to sign.
|
|
320
406
|
* @param privateKey The private key to sign the document.
|
|
321
407
|
* @param keyId The ID of the public key that corresponds to the private key.
|
|
@@ -329,14 +415,17 @@ async function createSignature(jsonLd, privateKey, keyId, { contextLoader, creat
|
|
|
329
415
|
validateCryptoKey(privateKey, "private");
|
|
330
416
|
if (privateKey.algorithm.name !== "RSASSA-PKCS1-v1_5") throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
|
|
331
417
|
const options = {
|
|
332
|
-
"@context": "https://w3id.org/identity/v1",
|
|
333
418
|
creator: keyId.href,
|
|
334
419
|
created: created?.toString() ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
335
420
|
};
|
|
336
|
-
const message = await hashJsonLd(
|
|
421
|
+
const message = await hashJsonLd({
|
|
422
|
+
"@context": "https://w3id.org/identity/v1",
|
|
423
|
+
...options
|
|
424
|
+
}, contextLoader) + await hashJsonLd(prepareSignatureDocument(jsonLd), contextLoader);
|
|
337
425
|
const messageBytes = new TextEncoder().encode(message);
|
|
338
426
|
const signature = await crypto.subtle.sign("RSASSA-PKCS1-v1_5", privateKey, messageBytes);
|
|
339
427
|
return {
|
|
428
|
+
"@context": "https://w3id.org/security/v1",
|
|
340
429
|
...options,
|
|
341
430
|
type: "RsaSignature2017",
|
|
342
431
|
signatureValue: encodeBase64(signature)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
|
-
const require_middleware = require("./middleware-
|
|
3
|
+
const require_middleware = require("./middleware-CXoG7ZAW.cjs");
|
|
4
4
|
exports.FederationImpl = require_middleware.FederationImpl;
|
|
@@ -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 importJwk, d as name, f as version, i as exportJwk, l as validateCryptoKey, r as verifyRequest, t as doubleKnockScoped } from "./http-
|
|
5
|
+
import { c as importJwk, d as name, f as version, i as exportJwk, l as validateCryptoKey, r as verifyRequest, t as doubleKnockScoped } from "./http-CfyVeGgF.js";
|
|
6
6
|
import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-B1_pRFE_.js";
|
|
7
|
-
import { _ as signJsonLd, a as doesActorOwnKey, c as assertSafeJsonLd, f as detachSignature, g as isInvalidUrlTypeError, h as isClearlyMalformedContextReference, m as hasSignature, n as signObject, o as getKeyOwner, p as getNormalizationContextLoader, r as verifyObject, s as InvalidContextReferenceError, u as compactJsonLd, v as verifyCompactJsonLd, x as wrapContextLoaderForJsonLd } from "./proof-
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
7
|
+
import { _ as signJsonLd, a as doesActorOwnKey, c as assertSafeJsonLd, f as detachSignature, g as isInvalidUrlTypeError, h as isClearlyMalformedContextReference, m as hasSignature, n as signObject, o as getKeyOwner, p as getNormalizationContextLoader, r as verifyObject, s as InvalidContextReferenceError, u as compactJsonLd, v as verifyCompactJsonLd, x as wrapContextLoaderForJsonLd } from "./proof-CE8nwTF6.js";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-Zw0soD-7.js";
|
|
9
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
10
10
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
11
11
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
@@ -3002,7 +3002,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3002
3002
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
3003
3003
|
collectionSync: message.collectionSync,
|
|
3004
3004
|
orderingKey: message.orderingKey,
|
|
3005
|
-
context
|
|
3005
|
+
context,
|
|
3006
|
+
activityJsonLd: hasTopLevelProof(message.activity) ? message.activity : void 0
|
|
3006
3007
|
});
|
|
3007
3008
|
}
|
|
3008
3009
|
async #listenOutboxMessage(_, message, span) {
|
|
@@ -3409,7 +3410,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3409
3410
|
proofCreated = true;
|
|
3410
3411
|
}
|
|
3411
3412
|
}
|
|
3412
|
-
let jsonLd = await activity.toJsonLd({
|
|
3413
|
+
let jsonLd = options.activityJsonLd != null ? detachSignature(options.activityJsonLd) : await activity.toJsonLd({
|
|
3413
3414
|
format: "compact",
|
|
3414
3415
|
contextLoader
|
|
3415
3416
|
});
|
|
@@ -4126,7 +4127,17 @@ var ContextImpl = class ContextImpl {
|
|
|
4126
4127
|
allowPrivateAddress: this.federation.allowPrivateAddress
|
|
4127
4128
|
});
|
|
4128
4129
|
}
|
|
4129
|
-
sendActivity(sender, recipients, activity, options = {}) {
|
|
4130
|
+
async sendActivity(sender, recipients, activity, options = {}) {
|
|
4131
|
+
let activityJsonLd = void 0;
|
|
4132
|
+
let hasProof = activity.proofIds.length > 0;
|
|
4133
|
+
if (!hasProof) for await (const _ of activity.getProofs({ contextLoader: this.contextLoader })) {
|
|
4134
|
+
hasProof = true;
|
|
4135
|
+
break;
|
|
4136
|
+
}
|
|
4137
|
+
if (hasProof) {
|
|
4138
|
+
activityJsonLd = await activity.toJsonLd({ contextLoader: this.contextLoader });
|
|
4139
|
+
if (!hasTopLevelProof(activityJsonLd)) activityJsonLd = void 0;
|
|
4140
|
+
}
|
|
4130
4141
|
return this.tracerProvider.getTracer(name, version).startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
4131
4142
|
kind: this.federation.outboxQueue == null || options.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
4132
4143
|
attributes: {
|
|
@@ -4139,7 +4150,7 @@ var ContextImpl = class ContextImpl {
|
|
|
4139
4150
|
}, async (span) => {
|
|
4140
4151
|
try {
|
|
4141
4152
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
4142
|
-
await this.sendActivityInternal(sender, recipients, activity, options, span);
|
|
4153
|
+
await this.sendActivityInternal(sender, recipients, activity, options, span, activityJsonLd);
|
|
4143
4154
|
} catch (e) {
|
|
4144
4155
|
span.setStatus({
|
|
4145
4156
|
code: SpanStatusCode.ERROR,
|
|
@@ -4151,7 +4162,7 @@ var ContextImpl = class ContextImpl {
|
|
|
4151
4162
|
}
|
|
4152
4163
|
});
|
|
4153
4164
|
}
|
|
4154
|
-
async sendActivityInternal(sender, recipients, activity, options, span) {
|
|
4165
|
+
async sendActivityInternal(sender, recipients, activity, options, span, activityJsonLd) {
|
|
4155
4166
|
const logger = getLogger([
|
|
4156
4167
|
"fedify",
|
|
4157
4168
|
"federation",
|
|
@@ -4198,14 +4209,23 @@ var ContextImpl = class ContextImpl {
|
|
|
4198
4209
|
if (!(error instanceof RouterError)) throw error;
|
|
4199
4210
|
}
|
|
4200
4211
|
} else expandedRecipients = [recipients];
|
|
4201
|
-
const opts = {
|
|
4202
|
-
context: this,
|
|
4203
|
-
orderingKey: options.orderingKey,
|
|
4204
|
-
collectionSync,
|
|
4205
|
-
immediate: options.immediate
|
|
4206
|
-
};
|
|
4207
4212
|
span.setAttribute("activitypub.inboxes", expandedRecipients.length);
|
|
4208
4213
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
4214
|
+
let contextMatches = false;
|
|
4215
|
+
if (activityJsonLd != null) {
|
|
4216
|
+
const capturedJsonLd = activityJsonLd;
|
|
4217
|
+
const transformedJsonLd = await activity.toJsonLd({
|
|
4218
|
+
format: "compact",
|
|
4219
|
+
contextLoader: this.contextLoader
|
|
4220
|
+
});
|
|
4221
|
+
const contentChanged = getContentFields(transformedJsonLd) !== getContentFields(capturedJsonLd);
|
|
4222
|
+
contextMatches = getContextFields(transformedJsonLd) === getContextFields(capturedJsonLd);
|
|
4223
|
+
const proofsChanged = getProofFields(transformedJsonLd) !== getProofFields(capturedJsonLd);
|
|
4224
|
+
if (contentChanged || !contextMatches && proofsChanged) {
|
|
4225
|
+
activity = activity.clone({ proofs: await getUncapturedProofs(activity, capturedJsonLd, this.contextLoader) });
|
|
4226
|
+
activityJsonLd = void 0;
|
|
4227
|
+
} else if (proofsChanged) activityJsonLd = void 0;
|
|
4228
|
+
}
|
|
4209
4229
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
4210
4230
|
if (activity.actorId == null) {
|
|
4211
4231
|
logger.error("Activity {activityId} to send does not have an actor.", {
|
|
@@ -4216,14 +4236,27 @@ var ContextImpl = class ContextImpl {
|
|
|
4216
4236
|
}
|
|
4217
4237
|
if (actorKeyPairs != null) {
|
|
4218
4238
|
const contextLoader = this.contextLoader;
|
|
4239
|
+
if (actorKeyPairs.some((kp) => kp.privateKey.algorithm.name === "Ed25519" && kp.multikey.id != null)) {
|
|
4240
|
+
if (activityJsonLd != null && !contextMatches) activity = activity.clone({ proofs: [] });
|
|
4241
|
+
}
|
|
4242
|
+
let proofAdded = false;
|
|
4219
4243
|
for (const kp of actorKeyPairs) {
|
|
4220
4244
|
if (kp.privateKey.algorithm.name !== "Ed25519" || kp.multikey.id == null) continue;
|
|
4221
4245
|
activity = await signObject(activity, kp.privateKey, kp.multikey.id, {
|
|
4222
4246
|
contextLoader,
|
|
4223
4247
|
tracerProvider: this.tracerProvider
|
|
4224
4248
|
});
|
|
4249
|
+
proofAdded = true;
|
|
4225
4250
|
}
|
|
4251
|
+
if (proofAdded) activityJsonLd = void 0;
|
|
4226
4252
|
}
|
|
4253
|
+
const opts = {
|
|
4254
|
+
context: this,
|
|
4255
|
+
orderingKey: options.orderingKey,
|
|
4256
|
+
collectionSync,
|
|
4257
|
+
immediate: options.immediate,
|
|
4258
|
+
activityJsonLd
|
|
4259
|
+
};
|
|
4227
4260
|
const inboxes = extractInboxes({
|
|
4228
4261
|
recipients: expandedRecipients,
|
|
4229
4262
|
preferSharedInbox: options.preferSharedInbox,
|
|
@@ -4253,7 +4286,7 @@ var ContextImpl = class ContextImpl {
|
|
|
4253
4286
|
actorIds: [...actorIds],
|
|
4254
4287
|
sharedInbox
|
|
4255
4288
|
}])),
|
|
4256
|
-
activity: await activity.toJsonLd({
|
|
4289
|
+
activity: activityJsonLd != null ? detachSignature(activityJsonLd) : await activity.toJsonLd({
|
|
4257
4290
|
format: "compact",
|
|
4258
4291
|
contextLoader: this.contextLoader
|
|
4259
4292
|
}),
|
|
@@ -4739,6 +4772,69 @@ var KvSpecDeterminer = class {
|
|
|
4739
4772
|
function notFound(_request) {
|
|
4740
4773
|
return new Response("Not Found", { status: 404 });
|
|
4741
4774
|
}
|
|
4775
|
+
function hasTopLevelProof(value) {
|
|
4776
|
+
return typeof value === "object" && value != null && !Array.isArray(value) && globalThis.Object.prototype.hasOwnProperty.call(value, "proof");
|
|
4777
|
+
}
|
|
4778
|
+
function getContentFields(value) {
|
|
4779
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return JSON.stringify(sortJsonKeys(value));
|
|
4780
|
+
const record = { ...value };
|
|
4781
|
+
delete record["@context"];
|
|
4782
|
+
delete record.proof;
|
|
4783
|
+
delete record.signature;
|
|
4784
|
+
return JSON.stringify(sortJsonKeys(record));
|
|
4785
|
+
}
|
|
4786
|
+
function getContextFields(value) {
|
|
4787
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return JSON.stringify(sortJsonKeys(value));
|
|
4788
|
+
const context = value["@context"];
|
|
4789
|
+
return JSON.stringify(sortJsonKeys(context ?? null));
|
|
4790
|
+
}
|
|
4791
|
+
function getProofEntries(value) {
|
|
4792
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return [];
|
|
4793
|
+
const proof = value.proof;
|
|
4794
|
+
if (proof == null) return [];
|
|
4795
|
+
return Array.isArray(proof) ? proof : [proof];
|
|
4796
|
+
}
|
|
4797
|
+
function normalizeProofEntry(proof) {
|
|
4798
|
+
const stripped = stripContexts(proof);
|
|
4799
|
+
if (typeof stripped !== "object" || stripped == null || Array.isArray(stripped)) return stripped;
|
|
4800
|
+
const record = { ...stripped };
|
|
4801
|
+
if (typeof record.created === "string") try {
|
|
4802
|
+
record.created = Temporal.Instant.from(record.created).toString();
|
|
4803
|
+
} catch {}
|
|
4804
|
+
return record;
|
|
4805
|
+
}
|
|
4806
|
+
function getProofEntryFields(proof) {
|
|
4807
|
+
return JSON.stringify(sortJsonKeys(normalizeProofEntry(proof)));
|
|
4808
|
+
}
|
|
4809
|
+
function getProofFields(value) {
|
|
4810
|
+
return JSON.stringify(getProofEntries(value).map(getProofEntryFields).sort());
|
|
4811
|
+
}
|
|
4812
|
+
async function getUncapturedProofs(activity, capturedJsonLd, contextLoader) {
|
|
4813
|
+
const capturedProofs = new Set(getProofEntries(capturedJsonLd).map(getProofEntryFields));
|
|
4814
|
+
const retainedProofs = [];
|
|
4815
|
+
for await (const proof of activity.getProofs({ contextLoader })) {
|
|
4816
|
+
const proofJsonLd = await proof.toJsonLd({
|
|
4817
|
+
format: "compact",
|
|
4818
|
+
contextLoader
|
|
4819
|
+
});
|
|
4820
|
+
if (!capturedProofs.has(getProofEntryFields(proofJsonLd))) retainedProofs.push(proof);
|
|
4821
|
+
}
|
|
4822
|
+
return retainedProofs;
|
|
4823
|
+
}
|
|
4824
|
+
function stripContexts(value) {
|
|
4825
|
+
if (Array.isArray(value)) return value.map(stripContexts);
|
|
4826
|
+
if (typeof value !== "object" || value == null) return value;
|
|
4827
|
+
const record = { ...value };
|
|
4828
|
+
delete record["@context"];
|
|
4829
|
+
delete record.signature;
|
|
4830
|
+
for (const key of globalThis.Object.keys(record)) record[key] = stripContexts(record[key]);
|
|
4831
|
+
return record;
|
|
4832
|
+
}
|
|
4833
|
+
function sortJsonKeys(value) {
|
|
4834
|
+
if (Array.isArray(value)) return value.map(sortJsonKeys);
|
|
4835
|
+
if (typeof value !== "object" || value == null) return value;
|
|
4836
|
+
return globalThis.Object.fromEntries(globalThis.Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => [key, sortJsonKeys(item)]));
|
|
4837
|
+
}
|
|
4742
4838
|
function notAcceptable(_request) {
|
|
4743
4839
|
return new Response("Not Acceptable", {
|
|
4744
4840
|
status: 406,
|
|
@@ -2,24 +2,24 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { n as RouterError } from "./router-CrMLXoOr.mjs";
|
|
5
|
-
import { n as version, t as name } from "./deno
|
|
6
|
-
import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-
|
|
7
|
-
import { u as verifyRequest } from "./http-
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader } from "./docloader-
|
|
5
|
+
import { n as version, t as name } from "./deno--OYa_lxj.mjs";
|
|
6
|
+
import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-D5e9c_yV.mjs";
|
|
7
|
+
import { u as verifyRequest } from "./http-C3d2DXwF.mjs";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader } from "./docloader-BXR2f83H.mjs";
|
|
9
9
|
import { n as kvCache } from "./kv-cache-BrjuJue8.mjs";
|
|
10
|
-
import { a as compactJsonLd, c as getNormalizationContextLoader, d as isInvalidUrlTypeError, f as signJsonLd, g as wrapContextLoaderForJsonLd, l as hasSignature, p as verifyCompactJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as isClearlyMalformedContextReference } from "./ld-
|
|
11
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-
|
|
12
|
-
import { n as signObject, r as verifyObject } from "./proof-
|
|
10
|
+
import { a as compactJsonLd, c as getNormalizationContextLoader, d as isInvalidUrlTypeError, f as signJsonLd, g as wrapContextLoaderForJsonLd, l as hasSignature, p as verifyCompactJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as isClearlyMalformedContextReference } from "./ld-9qfz9rP_.mjs";
|
|
11
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-R4ffU9Ht.mjs";
|
|
12
|
+
import { n as signObject, r as verifyObject } from "./proof-CiBs9Q4l.mjs";
|
|
13
13
|
import { d as MAX_BODY_SIZE, f as readBoundedText, t as getNodeInfo, u as BodyTooLargeError } from "./client-DGNacEx_.mjs";
|
|
14
14
|
import { t as nodeInfoToJson } from "./types-MNlFfxjv.mjs";
|
|
15
|
-
import { n as actorsHaveSameOrigin, r as routeActivity } from "./inbox-
|
|
16
|
-
import { t as FederationBuilderImpl } from "./builder-
|
|
15
|
+
import { n as actorsHaveSameOrigin, r as routeActivity } from "./inbox-huUE3IP8.mjs";
|
|
16
|
+
import { t as FederationBuilderImpl } from "./builder-B5hI5Xsn.mjs";
|
|
17
17
|
import { t as buildCollectionSynchronizationHeader } from "./collection-DI6YzYpd.mjs";
|
|
18
18
|
import { t as KvKeyCache } from "./keycache-DBD6fzl1.mjs";
|
|
19
19
|
import { t as acceptsJsonLd } from "./negotiation-TWEs6Cl8.mjs";
|
|
20
|
-
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-
|
|
20
|
+
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-Dd-J410Z.mjs";
|
|
21
21
|
import { t as createExponentialBackoffPolicy } from "./retry-Ddbq3AcK.mjs";
|
|
22
|
-
import { i as sendActivity, n as extractInboxes, t as SendActivityError } from "./send-
|
|
22
|
+
import { i as sendActivity, n as extractInboxes, t as SendActivityError } from "./send-DpvZgVSA.mjs";
|
|
23
23
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
24
24
|
import { lookupWebFinger } from "@fedify/webfinger";
|
|
25
25
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
@@ -1665,7 +1665,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
1665
1665
|
await this.sendActivity(keys, message.inboxes, activity, {
|
|
1666
1666
|
collectionSync: message.collectionSync,
|
|
1667
1667
|
orderingKey: message.orderingKey,
|
|
1668
|
-
context
|
|
1668
|
+
context,
|
|
1669
|
+
activityJsonLd: hasTopLevelProof(message.activity) ? message.activity : void 0
|
|
1669
1670
|
});
|
|
1670
1671
|
}
|
|
1671
1672
|
async #listenOutboxMessage(_, message, span) {
|
|
@@ -2072,7 +2073,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2072
2073
|
proofCreated = true;
|
|
2073
2074
|
}
|
|
2074
2075
|
}
|
|
2075
|
-
let jsonLd = await activity.toJsonLd({
|
|
2076
|
+
let jsonLd = options.activityJsonLd != null ? detachSignature(options.activityJsonLd) : await activity.toJsonLd({
|
|
2076
2077
|
format: "compact",
|
|
2077
2078
|
contextLoader
|
|
2078
2079
|
});
|
|
@@ -2789,7 +2790,17 @@ var ContextImpl = class ContextImpl {
|
|
|
2789
2790
|
allowPrivateAddress: this.federation.allowPrivateAddress
|
|
2790
2791
|
});
|
|
2791
2792
|
}
|
|
2792
|
-
sendActivity(sender, recipients, activity, options = {}) {
|
|
2793
|
+
async sendActivity(sender, recipients, activity, options = {}) {
|
|
2794
|
+
let activityJsonLd = void 0;
|
|
2795
|
+
let hasProof = activity.proofIds.length > 0;
|
|
2796
|
+
if (!hasProof) for await (const _ of activity.getProofs({ contextLoader: this.contextLoader })) {
|
|
2797
|
+
hasProof = true;
|
|
2798
|
+
break;
|
|
2799
|
+
}
|
|
2800
|
+
if (hasProof) {
|
|
2801
|
+
activityJsonLd = await activity.toJsonLd({ contextLoader: this.contextLoader });
|
|
2802
|
+
if (!hasTopLevelProof(activityJsonLd)) activityJsonLd = void 0;
|
|
2803
|
+
}
|
|
2793
2804
|
return this.tracerProvider.getTracer(name, version).startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
2794
2805
|
kind: this.federation.outboxQueue == null || options.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|
|
2795
2806
|
attributes: {
|
|
@@ -2802,7 +2813,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2802
2813
|
}, async (span) => {
|
|
2803
2814
|
try {
|
|
2804
2815
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
2805
|
-
await this.sendActivityInternal(sender, recipients, activity, options, span);
|
|
2816
|
+
await this.sendActivityInternal(sender, recipients, activity, options, span, activityJsonLd);
|
|
2806
2817
|
} catch (e) {
|
|
2807
2818
|
span.setStatus({
|
|
2808
2819
|
code: SpanStatusCode.ERROR,
|
|
@@ -2814,7 +2825,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2814
2825
|
}
|
|
2815
2826
|
});
|
|
2816
2827
|
}
|
|
2817
|
-
async sendActivityInternal(sender, recipients, activity, options, span) {
|
|
2828
|
+
async sendActivityInternal(sender, recipients, activity, options, span, activityJsonLd) {
|
|
2818
2829
|
const logger = getLogger([
|
|
2819
2830
|
"fedify",
|
|
2820
2831
|
"federation",
|
|
@@ -2861,14 +2872,23 @@ var ContextImpl = class ContextImpl {
|
|
|
2861
2872
|
if (!(error instanceof RouterError)) throw error;
|
|
2862
2873
|
}
|
|
2863
2874
|
} else expandedRecipients = [recipients];
|
|
2864
|
-
const opts = {
|
|
2865
|
-
context: this,
|
|
2866
|
-
orderingKey: options.orderingKey,
|
|
2867
|
-
collectionSync,
|
|
2868
|
-
immediate: options.immediate
|
|
2869
|
-
};
|
|
2870
2875
|
span.setAttribute("activitypub.inboxes", expandedRecipients.length);
|
|
2871
2876
|
for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
|
|
2877
|
+
let contextMatches = false;
|
|
2878
|
+
if (activityJsonLd != null) {
|
|
2879
|
+
const capturedJsonLd = activityJsonLd;
|
|
2880
|
+
const transformedJsonLd = await activity.toJsonLd({
|
|
2881
|
+
format: "compact",
|
|
2882
|
+
contextLoader: this.contextLoader
|
|
2883
|
+
});
|
|
2884
|
+
const contentChanged = getContentFields(transformedJsonLd) !== getContentFields(capturedJsonLd);
|
|
2885
|
+
contextMatches = getContextFields(transformedJsonLd) === getContextFields(capturedJsonLd);
|
|
2886
|
+
const proofsChanged = getProofFields(transformedJsonLd) !== getProofFields(capturedJsonLd);
|
|
2887
|
+
if (contentChanged || !contextMatches && proofsChanged) {
|
|
2888
|
+
activity = activity.clone({ proofs: await getUncapturedProofs(activity, capturedJsonLd, this.contextLoader) });
|
|
2889
|
+
activityJsonLd = void 0;
|
|
2890
|
+
} else if (proofsChanged) activityJsonLd = void 0;
|
|
2891
|
+
}
|
|
2872
2892
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
|
2873
2893
|
if (activity.actorId == null) {
|
|
2874
2894
|
logger.error("Activity {activityId} to send does not have an actor.", {
|
|
@@ -2879,14 +2899,27 @@ var ContextImpl = class ContextImpl {
|
|
|
2879
2899
|
}
|
|
2880
2900
|
if (actorKeyPairs != null) {
|
|
2881
2901
|
const contextLoader = this.contextLoader;
|
|
2902
|
+
if (actorKeyPairs.some((kp) => kp.privateKey.algorithm.name === "Ed25519" && kp.multikey.id != null)) {
|
|
2903
|
+
if (activityJsonLd != null && !contextMatches) activity = activity.clone({ proofs: [] });
|
|
2904
|
+
}
|
|
2905
|
+
let proofAdded = false;
|
|
2882
2906
|
for (const kp of actorKeyPairs) {
|
|
2883
2907
|
if (kp.privateKey.algorithm.name !== "Ed25519" || kp.multikey.id == null) continue;
|
|
2884
2908
|
activity = await signObject(activity, kp.privateKey, kp.multikey.id, {
|
|
2885
2909
|
contextLoader,
|
|
2886
2910
|
tracerProvider: this.tracerProvider
|
|
2887
2911
|
});
|
|
2912
|
+
proofAdded = true;
|
|
2888
2913
|
}
|
|
2914
|
+
if (proofAdded) activityJsonLd = void 0;
|
|
2889
2915
|
}
|
|
2916
|
+
const opts = {
|
|
2917
|
+
context: this,
|
|
2918
|
+
orderingKey: options.orderingKey,
|
|
2919
|
+
collectionSync,
|
|
2920
|
+
immediate: options.immediate,
|
|
2921
|
+
activityJsonLd
|
|
2922
|
+
};
|
|
2890
2923
|
const inboxes = extractInboxes({
|
|
2891
2924
|
recipients: expandedRecipients,
|
|
2892
2925
|
preferSharedInbox: options.preferSharedInbox,
|
|
@@ -2916,7 +2949,7 @@ var ContextImpl = class ContextImpl {
|
|
|
2916
2949
|
actorIds: [...actorIds],
|
|
2917
2950
|
sharedInbox
|
|
2918
2951
|
}])),
|
|
2919
|
-
activity: await activity.toJsonLd({
|
|
2952
|
+
activity: activityJsonLd != null ? detachSignature(activityJsonLd) : await activity.toJsonLd({
|
|
2920
2953
|
format: "compact",
|
|
2921
2954
|
contextLoader: this.contextLoader
|
|
2922
2955
|
}),
|
|
@@ -3402,6 +3435,69 @@ var KvSpecDeterminer = class {
|
|
|
3402
3435
|
function notFound(_request) {
|
|
3403
3436
|
return new Response("Not Found", { status: 404 });
|
|
3404
3437
|
}
|
|
3438
|
+
function hasTopLevelProof(value) {
|
|
3439
|
+
return typeof value === "object" && value != null && !Array.isArray(value) && globalThis.Object.prototype.hasOwnProperty.call(value, "proof");
|
|
3440
|
+
}
|
|
3441
|
+
function getContentFields(value) {
|
|
3442
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return JSON.stringify(sortJsonKeys(value));
|
|
3443
|
+
const record = { ...value };
|
|
3444
|
+
delete record["@context"];
|
|
3445
|
+
delete record.proof;
|
|
3446
|
+
delete record.signature;
|
|
3447
|
+
return JSON.stringify(sortJsonKeys(record));
|
|
3448
|
+
}
|
|
3449
|
+
function getContextFields(value) {
|
|
3450
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return JSON.stringify(sortJsonKeys(value));
|
|
3451
|
+
const context = value["@context"];
|
|
3452
|
+
return JSON.stringify(sortJsonKeys(context ?? null));
|
|
3453
|
+
}
|
|
3454
|
+
function getProofEntries(value) {
|
|
3455
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return [];
|
|
3456
|
+
const proof = value.proof;
|
|
3457
|
+
if (proof == null) return [];
|
|
3458
|
+
return Array.isArray(proof) ? proof : [proof];
|
|
3459
|
+
}
|
|
3460
|
+
function normalizeProofEntry(proof) {
|
|
3461
|
+
const stripped = stripContexts(proof);
|
|
3462
|
+
if (typeof stripped !== "object" || stripped == null || Array.isArray(stripped)) return stripped;
|
|
3463
|
+
const record = { ...stripped };
|
|
3464
|
+
if (typeof record.created === "string") try {
|
|
3465
|
+
record.created = Temporal.Instant.from(record.created).toString();
|
|
3466
|
+
} catch {}
|
|
3467
|
+
return record;
|
|
3468
|
+
}
|
|
3469
|
+
function getProofEntryFields(proof) {
|
|
3470
|
+
return JSON.stringify(sortJsonKeys(normalizeProofEntry(proof)));
|
|
3471
|
+
}
|
|
3472
|
+
function getProofFields(value) {
|
|
3473
|
+
return JSON.stringify(getProofEntries(value).map(getProofEntryFields).sort());
|
|
3474
|
+
}
|
|
3475
|
+
async function getUncapturedProofs(activity, capturedJsonLd, contextLoader) {
|
|
3476
|
+
const capturedProofs = new Set(getProofEntries(capturedJsonLd).map(getProofEntryFields));
|
|
3477
|
+
const retainedProofs = [];
|
|
3478
|
+
for await (const proof of activity.getProofs({ contextLoader })) {
|
|
3479
|
+
const proofJsonLd = await proof.toJsonLd({
|
|
3480
|
+
format: "compact",
|
|
3481
|
+
contextLoader
|
|
3482
|
+
});
|
|
3483
|
+
if (!capturedProofs.has(getProofEntryFields(proofJsonLd))) retainedProofs.push(proof);
|
|
3484
|
+
}
|
|
3485
|
+
return retainedProofs;
|
|
3486
|
+
}
|
|
3487
|
+
function stripContexts(value) {
|
|
3488
|
+
if (Array.isArray(value)) return value.map(stripContexts);
|
|
3489
|
+
if (typeof value !== "object" || value == null) return value;
|
|
3490
|
+
const record = { ...value };
|
|
3491
|
+
delete record["@context"];
|
|
3492
|
+
delete record.signature;
|
|
3493
|
+
for (const key of globalThis.Object.keys(record)) record[key] = stripContexts(record[key]);
|
|
3494
|
+
return record;
|
|
3495
|
+
}
|
|
3496
|
+
function sortJsonKeys(value) {
|
|
3497
|
+
if (Array.isArray(value)) return value.map(sortJsonKeys);
|
|
3498
|
+
if (typeof value !== "object" || value == null) return value;
|
|
3499
|
+
return globalThis.Object.fromEntries(globalThis.Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => [key, sortJsonKeys(item)]));
|
|
3500
|
+
}
|
|
3405
3501
|
function notAcceptable(_request) {
|
|
3406
3502
|
return new Response("Not Acceptable", {
|
|
3407
3503
|
status: 406,
|