@fedify/fedify 2.4.0-dev.1964 → 2.4.0-dev.1995
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-B4zpKIFU.mjs → builder-D0DxgOV5.mjs} +2 -2
- package/dist/{client-CtxvmazV.mjs → client-DpnpgjyX.mjs} +78 -4
- 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-CJnWc6c-.mjs +495 -0
- package/dist/{context-COLwHogJ.d.cts → context-BeDnDuF3.d.cts} +4 -3
- package/dist/{context-DiiCt4S7.d.ts → context-uyRUWoZQ.d.ts} +4 -3
- package/dist/{deno-CtG93ohj.mjs → deno-CABhzCb_.mjs} +1 -1
- package/dist/{docloader-dk_k3S8d.mjs → docloader-BbGSL0Xq.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler-compound-proof.test.d.mts +2 -0
- package/dist/federation/handler-compound-proof.test.mjs +152 -0
- package/dist/federation/handler.test.mjs +122 -4
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/keycache.test.mjs +52 -9
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +111 -15
- 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/send.test.mjs +139 -4
- 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-Drjlrrax.cjs → federation-DCEHQk4G.cjs} +632 -57
- package/dist/{http-6TI0tI03.d.cts → http-65PYi9jY.d.ts} +34 -2
- package/dist/{http-Dj4s1UQ0.js → http-9WyuldYh.js} +170 -8
- package/dist/{http-CdrSn2ip.d.ts → http-CP-7OdSq.d.cts} +34 -2
- package/dist/{http-B3skRvGo.cjs → http-CRFns-UE.cjs} +181 -7
- package/dist/{http-D7LX-BL9.mjs → http-D9urSO2D.mjs} +3 -3
- package/dist/{key-BVjgbs_9.mjs → key-Ccs8cnd7.mjs} +169 -7
- package/dist/{keycache-ZLqIfrkL.mjs → keycache-BUDHB5rY.mjs} +12 -4
- package/dist/{kv-cache-DtsjH_bY.cjs → kv-cache-DXT9vmIg.cjs} +2 -2
- package/dist/{kv-cache-tGNbvDCF.js → kv-cache-DtmXhPXG.js} +2 -2
- package/dist/{kv-cache-xRcC_xxP.mjs → kv-cache-lKyFn_Dn.mjs} +1 -1
- package/dist/{ld-OuCeQFny.mjs → ld-qup__MAW.mjs} +3 -3
- package/dist/map-local-context-conflict-DOYEEJ3u.mjs +204 -0
- package/dist/map-local-create-note-B0SeXJms.mjs +214 -0
- package/dist/{metrics-B9N27cCB.mjs → metrics-CISXCvB1.mjs} +1 -1
- package/dist/{middleware-TeLjzoxn.mjs → middleware-CzvJvPHK.mjs} +58 -15
- package/dist/{middleware-Cd_vPqDH.mjs → middleware-DkrU2WhY.mjs} +1 -1
- package/dist/{middleware-CPTDFMmJ.js → middleware-DsfWajaD.js} +593 -18
- package/dist/{mod-DypxPS9H.d.ts → mod-C0BYc0OU.d.ts} +1 -1
- package/dist/{mod-CnGLNoVw.d.cts → mod-CbKDOnCt.d.cts} +1 -1
- package/dist/{mod-CLHkCwLm.d.cts → mod-CyiSjRkk.d.cts} +1 -1
- package/dist/{mod-CSH1Ee-I.d.ts → mod-D882_Xsg.d.ts} +1 -1
- package/dist/{mod-DzRXACM5.d.ts → mod-UDwMjuHM.d.ts} +1 -1
- package/dist/{mod-BZldCEU0.d.cts → mod-x9W0d0Pk.d.cts} +1 -1
- package/dist/mod.cjs +20 -20
- package/dist/mod.d.cts +6 -6
- package/dist/mod.d.ts +6 -6
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +28 -1
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/{owner-DGSfntI-.d.ts → owner-BF0L9cMt.d.cts} +12 -1
- package/dist/{proof-BO_esQii.js → owner-BIPEZGiU.js} +1255 -1098
- package/dist/{owner-r_waTiQj.d.cts → owner-BSzr5-I8.d.ts} +12 -1
- package/dist/owner-CRoq8Spb.mjs +175 -0
- package/dist/{proof-Dua0d906.cjs → owner-CVA7L9MA.cjs} +1266 -1097
- package/dist/{proof-D5Ajk4DJ.mjs → proof-BDxNVZ3E.mjs} +186 -83
- package/dist/{send-DVXyUqhO.mjs → send-BzM5GLyn.mjs} +68 -11
- package/dist/sig/compound-proof-discovery.test.d.mts +2 -0
- package/dist/sig/compound-proof-discovery.test.mjs +331 -0
- package/dist/sig/compound-proof-verification.test.d.mts +2 -0
- package/dist/sig/compound-proof-verification.test.mjs +465 -0
- package/dist/sig/compound-proof.test.d.mts +2 -0
- package/dist/sig/compound-proof.test.mjs +324 -0
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +169 -2
- package/dist/sig/ld.test.mjs +55 -2
- package/dist/sig/mod.cjs +17 -17
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +103 -4
- package/dist/sig/proof.test.mjs +120 -1
- package/dist/{temporal-BoDw51A-.mjs → temporal-Dv6Qv-8k.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +2 -1
- package/dist/{types-RXm5YxpC.cjs → types-Be2zbyeG.cjs} +94 -2
- package/dist/{types-Dtyf8lVj.js → types-C_cNlNVK.js} +78 -4
- package/dist/utils/docloader.test.mjs +27 -3
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +6 -6
- package/dist/owner-DTEqTzSr.mjs +0 -120
|
@@ -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 { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-
|
|
4
|
+
import { n as version, t as name } from "./deno-CABhzCb_.mjs";
|
|
5
|
+
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-CISXCvB1.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -86,6 +86,118 @@ async function importJwk(jwk, type) {
|
|
|
86
86
|
validateCryptoKey(key, type);
|
|
87
87
|
return key;
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Fetches the document that the given actor URI dereferences to, and returns
|
|
91
|
+
* the actor only if the host that served the document is authoritative for
|
|
92
|
+
* the id the document claims.
|
|
93
|
+
*
|
|
94
|
+
* Only the origin that serves an actor id can speak for it. Without that
|
|
95
|
+
* rule any host could serve a document describing somebody else's actor—and
|
|
96
|
+
* listing its own keys as that actor's.
|
|
97
|
+
*
|
|
98
|
+
* @param actorId The URI of the actor to fetch.
|
|
99
|
+
* @param options Options for fetching the document.
|
|
100
|
+
* @returns The actor, or `null` if the document cannot be fetched, is not an
|
|
101
|
+
* actor, or belongs to another origin.
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
async function fetchActorDocument(actorId, options = {}) {
|
|
105
|
+
const logger = getLogger([
|
|
106
|
+
"fedify",
|
|
107
|
+
"sig",
|
|
108
|
+
"key"
|
|
109
|
+
]);
|
|
110
|
+
const documentLoader = options.documentLoader ?? getDocumentLoader();
|
|
111
|
+
const contextLoader = options.contextLoader ?? getDocumentLoader();
|
|
112
|
+
const { tracerProvider } = options;
|
|
113
|
+
let document;
|
|
114
|
+
let documentUrl = actorId;
|
|
115
|
+
try {
|
|
116
|
+
const remoteDocument = await documentLoader(actorId.href);
|
|
117
|
+
document = remoteDocument.document;
|
|
118
|
+
documentUrl = new URL(remoteDocument.documentUrl ?? "", actorId);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
logger.debug("Failed to fetch the actor {actorId}: {error}", {
|
|
121
|
+
actorId: actorId.href,
|
|
122
|
+
error
|
|
123
|
+
});
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
let object;
|
|
127
|
+
try {
|
|
128
|
+
object = await Object$1.fromJsonLd(document, {
|
|
129
|
+
documentLoader,
|
|
130
|
+
contextLoader,
|
|
131
|
+
tracerProvider,
|
|
132
|
+
baseUrl: documentUrl
|
|
133
|
+
});
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (!(error instanceof TypeError)) throw error;
|
|
136
|
+
logger.debug("The document served at {documentUrl} is not a valid object: {error}", {
|
|
137
|
+
documentUrl: documentUrl.href,
|
|
138
|
+
error
|
|
139
|
+
});
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
if (!isActor(object)) return null;
|
|
143
|
+
if (object.id == null || object.id.origin !== documentUrl.origin) {
|
|
144
|
+
logger.debug("The document served at {documentUrl} claims to be the actor {actorId}, which belongs to another origin; refusing to treat it as that actor's document.", {
|
|
145
|
+
documentUrl: documentUrl.href,
|
|
146
|
+
actorId: object.id?.href
|
|
147
|
+
});
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
return object;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Resolves the owner that the given key claims, and returns it only if the
|
|
154
|
+
* claim holds.
|
|
155
|
+
*
|
|
156
|
+
* The `owner` of a {@link CryptographicKey}, like the `controller` of
|
|
157
|
+
* a {@link Multikey}, proves nothing on its own: the key document and the
|
|
158
|
+
* claim inside it are served by the same host, so anyone able to serve a key
|
|
159
|
+
* document can name any actor in the world as its owner. The claim becomes
|
|
160
|
+
* meaningful only once the named actor's own document is fetched and turns
|
|
161
|
+
* out to link back to the key. This function performs that mutual-link
|
|
162
|
+
* check, which is the only sound way to learn a fetched key's owner.
|
|
163
|
+
*
|
|
164
|
+
* The claimed owner is always dereferenced, never read out of the key
|
|
165
|
+
* document: an owner embedded there is written by whoever wrote the key.
|
|
166
|
+
*
|
|
167
|
+
* @param key The key whose ownership claim is to be verified. It must carry
|
|
168
|
+
* an `id`, as that is what the owner has to link back to.
|
|
169
|
+
* @param options Options for fetching the claimed owner.
|
|
170
|
+
* @returns The verified owner, or `null` if the key claims no owner, the
|
|
171
|
+
* owner cannot be fetched, or the owner does not link back to
|
|
172
|
+
* the key.
|
|
173
|
+
* @internal
|
|
174
|
+
*/
|
|
175
|
+
async function verifyKeyOwnership(key, options = {}) {
|
|
176
|
+
const logger = getLogger([
|
|
177
|
+
"fedify",
|
|
178
|
+
"sig",
|
|
179
|
+
"key"
|
|
180
|
+
]);
|
|
181
|
+
const keyId = key.id;
|
|
182
|
+
if (keyId == null) return null;
|
|
183
|
+
const claimedOwnerId = key instanceof CryptographicKey ? key.ownerId : key.controllerId;
|
|
184
|
+
if (claimedOwnerId == null) return null;
|
|
185
|
+
const owner = await fetchActorDocument(claimedOwnerId, options);
|
|
186
|
+
if (owner == null) {
|
|
187
|
+
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims could not be resolved.", {
|
|
188
|
+
keyId: keyId.href,
|
|
189
|
+
claimedOwnerId: claimedOwnerId.href
|
|
190
|
+
});
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
const linkedKeyIds = key instanceof CryptographicKey ? owner.publicKeyIds : owner.assertionMethodIds;
|
|
194
|
+
for (const linkedKeyId of linkedKeyIds) if (linkedKeyId.href === keyId.href) return owner;
|
|
195
|
+
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims does not list the key as its own.", {
|
|
196
|
+
keyId: keyId.href,
|
|
197
|
+
claimedOwnerId: claimedOwnerId.href
|
|
198
|
+
});
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
89
201
|
async function withFetchKeySpan(keyId, tracerProvider, fetcher) {
|
|
90
202
|
tracerProvider ??= trace.getTracerProvider();
|
|
91
203
|
return await tracerProvider.getTracer(name, version).startActiveSpan("activitypub.fetch_key", {
|
|
@@ -219,6 +331,18 @@ function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
|
|
|
219
331
|
async function clearFetchErrorMetadata(keyId, keyCache) {
|
|
220
332
|
await keyCache?.setFetchError?.(keyId, null);
|
|
221
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Returns the identifier a fragment-bearing DID URL is a fragment of, or
|
|
336
|
+
* `null` if the URL is not a DID URL. `did:web:example.com#key` is thereby
|
|
337
|
+
* traced back to `did:web:example.com`, the DID that resolving the key went
|
|
338
|
+
* through in the first place.
|
|
339
|
+
*/
|
|
340
|
+
function stripFragment(keyId) {
|
|
341
|
+
if (keyId.protocol !== "did:") return null;
|
|
342
|
+
const did = new URL(keyId.href);
|
|
343
|
+
did.hash = "";
|
|
344
|
+
return did;
|
|
345
|
+
}
|
|
222
346
|
function isDidKeyUrl(keyId) {
|
|
223
347
|
return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
|
|
224
348
|
}
|
|
@@ -274,7 +398,7 @@ async function resolveDidKey(cacheKey, cls, keyCache, logger) {
|
|
|
274
398
|
cached: false
|
|
275
399
|
};
|
|
276
400
|
}
|
|
277
|
-
async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
|
|
401
|
+
async function resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider, keyIdBoundByCaller }, logger) {
|
|
278
402
|
let object;
|
|
279
403
|
try {
|
|
280
404
|
object = await Object$1.fromJsonLd(document, {
|
|
@@ -304,8 +428,22 @@ async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoade
|
|
|
304
428
|
}
|
|
305
429
|
}
|
|
306
430
|
let key = null;
|
|
307
|
-
|
|
431
|
+
let ownerDocument = null;
|
|
432
|
+
if (object instanceof cls && (object.id == null || object.id.href === keyId)) key = object.id == null ? object.clone({ id: cacheKey }) : object;
|
|
308
433
|
else if (isActor(object)) {
|
|
434
|
+
if (object.id == null || object.id.origin !== documentUrl.origin) {
|
|
435
|
+
logger.debug("Failed to verify; the document served at {documentUrl} claims to be the actor {actorId}, which belongs to another origin.", {
|
|
436
|
+
keyId,
|
|
437
|
+
documentUrl: documentUrl.href,
|
|
438
|
+
actorId: object.id?.href
|
|
439
|
+
});
|
|
440
|
+
await keyCache?.set(cacheKey, null);
|
|
441
|
+
return {
|
|
442
|
+
key: null,
|
|
443
|
+
cached: false
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
ownerDocument = object;
|
|
309
447
|
const keys = cls === CryptographicKey ? object.getPublicKeys({
|
|
310
448
|
documentLoader,
|
|
311
449
|
contextLoader,
|
|
@@ -367,6 +505,27 @@ async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoade
|
|
|
367
505
|
cached: false
|
|
368
506
|
};
|
|
369
507
|
}
|
|
508
|
+
const claimedOwnerId = key instanceof CryptographicKey ? key.ownerId : key.controllerId;
|
|
509
|
+
if (!(keyIdBoundByCaller && claimedOwnerId != null && claimedOwnerId.href === stripFragment(cacheKey)?.href)) {
|
|
510
|
+
if (ownerDocument != null && claimedOwnerId == null) key = key instanceof CryptographicKey ? key.clone({ owner: ownerDocument.id }) : key.clone({ controller: ownerDocument.id });
|
|
511
|
+
else if (claimedOwnerId != null && claimedOwnerId.href !== ownerDocument?.id?.href) {
|
|
512
|
+
if (await verifyKeyOwnership(key, {
|
|
513
|
+
documentLoader,
|
|
514
|
+
contextLoader,
|
|
515
|
+
tracerProvider
|
|
516
|
+
}) == null) {
|
|
517
|
+
logger.debug("Failed to verify; the owner {claimedOwnerId} that key {keyId} claims does not list the key as its own.", {
|
|
518
|
+
keyId,
|
|
519
|
+
claimedOwnerId: claimedOwnerId.href
|
|
520
|
+
});
|
|
521
|
+
await keyCache?.set(cacheKey, null);
|
|
522
|
+
return {
|
|
523
|
+
key: null,
|
|
524
|
+
cached: false
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
370
529
|
if (keyCache != null) {
|
|
371
530
|
await keyCache.set(cacheKey, key);
|
|
372
531
|
logger.debug("Key {keyId} cached.", { keyId });
|
|
@@ -405,15 +564,18 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
|
|
|
405
564
|
}
|
|
406
565
|
logger.debug("Fetching key {keyId} to verify signature...", { keyId });
|
|
407
566
|
let document;
|
|
567
|
+
let documentUrl = cacheKey;
|
|
408
568
|
try {
|
|
409
|
-
|
|
569
|
+
const remoteDocument = await (options.documentLoader ?? getDocumentLoader())(keyId);
|
|
570
|
+
document = remoteDocument.document;
|
|
571
|
+
documentUrl = new URL(remoteDocument.documentUrl ?? "", cacheKey);
|
|
410
572
|
} catch (error) {
|
|
411
573
|
const classified = classifyFetchError(error);
|
|
412
574
|
const errored = await onFetchError(error, cacheKey, keyId, keyCache, logger);
|
|
413
575
|
outcome = classified;
|
|
414
576
|
return errored;
|
|
415
577
|
}
|
|
416
|
-
const resolved = await resolveFetchedKey(document, cacheKey, keyId, cls, options, logger);
|
|
578
|
+
const resolved = await resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, options, logger);
|
|
417
579
|
outcome = { result: resolved.key != null ? "fetched" : "invalid" };
|
|
418
580
|
return resolved;
|
|
419
581
|
} finally {
|
|
@@ -450,4 +612,4 @@ async function fetchKeyInternal(keyId, cls, options = {}) {
|
|
|
450
612
|
});
|
|
451
613
|
}
|
|
452
614
|
//#endregion
|
|
453
|
-
export {
|
|
615
|
+
export { generateCryptoKeyPair as a, verifyKeyOwnership as c, fetchKeyDetailed as i, fetchActorDocument as n, importJwk as o, fetchKey as r, validateCryptoKey as s, exportJwk as t };
|
|
@@ -3,6 +3,7 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { CryptographicKey, Multikey } from "@fedify/vocab";
|
|
5
5
|
//#region src/federation/keycache.ts
|
|
6
|
+
const KEY_CACHE_GENERATION = "2";
|
|
6
7
|
var KvKeyCache = class {
|
|
7
8
|
kv;
|
|
8
9
|
prefix;
|
|
@@ -25,13 +26,20 @@ var KvKeyCache = class {
|
|
|
25
26
|
keyId.href
|
|
26
27
|
];
|
|
27
28
|
}
|
|
29
|
+
#entryKey(keyId) {
|
|
30
|
+
return [
|
|
31
|
+
...this.prefix,
|
|
32
|
+
KEY_CACHE_GENERATION,
|
|
33
|
+
keyId.href
|
|
34
|
+
];
|
|
35
|
+
}
|
|
28
36
|
async get(keyId) {
|
|
29
37
|
const negativeExpiration = this.nullKeys.get(keyId.href);
|
|
30
38
|
if (negativeExpiration != null) {
|
|
31
39
|
if (Temporal.Now.instant().until(negativeExpiration).sign >= 0) return null;
|
|
32
40
|
this.nullKeys.delete(keyId.href);
|
|
33
41
|
}
|
|
34
|
-
const serialized = await this.kv.get(
|
|
42
|
+
const serialized = await this.kv.get(this.#entryKey(keyId));
|
|
35
43
|
if (serialized === void 0) return void 0;
|
|
36
44
|
if (serialized === null) {
|
|
37
45
|
this.nullKeys.set(keyId.href, Temporal.Now.instant().add(this.unavailableKeyTtl));
|
|
@@ -43,7 +51,7 @@ var KvKeyCache = class {
|
|
|
43
51
|
try {
|
|
44
52
|
return await Multikey.fromJsonLd(serialized, this.options);
|
|
45
53
|
} catch {
|
|
46
|
-
await this.kv.delete(
|
|
54
|
+
await this.kv.delete(this.#entryKey(keyId));
|
|
47
55
|
return;
|
|
48
56
|
}
|
|
49
57
|
}
|
|
@@ -51,12 +59,12 @@ var KvKeyCache = class {
|
|
|
51
59
|
async set(keyId, key) {
|
|
52
60
|
if (key == null) {
|
|
53
61
|
this.nullKeys.set(keyId.href, Temporal.Now.instant().add(this.unavailableKeyTtl));
|
|
54
|
-
await this.kv.set(
|
|
62
|
+
await this.kv.set(this.#entryKey(keyId), null, { ttl: this.unavailableKeyTtl });
|
|
55
63
|
return;
|
|
56
64
|
}
|
|
57
65
|
this.nullKeys.delete(keyId.href);
|
|
58
66
|
const serialized = await key.toJsonLd(this.options);
|
|
59
|
-
await this.kv.set(
|
|
67
|
+
await this.kv.set(this.#entryKey(keyId), serialized, { ttl: this.keyTtl });
|
|
60
68
|
}
|
|
61
69
|
async getFetchError(keyId) {
|
|
62
70
|
const cached = await this.kv.get(this.#getFetchErrorKey(keyId));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
|
-
const require_http = require("./http-
|
|
2
|
+
const require_http = require("./http-CRFns-UE.cjs");
|
|
3
3
|
let _logtape_logtape = require("@logtape/logtape");
|
|
4
|
-
let es_toolkit = require("es-toolkit");
|
|
5
4
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
5
|
+
let es_toolkit = require("es-toolkit");
|
|
6
6
|
//#region src/utils/docloader.ts
|
|
7
7
|
const logger$1 = (0, _logtape_logtape.getLogger)([
|
|
8
8
|
"fedify",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import {
|
|
3
|
+
import { T as recordDocumentCache, f as validateCryptoKey, t as doubleKnock } from "./http-9WyuldYh.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
|
-
import { curry } from "es-toolkit";
|
|
6
5
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
6
|
+
import { curry } from "es-toolkit";
|
|
7
7
|
//#region src/utils/docloader.ts
|
|
8
8
|
const logger$1 = getLogger([
|
|
9
9
|
"fedify",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { p as recordDocumentCache } from "./metrics-
|
|
4
|
+
import { p as recordDocumentCache } from "./metrics-CISXCvB1.mjs";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
import { preloadedContexts } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/utils/kv-cache.ts
|
|
@@ -1,9 +1,9 @@
|
|
|
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 { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
-
import {
|
|
4
|
+
import { n as version, t as name } from "./deno-CABhzCb_.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CISXCvB1.mjs";
|
|
6
|
+
import { r as fetchKey, s as validateCryptoKey } from "./key-Ccs8cnd7.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
9
9
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import "temporal-polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
//#region test-vectors/fep-8b32/map-local-context-conflict.json
|
|
5
|
+
var map_local_context_conflict_default = {
|
|
6
|
+
id: "fedify-fep-8b32-map-local-context-conflict-v1",
|
|
7
|
+
profile: "Fedify map-local compound proof profile",
|
|
8
|
+
cryptosuite: "eddsa-jcs-2022",
|
|
9
|
+
notes: [
|
|
10
|
+
"The parent sets a default language that the child's local context does not reset.",
|
|
11
|
+
"The inner proof authenticates the extracted standalone child JSON map.",
|
|
12
|
+
"The outer proof authenticates the complete compound JSON snapshot.",
|
|
13
|
+
"Both proofs can be valid even though standalone and in-parent JSON-LD expansions differ."
|
|
14
|
+
],
|
|
15
|
+
keys: {
|
|
16
|
+
"outer": {
|
|
17
|
+
"controller": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
|
|
18
|
+
"verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
|
|
19
|
+
"publicKeyMultibase": "z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
|
|
20
|
+
"publicKeyJwk": {
|
|
21
|
+
"kty": "OKP",
|
|
22
|
+
"crv": "Ed25519",
|
|
23
|
+
"x": "sA2Nk45_dz1RVlqtNqYj9TRPf10ZYPnPPo4SYg6igQ8",
|
|
24
|
+
"key_ops": ["verify"],
|
|
25
|
+
"ext": true
|
|
26
|
+
},
|
|
27
|
+
"testPrivateKeyJwk": {
|
|
28
|
+
"kty": "OKP",
|
|
29
|
+
"crv": "Ed25519",
|
|
30
|
+
"d": "yW756hDF5BTEcXI6_53nLDX6W3D66X6IMuysfS4rjtY",
|
|
31
|
+
"x": "sA2Nk45_dz1RVlqtNqYj9TRPf10ZYPnPPo4SYg6igQ8",
|
|
32
|
+
"key_ops": ["sign"],
|
|
33
|
+
"ext": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"inner": {
|
|
37
|
+
"controller": "did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3",
|
|
38
|
+
"verificationMethod": "did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3#z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3",
|
|
39
|
+
"publicKeyMultibase": "z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3",
|
|
40
|
+
"publicKeyJwk": {
|
|
41
|
+
"kty": "OKP",
|
|
42
|
+
"crv": "Ed25519",
|
|
43
|
+
"x": "LR8epAGDe-cVq5p2Tx49CCfphpk1rNhkNoY9i-XEUfg",
|
|
44
|
+
"key_ops": ["verify"],
|
|
45
|
+
"ext": true
|
|
46
|
+
},
|
|
47
|
+
"testPrivateKeyJwk": {
|
|
48
|
+
"kty": "OKP",
|
|
49
|
+
"crv": "Ed25519",
|
|
50
|
+
"d": "LledL195fP9TQGQrkE2l2Y2k48UvqCzYI9M1zXyh7zQ",
|
|
51
|
+
"x": "LR8epAGDe-cVq5p2Tx49CCfphpk1rNhkNoY9i-XEUfg",
|
|
52
|
+
"key_ops": ["sign"],
|
|
53
|
+
"ext": true
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
documents: {
|
|
58
|
+
"finalSecuredCompound": {
|
|
59
|
+
"@context": [
|
|
60
|
+
"https://www.w3.org/ns/activitystreams",
|
|
61
|
+
"https://w3id.org/security/data-integrity/v1",
|
|
62
|
+
{ "@language": "en" }
|
|
63
|
+
],
|
|
64
|
+
"id": "ap+ef61://did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2/activities/context-conflict",
|
|
65
|
+
"type": "Create",
|
|
66
|
+
"actor": "ap+ef61://did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2/actor",
|
|
67
|
+
"object": {
|
|
68
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
69
|
+
"id": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/objects/context-conflict",
|
|
70
|
+
"type": "Note",
|
|
71
|
+
"attributedTo": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/actor",
|
|
72
|
+
"content": "A portable note with inherited language",
|
|
73
|
+
"proof": {
|
|
74
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
75
|
+
"type": "DataIntegrityProof",
|
|
76
|
+
"cryptosuite": "eddsa-jcs-2022",
|
|
77
|
+
"verificationMethod": "did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3#z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3",
|
|
78
|
+
"proofPurpose": "assertionMethod",
|
|
79
|
+
"created": "2023-02-24T23:36:38Z",
|
|
80
|
+
"proofValue": "z3arp9jZdt6kcLacoXxx5kb6QVM8GZFXD13nEisfna52uwMprZz2yJCXsbyMBvvBKZopCCNRq3o22UqYgudLum5eM"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"proof": {
|
|
84
|
+
"@context": [
|
|
85
|
+
"https://www.w3.org/ns/activitystreams",
|
|
86
|
+
"https://w3id.org/security/data-integrity/v1",
|
|
87
|
+
{ "@language": "en" }
|
|
88
|
+
],
|
|
89
|
+
"type": "DataIntegrityProof",
|
|
90
|
+
"cryptosuite": "eddsa-jcs-2022",
|
|
91
|
+
"verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
|
|
92
|
+
"proofPurpose": "assertionMethod",
|
|
93
|
+
"created": "2023-02-24T23:36:38Z",
|
|
94
|
+
"proofValue": "z33BeAxXEtbCKnt9mKodwoJFSDKqK2Q2zMrWN36TtpFhDn9K9FFX7rvyfY2jkFh8gcUo3iQvUutzqBKXZdsyKZAEz"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"securedInner": {
|
|
98
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
99
|
+
"id": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/objects/context-conflict",
|
|
100
|
+
"type": "Note",
|
|
101
|
+
"attributedTo": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/actor",
|
|
102
|
+
"content": "A portable note with inherited language",
|
|
103
|
+
"proof": {
|
|
104
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
105
|
+
"type": "DataIntegrityProof",
|
|
106
|
+
"cryptosuite": "eddsa-jcs-2022",
|
|
107
|
+
"verificationMethod": "did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3#z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3",
|
|
108
|
+
"proofPurpose": "assertionMethod",
|
|
109
|
+
"created": "2023-02-24T23:36:38Z",
|
|
110
|
+
"proofValue": "z3arp9jZdt6kcLacoXxx5kb6QVM8GZFXD13nEisfna52uwMprZz2yJCXsbyMBvvBKZopCCNRq3o22UqYgudLum5eM"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"outerUnsecuredDocument": {
|
|
114
|
+
"@context": [
|
|
115
|
+
"https://www.w3.org/ns/activitystreams",
|
|
116
|
+
"https://w3id.org/security/data-integrity/v1",
|
|
117
|
+
{ "@language": "en" }
|
|
118
|
+
],
|
|
119
|
+
"id": "ap+ef61://did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2/activities/context-conflict",
|
|
120
|
+
"type": "Create",
|
|
121
|
+
"actor": "ap+ef61://did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2/actor",
|
|
122
|
+
"object": {
|
|
123
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
124
|
+
"id": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/objects/context-conflict",
|
|
125
|
+
"type": "Note",
|
|
126
|
+
"attributedTo": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/actor",
|
|
127
|
+
"content": "A portable note with inherited language",
|
|
128
|
+
"proof": {
|
|
129
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
130
|
+
"type": "DataIntegrityProof",
|
|
131
|
+
"cryptosuite": "eddsa-jcs-2022",
|
|
132
|
+
"verificationMethod": "did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3#z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3",
|
|
133
|
+
"proofPurpose": "assertionMethod",
|
|
134
|
+
"created": "2023-02-24T23:36:38Z",
|
|
135
|
+
"proofValue": "z3arp9jZdt6kcLacoXxx5kb6QVM8GZFXD13nEisfna52uwMprZz2yJCXsbyMBvvBKZopCCNRq3o22UqYgudLum5eM"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"innerUnsecuredDocument": {
|
|
140
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
141
|
+
"id": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/objects/context-conflict",
|
|
142
|
+
"type": "Note",
|
|
143
|
+
"attributedTo": "ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/actor",
|
|
144
|
+
"content": "A portable note with inherited language"
|
|
145
|
+
},
|
|
146
|
+
"outerProofConfiguration": {
|
|
147
|
+
"@context": [
|
|
148
|
+
"https://www.w3.org/ns/activitystreams",
|
|
149
|
+
"https://w3id.org/security/data-integrity/v1",
|
|
150
|
+
{ "@language": "en" }
|
|
151
|
+
],
|
|
152
|
+
"type": "DataIntegrityProof",
|
|
153
|
+
"cryptosuite": "eddsa-jcs-2022",
|
|
154
|
+
"verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
|
|
155
|
+
"proofPurpose": "assertionMethod",
|
|
156
|
+
"created": "2023-02-24T23:36:38Z"
|
|
157
|
+
},
|
|
158
|
+
"innerProofConfiguration": {
|
|
159
|
+
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
160
|
+
"type": "DataIntegrityProof",
|
|
161
|
+
"cryptosuite": "eddsa-jcs-2022",
|
|
162
|
+
"verificationMethod": "did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3#z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3",
|
|
163
|
+
"proofPurpose": "assertionMethod",
|
|
164
|
+
"created": "2023-02-24T23:36:38Z"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
canonicalization: {
|
|
168
|
+
"outer": {
|
|
169
|
+
"documentJcs": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",{\"@language\":\"en\"}],\"actor\":\"ap+ef61://did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2/actor\",\"id\":\"ap+ef61://did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2/activities/context-conflict\",\"object\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\"],\"attributedTo\":\"ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/actor\",\"content\":\"A portable note with inherited language\",\"id\":\"ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/objects/context-conflict\",\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\"],\"created\":\"2023-02-24T23:36:38Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z3arp9jZdt6kcLacoXxx5kb6QVM8GZFXD13nEisfna52uwMprZz2yJCXsbyMBvvBKZopCCNRq3o22UqYgudLum5eM\",\"type\":\"DataIntegrityProof\",\"verificationMethod\":\"did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3#z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3\"},\"type\":\"Note\"},\"type\":\"Create\"}",
|
|
170
|
+
"proofConfigurationJcs": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",{\"@language\":\"en\"}],\"created\":\"2023-02-24T23:36:38Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"type\":\"DataIntegrityProof\",\"verificationMethod\":\"did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2\"}"
|
|
171
|
+
},
|
|
172
|
+
"inner": {
|
|
173
|
+
"documentJcs": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\"],\"attributedTo\":\"ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/actor\",\"content\":\"A portable note with inherited language\",\"id\":\"ap+ef61://did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3/objects/context-conflict\",\"type\":\"Note\"}",
|
|
174
|
+
"proofConfigurationJcs": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\"],\"created\":\"2023-02-24T23:36:38Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"type\":\"DataIntegrityProof\",\"verificationMethod\":\"did:key:z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3#z6MkhVPuyvgG1RkMv67azDqDCDERPXVrUg1i3qchXY5EACE3\"}"
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
hashes: {
|
|
178
|
+
"outer": {
|
|
179
|
+
"documentSha256": "7b0a0d3668e43492c8c54cb98d0227a1bf0aefd11da7adb48af6e31f6d5322df",
|
|
180
|
+
"proofConfigurationSha256": "94b98e0a2519065217496bad2936e6e892bfe12ccb176282ec274ce8eb98a6a3",
|
|
181
|
+
"combinedSigningInput": "94b98e0a2519065217496bad2936e6e892bfe12ccb176282ec274ce8eb98a6a37b0a0d3668e43492c8c54cb98d0227a1bf0aefd11da7adb48af6e31f6d5322df"
|
|
182
|
+
},
|
|
183
|
+
"inner": {
|
|
184
|
+
"documentSha256": "3772e3a906c7b49d195345b05d73c3156bb3d61a5d1c641d64f4f03d661f7eeb",
|
|
185
|
+
"proofConfigurationSha256": "1ebdc71cb480bd324b030f85c02dc6f8db879716faf0f7ee0f05df4c395d71b4",
|
|
186
|
+
"combinedSigningInput": "1ebdc71cb480bd324b030f85c02dc6f8db879716faf0f7ee0f05df4c395d71b43772e3a906c7b49d195345b05d73c3156bb3d61a5d1c641d64f4f03d661f7eeb"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
proofValues: {
|
|
190
|
+
"outer": "z33BeAxXEtbCKnt9mKodwoJFSDKqK2Q2zMrWN36TtpFhDn9K9FFX7rvyfY2jkFh8gcUo3iQvUutzqBKXZdsyKZAEz",
|
|
191
|
+
"inner": "z3arp9jZdt6kcLacoXxx5kb6QVM8GZFXD13nEisfna52uwMprZz2yJCXsbyMBvvBKZopCCNRq3o22UqYgudLum5eM"
|
|
192
|
+
},
|
|
193
|
+
expectedVerification: { "original": {
|
|
194
|
+
"inner": true,
|
|
195
|
+
"outer": true
|
|
196
|
+
} },
|
|
197
|
+
expectedInterpretation: {
|
|
198
|
+
"standaloneAndInParentExpansionsEqual": false,
|
|
199
|
+
"standaloneContentLanguage": null,
|
|
200
|
+
"inParentContentLanguage": "en"
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
//#endregion
|
|
204
|
+
export { map_local_context_conflict_default as t };
|