@fedify/fedify 2.1.0-dev.565 → 2.1.0-dev.592

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 (96) hide show
  1. package/dist/accept-D7sAxyNa.js +143 -0
  2. package/dist/{assert_rejects-Ce45JcFg.js → assert_rejects-0h7I2Esa.js} +1 -1
  3. package/dist/{builder-Deoi2N2z.js → builder-B24i8eYp.js} +3 -3
  4. package/dist/compat/mod.d.cts +3 -3
  5. package/dist/compat/mod.d.ts +3 -3
  6. package/dist/compat/transformers.test.js +17 -16
  7. package/dist/{context-DL0cPpPV.d.cts → context-BcqA-0BL.d.cts} +52 -2
  8. package/dist/{context--RwChtri.d.ts → context-DyJjQQ_H.d.ts} +52 -2
  9. package/dist/{deno-CEdy89j9.js → deno-OR506Yti.js} +1 -2
  10. package/dist/{docloader-CL1QPJzN.js → docloader-BG_pP2fW.js} +2 -2
  11. package/dist/federation/builder.test.js +7 -7
  12. package/dist/federation/collection.test.js +5 -5
  13. package/dist/federation/handler.test.js +806 -26
  14. package/dist/federation/idempotency.test.js +22 -21
  15. package/dist/federation/inbox.test.js +3 -3
  16. package/dist/federation/keycache.test.js +1 -1
  17. package/dist/federation/kv.test.js +4 -4
  18. package/dist/federation/middleware.test.js +22 -21
  19. package/dist/federation/mod.cjs +4 -4
  20. package/dist/federation/mod.d.cts +4 -4
  21. package/dist/federation/mod.d.ts +4 -4
  22. package/dist/federation/mod.js +4 -4
  23. package/dist/federation/mq.test.js +4 -4
  24. package/dist/federation/negotiation.test.js +5 -5
  25. package/dist/federation/retry.test.js +2 -2
  26. package/dist/federation/router.test.js +4 -4
  27. package/dist/federation/send.test.js +11 -10
  28. package/dist/federation/webfinger.test.js +22 -21
  29. package/dist/{http-Dm9n1mRe.js → http-BUCxbGks.js} +144 -49
  30. package/dist/{http-DsqqmkXi.d.cts → http-BudnHZE2.d.cts} +229 -1
  31. package/dist/{http-iDlaLy8a.cjs → http-CaXARmaJ.cjs} +307 -50
  32. package/dist/{http-BbfOqHGG.d.ts → http-Dax_FIBo.d.ts} +229 -1
  33. package/dist/{http-VpqmUjje.js → http-DePHjWKP.js} +278 -51
  34. package/dist/{inbox-CMtnW0RE.js → inbox-D_LU1opv.js} +1 -1
  35. package/dist/{key-B0yADkL8.js → key-Cx3Tx_In.js} +1 -1
  36. package/dist/{kv-cache-551Om14-.cjs → kv-cache-CYTDBChd.cjs} +1 -1
  37. package/dist/{kv-cache-BSATpUtX.js → kv-cache-DizRqYX4.js} +1 -1
  38. package/dist/{ld-BBmbv1nb.js → ld-CLMJw_iX.js} +3 -3
  39. package/dist/{middleware-Cx0tTbX1.js → middleware--uATyG9i.js} +95 -18
  40. package/dist/{middleware-DpdPMZII.js → middleware-4fo4pEtA.js} +4 -4
  41. package/dist/{middleware-D11GYoP-.cjs → middleware-9YDezkYJ.cjs} +94 -17
  42. package/dist/middleware-C2PqSUaA.js +27 -0
  43. package/dist/middleware-DNY45l5T.cjs +12 -0
  44. package/dist/{middleware-Cldp2YSv.js → middleware-DzICTgdC.js} +113 -34
  45. package/dist/{mod-DE8MYisy.d.cts → mod-B7QkWzrL.d.cts} +1 -1
  46. package/dist/{mod-DKG0ovjR.d.cts → mod-Bx9jcLB8.d.cts} +1 -1
  47. package/dist/{mod-CFBU2OT3.d.cts → mod-Coe7KEgX.d.cts} +1 -1
  48. package/dist/{mod-BugwI0JN.d.ts → mod-Cs2dYEwI.d.ts} +1 -1
  49. package/dist/{mod-DcfFNgYf.d.ts → mod-D6MdymW7.d.ts} +1 -1
  50. package/dist/{mod-CvxylbuV.d.ts → mod-D6dOd--H.d.ts} +1 -1
  51. package/dist/{mod-Z7lIaCfo.d.ts → mod-SMHOMNpZ.d.ts} +1 -1
  52. package/dist/{mod-Dp0kK0hO.d.cts → mod-em2Il1eD.d.cts} +1 -1
  53. package/dist/mod.cjs +12 -4
  54. package/dist/mod.d.cts +8 -8
  55. package/dist/mod.d.ts +8 -8
  56. package/dist/mod.js +9 -5
  57. package/dist/nodeinfo/client.test.js +4 -4
  58. package/dist/nodeinfo/handler.test.js +22 -21
  59. package/dist/nodeinfo/types.test.js +4 -4
  60. package/dist/otel/exporter.test.js +4 -4
  61. package/dist/{owner-C1ZyG4NL.js → owner-D5J299vd.js} +1 -1
  62. package/dist/{proof-wclcUq0C.js → proof-BBLHhWMC.js} +2 -2
  63. package/dist/{proof-CgK60TcQ.cjs → proof-BVl5IgbN.cjs} +3 -3
  64. package/dist/{proof-DnRq8s8f.js → proof-CiCp_mCG.js} +2 -2
  65. package/dist/{send-DNJyYRVU.js → send-2b0Fn9cn.js} +2 -2
  66. package/dist/sig/accept.test.d.ts +3 -0
  67. package/dist/sig/accept.test.js +451 -0
  68. package/dist/sig/http.test.js +452 -27
  69. package/dist/sig/key.test.js +7 -7
  70. package/dist/sig/ld.test.js +6 -6
  71. package/dist/sig/mod.cjs +6 -2
  72. package/dist/sig/mod.d.cts +3 -3
  73. package/dist/sig/mod.d.ts +3 -3
  74. package/dist/sig/mod.js +3 -3
  75. package/dist/sig/owner.test.js +8 -8
  76. package/dist/sig/proof.test.js +8 -8
  77. package/dist/testing/mod.js +1 -1
  78. package/dist/utils/docloader.test.js +10 -9
  79. package/dist/utils/kv-cache.test.js +1 -1
  80. package/dist/utils/mod.cjs +2 -2
  81. package/dist/utils/mod.d.cts +2 -2
  82. package/dist/utils/mod.d.ts +2 -2
  83. package/dist/utils/mod.js +2 -2
  84. package/package.json +6 -7
  85. package/dist/middleware-BDr0P6dx.cjs +0 -12
  86. package/dist/middleware-BZ8WpBo6.js +0 -26
  87. /package/dist/{assert_not_equals-C80BG-_5.js → assert_not_equals-f3m3epl3.js} +0 -0
  88. /package/dist/{assert_throws-BNXdRGWP.js → assert_throws-rjdMBf31.js} +0 -0
  89. /package/dist/{collection-CcnIw1qY.js → collection-CSzG2j1P.js} +0 -0
  90. /package/dist/{context-pa9aIrwp.js → context-Aqenou7c.js} +0 -0
  91. /package/dist/{keycache-C7k8s1Bk.js → keycache-CpGWAUbj.js} +0 -0
  92. /package/dist/{keys-ZbcByPg9.js → keys-BFve7QQv.js} +0 -0
  93. /package/dist/{kv-cache-El7We5sy.js → kv-cache-Bw2F2ABq.js} +0 -0
  94. /package/dist/{negotiation-5NPJL6zp.js → negotiation-BlAuS_nr.js} +0 -0
  95. /package/dist/{retry-D4GJ670a.js → retry-mqLf4b-R.js} +0 -0
  96. /package/dist/{std__assert-DWivtrGR.js → std__assert-X-_kMxKM.js} +0 -0
