@fedify/fedify 2.4.0-dev.2084 → 2.4.0-dev.2099
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-BGlpUocK.mjs → builder-Bno54o_-.mjs} +34 -3
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-B6Aj2kGY.mjs → compound-proof-X3SxXVbc.mjs} +191 -13
- package/dist/{context-CZjZYXFC.d.cts → context-C43spTGI.d.cts} +5 -2
- package/dist/{context-BSywYspi.d.ts → context-MORIQJIh.d.ts} +5 -2
- package/dist/{deno-Dn-py9Zy.mjs → deno-dxdvl2XZ.mjs} +1 -1
- package/dist/{docloader-BUq5bYJr.mjs → docloader-eBxQDsk9.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/hashlink-media.test.mjs +2 -2
- 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.d.cts +2 -2
- package/dist/federation/mod.d.ts +2 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +254 -5
- package/dist/federation/portable-gateway-keys.test.mjs +72 -11
- package/dist/federation/portable-inbox.test.mjs +487 -10
- package/dist/federation/portable.test.mjs +182 -4
- 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 +89 -1
- package/dist/{federation-BLGx8JUH.cjs → federation-C4Ef3JKa.cjs} +1487 -1070
- package/dist/{http-B5q1CHtL.cjs → http-C8cZTE3Y.cjs} +1224 -985
- package/dist/{http-4PCCvhsU.js → http-D-rbr_Sy.js} +1663 -1460
- package/dist/{http-B0VRNipE.mjs → http-DsgawTd8.mjs} +82 -7
- package/dist/{key-BJrp524f.mjs → key-DYfmjnmp.mjs} +39 -99
- package/dist/{kv-cache-1KUmAPH7.js → kv-cache-DIxwMeNi.js} +1 -1
- package/dist/{kv-cache-Dhhhrryv.cjs → kv-cache-Dvd-Q-E2.cjs} +1 -1
- package/dist/{kv-cache-C4C3LyYW.mjs → kv-cache-EvOgrFsS.mjs} +1 -1
- package/dist/{ld-BmFz5NLA.mjs → ld-B00wWHzc.mjs} +3 -3
- package/dist/{metrics-Beod6tzO.mjs → metrics-BP3vdBpb.mjs} +1 -1
- package/dist/{middleware-BKeQYPm0.mjs → middleware-Br1_d-Ga.mjs} +606 -389
- package/dist/{middleware-D_9pNYe9.js → middleware-CcXMe400.js} +1602 -1185
- package/dist/{middleware-B7CNsyqt.mjs → middleware-CeBVBa61.mjs} +1 -1
- package/dist/{mod-B2h2KY0q.d.ts → mod-BL5BQHCq.d.ts} +1 -1
- package/dist/{mod-HDSvS-ww.d.cts → mod-C8LieBzF.d.cts} +16 -3
- package/dist/{mod-C9WSpZWm.d.ts → mod-Coacostr.d.ts} +16 -3
- package/dist/{mod-JzkaEXsi.d.cts → mod-DMI4DbOo.d.cts} +1 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +3 -3
- package/dist/mod.d.ts +3 -3
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-CsKVgMzk.mjs → owner-BJPDRDRq.mjs} +5 -4
- package/dist/{owner-BQFZtFV4.cjs → owner-DSzH7wro.cjs} +2 -2
- package/dist/{owner-_pbbgLJK.js → owner-U12fDpQW.js} +2 -2
- package/dist/{portable-key-B4R-CiIV.mjs → portable-key-D0mWbV9G.mjs} +60 -41
- package/dist/portable-key-id-Bva5iT3W.mjs +136 -0
- package/dist/{proof-ozG4HfcQ.mjs → proof-ChjBwnep.mjs} +59 -18
- package/dist/{send-ClPt8nYu.mjs → send-yFX0E-ye.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +160 -3
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +72 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +3 -3
- package/dist/sig/mod.d.cts +1 -1
- package/dist/sig/mod.d.ts +1 -1
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +69 -5
- package/dist/sig/portable-key.test.mjs +176 -10
- package/dist/sig/proof.test.mjs +107 -4
- package/dist/{sig-k3C8sF7g.cjs → sig-B689Nj7y.cjs} +19 -3
- package/dist/{sig-DhdomAN0.js → sig-C85KqAcx.js} +19 -3
- package/dist/{temporal-Ba0EAZAI.mjs → temporal-Dl9x-Qw4.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +5 -2
- 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 +7 -7
|
@@ -1,17 +1,17 @@
|
|
|
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 {
|
|
4
|
+
import { n as version, t as name } from "../deno-dxdvl2XZ.mjs";
|
|
5
|
+
import { l as verifyPortableObjectProofWithRoot, s as verifyPortableObjectProof } from "../proof-ChjBwnep.mjs";
|
|
6
6
|
import { n as ed25519PrivateKey, r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { Collection, CollectionPage, Note, Object as Object$1, OrderedCollection, Person, isActor, traverseCollection } from "@fedify/vocab";
|
|
9
9
|
import { trace } from "@opentelemetry/api";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
import { FetchError, canonicalizePortableUri, encodeMultibase, exportDidKey, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, parseIri, preloadedContexts } from "@fedify/vocab-runtime";
|
|
12
|
+
import { dereferencePortableIri, getPortableGatewayCandidates } from "@fedify/vocab-runtime/internal/portable-dereference";
|
|
12
13
|
import serialize from "json-canon";
|
|
13
14
|
import { deepStrictEqual, ok, strictEqual } from "node:assert/strict";
|
|
14
|
-
import { dereferencePortableIri, getPortableGatewayCandidates } from "@fedify/vocab-runtime/internal/portable-dereference";
|
|
15
15
|
//#region src/sig/portable-collection.ts
|
|
16
16
|
const logger = getLogger([
|
|
17
17
|
"fedify",
|
|
@@ -54,6 +54,8 @@ function getContextState(context) {
|
|
|
54
54
|
}
|
|
55
55
|
function canonicalize(id) {
|
|
56
56
|
try {
|
|
57
|
+
const portable = fromCompatibleEf61Id(id);
|
|
58
|
+
if (portable != null) return canonicalizePortableUri(formatIri(portable));
|
|
57
59
|
return canonicalizePortableUri(typeof id === "string" ? id : formatIri(id));
|
|
58
60
|
} catch (error) {
|
|
59
61
|
if (error instanceof TypeError) return null;
|
|
@@ -234,7 +236,20 @@ async function fetchOwner(candidate, options) {
|
|
|
234
236
|
const contextLoader = options.contextLoader ?? getDocumentLoader();
|
|
235
237
|
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
236
238
|
const tracer = tracerProvider.getTracer(name, version);
|
|
237
|
-
|
|
239
|
+
let inferredGateways;
|
|
240
|
+
try {
|
|
241
|
+
const portable = fromCompatibleEf61Id(candidate);
|
|
242
|
+
if (portable != null) {
|
|
243
|
+
inferredGateways = [new URL(candidate.origin)];
|
|
244
|
+
candidate = portable;
|
|
245
|
+
}
|
|
246
|
+
} catch (error) {
|
|
247
|
+
if (!(error instanceof TypeError)) throw error;
|
|
248
|
+
logger.debug("The owner {owner} of a portable collection is a malformed compatible identifier.", { owner: candidate.href });
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
const gateways = options.gateways ?? (inferredGateways != null || getPortableGatewayCandidates(candidate).length > 0 ? void 0 : options.gatewayHints);
|
|
252
|
+
if (options.gateways != null) inferredGateways = void 0;
|
|
238
253
|
const span = tracer.startSpan("activitypub.lookup_object");
|
|
239
254
|
try {
|
|
240
255
|
const object = await dereferencePortableIri(candidate, {
|
|
@@ -242,6 +257,7 @@ async function fetchOwner(candidate, options) {
|
|
|
242
257
|
contextLoader,
|
|
243
258
|
tracerProvider,
|
|
244
259
|
gateways,
|
|
260
|
+
...inferredGateways == null ? {} : { inferredGateways },
|
|
245
261
|
verifyPortableObject: (document, verifierOptions) => verifyPortableObjectProof(document, {
|
|
246
262
|
...options,
|
|
247
263
|
...verifierOptions
|
|
@@ -569,13 +585,61 @@ test("verifyPortableObject() uses the actual fetch source", async () => {
|
|
|
569
585
|
referrer,
|
|
570
586
|
documentUrl: new URL(`https://user@gw1.example/.well-known/apgateway/${did}/actor/outbox`)
|
|
571
587
|
}), "unknownCollectionSource");
|
|
572
|
-
|
|
588
|
+
const result = await verify(outbox({ id: gatewayUrl(evil, outboxId) }), {
|
|
589
|
+
documentLoader,
|
|
590
|
+
gateways,
|
|
591
|
+
referrer,
|
|
592
|
+
documentUrl: new URL(gatewayUrl(gw1, outboxId))
|
|
593
|
+
});
|
|
594
|
+
ok(result.verified);
|
|
595
|
+
strictEqual(result.method, "gateway");
|
|
596
|
+
if (result.method !== "gateway") return;
|
|
597
|
+
deepStrictEqual(result.gateway, new URL(gw1));
|
|
598
|
+
assertFailure(await verify(outbox({ id: `${evil}/outbox` }), {
|
|
573
599
|
documentLoader,
|
|
574
600
|
gateways,
|
|
575
601
|
referrer,
|
|
576
602
|
documentUrl: new URL(gatewayUrl(gw1, outboxId))
|
|
577
603
|
}), "notPortableObject");
|
|
578
604
|
});
|
|
605
|
+
test("verifyPortableObject() trusts unsecured collections of compatible-ID actors", async () => {
|
|
606
|
+
const compatibleActorId = gatewayUrl(gw1, actorId);
|
|
607
|
+
const compatibleOutboxId = gatewayUrl(gw1, outboxId);
|
|
608
|
+
const signed = await sign(actor({
|
|
609
|
+
id: compatibleActorId,
|
|
610
|
+
inbox: gatewayUrl(gw1, `ap://${did}/actor/inbox`),
|
|
611
|
+
outbox: compatibleOutboxId,
|
|
612
|
+
followers: gatewayUrl(gw1, `ap://${did}/actor/followers`)
|
|
613
|
+
}));
|
|
614
|
+
const collection = outbox({
|
|
615
|
+
id: compatibleOutboxId,
|
|
616
|
+
attributedTo: compatibleActorId
|
|
617
|
+
});
|
|
618
|
+
const documentLoader = createLoader({ [compatibleActorId]: signed });
|
|
619
|
+
const result = await verify(collection, {
|
|
620
|
+
documentLoader,
|
|
621
|
+
documentUrl: new URL(compatibleOutboxId)
|
|
622
|
+
});
|
|
623
|
+
ok(result.verified, JSON.stringify(result));
|
|
624
|
+
strictEqual(result.method, "gateway");
|
|
625
|
+
if (result.method !== "gateway") return;
|
|
626
|
+
deepStrictEqual(result.gateway, new URL(gw1));
|
|
627
|
+
deepStrictEqual(documentLoader.fetched, [compatibleActorId]);
|
|
628
|
+
const noGateways = createLoader({ [compatibleActorId]: signed });
|
|
629
|
+
assertFailure(await verify(collection, {
|
|
630
|
+
documentLoader: noGateways,
|
|
631
|
+
documentUrl: new URL(compatibleOutboxId),
|
|
632
|
+
gateways: []
|
|
633
|
+
}), "collectionOwnerUnavailable");
|
|
634
|
+
deepStrictEqual(noGateways.fetched.filter((url) => url === compatibleActorId), []);
|
|
635
|
+
assertFailure(await verify(collection, {
|
|
636
|
+
documentLoader: createLoader({ [compatibleActorId]: actor({
|
|
637
|
+
id: compatibleActorId,
|
|
638
|
+
outbox: compatibleOutboxId
|
|
639
|
+
}) }),
|
|
640
|
+
documentUrl: new URL(compatibleOutboxId)
|
|
641
|
+
}), "collectionOwnerUnavailable");
|
|
642
|
+
});
|
|
579
643
|
test("verifyPortableObject() requires an unambiguous owner", async () => {
|
|
580
644
|
const base = {
|
|
581
645
|
documentLoader: createLoader({ [gatewayUrl(gw1, actorId)]: signedActor }),
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { r as fetchKey } from "../key-
|
|
5
|
-
import {
|
|
4
|
+
import { r as fetchKey } from "../key-DYfmjnmp.mjs";
|
|
5
|
+
import { d as verifyRequest, l as signRequest } from "../http-DsgawTd8.mjs";
|
|
6
6
|
import { c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
7
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-
|
|
7
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-BJPDRDRq.mjs";
|
|
8
8
|
import { Create, CryptographicKey, Multikey, Person } from "@fedify/vocab";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
|
-
import { FetchError, encodeMultibase, exportDidKey, parseIri, preloadedContexts } from "@fedify/vocab-runtime";
|
|
10
|
+
import { FetchError, encodeMultibase, exportDidKey, exportSpki, parseIri, preloadedContexts } from "@fedify/vocab-runtime";
|
|
11
11
|
import serialize from "json-canon";
|
|
12
12
|
import { deepStrictEqual, ok, strictEqual } from "node:assert/strict";
|
|
13
13
|
//#region src/sig/portable-key.test.ts
|
|
@@ -129,7 +129,16 @@ test("verifyRequest() rejects gateway keys that portable actors do not vouch for
|
|
|
129
129
|
"an unsigned actor document": unsigned,
|
|
130
130
|
"an actor document signed by another DID": await sign(unsigned, otherKeyPair.privateKey, `${otherDid}#${otherDid.slice(8)}`),
|
|
131
131
|
"an unlisted gateway": await sign(await actorJson({ gateways: [gw2] })),
|
|
132
|
-
"a key missing from assertionMethod": await sign(await actorJson({
|
|
132
|
+
"a key missing from both assertionMethod and publicKey": await sign(await actorJson({
|
|
133
|
+
assertionMethod: false,
|
|
134
|
+
publicKey: null
|
|
135
|
+
})),
|
|
136
|
+
"a key referred to by URL in assertionMethod, embedded in publicKey": await sign({
|
|
137
|
+
...await actorJson({ assertionMethod: false }),
|
|
138
|
+
assertionMethod: [keyId.href]
|
|
139
|
+
}),
|
|
140
|
+
"a key only in publicKey without an owner": await sign(withoutPublicKeyOwner(await actorJson({ assertionMethod: false }))),
|
|
141
|
+
"two keys with the same ID in publicKey": await sign(await duplicatePublicKey(await actorJson({ assertionMethod: false }))),
|
|
133
142
|
"a key referred to by URL": await sign({
|
|
134
143
|
...await actorJson({
|
|
135
144
|
publicKey: null,
|
|
@@ -154,18 +163,175 @@ test("verifyRequest() rejects gateway keys that portable actors do not vouch for
|
|
|
154
163
|
contextLoader
|
|
155
164
|
}), null);
|
|
156
165
|
});
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
166
|
+
function withoutPublicKeyOwner(json) {
|
|
167
|
+
const { owner: _, ...publicKey } = json.publicKey;
|
|
168
|
+
return {
|
|
169
|
+
...json,
|
|
170
|
+
publicKey
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async function duplicatePublicKey(json) {
|
|
174
|
+
const publicKey = json.publicKey;
|
|
175
|
+
return {
|
|
176
|
+
...json,
|
|
177
|
+
publicKey: [publicKey, {
|
|
178
|
+
...publicKey,
|
|
179
|
+
publicKeyPem: await exportSpki(rsaPublicKey3.publicKey)
|
|
180
|
+
}]
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
test("verifyRequest() accepts gateway keys referred to by URL in publicKey", async () => {
|
|
184
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await sign({
|
|
185
|
+
...await actorJson({ publicKey: null }),
|
|
186
|
+
publicKey: keyId.href
|
|
162
187
|
}) });
|
|
188
|
+
strictEqual((await verifyRequest(await signedRequest(), {
|
|
189
|
+
documentLoader,
|
|
190
|
+
contextLoader
|
|
191
|
+
}))?.id?.href, keyId.href);
|
|
192
|
+
});
|
|
193
|
+
test("verifyRequest() accepts gateway keys only in publicKey", async () => {
|
|
194
|
+
const documentLoader = createLoader({ [compatibleId(gw1)]: await sign(await actorJson({ assertionMethod: false })) });
|
|
163
195
|
const key = await verifyRequest(await signedRequest(), {
|
|
164
196
|
documentLoader,
|
|
165
197
|
contextLoader
|
|
166
198
|
});
|
|
167
199
|
strictEqual(key?.id?.href, keyId.href);
|
|
200
|
+
strictEqual(key?.ownerId?.href, parseIri(actorId).href);
|
|
201
|
+
});
|
|
202
|
+
test("verifyRequest() resolves gateway keys of compatible-ID actors", async () => {
|
|
203
|
+
const id = compatibleId(gw1);
|
|
204
|
+
const signed = await sign(await actorJson({
|
|
205
|
+
id,
|
|
206
|
+
gateways: [gw1]
|
|
207
|
+
}));
|
|
208
|
+
let key = await verifyRequest(await signedRequest(), {
|
|
209
|
+
documentLoader: createLoader({ [id]: signed }),
|
|
210
|
+
contextLoader
|
|
211
|
+
});
|
|
212
|
+
strictEqual(key?.id?.href, keyId.href);
|
|
168
213
|
strictEqual(key?.ownerId?.href, id);
|
|
214
|
+
key = await verifyRequest(await signedRequest(), {
|
|
215
|
+
documentLoader: createLoader({ [id]: await sign(await actorJson({
|
|
216
|
+
id,
|
|
217
|
+
gateways: [gw1],
|
|
218
|
+
assertionMethod: false
|
|
219
|
+
})) }),
|
|
220
|
+
contextLoader
|
|
221
|
+
});
|
|
222
|
+
strictEqual(key?.id?.href, keyId.href);
|
|
223
|
+
const evil = "https://evil.example";
|
|
224
|
+
const evilId = compatibleId(evil);
|
|
225
|
+
const evilKeyId = new URL(`${evilId}#main-key`);
|
|
226
|
+
const unsigned = await actorJson({
|
|
227
|
+
id: evilId,
|
|
228
|
+
gateways: [evil],
|
|
229
|
+
key: evilKeyId
|
|
230
|
+
});
|
|
231
|
+
const documentLoader = createLoader({ [evilId]: unsigned });
|
|
232
|
+
strictEqual(await verifyRequest(await signedRequest(void 0, evilKeyId), {
|
|
233
|
+
documentLoader,
|
|
234
|
+
contextLoader
|
|
235
|
+
}), null);
|
|
236
|
+
strictEqual(await getKeyOwner(evilKeyId, {
|
|
237
|
+
documentLoader,
|
|
238
|
+
contextLoader
|
|
239
|
+
}), null);
|
|
240
|
+
strictEqual(await verifyRequest(await signedRequest(), {
|
|
241
|
+
documentLoader: createLoader({ [id]: await sign(await actorJson({
|
|
242
|
+
id,
|
|
243
|
+
gateways: [gw1]
|
|
244
|
+
}), otherKeyPair.privateKey, `${otherDid}#${otherDid.slice(8)}`) }),
|
|
245
|
+
contextLoader
|
|
246
|
+
}), null);
|
|
247
|
+
});
|
|
248
|
+
test("keys at ordinary URLs cannot belong to portable actors", async () => {
|
|
249
|
+
const evil = "https://evil.example";
|
|
250
|
+
const evilActorId = compatibleId(evil);
|
|
251
|
+
const evilKeyId = new URL(`${evil}/keys/1`);
|
|
252
|
+
const options = {
|
|
253
|
+
documentLoader: createLoader({
|
|
254
|
+
[evilKeyId.href]: {
|
|
255
|
+
"@context": "https://w3id.org/security/v1",
|
|
256
|
+
id: evilKeyId.href,
|
|
257
|
+
type: "Key",
|
|
258
|
+
owner: evilActorId,
|
|
259
|
+
publicKeyPem: await exportSpki(gatewayPublicKey)
|
|
260
|
+
},
|
|
261
|
+
[evilActorId]: await actorJson({
|
|
262
|
+
id: evilActorId,
|
|
263
|
+
gateways: [evil],
|
|
264
|
+
key: evilKeyId,
|
|
265
|
+
assertionMethod: false
|
|
266
|
+
})
|
|
267
|
+
}),
|
|
268
|
+
contextLoader
|
|
269
|
+
};
|
|
270
|
+
strictEqual(await verifyRequest(await signedRequest(void 0, evilKeyId), options), null);
|
|
271
|
+
strictEqual((await fetchKey(evilKeyId, CryptographicKey, options)).key, null);
|
|
272
|
+
strictEqual(await getKeyOwner(evilKeyId, options), null);
|
|
273
|
+
const key = new CryptographicKey({
|
|
274
|
+
id: evilKeyId,
|
|
275
|
+
owner: new URL(evilActorId),
|
|
276
|
+
publicKey: gatewayPublicKey
|
|
277
|
+
});
|
|
278
|
+
strictEqual(await getKeyOwner(key, options), null);
|
|
279
|
+
ok(!await doesActorOwnKey(new Create({
|
|
280
|
+
id: new URL(`${evil}/activities/1`),
|
|
281
|
+
actor: new URL(evilActorId)
|
|
282
|
+
}), key, options));
|
|
283
|
+
const actorKeyId = new URL(`${evil}/users/alice#main-key`);
|
|
284
|
+
for (const document of [await actorJson({
|
|
285
|
+
id: evilActorId,
|
|
286
|
+
gateways: [evil],
|
|
287
|
+
key: actorKeyId
|
|
288
|
+
}), withoutPublicKeyOwner(await actorJson({
|
|
289
|
+
id: evilActorId,
|
|
290
|
+
gateways: [evil],
|
|
291
|
+
key: actorKeyId,
|
|
292
|
+
assertionMethod: false
|
|
293
|
+
}))]) {
|
|
294
|
+
const actorOptions = {
|
|
295
|
+
documentLoader: createLoader({ [`${evil}/users/alice`]: document }),
|
|
296
|
+
contextLoader
|
|
297
|
+
};
|
|
298
|
+
strictEqual(await verifyRequest(await signedRequest(void 0, actorKeyId), actorOptions), null);
|
|
299
|
+
strictEqual((await fetchKey(actorKeyId, CryptographicKey, actorOptions)).key, null);
|
|
300
|
+
strictEqual(await getKeyOwner(actorKeyId, actorOptions), null);
|
|
301
|
+
}
|
|
302
|
+
const ownerKeyId = new URL(`${evil}/keys/2`);
|
|
303
|
+
const ownerOptions = {
|
|
304
|
+
documentLoader: createLoader({
|
|
305
|
+
[ownerKeyId.href]: {
|
|
306
|
+
"@context": "https://w3id.org/security/v1",
|
|
307
|
+
id: ownerKeyId.href,
|
|
308
|
+
type: "Key",
|
|
309
|
+
owner: `${evil}/users/bob`,
|
|
310
|
+
publicKeyPem: await exportSpki(gatewayPublicKey)
|
|
311
|
+
},
|
|
312
|
+
[`${evil}/users/bob`]: await actorJson({
|
|
313
|
+
id: evilActorId,
|
|
314
|
+
gateways: [evil],
|
|
315
|
+
key: ownerKeyId,
|
|
316
|
+
assertionMethod: false
|
|
317
|
+
})
|
|
318
|
+
}),
|
|
319
|
+
contextLoader
|
|
320
|
+
};
|
|
321
|
+
strictEqual(await getKeyOwner(ownerKeyId, ownerOptions), null);
|
|
322
|
+
strictEqual(await getKeyOwner(new CryptographicKey({
|
|
323
|
+
id: ownerKeyId,
|
|
324
|
+
owner: new URL(`${evil}/users/bob`),
|
|
325
|
+
publicKey: gatewayPublicKey
|
|
326
|
+
}), ownerOptions), null);
|
|
327
|
+
const keyCache = {
|
|
328
|
+
get: () => Promise.resolve(key),
|
|
329
|
+
set: () => Promise.resolve()
|
|
330
|
+
};
|
|
331
|
+
strictEqual((await fetchKey(evilKeyId, CryptographicKey, {
|
|
332
|
+
...options,
|
|
333
|
+
keyCache
|
|
334
|
+
})).key, null);
|
|
169
335
|
});
|
|
170
336
|
test("gateway keys are neither cached nor accepted outside HTTP Signatures", async () => {
|
|
171
337
|
const calls = [];
|
package/dist/sig/proof.test.mjs
CHANGED
|
@@ -10,10 +10,10 @@ import "../std__assert-DvMDRPes.mjs";
|
|
|
10
10
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
11
11
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
12
12
|
import { r as normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-4IJqPYos.mjs";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { i as signObject, n as createProof, o as verifyObject, r as hasProofLike, s as verifyPortableObjectProof, u as verifyProof } from "../proof-ChjBwnep.mjs";
|
|
14
|
+
import { d as verifyRequest } from "../http-DsgawTd8.mjs";
|
|
15
15
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
16
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
16
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-eBxQDsk9.mjs";
|
|
17
17
|
import { Create, DataIntegrityProof, Document, Multikey, Note, PUBLIC_COLLECTION, Place, Translation } from "@fedify/vocab";
|
|
18
18
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
19
19
|
import { decodeMultibase, encodeMultibase, exportDidKey, exportMultibaseKey, formatIri, importMultibaseKey, parseIri } from "@fedify/vocab-runtime";
|
|
@@ -1064,6 +1064,45 @@ test("verifyPortableObjectProof()", async (t) => {
|
|
|
1064
1064
|
reason: { type: "missingProof" }
|
|
1065
1065
|
});
|
|
1066
1066
|
});
|
|
1067
|
+
await t.step("treats compatible identifiers as portable IDs", async () => {
|
|
1068
|
+
const compatibleActorId = `https://gateway.example/.well-known/apgateway/did:key:${portableDidMethod}/actor`;
|
|
1069
|
+
const actor = {
|
|
1070
|
+
"@context": portableContext,
|
|
1071
|
+
id: compatibleActorId,
|
|
1072
|
+
type: "Person",
|
|
1073
|
+
inbox: `${compatibleActorId}/inbox`,
|
|
1074
|
+
outbox: `${compatibleActorId}/outbox`
|
|
1075
|
+
};
|
|
1076
|
+
const signed = await signPortableJsonLd(actor);
|
|
1077
|
+
const result = await verifyPortableObjectProof(signed, options);
|
|
1078
|
+
assert(result.verified);
|
|
1079
|
+
assertEquals(result.keys[0].id, portableKeyId);
|
|
1080
|
+
assertEquals(signed.id, compatibleActorId);
|
|
1081
|
+
assertEquals(await verifyPortableObjectProof(actor, options), {
|
|
1082
|
+
verified: false,
|
|
1083
|
+
reason: { type: "missingProof" }
|
|
1084
|
+
});
|
|
1085
|
+
const otherId = `https://gateway.example/.well-known/apgateway/did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK/activities/1`;
|
|
1086
|
+
assertEquals(await verifyPortableObjectProof(await signPortableJsonLd({
|
|
1087
|
+
"@context": portableContext,
|
|
1088
|
+
id: otherId,
|
|
1089
|
+
type: "Create",
|
|
1090
|
+
actor: compatibleActorId,
|
|
1091
|
+
object: "https://social.example/objects/1"
|
|
1092
|
+
}), options), {
|
|
1093
|
+
verified: false,
|
|
1094
|
+
reason: {
|
|
1095
|
+
type: "verificationMethodMismatch",
|
|
1096
|
+
proofIndex: 0,
|
|
1097
|
+
objectId: new URL(otherId),
|
|
1098
|
+
verificationMethod: portableKeyId
|
|
1099
|
+
}
|
|
1100
|
+
});
|
|
1101
|
+
await assertRejects(() => verifyPortableObjectProof({
|
|
1102
|
+
...actor,
|
|
1103
|
+
id: `https://user@gateway.example/.well-known/apgateway/did:key:${portableDidMethod}/actor`
|
|
1104
|
+
}, options), TypeError);
|
|
1105
|
+
});
|
|
1067
1106
|
await t.step("keeps non-portable documents outside the policy", async () => {
|
|
1068
1107
|
for (const document of [
|
|
1069
1108
|
{
|
|
@@ -1072,7 +1111,7 @@ test("verifyPortableObjectProof()", async (t) => {
|
|
|
1072
1111
|
},
|
|
1073
1112
|
{
|
|
1074
1113
|
...unsignedObject,
|
|
1075
|
-
id: "https://gateway.example/.well-known/apgateway/
|
|
1114
|
+
id: "https://gateway.example/.well-known/apgateway/hl:zQmdfTbBqBPQ"
|
|
1076
1115
|
},
|
|
1077
1116
|
{
|
|
1078
1117
|
"@context": portableContext,
|
|
@@ -1804,6 +1843,70 @@ test("verifyObject() rejects did:key proofs from another portable attribution or
|
|
|
1804
1843
|
contextLoader: mockDocumentLoader
|
|
1805
1844
|
}), null);
|
|
1806
1845
|
});
|
|
1846
|
+
async function signCompatibleNote(attribution, keyId) {
|
|
1847
|
+
const context = ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"];
|
|
1848
|
+
return await (await signObject(new Note({
|
|
1849
|
+
id: new URL(`${attribution}/notes/1`),
|
|
1850
|
+
attribution: new URL(attribution),
|
|
1851
|
+
content: "Note of a compatible-ID actor"
|
|
1852
|
+
}), ed25519PrivateKey, keyId, {
|
|
1853
|
+
contextLoader: mockDocumentLoader,
|
|
1854
|
+
context
|
|
1855
|
+
})).toJsonLd({
|
|
1856
|
+
format: "compact",
|
|
1857
|
+
contextLoader: mockDocumentLoader,
|
|
1858
|
+
context
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
test("verifyObject() authenticates compatible-ID attributions by DID proofs", async () => {
|
|
1862
|
+
const did = await exportDidKey(ed25519PublicKey.publicKey);
|
|
1863
|
+
const keyId = new URL(`${did}#${did.substring(8)}`);
|
|
1864
|
+
const options = {
|
|
1865
|
+
documentLoader() {
|
|
1866
|
+
throw new TypeError("did:key must not use the document loader");
|
|
1867
|
+
},
|
|
1868
|
+
contextLoader: mockDocumentLoader
|
|
1869
|
+
};
|
|
1870
|
+
for (const gateway of ["https://gw1.example", "https://gw2.example"]) assertInstanceOf(await verifyObject(Note, await signCompatibleNote(`${gateway}/.well-known/apgateway/${did}/actor`, keyId), options), Note);
|
|
1871
|
+
assertEquals(await verifyObject(Note, await signCompatibleNote("https://gw1.example/.well-known/apgateway/did:key:z6MkOther/actor", keyId), options), null);
|
|
1872
|
+
});
|
|
1873
|
+
test("verifyObject() does not trust compatible-ID actors by web origin", async () => {
|
|
1874
|
+
const did = await exportDidKey(ed25519PublicKey.publicKey);
|
|
1875
|
+
const attribution = `https://evil.example/.well-known/apgateway/${did}/actor`;
|
|
1876
|
+
const keyId = new URL("https://evil.example/keys/1");
|
|
1877
|
+
const documents = {
|
|
1878
|
+
[keyId.href]: {
|
|
1879
|
+
"@context": "https://w3id.org/security/multikey/v1",
|
|
1880
|
+
id: keyId.href,
|
|
1881
|
+
type: "Multikey",
|
|
1882
|
+
controller: attribution,
|
|
1883
|
+
publicKeyMultibase: await exportMultibaseKey(ed25519PublicKey.publicKey)
|
|
1884
|
+
},
|
|
1885
|
+
[attribution]: {
|
|
1886
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/multikey/v1"],
|
|
1887
|
+
id: attribution,
|
|
1888
|
+
type: "Person",
|
|
1889
|
+
inbox: `${attribution}/inbox`,
|
|
1890
|
+
assertionMethod: keyId.href
|
|
1891
|
+
}
|
|
1892
|
+
};
|
|
1893
|
+
const fetched = [];
|
|
1894
|
+
assertEquals(await verifyObject(Note, await signCompatibleNote(attribution, keyId), {
|
|
1895
|
+
documentLoader: (url) => {
|
|
1896
|
+
fetched.push(url);
|
|
1897
|
+
const document = documents[url];
|
|
1898
|
+
if (document == null) throw new TypeError(`Unexpected: ${url}`);
|
|
1899
|
+
return Promise.resolve({
|
|
1900
|
+
contextUrl: null,
|
|
1901
|
+
documentUrl: url,
|
|
1902
|
+
document
|
|
1903
|
+
});
|
|
1904
|
+
},
|
|
1905
|
+
contextLoader: mockDocumentLoader
|
|
1906
|
+
}), null);
|
|
1907
|
+
assertEquals(fetched, [keyId.href]);
|
|
1908
|
+
assertEquals(await verifyObject(Note, await signCompatibleNote(`https://user@gw.example/.well-known/apgateway/${did}/actor`, new URL(`${did}#${did.substring(8)}`)), { contextLoader: mockDocumentLoader }), null);
|
|
1909
|
+
});
|
|
1807
1910
|
test("signObject() preserves FEP-22cd contexts through proof verification", async () => {
|
|
1808
1911
|
const did = await exportDidKey(ed25519PublicKey.publicKey);
|
|
1809
1912
|
const keyId = new URL(`${did}#${did.substring(8)}`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
|
-
const require_http = require("./http-
|
|
3
|
-
require("./owner-
|
|
2
|
+
const require_http = require("./http-C8cZTE3Y.cjs");
|
|
3
|
+
require("./owner-DSzH7wro.cjs");
|
|
4
4
|
let _logtape_logtape = require("@logtape/logtape");
|
|
5
5
|
let _fedify_vocab = require("@fedify/vocab");
|
|
6
6
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -48,6 +48,8 @@ function getContextState(context) {
|
|
|
48
48
|
}
|
|
49
49
|
function canonicalize(id) {
|
|
50
50
|
try {
|
|
51
|
+
const portable = (0, _fedify_vocab_runtime.fromCompatibleEf61Id)(id);
|
|
52
|
+
if (portable != null) return (0, _fedify_vocab_runtime.canonicalizePortableUri)((0, _fedify_vocab_runtime.formatIri)(portable));
|
|
51
53
|
return (0, _fedify_vocab_runtime.canonicalizePortableUri)(typeof id === "string" ? id : (0, _fedify_vocab_runtime.formatIri)(id));
|
|
52
54
|
} catch (error) {
|
|
53
55
|
if (error instanceof TypeError) return null;
|
|
@@ -228,7 +230,20 @@ async function fetchOwner(candidate, options) {
|
|
|
228
230
|
const contextLoader = options.contextLoader ?? (0, _fedify_vocab_runtime.getDocumentLoader)();
|
|
229
231
|
const tracerProvider = options.tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
230
232
|
const tracer = tracerProvider.getTracer(require_http.name, require_http.version);
|
|
231
|
-
|
|
233
|
+
let inferredGateways;
|
|
234
|
+
try {
|
|
235
|
+
const portable = (0, _fedify_vocab_runtime.fromCompatibleEf61Id)(candidate);
|
|
236
|
+
if (portable != null) {
|
|
237
|
+
inferredGateways = [new URL(candidate.origin)];
|
|
238
|
+
candidate = portable;
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
if (!(error instanceof TypeError)) throw error;
|
|
242
|
+
logger.debug("The owner {owner} of a portable collection is a malformed compatible identifier.", { owner: candidate.href });
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
const gateways = options.gateways ?? (inferredGateways != null || (0, _fedify_vocab_runtime_internal_portable_dereference.getPortableGatewayCandidates)(candidate).length > 0 ? void 0 : options.gatewayHints);
|
|
246
|
+
if (options.gateways != null) inferredGateways = void 0;
|
|
232
247
|
const span = tracer.startSpan("activitypub.lookup_object");
|
|
233
248
|
try {
|
|
234
249
|
const object = await (0, _fedify_vocab_runtime_internal_portable_dereference.dereferencePortableIri)(candidate, {
|
|
@@ -236,6 +251,7 @@ async function fetchOwner(candidate, options) {
|
|
|
236
251
|
contextLoader,
|
|
237
252
|
tracerProvider,
|
|
238
253
|
gateways,
|
|
254
|
+
...inferredGateways == null ? {} : { inferredGateways },
|
|
239
255
|
verifyPortableObject: (document, verifierOptions) => require_http.verifyPortableObjectProof(document, {
|
|
240
256
|
...options,
|
|
241
257
|
...verifierOptions
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import {
|
|
4
|
-
import "./owner-
|
|
3
|
+
import { _ as verifyPortableObjectProofWithRoot, bt as name, h as verifyPortableObjectProof, xt as version } from "./http-D-rbr_Sy.js";
|
|
4
|
+
import "./owner-U12fDpQW.js";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
import { CollectionPage, Object as Object$1, isActor } from "@fedify/vocab";
|
|
7
7
|
import { trace } from "@opentelemetry/api";
|
|
@@ -49,6 +49,8 @@ function getContextState(context) {
|
|
|
49
49
|
}
|
|
50
50
|
function canonicalize(id) {
|
|
51
51
|
try {
|
|
52
|
+
const portable = fromCompatibleEf61Id(id);
|
|
53
|
+
if (portable != null) return canonicalizePortableUri(formatIri(portable));
|
|
52
54
|
return canonicalizePortableUri(typeof id === "string" ? id : formatIri(id));
|
|
53
55
|
} catch (error) {
|
|
54
56
|
if (error instanceof TypeError) return null;
|
|
@@ -229,7 +231,20 @@ async function fetchOwner(candidate, options) {
|
|
|
229
231
|
const contextLoader = options.contextLoader ?? getDocumentLoader();
|
|
230
232
|
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
231
233
|
const tracer = tracerProvider.getTracer(name, version);
|
|
232
|
-
|
|
234
|
+
let inferredGateways;
|
|
235
|
+
try {
|
|
236
|
+
const portable = fromCompatibleEf61Id(candidate);
|
|
237
|
+
if (portable != null) {
|
|
238
|
+
inferredGateways = [new URL(candidate.origin)];
|
|
239
|
+
candidate = portable;
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
if (!(error instanceof TypeError)) throw error;
|
|
243
|
+
logger.debug("The owner {owner} of a portable collection is a malformed compatible identifier.", { owner: candidate.href });
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
const gateways = options.gateways ?? (inferredGateways != null || getPortableGatewayCandidates(candidate).length > 0 ? void 0 : options.gatewayHints);
|
|
247
|
+
if (options.gateways != null) inferredGateways = void 0;
|
|
233
248
|
const span = tracer.startSpan("activitypub.lookup_object");
|
|
234
249
|
try {
|
|
235
250
|
const object = await dereferencePortableIri(candidate, {
|
|
@@ -237,6 +252,7 @@ async function fetchOwner(candidate, options) {
|
|
|
237
252
|
contextLoader,
|
|
238
253
|
tracerProvider,
|
|
239
254
|
gateways,
|
|
255
|
+
...inferredGateways == null ? {} : { inferredGateways },
|
|
240
256
|
verifyPortableObject: (document, verifierOptions) => verifyPortableObjectProof(document, {
|
|
241
257
|
...options,
|
|
242
258
|
...verifierOptions
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { c as getNormalizationContextLoader } from "./ld-
|
|
4
|
+
import { c as getNormalizationContextLoader } from "./ld-B00wWHzc.mjs";
|
|
5
5
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
6
6
|
//#region src/federation/temporal.ts
|
|
7
7
|
function isPlainObject(value) {
|
package/dist/testing/kv.test.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
6
6
|
import { t as ManualClockKvStore } from "../kv-DBRWVx3Q.mjs";
|
|
7
7
|
import { n as baseOptions, o as stringSchema, t as MockQueue } from "../tasks-dbCShlCb.mjs";
|
|
8
8
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
+
import { o as createFederation } from "../middleware-Br1_d-Ga.mjs";
|
|
10
10
|
//#region src/testing/kv.test.ts
|
|
11
11
|
test("ManualClockKvStore keeps an entry at its exact expiration instant", async () => {
|
|
12
12
|
const kv = new ManualClockKvStore();
|
package/dist/testing/mod.d.mts
CHANGED
|
@@ -2035,8 +2035,11 @@ interface PortableInboxForwardingOptions {
|
|
|
2035
2035
|
/**
|
|
2036
2036
|
* How long a delivery waits for forwarding requests made immediately, i.e.,
|
|
2037
2037
|
* when no outbox queue is configured, before Fedify responds to it.
|
|
2038
|
-
* Requests still running afterwards continue in the background. It
|
|
2039
|
-
*
|
|
2038
|
+
* Requests still running afterwards continue in the background. It also
|
|
2039
|
+
* bounds verifying the HTTP Signature that identifies the gateway which
|
|
2040
|
+
* forwarded the delivery, with or without an outbox queue; if the
|
|
2041
|
+
* verification does not finish in time, the activity is forwarded to that
|
|
2042
|
+
* gateway as well. It cannot have calendar units,
|
|
2040
2043
|
* i.e., weeks, months, or years, and cannot be longer than
|
|
2041
2044
|
* 2,147,483,647 milliseconds (about 24.8 days), the longest delay timers
|
|
2042
2045
|
* support.
|
|
@@ -5,9 +5,9 @@ import { t as esm_default } from "../esm-BHXXx4Wx.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
6
|
import "../std__assert-DvMDRPes.mjs";
|
|
7
7
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
8
|
-
import {
|
|
8
|
+
import { d as verifyRequest } from "../http-DsgawTd8.mjs";
|
|
9
9
|
import { i as rsaPrivateKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
10
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
10
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-eBxQDsk9.mjs";
|
|
11
11
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
12
12
|
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
13
13
|
//#region src/utils/docloader.test.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as kvCache, t as MockKvStore } from "../kv-cache-
|
|
4
|
+
import { n as kvCache, t as MockKvStore } from "../kv-cache-EvOgrFsS.mjs";
|
|
5
5
|
import { deepStrictEqual, throws } from "node:assert";
|
|
6
6
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
7
7
|
import { preloadedContexts } from "@fedify/vocab-runtime";
|
package/dist/utils/mod.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_kv_cache = require("../kv-cache-
|
|
3
|
+
const require_kv_cache = require("../kv-cache-Dvd-Q-E2.cjs");
|
|
4
4
|
exports.getAuthenticatedDocumentLoader = require_kv_cache.getAuthenticatedDocumentLoader;
|
|
5
5
|
exports.kvCache = require_kv_cache.kvCache;
|
package/dist/utils/mod.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-
|
|
3
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-DIxwMeNi.js";
|
|
4
4
|
export { getAuthenticatedDocumentLoader, kvCache };
|