@fedify/fedify 2.0.0-pr.490.2 → 2.0.0-pr.559.4
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/LICENSE +1 -1
- package/README.md +64 -37
- package/dist/{builder-4syLV1-z.js → builder-DTlQwmVF.js} +10 -3
- package/dist/{client-BsGzbnV-.d.ts → client-CUTUGgvJ.d.ts} +18 -18
- package/dist/{client-pY7-3icS.js → client-Dg7OfUDA.js} +28 -23
- package/dist/{client-94iWEfQa.d.cts → client-by-PEGAJ.d.cts} +18 -18
- package/dist/compat/mod.cjs +1 -1
- package/dist/compat/mod.d.cts +6 -10
- package/dist/compat/mod.d.ts +6 -10
- package/dist/compat/mod.js +1 -1
- package/dist/compat/transformers.test.js +22 -21
- package/dist/{context-PxGADCsD.d.cts → context-B6X-7loD.d.cts} +206 -74
- package/dist/{context-V-XS2_6O.d.ts → context-CJaICYPw.d.ts} +206 -74
- package/dist/context-CZ5llAss.js +109 -0
- package/dist/deno-DGx1JZHr.js +124 -0
- package/dist/{testing-BslrM_9E.js → dist-B5f6a8Tt.js} +90 -110
- package/dist/{docloader-DndkGj0O.js → docloader-D8UHsyqD.js} +3 -3
- package/dist/{esm-VlKMJQqV.js → esm-DGl7uK1r.js} +1 -1
- package/dist/federation/builder.test.js +7 -5
- package/dist/federation/collection.test.js +2 -3
- package/dist/federation/handler.test.js +24 -23
- package/dist/federation/idempotency.test.js +59 -22
- package/dist/federation/inbox.test.js +4 -3
- package/dist/federation/keycache.test.js +4 -4
- package/dist/federation/kv.test.js +56 -3
- package/dist/federation/middleware.test.js +307 -93
- package/dist/federation/mod.cjs +9 -10
- package/dist/federation/mod.d.cts +7 -11
- package/dist/federation/mod.d.ts +7 -11
- package/dist/federation/mod.js +8 -11
- package/dist/federation/mq.test.js +167 -16
- package/dist/federation/negotiation.test.js +2 -3
- package/dist/federation/retry.test.js +2 -3
- package/dist/federation/router.test.js +2 -2
- package/dist/federation/send.test.js +93 -11
- package/dist/{webfinger/handler.test.js → federation/webfinger.test.js} +24 -22
- package/dist/{federation-CRpdnOMS.cjs → federation-CE0CJ_0G.cjs} +116 -10
- package/dist/{federation-jcR8-ZxP.js → federation-D6FVaeAR.js} +122 -16
- package/dist/{http-YhR_TMMQ.js → http-CL3G0rnf.js} +126 -9
- package/dist/{http-M8k5mKc0.d.cts → http-ClB3pLcL.d.cts} +1 -1
- package/dist/{http-Dxpqz4hE.cjs → http-DKBUv5zZ.cjs} +139 -16
- package/dist/{http-BbO0ejuk.d.ts → http-DLBDPal9.d.ts} +1 -1
- package/dist/{http-DH47B-h3.js → http-LGtYlSfN.js} +3 -2
- package/dist/{inbox-CEyHvxOo.js → inbox-DbtWQY2D.js} +2 -1
- package/dist/{key-x7E5PYI0.js → key-BCtt1Ugy.js} +3 -3
- package/dist/{keycache-BRXuBDuy.js → keycache-DRxpZ5r9.js} +1 -1
- package/dist/{keys-DLk_8H-l.js → keys-ZbcByPg9.js} +1 -1
- package/dist/{kv-Bxr0Q87_.d.cts → kv-B4vFhIYL.d.cts} +30 -1
- package/dist/{kv-BKNZ-Tb-.d.ts → kv-CYySNrsn.d.ts} +30 -1
- package/dist/{kv-CRZrzyXm.js → kv-QzKcOQgP.js} +22 -0
- package/dist/{kv-cache-HFnFIjSD.js → kv-cache-0786BfqY.js} +3 -3
- package/dist/{kv-cache-DN9pfMBe.js → kv-cache-B__dHl7g.js} +15 -2
- package/dist/{kv-cache-BMpfJFTx.cjs → kv-cache-DCJojeTn.cjs} +3 -3
- package/dist/{ld-CRPaU6c8.js → ld-QlZPwGEH.js} +4 -3
- package/dist/middleware-B3jUPnDa.js +12 -0
- package/dist/middleware-BFiwWMA2.cjs +12 -0
- package/dist/middleware-DMx6DyIw.js +26 -0
- package/dist/{middleware-DfLpMu7C.js → middleware-Dm58nObp.js} +280 -166
- package/dist/{middleware-BIqFwRwI.js → middleware-WokE4qxc.js} +245 -178
- package/dist/{middleware-Ck7O6mb0.cjs → middleware-hWyKOO_6.cjs} +332 -206
- package/dist/{mod-DMpuiKXi.d.cts → mod-BHXq4Q3x.d.cts} +7 -7
- package/dist/{mod-DgxG-byT.d.cts → mod-BrS8tiad.d.cts} +2 -2
- package/dist/mod-CoMP50Rf.d.ts +64 -0
- package/dist/{mod-BoRKfJPE.d.cts → mod-DScazwCW.d.cts} +4 -4
- package/dist/mod-DTzN6Pv3.d.cts +62 -0
- package/dist/{mod-aAE2wOWV.d.ts → mod-DZmuPaKv.d.ts} +7 -7
- package/dist/{mod-D5Z2tISD.d.ts → mod-jOa7W503.d.ts} +2 -2
- package/dist/{mod-Cdo6SYlJ.d.ts → mod-xKJ57rwu.d.ts} +4 -4
- package/dist/mod.cjs +12 -93
- package/dist/mod.d.cts +11 -15
- package/dist/mod.d.ts +11 -15
- package/dist/mod.js +11 -15
- package/dist/nodeinfo/client.test.js +3 -4
- package/dist/nodeinfo/handler.test.js +22 -21
- package/dist/nodeinfo/mod.cjs +2 -2
- package/dist/nodeinfo/mod.d.cts +2 -2
- package/dist/nodeinfo/mod.d.ts +2 -2
- package/dist/nodeinfo/mod.js +2 -2
- package/dist/nodeinfo/types.test.js +2 -3
- package/dist/otel/exporter.test.js +893 -0
- package/dist/otel/mod.cjs +256 -0
- package/dist/otel/mod.d.cts +230 -0
- package/dist/otel/mod.d.ts +232 -0
- package/dist/otel/mod.js +255 -0
- package/dist/{owner-kQRGVXG1.d.ts → owner-BgI8C-VY.d.ts} +1 -2
- package/dist/{owner-B4HbyP8s.d.cts → owner-C-zfmVAD.d.cts} +1 -2
- package/dist/{owner-CIWnopkT.js → owner-Cejm-F7S.js} +2 -2
- package/dist/{proof-D-5ri6rf.js → proof-BOQBHd-i.js} +3 -2
- package/dist/{proof-fEwcA7LA.cjs → proof-Bmi8ZIcW.cjs} +24 -25
- package/dist/{proof-C8-2l0zH.js → proof-CnaEQ_Ev.js} +4 -5
- package/dist/router-D9eI0s4b.js +118 -0
- package/dist/{send-CPGk9QKZ.js → send-jFxXfsN8.js} +38 -4
- package/dist/sig/http.test.js +6 -7
- package/dist/sig/key.test.js +5 -5
- package/dist/sig/ld.test.js +6 -6
- package/dist/sig/mod.cjs +3 -5
- package/dist/sig/mod.d.cts +3 -5
- package/dist/sig/mod.d.ts +3 -5
- package/dist/sig/mod.js +3 -5
- package/dist/sig/owner.test.js +6 -7
- package/dist/sig/proof.test.js +6 -6
- package/dist/testing/mod.d.ts +173 -7006
- package/dist/testing/mod.js +4 -3
- package/dist/{transformers-CoBS-oFG.cjs → transformers-BjBg6Lag.cjs} +2 -2
- package/dist/{transformers-BFT6d7J5.js → transformers-N_ip_y4P.js} +2 -2
- package/dist/{types-BtUjyi5y.js → types-8l28uC8o.js} +30 -25
- package/dist/{types-CWgzGaqk.cjs → types-B6z6CqIz.cjs} +30 -25
- package/dist/{types-C2XVl6gj.js → types-CPz01LGH.js} +3 -3
- package/dist/utils/docloader.test.js +7 -8
- package/dist/utils/kv-cache.test.js +5 -3
- package/dist/utils/mod.cjs +3 -5
- package/dist/utils/mod.d.cts +3 -4
- package/dist/utils/mod.d.ts +3 -4
- package/dist/utils/mod.js +3 -5
- package/dist/vocab/mod.cjs +8 -81
- package/dist/vocab/mod.d.cts +1 -4
- package/dist/vocab/mod.d.ts +1 -4
- package/dist/vocab/mod.js +1 -5
- package/package.json +27 -27
- package/dist/actor-BT-e5fn9.js +0 -146
- package/dist/actor-B_gRMloq.js +0 -41647
- package/dist/actor-CBfPjuWj.cjs +0 -42079
- package/dist/actor-DqFajh9s.d.ts +0 -130
- package/dist/actor-f2NtjyCg.d.cts +0 -128
- package/dist/fixtures/activitypub.academy/users/brauca_darradiul.json +0 -83
- package/dist/fixtures/example.com/announce.json +0 -6
- package/dist/fixtures/example.com/collection.json +0 -19
- package/dist/fixtures/example.com/create.json +0 -6
- package/dist/fixtures/example.com/cross-origin-actor.json +0 -6
- package/dist/fixtures/example.com/hong-gildong.json +0 -11
- package/dist/fixtures/example.com/invite.json +0 -7
- package/dist/fixtures/example.com/key.json +0 -7
- package/dist/fixtures/example.com/key2.json +0 -6
- package/dist/fixtures/example.com/object.json +0 -6
- package/dist/fixtures/example.com/orderedcollectionpage.json +0 -24
- package/dist/fixtures/example.com/paged/a.json +0 -13
- package/dist/fixtures/example.com/paged/b.json +0 -16
- package/dist/fixtures/example.com/paged-collection.json +0 -6
- package/dist/fixtures/example.com/person.json +0 -22
- package/dist/fixtures/example.com/person2.json +0 -40
- package/dist/fixtures/example.com/test.json +0 -5
- package/dist/fixtures/example.com/users/handle.json +0 -16
- package/dist/fixtures/example.com/wrong-type.json +0 -3
- package/dist/fixtures/media.example.com/avatars/test-avatar.jpg.json +0 -6
- package/dist/fixtures/oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd.json +0 -24
- package/dist/fixtures/remote.domain/users/bob.json +0 -20
- package/dist/fixtures/server.example/users/alice.json +0 -20
- package/dist/fixtures/w3id.org/identity/v1.json +0 -152
- package/dist/fixtures/w3id.org/security/data-integrity/v1.json +0 -74
- package/dist/fixtures/w3id.org/security/multikey/v1.json +0 -35
- package/dist/fixtures/w3id.org/security/v1.json +0 -50
- package/dist/fixtures/wizard.casa/users/hongminhee.json +0 -69
- package/dist/fixtures/www.w3.org/ns/activitystreams.json +0 -379
- package/dist/fixtures/www.w3.org/ns/did/v1.json +0 -58
- package/dist/lookup-BTqtVATt.cjs +0 -266
- package/dist/lookup-DOSnR912.js +0 -254
- package/dist/lookup-Dj9-mgOn.js +0 -42184
- package/dist/middleware-CxswDtQn.js +0 -15
- package/dist/middleware-CyITsnX0.js +0 -26
- package/dist/middleware-Z8lc_drL.cjs +0 -15
- package/dist/mod-BlVovdcy.d.ts +0 -309
- package/dist/mod-BxRCHTz-.d.cts +0 -307
- package/dist/mod-C58MZ7Wx.d.cts +0 -113
- package/dist/mod-CcDPcLJW.d.cts +0 -1
- package/dist/mod-Ds0mpFZU.d.ts +0 -115
- package/dist/mod-bjzj5QIb.d.ts +0 -2
- package/dist/otel-1BmGPuZc.js +0 -64
- package/dist/src/vocab/accept.yaml +0 -15
- package/dist/src/vocab/activity.yaml +0 -98
- package/dist/src/vocab/add.yaml +0 -16
- package/dist/src/vocab/announce.yaml +0 -30
- package/dist/src/vocab/application.yaml +0 -324
- package/dist/src/vocab/arrive.yaml +0 -15
- package/dist/src/vocab/article.yaml +0 -46
- package/dist/src/vocab/audio.yaml +0 -11
- package/dist/src/vocab/block.yaml +0 -16
- package/dist/src/vocab/chatmessage.yaml +0 -50
- package/dist/src/vocab/collection.yaml +0 -154
- package/dist/src/vocab/collectionpage.yaml +0 -55
- package/dist/src/vocab/create.yaml +0 -28
- package/dist/src/vocab/dataintegrityproof.yaml +0 -56
- package/dist/src/vocab/delete.yaml +0 -27
- package/dist/src/vocab/didservice.yaml +0 -22
- package/dist/src/vocab/dislike.yaml +0 -14
- package/dist/src/vocab/document.yaml +0 -31
- package/dist/src/vocab/emoji.yaml +0 -12
- package/dist/src/vocab/emojireact.yaml +0 -17
- package/dist/src/vocab/endpoints.yaml +0 -85
- package/dist/src/vocab/event.yaml +0 -11
- package/dist/src/vocab/export.yaml +0 -9
- package/dist/src/vocab/flag.yaml +0 -15
- package/dist/src/vocab/follow.yaml +0 -19
- package/dist/src/vocab/group.yaml +0 -324
- package/dist/src/vocab/hashtag.yaml +0 -14
- package/dist/src/vocab/ignore.yaml +0 -14
- package/dist/src/vocab/image.yaml +0 -9
- package/dist/src/vocab/intransitiveactivity.yaml +0 -15
- package/dist/src/vocab/invite.yaml +0 -14
- package/dist/src/vocab/join.yaml +0 -14
- package/dist/src/vocab/key.yaml +0 -28
- package/dist/src/vocab/leave.yaml +0 -14
- package/dist/src/vocab/like.yaml +0 -16
- package/dist/src/vocab/link.yaml +0 -101
- package/dist/src/vocab/listen.yaml +0 -12
- package/dist/src/vocab/mention.yaml +0 -9
- package/dist/src/vocab/move.yaml +0 -15
- package/dist/src/vocab/multikey.yaml +0 -36
- package/dist/src/vocab/note.yaml +0 -48
- package/dist/src/vocab/object.yaml +0 -404
- package/dist/src/vocab/offer.yaml +0 -15
- package/dist/src/vocab/orderedcollection.yaml +0 -39
- package/dist/src/vocab/orderedcollectionpage.yaml +0 -50
- package/dist/src/vocab/organization.yaml +0 -324
- package/dist/src/vocab/page.yaml +0 -11
- package/dist/src/vocab/person.yaml +0 -324
- package/dist/src/vocab/place.yaml +0 -75
- package/dist/src/vocab/profile.yaml +0 -26
- package/dist/src/vocab/propertyvalue.yaml +0 -32
- package/dist/src/vocab/question.yaml +0 -103
- package/dist/src/vocab/read.yaml +0 -13
- package/dist/src/vocab/reject.yaml +0 -14
- package/dist/src/vocab/relationship.yaml +0 -52
- package/dist/src/vocab/remove.yaml +0 -14
- package/dist/src/vocab/service.yaml +0 -324
- package/dist/src/vocab/source.yaml +0 -26
- package/dist/src/vocab/tentativeaccept.yaml +0 -14
- package/dist/src/vocab/tentativereject.yaml +0 -14
- package/dist/src/vocab/tombstone.yaml +0 -24
- package/dist/src/vocab/travel.yaml +0 -16
- package/dist/src/vocab/undo.yaml +0 -26
- package/dist/src/vocab/update.yaml +0 -58
- package/dist/src/vocab/video.yaml +0 -11
- package/dist/src/vocab/view.yaml +0 -13
- package/dist/testing/docloader.test.js +0 -22
- package/dist/vocab/actor.test.js +0 -5963
- package/dist/vocab/lookup.test.d.ts +0 -3
- package/dist/vocab/lookup.test.js +0 -476
- package/dist/vocab/type.test.d.ts +0 -3
- package/dist/vocab/type.test.js +0 -24
- package/dist/vocab/vocab.test.d.ts +0 -3
- package/dist/vocab/vocab.test.js +0 -9397
- package/dist/vocab-BCWe1Ih5.d.ts +0 -14905
- package/dist/vocab-ByUp-A2_.js +0 -260
- package/dist/vocab-CeDBzu-f.d.cts +0 -14903
- package/dist/vocab-X_X5T8D3.cjs +0 -296
- package/dist/webfinger/handler.test.d.ts +0 -3
- package/dist/webfinger/lookup.test.d.ts +0 -3
- package/dist/webfinger/lookup.test.js +0 -193
- package/dist/webfinger/mod.cjs +0 -8
- package/dist/webfinger/mod.d.cts +0 -2
- package/dist/webfinger/mod.d.ts +0 -4
- package/dist/webfinger/mod.js +0 -8
- package/dist/webfinger-C72Y8lrh.js +0 -4
- package/dist/webfinger-vAtLmxOF.cjs +0 -4
- /package/dist/{collection-BzWsN9pB.js → collection-CcnIw1qY.js} +0 -0
- /package/dist/{testing/docloader.test.d.ts → federation/webfinger.test.d.ts} +0 -0
- /package/dist/{mod-CVgZgliM.d.ts → mod-1E3W847c.d.ts} +0 -0
- /package/dist/{mod-B-hUPT2N.d.cts → mod-C81L6_lQ.d.cts} +0 -0
- /package/dist/{negotiation-C4nFufNk.js → negotiation-5NPJL6zp.js} +0 -0
- /package/dist/{nodeinfo-BnthBobC.js → nodeinfo-BlLsRSiT.js} +0 -0
- /package/dist/{nodeinfo-CdN0rEnZ.cjs → nodeinfo-DuMYTpbZ.cjs} +0 -0
- /package/dist/{vocab/actor.test.d.ts → otel/exporter.test.d.ts} +0 -0
- /package/dist/{retry-CfF8Gn4d.js → retry-D4GJ670a.js} +0 -0
- /package/dist/{sig-C34-oHBl.js → sig-CwuONEzF.js} +0 -0
- /package/dist/{sig-YYj5tCnr.cjs → sig-DeXX2xnj.cjs} +0 -0
- /package/dist/{utils-DyRU1gdZ.cjs → utils-Db0ZmjcD.cjs} +0 -0
- /package/dist/{utils-D-Va7aXC.js → utils-Wranxuoe.js} +0 -0
package/dist/otel/mod.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
|
|
2
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
3
|
+
import { URLPattern } from "urlpattern-polyfill";
|
|
4
|
+
|
|
5
|
+
import { getLogger } from "@logtape/logtape";
|
|
6
|
+
import { ExportResultCode } from "@opentelemetry/core";
|
|
7
|
+
|
|
8
|
+
//#region src/otel/exporter.ts
|
|
9
|
+
/**
|
|
10
|
+
* A SpanExporter that persists ActivityPub activity traces to a
|
|
11
|
+
* {@link KvStore}. This enables distributed tracing across multiple
|
|
12
|
+
* nodes in a Fedify deployment.
|
|
13
|
+
*
|
|
14
|
+
* The exporter captures activity data from OpenTelemetry span events
|
|
15
|
+
* (`activitypub.activity.received` and `activitypub.activity.sent`)
|
|
16
|
+
* and stores them in the KvStore with trace context preserved.
|
|
17
|
+
*
|
|
18
|
+
* @example Basic usage with MemoryKvStore
|
|
19
|
+
* ```typescript ignore
|
|
20
|
+
* import { MemoryKvStore } from "@fedify/fedify";
|
|
21
|
+
* import { FedifySpanExporter } from "@fedify/fedify/otel";
|
|
22
|
+
* import {
|
|
23
|
+
* BasicTracerProvider,
|
|
24
|
+
* SimpleSpanProcessor,
|
|
25
|
+
* } from "@opentelemetry/sdk-trace-base";
|
|
26
|
+
*
|
|
27
|
+
* const kv = new MemoryKvStore();
|
|
28
|
+
* const exporter = new FedifySpanExporter(kv, {
|
|
29
|
+
* ttl: Temporal.Duration.from({ hours: 1 }),
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* const provider = new BasicTracerProvider({
|
|
33
|
+
* spanProcessors: [new SimpleSpanProcessor(exporter)],
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @example Querying stored traces
|
|
38
|
+
* ```typescript ignore
|
|
39
|
+
* import { MemoryKvStore } from "@fedify/fedify";
|
|
40
|
+
* import { FedifySpanExporter } from "@fedify/fedify/otel";
|
|
41
|
+
*
|
|
42
|
+
* const kv = new MemoryKvStore();
|
|
43
|
+
* const exporter = new FedifySpanExporter(kv);
|
|
44
|
+
* const traceId = "abc123";
|
|
45
|
+
*
|
|
46
|
+
* // Get all activities for a specific trace
|
|
47
|
+
* const activities = await exporter.getActivitiesByTraceId(traceId);
|
|
48
|
+
*
|
|
49
|
+
* // Get recent traces
|
|
50
|
+
* const recentTraces = await exporter.getRecentTraces({ limit: 100 });
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @since 1.10.0
|
|
54
|
+
*/
|
|
55
|
+
var FedifySpanExporter = class {
|
|
56
|
+
#kv;
|
|
57
|
+
#ttl;
|
|
58
|
+
#keyPrefix;
|
|
59
|
+
/**
|
|
60
|
+
* Creates a new FedifySpanExporter.
|
|
61
|
+
*
|
|
62
|
+
* @param kv The KvStore to persist trace data to.
|
|
63
|
+
* @param options Configuration options.
|
|
64
|
+
*/
|
|
65
|
+
constructor(kv, options) {
|
|
66
|
+
this.#kv = kv;
|
|
67
|
+
this.#ttl = options?.ttl;
|
|
68
|
+
this.#keyPrefix = options?.keyPrefix ?? ["fedify", "traces"];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Exports spans to the KvStore.
|
|
72
|
+
*
|
|
73
|
+
* @param spans The spans to export.
|
|
74
|
+
* @param resultCallback Callback to invoke with the export result.
|
|
75
|
+
*/
|
|
76
|
+
export(spans, resultCallback) {
|
|
77
|
+
this.#exportAsync(spans).then(() => resultCallback({ code: ExportResultCode.SUCCESS })).catch((error) => {
|
|
78
|
+
getLogger([
|
|
79
|
+
"fedify",
|
|
80
|
+
"otel",
|
|
81
|
+
"exporter"
|
|
82
|
+
]).error("Failed to export spans to KvStore: {error}", { error });
|
|
83
|
+
resultCallback({ code: ExportResultCode.FAILED });
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async #exportAsync(spans) {
|
|
87
|
+
const storeOperations = [];
|
|
88
|
+
for (const span of spans) {
|
|
89
|
+
const records = this.#extractRecords(span);
|
|
90
|
+
for (const record of records) storeOperations.push(this.#storeRecord(record));
|
|
91
|
+
}
|
|
92
|
+
const results = await Promise.allSettled(storeOperations);
|
|
93
|
+
const rejected = results.filter((r) => r.status === "rejected");
|
|
94
|
+
if (rejected.length > 0) throw new AggregateError(rejected.map((r) => r.reason), "Failed to store one or more trace activity records.");
|
|
95
|
+
}
|
|
96
|
+
#extractRecords(span) {
|
|
97
|
+
const records = [];
|
|
98
|
+
const spanContext = span.spanContext();
|
|
99
|
+
const traceId = spanContext.traceId;
|
|
100
|
+
const spanId = spanContext.spanId;
|
|
101
|
+
const parentSpanId = span.parentSpanContext?.spanId;
|
|
102
|
+
for (const event of span.events) if (event.name === "activitypub.activity.received") {
|
|
103
|
+
const record = this.#extractInboundRecord(event, traceId, spanId, parentSpanId);
|
|
104
|
+
if (record != null) records.push(record);
|
|
105
|
+
} else if (event.name === "activitypub.activity.sent") {
|
|
106
|
+
const record = this.#extractOutboundRecord(event, traceId, spanId, parentSpanId);
|
|
107
|
+
if (record != null) records.push(record);
|
|
108
|
+
}
|
|
109
|
+
return records;
|
|
110
|
+
}
|
|
111
|
+
#extractInboundRecord(event, traceId, spanId, parentSpanId) {
|
|
112
|
+
const attrs = event.attributes;
|
|
113
|
+
if (attrs == null) return null;
|
|
114
|
+
const activityJson = attrs["activitypub.activity.json"];
|
|
115
|
+
if (typeof activityJson !== "string") return null;
|
|
116
|
+
let activityType = "Unknown";
|
|
117
|
+
let activityId;
|
|
118
|
+
let actorId;
|
|
119
|
+
try {
|
|
120
|
+
const activity = JSON.parse(activityJson);
|
|
121
|
+
activityType = activity.type ?? "Unknown";
|
|
122
|
+
activityId = activity.id;
|
|
123
|
+
if (typeof activity.actor === "string") actorId = activity.actor;
|
|
124
|
+
else if (activity.actor != null && typeof activity.actor.id === "string") actorId = activity.actor.id;
|
|
125
|
+
} catch {}
|
|
126
|
+
const verified = attrs["activitypub.activity.verified"];
|
|
127
|
+
const httpSigVerified = attrs["http_signatures.verified"];
|
|
128
|
+
const httpSigKeyId = attrs["http_signatures.key_id"];
|
|
129
|
+
const ldSigVerified = attrs["ld_signatures.verified"];
|
|
130
|
+
let signatureDetails;
|
|
131
|
+
if (typeof httpSigVerified === "boolean" || typeof ldSigVerified === "boolean") signatureDetails = {
|
|
132
|
+
httpSignaturesVerified: httpSigVerified === true,
|
|
133
|
+
httpSignaturesKeyId: typeof httpSigKeyId === "string" && httpSigKeyId !== "" ? httpSigKeyId : void 0,
|
|
134
|
+
ldSignaturesVerified: ldSigVerified === true
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
traceId,
|
|
138
|
+
spanId,
|
|
139
|
+
parentSpanId,
|
|
140
|
+
direction: "inbound",
|
|
141
|
+
activityType,
|
|
142
|
+
activityId,
|
|
143
|
+
actorId,
|
|
144
|
+
activityJson,
|
|
145
|
+
verified: typeof verified === "boolean" ? verified : void 0,
|
|
146
|
+
signatureDetails,
|
|
147
|
+
timestamp: (/* @__PURE__ */ new Date(event.time[0] * 1e3 + event.time[1] / 1e6)).toISOString()
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
#extractOutboundRecord(event, traceId, spanId, parentSpanId) {
|
|
151
|
+
const attrs = event.attributes;
|
|
152
|
+
if (attrs == null) return null;
|
|
153
|
+
const activityJson = attrs["activitypub.activity.json"];
|
|
154
|
+
if (typeof activityJson !== "string") return null;
|
|
155
|
+
let activityType = "Unknown";
|
|
156
|
+
let activityId;
|
|
157
|
+
let actorId;
|
|
158
|
+
try {
|
|
159
|
+
const activity = JSON.parse(activityJson);
|
|
160
|
+
activityType = activity.type ?? "Unknown";
|
|
161
|
+
activityId = activity.id;
|
|
162
|
+
if (typeof activity.actor === "string") actorId = activity.actor;
|
|
163
|
+
else if (activity.actor != null && typeof activity.actor.id === "string") actorId = activity.actor.id;
|
|
164
|
+
} catch {}
|
|
165
|
+
const inboxUrl = attrs["activitypub.inbox.url"];
|
|
166
|
+
const explicitActivityId = attrs["activitypub.activity.id"];
|
|
167
|
+
return {
|
|
168
|
+
traceId,
|
|
169
|
+
spanId,
|
|
170
|
+
parentSpanId,
|
|
171
|
+
direction: "outbound",
|
|
172
|
+
activityType,
|
|
173
|
+
activityId: activityId ?? (typeof explicitActivityId === "string" && explicitActivityId !== "" ? explicitActivityId : void 0),
|
|
174
|
+
actorId,
|
|
175
|
+
activityJson,
|
|
176
|
+
timestamp: (/* @__PURE__ */ new Date(event.time[0] * 1e3 + event.time[1] / 1e6)).toISOString(),
|
|
177
|
+
inboxUrl: typeof inboxUrl === "string" ? inboxUrl : void 0
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
async #storeRecord(record) {
|
|
181
|
+
const options = this.#ttl != null ? { ttl: this.#ttl } : void 0;
|
|
182
|
+
const key = [
|
|
183
|
+
...this.#keyPrefix,
|
|
184
|
+
record.traceId,
|
|
185
|
+
record.spanId
|
|
186
|
+
];
|
|
187
|
+
await this.#kv.set(key, record, options);
|
|
188
|
+
await this.#updateTraceSummary(record, options);
|
|
189
|
+
}
|
|
190
|
+
async #setWithCasRetry(key, transform, options) {
|
|
191
|
+
if (this.#kv.cas != null) for (let attempt = 0; attempt < 3; attempt++) {
|
|
192
|
+
const existing$1 = await this.#kv.get(key);
|
|
193
|
+
const newValue$1 = transform(existing$1);
|
|
194
|
+
if (await this.#kv.cas(key, existing$1, newValue$1, options)) return;
|
|
195
|
+
}
|
|
196
|
+
const existing = await this.#kv.get(key);
|
|
197
|
+
const newValue = transform(existing);
|
|
198
|
+
await this.#kv.set(key, newValue, options);
|
|
199
|
+
}
|
|
200
|
+
async #updateTraceSummary(record, options) {
|
|
201
|
+
const summaryKey = [
|
|
202
|
+
...this.#keyPrefix,
|
|
203
|
+
"_summaries",
|
|
204
|
+
record.traceId
|
|
205
|
+
];
|
|
206
|
+
await this.#setWithCasRetry(summaryKey, (existing) => {
|
|
207
|
+
const activityCount = existing != null ? existing.activityCount + 1 : 1;
|
|
208
|
+
const activityTypes = existing != null ? existing.activityTypes.includes(record.activityType) ? existing.activityTypes : [...existing.activityTypes, record.activityType] : [record.activityType];
|
|
209
|
+
return {
|
|
210
|
+
traceId: existing?.traceId ?? record.traceId,
|
|
211
|
+
timestamp: existing?.timestamp ?? record.timestamp,
|
|
212
|
+
activityCount,
|
|
213
|
+
activityTypes
|
|
214
|
+
};
|
|
215
|
+
}, options);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Gets all activity records for a specific trace ID.
|
|
219
|
+
*
|
|
220
|
+
* @param traceId The trace ID to query.
|
|
221
|
+
* @returns An array of activity records belonging to the trace.
|
|
222
|
+
*/
|
|
223
|
+
async getActivitiesByTraceId(traceId) {
|
|
224
|
+
const prefix = [...this.#keyPrefix, traceId];
|
|
225
|
+
const records = [];
|
|
226
|
+
for await (const entry of this.#kv.list(prefix)) records.push(entry.value);
|
|
227
|
+
return records;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Gets recent traces with summary information.
|
|
231
|
+
*
|
|
232
|
+
* @param options Options for the query.
|
|
233
|
+
* @returns An array of trace summaries.
|
|
234
|
+
*/
|
|
235
|
+
async getRecentTraces(options) {
|
|
236
|
+
const summaryPrefix = [...this.#keyPrefix, "_summaries"];
|
|
237
|
+
const summaries = [];
|
|
238
|
+
for await (const entry of this.#kv.list(summaryPrefix)) summaries.push(entry.value);
|
|
239
|
+
summaries.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
240
|
+
if (options?.limit != null) return summaries.slice(0, options.limit);
|
|
241
|
+
return summaries;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Forces the exporter to flush any buffered data.
|
|
245
|
+
* This is a no-op because we write directly to the KvStore without buffering.
|
|
246
|
+
*/
|
|
247
|
+
async forceFlush() {}
|
|
248
|
+
/**
|
|
249
|
+
* Shuts down the exporter.
|
|
250
|
+
*/
|
|
251
|
+
async shutdown() {}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
//#endregion
|
|
255
|
+
export { FedifySpanExporter };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { Activity, CryptographicKey } from "
|
|
4
|
-
import { Actor } from "./actor-DqFajh9s.js";
|
|
3
|
+
import { Activity, Actor, CryptographicKey } from "@fedify/vocab";
|
|
5
4
|
import { TracerProvider } from "@opentelemetry/api";
|
|
6
5
|
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
7
6
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Activity, CryptographicKey } from "
|
|
2
|
-
import { Actor } from "./actor-f2NtjyCg.cjs";
|
|
1
|
+
import { Activity, Actor, CryptographicKey } from "@fedify/vocab";
|
|
3
2
|
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
4
3
|
import { TracerProvider } from "@opentelemetry/api";
|
|
5
4
|
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
|
4
4
|
globalThis.addEventListener = () => {};
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { isActor } from "
|
|
6
|
+
import { deno_default } from "./deno-DGx1JZHr.js";
|
|
7
|
+
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
8
8
|
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
9
9
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
10
10
|
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
|
4
4
|
globalThis.addEventListener = () => {};
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { fetchKey, validateCryptoKey } from "./key-
|
|
6
|
+
import { deno_default } from "./deno-DGx1JZHr.js";
|
|
7
|
+
import { fetchKey, validateCryptoKey } from "./key-BCtt1Ugy.js";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
9
|
+
import { Activity, DataIntegrityProof, Multikey, getTypeId } from "@fedify/vocab";
|
|
9
10
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
10
11
|
import { encodeHex } from "byte-encodings/hex";
|
|
11
12
|
import serialize from "json-canon";
|
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
4
4
|
|
|
5
5
|
const require_chunk = require('./chunk-DqRYRqnO.cjs');
|
|
6
|
-
const
|
|
7
|
-
const require_actor = require('./actor-CBfPjuWj.cjs');
|
|
8
|
-
const require_http = require('./http-Dxpqz4hE.cjs');
|
|
6
|
+
const require_http = require('./http-DKBUv5zZ.cjs');
|
|
9
7
|
const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
|
|
8
|
+
const __fedify_vocab = require_chunk.__toESM(require("@fedify/vocab"));
|
|
10
9
|
const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
|
|
11
|
-
const jsonld = require_chunk.__toESM(require("jsonld"));
|
|
12
|
-
const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
|
|
13
10
|
const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
|
|
14
11
|
const byte_encodings_base64 = require_chunk.__toESM(require("byte-encodings/base64"));
|
|
12
|
+
const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
|
|
13
|
+
const jsonld = require_chunk.__toESM(require("jsonld"));
|
|
15
14
|
const json_canon = require_chunk.__toESM(require("json-canon"));
|
|
16
15
|
|
|
17
16
|
//#region src/sig/ld.ts
|
|
@@ -82,7 +81,7 @@ async function createSignature(jsonLd, privateKey, keyId, { contextLoader, creat
|
|
|
82
81
|
*/
|
|
83
82
|
async function signJsonLd(jsonLd, privateKey, keyId, options) {
|
|
84
83
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
85
|
-
const tracer = tracerProvider.getTracer(
|
|
84
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
86
85
|
return await tracer.startActiveSpan("ld_signatures.sign", { attributes: { "ld_signatures.key_id": keyId.href } }, async (span) => {
|
|
87
86
|
try {
|
|
88
87
|
const signature = await createSignature(jsonLd, privateKey, keyId, options);
|
|
@@ -151,7 +150,7 @@ async function verifySignature(jsonLd, options = {}) {
|
|
|
151
150
|
});
|
|
152
151
|
return null;
|
|
153
152
|
}
|
|
154
|
-
const { key, cached } = await require_http.fetchKey(new URL(sig.creator),
|
|
153
|
+
const { key, cached } = await require_http.fetchKey(new URL(sig.creator), __fedify_vocab.CryptographicKey, options);
|
|
155
154
|
if (key == null) return null;
|
|
156
155
|
const sigOpts = {
|
|
157
156
|
...sig,
|
|
@@ -192,7 +191,7 @@ async function verifySignature(jsonLd, options = {}) {
|
|
|
192
191
|
keyId: sig.creator,
|
|
193
192
|
...sig
|
|
194
193
|
});
|
|
195
|
-
const { key: key$1 } = await require_http.fetchKey(new URL(sig.creator),
|
|
194
|
+
const { key: key$1 } = await require_http.fetchKey(new URL(sig.creator), __fedify_vocab.CryptographicKey, {
|
|
196
195
|
...options,
|
|
197
196
|
keyCache: {
|
|
198
197
|
get: () => Promise.resolve(void 0),
|
|
@@ -221,19 +220,19 @@ async function verifySignature(jsonLd, options = {}) {
|
|
|
221
220
|
*/
|
|
222
221
|
async function verifyJsonLd(jsonLd, options = {}) {
|
|
223
222
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
224
|
-
const tracer = tracerProvider.getTracer(
|
|
223
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
225
224
|
return await tracer.startActiveSpan("ld_signatures.verify", async (span) => {
|
|
226
225
|
try {
|
|
227
|
-
const object = await
|
|
226
|
+
const object = await __fedify_vocab.Object.fromJsonLd(jsonLd, options);
|
|
228
227
|
if (object.id != null) span.setAttribute("activitypub.object.id", object.id.href);
|
|
229
|
-
span.setAttribute("activitypub.object.type",
|
|
228
|
+
span.setAttribute("activitypub.object.type", (0, __fedify_vocab.getTypeId)(object).href);
|
|
230
229
|
if (typeof jsonLd === "object" && jsonLd != null && "signature" in jsonLd && typeof jsonLd.signature === "object" && jsonLd.signature != null) {
|
|
231
230
|
if ("creator" in jsonLd.signature && typeof jsonLd.signature.creator === "string") span.setAttribute("ld_signatures.key_id", jsonLd.signature.creator);
|
|
232
231
|
if ("signatureValue" in jsonLd.signature && typeof jsonLd.signature.signatureValue === "string") span.setAttribute("ld_signatures.signature", jsonLd.signature.signatureValue);
|
|
233
232
|
if ("type" in jsonLd.signature && typeof jsonLd.signature.type === "string") span.setAttribute("ld_signatures.type", jsonLd.signature.type);
|
|
234
233
|
}
|
|
235
234
|
const attributions = new Set(object.attributionIds.map((uri) => uri.href));
|
|
236
|
-
if (object instanceof
|
|
235
|
+
if (object instanceof __fedify_vocab.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
|
|
237
236
|
const key = await verifySignature(jsonLd, options);
|
|
238
237
|
if (key == null) return false;
|
|
239
238
|
if (key.ownerId == null) {
|
|
@@ -278,7 +277,7 @@ async function hashJsonLd(jsonLd, contextLoader) {
|
|
|
278
277
|
*/
|
|
279
278
|
async function doesActorOwnKey(activity, key, options) {
|
|
280
279
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
281
|
-
const tracer = tracerProvider.getTracer(
|
|
280
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
282
281
|
return await tracer.startActiveSpan("activitypub.verify_key_ownership", {
|
|
283
282
|
kind: __opentelemetry_api.SpanKind.INTERNAL,
|
|
284
283
|
attributes: {
|
|
@@ -294,7 +293,7 @@ async function doesActorOwnKey(activity, key, options) {
|
|
|
294
293
|
return owns;
|
|
295
294
|
}
|
|
296
295
|
const actor = await activity.getActor(options);
|
|
297
|
-
if (actor == null || !
|
|
296
|
+
if (actor == null || !(0, __fedify_vocab.isActor)(actor)) {
|
|
298
297
|
span.setAttribute("activitypub.key_ownership.verified", false);
|
|
299
298
|
span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
|
|
300
299
|
return false;
|
|
@@ -334,7 +333,7 @@ async function getKeyOwner(keyId, options) {
|
|
|
334
333
|
const documentLoader = options.documentLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)();
|
|
335
334
|
const contextLoader = options.contextLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)();
|
|
336
335
|
let object;
|
|
337
|
-
if (keyId instanceof
|
|
336
|
+
if (keyId instanceof __fedify_vocab.CryptographicKey) {
|
|
338
337
|
object = keyId;
|
|
339
338
|
if (object.id == null) return null;
|
|
340
339
|
keyId = object.id;
|
|
@@ -347,7 +346,7 @@ async function getKeyOwner(keyId, options) {
|
|
|
347
346
|
return null;
|
|
348
347
|
}
|
|
349
348
|
try {
|
|
350
|
-
object = await
|
|
349
|
+
object = await __fedify_vocab.Object.fromJsonLd(keyDoc, {
|
|
351
350
|
documentLoader,
|
|
352
351
|
contextLoader,
|
|
353
352
|
tracerProvider
|
|
@@ -355,7 +354,7 @@ async function getKeyOwner(keyId, options) {
|
|
|
355
354
|
} catch (e) {
|
|
356
355
|
if (!(e instanceof TypeError)) throw e;
|
|
357
356
|
try {
|
|
358
|
-
object = await
|
|
357
|
+
object = await __fedify_vocab.CryptographicKey.fromJsonLd(keyDoc, {
|
|
359
358
|
documentLoader,
|
|
360
359
|
contextLoader,
|
|
361
360
|
tracerProvider
|
|
@@ -367,14 +366,14 @@ async function getKeyOwner(keyId, options) {
|
|
|
367
366
|
}
|
|
368
367
|
}
|
|
369
368
|
let owner = null;
|
|
370
|
-
if (object instanceof
|
|
369
|
+
if (object instanceof __fedify_vocab.CryptographicKey) {
|
|
371
370
|
if (object.ownerId == null) return null;
|
|
372
371
|
owner = await object.getOwner({
|
|
373
372
|
documentLoader,
|
|
374
373
|
contextLoader,
|
|
375
374
|
tracerProvider
|
|
376
375
|
});
|
|
377
|
-
} else if (
|
|
376
|
+
} else if ((0, __fedify_vocab.isActor)(object)) owner = object;
|
|
378
377
|
else return null;
|
|
379
378
|
if (owner == null) return null;
|
|
380
379
|
for (const kid of owner.publicKeyIds) if (kid.href === keyId.href) return owner;
|
|
@@ -427,7 +426,7 @@ async function createProof(object, privateKey, keyId, { contextLoader, context,
|
|
|
427
426
|
digest.set(new Uint8Array(proofDigest), 0);
|
|
428
427
|
digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
|
|
429
428
|
const sig = await crypto.subtle.sign("Ed25519", privateKey, digest);
|
|
430
|
-
return new
|
|
429
|
+
return new __fedify_vocab.DataIntegrityProof({
|
|
431
430
|
cryptosuite: "eddsa-jcs-2022",
|
|
432
431
|
verificationMethod: keyId,
|
|
433
432
|
proofPurpose: "assertionMethod",
|
|
@@ -447,8 +446,8 @@ async function createProof(object, privateKey, keyId, { contextLoader, context,
|
|
|
447
446
|
*/
|
|
448
447
|
async function signObject(object, privateKey, keyId, options = {}) {
|
|
449
448
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
450
|
-
const tracer = tracerProvider.getTracer(
|
|
451
|
-
return await tracer.startActiveSpan("object_integrity_proofs.sign", { attributes: { "activitypub.object.type":
|
|
449
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
450
|
+
return await tracer.startActiveSpan("object_integrity_proofs.sign", { attributes: { "activitypub.object.type": (0, __fedify_vocab.getTypeId)(object).href } }, async (span) => {
|
|
452
451
|
try {
|
|
453
452
|
if (object.id != null) span.setAttribute("activitypub.object.id", object.id.href);
|
|
454
453
|
const existingProofs = [];
|
|
@@ -483,7 +482,7 @@ async function signObject(object, privateKey, keyId, options = {}) {
|
|
|
483
482
|
*/
|
|
484
483
|
async function verifyProof(jsonLd, proof, options = {}) {
|
|
485
484
|
const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
|
|
486
|
-
const tracer = tracerProvider.getTracer(
|
|
485
|
+
const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
|
|
487
486
|
return await tracer.startActiveSpan("object_integrity_proofs.verify", async (span) => {
|
|
488
487
|
if (span.isRecording()) {
|
|
489
488
|
if (proof.cryptosuite != null) span.setAttribute("object_integrity_proofs.cryptosuite", proof.cryptosuite);
|
|
@@ -507,7 +506,7 @@ async function verifyProof(jsonLd, proof, options = {}) {
|
|
|
507
506
|
}
|
|
508
507
|
async function verifyProofInternal(jsonLd, proof, options) {
|
|
509
508
|
if (typeof jsonLd !== "object" || proof.cryptosuite !== "eddsa-jcs-2022" || proof.verificationMethodId == null || proof.proofPurpose !== "assertionMethod" || proof.proofValue == null || proof.created == null) return null;
|
|
510
|
-
const publicKeyPromise = require_http.fetchKey(proof.verificationMethodId,
|
|
509
|
+
const publicKeyPromise = require_http.fetchKey(proof.verificationMethodId, __fedify_vocab.Multikey, options);
|
|
511
510
|
const proofConfig = {
|
|
512
511
|
"@context": jsonLd["@context"],
|
|
513
512
|
type: "DataIntegrityProof",
|
|
@@ -612,7 +611,7 @@ async function verifyObject(cls, jsonLd, options = {}) {
|
|
|
612
611
|
]);
|
|
613
612
|
const object = await cls.fromJsonLd(jsonLd, options);
|
|
614
613
|
const attributions = new Set(object.attributionIds.map((uri) => uri.href));
|
|
615
|
-
if (object instanceof
|
|
614
|
+
if (object instanceof __fedify_vocab.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
|
|
616
615
|
for await (const proof of object.getProofs(options)) {
|
|
617
616
|
const key = await verifyProof(jsonLd, proof, options);
|
|
618
617
|
if (key === null) return null;
|
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
import { Temporal } from "@js-temporal/polyfill";
|
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
|
4
4
|
|
|
5
|
-
import { deno_default } from "./
|
|
6
|
-
import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, getTypeId, isActor } from "./actor-B_gRMloq.js";
|
|
7
|
-
import { fetchKey, validateCryptoKey } from "./http-YhR_TMMQ.js";
|
|
5
|
+
import { deno_default, fetchKey, validateCryptoKey } from "./http-CL3G0rnf.js";
|
|
8
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
|
+
import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, getTypeId, isActor } from "@fedify/vocab";
|
|
9
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
10
|
-
import jsonld from "jsonld";
|
|
11
|
-
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
12
9
|
import { encodeHex } from "byte-encodings/hex";
|
|
13
10
|
import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
11
|
+
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
12
|
+
import jsonld from "jsonld";
|
|
14
13
|
import serialize from "json-canon";
|
|
15
14
|
|
|
16
15
|
//#region src/sig/ld.ts
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
|
|
2
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
3
|
+
import { URLPattern } from "urlpattern-polyfill";
|
|
4
|
+
globalThis.addEventListener = () => {};
|
|
5
|
+
|
|
6
|
+
import { cloneDeep } from "es-toolkit";
|
|
7
|
+
import { Router } from "uri-template-router";
|
|
8
|
+
import { parseTemplate } from "url-template";
|
|
9
|
+
|
|
10
|
+
//#region src/federation/router.ts
|
|
11
|
+
function cloneInnerRouter(router) {
|
|
12
|
+
const clone = new Router();
|
|
13
|
+
clone.nid = router.nid;
|
|
14
|
+
clone.fsm = cloneDeep(router.fsm);
|
|
15
|
+
clone.routeSet = new Set(router.routeSet);
|
|
16
|
+
clone.templateRouteMap = new Map(router.templateRouteMap);
|
|
17
|
+
clone.valueRouteMap = new Map(router.valueRouteMap);
|
|
18
|
+
clone.hierarchy = cloneDeep(router.hierarchy);
|
|
19
|
+
return clone;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* URL router and constructor based on URI Template
|
|
23
|
+
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)).
|
|
24
|
+
*/
|
|
25
|
+
var Router$1 = class Router$1 {
|
|
26
|
+
#router;
|
|
27
|
+
#templates;
|
|
28
|
+
#templateStrings;
|
|
29
|
+
/**
|
|
30
|
+
* Whether to ignore trailing slashes when matching paths.
|
|
31
|
+
* @since 1.6.0
|
|
32
|
+
*/
|
|
33
|
+
trailingSlashInsensitive;
|
|
34
|
+
/**
|
|
35
|
+
* Create a new {@link Router}.
|
|
36
|
+
* @param options Options for the router.
|
|
37
|
+
*/
|
|
38
|
+
constructor(options = {}) {
|
|
39
|
+
this.#router = new Router();
|
|
40
|
+
this.#templates = {};
|
|
41
|
+
this.#templateStrings = {};
|
|
42
|
+
this.trailingSlashInsensitive = options.trailingSlashInsensitive ?? false;
|
|
43
|
+
}
|
|
44
|
+
clone() {
|
|
45
|
+
const clone = new Router$1({ trailingSlashInsensitive: this.trailingSlashInsensitive });
|
|
46
|
+
clone.#router = cloneInnerRouter(this.#router);
|
|
47
|
+
clone.#templates = { ...this.#templates };
|
|
48
|
+
clone.#templateStrings = { ...this.#templateStrings };
|
|
49
|
+
return clone;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Checks if a path name exists in the router.
|
|
53
|
+
* @param name The name of the path.
|
|
54
|
+
* @returns `true` if the path name exists, otherwise `false`.
|
|
55
|
+
*/
|
|
56
|
+
has(name) {
|
|
57
|
+
return name in this.#templates;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Adds a new path rule to the router.
|
|
61
|
+
* @param template The path pattern.
|
|
62
|
+
* @param name The name of the path.
|
|
63
|
+
* @returns The names of the variables in the path pattern.
|
|
64
|
+
*/
|
|
65
|
+
add(template, name) {
|
|
66
|
+
if (!template.startsWith("/")) throw new RouterError("Path must start with a slash.");
|
|
67
|
+
const rule = this.#router.addTemplate(template, {}, name);
|
|
68
|
+
this.#templates[name] = parseTemplate(template);
|
|
69
|
+
this.#templateStrings[name] = template;
|
|
70
|
+
return new Set(rule.variables.map((v) => v.varname));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolves a path name and values from a URL, if any match.
|
|
74
|
+
* @param url The URL to resolve.
|
|
75
|
+
* @returns The name of the path and its values, if any match. Otherwise,
|
|
76
|
+
* `null`.
|
|
77
|
+
*/
|
|
78
|
+
route(url) {
|
|
79
|
+
let match = this.#router.resolveURI(url);
|
|
80
|
+
if (match == null) {
|
|
81
|
+
if (!this.trailingSlashInsensitive) return null;
|
|
82
|
+
url = url.endsWith("/") ? url.replace(/\/+$/, "") : `${url}/`;
|
|
83
|
+
match = this.#router.resolveURI(url);
|
|
84
|
+
if (match == null) return null;
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
name: match.matchValue,
|
|
88
|
+
template: this.#templateStrings[match.matchValue],
|
|
89
|
+
values: match.params
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Constructs a URL/path from a path name and values.
|
|
94
|
+
* @param name The name of the path.
|
|
95
|
+
* @param values The values to expand the path with.
|
|
96
|
+
* @returns The URL/path, if the name exists. Otherwise, `null`.
|
|
97
|
+
*/
|
|
98
|
+
build(name, values) {
|
|
99
|
+
if (name in this.#templates) return this.#templates[name].expand(values);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* An error thrown by the {@link Router}.
|
|
105
|
+
*/
|
|
106
|
+
var RouterError = class extends Error {
|
|
107
|
+
/**
|
|
108
|
+
* Create a new {@link RouterError}.
|
|
109
|
+
* @param message The error message.
|
|
110
|
+
*/
|
|
111
|
+
constructor(message) {
|
|
112
|
+
super(message);
|
|
113
|
+
this.name = "RouterError";
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
export { Router$1 as Router, RouterError };
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { URLPattern } from "urlpattern-polyfill";
|
|
4
4
|
globalThis.addEventListener = () => {};
|
|
5
5
|
|
|
6
|
-
import { deno_default } from "./
|
|
7
|
-
import { doubleKnock } from "./http-
|
|
6
|
+
import { deno_default } from "./deno-DGx1JZHr.js";
|
|
7
|
+
import { doubleKnock } from "./http-LGtYlSfN.js";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
9
9
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
10
10
|
|
|
@@ -120,7 +120,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
120
120
|
statusText: response.statusText,
|
|
121
121
|
error
|
|
122
122
|
});
|
|
123
|
-
throw new
|
|
123
|
+
throw new SendActivityError(inbox, response.status, `Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`, error);
|
|
124
124
|
}
|
|
125
125
|
span.addEvent("activitypub.activity.sent", {
|
|
126
126
|
"activitypub.activity.json": JSON.stringify(activity),
|
|
@@ -128,6 +128,40 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
|
|
|
128
128
|
"activitypub.activity.id": activityId ?? ""
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* An error that is thrown when an activity fails to send to a remote inbox.
|
|
133
|
+
* It contains structured information about the failure, including the HTTP
|
|
134
|
+
* status code, the inbox URL, and the response body.
|
|
135
|
+
* @since 2.0.0
|
|
136
|
+
*/
|
|
137
|
+
var SendActivityError = class extends Error {
|
|
138
|
+
/**
|
|
139
|
+
* The inbox URL that the activity was being sent to.
|
|
140
|
+
*/
|
|
141
|
+
inbox;
|
|
142
|
+
/**
|
|
143
|
+
* The HTTP status code returned by the inbox.
|
|
144
|
+
*/
|
|
145
|
+
statusCode;
|
|
146
|
+
/**
|
|
147
|
+
* The response body from the inbox, if any.
|
|
148
|
+
*/
|
|
149
|
+
responseBody;
|
|
150
|
+
/**
|
|
151
|
+
* Creates a new {@link SendActivityError}.
|
|
152
|
+
* @param inbox The inbox URL.
|
|
153
|
+
* @param statusCode The HTTP status code.
|
|
154
|
+
* @param message The error message.
|
|
155
|
+
* @param responseBody The response body.
|
|
156
|
+
*/
|
|
157
|
+
constructor(inbox, statusCode, message, responseBody) {
|
|
158
|
+
super(message);
|
|
159
|
+
this.name = "SendActivityError";
|
|
160
|
+
this.inbox = inbox;
|
|
161
|
+
this.statusCode = statusCode;
|
|
162
|
+
this.responseBody = responseBody;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
131
165
|
|
|
132
166
|
//#endregion
|
|
133
|
-
export { extractInboxes, sendActivity };
|
|
167
|
+
export { SendActivityError, extractInboxes, sendActivity };
|