@@ -0,0 +1,143 @@
1
+
2
+ import { Temporal } from "@js-temporal/polyfill";
3
+ import { URLPattern } from "urlpattern-polyfill";
4
+ globalThis.addEventListener = () => {};
5
+
6
+ import { getLogger } from "@logtape/logtape";
7
+ import { Item, decodeDict, encodeDict } from "structured-field-values";
8
+
9
+ //#region src/sig/accept.ts
10
+ /**
11
+ * Parses an `Accept-Signature` header value (RFC 9421 §5.1) into an
12
+ * array of {@link AcceptSignatureMember} objects.
13
+ *
14
+ * The `Accept-Signature` field is a Dictionary Structured Field
15
+ * (RFC 8941 §3.2). Each dictionary member describes a single
16
+ * requested message signature.
17
+ *
18
+ * On parse failure (malformed or empty header), returns an empty array.
19
+ *
20
+ * @param header The raw `Accept-Signature` header value string.
21
+ * @returns An array of parsed members. Empty if the header is
22
+ * malformed or empty.
23
+ * @since 2.1.0
24
+ */
25
+ function parseAcceptSignature(header) {
26
+ try {
27
+ return parseEachSignature(decodeDict(header));
28
+ } catch {
29
+ getLogger([
30
+ "fedify",
31
+ "sig",
32
+ "http"
33
+ ]).warn("Failed to parse Accept-Signature header: {header}", { header });
34
+ return [];
35
+ }
36
+ }
37
+ const compactObject = (obj) => Object.fromEntries(Object.entries(obj).filter(([_, v]) => v !== void 0));
38
+ const parseEachSignature = (dict) => Object.entries(dict).filter(([_, item]) => Array.isArray(item.value)).map(([label, item]) => ({
39
+ label,
40
+ components: item.value.filter((subitem) => typeof subitem.value === "string").map((subitem) => ({
41
+ value: subitem.value,
42
+ params: subitem.params ?? {}
43
+ })),
44
+ parameters: compactParams(item)
45
+ }));
46
+ const compactParams = (item) => {
47
+ const { keyid, alg, created, expires, nonce, tag } = item.params ?? {};
48
+ return compactObject({
49
+ keyid: stringOrUndefined(keyid),
50
+ alg: stringOrUndefined(alg),
51
+ created: trueOrUndefined(created),
52
+ expires: trueOrUndefined(expires),
53
+ nonce: stringOrUndefined(nonce),
54
+ tag: stringOrUndefined(tag)
55
+ });
56
+ };
57
+ const stringOrUndefined = (v) => typeof v === "string" ? v : void 0;
58
+ const trueOrUndefined = (v) => v === true ? true : void 0;
59
+ /**
60
+ * Serializes an array of {@link AcceptSignatureMember} objects into an
61
+ * `Accept-Signature` header value string (RFC 9421 §5.1).
62
+ *
63
+ * The output is a Dictionary Structured Field (RFC 8941 §3.2).
64
+ *
65
+ * @param members The members to serialize.
66
+ * @returns The serialized header value string.
67
+ * @since 2.1.0
68
+ */
69
+ function formatAcceptSignature(members) {
70
+ const items = members.map((member) => [member.label, new Item(compToItems(member), compactParameters(member))]);
71
+ return encodeDict(Object.fromEntries(items));
72
+ }
73
+ const compToItems = (member) => member.components.map((c) => new Item(c.value, c.params));
74
+ const compactParameters = (member) => {
75
+ const { keyid, alg, created, expires, nonce, tag } = member.parameters;
76
+ return compactObject({
77
+ keyid,
78
+ alg,
79
+ created,
80
+ expires,
81
+ nonce,
82
+ tag
83
+ });
84
+ };
85
+ /**
86
+ * Filters out {@link AcceptSignatureMember} entries whose covered
87
+ * components include response-only identifiers (`@status`) that are
88
+ * not applicable to request-target messages, as required by
89
+ * [RFC 9421 §5](https://www.rfc-editor.org/rfc/rfc9421#section-5).
90
+ *
91
+ * A warning is logged for each discarded entry.
92
+ *
93
+ * @param members The parsed `Accept-Signature` entries to validate.
94
+ * @returns Only entries that are valid for request-target messages.
95
+ * @since 2.1.0
96
+ */
97
+ function validateAcceptSignature(members) {
98
+ const logger = getLogger([
99
+ "fedify",
100
+ "sig",
101
+ "http"
102
+ ]);
103
+ return members.filter((member) => {
104
+ if (member.components.every((c) => c.value !== "@status")) return true;
105
+ logLabel(logger, member.label);
106
+ return false;
107
+ });
108
+ }
109
+ const logLabel = (logger, label) => logger.warn("Discarding Accept-Signature member {label}: covered components include response-only identifier @status.", { label });
110
+ /**
111
+ * Attempts to translate an {@link AcceptSignatureMember} challenge into
112
+ * RFC 9421 signing options that the local signer can fulfill.
113
+ *
114
+ * Returns `null` if the challenge cannot be fulfilled—for example, if
115
+ * the requested `alg` or `keyid` is incompatible with the local key.
116
+ *
117
+ * Safety constraints:
118
+ * - `alg`: only honored if it matches `localAlg`.
119
+ * - `keyid`: only honored if it matches `localKeyId`.
120
+ * - `components`: passed through exactly as requested, per RFC 9421 §5.2.
121
+ * - `nonce`, `tag`, and `expires` are passed through directly.
122
+ *
123
+ * @param entry The challenge entry from the `Accept-Signature` header.
124
+ * @param localKeyId The local key identifier (e.g., the actor key URL).
125
+ * @param localAlg The algorithm of the local private key
126
+ * (e.g., `"rsa-v1_5-sha256"`).
127
+ * @returns Signing options if the challenge can be fulfilled, or `null`.
128
+ * @since 2.1.0
129
+ */
130
+ function fulfillAcceptSignature(entry, localKeyId, localAlg) {
131
+ if (entry.parameters.alg != null && entry.parameters.alg !== localAlg) return null;
132
+ if (entry.parameters.keyid != null && entry.parameters.keyid !== localKeyId) return null;
133
+ return {
134
+ label: entry.label,
135
+ components: entry.components,
136
+ nonce: entry.parameters.nonce,
137
+ tag: entry.parameters.tag,
138
+ expires: entry.parameters.expires
139
+ };
140
+ }
141
+
142
+ //#endregion
143
+ export { formatAcceptSignature, fulfillAcceptSignature, parseAcceptSignature, validateAcceptSignature };
@@ -4,7 +4,7 @@
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
6
  import { AssertionError } from "./assert_equals-DSbWqCm3.js";
