@fedify/fedify 0.10.0-dev.203 → 0.10.0-dev.205
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGES.md +5 -0
- package/esm/federation/handler.js +26 -16
- package/esm/sig/proof.js +9 -5
- package/package.json +1 -1
- package/types/federation/handler.d.ts.map +1 -1
- package/types/sig/proof.d.ts +8 -4
- package/types/sig/proof.d.ts.map +1 -1
package/CHANGES.md
CHANGED
@@ -85,6 +85,11 @@ To be released.
|
|
85
85
|
|
86
86
|
- Implemented Object Integrity Proofs. [[FEP-8b32], [#54]]
|
87
87
|
|
88
|
+
- If there are any Ed25519 key pairs, the `Context.sendActivity()` and
|
89
|
+
`Federation.sendActivity()` methods now make Object Integrity Proofs
|
90
|
+
for the activity to be sent.
|
91
|
+
- If the incoming activity has Object Integrity Proofs, the inbox listener
|
92
|
+
now verifies them and ignores HTTP Signatures (if any).
|
88
93
|
- Added `signObject()` function.
|
89
94
|
- Added `SignObjectOptions` interface.
|
90
95
|
- Added `createProof()` function.
|
@@ -3,6 +3,7 @@ import { getLogger } from "@logtape/logtape";
|
|
3
3
|
import { accepts } from "../deps/jsr.io/@std/http/0.224.4/negotiation.js";
|
4
4
|
import { verifyRequest } from "../sig/http.js";
|
5
5
|
import { doesActorOwnKey } from "../sig/owner.js";
|
6
|
+
import { verifyObject } from "../sig/proof.js";
|
6
7
|
import { Activity, Link, Object, OrderedCollection, OrderedCollectionPage, } from "../vocab/vocab.js";
|
7
8
|
export function acceptsJsonLd(request) {
|
8
9
|
const types = accepts(request);
|
@@ -175,21 +176,9 @@ export async function handleInbox(request, { handle, context, kv, kvPrefix, acto
|
|
175
176
|
return await onNotFound(request);
|
176
177
|
}
|
177
178
|
}
|
178
|
-
const key = await verifyRequest(request, {
|
179
|
-
...context,
|
180
|
-
timeWindow: signatureTimeWindow,
|
181
|
-
});
|
182
|
-
if (key == null) {
|
183
|
-
logger.error("Failed to verify the request signature.", { handle });
|
184
|
-
const response = new Response("Failed to verify the request signature.", {
|
185
|
-
status: 401,
|
186
|
-
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
187
|
-
});
|
188
|
-
return response;
|
189
|
-
}
|
190
179
|
let json;
|
191
180
|
try {
|
192
|
-
json = await request.json();
|
181
|
+
json = await request.clone().json();
|
193
182
|
}
|
194
183
|
catch (error) {
|
195
184
|
logger.error("Failed to parse JSON:\n{error}", { handle, error });
|
@@ -201,7 +190,7 @@ export async function handleInbox(request, { handle, context, kv, kvPrefix, acto
|
|
201
190
|
}
|
202
191
|
let activity;
|
203
192
|
try {
|
204
|
-
activity = await Activity
|
193
|
+
activity = await verifyObject(Activity, json, context);
|
205
194
|
}
|
206
195
|
catch (error) {
|
207
196
|
logger.error("Failed to parse activity:\n{error}", { handle, json, error });
|
@@ -211,6 +200,23 @@ export async function handleInbox(request, { handle, context, kv, kvPrefix, acto
|
|
211
200
|
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
212
201
|
});
|
213
202
|
}
|
203
|
+
let httpSigKey = null;
|
204
|
+
if (activity == null) {
|
205
|
+
const key = await verifyRequest(request, {
|
206
|
+
...context,
|
207
|
+
timeWindow: signatureTimeWindow,
|
208
|
+
});
|
209
|
+
if (key == null) {
|
210
|
+
logger.error("Failed to verify the request signature.", { handle });
|
211
|
+
const response = new Response("Failed to verify the request signature.", {
|
212
|
+
status: 401,
|
213
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
214
|
+
});
|
215
|
+
return response;
|
216
|
+
}
|
217
|
+
httpSigKey = key;
|
218
|
+
activity = await Activity.fromJsonLd(json, context);
|
219
|
+
}
|
214
220
|
const cacheKey = activity.id == null
|
215
221
|
? null
|
216
222
|
: [...kvPrefix, activity.id.href];
|
@@ -235,8 +241,12 @@ export async function handleInbox(request, { handle, context, kv, kvPrefix, acto
|
|
235
241
|
});
|
236
242
|
return response;
|
237
243
|
}
|
238
|
-
if (!await doesActorOwnKey(activity,
|
239
|
-
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
244
|
+
if (httpSigKey != null && !await doesActorOwnKey(activity, httpSigKey, context)) {
|
245
|
+
logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
|
246
|
+
activity: json,
|
247
|
+
keyId: httpSigKey.id?.href,
|
248
|
+
actorId: activity.actorId.href,
|
249
|
+
});
|
240
250
|
const response = new Response("The signer and the actor do not match.", {
|
241
251
|
status: 401,
|
242
252
|
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
package/esm/sig/proof.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as dntShim from "../_dnt.shims.js";
|
2
2
|
// @ts-ignore: json-canon is not typed
|
3
3
|
import serialize from "json-canon";
|
4
|
-
import { DataIntegrityProof
|
4
|
+
import { DataIntegrityProof } from "../vocab/vocab.js";
|
5
5
|
import { fetchKey, validateCryptoKey } from "./key.js";
|
6
6
|
import { Activity, Multikey } from "../vocab/mod.js";
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
@@ -148,17 +148,21 @@ export async function verifyProof(jsonLd, proof, options = {}) {
|
|
148
148
|
* Verifies the given object. It will verify all the proofs in the object,
|
149
149
|
* and succeed only if all the proofs are valid and all attributions and
|
150
150
|
* actors are authenticated by the proofs.
|
151
|
+
* @typeParam T The type of the object to verify.
|
152
|
+
* @param cls The class of the object to verify. It must be a subclass of
|
153
|
+
* the {@link Object}.
|
151
154
|
* @param jsonLd The JSON-LD object to verify. It's assumed that the object
|
152
|
-
* is a compacted JSON-LD representation of
|
153
|
-
* with `@context`.
|
155
|
+
* is a compacted JSON-LD representation of a `T` with `@context`.
|
154
156
|
* @param options Additional options. See also {@link VerifyObjectOptions}.
|
155
157
|
* @returns The object if it's verified, or `null` if it's not.
|
156
158
|
* @throws {TypeError} If the object is invalid or unsupported.
|
157
159
|
* @since 0.10.0
|
158
160
|
*/
|
159
|
-
export async function verifyObject(
|
161
|
+
export async function verifyObject(
|
162
|
+
// deno-lint-ignore no-explicit-any
|
163
|
+
cls, jsonLd, options = {}) {
|
160
164
|
const logger = getLogger(["fedify", "sig", "proof"]);
|
161
|
-
const object = await
|
165
|
+
const object = await cls.fromJsonLd(jsonLd, options);
|
162
166
|
const attributions = new Set(object.attributionIds.map((uri) => uri.href));
|
163
167
|
if (object instanceof Activity) {
|
164
168
|
for (const uri of object.actorIds)
|
package/package.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/federation/handler.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/federation/handler.ts"],"names":[],"mappings":"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"}
|
package/types/sig/proof.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/// <reference types="node" />
|
2
2
|
import * as dntShim from "../_dnt.shims.js";
|
3
3
|
import type { DocumentLoader } from "../runtime/docloader.js";
|
4
|
-
import { DataIntegrityProof, Object } from "../vocab/vocab.js";
|
4
|
+
import { DataIntegrityProof, type Object } from "../vocab/vocab.js";
|
5
5
|
import { Multikey } from "../vocab/mod.js";
|
6
6
|
/**
|
7
7
|
* Options for {@link createProof}.
|
@@ -89,13 +89,17 @@ export interface VerifyObjectOptions extends VerifyProofOptions {
|
|
89
89
|
* Verifies the given object. It will verify all the proofs in the object,
|
90
90
|
* and succeed only if all the proofs are valid and all attributions and
|
91
91
|
* actors are authenticated by the proofs.
|
92
|
+
* @typeParam T The type of the object to verify.
|
93
|
+
* @param cls The class of the object to verify. It must be a subclass of
|
94
|
+
* the {@link Object}.
|
92
95
|
* @param jsonLd The JSON-LD object to verify. It's assumed that the object
|
93
|
-
* is a compacted JSON-LD representation of
|
94
|
-
* with `@context`.
|
96
|
+
* is a compacted JSON-LD representation of a `T` with `@context`.
|
95
97
|
* @param options Additional options. See also {@link VerifyObjectOptions}.
|
96
98
|
* @returns The object if it's verified, or `null` if it's not.
|
97
99
|
* @throws {TypeError} If the object is invalid or unsupported.
|
98
100
|
* @since 0.10.0
|
99
101
|
*/
|
100
|
-
export declare function verifyObject(
|
102
|
+
export declare function verifyObject<T extends Object>(cls: (new (...args: any[]) => T) & {
|
103
|
+
fromJsonLd(jsonLd: unknown, options: VerifyObjectOptions): Promise<T>;
|
104
|
+
}, jsonLd: unknown, options?: VerifyObjectOptions): Promise<T | null>;
|
101
105
|
//# sourceMappingURL=proof.d.ts.map
|
package/types/sig/proof.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/sig/proof.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
1
|
+
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../src/sig/proof.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEpE,OAAO,EAAY,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAKrD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,EACJ,MAAM,GACN,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtB,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IAExC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,OAAO,CAAC,SAAS,EAC7B,KAAK,EAAE,GAAG,EACV,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,kBAAuB,GAC3D,OAAO,CAAC,kBAAkB,CAAC,CA2C7B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,MAAM,EAC/C,MAAM,EAAE,CAAC,EACT,UAAU,EAAE,OAAO,CAAC,SAAS,EAC7B,KAAK,EAAE,GAAG,EACV,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAE/B;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAqE1B;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;CAC9D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EAEjD,GAAG,EAAE,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,GAAG;IACjC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACvE,EACD,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CA2BnB"}
|