import { UnauthorizedException } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { IdentityService } from '@task-stream/api/identity/application'; import { createHmac } from 'node:crypto'; import { PireonWebhookController } from './pireon-webhook.controller'; describe('PireonWebhookController', () => { const handled: string[] = []; const controller = (secrets: Record) => new PireonWebhookController( { handleWebhook: async (event: string) => { handled.push(event); }, } as unknown as IdentityService, { get: (key: string) => secrets[key] } as unknown as ConfigService, ); const body = { event: 'token.revoked', data: { token_id: 't-1' } }; const raw = Buffer.from(JSON.stringify(body)); const signed = (secret: string) => createHmac('sha256', secret).update(raw).digest('hex'); const request = { rawBody: raw, body } as never; beforeEach(() => (handled.length = 0)); it("accepts a delivery signed with either Pireon client's secret", async () => { const both = controller({ PIREON_WEBHOOK_SECRET: 'web-secret', PIREON_PASSWORD_WEBHOOK_SECRET: 'password-secret', }); await both.receive(request, signed('web-secret')); await both.receive(request, `sha256=${signed('password-secret')}`); expect(handled).toEqual(['token.revoked', 'token.revoked']); }); it('refuses any other signature, and everything when no secret is set', async () => { await expect( controller({ PIREON_WEBHOOK_SECRET: 'web-secret' }).receive( request, signed('password-secret'), ), ).rejects.toThrow(UnauthorizedException); await expect( controller({}).receive(request, signed('web-secret')), ).rejects.toThrow(/disabled/); expect(handled).toEqual([]); }); });