import { describe, it, expect } from 'vitest';
import { signPayload, verifySignature } from '../../webhooks/index.js';
import { validateWebhookUrl } from '../../security/webhook.js';
describe('Webhook signing', () => {
    const secret = 'test-webhook-secret-key-12345';
    it('signPayload produces a hex string', async () => {
        const sig = await signPayload('{"event":"test"}', secret);
        expect(sig).toMatch(/^[0-9a-f]{64}$/);
    });
    it('signPayload is deterministic', async () => {
        const body = '{"event":"document.created","data":{}}';
        const sig1 = await signPayload(body, secret);
        const sig2 = await signPayload(body, secret);
        expect(sig1).toBe(sig2);
    });
    it('different payloads produce different signatures', async () => {
        const sig1 = await signPayload('payload-a', secret);
        const sig2 = await signPayload('payload-b', secret);
        expect(sig1).not.toBe(sig2);
    });
    it('different secrets produce different signatures', async () => {
        const body = 'same-payload';
        const sig1 = await signPayload(body, 'secret-1');
        const sig2 = await signPayload(body, 'secret-2');
        expect(sig1).not.toBe(sig2);
    });
    it('verifySignature returns true for valid signature', async () => {
        const body = '{"event":"test","data":{}}';
        const sig = await signPayload(body, secret);
        const valid = await verifySignature(body, sig, secret);
        expect(valid).toBe(true);
    });
    it('verifySignature returns false for tampered payload', async () => {
        const sig = await signPayload('original', secret);
        const valid = await verifySignature('tampered', sig, secret);
        expect(valid).toBe(false);
    });
    it('verifySignature returns false for wrong secret', async () => {
        const body = 'test-payload';
        const sig = await signPayload(body, secret);
        const valid = await verifySignature(body, sig, 'wrong-secret');
        expect(valid).toBe(false);
    });
    it('verifySignature returns false for truncated signature', async () => {
        const body = 'test';
        const sig = await signPayload(body, secret);
        const valid = await verifySignature(body, sig.slice(0, 32), secret);
        expect(valid).toBe(false);
    });
});
describe('Webhook URL SSRF validation', () => {
    it('allows valid HTTPS URLs', () => {
        expect(validateWebhookUrl('https://example.com/webhook')).toEqual({ valid: true });
        expect(validateWebhookUrl('https://hooks.slack.com/services/xxx')).toEqual({ valid: true });
    });
    it('allows valid HTTP URLs', () => {
        expect(validateWebhookUrl('http://example.com/webhook')).toEqual({ valid: true });
    });
    it('rejects localhost', () => {
        const result = validateWebhookUrl('http://localhost:3000/hook');
        expect(result.valid).toBe(false);
    });
    it('rejects 0.0.0.0', () => {
        const result = validateWebhookUrl('http://0.0.0.0/hook');
        expect(result.valid).toBe(false);
    });
    it('rejects 10.x private range', () => {
        const result = validateWebhookUrl('http://10.0.0.1/hook');
        expect(result.valid).toBe(false);
    });
    it('rejects 192.168.x private range', () => {
        const result = validateWebhookUrl('http://192.168.1.1/hook');
        expect(result.valid).toBe(false);
    });
    it('rejects 172.16-31.x private range', () => {
        expect(validateWebhookUrl('http://172.16.0.1/hook').valid).toBe(false);
        expect(validateWebhookUrl('http://172.31.255.1/hook').valid).toBe(false);
    });
    it('rejects 127.x loopback', () => {
        const result = validateWebhookUrl('http://127.0.0.1/hook');
        expect(result.valid).toBe(false);
    });
    it('rejects link-local addresses', () => {
        const result = validateWebhookUrl('http://169.254.1.1/hook');
        expect(result.valid).toBe(false);
    });
    it('rejects non-HTTP protocols', () => {
        expect(validateWebhookUrl('ftp://example.com/file').valid).toBe(false);
        expect(validateWebhookUrl('file:///etc/passwd').valid).toBe(false);
    });
    it('rejects invalid URLs', () => {
        expect(validateWebhookUrl('not-a-url').valid).toBe(false);
        expect(validateWebhookUrl('').valid).toBe(false);
    });
});
//# sourceMappingURL=webhooks.test.js.map