@fedify/fedify 2.4.0-dev.2127 → 2.4.0-dev.2141

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 (92) hide show
  1. package/dist/{builder-B2bgGYbP.mjs → builder-BI7H61zO.mjs} +3 -3
  2. package/dist/compat/mod.d.cts +1 -1
  3. package/dist/compat/mod.d.ts +1 -1
  4. package/dist/compat/transformers.test.mjs +1 -1
  5. package/dist/{compound-proof-SVlHSzV7.mjs → compound-proof-D0H4LLvQ.mjs} +15 -20
  6. package/dist/{context-Ci5vuUr_.d.ts → context-B2C8nuN3.d.ts} +4 -3
  7. package/dist/{context-Bm6ldGvx.d.cts → context-CrDDVrbF.d.cts} +4 -3
  8. package/dist/{deno-Be9xoxps.mjs → deno-BXI_BLNy.mjs} +1 -1
  9. package/dist/{docloader-Dtuyb0ps.mjs → docloader-B5BIo7e9.mjs} +2 -2
  10. package/dist/federation/builder.test.mjs +1 -1
  11. package/dist/federation/compound-fanout.test.mjs +3 -3
  12. package/dist/federation/handler-compound-proof.test.mjs +64 -8
  13. package/dist/federation/handler.test.mjs +5 -5
  14. package/dist/federation/hashlink-media.test.mjs +2 -2
  15. package/dist/federation/idempotency.test.mjs +2 -2
  16. package/dist/federation/metrics.test.mjs +1 -1
  17. package/dist/federation/middleware.test.mjs +7 -7
  18. package/dist/federation/mod.cjs +1 -1
  19. package/dist/federation/mod.d.cts +2 -2
  20. package/dist/federation/mod.d.ts +2 -2
  21. package/dist/federation/mod.js +1 -1
  22. package/dist/federation/outgoing-proof.test.mjs +6 -6
  23. package/dist/federation/portable-actor.test.mjs +3 -3
  24. package/dist/federation/portable-chain.test.mjs +17 -5
  25. package/dist/federation/portable-gateway-keys.test.mjs +76 -5
  26. package/dist/federation/portable-inbox.test.mjs +9 -4
  27. package/dist/federation/portable.test.mjs +3 -3
  28. package/dist/federation/send.test.mjs +3 -3
  29. package/dist/federation/tasks/enqueue.test.mjs +1 -1
  30. package/dist/federation/tasks/tasks.test.mjs +2 -2
  31. package/dist/federation/temporal.test.mjs +1 -1
  32. package/dist/federation/webfinger.test.mjs +1 -1
  33. package/dist/{federation-B6IHuS6n.cjs → federation-DqDOPjWo.cjs} +23 -28
  34. package/dist/{http-D76Py0M4.d.cts → http-C-x_OLSp.d.ts} +57 -14
  35. package/dist/{http-BFeK9sBg.mjs → http-CEx2SZjf.mjs} +18 -12
  36. package/dist/{http-BrQgkJay.d.ts → http-CjezPjFX.d.cts} +57 -14
  37. package/dist/{http-Rmbiu-5S.js → http-D4KW2GTi.js} +376 -36
  38. package/dist/{http-o8l4QeUY.cjs → http-DSYQQn23.cjs} +392 -34
  39. package/dist/{key-Cc1b6pW9.mjs → key-C0giKuki.mjs} +103 -16
  40. package/dist/{kv-cache-tLKBfxHc.mjs → kv-cache-AWTrxTq3.mjs} +1 -1
  41. package/dist/{kv-cache-BUkgZAcX.cjs → kv-cache-BcsvaCCL.cjs} +1 -1
  42. package/dist/{kv-cache-BweDce2I.js → kv-cache-D_E-2K3i.js} +1 -1
  43. package/dist/{ld-DQNTIrAe.mjs → ld-CWDReGMZ.mjs} +3 -3
  44. package/dist/{metrics-DDE9S63Q.mjs → metrics-DxlVXwn5.mjs} +1 -1
  45. package/dist/{middleware-K9aLnf57.js → middleware-1mv9QR16.js} +23 -28
  46. package/dist/{middleware-CsQorLC_.mjs → middleware-B7stx5gy.mjs} +1 -1
  47. package/dist/{middleware-BdhvduR9.mjs → middleware-CAWRGSwH.mjs} +24 -24
  48. package/dist/{mod-AVir5nVI.d.cts → mod-B7SfEqIP.d.cts} +1 -1
  49. package/dist/{mod-Co53r-VP.d.ts → mod-Bz9tFXI2.d.ts} +1 -1
  50. package/dist/{mod-eVOUPbQE.d.ts → mod-C06GoL5Z.d.ts} +1 -1
  51. package/dist/{mod-Cwdt_CWU.d.ts → mod-CZetqT5h.d.ts} +1 -1
  52. package/dist/{mod-Cr79cQlc.d.cts → mod-D4g9ffEn.d.cts} +1 -1
  53. package/dist/{mod-Byt5tvAS.d.cts → mod-S--JxYjo.d.cts} +1 -1
  54. package/dist/mod.cjs +4 -4
  55. package/dist/mod.d.cts +5 -5
  56. package/dist/mod.d.ts +5 -5
  57. package/dist/mod.js +4 -4
  58. package/dist/nodeinfo/handler.test.mjs +1 -1
  59. package/dist/{owner-CCfdL83M.mjs → owner-CgoCOTUQ.mjs} +37 -4
  60. package/dist/{portable-collection-WXaHkNqC.mjs → portable-collection-0_5DyXMt.mjs} +2 -2
  61. package/dist/{portable-collection-DXogVs__.cjs → portable-collection-BD8fE3j3.cjs} +34 -1
  62. package/dist/{portable-collection-DdXsKBg4.js → portable-collection-CG9P_i0E.js} +34 -1
  63. package/dist/portable-key-BXkgMpw1.mjs +395 -0
  64. package/dist/{portable-key-id-T7lecIbt.mjs → portable-key-id-Bg259c4Z.mjs} +69 -2
  65. package/dist/{proof-CW8k0R1G.mjs → proof-B5s-W6Sm.mjs} +7 -6
  66. package/dist/{send--FORaIc4.mjs → send-BAJvkdNL.mjs} +3 -3
  67. package/dist/sig/compound-proof-discovery.test.mjs +1 -1
  68. package/dist/sig/compound-proof-producer.test.mjs +1 -1
  69. package/dist/sig/compound-proof-verification.test.mjs +196 -2
  70. package/dist/sig/compound-proof.test.mjs +2 -2
  71. package/dist/sig/http.test.mjs +2 -2
  72. package/dist/sig/key.test.mjs +1 -1
  73. package/dist/sig/ld.test.mjs +2 -2
  74. package/dist/sig/mod.cjs +2 -2
  75. package/dist/sig/mod.d.cts +2 -2
  76. package/dist/sig/mod.d.ts +2 -2
  77. package/dist/sig/mod.js +2 -2
  78. package/dist/sig/owner.test.mjs +1 -1
  79. package/dist/sig/portable-collection.test.mjs +1 -1
  80. package/dist/sig/portable-key.test.mjs +479 -5
  81. package/dist/sig/proof.test.mjs +45 -3
  82. package/dist/{temporal-CffY_XOJ.mjs → temporal-BkCPJ_uC.mjs} +1 -1
  83. package/dist/testing/kv.test.mjs +1 -1
  84. package/dist/testing/mod.d.mts +3 -2
  85. package/dist/utils/docloader.test.mjs +2 -2
  86. package/dist/utils/kv-cache.test.mjs +1 -1
  87. package/dist/utils/mod.cjs +1 -1
  88. package/dist/utils/mod.d.cts +1 -1
  89. package/dist/utils/mod.d.ts +1 -1
  90. package/dist/utils/mod.js +1 -1
  91. package/package.json +6 -6
  92. package/dist/portable-key-C-fPq_Yf.mjs +0 -214
