@fedify/fedify 0.10.0-dev.202 → 0.10.0-dev.204
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGES.md +10 -0
- package/esm/federation/handler.js +26 -16
- package/esm/federation/middleware.js +45 -21
- package/esm/federation/send.js +54 -4
- package/esm/sig/proof.js +186 -0
- package/esm/webfinger/handler.js +6 -12
- package/package.json +3 -3
- package/types/federation/context.d.ts +5 -10
- package/types/federation/context.d.ts.map +1 -1
- package/types/federation/handler.d.ts.map +1 -1
- package/types/federation/middleware.d.ts +3 -5
- package/types/federation/middleware.d.ts.map +1 -1
- package/types/federation/mod.d.ts +1 -0
- package/types/federation/mod.d.ts.map +1 -1
- package/types/federation/queue.d.ts +5 -2
- package/types/federation/queue.d.ts.map +1 -1
- package/types/federation/send.d.ts +23 -7
- package/types/federation/send.d.ts.map +1 -1
- package/types/sig/proof.d.ts +105 -0
- package/types/sig/proof.d.ts.map +1 -1
- package/types/webfinger/handler.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.
|
@@ -95,6 +100,11 @@ To be released.
|
|
95
100
|
- Added `VerifyProofOptions` interface.
|
96
101
|
- Added `fetchKey()` function.
|
97
102
|
- Added `FetchKeyOptions` interface.
|
103
|
+
- Added `SenderKeyPair` interface.
|
104
|
+
- The type of `Federation.sendActivity()` method's first parameter became
|
105
|
+
`SenderKeyPair[]` (was `{ keyId: URL; privateKey: CryptoKey }`).
|
106
|
+
- The `Context.sendActivity()` method's first parameter now accepts
|
107
|
+
`SenderKeyPair[]` as well.
|
98
108
|
|
99
109
|
- Added `context` option to `Object.toJsonLd()` method. This applies to
|
100
110
|
any subclasses of the `Object` class too.
|
@@ -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" },
|
@@ -98,7 +98,7 @@ export class Federation {
|
|
98
98
|
async #listenQueue(message) {
|
99
99
|
const logger = getLogger(["fedify", "federation", "outbox"]);
|
100
100
|
const logData = {
|
101
|
-
|
101
|
+
keyIds: message.keys.map((pair) => pair.keyId),
|
102
102
|
inbox: message.inbox,
|
103
103
|
activity: message.activity,
|
104
104
|
trial: message.trial,
|
@@ -106,16 +106,28 @@ export class Federation {
|
|
106
106
|
};
|
107
107
|
let activity = null;
|
108
108
|
try {
|
109
|
-
const
|
110
|
-
|
111
|
-
const
|
109
|
+
const keys = [];
|
110
|
+
let rsaKeyPair = null;
|
111
|
+
for (const { keyId, privateKey } of message.keys) {
|
112
|
+
const pair = {
|
113
|
+
keyId: new URL(keyId),
|
114
|
+
privateKey: await importJwk(privateKey, "private"),
|
115
|
+
};
|
116
|
+
if (rsaKeyPair == null &&
|
117
|
+
pair.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
118
|
+
rsaKeyPair = pair;
|
119
|
+
}
|
120
|
+
keys.push(pair);
|
121
|
+
}
|
122
|
+
const documentLoader = rsaKeyPair == null
|
123
|
+
? this.#documentLoader
|
124
|
+
: this.#authenticatedDocumentLoaderFactory(rsaKeyPair);
|
112
125
|
activity = await Activity.fromJsonLd(message.activity, {
|
113
126
|
documentLoader,
|
114
127
|
contextLoader: this.#contextLoader,
|
115
128
|
});
|
116
129
|
await sendActivity({
|
117
|
-
|
118
|
-
privateKey,
|
130
|
+
keys,
|
119
131
|
activity,
|
120
132
|
inbox: new URL(message.inbox),
|
121
133
|
contextLoader: this.#contextLoader,
|
@@ -578,14 +590,20 @@ export class Federation {
|
|
578
590
|
* Sends an activity to recipients' inboxes. You would typically use
|
579
591
|
* {@link Context.sendActivity} instead of this method.
|
580
592
|
*
|
581
|
-
* @param
|
593
|
+
* @param keys The sender's key pairs.
|
582
594
|
* @param recipients The recipients of the activity.
|
583
595
|
* @param activity The activity to send.
|
584
596
|
* @param options Options for sending the activity.
|
585
597
|
* @throws {TypeError} If the activity to send does not have an actor.
|
586
598
|
*/
|
587
|
-
async sendActivity(
|
599
|
+
async sendActivity(keys, recipients, activity, { preferSharedInbox, immediate, excludeBaseUris, collectionSync } = {}) {
|
588
600
|
const logger = getLogger(["fedify", "federation", "outbox"]);
|
601
|
+
if (keys.length < 1) {
|
602
|
+
throw new TypeError("The sender's keys must not be empty.");
|
603
|
+
}
|
604
|
+
for (const { privateKey } of keys) {
|
605
|
+
validateCryptoKey(privateKey, "private");
|
606
|
+
}
|
589
607
|
if (activity.actorId == null) {
|
590
608
|
logger.error("Activity {activityId} to send does not have an actor.", { activity, activityId: activity?.id?.href });
|
591
609
|
throw new TypeError("The activity to send must have at least one actor property.");
|
@@ -596,7 +614,6 @@ export class Federation {
|
|
596
614
|
id: new URL(`urn:uuid:${dntShim.crypto.randomUUID()}`),
|
597
615
|
});
|
598
616
|
}
|
599
|
-
validateCryptoKey(privateKey, "private");
|
600
617
|
const inboxes = extractInboxes({
|
601
618
|
recipients: Array.isArray(recipients) ? recipients : [recipients],
|
602
619
|
preferSharedInbox,
|
@@ -618,8 +635,7 @@ export class Federation {
|
|
618
635
|
const promises = [];
|
619
636
|
for (const inbox in inboxes) {
|
620
637
|
promises.push(sendActivity({
|
621
|
-
|
622
|
-
privateKey,
|
638
|
+
keys,
|
623
639
|
activity,
|
624
640
|
inbox: new URL(inbox),
|
625
641
|
contextLoader: this.#contextLoader,
|
@@ -632,15 +648,18 @@ export class Federation {
|
|
632
648
|
return;
|
633
649
|
}
|
634
650
|
logger.debug("Enqueuing activity {activityId} to send later.", { activityId: activity.id?.href, activity });
|
635
|
-
const
|
651
|
+
const keyJwkPairs = [];
|
652
|
+
for (const { keyId, privateKey } of keys) {
|
653
|
+
const privateKeyJwk = await exportJwk(privateKey);
|
654
|
+
keyJwkPairs.push({ keyId: keyId.href, privateKey: privateKeyJwk });
|
655
|
+
}
|
636
656
|
const activityJson = await activity.toJsonLd({
|
637
657
|
contextLoader: this.#contextLoader,
|
638
658
|
});
|
639
659
|
for (const inbox in inboxes) {
|
640
660
|
const message = {
|
641
661
|
type: "outbox",
|
642
|
-
|
643
|
-
privateKey: privateKeyJwk,
|
662
|
+
keys: keyJwkPairs,
|
644
663
|
activity: activityJson,
|
645
664
|
inbox,
|
646
665
|
trial: 0,
|
@@ -1053,16 +1072,21 @@ class ContextImpl {
|
|
1053
1072
|
return this.#authenticatedDocumentLoaderFactory(identity);
|
1054
1073
|
}
|
1055
1074
|
async sendActivity(sender, recipients, activity, options = {}) {
|
1056
|
-
let
|
1075
|
+
let keys;
|
1057
1076
|
if ("handle" in sender) {
|
1058
|
-
|
1059
|
-
if (
|
1060
|
-
throw new Error(`No key pair found for actor ${sender.handle}
|
1077
|
+
keys = await this.getKeyPairsFromHandle(this.#url, this.data, sender.handle);
|
1078
|
+
if (keys.length < 1) {
|
1079
|
+
throw new Error(`No key pair found for actor ${JSON.stringify(sender.handle)}.`);
|
1080
|
+
}
|
1081
|
+
}
|
1082
|
+
else if (Array.isArray(sender)) {
|
1083
|
+
if (sender.length < 1) {
|
1084
|
+
throw new Error("The sender's key pairs are empty.");
|
1061
1085
|
}
|
1062
|
-
|
1086
|
+
keys = sender;
|
1063
1087
|
}
|
1064
1088
|
else {
|
1065
|
-
|
1089
|
+
keys = [sender];
|
1066
1090
|
}
|
1067
1091
|
const opts = { ...options };
|
1068
1092
|
let expandedRecipients;
|
@@ -1085,7 +1109,7 @@ class ContextImpl {
|
|
1085
1109
|
else {
|
1086
1110
|
expandedRecipients = [recipients];
|
1087
1111
|
}
|
1088
|
-
return await this.#federation.sendActivity(
|
1112
|
+
return await this.#federation.sendActivity(keys, expandedRecipients, activity, opts);
|
1089
1113
|
}
|
1090
1114
|
getFollowers(_handle) {
|
1091
1115
|
throw new Error('"followers" recipients are not supported in Context. ' +
|
package/esm/federation/send.js
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import { getLogger } from "@logtape/logtape";
|
2
2
|
import { signRequest } from "../sig/http.js";
|
3
|
+
import { validateCryptoKey } from "../sig/key.js";
|
4
|
+
import { signObject } from "../sig/proof.js";
|
3
5
|
/**
|
4
6
|
* Extracts the inbox URLs from recipients.
|
5
7
|
* @param parameters The parameters to extract the inboxes.
|
@@ -30,11 +32,40 @@ export function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris
|
|
30
32
|
* See also {@link SendActivityParameters}.
|
31
33
|
* @throws {Error} If the activity fails to send.
|
32
34
|
*/
|
33
|
-
export async function sendActivity({ activity,
|
35
|
+
export async function sendActivity({ activity, keys, inbox, contextLoader, documentLoader, headers, }) {
|
34
36
|
const logger = getLogger(["fedify", "federation", "outbox"]);
|
37
|
+
if (activity.id == null) {
|
38
|
+
throw new TypeError("The activity to send must have an id.");
|
39
|
+
}
|
35
40
|
if (activity.actorId == null) {
|
36
41
|
throw new TypeError("The activity to send must have at least one actor property.");
|
37
42
|
}
|
43
|
+
else if (keys.length < 1) {
|
44
|
+
throw new TypeError("The keys must not be empty.");
|
45
|
+
}
|
46
|
+
const activityId = activity.id.href;
|
47
|
+
let proofCreated = false;
|
48
|
+
for (const { keyId, privateKey } of keys) {
|
49
|
+
validateCryptoKey(privateKey, "private");
|
50
|
+
if (privateKey.algorithm.name === "Ed25519") {
|
51
|
+
activity = await signObject(activity, privateKey, keyId, {
|
52
|
+
documentLoader,
|
53
|
+
contextLoader,
|
54
|
+
});
|
55
|
+
proofCreated = true;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
if (!proofCreated) {
|
59
|
+
logger.warn("No supported key found to create a proof for the activity {activityId}. " +
|
60
|
+
"The activity will be sent without a proof. " +
|
61
|
+
"In order to create a proof, at least one Ed25519 key must be provided.", {
|
62
|
+
activityId,
|
63
|
+
keys: keys.map((pair) => ({
|
64
|
+
keyId: pair.keyId.href,
|
65
|
+
privateKey: pair.privateKey,
|
66
|
+
})),
|
67
|
+
});
|
68
|
+
}
|
38
69
|
const jsonLd = await activity.toJsonLd({ contextLoader });
|
39
70
|
headers = new Headers(headers);
|
40
71
|
headers.set("Content-Type", "application/activity+json");
|
@@ -43,7 +74,26 @@ export async function sendActivity({ activity, privateKey, keyId, inbox, context
|
|
43
74
|
headers,
|
44
75
|
body: JSON.stringify(jsonLd),
|
45
76
|
});
|
46
|
-
|
77
|
+
let requestSigned = false;
|
78
|
+
for (const { privateKey, keyId } of keys) {
|
79
|
+
if (privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
80
|
+
request = await signRequest(request, privateKey, keyId);
|
81
|
+
requestSigned = true;
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
if (!requestSigned) {
|
86
|
+
logger.warn("No supported key found to sign the request to {inbox}. " +
|
87
|
+
"The request will be sent without a signature. " +
|
88
|
+
"In order to sign the request, at least one RSASSA-PKCS1-v1_5 key " +
|
89
|
+
"must be provided.", {
|
90
|
+
inbox: inbox.href,
|
91
|
+
keys: keys.map((pair) => ({
|
92
|
+
keyId: pair.keyId.href,
|
93
|
+
privateKey: pair.privateKey,
|
94
|
+
})),
|
95
|
+
});
|
96
|
+
}
|
47
97
|
const response = await fetch(request);
|
48
98
|
if (!response.ok) {
|
49
99
|
let error;
|
@@ -55,13 +105,13 @@ export async function sendActivity({ activity, privateKey, keyId, inbox, context
|
|
55
105
|
}
|
56
106
|
logger.error("Failed to send activity {activityId} to {inbox} ({status} " +
|
57
107
|
"{statusText}):\n{error}", {
|
58
|
-
activityId
|
108
|
+
activityId,
|
59
109
|
inbox: inbox.href,
|
60
110
|
status: response.status,
|
61
111
|
statusText: response.statusText,
|
62
112
|
error,
|
63
113
|
});
|
64
|
-
throw new Error(`Failed to send activity ${
|
114
|
+
throw new Error(`Failed to send activity ${activityId} to ${inbox.href} ` +
|
65
115
|
`(${response.status} ${response.statusText}):\n${error}`);
|
66
116
|
}
|
67
117
|
}
|
package/esm/sig/proof.js
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
2
|
+
// @ts-ignore: json-canon is not typed
|
3
|
+
import serialize from "json-canon";
|
4
|
+
import { DataIntegrityProof } from "../vocab/vocab.js";
|
5
|
+
import { fetchKey, validateCryptoKey } from "./key.js";
|
6
|
+
import { Activity, Multikey } from "../vocab/mod.js";
|
7
|
+
import { getLogger } from "@logtape/logtape";
|
8
|
+
const logger = getLogger(["fedify", "sig", "proof"]);
|
9
|
+
/**
|
10
|
+
* Creates a proof for the given object.
|
11
|
+
* @param object The object to create a proof for.
|
12
|
+
* @param privateKey The private key to sign the proof with.
|
13
|
+
* @param keyId The key ID to use in the proof. It will be used by the verifier.
|
14
|
+
* @param options Additional options. See also {@link CreateProofOptions}.
|
15
|
+
* @returns The created proof.
|
16
|
+
* @throws {TypeError} If the private key is invalid or unsupported.
|
17
|
+
* @since 0.10.0
|
18
|
+
*/
|
19
|
+
export async function createProof(object, privateKey, keyId, { contextLoader, context, created } = {}) {
|
20
|
+
validateCryptoKey(privateKey, "private");
|
21
|
+
if (privateKey.algorithm.name !== "Ed25519") {
|
22
|
+
throw new TypeError("Unsupported algorithm: " + privateKey.algorithm.name);
|
23
|
+
}
|
24
|
+
const objectWithoutProofs = object.clone({ proofs: [] });
|
25
|
+
const compactMsg = await objectWithoutProofs.toJsonLd({
|
26
|
+
contextLoader,
|
27
|
+
context,
|
28
|
+
});
|
29
|
+
const msgCanon = serialize(compactMsg);
|
30
|
+
const encoder = new TextEncoder();
|
31
|
+
const msgBytes = encoder.encode(msgCanon);
|
32
|
+
const msgDigest = await dntShim.crypto.subtle.digest("SHA-256", msgBytes);
|
33
|
+
created ??= dntShim.Temporal.Now.instant();
|
34
|
+
const proofConfig = {
|
35
|
+
// The below commented out line is needed according to section 3.3.1 of
|
36
|
+
// the Data Integrity EdDSA Cryptosuites v1.0 spec, the FEP-8b32 spec does
|
37
|
+
// not reflect this step; however, the FEP-8b32 spec will be updated to
|
38
|
+
// be consistent with the Data Integrity EdDSA Cryptosuites v1.0 spec
|
39
|
+
// some time soon. Before that happens, the below line is commented out.
|
40
|
+
// See also: https://socialhub.activitypub.rocks/t/fep-8b32-object-integrity-proofs/2725/91?u=hongminhee
|
41
|
+
// "@context": (compactMsg as any)["@context"],
|
42
|
+
type: "DataIntegrityProof",
|
43
|
+
cryptosuite: "eddsa-jcs-2022",
|
44
|
+
verificationMethod: keyId.href,
|
45
|
+
proofPurpose: "assertionMethod",
|
46
|
+
created: created.toString(),
|
47
|
+
};
|
48
|
+
const proofCanon = serialize(proofConfig);
|
49
|
+
const proofBytes = encoder.encode(proofCanon);
|
50
|
+
const proofDigest = await dntShim.crypto.subtle.digest("SHA-256", proofBytes);
|
51
|
+
const digest = new Uint8Array(proofDigest.byteLength + msgDigest.byteLength);
|
52
|
+
digest.set(new Uint8Array(proofDigest), 0);
|
53
|
+
digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
|
54
|
+
const sig = await dntShim.crypto.subtle.sign("Ed25519", privateKey, digest);
|
55
|
+
return new DataIntegrityProof({
|
56
|
+
cryptosuite: "eddsa-jcs-2022",
|
57
|
+
verificationMethod: keyId,
|
58
|
+
proofPurpose: "assertionMethod",
|
59
|
+
created: created ?? dntShim.Temporal.Now.instant(),
|
60
|
+
proofValue: new Uint8Array(sig),
|
61
|
+
});
|
62
|
+
}
|
63
|
+
/**
|
64
|
+
* Signs the given object with the private key and returns the signed object.
|
65
|
+
* @param object The object to create a proof for.
|
66
|
+
* @param privateKey The private key to sign the proof with.
|
67
|
+
* @param keyId The key ID to use in the proof. It will be used by the verifier.
|
68
|
+
* @param options Additional options. See also {@link SignObjectOptions}.
|
69
|
+
* @returns The signed object.
|
70
|
+
* @throws {TypeError} If the private key is invalid or unsupported.
|
71
|
+
* @since 0.10.0
|
72
|
+
*/
|
73
|
+
export async function signObject(object, privateKey, keyId, options = {}) {
|
74
|
+
const existingProofs = [];
|
75
|
+
for await (const proof of object.getProofs(options)) {
|
76
|
+
existingProofs.push(proof);
|
77
|
+
}
|
78
|
+
const proof = await createProof(object, privateKey, keyId, options);
|
79
|
+
return object.clone({ proofs: [...existingProofs, proof] });
|
80
|
+
}
|
81
|
+
/**
|
82
|
+
* Verifies the given proof for the object.
|
83
|
+
* @param jsonLd The JSON-LD object to verify the proof for. If it contains
|
84
|
+
* any proofs, they will be ignored.
|
85
|
+
* @param proof The proof to verify.
|
86
|
+
* @param options Additional options. See also {@link VerifyProofOptions}.
|
87
|
+
* @returns The public key that was used to sign the proof, or `null` if the
|
88
|
+
* proof is invalid.
|
89
|
+
* @since 0.10.0
|
90
|
+
*/
|
91
|
+
export async function verifyProof(jsonLd, proof, options = {}) {
|
92
|
+
if (typeof jsonLd !== "object" ||
|
93
|
+
proof.cryptosuite !== "eddsa-jcs-2022" ||
|
94
|
+
proof.verificationMethodId == null ||
|
95
|
+
proof.proofPurpose !== "assertionMethod" ||
|
96
|
+
proof.proofValue == null ||
|
97
|
+
proof.created == null)
|
98
|
+
return null;
|
99
|
+
const publicKeyPromise = fetchKey(proof.verificationMethodId, Multikey, options);
|
100
|
+
const proofConfig = {
|
101
|
+
// The below commented out line is needed according to section 3.3.1 of
|
102
|
+
// the Data Integrity EdDSA Cryptosuites v1.0 spec, the FEP-8b32 spec does
|
103
|
+
// not reflect this step; however, the FEP-8b32 spec will be updated to
|
104
|
+
// be consistent with the Data Integrity EdDSA Cryptosuites v1.0 spec
|
105
|
+
// some time soon. Before that happens, the below line is commented out.
|
106
|
+
// See also: https://socialhub.activitypub.rocks/t/fep-8b32-object-integrity-proofs/2725/91?u=hongminhee
|
107
|
+
// "@context": (jsonLd as any)["@context"],
|
108
|
+
type: "DataIntegrityProof",
|
109
|
+
cryptosuite: proof.cryptosuite,
|
110
|
+
verificationMethod: proof.verificationMethodId.href,
|
111
|
+
proofPurpose: proof.proofPurpose,
|
112
|
+
created: proof.created.toString(),
|
113
|
+
};
|
114
|
+
const proofCanon = serialize(proofConfig);
|
115
|
+
const encoder = new TextEncoder();
|
116
|
+
const proofBytes = encoder.encode(proofCanon);
|
117
|
+
const proofDigest = await dntShim.crypto.subtle.digest("SHA-256", proofBytes);
|
118
|
+
const msg = { ...jsonLd };
|
119
|
+
if ("proof" in msg)
|
120
|
+
delete msg.proof;
|
121
|
+
const msgCanon = serialize(msg);
|
122
|
+
const msgBytes = encoder.encode(msgCanon);
|
123
|
+
const msgDigest = await dntShim.crypto.subtle.digest("SHA-256", msgBytes);
|
124
|
+
const digest = new Uint8Array(proofDigest.byteLength + msgDigest.byteLength);
|
125
|
+
digest.set(new Uint8Array(proofDigest), 0);
|
126
|
+
digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
|
127
|
+
let publicKey;
|
128
|
+
try {
|
129
|
+
publicKey = await publicKeyPromise;
|
130
|
+
}
|
131
|
+
catch (error) {
|
132
|
+
logger.debug("Failed to get the key (verificationMethod) for the proof:\n{proof}", { proof, error });
|
133
|
+
return null;
|
134
|
+
}
|
135
|
+
if (publicKey == null || publicKey.publicKey.algorithm.name !== "Ed25519") {
|
136
|
+
logger.debug("The key (verificationMethod) for the proof is not a valid Ed25519 " +
|
137
|
+
"key:\n{keyId}", { proof, keyId: proof.verificationMethodId.href });
|
138
|
+
return null;
|
139
|
+
}
|
140
|
+
const verified = await dntShim.crypto.subtle.verify("Ed25519", publicKey.publicKey, proof.proofValue, digest);
|
141
|
+
if (!verified) {
|
142
|
+
logger.debug("The proof's signature is invalid.", { proof });
|
143
|
+
return null;
|
144
|
+
}
|
145
|
+
return publicKey;
|
146
|
+
}
|
147
|
+
/**
|
148
|
+
* Verifies the given object. It will verify all the proofs in the object,
|
149
|
+
* and succeed only if all the proofs are valid and all attributions and
|
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}.
|
154
|
+
* @param jsonLd The JSON-LD object to verify. It's assumed that the object
|
155
|
+
* is a compacted JSON-LD representation of a `T` with `@context`.
|
156
|
+
* @param options Additional options. See also {@link VerifyObjectOptions}.
|
157
|
+
* @returns The object if it's verified, or `null` if it's not.
|
158
|
+
* @throws {TypeError} If the object is invalid or unsupported.
|
159
|
+
* @since 0.10.0
|
160
|
+
*/
|
161
|
+
export async function verifyObject(
|
162
|
+
// deno-lint-ignore no-explicit-any
|
163
|
+
cls, jsonLd, options = {}) {
|
164
|
+
const logger = getLogger(["fedify", "sig", "proof"]);
|
165
|
+
const object = await cls.fromJsonLd(jsonLd, options);
|
166
|
+
const attributions = new Set(object.attributionIds.map((uri) => uri.href));
|
167
|
+
if (object instanceof Activity) {
|
168
|
+
for (const uri of object.actorIds)
|
169
|
+
attributions.add(uri.href);
|
170
|
+
}
|
171
|
+
for await (const proof of object.getProofs(options)) {
|
172
|
+
const key = await verifyProof(jsonLd, proof, options);
|
173
|
+
if (key === null)
|
174
|
+
return null;
|
175
|
+
if (key.controllerId == null) {
|
176
|
+
logger.debug("Key {keyId} does not have a controller.", { keyId: key.id?.href });
|
177
|
+
continue;
|
178
|
+
}
|
179
|
+
attributions.delete(key.controllerId.href);
|
180
|
+
}
|
181
|
+
if (attributions.size > 0) {
|
182
|
+
logger.debug("Some attributions are not authenticated by the proofs: {attributions}.", { attributions: [...attributions] });
|
183
|
+
return null;
|
184
|
+
}
|
185
|
+
return object;
|
186
|
+
}
|
package/esm/webfinger/handler.js
CHANGED
@@ -7,10 +7,8 @@ import { Link as LinkObject } from "../vocab/mod.js";
|
|
7
7
|
* @returns The response to the request.
|
8
8
|
*/
|
9
9
|
export async function handleWebFinger(request, { context, actorDispatcher, onNotFound, }) {
|
10
|
-
if (actorDispatcher == null)
|
11
|
-
|
12
|
-
return response instanceof Promise ? await response : response;
|
13
|
-
}
|
10
|
+
if (actorDispatcher == null)
|
11
|
+
return await onNotFound(request);
|
14
12
|
const resource = context.url.searchParams.get("resource");
|
15
13
|
if (resource == null) {
|
16
14
|
return new Response("Missing resource parameter.", { status: 400 });
|
@@ -30,20 +28,16 @@ export async function handleWebFinger(request, { context, actorDispatcher, onNot
|
|
30
28
|
if (uriParsed?.type != "actor") {
|
31
29
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
32
30
|
if (match == null || match[2] != context.url.host) {
|
33
|
-
|
34
|
-
return response instanceof Promise ? await response : response;
|
31
|
+
return await onNotFound(request);
|
35
32
|
}
|
36
33
|
handle = match[1];
|
37
34
|
}
|
38
35
|
else {
|
39
36
|
handle = uriParsed.handle;
|
40
37
|
}
|
41
|
-
const
|
42
|
-
|
43
|
-
|
44
|
-
const response = onNotFound(request);
|
45
|
-
return response instanceof Promise ? await response : response;
|
46
|
-
}
|
38
|
+
const actor = await context.getActor(handle);
|
39
|
+
if (actor == null)
|
40
|
+
return await onNotFound(request);
|
47
41
|
const links = [
|
48
42
|
{
|
49
43
|
rel: "self",
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fedify/fedify",
|
3
|
-
"version": "0.10.0-dev.
|
3
|
+
"version": "0.10.0-dev.204+89278560",
|
4
4
|
"description": "An ActivityPub server framework",
|
5
5
|
"keywords": [
|
6
6
|
"ActivityPub",
|
@@ -85,6 +85,7 @@
|
|
85
85
|
"@logtape/logtape": "^0.4.0",
|
86
86
|
"@phensley/language-tag": "^1.8.0",
|
87
87
|
"asn1js": "^3.0.5",
|
88
|
+
"json-canon": "^1.0.1",
|
88
89
|
"jsonld": "^8.3.2",
|
89
90
|
"multibase": "^4.0.6",
|
90
91
|
"multicodec": "^3.2.1",
|
@@ -100,8 +101,7 @@
|
|
100
101
|
"@types/node": "^20.9.0",
|
101
102
|
"picocolors": "^1.0.0",
|
102
103
|
"@cfworker/json-schema": "^1.12.8",
|
103
|
-
"fast-check": "^3.18.0"
|
104
|
-
"json-canon": "^1.0.1"
|
104
|
+
"fast-check": "^3.18.0"
|
105
105
|
},
|
106
106
|
"_generatedBy": "dnt@dev"
|
107
107
|
}
|
@@ -4,6 +4,7 @@ import * as dntShim from "../_dnt.shims.js";
|
|
4
4
|
import type { DocumentLoader } from "../runtime/docloader.js";
|
5
5
|
import type { Actor, Recipient } from "../vocab/actor.js";
|
6
6
|
import type { Activity, CryptographicKey, Multikey, Object } from "../vocab/mod.js";
|
7
|
+
import type { SenderKeyPair } from "./send.js";
|
7
8
|
/**
|
8
9
|
* A context.
|
9
10
|
*/
|
@@ -138,15 +139,12 @@ export interface Context<TContextData> {
|
|
138
139
|
}): DocumentLoader;
|
139
140
|
/**
|
140
141
|
* Sends an activity to recipients' inboxes.
|
141
|
-
* @param sender The sender's handle or the sender's key pair.
|
142
|
+
* @param sender The sender's handle or the sender's key pair(s).
|
142
143
|
* @param recipients The recipients of the activity.
|
143
144
|
* @param activity The activity to send.
|
144
145
|
* @param options Options for sending the activity.
|
145
146
|
*/
|
146
|
-
sendActivity(sender: {
|
147
|
-
keyId: URL;
|
148
|
-
privateKey: dntShim.CryptoKey;
|
149
|
-
} | {
|
147
|
+
sendActivity(sender: SenderKeyPair | SenderKeyPair[] | {
|
150
148
|
handle: string;
|
151
149
|
}, recipients: Recipient | Recipient[], activity: Activity, options?: SendActivityOptions): Promise<void>;
|
152
150
|
}
|
@@ -212,15 +210,12 @@ export interface RequestContext<TContextData> extends Context<TContextData> {
|
|
212
210
|
getSignedKeyOwner(): Promise<Actor | null>;
|
213
211
|
/**
|
214
212
|
* Sends an activity to recipients' inboxes.
|
215
|
-
* @param sender The sender's handle or the sender's key pair.
|
213
|
+
* @param sender The sender's handle or the sender's key pair(s).
|
216
214
|
* @param recipients The recipients of the activity.
|
217
215
|
* @param activity The activity to send.
|
218
216
|
* @param options Options for sending the activity.
|
219
217
|
*/
|
220
|
-
sendActivity(sender: {
|
221
|
-
keyId: URL;
|
222
|
-
privateKey: dntShim.CryptoKey;
|
223
|
-
} | {
|
218
|
+
sendActivity(sender: SenderKeyPair | SenderKeyPair[] | {
|
224
219
|
handle: string;
|
225
220
|
}, recipients: Recipient | Recipient[], activity: Activity, options?: SendActivityOptions): Promise<void>;
|
226
221
|
/**
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/federation/context.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,QAAQ,EACR,MAAM,EACP,MAAM,iBAAiB,CAAC;
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/federation/context.ts"],"names":[],"mappings":"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"}
|
@@ -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":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAM5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,QAAQ,EAER,IAAI,EACJ,MAAM,EAGP,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CASvD;AAED,MAAM,WAAW,sBAAsB,CAAC,YAAY;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAChD,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACtD,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/D,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACjE;AAED,wBAAsB,WAAW,CAAC,YAAY,EAC5C,OAAO,EAAE,OAAO,EAChB,EACE,MAAM,EACN,OAAO,EACP,eAAe,EACf,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,cAAc,GACf,EAAE,sBAAsB,CAAC,YAAY,CAAC,GACtC,OAAO,CAAC,QAAQ,CAAC,CAmBnB;AAED,MAAM,WAAW,uBAAuB,CAAC,YAAY;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IACtC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClE,kBAAkB,CAAC,EAAE,wBAAwB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACpE,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/D,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACjE;AAED,wBAAsB,YAAY,CAAC,YAAY,EAC7C,OAAO,EAAE,OAAO,EAChB,EACE,MAAM,EACN,OAAO,EACP,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,cAAc,GACf,EAAE,uBAAuB,CAAC,YAAY,CAAC,GACvC,OAAO,CAAC,QAAQ,CAAC,CAmBnB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO;IAC/D;;OAEG;IACH,UAAU,EAAE,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAE/D;;OAEG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEnD;;OAEG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEtD;;OAEG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAErD;;OAEG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,2BAA2B,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IACtC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACxE,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/D,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACjE;AAED,wBAAsB,gBAAgB,CACpC,KAAK,SAAS,GAAG,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EAC7C,YAAY,EACZ,OAAO,EAEP,OAAO,EAAE,OAAO,EAChB,EACE,IAAI,EACJ,MAAM,EACN,MAAM,EACN,eAAe,EACf,OAAO,EACP,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,eAAe,GAChB,EAAE,2BAA2B,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,GAC3D,OAAO,CAAC,QAAQ,CAAC,CA4FnB;AA+BD,MAAM,WAAW,sBAAsB,CAAC,YAAY;IAClD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,KAAK,CAAC;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAChD,cAAc,EAAE,GAAG,CACjB,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,QAAQ,EACpC,aAAa,CAAC,YAAY,EAAE,QAAQ,CAAC,CACtC,CAAC;IACF,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IACpD,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,mBAAmB,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;CACpD;AAED,wBAAsB,WAAW,CAAC,YAAY,EAC5C,OAAO,EAAE,OAAO,EAChB,EACE,MAAM,EACN,OAAO,EACP,EAAE,EACF,QAAQ,EACR,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,mBAAmB,GACpB,EAAE,sBAAsB,CAAC,YAAY,CAAC,GACtC,OAAO,CAAC,QAAQ,CAAC,CA0InB;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,aAAa,EAAE,cAAc,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,QAAQ,CAAC,CAOnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAK1B"}
|
@@ -8,6 +8,7 @@ import type { ActorDispatcher, ActorKeyPairDispatcher, ActorKeyPairsDispatcher,
|
|
8
8
|
import type { Context, RequestContext, SendActivityOptions } from "./context.js";
|
9
9
|
import type { KvKey, KvStore } from "./kv.js";
|
10
10
|
import type { MessageQueue } from "./mq.js";
|
11
|
+
import { type SenderKeyPair } from "./send.js";
|
11
12
|
/**
|
12
13
|
* Parameters for initializing a {@link Federation} instance.
|
13
14
|
*/
|
@@ -346,16 +347,13 @@ export declare class Federation<TContextData> {
|
|
346
347
|
* Sends an activity to recipients' inboxes. You would typically use
|
347
348
|
* {@link Context.sendActivity} instead of this method.
|
348
349
|
*
|
349
|
-
* @param
|
350
|
+
* @param keys The sender's key pairs.
|
350
351
|
* @param recipients The recipients of the activity.
|
351
352
|
* @param activity The activity to send.
|
352
353
|
* @param options Options for sending the activity.
|
353
354
|
* @throws {TypeError} If the activity to send does not have an actor.
|
354
355
|
*/
|
355
|
-
sendActivity({
|
356
|
-
keyId: URL;
|
357
|
-
privateKey: dntShim.CryptoKey;
|
358
|
-
}, recipients: Recipient | Recipient[], activity: Activity, { preferSharedInbox, immediate, excludeBaseUris, collectionSync }?: SendActivityInternalOptions): Promise<void>;
|
356
|
+
sendActivity(keys: SenderKeyPair[], recipients: Recipient | Recipient[], activity: Activity, { preferSharedInbox, immediate, excludeBaseUris, collectionSync }?: SendActivityInternalOptions): Promise<void>;
|
359
357
|
/**
|
360
358
|
* Handles a request related to federation. If a request is not related to
|
361
359
|
* federation, the `onNotFound` or `onNotAcceptable` callback is called.
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/federation/middleware.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAM5C,OAAO,EACL,KAAK,kCAAkC,EACvC,KAAK,cAAc,EAIpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EACL,QAAQ,EAGR,KAAK,MAAM,EACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EACV,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAEV,OAAO,EAEP,cAAc,EACd,mBAAmB,EACpB,MAAM,cAAc,CAAC;AAQtB,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/federation/middleware.ts"],"names":[],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/federation/mod.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,cAAc,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC"}
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/federation/mod.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,cAAc,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC"}
|
@@ -1,8 +1,11 @@
|
|
1
1
|
import * as dntShim from "../_dnt.shims.js";
|
2
|
-
export interface
|
3
|
-
type: "outbox";
|
2
|
+
export interface SenderKeyJwkPair {
|
4
3
|
keyId: string;
|
5
4
|
privateKey: dntShim.JsonWebKey;
|
5
|
+
}
|
6
|
+
export interface OutboxMessage {
|
7
|
+
type: "outbox";
|
8
|
+
keys: SenderKeyJwkPair[];
|
6
9
|
activity: unknown;
|
7
10
|
inbox: string;
|
8
11
|
trial: number;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/federation/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,MAAM,WAAW,
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/federation/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC"}
|
@@ -35,13 +35,10 @@ export interface ExtractInboxesParameters {
|
|
35
35
|
*/
|
36
36
|
export declare function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }: ExtractInboxesParameters): Record<string, Set<string>>;
|
37
37
|
/**
|
38
|
-
*
|
38
|
+
* A key pair for an actor who sends an activity.
|
39
|
+
* @since 0.10.0
|
39
40
|
*/
|
40
|
-
export interface
|
41
|
-
/**
|
42
|
-
* The activity to send.
|
43
|
-
*/
|
44
|
-
activity: Activity;
|
41
|
+
export interface SenderKeyPair {
|
45
42
|
/**
|
46
43
|
* The actor's private key to sign the request.
|
47
44
|
*/
|
@@ -50,6 +47,20 @@ export interface SendActivityParameters {
|
|
50
47
|
* The public key ID that corresponds to the private key.
|
51
48
|
*/
|
52
49
|
keyId: URL;
|
50
|
+
}
|
51
|
+
/**
|
52
|
+
* Parameters for {@link sendActivity}.
|
53
|
+
*/
|
54
|
+
export interface SendActivityParameters {
|
55
|
+
/**
|
56
|
+
* The activity to send.
|
57
|
+
*/
|
58
|
+
activity: Activity;
|
59
|
+
/**
|
60
|
+
* The key pairs of the sender to sign the request. It must not be empty.
|
61
|
+
* @since 0.10.0
|
62
|
+
*/
|
63
|
+
keys: SenderKeyPair[];
|
53
64
|
/**
|
54
65
|
* The inbox URL to send the activity to.
|
55
66
|
*/
|
@@ -59,6 +70,11 @@ export interface SendActivityParameters {
|
|
59
70
|
* @since 0.8.0
|
60
71
|
*/
|
61
72
|
contextLoader?: DocumentLoader;
|
73
|
+
/**
|
74
|
+
* The document loader for loading remote JSON-LD documents.
|
75
|
+
* @since 0.10.0
|
76
|
+
*/
|
77
|
+
documentLoader?: DocumentLoader;
|
62
78
|
/**
|
63
79
|
* Additional headers to include in the request.
|
64
80
|
*/
|
@@ -71,5 +87,5 @@ export interface SendActivityParameters {
|
|
71
87
|
* See also {@link SendActivityParameters}.
|
72
88
|
* @throws {Error} If the activity fails to send.
|
73
89
|
*/
|
74
|
-
export declare function sendActivity({ activity,
|
90
|
+
export declare function sendActivity({ activity, keys, inbox, contextLoader, documentLoader, headers, }: SendActivityParameters): Promise<void>;
|
75
91
|
//# sourceMappingURL=send.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/federation/send.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/federation/send.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,UAAU,EAAE,SAAS,EAAE,CAAC;IAExB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,EAAE,UAAU,EAAE,iBAAiB,EAAE,eAAe,EAAE,EAAE,wBAAwB,GAC3E,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAkB7B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;IAEnB;;;OAGG;IACH,IAAI,EAAE,aAAa,EAAE,CAAC;IAEtB;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC;IAEX;;;OAGG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAE/B;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,EACE,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,aAAa,EACb,cAAc,EACd,OAAO,GACR,EAAE,sBAAsB,GACxB,OAAO,CAAC,IAAI,CAAC,CA6Ff"}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
import * as dntShim from "../_dnt.shims.js";
|
3
|
+
import type { DocumentLoader } from "../runtime/docloader.js";
|
4
|
+
import { DataIntegrityProof, type Object } from "../vocab/vocab.js";
|
5
|
+
import { Multikey } from "../vocab/mod.js";
|
6
|
+
/**
|
7
|
+
* Options for {@link createProof}.
|
8
|
+
* @since 0.10.0
|
9
|
+
*/
|
10
|
+
export interface CreateProofOptions {
|
11
|
+
/**
|
12
|
+
* The context loader for loading remote JSON-LD contexts.
|
13
|
+
*/
|
14
|
+
contextLoader?: DocumentLoader;
|
15
|
+
/**
|
16
|
+
* The JSON-LD context to use for serializing the object to sign.
|
17
|
+
*/
|
18
|
+
context?: string | Record<string, string> | (string | Record<string, string>)[];
|
19
|
+
/**
|
20
|
+
* The time when the proof was created. If not specified, the current time
|
21
|
+
* will be used.
|
22
|
+
*/
|
23
|
+
created?: dntShim.Temporal.Instant;
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* Creates a proof for the given object.
|
27
|
+
* @param object The object to create a proof for.
|
28
|
+
* @param privateKey The private key to sign the proof with.
|
29
|
+
* @param keyId The key ID to use in the proof. It will be used by the verifier.
|
30
|
+
* @param options Additional options. See also {@link CreateProofOptions}.
|
31
|
+
* @returns The created proof.
|
32
|
+
* @throws {TypeError} If the private key is invalid or unsupported.
|
33
|
+
* @since 0.10.0
|
34
|
+
*/
|
35
|
+
export declare function createProof(object: Object, privateKey: dntShim.CryptoKey, keyId: URL, { contextLoader, context, created }?: CreateProofOptions): Promise<DataIntegrityProof>;
|
36
|
+
/**
|
37
|
+
* Options for {@link signObject}.
|
38
|
+
* @since 0.10.0
|
39
|
+
*/
|
40
|
+
export interface SignObjectOptions extends CreateProofOptions {
|
41
|
+
/**
|
42
|
+
* The document loader for loading remote JSON-LD documents.
|
43
|
+
*/
|
44
|
+
documentLoader?: DocumentLoader;
|
45
|
+
}
|
46
|
+
/**
|
47
|
+
* Signs the given object with the private key and returns the signed object.
|
48
|
+
* @param object The object to create a proof for.
|
49
|
+
* @param privateKey The private key to sign the proof with.
|
50
|
+
* @param keyId The key ID to use in the proof. It will be used by the verifier.
|
51
|
+
* @param options Additional options. See also {@link SignObjectOptions}.
|
52
|
+
* @returns The signed object.
|
53
|
+
* @throws {TypeError} If the private key is invalid or unsupported.
|
54
|
+
* @since 0.10.0
|
55
|
+
*/
|
56
|
+
export declare function signObject<T extends Object>(object: T, privateKey: dntShim.CryptoKey, keyId: URL, options?: SignObjectOptions): Promise<T>;
|
57
|
+
/**
|
58
|
+
* Options for {@link verifyProof}.
|
59
|
+
* @since 0.10.0
|
60
|
+
*/
|
61
|
+
export interface VerifyProofOptions {
|
62
|
+
/**
|
63
|
+
* The context loader for loading remote JSON-LD contexts.
|
64
|
+
*/
|
65
|
+
contextLoader?: DocumentLoader;
|
66
|
+
/**
|
67
|
+
* The document loader for loading remote JSON-LD documents.
|
68
|
+
*/
|
69
|
+
documentLoader?: DocumentLoader;
|
70
|
+
}
|
71
|
+
/**
|
72
|
+
* Verifies the given proof for the object.
|
73
|
+
* @param jsonLd The JSON-LD object to verify the proof for. If it contains
|
74
|
+
* any proofs, they will be ignored.
|
75
|
+
* @param proof The proof to verify.
|
76
|
+
* @param options Additional options. See also {@link VerifyProofOptions}.
|
77
|
+
* @returns The public key that was used to sign the proof, or `null` if the
|
78
|
+
* proof is invalid.
|
79
|
+
* @since 0.10.0
|
80
|
+
*/
|
81
|
+
export declare function verifyProof(jsonLd: unknown, proof: DataIntegrityProof, options?: VerifyProofOptions): Promise<Multikey | null>;
|
82
|
+
/**
|
83
|
+
* Options for {@link verifyObject}.
|
84
|
+
* @since 0.10.0
|
85
|
+
*/
|
86
|
+
export interface VerifyObjectOptions extends VerifyProofOptions {
|
87
|
+
}
|
88
|
+
/**
|
89
|
+
* Verifies the given object. It will verify all the proofs in the object,
|
90
|
+
* and succeed only if all the proofs are valid and all attributions and
|
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}.
|
95
|
+
* @param jsonLd The JSON-LD object to verify. It's assumed that the object
|
96
|
+
* is a compacted JSON-LD representation of a `T` with `@context`.
|
97
|
+
* @param options Additional options. See also {@link VerifyObjectOptions}.
|
98
|
+
* @returns The object if it's verified, or `null` if it's not.
|
99
|
+
* @throws {TypeError} If the object is invalid or unsupported.
|
100
|
+
* @since 0.10.0
|
101
|
+
*/
|
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>;
|
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,
|
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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/webfinger/handler.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D;;GAEG;AACH,MAAM,WAAW,0BAA0B,CAAC,YAAY;IACtD;;OAEG;IACH,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IAEtC;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAEhD;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC5D;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAChD,OAAO,EAAE,OAAO,EAChB,EACE,OAAO,EACP,eAAe,EACf,UAAU,GACX,EAAE,0BAA0B,CAAC,YAAY,CAAC,GAC1C,OAAO,CAAC,QAAQ,CAAC,
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/webfinger/handler.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D;;GAEG;AACH,MAAM,WAAW,0BAA0B,CAAC,YAAY;IACtD;;OAEG;IACH,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IAEtC;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAEhD;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC5D;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAChD,OAAO,EAAE,OAAO,EAChB,EACE,OAAO,EACP,eAAe,EACf,UAAU,GACX,EAAE,0BAA0B,CAAC,YAAY,CAAC,GAC1C,OAAO,CAAC,QAAQ,CAAC,CA4DnB"}
|