7
- import { assertIsError } from "./assert_throws-BNXdRGWP.js";
7
+ import { assertIsError } from "./assert_throws-rjdMBf31.js";
8
8
 
9
9
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_false.js
10
10
  /**
@@ -3,9 +3,9 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { deno_default } from "./deno-CEdy89j9.js";
6
+ import { deno_default } from "./deno-OR506Yti.js";
7
7
  import { Router, RouterError } from "./router-D9eI0s4b.js";
8
- import { InboxListenerSet } from "./inbox-CMtnW0RE.js";
8
+ import { InboxListenerSet } from "./inbox-D_LU1opv.js";
9
9
  import { getTypeId } from "@fedify/vocab";
10
10
  import { getLogger } from "@logtape/logtape";
11
11
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
@@ -46,7 +46,7 @@ var FederationBuilderImpl = class {
46
46
  this.collectionTypeIds = {};
47
47
  }
48
48
  async build(options) {
49
- const { FederationImpl } = await import("./middleware-BZ8WpBo6.js");
49
+ const { FederationImpl } = await import("./middleware-C2PqSUaA.js");
50
50
  const f = new FederationImpl(options);
51
51
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
52
52
  f.router = this.router.clone();
@@ -1,7 +1,7 @@
1
1
  import "../client-C97KOq3x.cjs";
2
- import "../http-DsqqmkXi.cjs";
2
+ import "../http-BudnHZE2.cjs";
3
3
  import "../owner-1AbPBOOZ.cjs";
4
- import { ActivityTransformer } from "../context-DL0cPpPV.cjs";
4
+ import { ActivityTransformer } from "../context-BcqA-0BL.cjs";
5
5
  import "../kv-BL4nlICN.cjs";
6
- import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "../mod-DE8MYisy.cjs";
6
+ import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "../mod-B7QkWzrL.cjs";
7
7
  export { ActivityTransformer, actorDehydrator, autoIdAssigner, getDefaultActivityTransformers };
@@ -1,9 +1,9 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import "../client-BxMZiQaD.js";
4
- import "../http-BbfOqHGG.js";
4
+ import "../http-Dax_FIBo.js";
5
5
  import "../owner-gd0Q9FuU.js";
6
- import { ActivityTransformer } from "../context--RwChtri.js";
6
+ import { ActivityTransformer } from "../context-DyJjQQ_H.js";
7
7
  import "../kv-DXEUEP6z.js";
8
- import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "../mod-Z7lIaCfo.js";
8
+ import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "../mod-SMHOMNpZ.js";
9
9
  export { ActivityTransformer, actorDehydrator, autoIdAssigner, getDefaultActivityTransformers };
@@ -7,25 +7,26 @@ import { assertEquals } from "../assert_equals-DSbWqCm3.js";
7
7
  import { assert } from "../assert-MZs1qjMx.js";
8
8
  import { assertInstanceOf } from "../assert_instance_of-DHz7EHNU.js";
9
9
  import { MemoryKvStore } from "../kv-QzKcOQgP.js";
10
- import "../deno-CEdy89j9.js";
11
- import { FederationImpl, actorDehydrator, autoIdAssigner } from "../middleware-Cldp2YSv.js";
10
+ import "../deno-OR506Yti.js";
11
+ import { FederationImpl, actorDehydrator, autoIdAssigner } from "../middleware-DzICTgdC.js";
12
12
  import "../client-CoCIaTNO.js";
13
13
  import "../router-D9eI0s4b.js";
14
14
  import "../types-CPz01LGH.js";
15
- import "../key-B0yADkL8.js";
16
- import "../http-Dm9n1mRe.js";
17
- import "../ld-BBmbv1nb.js";
18
- import "../owner-C1ZyG4NL.js";
19
- import "../proof-wclcUq0C.js";
20
- import "../docloader-CL1QPJzN.js";
21
- import "../kv-cache-El7We5sy.js";
22
- import "../inbox-CMtnW0RE.js";
23
- import "../builder-Deoi2N2z.js";
24
- import "../collection-CcnIw1qY.js";
25
- import "../keycache-C7k8s1Bk.js";
26
- import "../negotiation-5NPJL6zp.js";
27
- import "../retry-D4GJ670a.js";
28
- import "../send-DNJyYRVU.js";
15
+ import "../accept-D7sAxyNa.js";
16
+ import "../key-Cx3Tx_In.js";
17
+ import "../http-BUCxbGks.js";
18
+ import "../ld-CLMJw_iX.js";
19
+ import "../owner-D5J299vd.js";
20
+ import "../proof-BBLHhWMC.js";
21
+ import "../docloader-BG_pP2fW.js";
22
+ import "../kv-cache-Bw2F2ABq.js";
23
+ import "../inbox-D_LU1opv.js";
24
+ import "../builder-B24i8eYp.js";
25
+ import "../collection-CSzG2j1P.js";
26
+ import "../keycache-CpGWAUbj.js";
27
+ import "../negotiation-BlAuS_nr.js";
28
+ import "../retry-mqLf4b-R.js";
29
+ import "../send-2b0Fn9cn.js";
29
30
  import { test } from "@fedify/fixture";
30
31
  import { Follow, Person } from "@fedify/vocab";
31
32
 
@@ -1,5 +1,5 @@
1
1
  import { GetNodeInfoOptions, JsonValue, NodeInfo } from "./client-C97KOq3x.cjs";
2
- import { HttpMessageSignaturesSpec, VerifyRequestFailureReason } from "./http-DsqqmkXi.cjs";
2
+ import { HttpMessageSignaturesSpec, VerifyRequestFailureReason } from "./http-BudnHZE2.cjs";
3
3
  import { GetKeyOwnerOptions } from "./owner-1AbPBOOZ.cjs";
4
4
  import { KvKey, KvStore } from "./kv-BL4nlICN.cjs";
5
5
  import { Activity, Actor, Collection, CryptographicKey, Hashtag, Link, LookupObjectOptions, Multikey, Object as Object$1, Recipient, TraverseCollectionOptions } from "@fedify/vocab";
@@ -837,6 +837,13 @@ interface FederationKvPrefixes {
837
837
  * @since 1.6.0
838
838
  */
