@fedify/fedify 2.4.0-dev.2155 → 2.4.0-dev.2159
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-CxHALSwA.mjs → builder-D89oOfHC.mjs} +2 -2
- package/dist/{client-DpnpgjyX.mjs → client-CEnNz8O7.mjs} +7 -3
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-nhrXTRQO.mjs → compound-proof-B02Os8h2.mjs} +2 -2
- package/dist/{context-OrnjnuMq.mjs → context-B2rlkkyJ.mjs} +1 -1
- package/dist/{context-BMggDR-l.d.cts → context-DpsaHkk1.d.cts} +119 -2
- package/dist/{context-exYu7gDU.d.ts → context-JDNkUtnu.d.ts} +119 -2
- package/dist/{deno-YLLbRq06.mjs → deno-CE_s0yQb.mjs} +1 -1
- package/dist/{dist-BQvArojP.mjs → dist-DJQM4u7i.mjs} +2 -1
- package/dist/docloader-C5p26tpa.mjs +79 -0
- 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 +4 -4
- package/dist/federation/handler.test.mjs +6 -6
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +187 -10
- 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/mq.test.mjs +98 -69
- package/dist/federation/outgoing-proof.test.mjs +5 -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-gateway-keys.test.mjs +4 -4
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable-parse-uri.test.d.mts +2 -0
- package/dist/federation/portable-parse-uri.test.mjs +348 -0
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/send.test.mjs +84 -3
- package/dist/federation/tasks/enqueue.test.mjs +3 -3
- package/dist/federation/tasks/tasks.test.mjs +4 -4
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +2 -2
- package/dist/{federation-D9TufmIO.cjs → federation-dBOqmJcA.cjs} +74 -10
- package/dist/{http-CXnNbRe_.mjs → http-DV_yW4dv.mjs} +9 -5
- package/dist/{http-Dk4O3WM0.js → http-nTZuTacw.js} +7 -3
- package/dist/{http-eqYXHRkz.cjs → http-wdsia0-O.cjs} +7 -3
- package/dist/{key-BZ-Z4uez.mjs → key-C6jnekFI.mjs} +2 -2
- package/dist/{kv-cache-DzClEalR.cjs → kv-cache-BHNtQi9e.cjs} +34 -8
- package/dist/{kv-cache-DZr8HTel.mjs → kv-cache-Bxm0a0Ww.mjs} +1 -1
- package/dist/{kv-cache-3uKc0G76.js → kv-cache-DhIl9YlV.js} +35 -9
- package/dist/{ld-Djxsq6JR.mjs → ld-ya2C1Xip.mjs} +4 -4
- package/dist/{metrics-CBHhbHgG.mjs → metrics-ByOQOHHS.mjs} +1 -1
- package/dist/{middleware-DDa8pCUa.mjs → middleware-Bdwd_Gg8.mjs} +70 -20
- package/dist/{middleware-BahNnLfD.mjs → middleware-DoVWq8mE.mjs} +1 -1
- package/dist/{middleware-BDUR99k3.js → middleware-WiaN4RS3.js} +74 -10
- package/dist/{mod-Decmur1U.d.cts → mod-DSKkTwH2.d.cts} +1 -1
- package/dist/{mod-CZetqT5h.d.ts → mod-DaiBrWDW.d.ts} +2 -0
- package/dist/{mod-D4g9ffEn.d.cts → mod-Mt4aO3DX.d.cts} +2 -0
- package/dist/{mod-CnGtADvO.d.ts → mod-_4K05HZF.d.ts} +1 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +49 -1
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/{owner-OdWSE8am.mjs → owner-C6Nv5yyw.mjs} +3 -3
- package/dist/{portable-collection-BCy06GiS.js → portable-collection-B-mU1F1-.js} +1 -1
- package/dist/{portable-collection-wBWbuHOH.cjs → portable-collection-C65SwL2l.cjs} +1 -1
- package/dist/{portable-collection-DAV7Ho3m.mjs → portable-collection-uWj3hfzv.mjs} +2 -2
- package/dist/{portable-key-BL6K88p2.mjs → portable-key-BXsVLSMa.mjs} +1 -1
- package/dist/{proof-vZ04IAjq.mjs → proof-BdO3BbLh.mjs} +4 -4
- package/dist/{send-ylV8KCLx.mjs → send-BwANxryy.mjs} +18 -4
- 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 +42 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +5 -2
- 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 +2 -2
- package/dist/sig/portable-key.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/{tasks-dbCShlCb.mjs → tasks-IG3pHfvZ.mjs} +1 -1
- package/dist/{temporal-BTD4f_mZ.mjs → temporal-CbPfRGZq.mjs} +1 -1
- package/dist/testing/context.test.mjs +1 -1
- package/dist/testing/kv.test.mjs +3 -3
- package/dist/testing/mod.d.mts +118 -1
- package/dist/testing/mod.mjs +4 -4
- package/dist/{testing-CKaJhcA0.mjs → testing-C1itIjqW.mjs} +3 -3
- package/dist/{types-C_cNlNVK.js → types-_S2_MeLF.js} +7 -3
- package/dist/{types-Be2zbyeG.cjs → types-poIao40f.cjs} +7 -3
- package/dist/utils/docloader.test.mjs +297 -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/dist/vocab/cjs.test.mjs +1 -1
- package/package.json +7 -7
- package/dist/docloader-vc-pSu9-.mjs +0 -53
|
@@ -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-
|
|
5
|
-
const require_types = require("./types-
|
|
6
|
-
const require_portable_collection = require("./portable-collection-
|
|
7
|
-
const require_kv_cache = require("./kv-cache-
|
|
4
|
+
const require_http = require("./http-wdsia0-O.cjs");
|
|
5
|
+
const require_types = require("./types-poIao40f.cjs");
|
|
6
|
+
const require_portable_collection = require("./portable-collection-C65SwL2l.cjs");
|
|
7
|
+
const require_kv_cache = require("./kv-cache-BHNtQi9e.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");
|
|
@@ -2823,6 +2823,43 @@ function parsePortableGatewayRequest(url) {
|
|
|
2823
2823
|
};
|
|
2824
2824
|
}
|
|
2825
2825
|
/**
|
|
2826
|
+
* Recognizes an FEP-ef61 portable ID, i.e., an `ap:` or `ap+ef61:` URI, or
|
|
2827
|
+
* a compatible identifier on any gateway, and splits it into its DID and
|
|
2828
|
+
* the object path to route.
|
|
2829
|
+
*
|
|
2830
|
+
* It accepts the same IDs as the gateway endpoint does: the query, e.g.,
|
|
2831
|
+
* location hints, and the fragment are ignored, and a malformed DID, or
|
|
2832
|
+
* a `did:key` DID that is not encoded in base58-btc, is refused.
|
|
2833
|
+
*
|
|
2834
|
+
* @param uri The ID to recognize.
|
|
2835
|
+
* @returns The DID normalized as an FEP-fe34 origin, and the object path,
|
|
2836
|
+
* or `null` if the ID is not a portable ID or is malformed.
|
|
2837
|
+
*/
|
|
2838
|
+
function parsePortableId(uri) {
|
|
2839
|
+
if (uri.username !== "" || uri.password !== "") return null;
|
|
2840
|
+
if (uri.protocol !== "ap:" && uri.protocol !== "ap+ef61:") {
|
|
2841
|
+
const request = parsePortableGatewayRequest(uri);
|
|
2842
|
+
if (request?.type !== "object") return null;
|
|
2843
|
+
return {
|
|
2844
|
+
authority: request.portableRequest.authority,
|
|
2845
|
+
path: request.path
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
try {
|
|
2849
|
+
const id = (0, _fedify_vocab_runtime.parseIri)(uri);
|
|
2850
|
+
(0, _fedify_vocab_runtime.canonicalizePortableUri)((0, _fedify_vocab_runtime.formatIri)(id));
|
|
2851
|
+
const authority = (0, _fedify_vocab_runtime.getFe34Origin)(id);
|
|
2852
|
+
assertBase58BtcDidKey(authority);
|
|
2853
|
+
return {
|
|
2854
|
+
authority,
|
|
2855
|
+
path: id.pathname
|
|
2856
|
+
};
|
|
2857
|
+
} catch (error) {
|
|
2858
|
+
if (error instanceof TypeError) return null;
|
|
2859
|
+
throw error;
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
/**
|
|
2826
2863
|
* Builds a portable ID from a DID authority and an object path.
|
|
2827
2864
|
* @param authority The bare DID, e.g., `did:key:z6Mk...`.
|
|
2828
2865
|
* @param path The object path, e.g., `/notes/123`.
|
|
@@ -3016,6 +3053,15 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
|
|
|
3016
3053
|
if (!allowPrivateAddress) try {
|
|
3017
3054
|
await (0, _fedify_vocab_runtime.validatePublicUrl)(url);
|
|
3018
3055
|
} catch (error) {
|
|
3056
|
+
if (error instanceof _fedify_vocab_runtime.UrlError && error.reason === "dns") {
|
|
3057
|
+
logger.error("DNS resolution failed for URL: {url}", {
|
|
3058
|
+
url,
|
|
3059
|
+
error
|
|
3060
|
+
});
|
|
3061
|
+
const failure = new _fedify_vocab_runtime.FetchError(url, error.message);
|
|
3062
|
+
failure.cause = error;
|
|
3063
|
+
throw failure;
|
|
3064
|
+
}
|
|
3019
3065
|
if (error instanceof _fedify_vocab_runtime.UrlError) logger.error("Disallowed private URL: {url}", {
|
|
3020
3066
|
url,
|
|
3021
3067
|
error
|
|
@@ -3023,7 +3069,12 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
|
|
|
3023
3069
|
throw error;
|
|
3024
3070
|
}
|
|
3025
3071
|
}
|
|
3026
|
-
|
|
3072
|
+
try {
|
|
3073
|
+
await validateUrl(inbox.href);
|
|
3074
|
+
} catch (error) {
|
|
3075
|
+
if (error instanceof _fedify_vocab_runtime.FetchError) federationMetrics.recordDelivery(inbox, require_http.getDurationMs(started), false, activityType);
|
|
3076
|
+
throw error;
|
|
3077
|
+
}
|
|
3027
3078
|
headers = new Headers(headers);
|
|
3028
3079
|
headers.set("Content-Type", "application/activity+json");
|
|
3029
3080
|
const request = new Request(inbox, {
|
|
@@ -9470,12 +9521,25 @@ var ContextImpl = class ContextImpl {
|
|
|
9470
9521
|
if (path === null) throw new _fedify_uri_template.RouterError(`No collection dispatcher registered for "${String(name)}".`);
|
|
9471
9522
|
return buildPortableUri(requirePortableAuthority(authority), path);
|
|
9472
9523
|
}
|
|
9473
|
-
parseUri(uri) {
|
|
9524
|
+
parseUri(uri, options = {}) {
|
|
9474
9525
|
if (uri == null) return null;
|
|
9475
|
-
if (uri.origin
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9526
|
+
if (uri.origin === this.origin || uri.origin === this.canonicalOrigin) {
|
|
9527
|
+
const route = this.federation.router.route(uri.pathname);
|
|
9528
|
+
if (route != null) return this.#parseRoute(route);
|
|
9529
|
+
}
|
|
9530
|
+
if (!options.portable) return null;
|
|
9531
|
+
const portable = parsePortableId(uri);
|
|
9532
|
+
if (portable == null) return null;
|
|
9533
|
+
const route = this.federation.router.route(portable.path);
|
|
9534
|
+
if (route == null || route.name === "sharedInbox") return null;
|
|
9535
|
+
const result = this.#parseRoute(route);
|
|
9536
|
+
return result == null ? null : {
|
|
9537
|
+
...result,
|
|
9538
|
+
authority: portable.authority
|
|
9539
|
+
};
|
|
9540
|
+
}
|
|
9541
|
+
#parseRoute(route) {
|
|
9542
|
+
if (route.name === "sharedInbox") return {
|
|
9479
9543
|
type: "inbox",
|
|
9480
9544
|
identifier: void 0
|
|
9481
9545
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Temporal } from "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-
|
|
4
|
+
import { n as version, t as name } from "./deno-CE_s0yQb.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-ByOQOHHS.mjs";
|
|
6
6
|
import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPVqki78.mjs";
|
|
7
7
|
import { f as parseKeyIdString } from "./portable-key-id-Bg259c4Z.mjs";
|
|
8
|
-
import { a as fetchKeyDetailed, c as validateCryptoKey, t as bypassKeyCacheReads } from "./key-
|
|
9
|
-
import { n as resolvePortableActorKey, r as verifyPortableGatewayKeyDocument } from "./portable-key-
|
|
8
|
+
import { a as fetchKeyDetailed, c as validateCryptoKey, t as bypassKeyCacheReads } from "./key-C6jnekFI.mjs";
|
|
9
|
+
import { n as resolvePortableActorKey, r as verifyPortableGatewayKeyDocument } from "./portable-key-BXsVLSMa.mjs";
|
|
10
10
|
import { getLogger } from "@logtape/logtape";
|
|
11
11
|
import { CryptographicKey } from "@fedify/vocab";
|
|
12
12
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -804,6 +804,8 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
|
|
|
804
804
|
failure = result;
|
|
805
805
|
failureAlgorithm = algorithm;
|
|
806
806
|
};
|
|
807
|
+
let body = null;
|
|
808
|
+
let digestValid = null;
|
|
807
809
|
for (const sigName of signatureNames) {
|
|
808
810
|
if (!signatures[sigName]) {
|
|
809
811
|
setFailure(invalidSignatureResult(parseKeyId(signatureInputs[sigName]?.keyId)));
|
|
@@ -855,7 +857,9 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
|
|
|
855
857
|
setFailure(invalidSignatureResult(keyId));
|
|
856
858
|
continue;
|
|
857
859
|
}
|
|
858
|
-
|
|
860
|
+
body ??= await request.arrayBuffer();
|
|
861
|
+
digestValid ??= await verifyRfc9421ContentDigest(contentDigestHeader, body);
|
|
862
|
+
if (!digestValid) {
|
|
859
863
|
logger.debug("Failed to verify; Content-Digest verification failed.", { contentDigest: contentDigestHeader });
|
|
860
864
|
setFailure(invalidSignatureResult(keyId));
|
|
861
865
|
continue;
|
|
@@ -14,7 +14,7 @@ import serialize from "json-canon";
|
|
|
14
14
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
15
15
|
//#region deno.json
|
|
16
16
|
var name = "@fedify/fedify";
|
|
17
|
-
var version = "2.4.0-dev.
|
|
17
|
+
var version = "2.4.0-dev.2159+bb072eda";
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/sig/portable-key-id.ts
|
|
20
20
|
const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
|
|
@@ -2238,7 +2238,7 @@ function normalizeContextReference(reference, baseUrl) {
|
|
|
2238
2238
|
/** @internal */
|
|
2239
2239
|
function isInvalidUrlTypeError(error) {
|
|
2240
2240
|
const code = error.code;
|
|
2241
|
-
return error instanceof TypeError && (code === "ERR_INVALID_URL" || /^Invalid URL(?::|$)/.test(error.message) || / cannot be parsed as a URL\.?$/.test(error.message));
|
|
2241
|
+
return error instanceof TypeError && (code === "ERR_INVALID_URL" || error.message === "Invalid URL string." || /^Invalid URL(?::|$)/.test(error.message) || / cannot be parsed as a URL\.?$/.test(error.message));
|
|
2242
2242
|
}
|
|
2243
2243
|
async function applyGraphAliasContext(state, context, documentLoader, remoteContextCache, baseUrl = null, processingContexts = /* @__PURE__ */ new Set()) {
|
|
2244
2244
|
if (context === null) return createGraphAliasContextState();
|
|
@@ -5340,6 +5340,8 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
|
|
|
5340
5340
|
failure = result;
|
|
5341
5341
|
failureAlgorithm = algorithm;
|
|
5342
5342
|
};
|
|
5343
|
+
let body = null;
|
|
5344
|
+
let digestValid = null;
|
|
5343
5345
|
for (const sigName of signatureNames) {
|
|
5344
5346
|
if (!signatures[sigName]) {
|
|
5345
5347
|
setFailure(invalidSignatureResult(parseKeyId(signatureInputs[sigName]?.keyId)));
|
|
@@ -5391,7 +5393,9 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
|
|
|
5391
5393
|
setFailure(invalidSignatureResult(keyId));
|
|
5392
5394
|
continue;
|
|
5393
5395
|
}
|
|
5394
|
-
|
|
5396
|
+
body ??= await request.arrayBuffer();
|
|
5397
|
+
digestValid ??= await verifyRfc9421ContentDigest(contentDigestHeader, body);
|
|
5398
|
+
if (!digestValid) {
|
|
5395
5399
|
logger.debug("Failed to verify; Content-Digest verification failed.", { contentDigest: contentDigestHeader });
|
|
5396
5400
|
setFailure(invalidSignatureResult(keyId));
|
|
5397
5401
|
continue;
|
|
@@ -16,7 +16,7 @@ json_canon = require_rolldown_runtime.__toESM(json_canon, 1);
|
|
|
16
16
|
let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
17
17
|
//#region deno.json
|
|
18
18
|
var name = "@fedify/fedify";
|
|
19
|
-
var version = "2.4.0-dev.
|
|
19
|
+
var version = "2.4.0-dev.2159+bb072eda";
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/sig/portable-key-id.ts
|
|
22
22
|
const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
|
|
@@ -5804,7 +5804,7 @@ function normalizeContextReference(reference, baseUrl) {
|
|
|
5804
5804
|
/** @internal */
|
|
5805
5805
|
function isInvalidUrlTypeError(error) {
|
|
5806
5806
|
const code = error.code;
|
|
5807
|
-
return error instanceof TypeError && (code === "ERR_INVALID_URL" || /^Invalid URL(?::|$)/.test(error.message) || / cannot be parsed as a URL\.?$/.test(error.message));
|
|
5807
|
+
return error instanceof TypeError && (code === "ERR_INVALID_URL" || error.message === "Invalid URL string." || /^Invalid URL(?::|$)/.test(error.message) || / cannot be parsed as a URL\.?$/.test(error.message));
|
|
5808
5808
|
}
|
|
5809
5809
|
async function applyGraphAliasContext(state, context, documentLoader, remoteContextCache, baseUrl = null, processingContexts = /* @__PURE__ */ new Set()) {
|
|
5810
5810
|
if (context === null) return createGraphAliasContextState();
|
|
@@ -8908,6 +8908,8 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
|
|
|
8908
8908
|
failure = result;
|
|
8909
8909
|
failureAlgorithm = algorithm;
|
|
8910
8910
|
};
|
|
8911
|
+
let body = null;
|
|
8912
|
+
let digestValid = null;
|
|
8911
8913
|
for (const sigName of signatureNames) {
|
|
8912
8914
|
if (!signatures[sigName]) {
|
|
8913
8915
|
setFailure(invalidSignatureResult(parseKeyId(signatureInputs[sigName]?.keyId)));
|
|
@@ -8959,7 +8961,9 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
|
|
|
8959
8961
|
setFailure(invalidSignatureResult(keyId));
|
|
8960
8962
|
continue;
|
|
8961
8963
|
}
|
|
8962
|
-
|
|
8964
|
+
body ??= await request.arrayBuffer();
|
|
8965
|
+
digestValid ??= await verifyRfc9421ContentDigest(contentDigestHeader, body);
|
|
8966
|
+
if (!digestValid) {
|
|
8963
8967
|
logger.debug("Failed to verify; Content-Digest verification failed.", { contentDigest: contentDigestHeader });
|
|
8964
8968
|
setFailure(invalidSignatureResult(keyId));
|
|
8965
8969
|
continue;
|
|
@@ -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-CE_s0yQb.mjs";
|
|
5
|
+
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-ByOQOHHS.mjs";
|
|
6
6
|
import { c as isPortableId, f as parseKeyIdString, o as isCompatibleKeyId, s as isPortableActorDocument, u as isPortableUri } from "./portable-key-id-Bg259c4Z.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
|
-
const require_http = require("./http-
|
|
2
|
+
const require_http = require("./http-wdsia0-O.cjs");
|
|
3
3
|
let _logtape_logtape = require("@logtape/logtape");
|
|
4
4
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
5
5
|
let es_toolkit = require("es-toolkit");
|
|
@@ -9,10 +9,13 @@ const logger$1 = (0, _logtape_logtape.getLogger)([
|
|
|
9
9
|
"utils",
|
|
10
10
|
"docloader"
|
|
11
11
|
]);
|
|
12
|
+
const DEFAULT_MAX_REDIRECTION = 20;
|
|
12
13
|
/**
|
|
13
14
|
* Gets an authenticated {@link DocumentLoader} for the given identity.
|
|
14
15
|
* Note that an authenticated document loader intentionally does not cache
|
|
15
16
|
* the fetched documents.
|
|
17
|
+
* At most 20 HTTP redirects and alternate document links are followed in total
|
|
18
|
+
* per call. Revisiting a URL within that chain throws a {@link FetchError}.
|
|
16
19
|
* @param identity The identity to get the document loader for.
|
|
17
20
|
* The actor's key pair.
|
|
18
21
|
* @param options The options for the document loader.
|
|
@@ -22,29 +25,52 @@ const logger$1 = (0, _logtape_logtape.getLogger)([
|
|
|
22
25
|
*/
|
|
23
26
|
function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedirection, userAgent, specDeterminer, tracerProvider } = {}) {
|
|
24
27
|
require_http.validateCryptoKey(identity.privateKey);
|
|
25
|
-
async function load(url, options) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
async function load(url, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
|
|
29
|
+
options?.signal?.throwIfAborted();
|
|
30
|
+
let currentUrl = new URL(url).href;
|
|
31
|
+
await validateUrl(currentUrl, options);
|
|
32
|
+
visited.add(currentUrl);
|
|
33
|
+
const originalRequest = (0, _fedify_vocab_runtime.createActivityPubRequest)(currentUrl, { userAgent });
|
|
34
|
+
function follow(nextUrl) {
|
|
35
|
+
options?.signal?.throwIfAborted();
|
|
36
|
+
if (redirected >= DEFAULT_MAX_REDIRECTION) throw new _fedify_vocab_runtime.FetchError(currentUrl, `Too many redirections (${redirected + 1})`);
|
|
37
|
+
if (visited.has(nextUrl)) throw new _fedify_vocab_runtime.FetchError(currentUrl, `Redirect loop detected: ${nextUrl}`);
|
|
38
|
+
redirected++;
|
|
39
|
+
}
|
|
40
|
+
const response = await require_http.doubleKnock(originalRequest, identity, {
|
|
28
41
|
maxRedirection,
|
|
29
42
|
specDeterminer,
|
|
30
43
|
log: (0, es_toolkit.curry)(_fedify_vocab_runtime.logRequest)(logger$1),
|
|
31
44
|
tracerProvider,
|
|
32
45
|
signal: options?.signal,
|
|
33
|
-
validateRedirect: (
|
|
34
|
-
|
|
46
|
+
validateRedirect: async (nextUrl) => {
|
|
47
|
+
follow(nextUrl);
|
|
48
|
+
await validateUrl(nextUrl, options);
|
|
49
|
+
visited.add(nextUrl);
|
|
50
|
+
currentUrl = nextUrl;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return (0, _fedify_vocab_runtime.getRemoteDocument)(currentUrl, response, (alternateUrl) => {
|
|
54
|
+
follow(alternateUrl);
|
|
55
|
+
return load(alternateUrl, options, redirected, visited);
|
|
56
|
+
}, options);
|
|
35
57
|
}
|
|
36
58
|
async function validateUrl(url, options) {
|
|
37
59
|
if (!allowPrivateAddress) try {
|
|
38
60
|
await (0, _fedify_vocab_runtime.validatePublicUrl)(url);
|
|
39
61
|
} catch (error) {
|
|
40
|
-
if (error instanceof _fedify_vocab_runtime.UrlError)
|
|
62
|
+
if (error instanceof _fedify_vocab_runtime.UrlError) if (error.reason === "dns") logger$1.debug("DNS lookup failed for {url}", {
|
|
63
|
+
url,
|
|
64
|
+
error
|
|
65
|
+
});
|
|
66
|
+
else logger$1[options?.suppressError ? "warn" : "error"]("Disallowed private URL: {url}", {
|
|
41
67
|
url,
|
|
42
68
|
error
|
|
43
69
|
});
|
|
44
70
|
throw error;
|
|
45
71
|
}
|
|
46
72
|
}
|
|
47
|
-
return load;
|
|
73
|
+
return (url, options) => load(url, options);
|
|
48
74
|
}
|
|
49
75
|
//#endregion
|
|
50
76
|
//#region src/utils/kv-cache.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { p as recordDocumentCache } from "./metrics-
|
|
4
|
+
import { p as recordDocumentCache } from "./metrics-ByOQOHHS.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,8 +1,8 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { W as validateCryptoKey, nt as recordDocumentCache, t as doubleKnock } from "./http-
|
|
3
|
+
import { W as validateCryptoKey, nt as recordDocumentCache, t as doubleKnock } from "./http-nTZuTacw.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
|
-
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
5
|
+
import { FetchError, UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
6
6
|
import { curry } from "es-toolkit";
|
|
7
7
|
//#region src/utils/docloader.ts
|
|
8
8
|
const logger$1 = getLogger([
|
|
@@ -10,10 +10,13 @@ const logger$1 = getLogger([
|
|
|
10
10
|
"utils",
|
|
11
11
|
"docloader"
|
|
12
12
|
]);
|
|
13
|
+
const DEFAULT_MAX_REDIRECTION = 20;
|
|
13
14
|
/**
|
|
14
15
|
* Gets an authenticated {@link DocumentLoader} for the given identity.
|
|
15
16
|
* Note that an authenticated document loader intentionally does not cache
|
|
16
17
|
* the fetched documents.
|
|
18
|
+
* At most 20 HTTP redirects and alternate document links are followed in total
|
|
19
|
+
* per call. Revisiting a URL within that chain throws a {@link FetchError}.
|
|
17
20
|
* @param identity The identity to get the document loader for.
|
|
18
21
|
* The actor's key pair.
|
|
19
22
|
* @param options The options for the document loader.
|
|
@@ -23,29 +26,52 @@ const logger$1 = getLogger([
|
|
|
23
26
|
*/
|
|
24
27
|
function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedirection, userAgent, specDeterminer, tracerProvider } = {}) {
|
|
25
28
|
validateCryptoKey(identity.privateKey);
|
|
26
|
-
async function load(url, options) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
async function load(url, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
|
|
30
|
+
options?.signal?.throwIfAborted();
|
|
31
|
+
let currentUrl = new URL(url).href;
|
|
32
|
+
await validateUrl(currentUrl, options);
|
|
33
|
+
visited.add(currentUrl);
|
|
34
|
+
const originalRequest = createActivityPubRequest(currentUrl, { userAgent });
|
|
35
|
+
function follow(nextUrl) {
|
|
36
|
+
options?.signal?.throwIfAborted();
|
|
37
|
+
if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(currentUrl, `Too many redirections (${redirected + 1})`);
|
|
38
|
+
if (visited.has(nextUrl)) throw new FetchError(currentUrl, `Redirect loop detected: ${nextUrl}`);
|
|
39
|
+
redirected++;
|
|
40
|
+
}
|
|
41
|
+
const response = await doubleKnock(originalRequest, identity, {
|
|
29
42
|
maxRedirection,
|
|
30
43
|
specDeterminer,
|
|
31
44
|
log: curry(logRequest)(logger$1),
|
|
32
45
|
tracerProvider,
|
|
33
46
|
signal: options?.signal,
|
|
34
|
-
validateRedirect: (
|
|
35
|
-
|
|
47
|
+
validateRedirect: async (nextUrl) => {
|
|
48
|
+
follow(nextUrl);
|
|
49
|
+
await validateUrl(nextUrl, options);
|
|
50
|
+
visited.add(nextUrl);
|
|
51
|
+
currentUrl = nextUrl;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return getRemoteDocument(currentUrl, response, (alternateUrl) => {
|
|
55
|
+
follow(alternateUrl);
|
|
56
|
+
return load(alternateUrl, options, redirected, visited);
|
|
57
|
+
}, options);
|
|
36
58
|
}
|
|
37
59
|
async function validateUrl(url, options) {
|
|
38
60
|
if (!allowPrivateAddress) try {
|
|
39
61
|
await validatePublicUrl(url);
|
|
40
62
|
} catch (error) {
|
|
41
|
-
if (error instanceof UrlError)
|
|
63
|
+
if (error instanceof UrlError) if (error.reason === "dns") logger$1.debug("DNS lookup failed for {url}", {
|
|
64
|
+
url,
|
|
65
|
+
error
|
|
66
|
+
});
|
|
67
|
+
else logger$1[options?.suppressError ? "warn" : "error"]("Disallowed private URL: {url}", {
|
|
42
68
|
url,
|
|
43
69
|
error
|
|
44
70
|
});
|
|
45
71
|
throw error;
|
|
46
72
|
}
|
|
47
73
|
}
|
|
48
|
-
return load;
|
|
74
|
+
return (url, options) => load(url, options);
|
|
49
75
|
}
|
|
50
76
|
//#endregion
|
|
51
77
|
//#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 { c as validateCryptoKey, i as fetchKey, t as bypassKeyCacheReads } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-CE_s0yQb.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-ByOQOHHS.mjs";
|
|
6
|
+
import { c as validateCryptoKey, i as fetchKey, t as bypassKeyCacheReads } from "./key-C6jnekFI.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";
|
|
@@ -206,7 +206,7 @@ function normalizeContextReference(reference, baseUrl) {
|
|
|
206
206
|
/** @internal */
|
|
207
207
|
function isInvalidUrlTypeError(error) {
|
|
208
208
|
const code = error.code;
|
|
209
|
-
return error instanceof TypeError && (code === "ERR_INVALID_URL" || /^Invalid URL(?::|$)/.test(error.message) || / cannot be parsed as a URL\.?$/.test(error.message));
|
|
209
|
+
return error instanceof TypeError && (code === "ERR_INVALID_URL" || error.message === "Invalid URL string." || /^Invalid URL(?::|$)/.test(error.message) || / cannot be parsed as a URL\.?$/.test(error.message));
|
|
210
210
|
}
|
|
211
211
|
async function applyGraphAliasContext(state, context, documentLoader, remoteContextCache, baseUrl = null, processingContexts = /* @__PURE__ */ new Set()) {
|
|
212
212
|
if (context === null) return createGraphAliasContextState();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-CE_s0yQb.mjs";
|
|
5
5
|
import { metrics } from "@opentelemetry/api";
|
|
6
6
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/federation/metrics.ts
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-
|
|
4
|
+
import { n as version, t as name } from "./deno-CE_s0yQb.mjs";
|
|
5
|
+
import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-ByOQOHHS.mjs";
|
|
6
6
|
import { t as formatAcceptSignature } from "./accept-CPVqki78.mjs";
|
|
7
7
|
import { a as hasPortableActor, c as isPortableId, l as isPortableKeyId, n as getGatewayKeyBase, o as isCompatibleKeyId, r as getPortableDid, t as getCanonicalPortableId, u as isPortableUri } from "./portable-key-id-Bg259c4Z.mjs";
|
|
8
|
-
import { c as validateCryptoKey, n as exportJwk, s as importJwk } from "./key-
|
|
8
|
+
import { c as validateCryptoKey, n as exportJwk, s as importJwk } from "./key-C6jnekFI.mjs";
|
|
9
9
|
import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-4IJqPYos.mjs";
|
|
10
|
-
import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-
|
|
11
|
-
import { a as signObject, c as verifyPortableObjectProof, i as hasProofLike, s as verifyObject, t as InvalidPortableObjectIdError, u as verifyPortableObjectProofWithRoot } from "./proof-
|
|
12
|
-
import { a as listRequestSignatures, c as selectRequestSignature, d as verifyRequest, f as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-
|
|
13
|
-
import { t as getAuthenticatedDocumentLoader } from "./docloader-
|
|
14
|
-
import { n as kvCache } from "./kv-cache-
|
|
15
|
-
import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-
|
|
10
|
+
import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-ya2C1Xip.mjs";
|
|
11
|
+
import { a as signObject, c as verifyPortableObjectProof, i as hasProofLike, s as verifyObject, t as InvalidPortableObjectIdError, u as verifyPortableObjectProofWithRoot } from "./proof-BdO3BbLh.mjs";
|
|
12
|
+
import { a as listRequestSignatures, c as selectRequestSignature, d as verifyRequest, f as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-DV_yW4dv.mjs";
|
|
13
|
+
import { t as getAuthenticatedDocumentLoader } from "./docloader-C5p26tpa.mjs";
|
|
14
|
+
import { n as kvCache } from "./kv-cache-Bxm0a0Ww.mjs";
|
|
15
|
+
import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-CEnNz8O7.mjs";
|
|
16
16
|
import { t as nodeInfoToJson } from "./types-DE_LV1JB.mjs";
|
|
17
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-
|
|
18
|
-
import { t as verifyPortableObject } from "./portable-collection-
|
|
19
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-
|
|
20
|
-
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-
|
|
17
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-C6Nv5yyw.mjs";
|
|
18
|
+
import { t as verifyPortableObject } from "./portable-collection-uWj3hfzv.mjs";
|
|
19
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-BwANxryy.mjs";
|
|
20
|
+
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-D89oOfHC.mjs";
|
|
21
21
|
import { t as CircuitBreaker } from "./circuit-breaker-C5NqoLBJ.mjs";
|
|
22
22
|
import { t as buildCollectionSynchronizationHeader } from "./collection-CnnP1UAv.mjs";
|
|
23
|
-
import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, s as verifyServedPortableObjects, t as containsCompoundPortableObject } from "./compound-proof-
|
|
23
|
+
import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, s as verifyServedPortableObjects, t as containsCompoundPortableObject } from "./compound-proof-B02Os8h2.mjs";
|
|
24
24
|
import { t as KvKeyCache } from "./keycache-BInaECGj.mjs";
|
|
25
25
|
import { t as acceptsJsonLd } from "./negotiation-CCocWT_N.mjs";
|
|
26
|
-
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-
|
|
26
|
+
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-CbPfRGZq.mjs";
|
|
27
27
|
import { t as createExponentialBackoffPolicy } from "./retry-zX5xw5e0.mjs";
|
|
28
28
|
import { t as TaskCodec } from "./codec-C6rTrpIp.mjs";
|
|
29
29
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
@@ -583,6 +583,43 @@ function parsePortableGatewayRequest(url) {
|
|
|
583
583
|
};
|
|
584
584
|
}
|
|
585
585
|
/**
|
|
586
|
+
* Recognizes an FEP-ef61 portable ID, i.e., an `ap:` or `ap+ef61:` URI, or
|
|
587
|
+
* a compatible identifier on any gateway, and splits it into its DID and
|
|
588
|
+
* the object path to route.
|
|
589
|
+
*
|
|
590
|
+
* It accepts the same IDs as the gateway endpoint does: the query, e.g.,
|
|
591
|
+
* location hints, and the fragment are ignored, and a malformed DID, or
|
|
592
|
+
* a `did:key` DID that is not encoded in base58-btc, is refused.
|
|
593
|
+
*
|
|
594
|
+
* @param uri The ID to recognize.
|
|
595
|
+
* @returns The DID normalized as an FEP-fe34 origin, and the object path,
|
|
596
|
+
* or `null` if the ID is not a portable ID or is malformed.
|
|
597
|
+
*/
|
|
598
|
+
function parsePortableId(uri) {
|
|
599
|
+
if (uri.username !== "" || uri.password !== "") return null;
|
|
600
|
+
if (uri.protocol !== "ap:" && uri.protocol !== "ap+ef61:") {
|
|
601
|
+
const request = parsePortableGatewayRequest(uri);
|
|
602
|
+
if (request?.type !== "object") return null;
|
|
603
|
+
return {
|
|
604
|
+
authority: request.portableRequest.authority,
|
|
605
|
+
path: request.path
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
try {
|
|
609
|
+
const id = parseIri(uri);
|
|
610
|
+
canonicalizePortableUri(formatIri(id));
|
|
611
|
+
const authority = getFe34Origin(id);
|
|
612
|
+
assertBase58BtcDidKey(authority);
|
|
613
|
+
return {
|
|
614
|
+
authority,
|
|
615
|
+
path: id.pathname
|
|
616
|
+
};
|
|
617
|
+
} catch (error) {
|
|
618
|
+
if (error instanceof TypeError) return null;
|
|
619
|
+
throw error;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
586
623
|
* Builds a portable ID from a DID authority and an object path.
|
|
587
624
|
* @param authority The bare DID, e.g., `did:key:z6Mk...`.
|
|
588
625
|
* @param path The object path, e.g., `/notes/123`.
|
|
@@ -6348,12 +6385,25 @@ var ContextImpl = class ContextImpl {
|
|
|
6348
6385
|
if (path === null) throw new RouterError(`No collection dispatcher registered for "${String(name)}".`);
|
|
6349
6386
|
return buildPortableUri(requirePortableAuthority(authority), path);
|
|
6350
6387
|
}
|
|
6351
|
-
parseUri(uri) {
|
|
6388
|
+
parseUri(uri, options = {}) {
|
|
6352
6389
|
if (uri == null) return null;
|
|
6353
|
-
if (uri.origin
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6390
|
+
if (uri.origin === this.origin || uri.origin === this.canonicalOrigin) {
|
|
6391
|
+
const route = this.federation.router.route(uri.pathname);
|
|
6392
|
+
if (route != null) return this.#parseRoute(route);
|
|
6393
|
+
}
|
|
6394
|
+
if (!options.portable) return null;
|
|
6395
|
+
const portable = parsePortableId(uri);
|
|
6396
|
+
if (portable == null) return null;
|
|
6397
|
+
const route = this.federation.router.route(portable.path);
|
|
6398
|
+
if (route == null || route.name === "sharedInbox") return null;
|
|
6399
|
+
const result = this.#parseRoute(route);
|
|
6400
|
+
return result == null ? null : {
|
|
6401
|
+
...result,
|
|
6402
|
+
authority: portable.authority
|
|
6403
|
+
};
|
|
6404
|
+
}
|
|
6405
|
+
#parseRoute(route) {
|
|
6406
|
+
if (route.name === "sharedInbox") return {
|
|
6357
6407
|
type: "inbox",
|
|
6358
6408
|
identifier: void 0
|
|
6359
6409
|
};
|