From 36226adc50797bf4cc9ba3fe2cad60e4abbec6c0 Mon Sep 17 00:00:00 2001 From: ANDROIDHASSAN <84630851+ANDROIDHASSAN@users.noreply.github.com> Date: Thu, 15 Oct 2026 01:00:50 +0530 Subject: [PATCH] fix(server-sdk): report a missing sha256 claim in WebhookReceiver A token without a sha256 claim was reported as "sha256 checksum of body does not match", which points at the body rather than the token. Check for the claim first, with the message the Python server SDK uses. --- .changeset/webhook-missing-sha256.md | 5 +++++ .../livekit-server-sdk/src/WebhookReceiver.test.ts | 14 ++++++++++++++ packages/livekit-server-sdk/src/WebhookReceiver.ts | 3 +++ 3 files changed, 22 insertions(+) create mode 100644 .changeset/webhook-missing-sha256.md diff --git a/.changeset/webhook-missing-sha256.md b/.changeset/webhook-missing-sha256.md new file mode 100644 index 00000000..2271109c --- /dev/null +++ b/.changeset/webhook-missing-sha256.md @@ -0,0 +1,5 @@ +--- +'livekit-server-sdk': patch +--- + +`WebhookReceiver.receive` reports a token without a `sha256` claim as "sha256 was not found in the token" instead of "sha256 checksum of body does not match", as the Python server SDK does. diff --git a/packages/livekit-server-sdk/src/WebhookReceiver.test.ts b/packages/livekit-server-sdk/src/WebhookReceiver.test.ts index 8f8a2df9..d12d309f 100644 --- a/packages/livekit-server-sdk/src/WebhookReceiver.test.ts +++ b/packages/livekit-server-sdk/src/WebhookReceiver.test.ts @@ -24,6 +24,20 @@ describe('webhook receiver', () => { expect(event.room?.name).toBe('mytestroom'); expect(event.event).toBe('room_started'); }); + + it('rejects a body that does not match the token hash', async () => { + const token = await t.toJwt(); + await expect(receiver.receive(`${body} `, token)).rejects.toThrow( + 'sha256 checksum of body does not match', + ); + }); + + it('reports a token without a sha256 claim as such', async () => { + const token = await new AccessToken(testApiKey, testSecret).toJwt(); + await expect(receiver.receive(body, token)).rejects.toThrow( + 'sha256 was not found in the token', + ); + }); }); describe('decoding json payload', () => { diff --git a/packages/livekit-server-sdk/src/WebhookReceiver.ts b/packages/livekit-server-sdk/src/WebhookReceiver.ts index b608ac77..24bdfd87 100644 --- a/packages/livekit-server-sdk/src/WebhookReceiver.ts +++ b/packages/livekit-server-sdk/src/WebhookReceiver.ts @@ -69,6 +69,9 @@ export class WebhookReceiver { throw new Error('authorization header is empty'); } const claims = await this.verifier.verify(authHeader, clockTolerance); + if (!claims.sha256) { + throw new Error('sha256 was not found in the token'); + } // confirm sha const hash = await digest(body); const hashDecoded = btoa(