import { describe, expect, test } from 'vitest'; import { timingSafeEqualHex, verifyGithubSignature, } from '../../convex/githubWebhookVerify'; const SECRET = "It's a Secret to Everybody"; const BODY = 'Hello, World!'; const VALID_SIGNATURE = 'sha256=757107ea0eb2509fc211221cce984b8a37570b6d7586c22c46f4379c8b043e17'; describe('verifyGithubSignature', () => { test('verifies the GitHub known vector', async () => { expect(await verifyGithubSignature(SECRET, BODY, VALID_SIGNATURE)).toBe( true, ); }); test('rejects a tampered body', async () => { expect( await verifyGithubSignature(SECRET, 'Hello, World?', VALID_SIGNATURE), ).toBe(false); }); test('rejects a wrong secret', async () => { expect( await verifyGithubSignature('wrong secret', BODY, VALID_SIGNATURE), ).toBe(false); }); test('rejects a header missing the sha256= prefix', async () => { expect( await verifyGithubSignature( SECRET, BODY, '757107ea0eb2509fc211221cce984b8a37570b6d7586c22c46f4379c8b043e17', ), ).toBe(false); }); test('rejects a null header', async () => { expect(await verifyGithubSignature(SECRET, BODY, null)).toBe(false); }); test('rejects an empty header', async () => { expect(await verifyGithubSignature(SECRET, BODY, '')).toBe(false); }); test('rejects a correct-format but wrong-length signature', async () => { expect( await verifyGithubSignature(SECRET, BODY, 'sha256=deadbeef'), ).toBe(false); }); test('rejects an empty secret', async () => { expect(await verifyGithubSignature('', BODY, VALID_SIGNATURE)).toBe(false); }); }); describe('timingSafeEqualHex', () => { test('returns true for equal strings', () => { expect(timingSafeEqualHex('abcd', 'abcd')).toBe(true); }); test('returns false for equal-length but differing strings', () => { expect(timingSafeEqualHex('abcd', 'abce')).toBe(false); }); test('returns false for different lengths', () => { expect(timingSafeEqualHex('abcd', 'abcde')).toBe(false); }); });