@fedify/fedify 1.2.24 → 1.2.25
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
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
Fedify changelog
|
|
4
4
|
================
|
|
5
5
|
|
|
6
|
+
Version 1.2.25
|
|
7
|
+
--------------
|
|
8
|
+
|
|
9
|
+
Released on August 25, 2025.
|
|
10
|
+
|
|
11
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
12
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
13
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
14
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
15
|
+
Now it correctly handles these fields as unquoted integers according
|
|
16
|
+
to the specification.
|
|
17
|
+
|
|
18
|
+
|
|
6
19
|
Version 1.2.24
|
|
7
20
|
--------------
|
|
8
21
|
|
|
@@ -427,6 +440,19 @@ Released on October 31, 2024.
|
|
|
427
440
|
[#118]: https://github.com/dahlia/fedify/issues/118
|
|
428
441
|
|
|
429
442
|
|
|
443
|
+
Version 1.1.25
|
|
444
|
+
--------------
|
|
445
|
+
|
|
446
|
+
Released on August 25, 2025.
|
|
447
|
+
|
|
448
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
449
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
450
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
451
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
452
|
+
Now it correctly handles these fields as unquoted integers according
|
|
453
|
+
to the specification.
|
|
454
|
+
|
|
455
|
+
|
|
430
456
|
Version 1.1.24
|
|
431
457
|
--------------
|
|
432
458
|
|
|
@@ -892,6 +918,19 @@ Released on October 20, 2024.
|
|
|
892
918
|
[#150]: https://github.com/dahlia/fedify/issues/150
|
|
893
919
|
|
|
894
920
|
|
|
921
|
+
Version 1.0.28
|
|
922
|
+
--------------
|
|
923
|
+
|
|
924
|
+
Released on August 25, 2025.
|
|
925
|
+
|
|
926
|
+
- Fixed a bug where `verifyRequest()` function threw a `TypeError` when
|
|
927
|
+
verifying HTTP Signatures with `created` or `expires` fields in
|
|
928
|
+
the `Signature` header as defined in draft-cavage-http-signatures-12,
|
|
929
|
+
causing `500 Internal Server Error` responses in inbox handlers.
|
|
930
|
+
Now it correctly handles these fields as unquoted integers according
|
|
931
|
+
to the specification.
|
|
932
|
+
|
|
933
|
+
|
|
895
934
|
Version 1.0.27
|
|
896
935
|
--------------
|
|
897
936
|
|
package/esm/sig/http.js
CHANGED
|
@@ -150,7 +150,7 @@ export async function verifyRequest(request, { documentLoader, contextLoader, ti
|
|
|
150
150
|
return null;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
const sigValues = Object.fromEntries(sigHeader.split(",").map((pair) => pair.match(/^\s*([A-Za-z]+)="([^"]*)"\s*$/)).filter((m) => m != null).map((m) => m
|
|
153
|
+
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]]));
|
|
154
154
|
if (!("keyId" in sigValues)) {
|
|
155
155
|
logger.debug("Failed to verify; no keyId field found in the Signature header.", { signature: sigHeader });
|
|
156
156
|
return null;
|
|
@@ -163,6 +163,41 @@ export async function verifyRequest(request, { documentLoader, contextLoader, ti
|
|
|
163
163
|
logger.debug("Failed to verify; no signature field found in the Signature header.", { signature: sigHeader });
|
|
164
164
|
return null;
|
|
165
165
|
}
|
|
166
|
+
if ("expires" in sigValues) {
|
|
167
|
+
const expiresSeconds = parseInt(sigValues.expires);
|
|
168
|
+
if (!Number.isInteger(expiresSeconds)) {
|
|
169
|
+
logger.debug("Failed to verify; invalid expires field in the Signature header: {expires}.", { expires: sigValues.expires, signature: sigHeader });
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
const expires = dntShim.Temporal.Instant.fromEpochMilliseconds(expiresSeconds * 1000);
|
|
173
|
+
if (dntShim.Temporal.Instant.compare(now, expires) > 0) {
|
|
174
|
+
logger.debug("Failed to verify; signature expired at {expires} (now: {now}).", {
|
|
175
|
+
expires: expires.toString(),
|
|
176
|
+
now: now.toString(),
|
|
177
|
+
signature: sigHeader,
|
|
178
|
+
});
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if ("created" in sigValues) {
|
|
183
|
+
const createdSeconds = parseInt(sigValues.created);
|
|
184
|
+
if (!Number.isInteger(createdSeconds)) {
|
|
185
|
+
logger.debug("Failed to verify; invalid created field in the Signature header: {created}.", { created: sigValues.created, signature: sigHeader });
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
if (timeWindow !== false) {
|
|
189
|
+
const created = dntShim.Temporal.Instant.fromEpochMilliseconds(createdSeconds * 1000);
|
|
190
|
+
const tw = timeWindow ?? { minutes: 1 };
|
|
191
|
+
if (dntShim.Temporal.Instant.compare(created, now.add(tw)) > 0) {
|
|
192
|
+
logger.debug("Failed to verify; created is too far in the future.", { created: created.toString(), now: now.toString() });
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
else if (dntShim.Temporal.Instant.compare(created, now.subtract(tw)) < 0) {
|
|
196
|
+
logger.debug("Failed to verify; created is too far in the past.", { created: created.toString(), now: now.toString() });
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
166
201
|
const { keyId, headers, signature } = sigValues;
|
|
167
202
|
const keyResult = await fetchKey(new URL(keyId), CryptographicKey, {
|
|
168
203
|
documentLoader,
|
|
@@ -184,11 +219,15 @@ export async function verifyRequest(request, { documentLoader, contextLoader, ti
|
|
|
184
219
|
return null;
|
|
185
220
|
}
|
|
186
221
|
const message = headerNames.map((name) => `${name}: ` +
|
|
187
|
-
(name
|
|
222
|
+
(name === "(request-target)"
|
|
188
223
|
? `${request.method.toLowerCase()} ${new URL(request.url).pathname}`
|
|
189
|
-
: name
|
|
190
|
-
?
|
|
191
|
-
:
|
|
224
|
+
: name === "(created)"
|
|
225
|
+
? (sigValues.created ?? "")
|
|
226
|
+
: name === "(expires)"
|
|
227
|
+
? (sigValues.expires ?? "")
|
|
228
|
+
: name === "host"
|
|
229
|
+
? request.headers.get("host") ?? new URL(request.url).host
|
|
230
|
+
: request.headers.get(name))).join("\n");
|
|
192
231
|
const sig = decodeBase64(signature);
|
|
193
232
|
// TODO: support other than RSASSA-PKCS1-v1_5:
|
|
194
233
|
const verified = await dntShim.crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, sig, new TextEncoder().encode(message));
|
|
@@ -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
|
+
}
|
package/package.json
CHANGED
package/types/sig/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/sig/http.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAI5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAY,KAAK,QAAQ,EAAqB,MAAM,UAAU,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,OAAO,CAAC,SAAS,EAC7B,KAAK,EAAE,GAAG,GACT,OAAO,CAAC,OAAO,CAAC,CA0ClB;AAQD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;OAEG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAE/B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,GAAG,KAAK,CAAC;IAE/E;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,GAClE,oBAAyB,GAC1B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/sig/http.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAI5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAY,KAAK,QAAQ,EAAqB,MAAM,UAAU,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,OAAO,CAAC,SAAS,EAC7B,KAAK,EAAE,GAAG,GACT,OAAO,CAAC,OAAO,CAAC,CA0ClB;AAQD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;OAEG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAE/B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,GAAG,KAAK,CAAC;IAE/E;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,GAClE,oBAAyB,GAC1B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA6QlC"}
|