839
839
  readonly httpMessageSignaturesSpec: KvKey;
840
+ /**
841
+ * The key prefix used for storing `Accept-Signature` challenge nonces.
842
+ * Only used when {@link InboxChallengePolicy.requestNonce} is `true`.
843
+ * @default `["_fedify", "acceptSignatureNonce"]`
844
+ * @since 2.1.0
845
+ */
846
+ readonly acceptSignatureNonce: KvKey;
840
847
  }
841
848
  /**
842
849
  * Options for {@link FederationOptions.origin} when it is not a string.
@@ -1321,6 +1328,39 @@ interface FederationBuilder<TContextData> extends Federatable<TContextData> {
1321
1328
  build(options: FederationOptions<TContextData>): Promise<Federation<TContextData>>;
1322
1329
  }
1323
1330
  /**
1331
+ * Policy for emitting `Accept-Signature` challenges on inbox `401`
1332
+ * responses, as defined in
1333
+ * [RFC 9421 §5](https://www.rfc-editor.org/rfc/rfc9421#section-5).
1334
+ * @since 2.1.0
1335
+ */
1336
+ interface InboxChallengePolicy {
1337
+ /**
1338
+ * Whether to emit `Accept-Signature` headers on `401` responses
1339
+ * caused by HTTP Signature verification failures.
1340
+ */
1341
+ enabled: boolean;
1342
+ /**
1343
+ * The covered component identifiers to request. Only request-applicable
1344
+ * identifiers should be used (`@status` is automatically excluded).
1345
+ * @default `["@method", "@target-uri", "@authority", "content-digest"]`
1346
+ */
1347
+ components?: string[];
1348
+ /**
1349
+ * Whether to generate and require a one-time nonce for replay protection.
1350
+ * When enabled, a cryptographically random nonce is included in each
1351
+ * challenge and verified on subsequent requests. Requires a
1352
+ * {@link KvStore}.
1353
+ * @default `false`
1354
+ */
1355
+ requestNonce?: boolean;
1356
+ /**
1357
+ * The time-to-live (in seconds) for stored nonces. After this period,
1358
+ * nonces expire and are no longer accepted.
1359
+ * @default `300` (5 minutes)
1360
+ */
1361
+ nonceTtlSeconds?: number;
1362
+ }
1363
+ /**
1324
1364
  * Options for creating a {@link Federation} object.
1325
1365
  * @template TContextData The context data to pass to the {@link Context}.
1326
1366
  * @since 1.6.0
@@ -1462,6 +1502,16 @@ interface FederationOptions<TContextData> {
1462
1502
  */
