@evanp/activitypub-bot 0.48.0 → 0.48.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 +13 -0
- package/lib/httpsignatureauthenticator.js +12 -12
- package/lib/remotekeystorage.js +12 -2
- package/lib/remoteobjectcache.js +1 -1
- package/lib/routes/nodeinfo.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,19 @@ and this project adheres to
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
- Missing required `instance` property in /nodeinfo/2.2.
|
|
13
|
+
|
|
14
|
+
## [0.48.2] - 2026-06-04
|
|
15
|
+
|
|
16
|
+
- Immediate expiry for actors.
|
|
17
|
+
- Include required 'instance' property in nodeinfo 2.2.
|
|
18
|
+
|
|
19
|
+
## [0.48.1] - 2026-05-28
|
|
20
|
+
|
|
21
|
+
- 401 Unauthorized for authentication errors
|
|
22
|
+
- 401 Unauthorized when actor has been
|
|
23
|
+
deleted
|
|
24
|
+
|
|
12
25
|
## [0.48.0] - 2026-05-28
|
|
13
26
|
|
|
14
27
|
### 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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
171
|
+
throw new ProblemDetailsError(401, 'public key not found')
|
|
172
172
|
}
|
|
173
173
|
let owner = ok.owner
|
|
174
174
|
let publicKeyPem = ok.publicKeyPem
|
package/lib/remotekeystorage.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
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/lib/remoteobjectcache.js
CHANGED
|
@@ -147,7 +147,7 @@ export class RemoteObjectCache {
|
|
|
147
147
|
if (as2obj.isActivity()) {
|
|
148
148
|
offset = 24 * 60 * 60 * 1000
|
|
149
149
|
} else if (as2obj.inbox) {
|
|
150
|
-
offset =
|
|
150
|
+
offset = -1000
|
|
151
151
|
} else if (KEY_TYPES.includes(as2obj.type)) {
|
|
152
152
|
offset = -1000
|
|
153
153
|
} else if (COLLECTION_TYPES.includes(as2obj.type)) {
|
package/lib/routes/nodeinfo.js
CHANGED