@evanp/activitypub-bot 0.43.0 → 0.43.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.
- package/CHANGELOG.md +29 -0
- package/lib/activitypubclient.js +22 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,35 @@ and this project adheres to
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.43.2] - 2026-04-22
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- `ActivityPubClient.post()` now re-sends the original activity JSON when
|
|
17
|
+
falling back from RFC 9421 to draft-cavage-12. A variable-shadowing bug
|
|
18
|
+
caused the retry to POST the error response body from the failed RFC 9421
|
|
19
|
+
attempt (e.g. `{"error":"missing signature header"}`) instead of the
|
|
20
|
+
original activity, which remote servers then rejected with `400 "no actor
|
|
21
|
+
in message"`.
|
|
22
|
+
|
|
23
|
+
## [0.43.1] - 2026-04-22
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- `ActivityPubClient` now falls back from RFC 9421 to draft-cavage-12
|
|
28
|
+
signatures on `400`, `401`, or `403` responses (previously only 401 and
|
|
29
|
+
403), so remote servers that reject RFC 9421 with a 400 — e.g.
|
|
30
|
+
Pleroma-Relay's `"missing signature header"` — now trigger the
|
|
31
|
+
double-knock instead of failing the request.
|
|
32
|
+
- Signature-policy caching is no longer overeager: successful RFC 9421
|
|
33
|
+
requests no longer store a per-origin policy, and only confirmed
|
|
34
|
+
draft-cavage-12 fallbacks are cached. This prevents origins whose
|
|
35
|
+
public endpoints don't actually verify signatures (e.g. public
|
|
36
|
+
actor fetches) from pinning the wrong scheme.
|
|
37
|
+
- Fallback on auth-shaped errors now also fires when the stored policy
|
|
38
|
+
is the legacy `rfc9421` value, so existing caches from earlier
|
|
39
|
+
releases self-correct on their next failure.
|
|
40
|
+
|
|
12
41
|
## [0.43.0] - 2026-04-22
|
|
13
42
|
|
|
14
43
|
### Added
|
package/lib/activitypubclient.js
CHANGED
|
@@ -205,12 +205,12 @@ export class ActivityPubClient {
|
|
|
205
205
|
}
|
|
206
206
|
)
|
|
207
207
|
this.#logger.debug({ hostname, status: res.status }, 'response received')
|
|
208
|
-
if ([401, 403].includes(res.status) &&
|
|
208
|
+
if ([400, 401, 403].includes(res.status) &&
|
|
209
209
|
sign &&
|
|
210
|
-
|
|
211
|
-
const
|
|
210
|
+
lastPolicy === SignaturePolicyStorage.RFC9421) {
|
|
211
|
+
const errBody = await res.text()
|
|
212
212
|
this.#logger.debug(
|
|
213
|
-
{ url, status: res.status, body, headers: res.headers },
|
|
213
|
+
{ url, status: res.status, body: errBody, headers: res.headers },
|
|
214
214
|
'Authentication error; retrying with draft-cavage-12 signature')
|
|
215
215
|
lastPolicy = SignaturePolicyStorage.DRAFT_CAVAGE_12
|
|
216
216
|
delete headers['signature-input']
|
|
@@ -230,15 +230,15 @@ export class ActivityPubClient {
|
|
|
230
230
|
this.#logger.debug({ baseUrl }, '304 Not Modified, returning cached object')
|
|
231
231
|
return cached.object
|
|
232
232
|
} else if (res.status < 200 || res.status > 299) {
|
|
233
|
-
const
|
|
233
|
+
const errBody = await res.text()
|
|
234
234
|
this.#logger.warn(
|
|
235
|
-
{ status: res.status, body, url: baseUrl },
|
|
235
|
+
{ status: res.status, body: errBody, url: baseUrl },
|
|
236
236
|
'Could not fetch url'
|
|
237
237
|
)
|
|
238
238
|
throw new ActivityPubClientError(
|
|
239
239
|
res.status,
|
|
240
240
|
`Could not fetch ${baseUrl}`,
|
|
241
|
-
{ url: baseUrl, method, headers: res.headers, body }
|
|
241
|
+
{ url: baseUrl, method, headers: res.headers, body: errBody }
|
|
242
242
|
)
|
|
243
243
|
}
|
|
244
244
|
|
|
@@ -256,7 +256,10 @@ export class ActivityPubClient {
|
|
|
256
256
|
throw err
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
|
|
259
|
+
// Only cache draft-cavage-12 (i.e. the degraded fallback). Caching
|
|
260
|
+
// rfc9421 would pin origins whose public endpoints don't actually
|
|
261
|
+
// verify signatures, and block future re-probing when they upgrade.
|
|
262
|
+
if (lastPolicy === SignaturePolicyStorage.DRAFT_CAVAGE_12) {
|
|
260
263
|
await this.#policyStorage.set(parsed.origin, lastPolicy)
|
|
261
264
|
}
|
|
262
265
|
|
|
@@ -342,10 +345,11 @@ export class ActivityPubClient {
|
|
|
342
345
|
body
|
|
343
346
|
}
|
|
344
347
|
)
|
|
345
|
-
if ([401, 403].includes(res.status) &&
|
|
346
|
-
|
|
348
|
+
if ([400, 401, 403].includes(res.status) &&
|
|
349
|
+
lastPolicy === SignaturePolicyStorage.RFC9421) {
|
|
350
|
+
const errBody = await res.text()
|
|
347
351
|
this.#logger.debug(
|
|
348
|
-
{ url, status: res.status, body, headers: res.headers },
|
|
352
|
+
{ url, status: res.status, body: errBody, headers: res.headers },
|
|
349
353
|
'Authentication error; retrying with draft-cavage-12 signature'
|
|
350
354
|
)
|
|
351
355
|
lastPolicy = SignaturePolicyStorage.DRAFT_CAVAGE_12
|
|
@@ -367,18 +371,21 @@ export class ActivityPubClient {
|
|
|
367
371
|
await this.#throttler.update(hostname, res.headers)
|
|
368
372
|
this.#logger.debug({ url }, 'Done fetching POST')
|
|
369
373
|
if (res.status < 200 || res.status > 299) {
|
|
370
|
-
const
|
|
374
|
+
const errBody = await res.text()
|
|
371
375
|
this.#logger.debug(
|
|
372
|
-
{ url, status: res.status, body, headers: res.headers },
|
|
376
|
+
{ url, status: res.status, body: errBody, headers: res.headers },
|
|
373
377
|
'Error posting to url'
|
|
374
378
|
)
|
|
375
379
|
throw new ActivityPubClientError(
|
|
376
380
|
res.status,
|
|
377
381
|
`Could not post to ${url}`,
|
|
378
|
-
{ url, method, headers: res.headers, body }
|
|
382
|
+
{ url, method, headers: res.headers, body: errBody }
|
|
379
383
|
)
|
|
380
384
|
}
|
|
381
|
-
|
|
385
|
+
// Only cache draft-cavage-12 (i.e. the degraded fallback). Caching
|
|
386
|
+
// rfc9421 would pin origins whose public endpoints don't actually
|
|
387
|
+
// verify signatures, and block future re-probing when they upgrade.
|
|
388
|
+
if (lastPolicy === SignaturePolicyStorage.DRAFT_CAVAGE_12) {
|
|
382
389
|
await this.#policyStorage.set(parsed.origin, lastPolicy)
|
|
383
390
|
}
|
|
384
391
|
}
|