1463
1503
  firstKnock?: HttpMessageSignaturesSpec;
1464
1504
  /**
1505
+ * The policy for emitting `Accept-Signature` challenges on inbox `401`
1506
+ * responses (RFC 9421 §5). When enabled, failed HTTP Signature
1507
+ * verification responses will include an `Accept-Signature` header
1508
+ * telling the sender which components and parameters to include.
1509
+ *
1510
+ * Disabled by default (no `Accept-Signature` header is emitted).
1511
+ * @since 2.1.0
1512
+ */
1513
+ inboxChallengePolicy?: InboxChallengePolicy;
1514
+ /**
1465
1515
  * The retry policy for sending activities to recipients' inboxes.
1466
1516
  * By default, this uses an exponential backoff strategy with a maximum of
1467
1517
  * 10 attempts and a maximum delay of 12 hours.
@@ -2543,4 +2593,4 @@ interface ActorKeyPair extends CryptoKeyPair {
2543
2593
  readonly multikey: Multikey;
2544
2594
  }
2545
2595
  //#endregion
2546
- export { ActivityTransformer, ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, respondWithObject, respondWithObjectIfAcceptable };
2596
+ export { ActivityTransformer, ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, respondWithObject, respondWithObjectIfAcceptable };
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { GetNodeInfoOptions, JsonValue, NodeInfo } from "./client-BxMZiQaD.js";
4
- import { HttpMessageSignaturesSpec, VerifyRequestFailureReason } from "./http-BbfOqHGG.js";
4
+ import { HttpMessageSignaturesSpec, VerifyRequestFailureReason } from "./http-Dax_FIBo.js";
5
5
  import { GetKeyOwnerOptions } from "./owner-gd0Q9FuU.js";
6
6
  import { KvKey, KvStore } from "./kv-DXEUEP6z.js";
7
7
  import { Activity, Actor, Collection, CryptographicKey, Hashtag, Link, LookupObjectOptions, Multikey, Object as Object$1, Recipient, TraverseCollectionOptions } from "@fedify/vocab";
@@ -839,6 +839,13 @@ interface FederationKvPrefixes {
839
839
  * @since 1.6.0
840
840
  */
