@fedify/fedify 2.3.0-dev.1110 → 2.3.0-dev.1119
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/{assert_rejects-B-qJtC9Z.mjs → assert_rejects-DQP-q39h.mjs} +27 -2
- package/dist/{builder-B-Y6fwSu.mjs → builder-Ond_h57y.mjs} +3 -3
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/outgoing-jsonld.test.mjs +1 -1
- package/dist/compat/public-audience.test.mjs +1 -1
- package/dist/compat/transformers.test.mjs +2 -2
- package/dist/{context-C0C_sRha.d.cts → context-Ch-ZLyTQ.d.cts} +1 -1
- package/dist/{context-Dqgt8saU.d.ts → context-cSUMk2da.d.ts} +1 -1
- package/dist/{deno-hqC7tKJn.mjs → deno-DVsHS7rA.mjs} +1 -1
- package/dist/{docloader-BOEuuXkX.mjs → docloader-WsWfKaE5.mjs} +2 -2
- package/dist/federation/builder.test.mjs +3 -3
- package/dist/federation/collection.test.mjs +2 -2
- package/dist/federation/handler.test.mjs +8 -7
- package/dist/federation/idempotency.test.mjs +5 -5
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/keycache.test.mjs +1 -1
- package/dist/federation/kv.test.mjs +2 -2
- package/dist/federation/metrics.test.d.mts +2 -0
- package/dist/federation/metrics.test.mjs +107 -0
- package/dist/federation/middleware.test.mjs +390 -10
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +2 -2
- package/dist/federation/mod.d.ts +2 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/mq.test.mjs +2 -2
- package/dist/federation/negotiation.test.mjs +2 -2
- package/dist/federation/router.test.mjs +2 -2
- package/dist/federation/send.test.mjs +11 -11
- package/dist/federation/webfinger.test.mjs +3 -3
- package/dist/{getMachineId-bsd-etIyxDet.mjs → getMachineId-bsd-BY01PL1n.mjs} +1 -1
- package/dist/{getMachineId-darwin-D23zTf4g.mjs → getMachineId-darwin-Dr1gkBkp.mjs} +1 -1
- package/dist/{getMachineId-win-Dpap6v5i.mjs → getMachineId-win-QEYwcJiy.mjs} +1 -1
- package/dist/{http-O8MYWwk8.js → http-CouJSFVK.js} +461 -37
- package/dist/{http-DV0il3vk.cjs → http-CubOB9wq.cjs} +513 -35
- package/dist/{http-BDZeS5om.d.ts → http-D6LP89UO.d.ts} +7 -1
- package/dist/{http-C87EWkO0.d.cts → http-D6aw3j2U.d.cts} +7 -1
- package/dist/{http-BLopFpvC.mjs → http-DUV8ysti.mjs} +86 -37
- package/dist/{key-DW1EVmtP.mjs → key-BoWaYRHm.mjs} +1 -1
- package/dist/{kv-cache-C3NWWiTg.js → kv-cache-DBNpsneh.js} +1 -1
- package/dist/{kv-cache-Dya-TWMe.cjs → kv-cache-Dz31ATUT.cjs} +1 -1
- package/dist/{ld-BNkk2Yal.mjs → ld-B5K1mSuG.mjs} +60 -9
- package/dist/{send-hokVCPu6.mjs → metrics-C4attqv0.mjs} +124 -224
- package/dist/{middleware-D6FbOjuK.mjs → middleware-BDKFRjue.mjs} +1 -1
- package/dist/{middleware-DUWeXjZR.cjs → middleware-CmsDtIHI.cjs} +75 -309
- package/dist/{middleware-CjzI3aYo.js → middleware-Dtjz-hSk.js} +46 -280
- package/dist/{middleware-DA2WTBr4.mjs → middleware-t0jC8I99.mjs} +59 -34
- package/dist/{mod-DXY9JF28.d.cts → mod-B-Lin9Sy.d.ts} +25 -2
- package/dist/{mod-DHO9lk3D.d.ts → mod-BDhgfjP7.d.cts} +25 -2
- package/dist/{mod-B0rWmfW5.d.cts → mod-BR_BB0bh.d.cts} +1 -1
- package/dist/{mod-Dx3-hqyo.d.ts → mod-C6E8rkcz.d.ts} +1 -1
- package/dist/{mod-BhU_H1I_.d.ts → mod-DLrRb0dx.d.ts} +1 -1
- package/dist/{mod-CLPnQPsv.d.cts → mod-P9tE2WmM.d.cts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/client.test.mjs +2 -2
- package/dist/nodeinfo/handler.test.mjs +3 -3
- package/dist/nodeinfo/types.test.mjs +2 -2
- package/dist/otel/exporter.test.mjs +2 -2
- package/dist/{outgoing-jsonld-BgFLCJQ_.mjs → outgoing-jsonld-BNL8AC14.mjs} +1 -1
- package/dist/{owner-jvJAtR5O.mjs → owner-hDxI0ufu.mjs} +2 -2
- package/dist/{proof-BD92WeqV.cjs → proof-BUWfVr6Q.cjs} +78 -11
- package/dist/{proof-mfmHH9j0.mjs → proof-DhVuz4bc.mjs} +25 -7
- package/dist/{proof-5kT7OUPV.js → proof-n60t8o9P.js} +78 -11
- package/dist/send-BPhyR5Oo.mjs +225 -0
- package/dist/sig/accept.test.mjs +1 -1
- package/dist/sig/http.test.mjs +212 -6
- package/dist/sig/key.test.mjs +4 -4
- package/dist/sig/ld.test.mjs +138 -5
- 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 +4 -4
- package/dist/sig/proof.test.mjs +167 -6
- package/dist/{std__assert-CRDpx_HF.mjs → std__assert-BTEgfoJo.mjs} +2 -27
- package/dist/utils/docloader.test.mjs +5 -5
- 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/package.json +5 -5
- /package/dist/{accept-CceiKpCy.mjs → accept-CgDcxvjV.mjs} +0 -0
- /package/dist/{activity-listener-tztVvlNb.mjs → activity-listener-BeTGV3wc.mjs} +0 -0
- /package/dist/{client-B_A6mfn3.mjs → client-Bneh_DYR.mjs} +0 -0
- /package/dist/{collection-CA3V5zyK.mjs → collection-Cc3DVAhE.mjs} +0 -0
- /package/dist/{execAsync-DCBrgFiV.mjs → execAsync-Dxb7rNf3.mjs} +0 -0
- /package/dist/{getMachineId-linux-ObI47Hql.mjs → getMachineId-linux-Bbhofx-s.mjs} +0 -0
- /package/dist/{getMachineId-unsupported-Ddu-PFeh.mjs → getMachineId-unsupported-dIOte2Ct.mjs} +0 -0
- /package/dist/{keys-C3kae-6B.mjs → keys-CSYsOMFG.mjs} +0 -0
- /package/dist/{kv-x2IvBUyq.mjs → kv-QHE0oeM3.mjs} +0 -0
- /package/dist/{kv-cache-CiiNwT6W.mjs → kv-cache-DihufyAQ.mjs} +0 -0
- /package/dist/{public-audience-N3pyOx2p.mjs → public-audience-c9zmYKgA.mjs} +0 -0
- /package/dist/{types-BFowWFTT.mjs → types-D09GN0uZ.mjs} +0 -0
|
@@ -11,7 +11,7 @@ let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conve
|
|
|
11
11
|
let byte_encodings_base64 = require("byte-encodings/base64");
|
|
12
12
|
//#region deno.json
|
|
13
13
|
var name = "@fedify/fedify";
|
|
14
|
-
var version = "2.3.0-dev.
|
|
14
|
+
var version = "2.3.0-dev.1119+6cc02662";
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/sig/accept.ts
|
|
17
17
|
/**
|
|
@@ -152,6 +152,382 @@ function fulfillAcceptSignature(entry, localKeyId, localAlg) {
|
|
|
152
152
|
};
|
|
153
153
|
}
|
|
154
154
|
//#endregion
|
|
155
|
+
//#region src/federation/metrics.ts
|
|
156
|
+
var FederationMetrics = class {
|
|
157
|
+
deliverySent;
|
|
158
|
+
deliveryPermanentFailure;
|
|
159
|
+
signatureVerificationFailure;
|
|
160
|
+
signatureVerificationDuration;
|
|
161
|
+
signatureKeyFetchDuration;
|
|
162
|
+
deliveryDuration;
|
|
163
|
+
inboxProcessingDuration;
|
|
164
|
+
httpServerRequestCount;
|
|
165
|
+
httpServerRequestDuration;
|
|
166
|
+
queueTaskEnqueued;
|
|
167
|
+
queueTaskStarted;
|
|
168
|
+
queueTaskCompleted;
|
|
169
|
+
queueTaskFailed;
|
|
170
|
+
queueTaskDuration;
|
|
171
|
+
queueTaskInFlight;
|
|
172
|
+
fanoutRecipients;
|
|
173
|
+
inboxActivity;
|
|
174
|
+
outboxActivity;
|
|
175
|
+
constructor(meterProvider) {
|
|
176
|
+
const meter = meterProvider.getMeter(name, version);
|
|
177
|
+
this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
|
|
178
|
+
description: "ActivityPub delivery attempts.",
|
|
179
|
+
unit: "{attempt}"
|
|
180
|
+
});
|
|
181
|
+
this.deliveryPermanentFailure = meter.createCounter("activitypub.delivery.permanent_failure", {
|
|
182
|
+
description: "ActivityPub deliveries abandoned as permanent failures.",
|
|
183
|
+
unit: "{failure}"
|
|
184
|
+
});
|
|
185
|
+
this.signatureVerificationFailure = meter.createCounter("activitypub.signature.verification_failure", {
|
|
186
|
+
description: "ActivityPub signature verification failures.",
|
|
187
|
+
unit: "{failure}"
|
|
188
|
+
});
|
|
189
|
+
this.signatureVerificationDuration = meter.createHistogram("activitypub.signature.verification.duration", {
|
|
190
|
+
description: "Duration of ActivityPub signature verification, including local key lookup and remote key fetches.",
|
|
191
|
+
unit: "ms"
|
|
192
|
+
});
|
|
193
|
+
this.signatureKeyFetchDuration = meter.createHistogram("activitypub.signature.key_fetch.duration", {
|
|
194
|
+
description: "Duration of public key lookup performed during ActivityPub signature verification.",
|
|
195
|
+
unit: "ms"
|
|
196
|
+
});
|
|
197
|
+
this.deliveryDuration = meter.createHistogram("activitypub.delivery.duration", {
|
|
198
|
+
description: "Duration of ActivityPub delivery attempts.",
|
|
199
|
+
unit: "ms"
|
|
200
|
+
});
|
|
201
|
+
this.inboxProcessingDuration = meter.createHistogram("activitypub.inbox.processing_duration", {
|
|
202
|
+
description: "Duration of ActivityPub inbox listener processing.",
|
|
203
|
+
unit: "ms"
|
|
204
|
+
});
|
|
205
|
+
this.httpServerRequestCount = meter.createCounter("fedify.http.server.request.count", {
|
|
206
|
+
description: "HTTP requests handled by Federation.fetch().",
|
|
207
|
+
unit: "{request}"
|
|
208
|
+
});
|
|
209
|
+
this.httpServerRequestDuration = meter.createHistogram("fedify.http.server.request.duration", {
|
|
210
|
+
description: "Duration of HTTP requests handled by Federation.fetch().",
|
|
211
|
+
unit: "ms",
|
|
212
|
+
advice: { explicitBucketBoundaries: [
|
|
213
|
+
5,
|
|
214
|
+
10,
|
|
215
|
+
25,
|
|
216
|
+
50,
|
|
217
|
+
75,
|
|
218
|
+
100,
|
|
219
|
+
250,
|
|
220
|
+
500,
|
|
221
|
+
750,
|
|
222
|
+
1e3,
|
|
223
|
+
2500,
|
|
224
|
+
5e3,
|
|
225
|
+
7500,
|
|
226
|
+
1e4
|
|
227
|
+
] }
|
|
228
|
+
});
|
|
229
|
+
this.queueTaskEnqueued = meter.createCounter("fedify.queue.task.enqueued", {
|
|
230
|
+
description: "Tasks Fedify enqueued for inbox, outbox, or fanout work.",
|
|
231
|
+
unit: "{task}"
|
|
232
|
+
});
|
|
233
|
+
this.queueTaskStarted = meter.createCounter("fedify.queue.task.started", {
|
|
234
|
+
description: "Tasks Fedify began processing as a queue worker.",
|
|
235
|
+
unit: "{task}"
|
|
236
|
+
});
|
|
237
|
+
this.queueTaskCompleted = meter.createCounter("fedify.queue.task.completed", {
|
|
238
|
+
description: "Queue tasks Fedify finished processing without throwing.",
|
|
239
|
+
unit: "{task}"
|
|
240
|
+
});
|
|
241
|
+
this.queueTaskFailed = meter.createCounter("fedify.queue.task.failed", {
|
|
242
|
+
description: "Queue tasks Fedify abandoned because processing threw.",
|
|
243
|
+
unit: "{task}"
|
|
244
|
+
});
|
|
245
|
+
this.queueTaskDuration = meter.createHistogram("fedify.queue.task.duration", {
|
|
246
|
+
description: "Duration of queue task processing in Fedify workers.",
|
|
247
|
+
unit: "ms",
|
|
248
|
+
advice: { explicitBucketBoundaries: [
|
|
249
|
+
5,
|
|
250
|
+
10,
|
|
251
|
+
25,
|
|
252
|
+
50,
|
|
253
|
+
75,
|
|
254
|
+
100,
|
|
255
|
+
250,
|
|
256
|
+
500,
|
|
257
|
+
750,
|
|
258
|
+
1e3,
|
|
259
|
+
2500,
|
|
260
|
+
5e3,
|
|
261
|
+
7500,
|
|
262
|
+
1e4
|
|
263
|
+
] }
|
|
264
|
+
});
|
|
265
|
+
this.queueTaskInFlight = meter.createUpDownCounter("fedify.queue.task.in_flight", {
|
|
266
|
+
description: "Queue tasks currently being processed in this Fedify process.",
|
|
267
|
+
unit: "{task}"
|
|
268
|
+
});
|
|
269
|
+
this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
|
|
270
|
+
description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
|
|
271
|
+
unit: "{recipient}"
|
|
272
|
+
});
|
|
273
|
+
this.inboxActivity = meter.createCounter("activitypub.inbox.activity", {
|
|
274
|
+
description: "ActivityPub activities observed at the inbox lifecycle level: queued, processed, retried, rejected, or abandoned.",
|
|
275
|
+
unit: "{activity}"
|
|
276
|
+
});
|
|
277
|
+
this.outboxActivity = meter.createCounter("activitypub.outbox.activity", {
|
|
278
|
+
description: "ActivityPub activities observed at the outbox lifecycle level: queued, retried, or abandoned. Per-recipient delivery counters live on `activitypub.delivery.*`.",
|
|
279
|
+
unit: "{activity}"
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
recordDelivery(inbox, durationMs, success, activityType) {
|
|
283
|
+
const deliveryAttributes = {
|
|
284
|
+
"activitypub.remote.host": getRemoteHost(inbox),
|
|
285
|
+
"activitypub.delivery.success": success
|
|
286
|
+
};
|
|
287
|
+
if (activityType != null) deliveryAttributes["activitypub.activity.type"] = activityType;
|
|
288
|
+
this.deliverySent.add(1, deliveryAttributes);
|
|
289
|
+
this.deliveryDuration.record(durationMs, deliveryAttributes);
|
|
290
|
+
}
|
|
291
|
+
recordPermanentFailure(inbox, statusCode) {
|
|
292
|
+
this.deliveryPermanentFailure.add(1, {
|
|
293
|
+
"activitypub.remote.host": getRemoteHost(inbox),
|
|
294
|
+
"http.response.status_code": statusCode
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
recordSignatureVerificationFailure(reason, remoteHost) {
|
|
298
|
+
const attributes = { "activitypub.verification.failure_reason": reason };
|
|
299
|
+
if (remoteHost != null) attributes["activitypub.remote.host"] = remoteHost;
|
|
300
|
+
this.signatureVerificationFailure.add(1, attributes);
|
|
301
|
+
}
|
|
302
|
+
recordSignatureVerificationDuration(durationMs, kind, result, extra = {}) {
|
|
303
|
+
const attributes = {
|
|
304
|
+
"activitypub.signature.kind": kind,
|
|
305
|
+
"activitypub.signature.result": result
|
|
306
|
+
};
|
|
307
|
+
if (extra.algorithm != null) attributes["http_signatures.algorithm"] = extra.algorithm;
|
|
308
|
+
if (extra.failureReason != null) attributes["http_signatures.failure_reason"] = extra.failureReason;
|
|
309
|
+
if (extra.ldType != null) attributes["ld_signatures.type"] = extra.ldType;
|
|
310
|
+
if (extra.cryptosuite != null) attributes["object_integrity_proofs.cryptosuite"] = extra.cryptosuite;
|
|
311
|
+
this.signatureVerificationDuration.record(durationMs, attributes);
|
|
312
|
+
}
|
|
313
|
+
recordSignatureKeyFetchDuration(durationMs, kind, result) {
|
|
314
|
+
this.signatureKeyFetchDuration.record(durationMs, {
|
|
315
|
+
"activitypub.signature.kind": kind,
|
|
316
|
+
"activitypub.signature.key_fetch.result": result
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
recordInboxProcessingDuration(activityType, durationMs) {
|
|
320
|
+
this.inboxProcessingDuration.record(durationMs, { "activitypub.activity.type": activityType });
|
|
321
|
+
}
|
|
322
|
+
recordHttpServerRequest(method, endpoint, durationMs, options = {}) {
|
|
323
|
+
const attributes = {
|
|
324
|
+
"http.request.method": normalizeHttpMethod(method),
|
|
325
|
+
"fedify.endpoint": endpoint
|
|
326
|
+
};
|
|
327
|
+
if (options.statusCode != null) attributes["http.response.status_code"] = options.statusCode;
|
|
328
|
+
if (options.routeTemplate != null) attributes["fedify.route.template"] = options.routeTemplate;
|
|
329
|
+
this.httpServerRequestCount.add(1, attributes);
|
|
330
|
+
this.httpServerRequestDuration.record(durationMs, attributes);
|
|
331
|
+
}
|
|
332
|
+
recordQueueTaskEnqueued(common, attempt) {
|
|
333
|
+
const attributes = buildQueueTaskAttributes(common);
|
|
334
|
+
attributes["fedify.queue.task.attempt"] = attempt;
|
|
335
|
+
this.queueTaskEnqueued.add(1, attributes);
|
|
336
|
+
}
|
|
337
|
+
recordQueueTaskStarted(common) {
|
|
338
|
+
this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
|
|
339
|
+
}
|
|
340
|
+
incrementQueueTaskInFlight(common) {
|
|
341
|
+
this.queueTaskInFlight.add(1, buildQueueTaskInFlightAttributes(common));
|
|
342
|
+
}
|
|
343
|
+
decrementQueueTaskInFlight(common) {
|
|
344
|
+
this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
|
|
345
|
+
}
|
|
346
|
+
recordQueueTaskOutcome(common, result, durationMs) {
|
|
347
|
+
const attributes = buildQueueTaskAttributes(common);
|
|
348
|
+
attributes["fedify.queue.task.result"] = result;
|
|
349
|
+
if (result === "completed") this.queueTaskCompleted.add(1, attributes);
|
|
350
|
+
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
351
|
+
this.queueTaskDuration.record(durationMs, attributes);
|
|
352
|
+
}
|
|
353
|
+
recordFanoutRecipients(recipientCount, activityType) {
|
|
354
|
+
const attributes = {};
|
|
355
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
356
|
+
this.fanoutRecipients.record(recipientCount, attributes);
|
|
357
|
+
}
|
|
358
|
+
recordInboxActivity(result, activityType) {
|
|
359
|
+
this.inboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
360
|
+
}
|
|
361
|
+
recordOutboxActivity(result, activityType) {
|
|
362
|
+
this.outboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
function buildActivityLifecycleAttributes(result, activityType) {
|
|
366
|
+
const attributes = { "activitypub.processing.result": result };
|
|
367
|
+
if (activityType != null) attributes["activitypub.activity.type"] = activityType;
|
|
368
|
+
return attributes;
|
|
369
|
+
}
|
|
370
|
+
function buildQueueTaskAttributes(common) {
|
|
371
|
+
const attributes = { "fedify.queue.role": common.role };
|
|
372
|
+
const backend = getQueueBackend(common.queue);
|
|
373
|
+
if (backend != null) attributes["fedify.queue.backend"] = backend;
|
|
374
|
+
const nativeRetrial = common.queue?.nativeRetrial;
|
|
375
|
+
if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
|
|
376
|
+
if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
|
|
377
|
+
return attributes;
|
|
378
|
+
}
|
|
379
|
+
function buildQueueTaskInFlightAttributes(common) {
|
|
380
|
+
return buildQueueTaskAttributes({
|
|
381
|
+
role: common.role,
|
|
382
|
+
queue: common.queue
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Returns the constructor name of the given message queue, when it is a
|
|
387
|
+
* meaningful identifier. Used as a best-effort `fedify.queue.backend`
|
|
388
|
+
* attribute on queue task metrics; returns `undefined` for plain object
|
|
389
|
+
* literals (whose constructor is `Object`) so the attribute does not appear
|
|
390
|
+
* with a non-informative value.
|
|
391
|
+
* @since 2.3.0
|
|
392
|
+
*/
|
|
393
|
+
function getQueueBackend(queue) {
|
|
394
|
+
const name = queue?.constructor?.name;
|
|
395
|
+
if (name == null || name === "" || name === "Object") return void 0;
|
|
396
|
+
return name;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
|
|
400
|
+
* for the initial attempt, also records
|
|
401
|
+
* `activitypub.outbox.activity{queued}`.
|
|
402
|
+
*
|
|
403
|
+
* Both `Context.sendActivity()` and `OutboxContext.forwardActivity()` enqueue
|
|
404
|
+
* outbox messages with the same metric attributes (role, queue, activity
|
|
405
|
+
* type, attempt), so they share this helper rather than each defining a local
|
|
406
|
+
* closure. Retry enqueues (attempt > 0) intentionally do not record a
|
|
407
|
+
* second `activitypub.outbox.activity{queued}`; retries are reported as
|
|
408
|
+
* `result=retried` from the retry-scheduling site, which has the failure
|
|
409
|
+
* context.
|
|
410
|
+
* @since 2.3.0
|
|
411
|
+
*/
|
|
412
|
+
function recordOutboxEnqueue(meterProvider, outboxQueue, message) {
|
|
413
|
+
const metrics = getFederationMetrics(meterProvider);
|
|
414
|
+
metrics.recordQueueTaskEnqueued({
|
|
415
|
+
role: "outbox",
|
|
416
|
+
queue: outboxQueue,
|
|
417
|
+
activityType: message.activityType
|
|
418
|
+
}, message.attempt);
|
|
419
|
+
if (message.attempt === 0) metrics.recordOutboxActivity("queued", message.activityType);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Records `activitypub.fanout.recipients` with the number of recipient
|
|
423
|
+
* inboxes a single fanout produced. The histogram is unitless count
|
|
424
|
+
* (one measurement per fanout enqueue). Recipient URLs are deliberately
|
|
425
|
+
* not recorded; only the activity type, when known.
|
|
426
|
+
* @since 2.3.0
|
|
427
|
+
*/
|
|
428
|
+
function recordFanoutRecipients(meterProvider, recipientCount, activityType) {
|
|
429
|
+
getFederationMetrics(meterProvider).recordFanoutRecipients(recipientCount, activityType);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Records one `activitypub.inbox.activity` measurement. The
|
|
433
|
+
* `activitypub.processing.result` attribute is always present;
|
|
434
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
435
|
+
* the activity type.
|
|
436
|
+
* @since 2.3.0
|
|
437
|
+
*/
|
|
438
|
+
function recordInboxActivity(meterProvider, result, activityType) {
|
|
439
|
+
getFederationMetrics(meterProvider).recordInboxActivity(result, activityType);
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Records one `activitypub.outbox.activity` measurement. The
|
|
443
|
+
* `activitypub.processing.result` attribute is always present;
|
|
444
|
+
* `activitypub.activity.type` is recorded only when Fedify already knows
|
|
445
|
+
* the activity type (it is always known for outbox lifecycle events).
|
|
446
|
+
* @since 2.3.0
|
|
447
|
+
*/
|
|
448
|
+
function recordOutboxActivity(meterProvider, result, activityType) {
|
|
449
|
+
getFederationMetrics(meterProvider).recordOutboxActivity(result, activityType);
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Times an awaited public key fetch and records exactly one
|
|
453
|
+
* `activitypub.signature.key_fetch.duration` measurement, classifying the
|
|
454
|
+
* outcome as `hit`, `fetched`, or `error` based on the `cached` flag and
|
|
455
|
+
* whether the returned key is non-null. Errors thrown by the fetch are
|
|
456
|
+
* reported as `error` and rethrown, so verifier behavior is unchanged.
|
|
457
|
+
*
|
|
458
|
+
* Shared by the three signature verifiers (HTTP, Linked Data, Object
|
|
459
|
+
* Integrity Proofs); the only per-call variation is the
|
|
460
|
+
* `activitypub.signature.kind` attribute value.
|
|
461
|
+
* @since 2.3.0
|
|
462
|
+
*/
|
|
463
|
+
async function measureSignatureKeyFetch(meterProvider, kind, fetch) {
|
|
464
|
+
const start = performance.now();
|
|
465
|
+
try {
|
|
466
|
+
const result = await fetch();
|
|
467
|
+
getFederationMetrics(meterProvider).recordSignatureKeyFetchDuration(getDurationMs(start), kind, result.key != null ? result.cached ? "hit" : "fetched" : "error");
|
|
468
|
+
return result;
|
|
469
|
+
} catch (error) {
|
|
470
|
+
getFederationMetrics(meterProvider).recordSignatureKeyFetchDuration(getDurationMs(start), kind, "error");
|
|
471
|
+
throw error;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Whether the given thrown value is an `AbortError`.
|
|
476
|
+
*
|
|
477
|
+
* `processQueuedTask` distinguishes aborted tasks (recorded as
|
|
478
|
+
* `fedify.queue.task.result=aborted`) from other failures so that backend
|
|
479
|
+
* shutdown signals do not inflate the `fedify.queue.task.failed` counter.
|
|
480
|
+
* @since 2.3.0
|
|
481
|
+
*/
|
|
482
|
+
function isAbortError$1(error) {
|
|
483
|
+
if (error == null || typeof error !== "object") return false;
|
|
484
|
+
const name = error.name;
|
|
485
|
+
return typeof name === "string" && name === "AbortError";
|
|
486
|
+
}
|
|
487
|
+
const KNOWN_HTTP_METHODS = new Set([
|
|
488
|
+
"CONNECT",
|
|
489
|
+
"DELETE",
|
|
490
|
+
"GET",
|
|
491
|
+
"HEAD",
|
|
492
|
+
"OPTIONS",
|
|
493
|
+
"PATCH",
|
|
494
|
+
"POST",
|
|
495
|
+
"PUT",
|
|
496
|
+
"QUERY",
|
|
497
|
+
"TRACE"
|
|
498
|
+
]);
|
|
499
|
+
function normalizeHttpMethod(method) {
|
|
500
|
+
const upper = method.toUpperCase();
|
|
501
|
+
return KNOWN_HTTP_METHODS.has(upper) ? upper : "_OTHER";
|
|
502
|
+
}
|
|
503
|
+
const federationMetrics = /* @__PURE__ */ new WeakMap();
|
|
504
|
+
/**
|
|
505
|
+
* Gets the cached Fedify metric instruments for a meter provider.
|
|
506
|
+
* @since 2.3.0
|
|
507
|
+
*/
|
|
508
|
+
function getFederationMetrics(meterProvider = _opentelemetry_api.metrics.getMeterProvider()) {
|
|
509
|
+
let instruments = federationMetrics.get(meterProvider);
|
|
510
|
+
if (instruments == null) {
|
|
511
|
+
instruments = new FederationMetrics(meterProvider);
|
|
512
|
+
federationMetrics.set(meterProvider, instruments);
|
|
513
|
+
}
|
|
514
|
+
return instruments;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Gets the bounded remote host attribute value for a URL.
|
|
518
|
+
* @since 2.3.0
|
|
519
|
+
*/
|
|
520
|
+
function getRemoteHost(url) {
|
|
521
|
+
return url.hostname;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Gets an elapsed duration in milliseconds from a `performance.now()` value.
|
|
525
|
+
* @since 2.3.0
|
|
526
|
+
*/
|
|
527
|
+
function getDurationMs(start) {
|
|
528
|
+
return Math.max(0, performance.now() - start);
|
|
529
|
+
}
|
|
530
|
+
//#endregion
|
|
155
531
|
//#region src/sig/key.ts
|
|
156
532
|
/**
|
|
157
533
|
* Checks if the given key is valid and supported. No-op if the key is valid,
|
|
@@ -800,6 +1176,27 @@ function parseKeyId(value) {
|
|
|
800
1176
|
function getKeyFetchErrorName(error) {
|
|
801
1177
|
return error.name || error.constructor.name || "Error";
|
|
802
1178
|
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Known draft-cavage `algorithm` parameter values, used to keep the
|
|
1181
|
+
* `http_signatures.algorithm` metric attribute on a bounded set. The header
|
|
1182
|
+
* field is attacker-controlled and not used to select the verification
|
|
1183
|
+
* algorithm, so unknown values are dropped from the metric to prevent
|
|
1184
|
+
* cardinality blow-up.
|
|
1185
|
+
*/
|
|
1186
|
+
const DRAFT_KNOWN_ALGORITHMS = new Set([
|
|
1187
|
+
"ecdsa-sha256",
|
|
1188
|
+
"ecdsa-sha384",
|
|
1189
|
+
"ecdsa-sha512",
|
|
1190
|
+
"ed25519",
|
|
1191
|
+
"hs2019",
|
|
1192
|
+
"rsa-sha1",
|
|
1193
|
+
"rsa-sha256",
|
|
1194
|
+
"rsa-sha512"
|
|
1195
|
+
]);
|
|
1196
|
+
function classifyHttpVerifyResult(result) {
|
|
1197
|
+
if (result.verified) return "verified";
|
|
1198
|
+
return result.reason.type === "noSignature" ? "missing" : "rejected";
|
|
1199
|
+
}
|
|
803
1200
|
function recordVerificationResult(span, result) {
|
|
804
1201
|
span.setAttribute("http_signatures.verified", result.verified);
|
|
805
1202
|
if (result.verified === true) return;
|
|
@@ -843,27 +1240,37 @@ async function verifyRequestDetailed(request, options = {}) {
|
|
|
843
1240
|
span.setAttribute(_opentelemetry_semantic_conventions.ATTR_URL_FULL, request.url);
|
|
844
1241
|
for (const [name, value] of request.headers) span.setAttribute((0, _opentelemetry_semantic_conventions.ATTR_HTTP_REQUEST_HEADER)(name), value);
|
|
845
1242
|
}
|
|
1243
|
+
const start = performance.now();
|
|
1244
|
+
const metricsContext = {};
|
|
1245
|
+
let result;
|
|
1246
|
+
let threw = false;
|
|
846
1247
|
try {
|
|
847
1248
|
let spec = options.spec;
|
|
848
1249
|
if (spec == null) spec = request.headers.has("Signature-Input") ? "rfc9421" : "draft-cavage-http-signatures-12";
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
else result = await verifyRequestDraft(request, span, options);
|
|
1250
|
+
if (spec === "rfc9421") result = await verifyRequestRfc9421(request, span, metricsContext, options);
|
|
1251
|
+
else result = await verifyRequestDraft(request, span, metricsContext, options);
|
|
852
1252
|
recordVerificationResult(span, result);
|
|
853
1253
|
if (!result.verified) span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
854
1254
|
return result;
|
|
855
1255
|
} catch (error) {
|
|
1256
|
+
threw = true;
|
|
856
1257
|
span.setStatus({
|
|
857
1258
|
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
858
1259
|
message: String(error)
|
|
859
1260
|
});
|
|
860
1261
|
throw error;
|
|
861
1262
|
} finally {
|
|
1263
|
+
const classified = threw ? "error" : classifyHttpVerifyResult(result);
|
|
1264
|
+
const failureReason = result != null && !result.verified && result.reason.type !== "noSignature" ? result.reason.type : void 0;
|
|
1265
|
+
getFederationMetrics(options.meterProvider).recordSignatureVerificationDuration(getDurationMs(start), "http", classified, {
|
|
1266
|
+
algorithm: metricsContext.algorithm,
|
|
1267
|
+
failureReason
|
|
1268
|
+
});
|
|
862
1269
|
span.end();
|
|
863
1270
|
}
|
|
864
1271
|
});
|
|
865
1272
|
}
|
|
866
|
-
async function verifyRequestDraft(request, span, { documentLoader, contextLoader, timeWindow, currentTime, keyCache, tracerProvider } = {}) {
|
|
1273
|
+
async function verifyRequestDraft(request, span, metricsContext, { documentLoader, contextLoader, timeWindow, currentTime, keyCache, meterProvider, tracerProvider } = {}) {
|
|
867
1274
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
868
1275
|
"fedify",
|
|
869
1276
|
"sig",
|
|
@@ -1011,13 +1418,17 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
1011
1418
|
const keyIdUrl = parseKeyId(keyId);
|
|
1012
1419
|
if (keyIdUrl == null) return invalidSignatureResult(null);
|
|
1013
1420
|
span?.setAttribute("http_signatures.key_id", keyId);
|
|
1014
|
-
if ("algorithm" in sigValues)
|
|
1015
|
-
|
|
1421
|
+
if ("algorithm" in sigValues) {
|
|
1422
|
+
span?.setAttribute("http_signatures.algorithm", sigValues.algorithm);
|
|
1423
|
+
const normalizedAlgorithm = sigValues.algorithm.toLowerCase();
|
|
1424
|
+
if (DRAFT_KNOWN_ALGORITHMS.has(normalizedAlgorithm)) metricsContext.algorithm = normalizedAlgorithm;
|
|
1425
|
+
}
|
|
1426
|
+
const { key, cached, fetchError } = await measureSignatureKeyFetch(meterProvider, "http", () => fetchKeyDetailed(keyIdUrl, _fedify_vocab.CryptographicKey, {
|
|
1016
1427
|
documentLoader,
|
|
1017
1428
|
contextLoader,
|
|
1018
1429
|
keyCache,
|
|
1019
1430
|
tracerProvider
|
|
1020
|
-
});
|
|
1431
|
+
}));
|
|
1021
1432
|
if (fetchError != null) return keyFetchErrorResult(keyIdUrl, fetchError);
|
|
1022
1433
|
if (key == null) return invalidSignatureResult(keyIdUrl);
|
|
1023
1434
|
const headerNames = headers.split(/\s+/g);
|
|
@@ -1039,7 +1450,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
1039
1450
|
signature,
|
|
1040
1451
|
message
|
|
1041
1452
|
});
|
|
1042
|
-
return await
|
|
1453
|
+
return await verifyRequestDraft(originalRequest, span, metricsContext, {
|
|
1043
1454
|
documentLoader,
|
|
1044
1455
|
contextLoader,
|
|
1045
1456
|
timeWindow,
|
|
@@ -1047,7 +1458,9 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
1047
1458
|
keyCache: {
|
|
1048
1459
|
get: () => Promise.resolve(void 0),
|
|
1049
1460
|
set: async (keyId, key) => await keyCache?.set(keyId, key)
|
|
1050
|
-
}
|
|
1461
|
+
},
|
|
1462
|
+
meterProvider,
|
|
1463
|
+
tracerProvider
|
|
1051
1464
|
});
|
|
1052
1465
|
}
|
|
1053
1466
|
logger.debug("Failed to verify with the fetched key {keyId}; signature {signature} is invalid. Check if the key is correct or if the signed message is correct. The message to sign is:\n{message}", {
|
|
@@ -1123,7 +1536,7 @@ async function verifyRfc9421ContentDigest(digestHeader, body) {
|
|
|
1123
1536
|
}
|
|
1124
1537
|
return false;
|
|
1125
1538
|
}
|
|
1126
|
-
async function verifyRequestRfc9421(request, span, { documentLoader, contextLoader, timeWindow, currentTime, keyCache, tracerProvider } = {}) {
|
|
1539
|
+
async function verifyRequestRfc9421(request, span, metricsContext, { documentLoader, contextLoader, timeWindow, currentTime, keyCache, meterProvider, tracerProvider } = {}) {
|
|
1127
1540
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
1128
1541
|
"fedify",
|
|
1129
1542
|
"sig",
|
|
@@ -1157,9 +1570,14 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1157
1570
|
return invalidSignatureResult(null);
|
|
1158
1571
|
}
|
|
1159
1572
|
let failure = noSignatureResult();
|
|
1573
|
+
let failureAlgorithm;
|
|
1574
|
+
const setFailure = (result, algorithm) => {
|
|
1575
|
+
failure = result;
|
|
1576
|
+
failureAlgorithm = algorithm;
|
|
1577
|
+
};
|
|
1160
1578
|
for (const sigName of signatureNames) {
|
|
1161
1579
|
if (!signatures[sigName]) {
|
|
1162
|
-
|
|
1580
|
+
setFailure(invalidSignatureResult(parseKeyId(signatureInputs[sigName]?.keyId)));
|
|
1163
1581
|
continue;
|
|
1164
1582
|
}
|
|
1165
1583
|
const sigInput = signatureInputs[sigName];
|
|
@@ -1170,7 +1588,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1170
1588
|
signatureName: sigName,
|
|
1171
1589
|
signatureInput: signatureInputHeader
|
|
1172
1590
|
});
|
|
1173
|
-
|
|
1591
|
+
setFailure(invalidSignatureResult(null));
|
|
1174
1592
|
continue;
|
|
1175
1593
|
}
|
|
1176
1594
|
if (!sigInput.created) {
|
|
@@ -1178,7 +1596,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1178
1596
|
signatureName: sigName,
|
|
1179
1597
|
signatureInput: signatureInputHeader
|
|
1180
1598
|
});
|
|
1181
|
-
|
|
1599
|
+
setFailure(invalidSignatureResult(keyId));
|
|
1182
1600
|
continue;
|
|
1183
1601
|
}
|
|
1184
1602
|
const signatureCreated = Temporal.Instant.fromEpochMilliseconds(sigInput.created * 1e3);
|
|
@@ -1190,14 +1608,14 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1190
1608
|
created: signatureCreated.toString(),
|
|
1191
1609
|
now: now.toString()
|
|
1192
1610
|
});
|
|
1193
|
-
|
|
1611
|
+
setFailure(invalidSignatureResult(keyId));
|
|
1194
1612
|
continue;
|
|
1195
1613
|
} else if (Temporal.Instant.compare(signatureCreated, now.subtract(tw)) < 0) {
|
|
1196
1614
|
logger.debug("Failed to verify; signature created time is too far in the past.", {
|
|
1197
1615
|
created: signatureCreated.toString(),
|
|
1198
1616
|
now: now.toString()
|
|
1199
1617
|
});
|
|
1200
|
-
|
|
1618
|
+
setFailure(invalidSignatureResult(keyId));
|
|
1201
1619
|
continue;
|
|
1202
1620
|
}
|
|
1203
1621
|
}
|
|
@@ -1205,34 +1623,34 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1205
1623
|
const contentDigestHeader = request.headers.get("Content-Digest");
|
|
1206
1624
|
if (!contentDigestHeader) {
|
|
1207
1625
|
logger.debug("Failed to verify; Content-Digest header required but not found.", { components: sigInput.components });
|
|
1208
|
-
|
|
1626
|
+
setFailure(invalidSignatureResult(keyId));
|
|
1209
1627
|
continue;
|
|
1210
1628
|
}
|
|
1211
1629
|
if (!await verifyRfc9421ContentDigest(contentDigestHeader, await request.arrayBuffer())) {
|
|
1212
1630
|
logger.debug("Failed to verify; Content-Digest verification failed.", { contentDigest: contentDigestHeader });
|
|
1213
|
-
|
|
1631
|
+
setFailure(invalidSignatureResult(keyId));
|
|
1214
1632
|
continue;
|
|
1215
1633
|
}
|
|
1216
1634
|
}
|
|
1217
1635
|
span?.setAttribute("http_signatures.key_id", sigInput.keyId);
|
|
1218
1636
|
span?.setAttribute("http_signatures.created", sigInput.created.toString());
|
|
1219
1637
|
if (keyId == null) {
|
|
1220
|
-
|
|
1638
|
+
setFailure(invalidSignatureResult(null));
|
|
1221
1639
|
continue;
|
|
1222
1640
|
}
|
|
1223
|
-
const { key, cached, fetchError } = await fetchKeyDetailed(keyId, _fedify_vocab.CryptographicKey, {
|
|
1641
|
+
const { key, cached, fetchError } = await measureSignatureKeyFetch(meterProvider, "http", () => fetchKeyDetailed(keyId, _fedify_vocab.CryptographicKey, {
|
|
1224
1642
|
documentLoader,
|
|
1225
1643
|
contextLoader,
|
|
1226
1644
|
keyCache,
|
|
1227
1645
|
tracerProvider
|
|
1228
|
-
});
|
|
1646
|
+
}));
|
|
1229
1647
|
if (fetchError != null) {
|
|
1230
|
-
|
|
1648
|
+
setFailure(keyFetchErrorResult(keyId, fetchError));
|
|
1231
1649
|
continue;
|
|
1232
1650
|
}
|
|
1233
1651
|
if (!key) {
|
|
1234
1652
|
logger.debug("Failed to fetch key: {keyId}", { keyId: sigInput.keyId });
|
|
1235
|
-
|
|
1653
|
+
setFailure(invalidSignatureResult(keyId));
|
|
1236
1654
|
continue;
|
|
1237
1655
|
}
|
|
1238
1656
|
let alg = sigInput.alg?.toLowerCase();
|
|
@@ -1244,12 +1662,13 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1244
1662
|
}
|
|
1245
1663
|
if (alg) span?.setAttribute("http_signatures.algorithm", alg);
|
|
1246
1664
|
const algorithm = alg && rfc9421AlgorithmMap[alg];
|
|
1665
|
+
const candidateAlgorithm = algorithm ? alg : void 0;
|
|
1247
1666
|
if (!algorithm) {
|
|
1248
1667
|
logger.debug("Failed to verify; unsupported algorithm: {algorithm}", {
|
|
1249
1668
|
algorithm: sigInput.alg,
|
|
1250
1669
|
supported: Object.keys(rfc9421AlgorithmMap)
|
|
1251
1670
|
});
|
|
1252
|
-
|
|
1671
|
+
setFailure(invalidSignatureResult(keyId));
|
|
1253
1672
|
continue;
|
|
1254
1673
|
}
|
|
1255
1674
|
let signatureBase;
|
|
@@ -1260,20 +1679,22 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1260
1679
|
error,
|
|
1261
1680
|
signatureInput: sigInput
|
|
1262
1681
|
});
|
|
1263
|
-
|
|
1682
|
+
setFailure(invalidSignatureResult(keyId), candidateAlgorithm);
|
|
1264
1683
|
continue;
|
|
1265
1684
|
}
|
|
1266
1685
|
const signatureBaseBytes = new TextEncoder().encode(signatureBase);
|
|
1267
1686
|
span?.setAttribute("http_signatures.signature", (0, byte_encodings_hex.encodeHex)(sigBytes));
|
|
1268
1687
|
try {
|
|
1269
|
-
if (await crypto.subtle.verify(algorithm, key.publicKey, sigBytes.slice(), signatureBaseBytes))
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1688
|
+
if (await crypto.subtle.verify(algorithm, key.publicKey, sigBytes.slice(), signatureBaseBytes)) {
|
|
1689
|
+
metricsContext.algorithm = candidateAlgorithm;
|
|
1690
|
+
return {
|
|
1691
|
+
verified: true,
|
|
1692
|
+
key,
|
|
1693
|
+
signatureLabel: sigName
|
|
1694
|
+
};
|
|
1695
|
+
} else if (cached) {
|
|
1275
1696
|
logger.debug("Failed to verify with cached key {keyId}; retrying with fresh key...", { keyId: sigInput.keyId });
|
|
1276
|
-
return await
|
|
1697
|
+
return await verifyRequestRfc9421(originalRequest, span, metricsContext, {
|
|
1277
1698
|
documentLoader,
|
|
1278
1699
|
contextLoader,
|
|
1279
1700
|
timeWindow,
|
|
@@ -1282,14 +1703,16 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1282
1703
|
get: () => Promise.resolve(void 0),
|
|
1283
1704
|
set: async (keyId, key) => await keyCache?.set(keyId, key)
|
|
1284
1705
|
},
|
|
1285
|
-
spec: "rfc9421"
|
|
1706
|
+
spec: "rfc9421",
|
|
1707
|
+
meterProvider,
|
|
1708
|
+
tracerProvider
|
|
1286
1709
|
});
|
|
1287
1710
|
} else {
|
|
1288
1711
|
logger.debug("Failed to verify signature with fetched key {keyId}; signature invalid.", {
|
|
1289
1712
|
keyId: sigInput.keyId,
|
|
1290
1713
|
signatureBase
|
|
1291
1714
|
});
|
|
1292
|
-
|
|
1715
|
+
setFailure(invalidSignatureResult(keyId), candidateAlgorithm);
|
|
1293
1716
|
}
|
|
1294
1717
|
} catch (error) {
|
|
1295
1718
|
logger.debug("Error during signature verification: {error}", {
|
|
@@ -1297,9 +1720,10 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1297
1720
|
keyId: sigInput.keyId,
|
|
1298
1721
|
algorithm: sigInput.alg
|
|
1299
1722
|
});
|
|
1300
|
-
|
|
1723
|
+
setFailure(invalidSignatureResult(keyId), candidateAlgorithm);
|
|
1301
1724
|
}
|
|
1302
1725
|
}
|
|
1726
|
+
metricsContext.algorithm = failureAlgorithm;
|
|
1303
1727
|
return failure;
|
|
1304
1728
|
}
|
|
1305
1729
|
/**
|
|
@@ -1563,12 +1987,42 @@ Object.defineProperty(exports, "generateCryptoKeyPair", {
|
|
|
1563
1987
|
return generateCryptoKeyPair;
|
|
1564
1988
|
}
|
|
1565
1989
|
});
|
|
1990
|
+
Object.defineProperty(exports, "getDurationMs", {
|
|
1991
|
+
enumerable: true,
|
|
1992
|
+
get: function() {
|
|
1993
|
+
return getDurationMs;
|
|
1994
|
+
}
|
|
1995
|
+
});
|
|
1996
|
+
Object.defineProperty(exports, "getFederationMetrics", {
|
|
1997
|
+
enumerable: true,
|
|
1998
|
+
get: function() {
|
|
1999
|
+
return getFederationMetrics;
|
|
2000
|
+
}
|
|
2001
|
+
});
|
|
2002
|
+
Object.defineProperty(exports, "getRemoteHost", {
|
|
2003
|
+
enumerable: true,
|
|
2004
|
+
get: function() {
|
|
2005
|
+
return getRemoteHost;
|
|
2006
|
+
}
|
|
2007
|
+
});
|
|
1566
2008
|
Object.defineProperty(exports, "importJwk", {
|
|
1567
2009
|
enumerable: true,
|
|
1568
2010
|
get: function() {
|
|
1569
2011
|
return importJwk;
|
|
1570
2012
|
}
|
|
1571
2013
|
});
|
|
2014
|
+
Object.defineProperty(exports, "isAbortError", {
|
|
2015
|
+
enumerable: true,
|
|
2016
|
+
get: function() {
|
|
2017
|
+
return isAbortError$1;
|
|
2018
|
+
}
|
|
2019
|
+
});
|
|
2020
|
+
Object.defineProperty(exports, "measureSignatureKeyFetch", {
|
|
2021
|
+
enumerable: true,
|
|
2022
|
+
get: function() {
|
|
2023
|
+
return measureSignatureKeyFetch;
|
|
2024
|
+
}
|
|
2025
|
+
});
|
|
1572
2026
|
Object.defineProperty(exports, "name", {
|
|
1573
2027
|
enumerable: true,
|
|
1574
2028
|
get: function() {
|
|
@@ -1587,6 +2041,30 @@ Object.defineProperty(exports, "parseRfc9421SignatureInput", {
|
|
|
1587
2041
|
return parseRfc9421SignatureInput;
|
|
1588
2042
|
}
|
|
1589
2043
|
});
|
|
2044
|
+
Object.defineProperty(exports, "recordFanoutRecipients", {
|
|
2045
|
+
enumerable: true,
|
|
2046
|
+
get: function() {
|
|
2047
|
+
return recordFanoutRecipients;
|
|
2048
|
+
}
|
|
2049
|
+
});
|
|
2050
|
+
Object.defineProperty(exports, "recordInboxActivity", {
|
|
2051
|
+
enumerable: true,
|
|
2052
|
+
get: function() {
|
|
2053
|
+
return recordInboxActivity;
|
|
2054
|
+
}
|
|
2055
|
+
});
|
|
2056
|
+
Object.defineProperty(exports, "recordOutboxActivity", {
|
|
2057
|
+
enumerable: true,
|
|
2058
|
+
get: function() {
|
|
2059
|
+
return recordOutboxActivity;
|
|
2060
|
+
}
|
|
2061
|
+
});
|
|
2062
|
+
Object.defineProperty(exports, "recordOutboxEnqueue", {
|
|
2063
|
+
enumerable: true,
|
|
2064
|
+
get: function() {
|
|
2065
|
+
return recordOutboxEnqueue;
|
|
2066
|
+
}
|
|
2067
|
+
});
|
|
1590
2068
|
Object.defineProperty(exports, "signRequest", {
|
|
1591
2069
|
enumerable: true,
|
|
1592
2070
|
get: function() {
|