diff --git a/extensions/nextcloud-talk/src/core.test.ts b/extensions/nextcloud-talk/src/core.test.ts index 8234314b9ab..725a4c4e8a9 100644 --- a/extensions/nextcloud-talk/src/core.test.ts +++ b/extensions/nextcloud-talk/src/core.test.ts @@ -131,6 +131,53 @@ describe("nextcloud talk core", () => { ).toBeNull(); }); + it("rejects tampered bodies, wrong secrets, and tampered signatures", () => { + const body = JSON.stringify({ hello: "world" }); + const generated = generateNextcloudTalkSignature({ + body, + secret: "secret-123", + }); + + expect( + verifyNextcloudTalkSignature({ + signature: generated.signature, + random: generated.random, + body: JSON.stringify({ hello: "tampered" }), + secret: "secret-123", + }), + ).toBe(false); + expect( + verifyNextcloudTalkSignature({ + signature: generated.signature, + random: generated.random, + body, + secret: "wrong-secret", + }), + ).toBe(false); + expect( + verifyNextcloudTalkSignature({ + signature: "a".repeat(generated.signature.length), + random: generated.random, + body, + secret: "secret-123", + }), + ).toBe(false); + }); + + it("takes the first value from array-backed headers", () => { + expect( + extractNextcloudTalkHeaders({ + "x-nextcloud-talk-signature": ["sig1", "sig2"], + "x-nextcloud-talk-random": ["rand1", "rand2"], + "x-nextcloud-talk-backend": ["backend1", "backend2"], + }), + ).toEqual({ + signature: "sig1", + random: "rand1", + backend: "backend1", + }); + }); + it("still runs timingSafeEqual when the supplied signature length mismatches", async () => { const timingSafeEqualMock = vi.fn();