@fedify/fedify 2.2.0-pr.695.16 → 2.2.0-pr.697.18

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.
Files changed (63) hide show
  1. package/dist/activity-listener-Ck3JZ_hR.mjs +40 -0
  2. package/dist/{builder-7PVCiLiR.mjs → builder-CssIxEgK.mjs} +57 -7
  3. package/dist/compat/mod.d.cts +1 -1
  4. package/dist/compat/mod.d.ts +1 -1
  5. package/dist/compat/transformers.test.mjs +1 -1
  6. package/dist/{context-78ecvxf5.d.ts → context-BGrYMSTk.d.ts} +143 -1
  7. package/dist/{context-DYDPdoCb.d.cts → context-CMUd4wy0.d.cts} +143 -1
  8. package/dist/{context-Juj6bdHC.mjs → context-Dk_tacqz.mjs} +17 -2
  9. package/dist/{deno-vxcWcxQS.mjs → deno-DFC3hdDk.mjs} +1 -1
  10. package/dist/{docloader-D7q0-Xef.mjs → docloader-DJSGzW4N.mjs} +2 -2
  11. package/dist/federation/builder.test.mjs +25 -1
  12. package/dist/federation/handler.test.mjs +369 -8
  13. package/dist/federation/idempotency.test.mjs +2 -2
  14. package/dist/federation/inbox.test.mjs +3 -3
  15. package/dist/federation/middleware.test.mjs +510 -8
  16. package/dist/federation/mod.cjs +1 -1
  17. package/dist/federation/mod.d.cts +3 -3
  18. package/dist/federation/mod.d.ts +3 -3
  19. package/dist/federation/mod.js +1 -1
  20. package/dist/federation/send.test.mjs +3 -3
  21. package/dist/federation/webfinger.test.mjs +2 -2
  22. package/dist/{http-RZPxDWq5.mjs → http-BrF-JQov.mjs} +2 -2
  23. package/dist/{http-JxF7bG0o.cjs → http-DDRsBRY5.cjs} +1 -1
  24. package/dist/{http-D-MhhYUF.js → http-nVAbZPuI.js} +1 -1
  25. package/dist/{key-CGx_dDkX.mjs → key-2MxqHz-F.mjs} +1 -1
  26. package/dist/{kv-cache-D84Mk0fZ.js → kv-cache-5w7DZnmJ.js} +1 -1
  27. package/dist/{kv-cache-C2gdVgvb.cjs → kv-cache-CPeV5q6I.cjs} +1 -1
  28. package/dist/{ld-wup-liFO.mjs → ld-bY6topKr.mjs} +26 -3
  29. package/dist/{middleware-BjVx-_bv.mjs → middleware-BCJUFXYb.mjs} +612 -180
  30. package/dist/{middleware-Bn75dPug.cjs → middleware-BPHO6DE3.cjs} +676 -323
  31. package/dist/{middleware-RF-sUfTr.js → middleware-C10kVjEo.js} +670 -322
  32. package/dist/{middleware-wdfeWjRJ.mjs → middleware-DI82-dr3.mjs} +1 -1
  33. package/dist/{middleware-CXOVT4Ph.cjs → middleware-JAlnEFGy.cjs} +1 -1
  34. package/dist/{mod-CEohtXhV.d.cts → mod-BcJHeuv1.d.cts} +1 -1
  35. package/dist/{mod-CokIUYDr.d.ts → mod-CJXfyw7v.d.ts} +1 -1
  36. package/dist/{mod-DvxszxXC.d.ts → mod-CR8soWa9.d.ts} +18 -1
  37. package/dist/{mod-DoJBjjnO.d.cts → mod-Cr3f-ACa.d.cts} +18 -1
  38. package/dist/mod.cjs +6 -4
  39. package/dist/mod.d.cts +5 -5
  40. package/dist/mod.d.ts +5 -5
  41. package/dist/mod.js +5 -5
  42. package/dist/nodeinfo/handler.test.mjs +2 -2
  43. package/dist/{owner-q2mUMM9a.mjs → owner-D4-A8f_n.mjs} +2 -2
  44. package/dist/{proof--CpZsF_p.mjs → proof-45_MjnD1.mjs} +32 -3
  45. package/dist/{proof-_Zyfqyce.cjs → proof-COdach6j.cjs} +61 -3
  46. package/dist/{proof-CirP9OSd.js → proof-CnfkRjXL.js} +54 -2
  47. package/dist/{send-CVJfx7bF.mjs → send-BeNvLSaC.mjs} +2 -2
  48. package/dist/sig/http.test.mjs +2 -2
  49. package/dist/sig/key.test.mjs +1 -1
  50. package/dist/sig/ld.test.mjs +44 -2
  51. package/dist/sig/mod.cjs +4 -2
  52. package/dist/sig/mod.d.cts +2 -2
  53. package/dist/sig/mod.d.ts +2 -2
  54. package/dist/sig/mod.js +3 -3
  55. package/dist/sig/owner.test.mjs +1 -1
  56. package/dist/sig/proof.test.mjs +46 -2
  57. package/dist/testing/mod.d.mts +149 -1
  58. package/dist/testing/mod.mjs +2 -2
  59. package/dist/utils/docloader.test.mjs +2 -2
  60. package/dist/utils/mod.cjs +1 -1
  61. package/dist/utils/mod.js +1 -1
  62. package/package.json +5 -5
  63. package/dist/inbox-CmYvcSMM.mjs +0 -179