841
841
  readonly httpMessageSignaturesSpec: KvKey;
842
+ /**
843
+ * The key prefix used for storing `Accept-Signature` challenge nonces.
844
+ * Only used when {@link InboxChallengePolicy.requestNonce} is `true`.
845
+ * @default `["_fedify", "acceptSignatureNonce"]`
846
+ * @since 2.1.0
847
+ */
848
+ readonly acceptSignatureNonce: KvKey;
842
849
  }
843
850
  /**
844
851
  * Options for {@link FederationOptions.origin} when it is not a string.
@@ -1323,6 +1330,39 @@ interface FederationBuilder<TContextData> extends Federatable<TContextData> {
1323
1330
  build(options: FederationOptions<TContextData>): Promise<Federation<TContextData>>;
1324
1331
  }
1325
1332
  /**
1333
+ * Policy for emitting `Accept-Signature` challenges on inbox `401`
1334
+ * responses, as defined in
1335
+ * [RFC 9421 §5](https://www.rfc-editor.org/rfc/rfc9421#section-5).
1336
+ * @since 2.1.0
1337
+ */
1338
+ interface InboxChallengePolicy {
1339
+ /**
1340
+ * Whether to emit `Accept-Signature` headers on `401` responses
1341
+ * caused by HTTP Signature verification failures.
1342
+ */
1343
+ enabled: boolean;
1344
+ /**
1345
+ * The covered component identifiers to request. Only request-applicable
1346
+ * identifiers should be used (`@status` is automatically excluded).
1347
+ * @default `["@method", "@target-uri", "@authority", "content-digest"]`
1348
+ */
1349
+ components?: string[];
1350
+ /**
1351
+ * Whether to generate and require a one-time nonce for replay protection.
1352
+ * When enabled, a cryptographically random nonce is included in each
1353
+ * challenge and verified on subsequent requests. Requires a
1354
+ * {@link KvStore}.
1355
+ * @default `false`
1356
+ */
1357
+ requestNonce?: boolean;
1358
+ /**
1359
+ * The time-to-live (in seconds) for stored nonces. After this period,
1360
+ * nonces expire and are no longer accepted.
1361
+ * @default `300` (5 minutes)
1362
+ */
1363
+ nonceTtlSeconds?: number;
1364
+ }
1365
+ /**
1326
1366
  * Options for creating a {@link Federation} object.
1327
1367
  * @template TContextData The context data to pass to the {@link Context}.
1328
1368
  * @since 1.6.0
@@ -1464,6 +1504,16 @@ interface FederationOptions<TContextData> {
1464
1504
  */
