@fedify/fedify 1.5.6 → 1.5.8
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/CHANGES.md +146 -0
- package/esm/deno.js +1 -1
- package/esm/runtime/key.js +5 -2
- package/esm/sig/http.js +44 -5
- package/esm/sig/ld.js +2 -2
- package/esm/sig/proof.js +1 -1
- package/esm/testing/fixtures/oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd +24 -0
- package/esm/vocab/vocab.js +206 -186
- package/package.json +1 -1
- package/types/runtime/key.d.ts.map +1 -1
- package/types/vocab/vocab.d.ts.map +1 -1
package/CHANGES.md
CHANGED
|
@@ -3,6 +3,30 @@
|
|
|
3
3
|
Fedify changelog
|
|
4
4
|
================
|
|
5
5
|
|
|
6
|
+
Version 1.5.8
|
|
7
|
+
-------------
|
|
8
|
+
|
|
9
|
+
Released on September 17, 2025.
|
|
10
|
+
|
|
11
|
+
- Added a temporary workaround for invalid AT Protocol URIs from BridgyFed.
|
|
12
|
+
URIs like `at://did:plc:...` that violate RFC 3986 URI syntax are now
|
|
13
|
+
automatically URL-encoded to `at://did%3Aplc%3A...` to prevent parsing
|
|
14
|
+
failures when processing bridged Bluesky content. [[#436]]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
Version 1.5.7
|
|
18
|
+
-------------
|
|
19
|
+
|
|
20
|
+
Released on August 25, 2025.
|
|
21
|
+
|
|
22
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
23
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
24
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
25
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
26
|
+
Now it correctly handles these fields as unquoted integers according
|
|
27
|
+
to the specification.
|
|
28
|
+
|
|
29
|
+
|
|
6
30
|
Version 1.5.6
|
|
7
31
|
-------------
|
|
8
32
|
|
|
@@ -201,6 +225,30 @@ Released on March 28, 2025.
|
|
|
201
225
|
[multibase]: https://github.com/multiformats/js-multibase
|
|
202
226
|
|
|
203
227
|
|
|
228
|
+
Version 1.4.16
|
|
229
|
+
--------------
|
|
230
|
+
|
|
231
|
+
Released on September 17, 2025.
|
|
232
|
+
|
|
233
|
+
- Added a temporary workaround for invalid AT Protocol URIs from BridgyFed.
|
|
234
|
+
URIs like `at://did:plc:...` that violate RFC 3986 URI syntax are now
|
|
235
|
+
automatically URL-encoded to `at://did%3Aplc%3A...` to prevent parsing
|
|
236
|
+
failures when processing bridged Bluesky content. [[#436]]
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
Version 1.4.15
|
|
240
|
+
--------------
|
|
241
|
+
|
|
242
|
+
Released on August 25, 2025.
|
|
243
|
+
|
|
244
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
245
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
246
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
247
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
248
|
+
Now it correctly handles these fields as unquoted integers according
|
|
249
|
+
to the specification.
|
|
250
|
+
|
|
251
|
+
|
|
204
252
|
Version 1.4.14
|
|
205
253
|
--------------
|
|
206
254
|
|
|
@@ -474,6 +522,30 @@ Released on February 5, 2025.
|
|
|
474
522
|
[#195]: https://github.com/fedify-dev/fedify/issues/195
|
|
475
523
|
|
|
476
524
|
|
|
525
|
+
Version 1.3.23
|
|
526
|
+
--------------
|
|
527
|
+
|
|
528
|
+
Released on September 17, 2025.
|
|
529
|
+
|
|
530
|
+
- Added a temporary workaround for invalid AT Protocol URIs from BridgyFed.
|
|
531
|
+
URIs like `at://did:plc:...` that violate RFC 3986 URI syntax are now
|
|
532
|
+
automatically URL-encoded to `at://did%3Aplc%3A...` to prevent parsing
|
|
533
|
+
failures when processing bridged Bluesky content. [[#436]]
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
Version 1.3.22
|
|
537
|
+
--------------
|
|
538
|
+
|
|
539
|
+
Released on August 25, 2025.
|
|
540
|
+
|
|
541
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
542
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
543
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
544
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
545
|
+
Now it correctly handles these fields as unquoted integers according
|
|
546
|
+
to the specification.
|
|
547
|
+
|
|
548
|
+
|
|
477
549
|
Version 1.3.21
|
|
478
550
|
--------------
|
|
479
551
|
|
|
@@ -865,6 +937,30 @@ Released on November 30, 2024.
|
|
|
865
937
|
[#193]: https://github.com/fedify-dev/fedify/issues/193
|
|
866
938
|
|
|
867
939
|
|
|
940
|
+
Version 1.2.26
|
|
941
|
+
--------------
|
|
942
|
+
|
|
943
|
+
Released on September 17, 2025.
|
|
944
|
+
|
|
945
|
+
- Added a temporary workaround for invalid AT Protocol URIs from BridgyFed.
|
|
946
|
+
URIs like `at://did:plc:...` that violate RFC 3986 URI syntax are now
|
|
947
|
+
automatically URL-encoded to `at://did%3Aplc%3A...` to prevent parsing
|
|
948
|
+
failures when processing bridged Bluesky content. [[#436]]
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
Version 1.2.25
|
|
952
|
+
--------------
|
|
953
|
+
|
|
954
|
+
Released on August 25, 2025.
|
|
955
|
+
|
|
956
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
957
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
958
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
959
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
960
|
+
Now it correctly handles these fields as unquoted integers according
|
|
961
|
+
to the specification.
|
|
962
|
+
|
|
963
|
+
|
|
868
964
|
Version 1.2.24
|
|
869
965
|
--------------
|
|
870
966
|
|
|
@@ -1289,6 +1385,30 @@ Released on October 31, 2024.
|
|
|
1289
1385
|
[#118]: https://github.com/fedify-dev/fedify/issues/118
|
|
1290
1386
|
|
|
1291
1387
|
|
|
1388
|
+
Version 1.1.26
|
|
1389
|
+
--------------
|
|
1390
|
+
|
|
1391
|
+
Released on September 17, 2025.
|
|
1392
|
+
|
|
1393
|
+
- Added a temporary workaround for invalid AT Protocol URIs from BridgyFed.
|
|
1394
|
+
URIs like `at://did:plc:...` that violate RFC 3986 URI syntax are now
|
|
1395
|
+
automatically URL-encoded to `at://did%3Aplc%3A...` to prevent parsing
|
|
1396
|
+
failures when processing bridged Bluesky content. [[#436]]
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
Version 1.1.25
|
|
1400
|
+
--------------
|
|
1401
|
+
|
|
1402
|
+
Released on August 25, 2025.
|
|
1403
|
+
|
|
1404
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
1405
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
1406
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
1407
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
1408
|
+
Now it correctly handles these fields as unquoted integers according
|
|
1409
|
+
to the specification.
|
|
1410
|
+
|
|
1411
|
+
|
|
1292
1412
|
Version 1.1.24
|
|
1293
1413
|
--------------
|
|
1294
1414
|
|
|
@@ -1754,6 +1874,32 @@ Released on October 20, 2024.
|
|
|
1754
1874
|
[#150]: https://github.com/fedify-dev/fedify/issues/150
|
|
1755
1875
|
|
|
1756
1876
|
|
|
1877
|
+
Version 1.0.29
|
|
1878
|
+
--------------
|
|
1879
|
+
|
|
1880
|
+
Released on September 17, 2025.
|
|
1881
|
+
|
|
1882
|
+
- Added a temporary workaround for invalid AT Protocol URIs from BridgyFed.
|
|
1883
|
+
URIs like `at://did:plc:...` that violate RFC 3986 URI syntax are now
|
|
1884
|
+
automatically URL-encoded to `at://did%3Aplc%3A...` to prevent parsing
|
|
1885
|
+
failures when processing bridged Bluesky content. [[#436]]
|
|
1886
|
+
|
|
1887
|
+
[#436]: https://github.com/fedify-dev/fedify/issues/436
|
|
1888
|
+
|
|
1889
|
+
|
|
1890
|
+
Version 1.0.28
|
|
1891
|
+
--------------
|
|
1892
|
+
|
|
1893
|
+
Released on August 25, 2025.
|
|
1894
|
+
|
|
1895
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
1896
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
1897
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
1898
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
1899
|
+
Now it correctly handles these fields as unquoted integers according
|
|
1900
|
+
to the specification.
|
|
1901
|
+
|
|
1902
|
+
|
|
1757
1903
|
Version 1.0.27
|
|
1758
1904
|
--------------
|
|
1759
1905
|
|
package/esm/deno.js
CHANGED
package/esm/runtime/key.js
CHANGED
|
@@ -94,11 +94,14 @@ export async function importMultibaseKey(key) {
|
|
|
94
94
|
format: "der",
|
|
95
95
|
type: "pkcs1",
|
|
96
96
|
});
|
|
97
|
-
const
|
|
97
|
+
const exported = keyObject.export({ type: "spki", format: "der" }).buffer;
|
|
98
|
+
const spki = exported instanceof Uint8Array
|
|
99
|
+
? exported
|
|
100
|
+
: new Uint8Array(exported);
|
|
98
101
|
return await dntShim.crypto.subtle.importKey("spki", new Uint8Array(spki), { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, true, ["verify"]);
|
|
99
102
|
}
|
|
100
103
|
else if (code === 0xed) { // ed25519-pub
|
|
101
|
-
return await dntShim.crypto.subtle.importKey("raw", content, "Ed25519", true, ["verify"]);
|
|
104
|
+
return await dntShim.crypto.subtle.importKey("raw", content.slice(), "Ed25519", true, ["verify"]);
|
|
102
105
|
}
|
|
103
106
|
else {
|
|
104
107
|
throw new TypeError("Unsupported key type: 0x" + code.toString(16));
|
package/esm/sig/http.js
CHANGED
|
@@ -221,7 +221,7 @@ async function verifyRequestInternal(request, span, { documentLoader, contextLoa
|
|
|
221
221
|
return null;
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
|
-
const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)="([^"]*)"\s*$/)).filter((m) => m != null).map((m) => m
|
|
224
|
+
const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)=(?:"([^"]*)"|(\d+))\s*$/)).filter((m) => m != null).map((m) => [m[1], m[2] ?? m[3]]));
|
|
225
225
|
if (!("keyId" in sigValues)) {
|
|
226
226
|
logger.debug("Failed to verify; no keyId field found in the Signature header.", { signature: sigHeader });
|
|
227
227
|
return null;
|
|
@@ -234,6 +234,41 @@ async function verifyRequestInternal(request, span, { documentLoader, contextLoa
|
|
|
234
234
|
logger.debug("Failed to verify; no signature field found in the Signature header.", { signature: sigHeader });
|
|
235
235
|
return null;
|
|
236
236
|
}
|
|
237
|
+
if ("expires" in sigValues) {
|
|
238
|
+
const expiresSeconds = parseInt(sigValues.expires);
|
|
239
|
+
if (!Number.isInteger(expiresSeconds)) {
|
|
240
|
+
logger.debug("Failed to verify; invalid expires field in the Signature header: {expires}.", { expires: sigValues.expires, signature: sigHeader });
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
const expires = dntShim.Temporal.Instant.fromEpochMilliseconds(expiresSeconds * 1000);
|
|
244
|
+
if (dntShim.Temporal.Instant.compare(now, expires) > 0) {
|
|
245
|
+
logger.debug("Failed to verify; signature expired at {expires} (now: {now}).", {
|
|
246
|
+
expires: expires.toString(),
|
|
247
|
+
now: now.toString(),
|
|
248
|
+
signature: sigHeader,
|
|
249
|
+
});
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if ("created" in sigValues) {
|
|
254
|
+
const createdSeconds = parseInt(sigValues.created);
|
|
255
|
+
if (!Number.isInteger(createdSeconds)) {
|
|
256
|
+
logger.debug("Failed to verify; invalid created field in the Signature header: {created}.", { created: sigValues.created, signature: sigHeader });
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
if (timeWindow !== false) {
|
|
260
|
+
const created = dntShim.Temporal.Instant.fromEpochMilliseconds(createdSeconds * 1000);
|
|
261
|
+
const tw = timeWindow ?? { minutes: 1 };
|
|
262
|
+
if (dntShim.Temporal.Instant.compare(created, now.add(tw)) > 0) {
|
|
263
|
+
logger.debug("Failed to verify; created is too far in the future.", { created: created.toString(), now: now.toString() });
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
else if (dntShim.Temporal.Instant.compare(created, now.subtract(tw)) < 0) {
|
|
267
|
+
logger.debug("Failed to verify; created is too far in the past.", { created: created.toString(), now: now.toString() });
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
237
272
|
const { keyId, headers, signature } = sigValues;
|
|
238
273
|
span?.setAttribute("http_signatures.key_id", keyId);
|
|
239
274
|
if ("algorithm" in sigValues) {
|
|
@@ -259,11 +294,15 @@ async function verifyRequestInternal(request, span, { documentLoader, contextLoa
|
|
|
259
294
|
return null;
|
|
260
295
|
}
|
|
261
296
|
const message = headerNames.map((name) => `${name}: ` +
|
|
262
|
-
(name
|
|
297
|
+
(name === "(request-target)"
|
|
263
298
|
? `${request.method.toLowerCase()} ${new URL(request.url).pathname}`
|
|
264
|
-
: name
|
|
265
|
-
?
|
|
266
|
-
:
|
|
299
|
+
: name === "(created)"
|
|
300
|
+
? (sigValues.created ?? "")
|
|
301
|
+
: name === "(expires)"
|
|
302
|
+
? (sigValues.expires ?? "")
|
|
303
|
+
: name === "host"
|
|
304
|
+
? request.headers.get("host") ?? new URL(request.url).host
|
|
305
|
+
: request.headers.get(name))).join("\n");
|
|
267
306
|
const sig = decodeBase64(signature);
|
|
268
307
|
span?.setAttribute("http_signatures.signature", encodeHex(sig));
|
|
269
308
|
// TODO: support other than RSASSA-PKCS1-v1_5:
|
package/esm/sig/ld.js
CHANGED
|
@@ -184,7 +184,7 @@ export async function verifySignature(jsonLd, options = {}) {
|
|
|
184
184
|
const encoder = new TextEncoder();
|
|
185
185
|
const message = sigOptsHash + docHash;
|
|
186
186
|
const messageBytes = encoder.encode(message);
|
|
187
|
-
const verified = await dntShim.crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature, messageBytes);
|
|
187
|
+
const verified = await dntShim.crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes);
|
|
188
188
|
if (verified)
|
|
189
189
|
return key;
|
|
190
190
|
if (cached) {
|
|
@@ -200,7 +200,7 @@ export async function verifySignature(jsonLd, options = {}) {
|
|
|
200
200
|
});
|
|
201
201
|
if (key == null)
|
|
202
202
|
return null;
|
|
203
|
-
const verified = await dntShim.crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature, messageBytes);
|
|
203
|
+
const verified = await dntShim.crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes);
|
|
204
204
|
return verified ? key : null;
|
|
205
205
|
}
|
|
206
206
|
logger.debug("Failed to verify with the fetched key {keyId}; " +
|
package/esm/sig/proof.js
CHANGED
|
@@ -209,7 +209,7 @@ async function verifyProofInternal(jsonLd, proof, options) {
|
|
|
209
209
|
"Ed25519 key:\n{keyId}", { proof, keyId: proof.verificationMethodId.href });
|
|
210
210
|
return null;
|
|
211
211
|
}
|
|
212
|
-
const verified = await dntShim.crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue, digest);
|
|
212
|
+
const verified = await dntShim.crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue.slice(), digest);
|
|
213
213
|
if (!verified) {
|
|
214
214
|
if (fetchedKey.cached) {
|
|
215
215
|
logger.debug("Failed to verify the proof with the cached key {keyId}; retrying " +
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": [
|
|
3
|
+
"https://www.w3.org/ns/activitystreams",
|
|
4
|
+
"https://w3id.org/security/v1"
|
|
5
|
+
],
|
|
6
|
+
"id": "https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd",
|
|
7
|
+
"type": "Person",
|
|
8
|
+
"preferredUsername": "hongminhee",
|
|
9
|
+
"name": "洪兔",
|
|
10
|
+
"inbox": "https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd/inbox",
|
|
11
|
+
"outbox": "https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd/outbox",
|
|
12
|
+
"publicKey": {
|
|
13
|
+
"id": "https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd#main-key",
|
|
14
|
+
"owner": "https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd",
|
|
15
|
+
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAowJfOzpA/nAYyL0bVDTm\niCAOlhFCIBnqwk1jvGrbkDhMzxlsgyoDqUSlmcJdKaPwu24YdFajDtJIgto27Ju7\nIC3hB7OFchnZ4JZrdYFo7CJABOzK58o12sdmmkCdY5hXWf1604E+mzyIdBAJ1FFJ\nL8vP07VEUsZ7yo9x0iVNg7HpCOK+y6BqI2GHS2dq9qkqQEIhC2TKHXn/RQVXwYB6\nG+YQmVUtcsbCVKdcWyTKhItLRGnepu3BqBSbieLxV27B1O9NFSoPu8xiBUnYwMoe\nsUQCE5tGcqxc75HzcVCbq7PqVqHZ1NW9RYssaSUqi4FYcjXxQrR08DrAl8rR4eXT\n4QIDAQAB\n-----END PUBLIC KEY-----\n"
|
|
16
|
+
},
|
|
17
|
+
"endpoints": {
|
|
18
|
+
"type": "as:Endpoints",
|
|
19
|
+
"sharedInbox": "https://oeee.cafe/inbox"
|
|
20
|
+
},
|
|
21
|
+
"followers": "https://oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd/followers",
|
|
22
|
+
"manuallyApprovesFollowers": false,
|
|
23
|
+
"url": "https://oeee.cafe/@hongminhee"
|
|
24
|
+
}
|