@fedify/fedify 2.5.0-dev.2364 → 2.5.0-dev.2378
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-ClDm_1c7.mjs → builder-J1K0IJj6.mjs} +2 -2
- 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-D03g5HXz.mjs → compound-proof-DtmVrMV7.mjs} +47 -19
- package/dist/{context-tsYPJ2Ew.d.cts → context-BjD_CTxh.d.cts} +1 -1
- package/dist/{context-7NyiqIcg.d.ts → context-C2-UDo2c.d.ts} +1 -1
- package/dist/{deno-Bp8q024B.mjs → deno-Ci6tSK9-.mjs} +1 -1
- package/dist/{docloader-DarxdYmj.mjs → docloader-DZ9h6KJS.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 +4 -5
- 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/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 +3 -3
- package/dist/federation/mod.d.ts +3 -3
- 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-BW53Wxj7.cjs → federation-lzy7M3hT.cjs} +48 -20
- package/dist/{http-D6JDnBO1.mjs → http-CFyizTHa.mjs} +4 -4
- package/dist/{http-Cg5Yj_yk.js → http-Cmz7x6Iw.js} +151 -19
- package/dist/{http-Btzv2JZU.cjs → http-D1RPHoq3.cjs} +161 -17
- package/dist/{key-DYxuyd-s.d.cts → key-DhsBxxZN.d.ts} +6 -2
- package/dist/{key-C1nv7_jD.d.ts → key-nYGY4QB9.d.cts} +6 -2
- package/dist/{kv-cache-CamfvHLY.js → kv-cache-C0-HuvwP.js} +1 -1
- package/dist/{kv-cache-0qHe-sN1.cjs → kv-cache-Jym5nP3J.cjs} +1 -1
- package/dist/{kv-cache-BoekCvYF.mjs → kv-cache-rOQX3I3c.mjs} +1 -1
- package/dist/{key-R5cUSA6S.mjs → ld-DJ--ZUpr.mjs} +760 -16
- package/dist/{metrics-DUdlIyrB.mjs → metrics-Dwgav7s_.mjs} +1 -1
- package/dist/{middleware-Hl0lTClT.mjs → middleware-BbBsa5iR.mjs} +13 -14
- package/dist/{middleware-DLB1TqQ1.mjs → middleware-CJWxuUy5.mjs} +1 -1
- package/dist/{middleware-BYOXwJvI.js → middleware-CqgRIsWM.js} +48 -20
- package/dist/{mod-Dw-nPxQh.d.cts → mod-B5-wdzmJ.d.cts} +1 -1
- package/dist/{mod-BojP2Bw3.d.cts → mod-BBPd4M_0.d.cts} +1 -1
- package/dist/{mod-CtpF2BU5.d.ts → mod-BRpER-B0.d.ts} +1 -1
- package/dist/{mod-Xj5P4s4d.d.ts → mod-CUYBGKof.d.ts} +1 -1
- package/dist/{mod-DEZXwV6J.d.ts → mod-DkhfZC1u.d.ts} +1 -1
- package/dist/{mod-CavhAgLw.d.cts → mod-xAfaLS4T.d.cts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-CKHKMnp-.mjs → owner-Btd7SwMj.mjs} +3 -3
- package/dist/{portable-collection-CyTnj1m9.cjs → portable-collection-BvWxS1sL.cjs} +1 -1
- package/dist/{portable-collection-Dhg0By3t.js → portable-collection-DwQT28O2.js} +1 -1
- package/dist/{portable-collection-DxVKitQN.mjs → portable-collection-gb9V8XEO.mjs} +2 -2
- package/dist/{portable-key-BOBhrrKN.mjs → portable-key-Cwti99nP.mjs} +1 -1
- package/dist/{proof-BGyUYuOb.mjs → proof-Bwzv6mXZ.mjs} +44 -11
- package/dist/{send-DmlYxKmb.mjs → send-BrQYUSb4.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 +168 -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.d.cts +2 -2
- package/dist/sig/mod.d.ts +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-Bvota1RR.mjs → temporal-BRaCTxVe.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +5 -1
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.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/ld-B6RQHcnq.mjs +0 -658
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as MemoryKvStore } from "../../kv-DCHkaJ9-.mjs";
|
|
5
5
|
import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../tasks-IG3pHfvZ.mjs";
|
|
6
6
|
import "../../testing-t8xDeJZ5.mjs";
|
|
7
|
-
import { o as createFederation } from "../../middleware-
|
|
7
|
+
import { o as createFederation } from "../../middleware-BbBsa5iR.mjs";
|
|
8
8
|
import { n as ParallelMessageQueue } from "../../mq-Dm1Wmtm-.mjs";
|
|
9
9
|
import { configure, reset } from "@logtape/logtape";
|
|
10
10
|
import { delay } from "es-toolkit";
|
|
@@ -4,8 +4,8 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as MemoryKvStore } from "../../kv-DCHkaJ9-.mjs";
|
|
5
5
|
import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../tasks-IG3pHfvZ.mjs";
|
|
6
6
|
import "../../testing-t8xDeJZ5.mjs";
|
|
7
|
-
import { o as createFederation } from "../../middleware-
|
|
8
|
-
import { r as createFederationBuilder } from "../../builder-
|
|
7
|
+
import { o as createFederation } from "../../middleware-BbBsa5iR.mjs";
|
|
8
|
+
import { r as createFederationBuilder } from "../../builder-J1K0IJj6.mjs";
|
|
9
9
|
import { t as TaskCodec } from "../../codec-C6rTrpIp.mjs";
|
|
10
10
|
import { t as InProcessMessageQueue } from "../../mq-Dm1Wmtm-.mjs";
|
|
11
11
|
import { W3CTraceContextPropagator } from "@opentelemetry/core";
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
5
5
|
import "../std__assert-DvMDRPes.mjs";
|
|
6
6
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
7
|
-
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-
|
|
7
|
+
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-BRaCTxVe.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/federation/temporal.test.ts
|
|
10
10
|
test("hasMalformedKnownTemporalLiteral() detects expanded proof timestamps", async () => {
|
|
@@ -6,7 +6,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import { t as assertNotEquals } from "../assert_not_equals-CpPK2t89.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
|
-
import { o as createFederation, s as handleWebFinger } from "../middleware-
|
|
9
|
+
import { o as createFederation, s as handleWebFinger } from "../middleware-BbBsa5iR.mjs";
|
|
10
10
|
import { Image, Link, Person, Tombstone } from "@fedify/vocab";
|
|
11
11
|
import { parseIri } from "@fedify/vocab-runtime";
|
|
12
12
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
@@ -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-D1RPHoq3.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-BvWxS1sL.cjs");
|
|
7
|
+
const require_kv_cache = require("./kv-cache-Jym5nP3J.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");
|
|
@@ -2054,7 +2054,7 @@ function discoverCompoundProofDocuments(json, limits) {
|
|
|
2054
2054
|
statistics: Object.freeze({ ...inspected })
|
|
2055
2055
|
};
|
|
2056
2056
|
}
|
|
2057
|
-
async function verifyDiscoveredProofDocuments(discovered, options) {
|
|
2057
|
+
async function verifyDiscoveredProofDocuments(discovered, options, rejectedPolicies = /* @__PURE__ */ new Map()) {
|
|
2058
2058
|
const documents = await Promise.all(discovered.documents.map(async (document) => {
|
|
2059
2059
|
const metadata = {
|
|
2060
2060
|
path: document.path,
|
|
@@ -2079,10 +2079,20 @@ async function verifyDiscoveredProofDocuments(discovered, options) {
|
|
|
2079
2079
|
id: subjectId,
|
|
2080
2080
|
pointer: document.path
|
|
2081
2081
|
}
|
|
2082
|
-
} }, "objectIntegrity", (observation) =>
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2082
|
+
} }, "objectIntegrity", async (observation) => {
|
|
2083
|
+
const reason = rejectedPolicies.get(document.path);
|
|
2084
|
+
if (reason != null) {
|
|
2085
|
+
if (observation.attempt != null) observation.attempt.reason = {
|
|
2086
|
+
type: "proofPolicy",
|
|
2087
|
+
reason
|
|
2088
|
+
};
|
|
2089
|
+
return null;
|
|
2090
|
+
}
|
|
2091
|
+
return await require_http.verifyMapLocalProof(document.securedDocument, {
|
|
2092
|
+
...options,
|
|
2093
|
+
[require_http.verificationObservation]: inherited == null ? void 0 : observation
|
|
2094
|
+
});
|
|
2095
|
+
}, (key) => key != null);
|
|
2086
2096
|
return key == null ? Object.freeze({
|
|
2087
2097
|
...metadata,
|
|
2088
2098
|
verified: false,
|
|
@@ -2104,7 +2114,29 @@ async function verifyDiscoveredProofDocuments(discovered, options) {
|
|
|
2104
2114
|
async function verifyCompoundPortableObjectProofs(json, limits, options = {}) {
|
|
2105
2115
|
const discovered = discoverCompoundProofDocuments(json, limits);
|
|
2106
2116
|
if (discovered.status !== "ok") return discovered;
|
|
2107
|
-
const
|
|
2117
|
+
const collected = collectPortableObjects(discovered.snapshot);
|
|
2118
|
+
const objectByPath = new Map(collected.map((object) => [object.path, object]));
|
|
2119
|
+
const isKeyCandidate = (object) => object.keyOf != null && !Object.hasOwn(object.document, "proof");
|
|
2120
|
+
const prepareObject = async (object) => {
|
|
2121
|
+
if (object.depth > 0 && !Object.hasOwn(object.document, "@context")) return {
|
|
2122
|
+
prepared: false,
|
|
2123
|
+
reason: { type: "missingContext" }
|
|
2124
|
+
};
|
|
2125
|
+
try {
|
|
2126
|
+
const policy = await require_http.preparePortableObjectProofPolicy(object.document, options);
|
|
2127
|
+
return policy.prepared ? policy : {
|
|
2128
|
+
prepared: false,
|
|
2129
|
+
reason: policy.result.reason
|
|
2130
|
+
};
|
|
2131
|
+
} catch {
|
|
2132
|
+
return {
|
|
2133
|
+
prepared: false,
|
|
2134
|
+
reason: { type: "invalidPortableObject" }
|
|
2135
|
+
};
|
|
2136
|
+
}
|
|
2137
|
+
};
|
|
2138
|
+
const preparedByPath = new Map(await Promise.all(collected.filter((object) => !isKeyCandidate(object)).map(async (object) => [object.path, await prepareObject(object)])));
|
|
2139
|
+
const proofs = await verifyDiscoveredProofDocuments(discovered, options, new Map([...preparedByPath].flatMap(([path, prepared]) => prepared.prepared ? [] : [[path, prepared.reason]])));
|
|
2108
2140
|
const proofByPath = new Map(proofs.map((proof) => [proof.path, proof]));
|
|
2109
2141
|
const verifyPortableObject = async (object) => {
|
|
2110
2142
|
const metadata = {
|
|
@@ -2112,15 +2144,14 @@ async function verifyCompoundPortableObjectProofs(json, limits, options = {}) {
|
|
|
2112
2144
|
id: object.id,
|
|
2113
2145
|
depth: object.depth
|
|
2114
2146
|
};
|
|
2115
|
-
if (object.depth > 0 && !Object.hasOwn(object.document, "@context")) return Object.freeze({
|
|
2116
|
-
...metadata,
|
|
2117
|
-
verified: false,
|
|
2118
|
-
reason: { type: "missingContext" }
|
|
2119
|
-
});
|
|
2120
|
-
const proof = proofByPath.get(object.path);
|
|
2121
|
-
const key = proof?.verified === true ? proof.key : null;
|
|
2122
2147
|
try {
|
|
2123
|
-
const
|
|
2148
|
+
const prepared = preparedByPath.get(object.path) ?? await prepareObject(object);
|
|
2149
|
+
const proof = proofByPath.get(object.path);
|
|
2150
|
+
const key = proof?.verified === true ? proof.key : null;
|
|
2151
|
+
const policy = prepared.prepared ? require_http.verifyPreparedPortableObjectProofPolicy(prepared, key) : {
|
|
2152
|
+
verified: false,
|
|
2153
|
+
reason: prepared.reason
|
|
2154
|
+
};
|
|
2124
2155
|
return policy.verified ? Object.freeze({
|
|
2125
2156
|
...metadata,
|
|
2126
2157
|
id: policy.objectId,
|
|
@@ -2139,9 +2170,6 @@ async function verifyCompoundPortableObjectProofs(json, limits, options = {}) {
|
|
|
2139
2170
|
});
|
|
2140
2171
|
}
|
|
2141
2172
|
};
|
|
2142
|
-
const collected = collectPortableObjects(discovered.snapshot);
|
|
2143
|
-
const objectByPath = new Map(collected.map((object) => [object.path, object]));
|
|
2144
|
-
const isKeyCandidate = (object) => object.keyOf != null && !Object.hasOwn(object.document, "proof");
|
|
2145
2173
|
const results = /* @__PURE__ */ new Map();
|
|
2146
2174
|
for (const result of await Promise.all(collected.filter((object) => !isKeyCandidate(object)).map(verifyPortableObject))) results.set(result.path, result);
|
|
2147
2175
|
let projections = 0;
|
|
@@ -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-Ci6tSK9-.mjs";
|
|
7
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-Dwgav7s_.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-DJ--ZUpr.mjs";
|
|
11
|
+
import { n as resolvePortableActorKey, r as verifyPortableGatewayKeyDocument } from "./portable-key-Cwti99nP.mjs";
|
|
12
12
|
import { getLogger } from "@logtape/logtape";
|
|
13
13
|
import { CryptographicKey } from "@fedify/vocab";
|
|
14
14
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -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.5.0-dev.
|
|
18
|
+
var version = "2.5.0-dev.2378+fea9c751";
|
|
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),
|
|
@@ -4420,34 +4518,68 @@ async function preparePortableObjectProof(jsonLd, options) {
|
|
|
4420
4518
|
};
|
|
4421
4519
|
}
|
|
4422
4520
|
/**
|
|
4423
|
-
*
|
|
4521
|
+
* Checks portable-object policy without resolving keys or verifying signatures.
|
|
4424
4522
|
*
|
|
4425
4523
|
* @internal
|
|
4426
4524
|
*/
|
|
4427
|
-
async function
|
|
4525
|
+
async function preparePortableObjectProofPolicy(jsonLd, options = {}) {
|
|
4428
4526
|
const policyOptions = {
|
|
4429
4527
|
...options,
|
|
4430
4528
|
contextLoader: preloadedOnlyDocumentLoader
|
|
4431
4529
|
};
|
|
4432
4530
|
const prepared = await preparePortableObjectProof(jsonLd, policyOptions);
|
|
4433
|
-
if (!prepared.prepared) return
|
|
4531
|
+
if (!prepared.prepared) return {
|
|
4532
|
+
prepared: false,
|
|
4533
|
+
result: prepared.result
|
|
4534
|
+
};
|
|
4434
4535
|
const policyProof = prepared.proofs[0];
|
|
4435
4536
|
const literalProof = isJsonLdNode(jsonLd) && isJsonLdNode(jsonLd.proof) ? (await parseRawProofCandidates(jsonLd, [jsonLd.proof], policyOptions, prepared.proofContextLoader))[0]?.proof : null;
|
|
4436
4537
|
const verificationMethod = policyProof?.verificationMethodId;
|
|
4437
|
-
if (prepared.proofs.length !== 1 ||
|
|
4538
|
+
if (prepared.proofs.length !== 1 || policyProof == null || literalProof == null || !sameProof(policyProof, literalProof) || verificationMethod == null) return {
|
|
4539
|
+
prepared: false,
|
|
4540
|
+
result: {
|
|
4541
|
+
verified: false,
|
|
4542
|
+
reason: {
|
|
4543
|
+
type: "invalidProof",
|
|
4544
|
+
proofIndex: prepared.proofs.length > 1 ? 1 : 0
|
|
4545
|
+
}
|
|
4546
|
+
}
|
|
4547
|
+
};
|
|
4548
|
+
return {
|
|
4549
|
+
prepared: true,
|
|
4550
|
+
verificationMethod,
|
|
4551
|
+
objectId: formatIri(prepared.objectId)
|
|
4552
|
+
};
|
|
4553
|
+
}
|
|
4554
|
+
/**
|
|
4555
|
+
* Binds prepared portable-object policy to the map-local verified key.
|
|
4556
|
+
*
|
|
4557
|
+
* @internal
|
|
4558
|
+
*/
|
|
4559
|
+
function verifyPreparedPortableObjectProofPolicy(prepared, key) {
|
|
4560
|
+
if (key == null || key.id?.href !== prepared.verificationMethod.href) return {
|
|
4438
4561
|
verified: false,
|
|
4439
4562
|
reason: {
|
|
4440
4563
|
type: "invalidProof",
|
|
4441
|
-
proofIndex:
|
|
4564
|
+
proofIndex: 0
|
|
4442
4565
|
}
|
|
4443
4566
|
};
|
|
4444
4567
|
return {
|
|
4445
4568
|
verified: true,
|
|
4446
4569
|
keys: [key],
|
|
4447
|
-
objectId:
|
|
4570
|
+
objectId: prepared.objectId
|
|
4448
4571
|
};
|
|
4449
4572
|
}
|
|
4450
4573
|
/**
|
|
4574
|
+
* Applies portable-object proof policy to one map-local cryptographic result.
|
|
4575
|
+
*
|
|
4576
|
+
* @internal
|
|
4577
|
+
*/
|
|
4578
|
+
async function verifyPortableObjectProofPolicy(jsonLd, key, options = {}) {
|
|
4579
|
+
const prepared = await preparePortableObjectProofPolicy(jsonLd, options);
|
|
4580
|
+
return prepared.prepared ? verifyPreparedPortableObjectProofPolicy(prepared, key) : prepared.result;
|
|
4581
|
+
}
|
|
4582
|
+
/**
|
|
4451
4583
|
* Verifies the FEP-ef61 Object Integrity Proof policy for a portable object.
|
|
4452
4584
|
*
|
|
4453
4585
|
* This applies the FEP-2277 core-type classification to the top-level JSON-LD
|
|
@@ -6524,4 +6656,4 @@ function timingSafeEqual(a, b) {
|
|
|
6524
6656
|
return result === 0;
|
|
6525
6657
|
}
|
|
6526
6658
|
//#endregion
|
|
6527
|
-
export {
|
|
6659
|
+
export { getFederationMetrics as $, detachSignature as A, isPortableId as At, wrapContextLoaderForJsonLd as B, verifyProof as C, getAuthenticationOrigin as Ct, attachSignature as D, getRawCanonicalPortableId as Dt, assertSafeJsonLd as E, getPortableDid as Et, isInvalidUrlTypeError as F, name as Ft, generateCryptoKeyPair as G, fetchActorDocument as H, signJsonLd as I, version as It, verifyKeyOwnership as J, importJwk as K, verifyCompactJsonLd as L, hasSignature as M, isPortableUri as Mt, hasSignatureLike as N, isSameObjectId as Nt, compactJsonLd as O, hasPortableActor as Ot, isClearlyMalformedContextReference as P, isSamePublicKey as Pt, getDurationMs as Q, verifyJsonLd as R, verifyPreparedPortableObjectProofPolicy as S, verificationObservation as St, InvalidContextReferenceError as T, getGatewayKeyBase as Tt, fetchKey as U, exportJwk as V, fetchKeyDetailed as W, getVerifiedKeyOwnerEvidence as X, MAX_PORTABLE_KEY_TTL as Y, parseKeyOwnerEvidence as Z, verifyMapLocalProof as _, fulfillAcceptSignature as _t, signRequest as a, recordCollectionPageItems as at, verifyPortableObjectProofPolicy as b, observeAttempt as bt, verifyRequestDetailed as c, recordDocumentCache as ct, InvalidPortableObjectIdError as d, recordOutboxActivity as dt, getRemoteHost as et, classifyFep2277CoreType as f, recordOutboxEnqueue as ft, signObject as g, formatAcceptSignature as gt, preparePortableObjectProofPolicy as h, preloadedOnlyDocumentLoader as ht, selectRequestSignature as i, recordCollectionDispatchDuration as it, getNormalizationContextLoader as j, isPortableKeyId as jt, createSignature as k, isCompatibleKeyId as kt, fetchPortableGatewayKey as l, recordFanoutRecipients as lt, hasProofLike as m, registerQueueDepthGauge as mt, listRequestSignatures as n, isAbortError$1 as nt, validateMaxSignatures as o, recordCollectionRequest as ot, createProof as p, recordWebFingerHandle as pt, validateCryptoKey as q, parseRfc9421SignatureInput as r, recordCircuitBreakerStateChange as rt, verifyRequest as s, recordCollectionTotalItems as st, doubleKnock as t, instrumentDocumentLoader as tt, resolvePortableActorKey as u, recordInboxActivity as ut, verifyObject as v, parseAcceptSignature as vt, normalizeOutgoingActivityJsonLd as w, getCanonicalPortableId as wt, verifyPortableObjectProofWithRoot as x, snapshotKey as xt, verifyPortableObjectProof as y, validateAcceptSignature as yt, verifySignature as z };
|