@fedify/fedify 2.3.2-dev.1556 → 2.3.2

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.
Files changed (56) hide show
  1. package/README.md +1 -1
  2. package/dist/{builder-DosLp_w5.mjs → builder-Dx4EI2YS.mjs} +4 -2
  3. package/dist/{client-ByXmQhYD.mjs → client-D1KuWxjH.mjs} +63 -5
  4. package/dist/compat/transformers.test.mjs +1 -1
  5. package/dist/{deno-Bg8I1L40.mjs → deno-B8lcQ4Ms.mjs} +1 -1
  6. package/dist/{docloader-Dxsk3R8v.mjs → docloader-BMjxpyJD.mjs} +2 -2
  7. package/dist/federation/builder.test.mjs +13 -1
  8. package/dist/federation/handler.test.mjs +3 -3
  9. package/dist/federation/idempotency.test.mjs +2 -2
  10. package/dist/federation/metrics.test.mjs +1 -1
  11. package/dist/federation/middleware.test.mjs +7 -7
  12. package/dist/federation/mod.cjs +1 -1
  13. package/dist/federation/mod.js +1 -1
  14. package/dist/federation/send.test.mjs +3 -3
  15. package/dist/federation/temporal.test.mjs +1 -1
  16. package/dist/federation/webfinger.test.mjs +69 -7
  17. package/dist/{http-y8Cigpuq.cjs → http-CpdQD2ke.cjs} +1 -1
  18. package/dist/{http-Bw8wN_Uk.js → http-DVZxcZEr.js} +1 -1
  19. package/dist/{http-BaUm6xbz.mjs → http-DlSQMJsb.mjs} +3 -3
  20. package/dist/{key-DOnwUeY9.mjs → key-BqT9YrM3.mjs} +2 -2
  21. package/dist/{kv-cache-DilyIIfz.js → kv-cache-B52kTPj4.js} +1 -1
  22. package/dist/{kv-cache-B9AAXEOS.cjs → kv-cache-B8gm4cVB.cjs} +1 -1
  23. package/dist/{kv-cache-CE_QUNa6.mjs → kv-cache-BD6BgCTF.mjs} +1 -1
  24. package/dist/{ld-CiONXo2U.mjs → ld-hwRDfZqq.mjs} +3 -3
  25. package/dist/{metrics-CmX7KEfY.mjs → metrics-DxJzdAgZ.mjs} +1 -1
  26. package/dist/{middleware-BEhF8uxY.js → middleware-B2rDMvhv.js} +41 -22
  27. package/dist/{middleware-Cf0dFqr9.mjs → middleware-CubmqVku.mjs} +48 -31
  28. package/dist/{middleware-DZf3vcun.cjs → middleware-D2F1jSer.cjs} +41 -22
  29. package/dist/{middleware-CRMohX8-.mjs → middleware-DxCKBFFT.mjs} +1 -1
  30. package/dist/mod.cjs +5 -5
  31. package/dist/mod.js +5 -5
  32. package/dist/nodeinfo/client.test.mjs +61 -1
  33. package/dist/nodeinfo/handler.test.mjs +1 -1
  34. package/dist/nodeinfo/mod.cjs +1 -1
  35. package/dist/nodeinfo/mod.js +1 -1
  36. package/dist/{owner-C7h5_D1P.mjs → owner-Btzxz2vj.mjs} +2 -2
  37. package/dist/{proof-BKOUYRRh.cjs → proof-BdnNZ9OM.cjs} +1 -1
  38. package/dist/{proof-DNlVt3rz.js → proof-C_kcg7vF.js} +1 -1
  39. package/dist/{proof-BVuILGqP.mjs → proof-D2Z0Wa9X.mjs} +3 -3
  40. package/dist/{send-7kSXrsl4.mjs → send-BljvjEOa.mjs} +3 -3
  41. package/dist/sig/http.test.mjs +2 -2
  42. package/dist/sig/key.test.mjs +1 -1
  43. package/dist/sig/ld.test.mjs +2 -2
  44. package/dist/sig/mod.cjs +2 -2
  45. package/dist/sig/mod.js +2 -2
  46. package/dist/sig/owner.test.mjs +1 -1
  47. package/dist/sig/proof.test.mjs +1 -1
  48. package/dist/{temporal-D3Bspq6d.mjs → temporal-Dg8Hb3lz.mjs} +1 -1
  49. package/dist/{types-CAY3OdLq.js → types-DTONwNqL.js} +63 -5
  50. package/dist/{types-KC4QAoxe.cjs → types-m8u9L86X.cjs} +62 -4
  51. package/dist/utils/docloader.test.mjs +2 -2
  52. package/dist/utils/kv-cache.test.mjs +1 -1
  53. package/dist/utils/mod.cjs +1 -1
  54. package/dist/utils/mod.js +1 -1
  55. package/package.json +6 -6
  56. package/skills/fedify/SKILL.md +462 -0
