|
| 1 | +import type { UnverifiedActivityReason } from "@fedify/fedify"; |
| 2 | +import { Delete, Follow } from "@fedify/vocab"; |
1 | 3 | import { eq } from "drizzle-orm"; |
2 | 4 | import { beforeEach, describe, expect, it } from "vitest"; |
3 | 5 | import { cleanDatabase } from "../../tests/helpers"; |
4 | 6 | import { createAccount } from "../../tests/helpers/oauth"; |
5 | 7 | import db from "../db"; |
6 | 8 | import * as Schema from "../schema"; |
7 | 9 | import type { Uuid } from "../uuid"; |
8 | | -import { onOutboxPermanentFailure } from "./index"; |
| 10 | +import { onOutboxPermanentFailure, onUnverifiedActivity } from "./index"; |
9 | 11 |
|
10 | 12 | async function createRemoteAccount( |
11 | 13 | username: string, |
@@ -59,6 +61,17 @@ async function createFollow( |
59 | 61 | }); |
60 | 62 | } |
61 | 63 |
|
| 64 | +function createKeyFetchErrorReason(status: number): UnverifiedActivityReason { |
| 65 | + return { |
| 66 | + type: "keyFetchError", |
| 67 | + keyId: new URL("https://remote.test/@alice#main-key"), |
| 68 | + result: { |
| 69 | + status, |
| 70 | + response: new Response(null, { status }), |
| 71 | + }, |
| 72 | + }; |
| 73 | +} |
| 74 | + |
62 | 75 | describe("onOutboxPermanentFailure", () => { |
63 | 76 | beforeEach(async () => { |
64 | 77 | await cleanDatabase(); |
@@ -293,3 +306,83 @@ describe("onOutboxPermanentFailure", () => { |
293 | 306 | }); |
294 | 307 | }); |
295 | 308 | }); |
| 309 | + |
| 310 | +describe("onUnverifiedActivity", () => { |
| 311 | + it("should acknowledge Delete activities whose actor key returns 410 Gone", async () => { |
| 312 | + expect.assertions(1); |
| 313 | + |
| 314 | + const response = await onUnverifiedActivity( |
| 315 | + null as never, |
| 316 | + new Delete({ |
| 317 | + actor: new URL("https://remote.test/@alice"), |
| 318 | + object: new URL("https://remote.test/@alice"), |
| 319 | + }), |
| 320 | + createKeyFetchErrorReason(410), |
| 321 | + ); |
| 322 | + |
| 323 | + expect(response?.status).toBe(202); |
| 324 | + }); |
| 325 | + |
| 326 | + it("should ignore Delete activities whose actor key returns 404", async () => { |
| 327 | + expect.assertions(1); |
| 328 | + |
| 329 | + const response = await onUnverifiedActivity( |
| 330 | + null as never, |
| 331 | + new Delete({ |
| 332 | + actor: new URL("https://remote.test/@alice"), |
| 333 | + object: new URL("https://remote.test/@alice"), |
| 334 | + }), |
| 335 | + createKeyFetchErrorReason(404), |
| 336 | + ); |
| 337 | + |
| 338 | + expect(response).toBeUndefined(); |
| 339 | + }); |
| 340 | + |
| 341 | + it("should ignore non-Delete activities even if the key fetch returns 410", async () => { |
| 342 | + expect.assertions(1); |
| 343 | + |
| 344 | + const response = await onUnverifiedActivity( |
| 345 | + null as never, |
| 346 | + new Follow({ |
| 347 | + actor: new URL("https://remote.test/@alice"), |
| 348 | + object: new URL("https://hollo.test/@owner"), |
| 349 | + }), |
| 350 | + createKeyFetchErrorReason(410), |
| 351 | + ); |
| 352 | + |
| 353 | + expect(response).toBeUndefined(); |
| 354 | + }); |
| 355 | + |
| 356 | + it("should ignore invalid signatures", async () => { |
| 357 | + expect.assertions(1); |
| 358 | + |
| 359 | + const response = await onUnverifiedActivity( |
| 360 | + null as never, |
| 361 | + new Delete({ |
| 362 | + actor: new URL("https://remote.test/@alice"), |
| 363 | + object: new URL("https://remote.test/@alice"), |
| 364 | + }), |
| 365 | + { |
| 366 | + type: "invalidSignature", |
| 367 | + keyId: new URL("https://remote.test/@alice#main-key"), |
| 368 | + }, |
| 369 | + ); |
| 370 | + |
| 371 | + expect(response).toBeUndefined(); |
| 372 | + }); |
| 373 | + |
| 374 | + it("should ignore unsigned activities", async () => { |
| 375 | + expect.assertions(1); |
| 376 | + |
| 377 | + const response = await onUnverifiedActivity( |
| 378 | + null as never, |
| 379 | + new Delete({ |
| 380 | + actor: new URL("https://remote.test/@alice"), |
| 381 | + object: new URL("https://remote.test/@alice"), |
| 382 | + }), |
| 383 | + { type: "noSignature" }, |
| 384 | + ); |
| 385 | + |
| 386 | + expect(response).toBeUndefined(); |
| 387 | + }); |
| 388 | +}); |
0 commit comments