@fedify/fedify 2.4.2-dev.2362 → 2.4.3
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-BJZRkSA0.mjs → builder-CztvQYX0.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-DO7ihi0I.mjs → compound-proof-rcvB6i5j.mjs} +2 -2
- package/dist/{deno-B_xugrFs.mjs → deno-BEgaR4dC.mjs} +1 -1
- package/dist/{docloader-BX3_MM3H.mjs → docloader-Wf9RroxL.mjs} +4 -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 +5 -5
- package/dist/federation/handler.test.mjs +258 -6
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox-report.test.mjs +5 -5
- package/dist/federation/inbox.test.mjs +43 -0
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +172 -10
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +4 -5
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +4 -4
- package/dist/federation/portable-delivery.test.mjs +2 -2
- package/dist/federation/portable-gateway-keys.test.mjs +4 -4
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-BlPXdMEb.cjs → federation-O8HwbuUv.cjs} +121 -20
- package/dist/{http-D7Ppe8wk.js → http-B5pRXkmQ.js} +110 -12
- package/dist/{http-DCu7taFA.cjs → http-BFC8b7mH.cjs} +109 -11
- package/dist/{http-CyBekRok.mjs → http-CQcqhcga.mjs} +4 -4
- package/dist/inbox-CsErRN6L.mjs +188 -0
- package/dist/{kv-cache-DO6xJhDx.mjs → kv-cache-4oZXC3pf.mjs} +1 -1
- package/dist/{kv-cache-C359WofH.js → kv-cache-Bih-8AoZ.js} +3 -1
- package/dist/{kv-cache-D-yaUQia.cjs → kv-cache-JOKAStz2.cjs} +3 -1
- package/dist/{key-Day6TpI3.mjs → ld-Qk4WqslS.mjs} +760 -16
- package/dist/{metrics-CulPbfp_.mjs → metrics-DAhJVtgg.mjs} +1 -1
- package/dist/{middleware-Cy25vZ9k.mjs → middleware-B582s7UO.mjs} +103 -180
- package/dist/{middleware-D69pEjVH.mjs → middleware-C76AHpbO.mjs} +1 -1
- package/dist/{middleware-BM-cjLqQ.js → middleware-KeANQWIR.js} +121 -20
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-B4HTXRVN.mjs → owner-CcyHGdSK.mjs} +3 -3
- package/dist/{portable-collection-yAUltLHw.mjs → portable-collection-0RzCsflU.mjs} +2 -2
- package/dist/{portable-collection-6fBD7lq_.cjs → portable-collection-BHZq0F_c.cjs} +1 -1
- package/dist/{portable-collection-W1VJx8ZT.js → portable-collection-Chb6A43p.js} +1 -1
- package/dist/{portable-key-DhZDzmTZ.mjs → portable-key-BY6G_X28.mjs} +1 -1
- package/dist/{proof-BAh1znka.mjs → proof-nIOXkRme.mjs} +3 -4
- package/dist/{send-LwdLJ1Pk.mjs → send-C2r9whkz.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 +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +208 -3
- package/dist/sig/ld.test.mjs +1 -2
- package/dist/sig/mitra-receive-interop.test.mjs +4 -4
- package/dist/sig/mitra-send-interop.test.mjs +3 -3
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-interop.test.mjs +3 -3
- package/dist/sig/portable-key.test.mjs +5 -6
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/sig/tootik-request-interop.test.mjs +4 -4
- package/dist/sig/tootik-send-interop.test.mjs +3 -3
- package/dist/sig/verification.test.mjs +3 -3
- package/dist/{temporal-B16oe94V.mjs → temporal-D5tHfTGO.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/utils/docloader.test.mjs +112 -37
- 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
- package/dist/ld-D7AdYXVK.mjs +0 -658
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
const require_rolldown_runtime = require("./rolldown-runtime-Dmm3t92W.cjs");
|
|
3
3
|
const require_transformers = require("./transformers-BalCrSsr.cjs");
|
|
4
|
-
const require_http = require("./http-
|
|
4
|
+
const require_http = require("./http-BFC8b7mH.cjs");
|
|
5
5
|
const require_types = require("./types-poIao40f.cjs");
|
|
6
|
-
const require_portable_collection = require("./portable-collection-
|
|
7
|
-
const require_kv_cache = require("./kv-cache-
|
|
6
|
+
const require_portable_collection = require("./portable-collection-BHZq0F_c.cjs");
|
|
7
|
+
const require_kv_cache = require("./kv-cache-JOKAStz2.cjs");
|
|
8
8
|
let _logtape_logtape = require("@logtape/logtape");
|
|
9
9
|
let _fedify_uri_template = require("@fedify/uri-template");
|
|
10
10
|
let _fedify_vocab = require("@fedify/vocab");
|
|
@@ -2779,12 +2779,41 @@ async function isInAudience(object, actor, options = {}) {
|
|
|
2779
2779
|
//#endregion
|
|
2780
2780
|
//#region src/federation/inbox.ts
|
|
2781
2781
|
const Temporal$10 = require_http.Temporal;
|
|
2782
|
+
/**
|
|
2783
|
+
* Checks whether an activity's ID and all of its actor IDs have the same
|
|
2784
|
+
* [FEP-fe34] origin. Activities without an ID have no origin to authenticate.
|
|
2785
|
+
*
|
|
2786
|
+
* Origins are compared by `getAuthenticationOrigin()`, so a portable activity
|
|
2787
|
+
* and its portable actors, including compatible identifiers on any gateway,
|
|
2788
|
+
* are compared by their DIDs. An ID that has no supported origin, such as an
|
|
2789
|
+
* opaque URN, never matches.
|
|
2790
|
+
*
|
|
2791
|
+
* The caller is responsible for rejecting a missing primary actor ID before
|
|
2792
|
+
* relying on this check.
|
|
2793
|
+
*
|
|
2794
|
+
* [FEP-fe34]: https://w3id.org/fep/fe34
|
|
2795
|
+
* @internal
|
|
2796
|
+
*/
|
|
2797
|
+
function actorsHaveSameOrigin(activity) {
|
|
2798
|
+
if (activity.id == null) return true;
|
|
2799
|
+
const origin = require_http.getAuthenticationOrigin(activity.id);
|
|
2800
|
+
return origin != null && activity.actorIds.every((actor) => require_http.getAuthenticationOrigin(actor) === origin);
|
|
2801
|
+
}
|
|
2782
2802
|
async function routeActivity({ context: ctx, json, originalJson, normalizedActivity, ldSignatureVerified, activity, recipient, inboxListeners, inboxContextFactory, listenerInboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, meterProvider, tracerProvider, idempotencyStrategy }) {
|
|
2783
2803
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
2784
2804
|
"fedify",
|
|
2785
2805
|
"federation",
|
|
2786
2806
|
"inbox"
|
|
2787
2807
|
]);
|
|
2808
|
+
if (activity.actorId == null) {
|
|
2809
|
+
logger.error("Missing actor.", { activity: json });
|
|
2810
|
+
span.setStatus({
|
|
2811
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2812
|
+
message: "Missing actor."
|
|
2813
|
+
});
|
|
2814
|
+
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
2815
|
+
return "missingActor";
|
|
2816
|
+
}
|
|
2788
2817
|
let cacheKey = null;
|
|
2789
2818
|
if (activity.id != null) {
|
|
2790
2819
|
const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, (0, _fedify_vocab.getTypeId)(activity).href);
|
|
@@ -2820,15 +2849,6 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
|
|
|
2820
2849
|
return "alreadyProcessed";
|
|
2821
2850
|
}
|
|
2822
2851
|
}
|
|
2823
|
-
if (activity.actorId == null) {
|
|
2824
|
-
logger.error("Missing actor.", { activity: json });
|
|
2825
|
-
span.setStatus({
|
|
2826
|
-
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
2827
|
-
message: "Missing actor."
|
|
2828
|
-
});
|
|
2829
|
-
require_http.recordInboxActivity(meterProvider, "rejected", (0, _fedify_vocab.getTypeId)(activity).href);
|
|
2830
|
-
return "missingActor";
|
|
2831
|
-
}
|
|
2832
2852
|
span.setAttribute("activitypub.actor.id", activity.actorId.href);
|
|
2833
2853
|
if (queue != null) {
|
|
2834
2854
|
const carrier = {};
|
|
@@ -4746,13 +4766,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
|
|
|
4746
4766
|
* @param parameters The parameters for handling the collection.
|
|
4747
4767
|
* @returns A promise that resolves to an HTTP response.
|
|
4748
4768
|
*/
|
|
4749
|
-
async function handleCollection(request, { name: name$
|
|
4750
|
-
const spanName = name$
|
|
4769
|
+
async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, portable, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
|
|
4770
|
+
const spanName = name$1.trim().replace(/\s+/g, "_");
|
|
4751
4771
|
tracerProvider = tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
4752
4772
|
const tracer = tracerProvider.getTracer(require_http.name, require_http.version);
|
|
4753
4773
|
const cursor = new URL(request.url).searchParams.get("cursor");
|
|
4754
4774
|
const metricBase = {
|
|
4755
|
-
kind: getCollectionMetricKind(name$
|
|
4775
|
+
kind: getCollectionMetricKind(name$1),
|
|
4756
4776
|
page: cursor != null,
|
|
4757
4777
|
dispatcher: "built_in"
|
|
4758
4778
|
};
|
|
@@ -4798,7 +4818,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
4798
4818
|
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
4799
4819
|
return await onNotFound(request);
|
|
4800
4820
|
}
|
|
4801
|
-
const items = filterCollectionItems(page.items, name$
|
|
4821
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
4802
4822
|
itemCount = items.length;
|
|
4803
4823
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
4804
4824
|
return items;
|
|
@@ -4840,7 +4860,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
4840
4860
|
} else {
|
|
4841
4861
|
const uri = new URL(portable == null ? baseUri : pageBase);
|
|
4842
4862
|
uri.searchParams.set("cursor", cursor);
|
|
4843
|
-
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$
|
|
4863
|
+
const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
|
|
4844
4864
|
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
4845
4865
|
attributes: {
|
|
4846
4866
|
"activitypub.collection.id": uri.href,
|
|
@@ -4856,7 +4876,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
|
|
|
4856
4876
|
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
4857
4877
|
return await onNotFound(request);
|
|
4858
4878
|
}
|
|
4859
|
-
const items = filterCollectionItems(page.items, name$
|
|
4879
|
+
const items = filterCollectionItems(page.items, name$1, filterPredicate);
|
|
4860
4880
|
itemCount = items.length;
|
|
4861
4881
|
span.setAttribute("fedify.collection.items", itemCount);
|
|
4862
4882
|
return {
|
|
@@ -6005,11 +6025,49 @@ async function handleInboxInternal(request, parameters, span) {
|
|
|
6005
6025
|
return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
|
|
6006
6026
|
}
|
|
6007
6027
|
}
|
|
6028
|
+
if (!skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
6029
|
+
observation.authentication = {
|
|
6030
|
+
status: "rejected",
|
|
6031
|
+
reason: { type: "verificationFailed" }
|
|
6032
|
+
};
|
|
6033
|
+
logger.error("The activity ({activityId}) and its actors do not have the same origin.", {
|
|
6034
|
+
activity: json,
|
|
6035
|
+
recipient,
|
|
6036
|
+
activityId: activity.id.href,
|
|
6037
|
+
actorIds: activity.actorIds.map((actor) => actor.href)
|
|
6038
|
+
});
|
|
6039
|
+
span.setStatus({
|
|
6040
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
6041
|
+
message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
|
|
6042
|
+
});
|
|
6043
|
+
return new Response("The activity and its actors do not have the same origin.", {
|
|
6044
|
+
status: 401,
|
|
6045
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
6046
|
+
});
|
|
6047
|
+
}
|
|
6008
6048
|
observation.authentication = skipSignatureVerification ? { status: "skipped" } : {
|
|
6009
6049
|
status: "verified",
|
|
6010
6050
|
attempts: observation.verification.attempts.filter((attempt) => attempt.status === "verified")
|
|
6011
6051
|
};
|
|
6012
6052
|
observation.stage = "dispatch";
|
|
6053
|
+
if (activity.actorId == null) {
|
|
6054
|
+
observation.result = {
|
|
6055
|
+
disposition: "rejected",
|
|
6056
|
+
reason: "missingActor"
|
|
6057
|
+
};
|
|
6058
|
+
logger.error("Missing actor.", {
|
|
6059
|
+
activity: json,
|
|
6060
|
+
recipient
|
|
6061
|
+
});
|
|
6062
|
+
span.setStatus({
|
|
6063
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
6064
|
+
message: "Missing actor."
|
|
6065
|
+
});
|
|
6066
|
+
return new Response("Missing actor.", {
|
|
6067
|
+
status: 400,
|
|
6068
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
6069
|
+
});
|
|
6070
|
+
}
|
|
6013
6071
|
const routeResult = await routeActivity({
|
|
6014
6072
|
context: ctx,
|
|
6015
6073
|
json,
|
|
@@ -6230,8 +6288,8 @@ var CustomCollectionHandler = class {
|
|
|
6230
6288
|
* @param CollectionPage The CollectionPage constructor.
|
|
6231
6289
|
* @param filterPredicate Optional filter predicate for items.
|
|
6232
6290
|
*/
|
|
6233
|
-
constructor(name$
|
|
6234
|
-
this.name = name$
|
|
6291
|
+
constructor(name$2, values, context, callbacks, tracerProvider = _opentelemetry_api.trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate, portable) {
|
|
6292
|
+
this.name = name$2;
|
|
6235
6293
|
this.values = values;
|
|
6236
6294
|
this.context = context;
|
|
6237
6295
|
this.callbacks = callbacks;
|
|
@@ -9357,6 +9415,35 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
9357
9415
|
span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
9358
9416
|
listenerSpan.setAttribute("activitypub.activity.id", activity.id.href);
|
|
9359
9417
|
}
|
|
9418
|
+
if (activity.actorId == null) {
|
|
9419
|
+
logger.error("Missing actor in queued incoming activity.", {
|
|
9420
|
+
activityId: activity.id?.href,
|
|
9421
|
+
activity: message.activity,
|
|
9422
|
+
recipient: message.identifier
|
|
9423
|
+
});
|
|
9424
|
+
listenerSpan.setStatus({
|
|
9425
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
9426
|
+
message: "Missing actor."
|
|
9427
|
+
});
|
|
9428
|
+
require_http.recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
9429
|
+
listenerSpan.end();
|
|
9430
|
+
return;
|
|
9431
|
+
}
|
|
9432
|
+
if (!this.skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
9433
|
+
logger.error("The queued activity ({activityId}) and its actors do not have the same origin.", {
|
|
9434
|
+
activityId: activity.id.href,
|
|
9435
|
+
actorIds: activity.actorIds.map((actor) => actor.href),
|
|
9436
|
+
activity: message.activity,
|
|
9437
|
+
recipient: message.identifier
|
|
9438
|
+
});
|
|
9439
|
+
listenerSpan.setStatus({
|
|
9440
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
9441
|
+
message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
|
|
9442
|
+
});
|
|
9443
|
+
require_http.recordInboxActivity(this.meterProvider, "rejected", activityType);
|
|
9444
|
+
listenerSpan.end();
|
|
9445
|
+
return;
|
|
9446
|
+
}
|
|
9360
9447
|
cacheKey = activity.id == null ? null : [
|
|
9361
9448
|
...this.kvPrefixes.activityIdempotence,
|
|
9362
9449
|
context.origin,
|
|
@@ -11433,6 +11520,20 @@ var ContextImpl = class ContextImpl {
|
|
|
11433
11520
|
recipient,
|
|
11434
11521
|
activity: json
|
|
11435
11522
|
});
|
|
11523
|
+
if (activity.actorId == null) {
|
|
11524
|
+
logger.debug("Activity is missing an actor; unable to verify.", {
|
|
11525
|
+
recipient,
|
|
11526
|
+
activity: json
|
|
11527
|
+
});
|
|
11528
|
+
return false;
|
|
11529
|
+
}
|
|
11530
|
+
if (activity.id != null && !actorsHaveSameOrigin(activity)) {
|
|
11531
|
+
logger.debug("Activity has actors from different origins; unable to verify.", {
|
|
11532
|
+
recipient,
|
|
11533
|
+
activity: json
|
|
11534
|
+
});
|
|
11535
|
+
return false;
|
|
11536
|
+
}
|
|
11436
11537
|
const routeResult = await routeActivity({
|
|
11437
11538
|
context: this,
|
|
11438
11539
|
json,
|
|
@@ -3,7 +3,7 @@ import { URLPattern } from "urlpattern-polyfill";
|
|
|
3
3
|
import { getLogger } from "@logtape/logtape";
|
|
4
4
|
import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, PUBLIC_COLLECTION, getTypeId, isActor } from "@fedify/vocab";
|
|
5
5
|
import { SpanKind, SpanStatusCode, metrics, trace } from "@opentelemetry/api";
|
|
6
|
-
import { FetchError, canonicalizePortableUri, encodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDidKeyVerificationMethod, parseGatewayUrl, parseIri, preloadedContexts, toCompatibleEf61Id } from "@fedify/vocab-runtime";
|
|
6
|
+
import { FetchError, UrlError, canonicalizePortableUri, encodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDidKeyVerificationMethod, parseGatewayUrl, parseIri, preloadedContexts, toCompatibleEf61Id } from "@fedify/vocab-runtime";
|
|
7
7
|
import { getPortableGatewayCandidates, isCompatibleEf61Iri } from "@fedify/vocab-runtime/internal/portable-dereference";
|
|
8
8
|
import { encodeHex } from "byte-encodings/hex";
|
|
9
9
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
@@ -15,7 +15,7 @@ import serialize from "json-canon";
|
|
|
15
15
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
16
16
|
//#region deno.json
|
|
17
17
|
var name = "@fedify/fedify";
|
|
18
|
-
var version = "2.4.
|
|
18
|
+
var version = "2.4.3";
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region src/sig/portable-key-id.ts
|
|
21
21
|
const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
|
|
@@ -1430,6 +1430,65 @@ async function parseKeyOwnerEvidence(evidence, options = {}) {
|
|
|
1430
1430
|
}
|
|
1431
1431
|
//#endregion
|
|
1432
1432
|
//#region src/sig/key.ts
|
|
1433
|
+
/** Classifies decoding failures without hiding unexpected loader errors. */
|
|
1434
|
+
function classifyKeyJsonLdError(error, seen = /* @__PURE__ */ new Set()) {
|
|
1435
|
+
if (!(error instanceof Error) || !error.name.startsWith("jsonld.")) return null;
|
|
1436
|
+
if (seen.has(error)) throw error;
|
|
1437
|
+
seen.add(error);
|
|
1438
|
+
const details = error.details;
|
|
1439
|
+
if (typeof details?.code !== "string") return null;
|
|
1440
|
+
if (details.code !== "loading remote context failed" || !("cause" in details) && !("cause" in error)) return "invalid";
|
|
1441
|
+
const cause = "cause" in details ? details.cause : error.cause;
|
|
1442
|
+
const nestedFailure = classifyKeyJsonLdError(cause, seen);
|
|
1443
|
+
if (nestedFailure != null) return nestedFailure;
|
|
1444
|
+
if (cause instanceof SyntaxError) return "invalid";
|
|
1445
|
+
if (cause instanceof FetchError || cause instanceof UrlError) return "fetch";
|
|
1446
|
+
if (cause instanceof Error && [
|
|
1447
|
+
"AbortError",
|
|
1448
|
+
"TimeoutError",
|
|
1449
|
+
"NetworkError"
|
|
1450
|
+
].includes(cause.name)) return "fetch";
|
|
1451
|
+
if (cause instanceof TypeError) {
|
|
1452
|
+
const urlCode = cause.code;
|
|
1453
|
+
if (cause.name === "InvalidContextReferenceError") return "invalid";
|
|
1454
|
+
if (urlCode === "ERR_INVALID_URL" || cause.message === "Invalid URL string." || /^Invalid URL(?::|$)/.test(cause.message) || / cannot be parsed as a URL\.?$/.test(cause.message)) return typeof details.url === "string" && /^[A-Za-z][A-Za-z0-9+.-]*:/.test(details.url) && !URL.canParse(details.url) ? "invalid" : "fetch";
|
|
1455
|
+
const networkCause = cause.cause;
|
|
1456
|
+
const code = cause.code ?? networkCause?.code;
|
|
1457
|
+
if (typeof code === "string" && [
|
|
1458
|
+
"ECONNREFUSED",
|
|
1459
|
+
"ECONNRESET",
|
|
1460
|
+
"ECONNABORTED",
|
|
1461
|
+
"ETIMEDOUT",
|
|
1462
|
+
"EHOSTUNREACH",
|
|
1463
|
+
"ENETUNREACH",
|
|
1464
|
+
"ENOTFOUND",
|
|
1465
|
+
"EAI_AGAIN",
|
|
1466
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
1467
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
1468
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
1469
|
+
"UND_ERR_SOCKET"
|
|
1470
|
+
].includes(code) || /^(fetch failed|Failed to fetch|error sending request|error reading a body from connection|Unable to connect|ConnectionRefused|Network connection lost|The socket connection was closed unexpectedly)/.test(cause.message)) return "fetch";
|
|
1471
|
+
}
|
|
1472
|
+
throw cause;
|
|
1473
|
+
}
|
|
1474
|
+
/** Carries a context transport failure through the key decoding boundary. */
|
|
1475
|
+
var KeyContextFetchError = class extends Error {
|
|
1476
|
+
error;
|
|
1477
|
+
constructor(error) {
|
|
1478
|
+
super("Failed to fetch a key's JSON-LD context.", { cause: error });
|
|
1479
|
+
this.error = error;
|
|
1480
|
+
}
|
|
1481
|
+
};
|
|
1482
|
+
function contextFetchError(error) {
|
|
1483
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1484
|
+
while (error instanceof Error && !seen.has(error)) {
|
|
1485
|
+
seen.add(error);
|
|
1486
|
+
const details = error.details;
|
|
1487
|
+
if (!error.name.startsWith("jsonld.") || details?.code !== "loading remote context failed") break;
|
|
1488
|
+
error = "cause" in details ? details.cause : error.cause;
|
|
1489
|
+
}
|
|
1490
|
+
return new KeyContextFetchError(error);
|
|
1491
|
+
}
|
|
1433
1492
|
/**
|
|
1434
1493
|
* Checks if the given key is valid and supported. No-op if the key is valid,
|
|
1435
1494
|
* otherwise throws an error.
|
|
@@ -1524,6 +1583,9 @@ async function importJwk(jwk, type) {
|
|
|
1524
1583
|
* @internal
|
|
1525
1584
|
*/
|
|
1526
1585
|
async function fetchActorDocument(actorId, options = {}) {
|
|
1586
|
+
return await fetchActorDocumentInternal(actorId, options, false);
|
|
1587
|
+
}
|
|
1588
|
+
async function fetchActorDocumentInternal(actorId, options, propagateContextFetchErrors) {
|
|
1527
1589
|
const logger = getLogger([
|
|
1528
1590
|
"fedify",
|
|
1529
1591
|
"sig",
|
|
@@ -1558,9 +1620,12 @@ async function fetchActorDocument(actorId, options = {}) {
|
|
|
1558
1620
|
baseUrl: documentUrl
|
|
1559
1621
|
});
|
|
1560
1622
|
} catch (error) {
|
|
1561
|
-
|
|
1562
|
-
|
|
1623
|
+
const failure = classifyKeyJsonLdError(error);
|
|
1624
|
+
if (failure === "fetch" && propagateContextFetchErrors) throw contextFetchError(error);
|
|
1625
|
+
if (failure == null && !(error instanceof TypeError)) throw error;
|
|
1626
|
+
logger.debug("Failed to decode the actor document at {documentUrl}: {error}", {
|
|
1563
1627
|
documentUrl: documentUrl.href,
|
|
1628
|
+
failure: failure ?? "invalid",
|
|
1564
1629
|
error
|
|
1565
1630
|
});
|
|
1566
1631
|
return null;
|
|
@@ -1606,6 +1671,9 @@ async function fetchActorDocument(actorId, options = {}) {
|
|
|
1606
1671
|
* @internal
|
|
1607
1672
|
*/
|
|
1608
1673
|
async function verifyKeyOwnership(key, options = {}) {
|
|
1674
|
+
return await verifyKeyOwnershipInternal(key, options, false);
|
|
1675
|
+
}
|
|
1676
|
+
async function verifyKeyOwnershipInternal(key, options, propagateContextFetchErrors) {
|
|
1609
1677
|
const logger = getLogger([
|
|
1610
1678
|
"fedify",
|
|
1611
1679
|
"sig",
|
|
@@ -1615,7 +1683,7 @@ async function verifyKeyOwnership(key, options = {}) {
|
|
|
1615
1683
|
if (keyId == null) return null;
|
|
1616
1684
|
const claimedOwnerId = key instanceof CryptographicKey ? key.ownerId : key.controllerId;
|
|
1617
1685
|
if (claimedOwnerId == null) return null;
|
|
1618
|
-
const owner = await
|
|
1686
|
+
const owner = await fetchActorDocumentInternal(claimedOwnerId, options, propagateContextFetchErrors);
|
|
1619
1687
|
if (owner == null) {
|
|
1620
1688
|
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims could not be resolved.", {
|
|
1621
1689
|
keyId: keyId.href,
|
|
@@ -1941,6 +2009,21 @@ async function resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, {
|
|
|
1941
2009
|
tracerProvider
|
|
1942
2010
|
});
|
|
1943
2011
|
} catch (e) {
|
|
2012
|
+
const failure = classifyKeyJsonLdError(e);
|
|
2013
|
+
if (failure === "fetch") throw contextFetchError(e);
|
|
2014
|
+
if (failure != null) {
|
|
2015
|
+
logger.debug("Failed to decode key {keyId}: {error}", {
|
|
2016
|
+
keyId,
|
|
2017
|
+
failure,
|
|
2018
|
+
error: e
|
|
2019
|
+
});
|
|
2020
|
+
await keyCache?.set(cacheKey, null);
|
|
2021
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
2022
|
+
return {
|
|
2023
|
+
key: null,
|
|
2024
|
+
cached: false
|
|
2025
|
+
};
|
|
2026
|
+
}
|
|
1944
2027
|
if (!(e instanceof TypeError)) throw e;
|
|
1945
2028
|
try {
|
|
1946
2029
|
object = await cls.fromJsonLd(document, {
|
|
@@ -1949,8 +2032,14 @@ async function resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, {
|
|
|
1949
2032
|
tracerProvider
|
|
1950
2033
|
});
|
|
1951
2034
|
} catch (e) {
|
|
1952
|
-
|
|
1953
|
-
|
|
2035
|
+
const failure = classifyKeyJsonLdError(e);
|
|
2036
|
+
if (failure === "fetch") throw contextFetchError(e);
|
|
2037
|
+
if (failure != null || e instanceof TypeError) {
|
|
2038
|
+
logger.debug("Failed to decode key {keyId}: {error}", {
|
|
2039
|
+
keyId,
|
|
2040
|
+
failure: failure ?? "invalid",
|
|
2041
|
+
error: e
|
|
2042
|
+
});
|
|
1954
2043
|
await keyCache?.set(cacheKey, null);
|
|
1955
2044
|
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
1956
2045
|
return {
|
|
@@ -2089,16 +2178,17 @@ async function resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, {
|
|
|
2089
2178
|
}
|
|
2090
2179
|
if (ownerDocument != null && claimedOwnerId == null) key = key instanceof CryptographicKey ? key.clone({ owner: ownerDocument.id }) : key.clone({ controller: ownerDocument.id });
|
|
2091
2180
|
else if (claimedOwnerId != null && claimedOwnerId.href !== ownerDocument?.id?.href) {
|
|
2092
|
-
if (await
|
|
2181
|
+
if (await verifyKeyOwnershipInternal(key, {
|
|
2093
2182
|
documentLoader,
|
|
2094
2183
|
contextLoader,
|
|
2095
2184
|
tracerProvider
|
|
2096
|
-
}) == null) {
|
|
2185
|
+
}, true) == null) {
|
|
2097
2186
|
logger.debug("Failed to verify; the owner {claimedOwnerId} that key {keyId} claims does not list the key as its own.", {
|
|
2098
2187
|
keyId,
|
|
2099
2188
|
claimedOwnerId: claimedOwnerId.href
|
|
2100
2189
|
});
|
|
2101
2190
|
await keyCache?.set(cacheKey, null);
|
|
2191
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
2102
2192
|
return {
|
|
2103
2193
|
key: null,
|
|
2104
2194
|
cached: false
|
|
@@ -2175,9 +2265,17 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
|
|
|
2175
2265
|
outcome = classified;
|
|
2176
2266
|
return errored;
|
|
2177
2267
|
}
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2268
|
+
try {
|
|
2269
|
+
const resolved = await resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, options, logger);
|
|
2270
|
+
outcome = { result: resolved.key != null ? "fetched" : "invalid" };
|
|
2271
|
+
return resolved;
|
|
2272
|
+
} catch (error) {
|
|
2273
|
+
if (!(error instanceof KeyContextFetchError)) throw error;
|
|
2274
|
+
const classified = classifyFetchError(error.error);
|
|
2275
|
+
const errored = await onFetchError(error.error, cacheKey, keyId, keyCache, logger);
|
|
2276
|
+
outcome = classified;
|
|
2277
|
+
return errored;
|
|
2278
|
+
}
|
|
2181
2279
|
} finally {
|
|
2182
2280
|
recordKeyLookup(options.meterProvider, {
|
|
2183
2281
|
durationMs: getDurationMs(start),
|
|
@@ -17,7 +17,7 @@ json_canon = require_rolldown_runtime.__toESM(json_canon, 1);
|
|
|
17
17
|
let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
18
18
|
//#region deno.json
|
|
19
19
|
var name = "@fedify/fedify";
|
|
20
|
-
var version = "2.4.
|
|
20
|
+
var version = "2.4.3";
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region src/sig/portable-key-id.ts
|
|
23
23
|
const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
|
|
@@ -4998,6 +4998,65 @@ async function parseKeyOwnerEvidence(evidence, options = {}) {
|
|
|
4998
4998
|
//#endregion
|
|
4999
4999
|
//#region src/sig/key.ts
|
|
5000
5000
|
const Temporal$2 = Temporal$4;
|
|
5001
|
+
/** Classifies decoding failures without hiding unexpected loader errors. */
|
|
5002
|
+
function classifyKeyJsonLdError(error, seen = /* @__PURE__ */ new Set()) {
|
|
5003
|
+
if (!(error instanceof Error) || !error.name.startsWith("jsonld.")) return null;
|
|
5004
|
+
if (seen.has(error)) throw error;
|
|
5005
|
+
seen.add(error);
|
|
5006
|
+
const details = error.details;
|
|
5007
|
+
if (typeof details?.code !== "string") return null;
|
|
5008
|
+
if (details.code !== "loading remote context failed" || !("cause" in details) && !("cause" in error)) return "invalid";
|
|
5009
|
+
const cause = "cause" in details ? details.cause : error.cause;
|
|
5010
|
+
const nestedFailure = classifyKeyJsonLdError(cause, seen);
|
|
5011
|
+
if (nestedFailure != null) return nestedFailure;
|
|
5012
|
+
if (cause instanceof SyntaxError) return "invalid";
|
|
5013
|
+
if (cause instanceof _fedify_vocab_runtime.FetchError || cause instanceof _fedify_vocab_runtime.UrlError) return "fetch";
|
|
5014
|
+
if (cause instanceof Error && [
|
|
5015
|
+
"AbortError",
|
|
5016
|
+
"TimeoutError",
|
|
5017
|
+
"NetworkError"
|
|
5018
|
+
].includes(cause.name)) return "fetch";
|
|
5019
|
+
if (cause instanceof TypeError) {
|
|
5020
|
+
const urlCode = cause.code;
|
|
5021
|
+
if (cause.name === "InvalidContextReferenceError") return "invalid";
|
|
5022
|
+
if (urlCode === "ERR_INVALID_URL" || cause.message === "Invalid URL string." || /^Invalid URL(?::|$)/.test(cause.message) || / cannot be parsed as a URL\.?$/.test(cause.message)) return typeof details.url === "string" && /^[A-Za-z][A-Za-z0-9+.-]*:/.test(details.url) && !URL.canParse(details.url) ? "invalid" : "fetch";
|
|
5023
|
+
const networkCause = cause.cause;
|
|
5024
|
+
const code = cause.code ?? networkCause?.code;
|
|
5025
|
+
if (typeof code === "string" && [
|
|
5026
|
+
"ECONNREFUSED",
|
|
5027
|
+
"ECONNRESET",
|
|
5028
|
+
"ECONNABORTED",
|
|
5029
|
+
"ETIMEDOUT",
|
|
5030
|
+
"EHOSTUNREACH",
|
|
5031
|
+
"ENETUNREACH",
|
|
5032
|
+
"ENOTFOUND",
|
|
5033
|
+
"EAI_AGAIN",
|
|
5034
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
5035
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
5036
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
5037
|
+
"UND_ERR_SOCKET"
|
|
5038
|
+
].includes(code) || /^(fetch failed|Failed to fetch|error sending request|error reading a body from connection|Unable to connect|ConnectionRefused|Network connection lost|The socket connection was closed unexpectedly)/.test(cause.message)) return "fetch";
|
|
5039
|
+
}
|
|
5040
|
+
throw cause;
|
|
5041
|
+
}
|
|
5042
|
+
/** Carries a context transport failure through the key decoding boundary. */
|
|
5043
|
+
var KeyContextFetchError = class extends Error {
|
|
5044
|
+
error;
|
|
5045
|
+
constructor(error) {
|
|
5046
|
+
super("Failed to fetch a key's JSON-LD context.", { cause: error });
|
|
5047
|
+
this.error = error;
|
|
5048
|
+
}
|
|
5049
|
+
};
|
|
5050
|
+
function contextFetchError(error) {
|
|
5051
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5052
|
+
while (error instanceof Error && !seen.has(error)) {
|
|
5053
|
+
seen.add(error);
|
|
5054
|
+
const details = error.details;
|
|
5055
|
+
if (!error.name.startsWith("jsonld.") || details?.code !== "loading remote context failed") break;
|
|
5056
|
+
error = "cause" in details ? details.cause : error.cause;
|
|
5057
|
+
}
|
|
5058
|
+
return new KeyContextFetchError(error);
|
|
5059
|
+
}
|
|
5001
5060
|
/**
|
|
5002
5061
|
* Checks if the given key is valid and supported. No-op if the key is valid,
|
|
5003
5062
|
* otherwise throws an error.
|
|
@@ -5092,6 +5151,9 @@ async function importJwk(jwk, type) {
|
|
|
5092
5151
|
* @internal
|
|
5093
5152
|
*/
|
|
5094
5153
|
async function fetchActorDocument(actorId, options = {}) {
|
|
5154
|
+
return await fetchActorDocumentInternal(actorId, options, false);
|
|
5155
|
+
}
|
|
5156
|
+
async function fetchActorDocumentInternal(actorId, options, propagateContextFetchErrors) {
|
|
5095
5157
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
5096
5158
|
"fedify",
|
|
5097
5159
|
"sig",
|
|
@@ -5126,9 +5188,12 @@ async function fetchActorDocument(actorId, options = {}) {
|
|
|
5126
5188
|
baseUrl: documentUrl
|
|
5127
5189
|
});
|
|
5128
5190
|
} catch (error) {
|
|
5129
|
-
|
|
5130
|
-
|
|
5191
|
+
const failure = classifyKeyJsonLdError(error);
|
|
5192
|
+
if (failure === "fetch" && propagateContextFetchErrors) throw contextFetchError(error);
|
|
5193
|
+
if (failure == null && !(error instanceof TypeError)) throw error;
|
|
5194
|
+
logger.debug("Failed to decode the actor document at {documentUrl}: {error}", {
|
|
5131
5195
|
documentUrl: documentUrl.href,
|
|
5196
|
+
failure: failure ?? "invalid",
|
|
5132
5197
|
error
|
|
5133
5198
|
});
|
|
5134
5199
|
return null;
|
|
@@ -5174,6 +5239,9 @@ async function fetchActorDocument(actorId, options = {}) {
|
|
|
5174
5239
|
* @internal
|
|
5175
5240
|
*/
|
|
5176
5241
|
async function verifyKeyOwnership(key, options = {}) {
|
|
5242
|
+
return await verifyKeyOwnershipInternal(key, options, false);
|
|
5243
|
+
}
|
|
5244
|
+
async function verifyKeyOwnershipInternal(key, options, propagateContextFetchErrors) {
|
|
5177
5245
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
5178
5246
|
"fedify",
|
|
5179
5247
|
"sig",
|
|
@@ -5183,7 +5251,7 @@ async function verifyKeyOwnership(key, options = {}) {
|
|
|
5183
5251
|
if (keyId == null) return null;
|
|
5184
5252
|
const claimedOwnerId = key instanceof _fedify_vocab.CryptographicKey ? key.ownerId : key.controllerId;
|
|
5185
5253
|
if (claimedOwnerId == null) return null;
|
|
5186
|
-
const owner = await
|
|
5254
|
+
const owner = await fetchActorDocumentInternal(claimedOwnerId, options, propagateContextFetchErrors);
|
|
5187
5255
|
if (owner == null) {
|
|
5188
5256
|
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims could not be resolved.", {
|
|
5189
5257
|
keyId: keyId.href,
|
|
@@ -5509,6 +5577,21 @@ async function resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, {
|
|
|
5509
5577
|
tracerProvider
|
|
5510
5578
|
});
|
|
5511
5579
|
} catch (e) {
|
|
5580
|
+
const failure = classifyKeyJsonLdError(e);
|
|
5581
|
+
if (failure === "fetch") throw contextFetchError(e);
|
|
5582
|
+
if (failure != null) {
|
|
5583
|
+
logger.debug("Failed to decode key {keyId}: {error}", {
|
|
5584
|
+
keyId,
|
|
5585
|
+
failure,
|
|
5586
|
+
error: e
|
|
5587
|
+
});
|
|
5588
|
+
await keyCache?.set(cacheKey, null);
|
|
5589
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
5590
|
+
return {
|
|
5591
|
+
key: null,
|
|
5592
|
+
cached: false
|
|
5593
|
+
};
|
|
5594
|
+
}
|
|
5512
5595
|
if (!(e instanceof TypeError)) throw e;
|
|
5513
5596
|
try {
|
|
5514
5597
|
object = await cls.fromJsonLd(document, {
|
|
@@ -5517,8 +5600,14 @@ async function resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, {
|
|
|
5517
5600
|
tracerProvider
|
|
5518
5601
|
});
|
|
5519
5602
|
} catch (e) {
|
|
5520
|
-
|
|
5521
|
-
|
|
5603
|
+
const failure = classifyKeyJsonLdError(e);
|
|
5604
|
+
if (failure === "fetch") throw contextFetchError(e);
|
|
5605
|
+
if (failure != null || e instanceof TypeError) {
|
|
5606
|
+
logger.debug("Failed to decode key {keyId}: {error}", {
|
|
5607
|
+
keyId,
|
|
5608
|
+
failure: failure ?? "invalid",
|
|
5609
|
+
error: e
|
|
5610
|
+
});
|
|
5522
5611
|
await keyCache?.set(cacheKey, null);
|
|
5523
5612
|
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
5524
5613
|
return {
|
|
@@ -5657,16 +5746,17 @@ async function resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, {
|
|
|
5657
5746
|
}
|
|
5658
5747
|
if (ownerDocument != null && claimedOwnerId == null) key = key instanceof _fedify_vocab.CryptographicKey ? key.clone({ owner: ownerDocument.id }) : key.clone({ controller: ownerDocument.id });
|
|
5659
5748
|
else if (claimedOwnerId != null && claimedOwnerId.href !== ownerDocument?.id?.href) {
|
|
5660
|
-
if (await
|
|
5749
|
+
if (await verifyKeyOwnershipInternal(key, {
|
|
5661
5750
|
documentLoader,
|
|
5662
5751
|
contextLoader,
|
|
5663
5752
|
tracerProvider
|
|
5664
|
-
}) == null) {
|
|
5753
|
+
}, true) == null) {
|
|
5665
5754
|
logger.debug("Failed to verify; the owner {claimedOwnerId} that key {keyId} claims does not list the key as its own.", {
|
|
5666
5755
|
keyId,
|
|
5667
5756
|
claimedOwnerId: claimedOwnerId.href
|
|
5668
5757
|
});
|
|
5669
5758
|
await keyCache?.set(cacheKey, null);
|
|
5759
|
+
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
5670
5760
|
return {
|
|
5671
5761
|
key: null,
|
|
5672
5762
|
cached: false
|
|
@@ -5743,9 +5833,17 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
|
|
|
5743
5833
|
outcome = classified;
|
|
5744
5834
|
return errored;
|
|
5745
5835
|
}
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5836
|
+
try {
|
|
5837
|
+
const resolved = await resolveFetchedKey(document, cacheKey, documentUrl, keyId, cls, options, logger);
|
|
5838
|
+
outcome = { result: resolved.key != null ? "fetched" : "invalid" };
|
|
5839
|
+
return resolved;
|
|
5840
|
+
} catch (error) {
|
|
5841
|
+
if (!(error instanceof KeyContextFetchError)) throw error;
|
|
5842
|
+
const classified = classifyFetchError(error.error);
|
|
5843
|
+
const errored = await onFetchError(error.error, cacheKey, keyId, keyCache, logger);
|
|
5844
|
+
outcome = classified;
|
|
5845
|
+
return errored;
|
|
5846
|
+
}
|
|
5749
5847
|
} finally {
|
|
5750
5848
|
recordKeyLookup(options.meterProvider, {
|
|
5751
5849
|
durationMs: getDurationMs(start),
|
|
@@ -3,12 +3,12 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { m as parseKeyIdString } from "./portable-key-id-Ca30-hOa.mjs";
|
|
5
5
|
import { a as verificationObservation, i as triedKey, n as observeCheck, t as observeAttempt } from "./verification-Dpfcw8ml.mjs";
|
|
6
|
-
import { n as version, t as name } from "./deno-
|
|
7
|
-
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
+
import { n as version, t as name } from "./deno-BEgaR4dC.mjs";
|
|
7
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-DAhJVtgg.mjs";
|
|
8
8
|
import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPVqki78.mjs";
|
|
9
9
|
import { a as promoteKeyOwnerEvidence } from "./key-owner-evidence-APB6NpSk.mjs";
|
|
10
|
-
import {
|
|
11
|
-
import { n as resolvePortableActorKey, r as verifyPortableGatewayKeyDocument } from "./portable-key-
|
|
10
|
+
import { S as fetchKeyDetailed, T as validateCryptoKey, v as bypassKeyCacheReads } from "./ld-Qk4WqslS.mjs";
|
|
11
|
+
import { n as resolvePortableActorKey, r as verifyPortableGatewayKeyDocument } from "./portable-key-BY6G_X28.mjs";
|
|
12
12
|
import { getLogger } from "@logtape/logtape";
|
|
13
13
|
import { CryptographicKey } from "@fedify/vocab";
|
|
14
14
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|