@@ -1,26 +1,26 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Bg8I1L40.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-CmX7KEfY.mjs";
4
+ import { n as version, t as name } from "./deno-B8lcQ4Ms.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-DxJzdAgZ.mjs";
6
6
  import { t as formatAcceptSignature } from "./accept-CPkZzmGN.mjs";
7
- import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-DOnwUeY9.mjs";
8
- import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-BaUm6xbz.mjs";
9
- import { t as getAuthenticatedDocumentLoader } from "./docloader-Dxsk3R8v.mjs";
10
- import { n as kvCache } from "./kv-cache-CE_QUNa6.mjs";
11
- 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-CiONXo2U.mjs";
12
- import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-C7h5_D1P.mjs";
7
+ import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-BqT9YrM3.mjs";
8
+ import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-DlSQMJsb.mjs";
9
+ import { t as getAuthenticatedDocumentLoader } from "./docloader-BMjxpyJD.mjs";
10
+ import { n as kvCache } from "./kv-cache-BD6BgCTF.mjs";
11
+ 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-hwRDfZqq.mjs";
12
+ import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-Btzxz2vj.mjs";
13
13
  import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-L_DbOaFe.mjs";
14
- import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-BVuILGqP.mjs";
15
- import { t as getNodeInfo } from "./client-ByXmQhYD.mjs";
14
+ import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-D2Z0Wa9X.mjs";
15
+ import { t as getNodeInfo } from "./client-D1KuWxjH.mjs";
16
16
  import { t as nodeInfoToJson } from "./types-J53Kw7so.mjs";
17
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-7kSXrsl4.mjs";
18
- import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-DosLp_w5.mjs";
17
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-BljvjEOa.mjs";
18
+ import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-Dx4EI2YS.mjs";
19
19
  import { t as CircuitBreaker } from "./circuit-breaker-DLS_n1x5.mjs";
20
20
  import { t as buildCollectionSynchronizationHeader } from "./collection-Cc3DVAhE.mjs";
21
21
  import { t as KvKeyCache } from "./keycache-BeU0LCII.mjs";
22
22
  import { t as acceptsJsonLd } from "./negotiation-DDstyBvc.mjs";
23
- import { t as hasMalformedKnownTemporalLiteral } from "./temporal-D3Bspq6d.mjs";
23
+ import { t as hasMalformedKnownTemporalLiteral } from "./temporal-Dg8Hb3lz.mjs";
24
24
  import { t as createExponentialBackoffPolicy } from "./retry-CXg_MBI-.mjs";
25
25
  import { getLogger, withContext } from "@logtape/logtape";
26
26
  import { RouterError } from "@fedify/uri-template";
@@ -2099,6 +2099,24 @@ const logger = getLogger([
2099
2099
  "webfinger",
2100
2100
  "server"
2101
2101
  ]);