@@ -1,11 +1,12 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
+ import { n as RouterError } from "../router-CrMLXoOr.mjs";
4
5
  import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
6
  import { a as assertExists } from "../std__assert-Duiq_YC9.mjs";
6
7
  import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
7
8
  import { t as MemoryKvStore } from "../kv-tL2TOE9X.mjs";
8
- import { n as createFederationBuilder } from "../builder-7PVCiLiR.mjs";
9
+ import { n as createFederationBuilder } from "../builder-CssIxEgK.mjs";
9
10
  import { test } from "@fedify/fixture";
10
11
  import { Activity, Note, Person } from "@fedify/vocab";
11
12
  //#region src/federation/builder.test.ts
@@ -19,6 +20,8 @@ test("FederationBuilder", async (t) => {
19
20
  builder.setActorDispatcher("/users/{identifier}", actorDispatcher);
20
21
  const inboxListener = (_ctx, _activity) => {};
21
22
  builder.setInboxListeners("/users/{identifier}/inbox").on(Activity, inboxListener);
23
+ const outboxListener = (_ctx, _activity) => {};
24
+ builder.setOutboxListeners("/users/{identifier}/outbox").on(Activity, outboxListener);
22
25
  const objectDispatcher = (_ctx, _values) => {
23
26
  return null;
24
27
  };
@@ -50,12 +53,15 @@ test("FederationBuilder", async (t) => {
50
53
  assertEquals(impl.router.route("/.well-known/webfinger")?.name, "webfinger");
51
54
  assertEquals(impl.router.route("/users/test123")?.name, "actor");
52
55
  assertEquals(impl.router.route("/users/test123/inbox")?.name, "inbox");
56
+ assertEquals(impl.router.route("/users/test123/outbox")?.name, "outbox");
53
57
  assertEquals(impl.router.route("/notes/456")?.name, `object:${Note.typeId.href}`);
54
58
  assertEquals(impl.router.route("/nodeinfo")?.name, "nodeInfo");
55
59
  const actorCallbacksDispatcher = impl.actorCallbacks?.dispatcher;
56
60
  assertExists(actorCallbacksDispatcher);
57
61
  const inboxListeners = impl.inboxListeners;
58
62
  assertExists(inboxListeners);
63
+ const outboxListeners = impl.outboxListeners;
64
+ assertExists(outboxListeners);
59
65
  assertExists(impl.objectCallbacks[Note.typeId.href]);
60
66
  assertExists(impl.nodeInfoDispatcher);
61
67
  assertEquals(impl.router.build(`object:${Note.typeId.href}`, { id: "123" }), "/notes/123");
@@ -70,6 +76,24 @@ test("FederationBuilder", async (t) => {
70
76
  assertExists(federation);
71
77
  assertEquals(federation.kv, kv);
72
78
  });
79
+ await t.step("should validate outbox listener paths", () => {
80
+ const builder = createFederationBuilder();
81
+ builder.setOutboxDispatcher("/users/{identifier}/outbox", () => ({ items: [] }));
82
+ assertThrows(() => builder.setOutboxListeners("/actors/{identifier}/outbox"), RouterError);
83
+ assertThrows(() => builder.setOutboxListeners("/users/outbox"), RouterError);
84
+ assertThrows(() => builder.setOutboxListeners("/users/{identifier}/outbox/{extra}"), RouterError);
85
+ assertThrows(() => builder.setOutboxListeners("/users/{identifier}/outbox/{identifier}"), RouterError);
86
+ const builderAfterInvalid = createFederationBuilder();
87
+ assertThrows(() => builderAfterInvalid.setOutboxListeners("/users/{identifier}/outbox/{extra}"), RouterError);
88
+ builderAfterInvalid.setOutboxListeners("/users/{identifier}/outbox");
89
+ const builder2 = createFederationBuilder();
90
+ builder2.setOutboxListeners("/users{/identifier}/outbox");
91
+ assertThrows(() => builder2.setOutboxDispatcher("/actors/{identifier}/outbox", () => ({ items: [] })), RouterError);
92
+ const builder3 = createFederationBuilder();
93
+ assertThrows(() => builder3.setOutboxListeners("/users{?identifier}/outbox"), RouterError);
94
+ const builder4 = createFederationBuilder();
95
+ assertThrows(() => builder4.setOutboxDispatcher("/users{?identifier}/outbox", () => ({ items: [] })), RouterError);
96
+ });
73
97
  await t.step("should pass build options correctly", async () => {
74
98
  const builder = createFederationBuilder();
75
99
  const kv = new MemoryKvStore();
@@ -1,18 +1,19 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as createRequestContext, t as createInboxContext } from "../context-Juj6bdHC.mjs";
4
+ import { n as createOutboxContext, r as createRequestContext, t as createInboxContext } from "../context-Dk_tacqz.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
6
6
  import "../std__assert-Duiq_YC9.mjs";
7
+ import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
7
8
  import { t as assert } from "../assert-ddO5KLpe.mjs";
8
9
  import { r as parseAcceptSignature } from "../accept-Dd__NiUL.mjs";
9
- import { s as signRequest } from "../http-RZPxDWq5.mjs";
10
+ import { s as signRequest } from "../http-BrF-JQov.mjs";
10
11
  import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-BAK-tUlf.mjs";
11
12
  import { t as MemoryKvStore } from "../kv-tL2TOE9X.mjs";
12
- import { a as createFederation, c as handleCollection, d as handleObject, f as respondWithObject, l as handleCustomCollection, p as respondWithObjectIfAcceptable, s as handleActor, u as handleInbox } from "../middleware-BjVx-_bv.mjs";
13
- import { t as InboxListenerSet } from "../inbox-CmYvcSMM.mjs";
13
+ import { c as handleActor, d as handleInbox, f as handleObject, h as respondWithObjectIfAcceptable, l as handleCollection, m as respondWithObject, o as createFederation, p as handleOutbox, u as handleCustomCollection } from "../middleware-BCJUFXYb.mjs";
14
+ import { t as ActivityListenerSet } from "../activity-listener-Ck3JZ_hR.mjs";
14
15
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
15
- import { Create, Note, Person, Tombstone } from "@fedify/vocab";
16
+ import { Activity, Create, Note, Person, Tombstone } from "@fedify/vocab";
16
17
  import { FetchError } from "@fedify/vocab-runtime";
17
18
  //#region src/federation/handler.test.ts
18
19
  const QUOTE_CONTEXT_TERMS = {
@@ -1126,6 +1127,366 @@ test("handleInbox()", async () => {
1126
1127
  assertEquals(onNotFoundCalled, null);
1127
1128
  assertEquals(response.status, 400);
1128
1129
  });
1130
+ test("handleOutbox()", async () => {
1131
+ const activity = new Create({
1132
+ id: new URL("https://example.com/activities/1"),
1133
+ actor: new URL("https://example.com/users/someone"),
1134
+ object: new Note({
1135
+ id: new URL("https://example.com/notes/1"),
1136
+ attribution: new URL("https://example.com/users/someone"),
1137
+ content: "Hello, world!"
1138
+ })
1139
+ });
1140
+ const requestUrl = "https://example.com/users/someone/outbox";
1141
+ const requestBody = JSON.stringify(await activity.toJsonLd());
1142
+ const federation = createFederation({ kv: new MemoryKvStore() });
1143
+ const createRequestContextPair = (body = requestBody) => {
1144
+ const request = new Request(requestUrl, {
1145
+ method: "POST",
1146
+ body
1147
+ });
1148
+ return {
1149
+ request,
1150
+ context: createRequestContext({
1151
+ federation,
1152
+ request,
1153
+ url: new URL(request.url),
1154
+ data: void 0,
1155
+ getActorUri(identifier) {
1156
+ return new URL(`https://example.com/users/${identifier}`);
1157
+ }
1158
+ })
1159
+ };
1160
+ };
1161
+ let onNotFoundCalled = null;
1162
+ const onNotFound = (request) => {
1163
+ onNotFoundCalled = request;
1164
+ return new Response("Not found", { status: 404 });
1165
+ };
1166
+ let onUnauthorizedCalled = null;
1167
+ const onUnauthorized = (request) => {
1168
+ onUnauthorizedCalled = request;
1169
+ return new Response("Unauthorized", { status: 401 });
1170
+ };
1171
+ const actorDispatcher = (ctx, identifier) => {
1172
+ if (identifier !== "someone") return null;
1173
+ return new Person({
1174
+ id: ctx.getActorUri(identifier),
1175
+ name: "Someone"
1176
+ });
1177
+ };
1178
+ const listeners = new ActivityListenerSet();
1179
+ const seen = [];
1180
+ listeners.add(Activity, (ctx, activity) => {
1181
+ seen.push(`${ctx.identifier}:${activity.id?.href}`);
1182
+ });
1183
+ let { request, context } = createRequestContextPair();
1184
+ let response = await handleOutbox(request, {
1185
+ identifier: "someone",
1186
+ context,
1187
+ outboxContextFactory(identifier) {
1188
+ return createOutboxContext({
1189
+ ...context,
1190
+ clone: void 0,
1191
+ identifier
1192
+ });
1193
+ },
1194
+ actorDispatcher: void 0,
1195
+ outboxListeners: listeners,
1196
+ onNotFound,
1197
+ onUnauthorized
1198
+ });
1199
+ assertEquals(onNotFoundCalled, request);
1200
+ assertEquals(response.status, 404);
1201
+ onNotFoundCalled = null;
1202
+ ({request, context} = createRequestContextPair());
1203
+ response = await handleOutbox(request, {
1204
+ identifier: "nobody",
1205
+ context,
1206
+ outboxContextFactory(identifier) {
1207
+ return createOutboxContext({
1208
+ ...context,
1209
+ clone: void 0,
1210
+ identifier
1211
+ });
1212
+ },
1213
+ actorDispatcher,
1214
+ outboxListeners: listeners,
1215
+ onNotFound,
1216
+ onUnauthorized
1217
+ });
1218
+ assertEquals(onNotFoundCalled, request);
1219
+ assertEquals(response.status, 404);
1220
+ onNotFoundCalled = null;
1221
+ ({request, context} = createRequestContextPair());
1222
+ response = await handleOutbox(request, {
1223
+ identifier: "someone",
1224
+ context,
1225
+ outboxContextFactory(identifier) {
1226
+ return createOutboxContext({
1227
+ ...context,
1228
+ clone: void 0,
1229
+ identifier
1230
+ });
1231
+ },
1232
+ actorDispatcher,
1233
+ outboxListeners: listeners,
1234
+ authorizePredicate: () => false,
1235
+ onNotFound,
1236
+ onUnauthorized
1237
+ });
1238
+ assertEquals(onNotFoundCalled, null);
1239
+ assertInstanceOf(onUnauthorizedCalled, Request);
1240
+ assertEquals(onUnauthorizedCalled === request, false);
1241
+ assertEquals(response.status, 401);
1242
+ assertEquals(seen, []);
1243
+ onNotFoundCalled = null;
1244
+ onUnauthorizedCalled = null;
1245
+ ({request, context} = createRequestContextPair());
1246
+ response = await handleOutbox(request, {
1247
+ identifier: "someone",
1248
+ context,
1249
+ outboxContextFactory(identifier) {
1250
+ return createOutboxContext({
1251
+ ...context,
1252
+ clone: void 0,
1253
+ identifier
1254
+ });
1255
+ },
1256
+ actorDispatcher: () => null,
1257
+ outboxListeners: listeners,
1258
+ authorizePredicate: () => false,
1259
+ onNotFound,
1260
+ onUnauthorized
1261
+ });
1262
+ assertEquals(onNotFoundCalled, null);
1263
+ assertInstanceOf(onUnauthorizedCalled, Request);
1264
+ assertEquals(response.status, 401);
1265
+ onUnauthorizedCalled = null;
1266
+ ({request, context} = createRequestContextPair());
1267
+ response = await handleOutbox(request, {
1268
+ identifier: "someone",
1269
+ context,
1270
+ outboxContextFactory(identifier) {
1271
+ return createOutboxContext({
1272
+ ...context,
1273
+ clone: void 0,
1274
+ identifier
1275
+ });
1276
+ },
1277
+ actorDispatcher,
1278
+ outboxListeners: listeners,
1279
+ authorizePredicate: () => true,
1280
+ onNotFound,
1281
+ onUnauthorized
1282
+ });
1283
+ assertEquals(onUnauthorizedCalled, null);
1284
+ assertEquals([response.status, await response.text()], [202, ""]);
1285
+ assertEquals(response.headers.get("content-type"), "text/plain; charset=utf-8");
1286
+ assertEquals(seen, [`someone:${activity.id?.href}`]);
1287
+ onUnauthorizedCalled = null;
1288
+ ({request, context} = createRequestContextPair());
1289
+ response = await handleOutbox(request, {
1290
+ identifier: "someone",
1291
+ context,
1292
+ outboxContextFactory(identifier) {
1293
+ return createOutboxContext({
1294
+ ...context,
1295
+ clone: void 0,
1296
+ identifier
1297
+ });
1298
+ },
1299
+ actorDispatcher,
1300
+ outboxListeners: listeners,
1301
+ authorizePredicate: async (ctx) => {
1302
+ await ctx.request.json();
1303
+ return true;
1304
+ },
1305
+ onNotFound,
1306
+ onUnauthorized
1307
+ });
1308
+ assertEquals(onUnauthorizedCalled, null);
1309
+ assertEquals([response.status, await response.text()], [202, ""]);
1310
+ assertEquals(response.headers.get("content-type"), "text/plain; charset=utf-8");
1311
+ assertEquals(seen, [`someone:${activity.id?.href}`, `someone:${activity.id?.href}`]);
1312
+ onUnauthorizedCalled = null;
1313
+ ({request, context} = createRequestContextPair());
1314
+ let unauthorizedBody = null;
1315
+ response = await handleOutbox(request, {
1316
+ identifier: "someone",
1317
+ context,
1318
+ outboxContextFactory(identifier) {
1319
+ return createOutboxContext({
1320
+ ...context,
1321
+ clone: void 0,
1322
+ identifier
1323
+ });
1324
+ },
1325
+ actorDispatcher,
1326
+ outboxListeners: listeners,
1327
+ authorizePredicate: async (ctx) => {
1328
+ await ctx.request.json();
1329
+ return false;
1330
+ },
1331
+ onNotFound,
1332
+ onUnauthorized: async (request) => {
1333
+ onUnauthorizedCalled = request;
1334
+ unauthorizedBody = await request.text();
1335
+ return new Response("Unauthorized", { status: 401 });
1336
+ }
1337
+ });
1338
+ assertInstanceOf(onUnauthorizedCalled, Request);
1339
+ assertEquals((unauthorizedBody ?? "").includes("\"type\":\"Create\""), true);
1340
+ assertEquals([response.status, await response.text()], [401, "Unauthorized"]);
1341
+ const invalidRequest = new Request("https://example.com/users/someone/outbox", {
1342
+ method: "POST",
1343
+ body: JSON.stringify({
1344
+ "@context": [
1345
+ "https://www.w3.org/ns/activitystreams",
1346
+ true,
1347
+ 23
1348
+ ],
1349
+ type: "Create",
1350
+ object: {
1351
+ type: "Note",
1352
+ content: "Hello, world!"
1353
+ },
1354
+ actor: "https://example.com/users/alice"
1355
+ })
1356
+ });
1357
+ const invalidContext = createRequestContext({
1358
+ federation,
1359
+ request: invalidRequest,
1360
+ url: new URL(invalidRequest.url),
1361
+ data: void 0,
1362
+ getActorUri(identifier) {
1363
+ return new URL(`https://example.com/users/${identifier}`);
1364
+ }
1365
+ });
1366
+ let invalidActivityId;
1367
+ let invalidActivityType;
1368
+ response = await handleOutbox(invalidRequest, {
1369
+ identifier: "someone",
1370
+ context: invalidContext,
1371
+ outboxContextFactory(identifier, _json, activityId, activityType) {
1372
+ invalidActivityId = activityId;
1373
+ invalidActivityType = activityType;
1374
+ return createOutboxContext({
1375
+ ...invalidContext,
1376
+ clone: void 0,
1377
+ identifier
1378
+ });
1379
+ },
1380
+ actorDispatcher,
1381
+ outboxListeners: listeners,
1382
+ onNotFound,
1383
+ onUnauthorized
1384
+ });
1385
+ assertEquals(response.status, 400);
1386
+ assertEquals(invalidActivityId, void 0);
1387
+ assertEquals(invalidActivityType, "Create");
1388
+ const mismatchedActorJson = await activity.toJsonLd();
1389
+ const missingActorRequest = new Request("https://example.com/users/someone/outbox", {
1390
+ method: "POST",
1391
+ body: JSON.stringify({
1392
+ ...mismatchedActorJson,
1393
+ actor: void 0
1394
+ })
1395
+ });
1396
+ const missingActorContext = createRequestContext({
1397
+ federation,
1398
+ request: missingActorRequest,
1399
+ url: new URL(missingActorRequest.url),
1400
+ data: void 0,
1401
+ getActorUri(identifier) {
1402
+ return new URL(`https://example.com/users/${identifier}`);
1403
+ }
1404
+ });
1405
+ let missingActorErrorMessage = null;
1406
+ response = await handleOutbox(missingActorRequest, {
1407
+ identifier: "someone",
1408
+ context: missingActorContext,
1409
+ outboxContextFactory(identifier) {
1410
+ return createOutboxContext({
1411
+ ...missingActorContext,
1412
+ clone: void 0,
1413
+ identifier
1414
+ });
1415
+ },
1416
+ actorDispatcher,
1417
+ outboxListeners: listeners,
1418
+ outboxErrorHandler: (_ctx, error) => {
1419
+ missingActorErrorMessage = error.message;
1420
+ },
1421
+ onNotFound,
1422
+ onUnauthorized
1423
+ });
1424
+ assertEquals([response.status, await response.text()], [400, "The posted activity has no actor."]);
1425
+ assertEquals(missingActorErrorMessage, "The posted activity has no actor.");
1426
+ const mismatchedActorRequest = new Request("https://example.com/users/someone/outbox", {
1427
+ method: "POST",
1428
+ body: JSON.stringify({
1429
+ ...mismatchedActorJson,
1430
+ actor: "https://example.com/users/somebody-else"
1431
+ })
1432
+ });
1433
+ const mismatchedActorContext = createRequestContext({
1434
+ federation,
1435
+ request: mismatchedActorRequest,
1436
+ url: new URL(mismatchedActorRequest.url),
1437
+ data: void 0,
1438
+ getActorUri(identifier) {
1439
+ return new URL(`https://example.com/users/${identifier}`);
1440
+ }
1441
+ });
1442
+ let mismatchedActorErrorMessage = null;
1443
+ response = await handleOutbox(mismatchedActorRequest, {
1444
+ identifier: "someone",
1445
+ context: mismatchedActorContext,
1446
+ outboxContextFactory(identifier) {
1447
+ return createOutboxContext({
1448
+ ...mismatchedActorContext,
1449
+ clone: void 0,
1450
+ identifier
1451
+ });
1452
+ },
1453
+ actorDispatcher,
1454
+ outboxListeners: listeners,
1455
+ outboxErrorHandler: (_ctx, error) => {
1456
+ mismatchedActorErrorMessage = error.message;
1457
+ },
1458
+ onNotFound,
1459
+ onUnauthorized
1460
+ });
1461
+ assertEquals([response.status, await response.text()], [400, "The activity actor does not match the outbox owner."]);
1462
+ assertEquals(mismatchedActorErrorMessage, "The activity actor does not match the outbox owner.");
1463
+ const throwingListeners = new ActivityListenerSet();
1464
+ let onErrorCalled = false;
1465
+ throwingListeners.add(Create, () => {
1466
+ throw new Error("Boom");
1467
+ });
1468
+ ({request, context} = createRequestContextPair());
1469
+ response = await handleOutbox(request, {
1470
+ identifier: "someone",
1471
+ context,
1472
+ outboxContextFactory(identifier) {
1473
+ return createOutboxContext({
1474
+ ...context,
1475
+ clone: void 0,
1476
+ identifier
1477
+ });
1478
+ },
1479
+ actorDispatcher,
1480
+ outboxListeners: throwingListeners,
1481
+ outboxErrorHandler: (_ctx, _error) => {
1482
+ onErrorCalled = true;
1483
+ },
1484
+ onNotFound,
1485
+ onUnauthorized
1486
+ });
1487
+ assertEquals(response.status, 500);
1488
+ assertEquals(onErrorCalled, true);
1489
+ });
1129
1490
  test("respondWithObject()", async () => {
1130
1491
  const response = await respondWithObject(new Note({
1131
1492
  id: new URL("https://example.com/notes/1"),
@@ -1163,7 +1524,7 @@ test("respondWithObject()", async () => {
1163
1524
  test("handleInbox() - authentication bypass vulnerability", async () => {
1164
1525
  const federation = createFederation({ kv: new MemoryKvStore() });
1165
1526
  let processedActivity;
1166
- const inboxListeners = new InboxListenerSet();
1527
+ const inboxListeners = new ActivityListenerSet();
1167
1528
  inboxListeners.add(Create, (_ctx, activity) => {
1168
1529
  processedActivity = activity;
1169
1530
  });
@@ -1587,7 +1948,7 @@ test("handleInbox() records OpenTelemetry span events", async () => {
1587
1948
  publicKey: rsaPublicKey2
1588
1949
  });
1589
1950
  };
1590
- const listeners = new InboxListenerSet();
1951
+ const listeners = new ActivityListenerSet();
1591
1952
  let receivedActivity = null;
1592
1953
  listeners.add(Create, (_ctx, activity) => {
1593
1954
  receivedActivity = activity;
@@ -1693,7 +2054,7 @@ test("handleInbox() records unverified HTTP signature details", async () => {
1693
2054
  acceptSignatureNonce: ["acceptSignatureNonce"]
1694
2055
  },
1695
2056
  actorDispatcher,
1696
- inboxListeners: new InboxListenerSet(),
2057
+ inboxListeners: new ActivityListenerSet(),
1697
2058
  inboxErrorHandler: void 0,
1698
2059
  unverifiedActivityHandler() {
1699
2060
  return new Response("", { status: 202 });
@@ -4,9 +4,9 @@ globalThis.addEventListener = () => {};
4
4
  import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
5
  import "../std__assert-Duiq_YC9.mjs";
6
6
  import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-BAK-tUlf.mjs";
7
- import { n as signObject } from "../proof--CpZsF_p.mjs";
7
+ import { r as signObject } from "../proof-45_MjnD1.mjs";
8
8
  import { t as MemoryKvStore } from "../kv-tL2TOE9X.mjs";
9
- import { a as createFederation } from "../middleware-BjVx-_bv.mjs";
9
+ import { o as createFederation } from "../middleware-BCJUFXYb.mjs";
10
10
  import { mockDocumentLoader, test } from "@fedify/fixture";
11
11
  import { Create, Follow, Person } from "@fedify/vocab";
12
12
  //#region src/federation/idempotency.test.ts
@@ -3,12 +3,12 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
5
  import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
6
- import { t as InboxListenerSet } from "../inbox-CmYvcSMM.mjs";
6
+ import { t as ActivityListenerSet } from "../activity-listener-Ck3JZ_hR.mjs";
7
7
  import { test } from "@fedify/fixture";
8
8
  import { Activity, Create, Invite, Offer, Update } from "@fedify/vocab";
9
9
  //#region src/federation/inbox.test.ts
10
- test("InboxListenerSet", () => {
11
- const listeners = new InboxListenerSet();
10
+ test("ActivityListenerSet", () => {
11
+ const listeners = new ActivityListenerSet();
12
12
  const activity = new Activity({});
13
13
  const offer = new Offer({});
14
14
  const invite = new Invite({});