@evanp/activitypub-bot 0.48.0 → 0.48.1

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 CHANGED
@@ -9,6 +9,12 @@ and this project adheres to
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.48.1] - 2026-05-28
13
+
14
+ - 401 Unauthorized for authentication errors
15
+ - 401 Unauthorized when actor has been
16
+ deleted
17
+
12
18
  ## [0.48.0] - 2026-05-28
13
19
 
14
20
  ### Added
@@ -77,21 +77,21 @@ export class HTTPSignatureAuthenticator {
77
77
  this.#logger.debug({ reqId: req.id, signature }, 'Got signed request')
78
78
  const date = req.get('Date')
79
79
  if (!date) {
80
- throw new ProblemDetailsError(400, 'No date provided')
80
+ throw new ProblemDetailsError(401, 'No date provided')
81
81
  }
82
82
  if (Math.abs(Date.parse(date) - Date.now()) >
83
83
  HTTPSignatureAuthenticator.#maxDateDiff) {
84
- throw new ProblemDetailsError(400, 'Time skew too large')
84
+ throw new ProblemDetailsError(401, 'Time skew too large')
85
85
  }
86
86
  if (req.rawBodyText && req.rawBodyText.length > 0) {
87
87
  const digest = req.get('Digest')
88
88
  if (!digest) {
89
- throw new ProblemDetailsError(400, 'No digest provided')
89
+ throw new ProblemDetailsError(401, 'No digest provided')
90
90
  }
91
91
  const calculated = await this.#digester.digest(req.rawBodyText)
92
92
  if (!this.#digester.equals(digest, calculated)) {
93
93
  this.#logger.debug({ reqId: req.id, calculated, digest }, 'Digest mismatch')
94
- throw new ProblemDetailsError(400, 'Digest mismatch')
94
+ throw new ProblemDetailsError(401, 'Digest mismatch')
95
95
  }
96
96
  }
97
97
  const { method, headers } = req
@@ -100,7 +100,7 @@ export class HTTPSignatureAuthenticator {
100
100
  this.#logger.debug({ reqId: req.id, keyId }, 'Signed with keyId')
101
101
  const ok = await this.#remoteKeyStorage.getPublicKey(keyId)
102
102
  if (!ok) {
103
- throw new ProblemDetailsError(400, 'public key not found')
103
+ throw new ProblemDetailsError(401, 'public key not found')
104
104
  }
105
105
  let owner = ok.owner
106
106
  let publicKeyPem = ok.publicKeyPem
@@ -137,25 +137,25 @@ export class HTTPSignatureAuthenticator {
137
137
  const date = req.get('Date')
138
138
  if (date && Math.abs(Date.parse(date) - Date.now()) >
139
139
  HTTPSignatureAuthenticator.#maxDateDiff) {
140
- throw new ProblemDetailsError(400, 'Time skew too large')
140
+ throw new ProblemDetailsError(401, 'Time skew too large')
141
141
  }
142
142
  if (req.rawBodyText && req.rawBodyText.length > 0) {
143
143
  const digest = req.get('Content-Digest')
144
144
  if (!digest) {
145
- throw new ProblemDetailsError(400, 'No digest provided')
145
+ throw new ProblemDetailsError(401, 'No digest provided')
146
146
  }
147
147
  const calculated = await this.#digester.contentDigest(req.rawBodyText)
148
148
  if (!this.#digester.equals(digest, calculated)) {
149
149
  this.#logger.debug({ reqId: req.id, calculated, digest }, 'Digest mismatch')
150
- throw new ProblemDetailsError(400, 'Digest mismatch')
150
+ throw new ProblemDetailsError(401, 'Digest mismatch')
151
151
  }
152
152
  }
153
153
  const created = this.#messageSigner.created(signatureInput)
154
154
  if (!created) {
155
- throw new ProblemDetailsError(400, 'No created timestamp provided')
155
+ throw new ProblemDetailsError(401, 'No created timestamp provided')
156
156
  }
157
157
  if (Math.abs(Date.now() - created * 1000) > HTTPSignatureAuthenticator.#maxDateDiff) {
158
- throw new ProblemDetailsError(400, 'Time skew too large')
158
+ throw new ProblemDetailsError(401, 'Time skew too large')
159
159
  }
160
160
  const { method, headers } = req
161
161
  const { origin } = req.app.locals
@@ -163,12 +163,12 @@ export class HTTPSignatureAuthenticator {
163
163
 
164
164
  const keyId = this.#messageSigner.keyId(signatureInput)
165
165
  if (!keyId) {
166
- throw new ProblemDetailsError(400, 'no public key provided')
166
+ throw new ProblemDetailsError(401, 'no public key provided')
167
167
  }
168
168
  this.#logger.debug({ reqId: req.id, keyId }, 'Signed with keyId')
169
169
  const ok = await this.#remoteKeyStorage.getPublicKey(keyId)
170
170
  if (!ok) {
171
- throw new ProblemDetailsError(400, 'public key not found')
171
+ throw new ProblemDetailsError(401, 'public key not found')
172
172
  }
173
173
  let owner = ok.owner
174
174
  let publicKeyPem = ok.publicKeyPem
@@ -31,7 +31,10 @@ export class RemoteKeyStorage {
31
31
  return null
32
32
  }
33
33
  if (!await this.#confirmPublicKey(remote.owner, id)) {
34
- this.#logger.warn({ owner: remote.owner, id }, 'Mismatched owner and key')
34
+ this.#logger.warn(
35
+ { owner: remote.owner, id },
36
+ 'Cannot confirm match between owner and public key'
37
+ )
35
38
  return null
36
39
  }
37
40
  await this.#cachePublicKey(id, remote.owner, remote.publicKeyPem)
@@ -58,7 +61,14 @@ export class RemoteKeyStorage {
58
61
 
59
62
  async #getRemotePublicKey (id) {
60
63
  this.debug(`#getRemotePublicKey(${id})`)
61
- const response = await this.#client.getKey(id)
64
+ let response
65
+ try {
66
+ response = await this.#client.getKey(id)
67
+ } catch (err) {
68
+ this.#logger.warn({ id, err }, 'error getting key')
69
+ return null
70
+ }
71
+
62
72
  if (!response) {
63
73
  return null
64
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evanp/activitypub-bot",
3
- "version": "0.48.0",
3
+ "version": "0.48.1",
4
4
  "description": "server-side ActivityPub bot framework",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",