2102
+ function getWebFingerSubjectAndAliases({ resourceUrl, actorUri, preferredUsername, acctUsername, host, contextHost }) {
2103
+ const aliases = [];
2104
+ let subject = resourceUrl.href;
2105
+ if (resourceUrl.protocol != "acct:" && preferredUsername != null) {
2106
+ aliases.push(`acct:${preferredUsername}@${host ?? contextHost}`);
2107
+ if (host != null && host !== contextHost) aliases.push(`acct:${preferredUsername}@${contextHost}`);
2108
+ }
2109
+ if (resourceUrl.href !== actorUri.href) aliases.push(actorUri.href);
2110
+ if (resourceUrl.protocol === "acct:" && host != null && host !== contextHost && !resourceUrl.href.endsWith(`@${host}`)) {
2111
+ subject = `acct:${preferredUsername ?? acctUsername}@${host}`;
2112
+ aliases.push(resourceUrl.href);
2113
+ if (preferredUsername != null && preferredUsername !== "" && preferredUsername !== acctUsername) aliases.push(`acct:${preferredUsername}@${contextHost}`);
2114
+ }
2115
+ return {
2116
+ subject,
2117
+ aliases
2118
+ };
2119
+ }
2102
2120
  /**
2103
2121
  * Handles a WebFinger request. You would not typically call this function
2104
2122
  * directly, but instead use {@link Federation.fetch} method.
@@ -2203,6 +2221,7 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
2203
2221
  return identifier;
2204
2222
  }
2205
2223
  let identifier = null;
2224
+ let acctUsername = null;
2206
2225
  const uriParsed = context.parseUri(resourceUrl);
2207
2226
  if (uriParsed?.type != "actor") {
2208
2227
  const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
@@ -2216,8 +2235,9 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
2216
2235
  const normalizedHost = portMatch == null ? domainToASCII(match[2].toLowerCase()) : domainToASCII(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
2217
2236
  if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
2218
2237
  else {
2219
- identifier = await mapUsernameToIdentifier(match[1]);
2220
- resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
2238
+ acctUsername = match[1];
2239
+ identifier = await mapUsernameToIdentifier(acctUsername);
2240
+ resourceUrl = new URL(`acct:${acctUsername}@${normalizedHost}`);
2221
2241
  }
2222
2242
  }
2223
2243
  } else identifier = uriParsed.identifier;
@@ -2231,9 +2251,10 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
2231
2251
  status: 410,
2232
2252
  headers: { "Access-Control-Allow-Origin": "*" }
2233
2253
  });
2254
+ const actorUri = context.getActorUri(identifier);
2234
2255
  const links = [{
2235
2256
  rel: "self",
2236
- href: context.getActorUri(identifier).href,
2257
+ href: actorUri.href,
2237
2258
  type: "application/activity+json"
2238
2259
  }];
2239
2260
  for (const url of actor.urls) if (url instanceof Link && url.href != null) links.push({
@@ -2257,23 +2278,19 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
2257
2278
  const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
2258
2279
  if (customLinks != null) for (const link of customLinks) links.push(link);
2259
2280
  }
2260
- const aliases = [];
2261
- const preferredUsername = actor.preferredUsername;
2262
- if (resourceUrl.protocol != "acct:" && preferredUsername != null) {
2263
- aliases.push(`acct:${preferredUsername}@${host ?? context.url.host}`);
2264
- if (host != null && host !== context.url.host) aliases.push(`acct:${preferredUsername}@${context.url.host}`);
2265
- }
2266
- if (resourceUrl.href !== context.getActorUri(identifier).href) aliases.push(context.getActorUri(identifier).href);
2267
- if (resourceUrl.protocol === "acct:" && host != null && host !== context.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
2268
- const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
2269
- aliases.push(`acct:${username}@${host}`);
2270
- }
2271
- const jrd = {
2272
- subject: resourceUrl.href,
2281
+ const { subject, aliases } = getWebFingerSubjectAndAliases({
2282
+ resourceUrl,
2283
+ actorUri,
2284
+ preferredUsername: actor.preferredUsername,
2285
+ acctUsername,
2286
+ host,
2287
+ contextHost: context.url.host
2288
+ });
2289
+ return new Response(JSON.stringify({
2290
+ subject,
2273
2291
  aliases,
2274
2292
  links
2275
- };
2276
- return new Response(JSON.stringify(jrd), { headers: {
2293
+ }), { headers: {
2277
2294
  "Content-Type": "application/jrd+json",
2278
2295
  "Access-Control-Allow-Origin": "*"
2279
2296
  } });
@@ -2,10 +2,10 @@ const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  const require_chunk = require("./chunk-DDcVe30Y.cjs");
4
4
  const require_transformers = require("./transformers-NeAONrAq.cjs");
5
- const require_http = require("./http-y8Cigpuq.cjs");
6
- const require_proof = require("./proof-BKOUYRRh.cjs");
7
- const require_types = require("./types-KC4QAoxe.cjs");
8
- const require_kv_cache = require("./kv-cache-B9AAXEOS.cjs");
5
+ const require_http = require("./http-CpdQD2ke.cjs");
6
+ const require_proof = require("./proof-BdnNZ9OM.cjs");
7
+ const require_types = require("./types-m8u9L86X.cjs");
8
+ const require_kv_cache = require("./kv-cache-B8gm4cVB.cjs");
9
9
  let _logtape_logtape = require("@logtape/logtape");
10
10
  let _fedify_uri_template = require("@fedify/uri-template");
11
11
  let _fedify_vocab = require("@fedify/vocab");
@@ -138,6 +138,8 @@ var FederationBuilderImpl = class {
138
138
  f.webFingerLinksDispatcher = this.webFingerLinksDispatcher;
139
139
  f.objectCallbacks = { ...this.objectCallbacks };
140
140
  f.objectTypeIds = { ...this.objectTypeIds };
141
+ f.collectionCallbacks = { ...this.collectionCallbacks };
142
+ f.collectionTypeIds = { ...this.collectionTypeIds };
141
143
  f.inboxPath = this.inboxPath;
142
144
  f.outboxPath = this.outboxPath;
143
145
  f.inboxCallbacks = this.inboxCallbacks == null ? void 0 : { ...this.inboxCallbacks };
@@ -3742,6 +3744,24 @@ const logger = (0, _logtape_logtape.getLogger)([
3742
3744
  "webfinger",
3743
3745
  "server"
3744
3746
  ]);
3747
+ function getWebFingerSubjectAndAliases({ resourceUrl, actorUri, preferredUsername, acctUsername, host, contextHost }) {
3748
+ const aliases = [];
3749
+ let subject = resourceUrl.href;
3750
+ if (resourceUrl.protocol != "acct:" && preferredUsername != null) {
3751
+ aliases.push(`acct:${preferredUsername}@${host ?? contextHost}`);
3752
+ if (host != null && host !== contextHost) aliases.push(`acct:${preferredUsername}@${contextHost}`);
3753
+ }
3754
+ if (resourceUrl.href !== actorUri.href) aliases.push(actorUri.href);
3755
+ if (resourceUrl.protocol === "acct:" && host != null && host !== contextHost && !resourceUrl.href.endsWith(`@${host}`)) {
3756
+ subject = `acct:${preferredUsername ?? acctUsername}@${host}`;
3757
+ aliases.push(resourceUrl.href);
3758
+ if (preferredUsername != null && preferredUsername !== "" && preferredUsername !== acctUsername) aliases.push(`acct:${preferredUsername}@${contextHost}`);
3759
+ }
3760
+ return {
3761
+ subject,
3762
+ aliases
3763
+ };
3764
+ }
3745
3765
  /**
3746
3766
  * Handles a WebFinger request. You would not typically call this function
3747
3767
  * directly, but instead use {@link Federation.fetch} method.
@@ -3846,6 +3866,7 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
3846
3866
  return identifier;
3847
3867
  }
3848
3868
  let identifier = null;
3869
+ let acctUsername = null;
3849
3870
  const uriParsed = context.parseUri(resourceUrl);
3850
3871
  if (uriParsed?.type != "actor") {
3851
3872
  const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
@@ -3859,8 +3880,9 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
3859
3880
  const normalizedHost = portMatch == null ? (0, node_url.domainToASCII)(match[2].toLowerCase()) : (0, node_url.domainToASCII)(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
3860
3881
  if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
3861
3882
  else {
3862
- identifier = await mapUsernameToIdentifier(match[1]);
3863
- resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
3883
+ acctUsername = match[1];
3884
+ identifier = await mapUsernameToIdentifier(acctUsername);
3885
+ resourceUrl = new URL(`acct:${acctUsername}@${normalizedHost}`);
3864
3886
  }
3865
3887
  }
3866
3888
  } else identifier = uriParsed.identifier;
@@ -3874,9 +3896,10 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
3874
3896
  status: 410,
3875
3897
  headers: { "Access-Control-Allow-Origin": "*" }
3876
3898
  });
3899
+ const actorUri = context.getActorUri(identifier);
3877
3900
  const links = [{
3878
3901
  rel: "self",
3879
- href: context.getActorUri(identifier).href,
3902
+ href: actorUri.href,
3880
3903
  type: "application/activity+json"
3881
3904
  }];
3882
3905
  for (const url of actor.urls) if (url instanceof _fedify_vocab.Link && url.href != null) links.push({
@@ -3900,23 +3923,19 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
3900
3923
  const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
3901
3924
  if (customLinks != null) for (const link of customLinks) links.push(link);
3902
3925
  }
3903
- const aliases = [];
3904
- const preferredUsername = actor.preferredUsername;
3905
- if (resourceUrl.protocol != "acct:" && preferredUsername != null) {
3906
- aliases.push(`acct:${preferredUsername}@${host ?? context.url.host}`);
3907
- if (host != null && host !== context.url.host) aliases.push(`acct:${preferredUsername}@${context.url.host}`);
3908
- }
3909
- if (resourceUrl.href !== context.getActorUri(identifier).href) aliases.push(context.getActorUri(identifier).href);
3910
- if (resourceUrl.protocol === "acct:" && host != null && host !== context.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
3911
- const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
3912
- aliases.push(`acct:${username}@${host}`);
3913
- }
3914
- const jrd = {
3915
- subject: resourceUrl.href,
3926
+ const { subject, aliases } = getWebFingerSubjectAndAliases({
3927
+ resourceUrl,
3928
+ actorUri,
3929
+ preferredUsername: actor.preferredUsername,
3930
+ acctUsername,
3931
+ host,
3932
+ contextHost: context.url.host
3933
+ });
3934
+ return new Response(JSON.stringify({
3935
+ subject,
3916
3936
  aliases,
3917
3937
  links
3918
- };
3919
- return new Response(JSON.stringify(jrd), { headers: {
3938
+ }), { headers: {
3920
3939
  "Content-Type": "application/jrd+json",
3921
3940
  "Access-Control-Allow-Origin": "*"
3922
3941
  } });
@@ -1,5 +1,5 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as FederationImpl } from "./middleware-Cf0dFqr9.mjs";
4
+ import { n as FederationImpl } from "./middleware-CubmqVku.mjs";
5
5
  export { FederationImpl };
package/dist/mod.cjs CHANGED
@@ -4,11 +4,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
4
  require("./chunk-DDcVe30Y.cjs");
5
5
  const require_transformers = require("./transformers-NeAONrAq.cjs");
6
6
  require("./compat/mod.cjs");
7
- const require_http = require("./http-y8Cigpuq.cjs");
8
- const require_middleware = require("./middleware-DZf3vcun.cjs");
9
- const require_proof = require("./proof-BKOUYRRh.cjs");
10
- const require_types = require("./types-KC4QAoxe.cjs");
11
- const require_kv_cache = require("./kv-cache-B9AAXEOS.cjs");
7
+ const require_http = require("./http-CpdQD2ke.cjs");
8
+ const require_middleware = require("./middleware-D2F1jSer.cjs");
9
+ const require_proof = require("./proof-BdnNZ9OM.cjs");
10
+ const require_types = require("./types-m8u9L86X.cjs");
11
+ const require_kv_cache = require("./kv-cache-B8gm4cVB.cjs");
12
12
  const require_federation_mod = require("./federation/mod.cjs");
13
13
  require("./nodeinfo/mod.cjs");
14
14
  require("./runtime/mod.cjs");
package/dist/mod.js CHANGED
@@ -3,11 +3,11 @@ import { URLPattern } from "urlpattern-polyfill";
3
3
  import "./chunk-CRNNMoPX.js";
4
4
  import { n as autoIdAssigner, r as getDefaultActivityTransformers, t as actorDehydrator } from "./transformers-BGMIq1cs.js";
5
5
  import "./compat/mod.js";
6
- import { A as formatAcceptSignature, M as parseAcceptSignature, N as validateAcceptSignature, a as verifyRequestDetailed, c as fetchKeyDetailed, i as verifyRequest, j as fulfillAcceptSignature, l as generateCryptoKeyPair, o as exportJwk, r as signRequest, s as fetchKey, u as importJwk } from "./http-Bw8wN_Uk.js";
7
- import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "./middleware-BEhF8uxY.js";
8
- import { C as verifySignature, S as verifyJsonLd, _ as hasSignatureLike, a as verifyProof, b as signJsonLd, c as getKeyOwner, d as attachSignature, i as verifyObject, m as detachSignature, n as hasProofLike, p as createSignature, r as signObject, s as doesActorOwnKey, t as createProof } from "./proof-DNlVt3rz.js";
9
- import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "./types-CAY3OdLq.js";
10
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-DilyIIfz.js";
6
+ import { A as formatAcceptSignature, M as parseAcceptSignature, N as validateAcceptSignature, a as verifyRequestDetailed, c as fetchKeyDetailed, i as verifyRequest, j as fulfillAcceptSignature, l as generateCryptoKeyPair, o as exportJwk, r as signRequest, s as fetchKey, u as importJwk } from "./http-DVZxcZEr.js";
7
+ import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "./middleware-B2rDMvhv.js";
8
+ import { C as verifySignature, S as verifyJsonLd, _ as hasSignatureLike, a as verifyProof, b as signJsonLd, c as getKeyOwner, d as attachSignature, i as verifyObject, m as detachSignature, n as hasProofLike, p as createSignature, r as signObject, s as doesActorOwnKey, t as createProof } from "./proof-C_kcg7vF.js";
9
+ import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "./types-DTONwNqL.js";
10
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-B52kTPj4.js";
11
11
  import { InProcessMessageQueue, MemoryKvStore, ParallelMessageQueue, Router, RouterError } from "./federation/mod.js";
12
12
  import "./nodeinfo/mod.js";
13
13
  import "./runtime/mod.js";
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
4
4
  import { t as esm_default } from "../esm-vrlUxr60.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
6
  import "../std__assert-BBjXFNOb.mjs";
7
- import { a as parseProtocol, c as parseUsage, i as parseOutboundService, n as parseInboundService, o as parseServices, r as parseNodeInfo, s as parseSoftware, t as getNodeInfo } from "../client-ByXmQhYD.mjs";
7
+ import { a as parseProtocol, c as parseUsage, i as parseOutboundService, n as parseInboundService, o as parseServices, r as parseNodeInfo, s as parseSoftware, t as getNodeInfo } from "../client-D1KuWxjH.mjs";
8
8
  import { test } from "@fedify/fixture";
9
9
  //#region src/nodeinfo/client.test.ts
10
10
  test("getNodeInfo()", async (t) => {
@@ -62,6 +62,66 @@ test("getNodeInfo()", async (t) => {
62
62
  });
63
63
  esm_default.hardReset();
64
64
  });
65
+ test("getNodeInfo() blocks SSRF", async (t) => {
66
+ esm_default.spyGlobal();
67
+ await t.step("link href pointing to a loopback address", async () => {
68
+ esm_default.removeRoutes();
69
+ esm_default.get("https://example.com/.well-known/nodeinfo", { body: { links: [{
70
+ rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
71
+ href: "http://127.0.0.1:8080/internal"
72
+ }] } });
73
+ let internalFetched = false;
74
+ esm_default.get("http://127.0.0.1:8080/internal", () => {
75
+ internalFetched = true;
76
+ return { body: { secret: "INTERNAL_DATA_LEAKED" } };
77
+ });
78
+ assertEquals(await getNodeInfo("https://example.com/", { parse: "none" }), void 0);
79
+ assertEquals(internalFetched, false);
80
+ });
81
+ await t.step("link href using a data: URL", async () => {
82
+ esm_default.removeRoutes();
83
+ esm_default.get("https://example.com/.well-known/nodeinfo", { body: { links: [{
84
+ rel: "http://nodeinfo.diaspora.software/ns/schema/2.0",
85
+ href: "data:application/json,{\"software\":{\"name\":\"x\"}}"
86
+ }] } });
87
+ assertEquals(await getNodeInfo("https://example.com/", { parse: "none" }), void 0);
88
+ });
89
+ await t.step("redirect to a private address", async () => {
90
+ esm_default.removeRoutes();
91
+ esm_default.get("https://example.com/.well-known/nodeinfo", { body: { links: [{
92
+ rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
93
+ href: "https://example.com/nodeinfo/2.1"
94
+ }] } });
95
+ esm_default.get("https://example.com/nodeinfo/2.1", {
96
+ status: 302,
97
+ headers: { Location: "https://127.0.0.1:8080/internal" }
98
+ });
99
+ let internalFetched = false;
100
+ esm_default.get("https://127.0.0.1:8080/internal", () => {
101
+ internalFetched = true;
102
+ return { body: { secret: "INTERNAL_DATA_LEAKED" } };
103
+ });
104
+ assertEquals(await getNodeInfo("https://example.com/", { parse: "none" }), void 0);
105
+ assertEquals(internalFetched, false);
106
+ });
107
+ await t.step("direct fetch of a private address", async () => {
108
+ esm_default.removeRoutes();
109
+ let internalFetched = false;
110
+ esm_default.get("http://127.0.0.1:8080/nodeinfo", () => {
111
+ internalFetched = true;
112
+ return { body: { software: {
113
+ name: "x",
114
+ version: "1.0.0"
115
+ } } };
116
+ });
117
+ assertEquals(await getNodeInfo("http://127.0.0.1:8080/nodeinfo", {
118
+ direct: true,
119
+ parse: "none"
120
+ }), void 0);
121
+ assertEquals(internalFetched, false);
122
+ });
123
+ esm_default.hardReset();
124
+ });
65
125
  test("parseNodeInfo()", () => {
66
126
  const input = {
67
127
  software: {
@@ -5,7 +5,7 @@ import { r as createRequestContext } from "../context-DVoTs_wM.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
6
  import "../std__assert-BBjXFNOb.mjs";
7
7
  import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
8
- import { _ as handleNodeInfo, o as createFederation, v as handleNodeInfoJrd } from "../middleware-Cf0dFqr9.mjs";
8
+ import { _ as handleNodeInfo, o as createFederation, v as handleNodeInfoJrd } from "../middleware-CubmqVku.mjs";
9
9
  import { test } from "@fedify/fixture";
10
10
  //#region src/nodeinfo/handler.test.ts
11
11
  test("handleNodeInfo()", async () => {
@@ -1,7 +1,7 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- const require_types = require("../types-KC4QAoxe.cjs");
4
+ const require_types = require("../types-m8u9L86X.cjs");
5
5
  exports.getNodeInfo = require_types.getNodeInfo;
6
6
  exports.nodeInfoToJson = require_types.nodeInfoToJson;
7
7
  exports.parseNodeInfo = require_types.parseNodeInfo;
@@ -1,4 +1,4 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "../types-CAY3OdLq.js";
3
+ import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "../types-DTONwNqL.js";
4
4
  export { getNodeInfo, nodeInfoToJson, parseNodeInfo };
@@ -1,8 +1,8 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Bg8I1L40.mjs";
5
- import "./key-DOnwUeY9.mjs";
4
+ import { n as version, t as name } from "./deno-B8lcQ4Ms.mjs";
5
+ import "./key-BqT9YrM3.mjs";
6
6
  import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
7
7
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
8
8
  import { getDocumentLoader } from "@fedify/vocab-runtime";
@@ -1,7 +1,7 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  const require_chunk = require("./chunk-DDcVe30Y.cjs");
4
- const require_http = require("./http-y8Cigpuq.cjs");
4
+ const require_http = require("./http-CpdQD2ke.cjs");
5
5
  let _logtape_logtape = require("@logtape/logtape");
6
6
  let _fedify_vocab = require("@fedify/vocab");
7
7
  let _opentelemetry_api = require("@opentelemetry/api");
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { F as version, P as name, _ as measureSignatureKeyFetch, d as validateCryptoKey, f as getDurationMs, p as getFederationMetrics, s as fetchKey } from "./http-Bw8wN_Uk.js";
3
+ import { F as version, P as name, _ as measureSignatureKeyFetch, d as validateCryptoKey, f as getDurationMs, p as getFederationMetrics, s as fetchKey } from "./http-DVZxcZEr.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, PUBLIC_COLLECTION, getTypeId, isActor } from "@fedify/vocab";
6
6
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,9 +1,9 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Bg8I1L40.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CmX7KEfY.mjs";
6
- import { n as fetchKey, o as validateCryptoKey } from "./key-DOnwUeY9.mjs";
4
+ import { n as version, t as name } from "./deno-B8lcQ4Ms.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-DxJzdAgZ.mjs";
6
+ import { n as fetchKey, o as validateCryptoKey } from "./key-BqT9YrM3.mjs";
7
7
  import { n as preloadedOnlyDocumentLoader } from "./public-audience-Cvbr2Gzt.mjs";
8
8
  import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-L_DbOaFe.mjs";
9
9
  import { getLogger } from "@logtape/logtape";
@@ -1,9 +1,9 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-Bg8I1L40.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics } from "./metrics-CmX7KEfY.mjs";
6
- import { n as doubleKnock } from "./http-BaUm6xbz.mjs";
4
+ import { n as version, t as name } from "./deno-B8lcQ4Ms.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics } from "./metrics-DxJzdAgZ.mjs";
6
+ import { n as doubleKnock } from "./http-DlSQMJsb.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
9
9
  import { FetchError } from "@fedify/vocab-runtime";
@@ -7,8 +7,8 @@ import { r as assertExists, t as assertStringIncludes } from "../std__assert-BBj
7
7
  import { n as assertGreaterOrEqual, r as assertFalse, t as assertRejects } from "../assert_rejects-DN60FHPX.mjs";
8
8
  import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
9
9
  import { t as assert } from "../assert-OguE97r2.mjs";
10
- import { t as exportJwk } from "../key-DOnwUeY9.mjs";
11
- import { a as parseRfc9421Signature, c as timingSafeEqual, i as formatRfc9421SignatureParameters, l as verifyRequest, n as doubleKnock, o as parseRfc9421SignatureInput, r as formatRfc9421Signature, s as signRequest, t as createRfc9421SignatureBase, u as verifyRequestDetailed } from "../http-BaUm6xbz.mjs";
10
+ import { t as exportJwk } from "../key-BqT9YrM3.mjs";
11
+ import { a as parseRfc9421Signature, c as timingSafeEqual, i as formatRfc9421SignatureParameters, l as verifyRequest, n as doubleKnock, o as parseRfc9421SignatureInput, r as formatRfc9421Signature, s as signRequest, t as createRfc9421SignatureBase, u as verifyRequestDetailed } from "../http-DlSQMJsb.mjs";
12
12
  import { i as rsaPrivateKey2, l as rsaPublicKey5, o as rsaPublicKey1, s as rsaPublicKey2 } from "../keys-DGu1NFwu.mjs";
13
13
  import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
14
14
  import { FetchError, exportSpki } from "@fedify/vocab-runtime";
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
5
  import "../std__assert-BBjXFNOb.mjs";
6
6
  import { t as assertRejects } from "../assert_rejects-DN60FHPX.mjs";
7
7
  import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
8
- import { a as importJwk, i as generateCryptoKeyPair, n as fetchKey, o as validateCryptoKey, r as fetchKeyDetailed, t as exportJwk } from "../key-DOnwUeY9.mjs";
8
+ import { a as importJwk, i as generateCryptoKeyPair, n as fetchKey, o as validateCryptoKey, r as fetchKeyDetailed, t as exportJwk } from "../key-BqT9YrM3.mjs";
9
9
  import { c as rsaPublicKey3, i as rsaPrivateKey2, o as rsaPublicKey1, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
10
10
  import { CryptographicKey, Multikey } from "@fedify/vocab";
11
11
  import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
@@ -5,9 +5,9 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
5
  import { n as assertGreaterOrEqual, r as assertFalse, t as assertRejects } from "../assert_rejects-DN60FHPX.mjs";
6
6
  import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
7
7
  import { t as assert } from "../assert-OguE97r2.mjs";
8
- import { i as generateCryptoKeyPair } from "../key-DOnwUeY9.mjs";
8
+ import { i as generateCryptoKeyPair } from "../key-BqT9YrM3.mjs";
9
9
  import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
10
- import { a as compactJsonLd, f as isInvalidUrlTypeError, g as verifySignature, h as verifyJsonLd, i as attachSignature, n as UnsafeJsonLdError, o as createSignature, p as signJsonLd, s as detachSignature, u as hasSignatureLike } from "../ld-CiONXo2U.mjs";
10
+ import { a as compactJsonLd, f as isInvalidUrlTypeError, g as verifySignature, h as verifyJsonLd, i as attachSignature, n as UnsafeJsonLdError, o as createSignature, p as signJsonLd, s as detachSignature, u as hasSignatureLike } from "../ld-hwRDfZqq.mjs";
11
11
  import { CryptographicKey } from "@fedify/vocab";
12
12
  import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
13
13
  import { encodeBase64 } from "byte-encodings/base64";
package/dist/sig/mod.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- const require_http = require("../http-y8Cigpuq.cjs");
5
- const require_proof = require("../proof-BKOUYRRh.cjs");
4
+ const require_http = require("../http-CpdQD2ke.cjs");
5
+ const require_proof = require("../proof-BdnNZ9OM.cjs");
6
6
  exports.attachSignature = require_proof.attachSignature;
7
7
  exports.createProof = require_proof.createProof;
8
8
  exports.createSignature = require_proof.createSignature;
package/dist/sig/mod.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { A as formatAcceptSignature, M as parseAcceptSignature, N as validateAcceptSignature, a as verifyRequestDetailed, c as fetchKeyDetailed, i as verifyRequest, j as fulfillAcceptSignature, l as generateCryptoKeyPair, o as exportJwk, r as signRequest, s as fetchKey, u as importJwk } from "../http-Bw8wN_Uk.js";
4
- import { C as verifySignature, S as verifyJsonLd, _ as hasSignatureLike, a as verifyProof, b as signJsonLd, c as getKeyOwner, d as attachSignature, i as verifyObject, m as detachSignature, n as hasProofLike, p as createSignature, r as signObject, s as doesActorOwnKey, t as createProof } from "../proof-DNlVt3rz.js";
3
+ import { A as formatAcceptSignature, M as parseAcceptSignature, N as validateAcceptSignature, a as verifyRequestDetailed, c as fetchKeyDetailed, i as verifyRequest, j as fulfillAcceptSignature, l as generateCryptoKeyPair, o as exportJwk, r as signRequest, s as fetchKey, u as importJwk } from "../http-DVZxcZEr.js";
4
+ import { C as verifySignature, S as verifyJsonLd, _ as hasSignatureLike, a as verifyProof, b as signJsonLd, c as getKeyOwner, d as attachSignature, i as verifyObject, m as detachSignature, n as hasProofLike, p as createSignature, r as signObject, s as doesActorOwnKey, t as createProof } from "../proof-C_kcg7vF.js";
5
5
  export { attachSignature, createProof, createSignature, detachSignature, doesActorOwnKey, exportJwk, fetchKey, fetchKeyDetailed, formatAcceptSignature, fulfillAcceptSignature, generateCryptoKeyPair, getKeyOwner, hasProofLike, hasSignatureLike, importJwk, parseAcceptSignature, signJsonLd, signObject, signRequest, validateAcceptSignature, verifyJsonLd, verifyObject, verifyProof, verifyRequest, verifyRequestDetailed, verifySignature };
@@ -6,7 +6,7 @@ import "../std__assert-BBjXFNOb.mjs";
6
6
  import { r as assertFalse } from "../assert_rejects-DN60FHPX.mjs";
7
7
  import { t as assert } from "../assert-OguE97r2.mjs";
8
8
  import { o as rsaPublicKey1, s as rsaPublicKey2 } from "../keys-DGu1NFwu.mjs";
9
- import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-C7h5_D1P.mjs";
9
+ import { n as getKeyOwner, t as doesActorOwnKey } from "../owner-Btzxz2vj.mjs";
10
10
  import { Create, CryptographicKey, lookupObject } from "@fedify/vocab";
11
11
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
12
12
  //#region src/sig/owner.test.ts
@@ -8,7 +8,7 @@ import { t as assertInstanceOf } from "../assert_instance_of-DBC5X09g.mjs";
8
8
  import { t as assert } from "../assert-OguE97r2.mjs";
9
9
  import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
10
10
  import { r as normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-L_DbOaFe.mjs";
11
- import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-BVuILGqP.mjs";
11
+ import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-D2Z0Wa9X.mjs";
12
12
  import { Create, DataIntegrityProof, Document, Multikey, Note, PUBLIC_COLLECTION, Place } from "@fedify/vocab";
13
13
  import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
14
14
  import { decodeMultibase, importMultibaseKey } from "@fedify/vocab-runtime";
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { c as getNormalizationContextLoader } from "./ld-CiONXo2U.mjs";
4
+ import { c as getNormalizationContextLoader } from "./ld-hwRDfZqq.mjs";
5
5
  import jsonld from "@fedify/vocab-runtime/jsonld";
6
6
  //#region src/federation/temporal.ts
7
7
  function isPlainObject(value) {