@fedify/fedify 2.4.0-dev.2253 → 2.4.0-dev.2259
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/dist/{builder-DdUWFCwL.mjs → builder-CBNa1Uw2.mjs} +8 -2
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-CcWDD5VB.mjs → compound-proof-CMPv4UK0.mjs} +20 -3
- package/dist/{context-CtI307_A.d.ts → context-7NyiqIcg.d.ts} +111 -2
- package/dist/{context-B6X-t8gI.d.cts → context-tsYPJ2Ew.d.cts} +111 -2
- package/dist/{deno-D9uhdIuD.mjs → deno-C8XaXmPB.mjs} +1 -1
- package/dist/{docloader-fbmPhCdS.mjs → docloader-CpdFLwAg.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +76 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox-report.test.d.mts +2 -0
- package/dist/federation/inbox-report.test.mjs +475 -0
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +7 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +4 -3
- package/dist/federation/mod.d.ts +4 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +5 -5
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +4 -4
- package/dist/federation/portable-delivery.test.mjs +2 -2
- package/dist/federation/portable-gateway-keys.test.mjs +4 -4
- package/dist/federation/portable-inbox.test.mjs +67 -6
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-B858-Ylk.cjs → federation-D6giSGUT.cjs} +524 -118
- package/dist/{http-CUyBaVsQ.mjs → http-BqSbUEiQ.mjs} +141 -98
- package/dist/{http-Bp0MKAK3.cjs → http-Cki-npuA.cjs} +456 -116
- package/dist/{http-BoGE-nk7.js → http-OMtKlbx1.js} +439 -117
- package/dist/{http-DGx0KOws.d.ts → key-C1nv7_jD.d.ts} +638 -229
- package/dist/{http-BrwKINQn.d.cts → key-DYxuyd-s.d.cts} +638 -229
- package/dist/{key-BlTaKABr.mjs → key-DecAtABm.mjs} +30 -3
- package/dist/{kv-cache-Dmqd7s2a.mjs → kv-cache-CWWlMv-s.mjs} +1 -1
- package/dist/{kv-cache-BnWemxH2.cjs → kv-cache-D73yVcE5.cjs} +1 -1
- package/dist/{kv-cache-DhMzUXEE.js → kv-cache-J0v3UbUn.js} +1 -1
- package/dist/{ld-Dx8r_qJU.mjs → ld-UsN-TIPh.mjs} +40 -5
- package/dist/{metrics-DFkZkLrO.mjs → metrics-DWCn4VXX.mjs} +2 -1
- package/dist/{middleware-DC018B4u.js → middleware-BqzfIlUO.js} +524 -118
- package/dist/{middleware-B0RRI88k.mjs → middleware-CkjwiEBd.mjs} +512 -127
- package/dist/{middleware-BNhF-Ayx.mjs → middleware-DHn2q0L1.mjs} +1 -1
- package/dist/{mod-C7_2j7VT.d.cts → mod-BojP2Bw3.d.cts} +1 -1
- package/dist/{mod-Cy9VNHVw.d.ts → mod-CavhAgLw.d.cts} +5 -253
- package/dist/{mod-DoTWIc7F.d.cts → mod-CtpF2BU5.d.ts} +5 -253
- package/dist/{mod-B8MI1mpi.d.ts → mod-DEZXwV6J.d.ts} +1 -1
- package/dist/{mod-DFL6IxYQ.d.cts → mod-Dw-nPxQh.d.cts} +1 -1
- package/dist/{mod-BhTaDR5H.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +7 -7
- package/dist/mod.d.ts +7 -7
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-B61jjp5K.mjs → owner-CEBn81LD.mjs} +3 -3
- package/dist/{portable-collection-DhEA_nWT.cjs → portable-collection-DqTUBKY7.cjs} +1 -1
- package/dist/{portable-collection-BnktjQ04.js → portable-collection-ZkUNjtb7.js} +1 -1
- package/dist/{portable-collection-CyBJDEzs.mjs → portable-collection-qFSYw4TG.mjs} +2 -2
- package/dist/{portable-key-CPN0QZSA.mjs → portable-key-LlMkP-vz.mjs} +1 -1
- package/dist/{proof-CZrjvoJ3.mjs → proof-BHRf_jMG.mjs} +142 -22
- package/dist/{send-enxOnmZo.mjs → send-DjG8DDU_.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +19 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mitra-receive-interop.test.d.mts +2 -0
- package/dist/sig/mitra-receive-interop.test.mjs +260 -0
- package/dist/sig/mitra-send-interop.test.d.mts +2 -0
- package/dist/sig/mitra-send-interop.test.mjs +461 -0
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-interop.test.d.mts +2 -0
- package/dist/sig/portable-interop.test.mjs +156 -0
- package/dist/sig/portable-key.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +161 -3
- package/dist/sig/tootik-request-interop.test.d.mts +2 -0
- package/dist/sig/tootik-request-interop.test.mjs +190 -0
- package/dist/sig/tootik-send-interop.test.d.mts +2 -0
- package/dist/sig/tootik-send-interop.test.mjs +331 -0
- package/dist/sig/verification.test.d.mts +2 -0
- package/dist/sig/verification.test.mjs +310 -0
- package/dist/{temporal-CBVv0xRB.mjs → temporal-BRFH_dte.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +315 -28
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/dist/verification-C3954hQh.mjs +5 -0
- package/dist/verification-Dpfcw8ml.mjs +105 -0
- package/package.json +6 -6
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import "temporal-polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { a as verificationObservation } from "../verification-Dpfcw8ml.mjs";
|
|
5
|
+
import { h as verifyJsonLd, p as signJsonLd } from "../ld-UsN-TIPh.mjs";
|
|
6
|
+
import { a as signObject, s as verifyObject } from "../proof-BHRf_jMG.mjs";
|
|
7
|
+
import { l as signRequest, p as verifyRequestDetailed } from "../http-BqSbUEiQ.mjs";
|
|
8
|
+
import { i as rsaPrivateKey2, n as ed25519PrivateKey, o as rsaPublicKey1, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
9
|
+
import { Activity, Create, CryptographicKey, Multikey } from "@fedify/vocab";
|
|
10
|
+
import { FetchError } from "@fedify/vocab-runtime";
|
|
11
|
+
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
12
|
+
import { deepStrictEqual, ok, strictEqual } from "node:assert/strict";
|
|
13
|
+
//#region src/sig/verification.test.ts
|
|
14
|
+
const loaders = {
|
|
15
|
+
documentLoader: mockDocumentLoader,
|
|
16
|
+
contextLoader: mockDocumentLoader
|
|
17
|
+
};
|
|
18
|
+
function observation() {
|
|
19
|
+
return { attempts: [] };
|
|
20
|
+
}
|
|
21
|
+
test("LDS evidence has no checks for absent or malformed signatures", async () => {
|
|
22
|
+
const json = await new Create({ actor: rsaPublicKey2.ownerId }).toJsonLd(loaders);
|
|
23
|
+
for (const signature of [
|
|
24
|
+
void 0,
|
|
25
|
+
null,
|
|
26
|
+
"invalid",
|
|
27
|
+
[],
|
|
28
|
+
{}
|
|
29
|
+
]) {
|
|
30
|
+
const evidence = observation();
|
|
31
|
+
strictEqual(await verifyJsonLd(signature === void 0 ? json : {
|
|
32
|
+
...json,
|
|
33
|
+
signature
|
|
34
|
+
}, {
|
|
35
|
+
...loaders,
|
|
36
|
+
[verificationObservation]: evidence
|
|
37
|
+
}), false);
|
|
38
|
+
const attempt = evidence.attempts[0];
|
|
39
|
+
ok(attempt.status === "rejected");
|
|
40
|
+
strictEqual(attempt.reason.type, signature === void 0 ? "noSignature" : "signatureVerificationFailed");
|
|
41
|
+
deepStrictEqual(attempt.checks, []);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
test("signature evidence preserves stale and fresh HTTP keys for both specs", async () => {
|
|
45
|
+
for (const spec of ["draft-cavage-http-signatures-12", "rfc9421"]) {
|
|
46
|
+
const evidence = observation();
|
|
47
|
+
const signed = await signRequest(new Request("https://example.com/inbox", {
|
|
48
|
+
method: "POST",
|
|
49
|
+
body: "{}"
|
|
50
|
+
}), rsaPrivateKey2, rsaPublicKey2.id, { spec });
|
|
51
|
+
const stale = rsaPublicKey1.clone({ id: rsaPublicKey2.id });
|
|
52
|
+
strictEqual((await verifyRequestDetailed(signed, {
|
|
53
|
+
...loaders,
|
|
54
|
+
[verificationObservation]: evidence,
|
|
55
|
+
keyCache: {
|
|
56
|
+
get: () => Promise.resolve(stale),
|
|
57
|
+
set: () => Promise.resolve()
|
|
58
|
+
}
|
|
59
|
+
})).verified, true);
|
|
60
|
+
const attempt = evidence.attempts[0];
|
|
61
|
+
ok(attempt.status === "verified");
|
|
62
|
+
strictEqual(attempt.checks.length, 1);
|
|
63
|
+
const check = attempt.checks[0];
|
|
64
|
+
ok(check.status === "verified");
|
|
65
|
+
strictEqual(check.triedKeys.length, 2);
|
|
66
|
+
strictEqual(check.triedKeys[0].publicKey, rsaPublicKey1.publicKey);
|
|
67
|
+
deepStrictEqual(await crypto.subtle.exportKey("jwk", check.triedKeys[1].publicKey), await crypto.subtle.exportKey("jwk", rsaPublicKey2.publicKey));
|
|
68
|
+
strictEqual(check.key, check.triedKeys[1]);
|
|
69
|
+
strictEqual(attempt.signatures[0], check);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
test("signature evidence retains the failed key when HTTP refresh cannot load", async () => {
|
|
73
|
+
for (const spec of ["draft-cavage-http-signatures-12", "rfc9421"]) {
|
|
74
|
+
const evidence = observation();
|
|
75
|
+
const signed = await signRequest(new Request("https://example.com/inbox", {
|
|
76
|
+
method: "POST",
|
|
77
|
+
body: "{}"
|
|
78
|
+
}), rsaPrivateKey2, rsaPublicKey2.id, { spec });
|
|
79
|
+
const response = new Response(null, { status: 410 });
|
|
80
|
+
strictEqual((await verifyRequestDetailed(signed, {
|
|
81
|
+
...loaders,
|
|
82
|
+
[verificationObservation]: evidence,
|
|
83
|
+
documentLoader: () => Promise.reject(new FetchError(rsaPublicKey2.id, "gone", response)),
|
|
84
|
+
keyCache: {
|
|
85
|
+
get: () => Promise.resolve(rsaPublicKey1.clone({ id: rsaPublicKey2.id })),
|
|
86
|
+
set: () => Promise.resolve()
|
|
87
|
+
}
|
|
88
|
+
})).verified, false);
|
|
89
|
+
const check = evidence.attempts[0].checks[0];
|
|
90
|
+
ok(check.status === "rejected");
|
|
91
|
+
strictEqual(check.reason.type, "keyFetchError");
|
|
92
|
+
strictEqual(check.triedKeys[0].publicKey, rsaPublicKey1.publicKey);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
test("signature evidence preserves failed LDS keys and successful stale-key refresh", async () => {
|
|
96
|
+
const signed = await signJsonLd(await new Create({ actor: new URL("https://example.com/person") }).toJsonLd(loaders), rsaPrivateKey2, rsaPublicKey2.id, loaders);
|
|
97
|
+
const evidence = observation();
|
|
98
|
+
strictEqual(await verifyJsonLd(signed, {
|
|
99
|
+
...loaders,
|
|
100
|
+
[verificationObservation]: evidence,
|
|
101
|
+
keyCache: {
|
|
102
|
+
get: () => Promise.resolve(rsaPublicKey1.clone({ id: rsaPublicKey2.id })),
|
|
103
|
+
set: () => Promise.resolve()
|
|
104
|
+
}
|
|
105
|
+
}), false);
|
|
106
|
+
const attempt = evidence.attempts[0];
|
|
107
|
+
ok(attempt.status === "rejected");
|
|
108
|
+
strictEqual(attempt.reason.type, "missingOwner");
|
|
109
|
+
strictEqual(attempt.checks[0].status, "verified");
|
|
110
|
+
strictEqual(attempt.checks[0].triedKeys.length, 2);
|
|
111
|
+
const bad = observation();
|
|
112
|
+
strictEqual(await verifyJsonLd(signed, {
|
|
113
|
+
...loaders,
|
|
114
|
+
[verificationObservation]: bad,
|
|
115
|
+
documentLoader: async () => ({
|
|
116
|
+
contextUrl: null,
|
|
117
|
+
documentUrl: rsaPublicKey2.id.href,
|
|
118
|
+
document: await new CryptographicKey({
|
|
119
|
+
id: rsaPublicKey2.id,
|
|
120
|
+
publicKey: rsaPublicKey1.publicKey
|
|
121
|
+
}).toJsonLd(loaders)
|
|
122
|
+
})
|
|
123
|
+
}), false);
|
|
124
|
+
strictEqual(bad.attempts[0].checks[0].status, "rejected");
|
|
125
|
+
strictEqual(bad.attempts[0].checks[0].triedKeys.length, 1);
|
|
126
|
+
});
|
|
127
|
+
test("signature evidence preserves multiple valid proofs despite uncovered attribution", async () => {
|
|
128
|
+
const second = await signObject(await signObject(new Create({ actor: new URL("https://example.com/person") }), ed25519PrivateKey, ed25519Multikey.id, loaders), ed25519PrivateKey, ed25519Multikey.id, loaders);
|
|
129
|
+
const evidence = observation();
|
|
130
|
+
strictEqual(await verifyObject(Activity, await second.toJsonLd(loaders), {
|
|
131
|
+
...loaders,
|
|
132
|
+
[verificationObservation]: evidence
|
|
133
|
+
}), null);
|
|
134
|
+
const attempt = evidence.attempts[0];
|
|
135
|
+
ok(attempt.status === "rejected");
|
|
136
|
+
strictEqual(attempt.reason.type, "uncoveredAttribution");
|
|
137
|
+
strictEqual(attempt.checks.length, 2);
|
|
138
|
+
ok(attempt.checks.every((check) => check.status === "verified"));
|
|
139
|
+
});
|
|
140
|
+
test("signature evidence preserves OIP stale keys when fresh verification fails", async () => {
|
|
141
|
+
const signed = await signObject(new Create({ actor: ed25519Multikey.controllerId }), ed25519PrivateKey, ed25519Multikey.id, loaders);
|
|
142
|
+
const pair = await crypto.subtle.generateKey("Ed25519", true, ["sign", "verify"]);
|
|
143
|
+
const stale = new Multikey({
|
|
144
|
+
id: ed25519Multikey.id,
|
|
145
|
+
controller: null,
|
|
146
|
+
publicKey: pair.publicKey
|
|
147
|
+
});
|
|
148
|
+
const evidence = observation();
|
|
149
|
+
strictEqual(await verifyObject(Activity, await signed.toJsonLd(loaders), {
|
|
150
|
+
...loaders,
|
|
151
|
+
[verificationObservation]: evidence,
|
|
152
|
+
keyCache: {
|
|
153
|
+
get: () => Promise.resolve(stale),
|
|
154
|
+
set: () => Promise.resolve()
|
|
155
|
+
},
|
|
156
|
+
documentLoader: async () => ({
|
|
157
|
+
contextUrl: null,
|
|
158
|
+
documentUrl: ed25519Multikey.id.href,
|
|
159
|
+
document: await stale.toJsonLd(loaders)
|
|
160
|
+
})
|
|
161
|
+
}), null);
|
|
162
|
+
const check = evidence.attempts[0].checks[0];
|
|
163
|
+
strictEqual(check.status, "rejected");
|
|
164
|
+
strictEqual(check.triedKeys.length, 2);
|
|
165
|
+
strictEqual(check.triedKeys[0].publicKey, pair.publicKey);
|
|
166
|
+
});
|
|
167
|
+
test("OIP check preserves the literal declared key ID", async () => {
|
|
168
|
+
const json = await (await signObject(new Create({ actor: ed25519Multikey.controllerId }), ed25519PrivateKey, ed25519Multikey.id, loaders)).toJsonLd(loaders);
|
|
169
|
+
const proof = json.proof;
|
|
170
|
+
const declaredKeyId = "https://EXAMPLE.com/person2#key4";
|
|
171
|
+
proof.verificationMethod = declaredKeyId;
|
|
172
|
+
const evidence = observation();
|
|
173
|
+
await verifyObject(Activity, json, {
|
|
174
|
+
...loaders,
|
|
175
|
+
[verificationObservation]: evidence
|
|
176
|
+
});
|
|
177
|
+
strictEqual(evidence.attempts[0].checks[0].declaredKeyId, declaredKeyId);
|
|
178
|
+
});
|
|
179
|
+
test("signature observation cannot turn a cached miss into a metadata exception", async () => {
|
|
180
|
+
const json = await signJsonLd(await new Create({ actor: new URL("https://example.com/person") }).toJsonLd(loaders), rsaPrivateKey2, rsaPublicKey2.id, loaders);
|
|
181
|
+
const evidence = observation();
|
|
182
|
+
const cache = {
|
|
183
|
+
get: () => Promise.resolve(null),
|
|
184
|
+
set: () => Promise.resolve(),
|
|
185
|
+
getFetchError: () => Promise.reject(/* @__PURE__ */ new Error("diagnostic unavailable"))
|
|
186
|
+
};
|
|
187
|
+
strictEqual(await verifyJsonLd(json, {
|
|
188
|
+
...loaders,
|
|
189
|
+
keyCache: cache,
|
|
190
|
+
[verificationObservation]: evidence
|
|
191
|
+
}), false);
|
|
192
|
+
strictEqual(evidence.attempts[0].checks[0].status, "rejected");
|
|
193
|
+
});
|
|
194
|
+
test("signature observation preserves rejection for consumed fetch-error responses", async () => {
|
|
195
|
+
const json = await signJsonLd(await new Create({ actor: new URL("https://example.com/person") }).toJsonLd(loaders), rsaPrivateKey2, rsaPublicKey2.id, loaders);
|
|
196
|
+
const response = new Response("gone", { status: 410 });
|
|
197
|
+
await response.text();
|
|
198
|
+
const error = new FetchError(rsaPublicKey2.id, "gone", response);
|
|
199
|
+
const options = {
|
|
200
|
+
...loaders,
|
|
201
|
+
documentLoader: () => Promise.reject(error)
|
|
202
|
+
};
|
|
203
|
+
strictEqual(await verifyJsonLd(json, options), false);
|
|
204
|
+
const evidence = observation();
|
|
205
|
+
strictEqual(await verifyJsonLd(json, {
|
|
206
|
+
...options,
|
|
207
|
+
[verificationObservation]: evidence
|
|
208
|
+
}), false);
|
|
209
|
+
const check = evidence.attempts[0].checks[0];
|
|
210
|
+
ok(check.status === "rejected" && check.reason.type === "keyFetchError");
|
|
211
|
+
let cloneThrows = false;
|
|
212
|
+
try {
|
|
213
|
+
response.clone();
|
|
214
|
+
} catch {
|
|
215
|
+
cloneThrows = true;
|
|
216
|
+
}
|
|
217
|
+
if (cloneThrows) {
|
|
218
|
+
ok("error" in check.reason.result);
|
|
219
|
+
strictEqual(check.reason.result.error, error);
|
|
220
|
+
} else {
|
|
221
|
+
ok("status" in check.reason.result);
|
|
222
|
+
strictEqual(check.reason.result.status, 410);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
test("OIP check retains aliased declarations without extra context fetches", async () => {
|
|
226
|
+
const json = await (await signObject(new Create({ actor: ed25519Multikey.controllerId }), ed25519PrivateKey, ed25519Multikey.id, loaders)).toJsonLd(loaders);
|
|
227
|
+
const proof = json.proof;
|
|
228
|
+
const context = { vm: {
|
|
229
|
+
"@id": "https://w3id.org/security#verificationMethod",
|
|
230
|
+
"@type": "@id"
|
|
231
|
+
} };
|
|
232
|
+
const contextUrl = "https://example.com/custom-proof-context";
|
|
233
|
+
json["@context"] = [...json["@context"], contextUrl];
|
|
234
|
+
proof["@context"] = [...proof["@context"], contextUrl];
|
|
235
|
+
const declaredKeyId = "https://EXAMPLE.com/person2#key4";
|
|
236
|
+
proof.vm = declaredKeyId;
|
|
237
|
+
delete proof.verificationMethod;
|
|
238
|
+
const run = async (evidence) => {
|
|
239
|
+
let fetches = 0;
|
|
240
|
+
await verifyObject(Activity, structuredClone(json), {
|
|
241
|
+
...loaders,
|
|
242
|
+
contextLoader: async (url, options) => {
|
|
243
|
+
fetches++;
|
|
244
|
+
if (url === contextUrl) return {
|
|
245
|
+
contextUrl: null,
|
|
246
|
+
documentUrl: url,
|
|
247
|
+
document: { "@context": context }
|
|
248
|
+
};
|
|
249
|
+
return await mockDocumentLoader(url, options);
|
|
250
|
+
},
|
|
251
|
+
...evidence == null ? {} : { [verificationObservation]: evidence }
|
|
252
|
+
});
|
|
253
|
+
return fetches;
|
|
254
|
+
};
|
|
255
|
+
const baselineFetches = await run();
|
|
256
|
+
const evidence = observation();
|
|
257
|
+
strictEqual(await run(evidence), baselineFetches);
|
|
258
|
+
strictEqual(evidence.attempts[0].checks[0].declaredKeyId, declaredKeyId);
|
|
259
|
+
});
|
|
260
|
+
test("OIP check preserves compact node identifiers and their aliases", async () => {
|
|
261
|
+
for (const idProperty of [
|
|
262
|
+
"id",
|
|
263
|
+
"rawId",
|
|
264
|
+
"scopedId"
|
|
265
|
+
]) {
|
|
266
|
+
const json = await (await signObject(new Create({ actor: ed25519Multikey.controllerId }), ed25519PrivateKey, ed25519Multikey.id, loaders)).toJsonLd(loaders);
|
|
267
|
+
const proof = json.proof;
|
|
268
|
+
const context = {
|
|
269
|
+
rawId: "@id",
|
|
270
|
+
vm: {
|
|
271
|
+
"@id": "https://w3id.org/security#verificationMethod",
|
|
272
|
+
"@type": "@id",
|
|
273
|
+
"@context": { scopedId: "@id" }
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
json["@context"] = [...json["@context"], context];
|
|
277
|
+
proof["@context"] = [...proof["@context"], context];
|
|
278
|
+
const declaredKeyId = "https://EXAMPLE.com/person2#key4";
|
|
279
|
+
if (idProperty === "scopedId") {
|
|
280
|
+
proof.vm = { [idProperty]: declaredKeyId };
|
|
281
|
+
delete proof.verificationMethod;
|
|
282
|
+
} else proof.verificationMethod = { [idProperty]: declaredKeyId };
|
|
283
|
+
const evidence = observation();
|
|
284
|
+
await verifyObject(Activity, json, {
|
|
285
|
+
...loaders,
|
|
286
|
+
[verificationObservation]: evidence
|
|
287
|
+
});
|
|
288
|
+
strictEqual(evidence.attempts[0].checks[0].declaredKeyId, declaredKeyId);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
test("signature evidence excludes keys loaded before canonicalization errors", async () => {
|
|
292
|
+
const json = await (await signObject(new Create({ actor: ed25519Multikey.controllerId }), ed25519PrivateKey, ed25519Multikey.id, loaders)).toJsonLd(loaders);
|
|
293
|
+
json.extra = JSON.parse("1e400");
|
|
294
|
+
const evidence = observation();
|
|
295
|
+
let thrown = false;
|
|
296
|
+
try {
|
|
297
|
+
await verifyObject(Activity, json, {
|
|
298
|
+
...loaders,
|
|
299
|
+
[verificationObservation]: evidence
|
|
300
|
+
});
|
|
301
|
+
} catch {
|
|
302
|
+
thrown = true;
|
|
303
|
+
}
|
|
304
|
+
strictEqual(thrown, true);
|
|
305
|
+
const check = evidence.attempts[0].checks[0];
|
|
306
|
+
strictEqual(check.status, "error");
|
|
307
|
+
deepStrictEqual(check.triedKeys, []);
|
|
308
|
+
});
|
|
309
|
+
//#endregion
|
|
310
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { c as getNormalizationContextLoader } from "./ld-
|
|
4
|
+
import { c as getNormalizationContextLoader } from "./ld-UsN-TIPh.mjs";
|
|
5
5
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
6
6
|
//#region src/federation/temporal.ts
|
|
7
7
|
function isPlainObject(value) {
|
package/dist/testing/kv.test.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
6
6
|
import { t as ManualClockKvStore } from "../kv-DBRWVx3Q.mjs";
|
|
7
7
|
import { n as baseOptions, o as stringSchema, t as MockQueue } from "../tasks-IG3pHfvZ.mjs";
|
|
8
8
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
+
import { o as createFederation } from "../middleware-CkjwiEBd.mjs";
|
|
10
10
|
//#region src/testing/kv.test.ts
|
|
11
11
|
test("ManualClockKvStore keeps an entry at its exact expiration instant", async () => {
|
|
12
12
|
const kv = new ManualClockKvStore();
|