1465
1505
  firstKnock?: HttpMessageSignaturesSpec;
1466
1506
  /**
1507
+ * The policy for emitting `Accept-Signature` challenges on inbox `401`
1508
+ * responses (RFC 9421 §5). When enabled, failed HTTP Signature
1509
+ * verification responses will include an `Accept-Signature` header
1510
+ * telling the sender which components and parameters to include.
1511
+ *
1512
+ * Disabled by default (no `Accept-Signature` header is emitted).
1513
+ * @since 2.1.0
1514
+ */
1515
+ inboxChallengePolicy?: InboxChallengePolicy;
1516
+ /**
1467
1517
  * The retry policy for sending activities to recipients' inboxes.
1468
1518
  * By default, this uses an exponential backoff strategy with a maximum of
1469
1519
  * 10 attempts and a maximum delay of 12 hours.
@@ -2545,4 +2595,4 @@ interface ActorKeyPair extends CryptoKeyPair {
2545
2595
  readonly multikey: Multikey;
2546
2596
  }
2547
2597
  //#endregion
2548
- export { ActivityTransformer, ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, respondWithObject, respondWithObjectIfAcceptable };
2598
+ export { ActivityTransformer, ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, respondWithObject, respondWithObjectIfAcceptable };
@@ -5,7 +5,7 @@
5
5
 
6
6
  //#region deno.json
7
7
  var name = "@fedify/fedify";
8
- var version = "2.1.0-dev.565+b4d238a9";
8
+ var version = "2.1.0-dev.592+6c1f6e6f";
9
9
  var license = "MIT";
10
10
  var exports = {
11
11
  ".": "./src/mod.ts",
@@ -27,7 +27,6 @@ var imports = {
27
27
  "fetch-mock": "npm:fetch-mock@^12.5.2",
28
28
  "json-canon": "npm:json-canon@^1.0.1",
29
29
  "jsonld": "npm:jsonld@^9.0.0",
30
- "multicodec": "npm:multicodec@^3.2.1",
31
30
  "pkijs": "npm:pkijs@^3.3.3",
32
31
  "structured-field-values": "npm:structured-field-values@^2.0.4",
33
32
  "uri-template-router": "npm:uri-template-router@^1.0.0",
@@ -3,8 +3,8 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { validateCryptoKey } from "./key-B0yADkL8.js";
7
- import { doubleKnock } from "./http-Dm9n1mRe.js";
6
+ import { validateCryptoKey } from "./key-Cx3Tx_In.js";
7
+ import { doubleKnock } from "./http-BUCxbGks.js";
8
8
  import { curry } from "es-toolkit";
9
9
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, validatePublicUrl } from "@fedify/vocab-runtime";
10
10
  import { getLogger } from "@logtape/logtape";
@@ -7,14 +7,14 @@ import { assertEquals } from "../assert_equals-DSbWqCm3.js";
7
7
  import "../assert-MZs1qjMx.js";
8
8
  import "../assert_instance_of-DHz7EHNU.js";
9
9
  import { MemoryKvStore } from "../kv-QzKcOQgP.js";
10
- import "../deno-CEdy89j9.js";
10
+ import "../deno-OR506Yti.js";
11
11
  import "../router-D9eI0s4b.js";
12
- import "../inbox-CMtnW0RE.js";
13
- import { createFederationBuilder } from "../builder-Deoi2N2z.js";
14
- import { assertExists } from "../std__assert-DWivtrGR.js";
15
- import "../assert_rejects-Ce45JcFg.js";
16
- import { assertThrows } from "../assert_throws-BNXdRGWP.js";
17
- import "../assert_not_equals-C80BG-_5.js";
12
+ import "../inbox-D_LU1opv.js";
13
+ import { createFederationBuilder } from "../builder-B24i8eYp.js";
14
+ import { assertExists } from "../std__assert-X-_kMxKM.js";
15
+ import "../assert_rejects-0h7I2Esa.js";
16
+ import { assertThrows } from "../assert_throws-rjdMBf31.js";
17
+ import "../assert_not_equals-f3m3epl3.js";
18
18
  import { test } from "@fedify/fixture";
19
19
  import { Activity, Note, Person } from "@fedify/vocab";
20
20
 
@@ -6,11 +6,11 @@
6
6
  import { assertEquals } from "../assert_equals-DSbWqCm3.js";
7
7
  import "../assert-MZs1qjMx.js";
8
8
  import "../assert_instance_of-DHz7EHNU.js";
9
- import { buildCollectionSynchronizationHeader, digest } from "../collection-CcnIw1qY.js";
10
- import "../std__assert-DWivtrGR.js";
11
- import "../assert_rejects-Ce45JcFg.js";
12
- import "../assert_throws-BNXdRGWP.js";
13
- import "../assert_not_equals-C80BG-_5.js";
9
+ import { buildCollectionSynchronizationHeader, digest } from "../collection-CSzG2j1P.js";
10
+ import "../std__assert-X-_kMxKM.js";
11
+ import "../assert_rejects-0h7I2Esa.js";
12
+ import "../assert_throws-rjdMBf31.js";
13
+ import "../assert_not_equals-f3m3epl3.js";
14
14
  import { test } from "@fedify/fixture";
15
15
  import { decodeHex } from "byte-encodings/hex";
16
16