@@ -1,214 +0,0 @@
1
- import "temporal-polyfill";
2
- import "urlpattern-polyfill";
3
- globalThis.addEventListener = () => {};
4
- import { l as isSamePublicKey, o as isPortableActorDocument, t as getCanonicalPortableId } from "./portable-key-id-T7lecIbt.mjs";
5
- import { l as verifyPortableObjectProofWithRoot } from "./proof-CW8k0R1G.mjs";
6
- import { getLogger } from "@logtape/logtape";
7
- import { CryptographicKey, Multikey, Object as Object$1 } from "@fedify/vocab";
8
- import { getDocumentLoader, isGatewayUrl } from "@fedify/vocab-runtime";
9
- //#region src/sig/portable-key.ts
10
- const logger = getLogger([
11
- "fedify",
12
- "sig",
13
- "key"
14
- ]);
15
- const SEC = "https://w3id.org/security#";
16
- /**
17
- * Verifies that the signed document of a portable actor vouches for
18
- * the gateway key with the given ID.
19
- *
20
- * A gateway key is accepted only if:
21
- *
22
- * - the document is an actor whose portable ID, i.e., its `ap:` ID or
23
- * the canonical portable ID of its compatible identifier, is the one
24
- * the key ID is the compatible identifier of;
25
- * - the document has a valid [FEP-8b32] Object Integrity Proof made by
26
- * the DID of its ID, i.e., it satisfies the [FEP-ef61] proof policy;
27
- * - the document embeds a `Multikey` with that ID in its `assertionMethod`,
28
- * whose `controller` is the actor, as [FEP-521a] requires, and a key
29
- * embedded in its `publicKey` with the same ID agrees with it; or, if
30
- * no `assertionMethod` entry has that ID, the document embeds
31
- * a `CryptographicKey` with that ID in its `publicKey`, whose `owner` is
32
- * the actor, as some publishers, e.g., tootik, list their RSA keys only
33
- * there;
34
- * - no more than one entry of either property has that ID; and
35
- * - the key ID's origin is one of the actor's `gateways`.
36
- *
37
- * [FEP-8b32]: https://w3id.org/fep/8b32
38
- * [FEP-ef61]: https://w3id.org/fep/ef61
39
- * [FEP-521a]: https://w3id.org/fep/521a
40
- *
41
- * @param document The raw JSON-LD document served at the key ID.
42
- * @param actor The parsed document, which must be a portable actor.
43
- * @param keyId The key ID, which must be a compatible key ID.
44
- * @param options Loaders and telemetry providers.
45
- * @returns The verification result, which is never `legacy`.
46
- * @internal
47
- */
48
- async function verifyPortableGatewayKeyDocument(document, actor, keyId, options = {}) {
49
- const reject = (reason) => {
50
- logger.debug("Failed to verify gateway key {keyId} of the portable actor {actorId}: {reason}", {
51
- keyId: keyId.href,
52
- actorId: actor.id?.href,
53
- reason
54
- });
55
- return {
56
- type: "rejected",
57
- reason
58
- };
59
- };
60
- const keyBase = new URL(keyId.href);
61
- keyBase.hash = "";
62
- const claimedActorId = getCanonicalPortableId(keyBase);
63
- const actorId = actor.id == null ? null : getCanonicalPortableId(actor.id);
64
- if (claimedActorId == null || actorId == null) return reject("The key ID or the actor ID is not a valid portable ID.");
65
- if (claimedActorId !== actorId) return reject("The key ID is not a compatible identifier of the actor it dereferences to.");
66
- let verification;
67
- try {
68
- verification = await verifyPortableObjectProofWithRoot(document, {
69
- documentLoader: options.documentLoader,
70
- contextLoader: options.contextLoader,
71
- keyCache: options.keyCache,
72
- tracerProvider: options.tracerProvider,
73
- meterProvider: options.meterProvider
74
- });
75
- } catch (error) {
76
- if (!(error instanceof TypeError)) throw error;
77
- return reject(`The actor document is malformed: ${error.message}`);
78
- }
79
- const { result, root, expires } = verification;
80
- if (!result.verified) return reject("The actor document does not satisfy the FEP-ef61 proof policy: " + result.reason.type);
81
- if (root == null) return reject("The actor document could not be expanded.");
82
- const refuse = (url) => Promise.reject(/* @__PURE__ */ new Error(`Refusing to fetch ${url}.`));
83
- const parseEmbeddedPublicKey = async (node) => {
84
- if (isReference(node)) return null;
85
- let key;
86
- try {
87
- key = await CryptographicKey.fromJsonLd(node, {
88
- documentLoader: refuse,
89
- contextLoader: options.contextLoader,
90
- tracerProvider: options.tracerProvider
91
- });
92
- } catch (error) {
93
- if (!(error instanceof TypeError)) throw error;
94
- return null;
95
- }
96
- return key.publicKey == null ? null : key;
97
- };
98
- let verifiedActor;
99
- try {
100
- verifiedActor = await Object$1.fromJsonLd(root, {
101
- documentLoader: refuse,
102
- contextLoader: options.contextLoader,
103
- tracerProvider: options.tracerProvider
104
- });
105
- } catch (error) {
106
- if (!(error instanceof TypeError)) throw error;
107
- return reject("The verified actor document is malformed.");
108
- }
109
- if (!isPortableActorDocument(verifiedActor) || getCanonicalPortableId(verifiedActor.id) !== claimedActorId) return reject("The key ID is not a compatible identifier of the actor whose document is signed.");
110
- actor = verifiedActor;
111
- const assertionNodes = findNodes(root[`${SEC}assertionMethod`], keyId);
112
- const publicKeyNodes = findNodes(root[`${SEC}publicKey`], keyId);
113
- if (assertionNodes.length > 1 || publicKeyNodes.length > 1) return reject("The actor document has more than one key with the ID.");
114
- let publicKey;
115
- if (assertionNodes.length > 0) {
116
- if (isReference(assertionNodes[0])) return reject("The actor document does not embed the key in its assertionMethod.");
117
- let multikey;
118
- try {
119
- multikey = await Multikey.fromJsonLd(assertionNodes[0], {
120
- documentLoader: refuse,
121
- contextLoader: options.contextLoader,
122
- tracerProvider: options.tracerProvider
123
- });
124
- } catch (error) {
125
- if (!(error instanceof TypeError)) throw error;
126
- return reject("The key in the assertionMethod is malformed.");
127
- }
128
- if (multikey.publicKey == null) return reject("The key in the assertionMethod has no public key.");
129
- if (multikey.controllerId == null || getCanonicalPortableId(multikey.controllerId) !== actorId) return reject("The controller of the key is not the actor.");
130
- publicKey = multikey.publicKey;
131
- if (publicKeyNodes.length > 0 && !isReference(publicKeyNodes[0])) {
132
- const embedded = await parseEmbeddedPublicKey(publicKeyNodes[0]);
133
- if (embedded == null || !await isSamePublicKey(embedded.publicKey, publicKey) || embedded.ownerId != null && getCanonicalPortableId(embedded.ownerId) !== actorId) return reject("The key in the publicKey does not agree with the one in the assertionMethod.");
134
- }
135
- } else {
136
- if (publicKeyNodes.length < 1) return reject("The actor document embeds the key in neither its assertionMethod nor its publicKey.");
137
- const embedded = await parseEmbeddedPublicKey(publicKeyNodes[0]);
138
- if (embedded == null) return reject("The key in the publicKey is not embedded or malformed.");
139
- if (embedded.ownerId == null || getCanonicalPortableId(embedded.ownerId) !== actorId) return reject("The owner of the key is not the actor.");
140
- publicKey = embedded.publicKey;
141
- }
142
- if (!actor.gateways.some((gateway) => isGatewayUrl(gateway) && gateway.origin === keyId.origin)) return reject(`The gateway ${keyId.origin} is not listed in the actor's gateways.`);
143
- const key = new CryptographicKey({
144
- id: keyId,
145
- owner: actor.id,
146
- publicKey
147
- });
148
- return {
149
- type: "verified",
150
- actor,
151
- key,
152
- ...expires == null ? {} : { expires }
153
- };
154
- }
155
- /**
156
- * Fetches the document at a compatible key ID, and resolves the key as
157
- * a gateway key if the document is a portable actor.
158
- *
159
- * @param keyId The key ID, which must be a compatible key ID.
160
- * @param options Loaders and telemetry providers.
161
- * @returns `legacy` if the document cannot be fetched or is not a portable
162
- * actor, which leaves the key to the usual resolution; otherwise,
163
- * the result of {@link verifyPortableGatewayKeyDocument}.
164
- * @internal
165
- */
166
- async function fetchPortableGatewayKey(keyId, options = {}) {
167
- const documentLoader = options.documentLoader ?? getDocumentLoader();
168
- const contextLoader = options.contextLoader ?? getDocumentLoader();
169
- let remoteDocument;
170
- try {
171
- remoteDocument = await documentLoader(keyId.href);
172
- } catch (error) {
173
- logger.debug("Failed to fetch key {keyId}: {error}", {
174
- keyId: keyId.href,
175
- error
176
- });
177
- return { type: "legacy" };
178
- }
179
- let object;
180
- try {
181
- object = await Object$1.fromJsonLd(remoteDocument.document, {
182
- documentLoader,
183
- contextLoader,
184
- tracerProvider: options.tracerProvider
185
- });
186
- } catch (error) {
187
- if (!(error instanceof TypeError)) throw error;
188
- return { type: "legacy" };
189
- }
190
- if (!isPortableActorDocument(object)) return { type: "legacy" };
191
- return await verifyPortableGatewayKeyDocument(remoteDocument.document, object, keyId, {
192
- ...options,
193
- documentLoader,
194
- contextLoader
195
- });
196
- }
197
- function findNodes(values, id) {
198
- if (!Array.isArray(values)) return [];
199
- const nodes = [];
200
- for (const value of values) {
201
- if (value == null || typeof value !== "object" || Array.isArray(value)) continue;
202
- const node = value;
203
- const nodeId = node["@id"];
204
- if (typeof nodeId !== "string" || !URL.canParse(nodeId)) continue;
205
- if (new URL(nodeId).href === id.href) nodes.push(node);
206
- }
207
- return nodes;
208
- }
209
- /** A node with nothing but an `@id` is a reference, not an embedded key. */
210
- function isReference(node) {
211
- return Object.keys(node).every((key) => key === "@id");
212
- }
213
- //#endregion
214
- export { verifyPortableGatewayKeyDocument as n, fetchPortableGatewayKey as t };