/ opencodehub / tests / unit / url-validator.test.ts
Swadhin Biswas test(qa): add e2e, integration, unit, and load coverage · 3/6/2026
1c29e63
101 lines · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { isAllowedWebhookUrlSync } from "@/lib/url-validator";
import { describe, expect, it } from "vitest";

describe("isAllowedWebhookUrlSync", () => {
  describe("blocks private/reserved IPs", () => {
    it("blocks localhost", () => {
      expect(isAllowedWebhookUrlSync("http://localhost/hook")).toBe(false);
    });

    it("blocks localhost with port", () => {
      expect(isAllowedWebhookUrlSync("http://localhost:8080/hook")).toBe(false);
    });

    it("blocks 127.0.0.1", () => {
      expect(isAllowedWebhookUrlSync("http://127.0.0.1/hook")).toBe(false);
    });

    it("blocks 10.x.x.x range", () => {
      expect(isAllowedWebhookUrlSync("http://10.0.0.1/hook")).toBe(false);
    });

    it("blocks 192.168.x.x range", () => {
      expect(isAllowedWebhookUrlSync("http://192.168.1.1/hook")).toBe(false);
    });

    it("blocks 172.16.x.x range", () => {
      expect(isAllowedWebhookUrlSync("http://172.16.0.1/hook")).toBe(false);
    });

    it("blocks 169.254.x.x metadata range", () => {
      expect(
        isAllowedWebhookUrlSync("http://169.254.169.254/latest/meta-data"),
      ).toBe(false);
    });

    it("blocks 0.0.0.0", () => {
      expect(isAllowedWebhookUrlSync("http://0.0.0.0/hook")).toBe(false);
    });

    it("blocks [::1] (IPv6 loopback)", () => {
      expect(isAllowedWebhookUrlSync("http://[::1]/hook")).toBe(false);
    });
  });

  describe("blocks non-http(s) schemes", () => {
    it("blocks ftp scheme", () => {
      expect(isAllowedWebhookUrlSync("ftp://example.com/hook")).toBe(false);
    });

    it("blocks file scheme", () => {
      expect(isAllowedWebhookUrlSync("file:///etc/passwd")).toBe(false);
    });

    it("blocks javascript scheme", () => {
      expect(isAllowedWebhookUrlSync("javascript:alert(1)")).toBe(false);
    });

    it("blocks data scheme", () => {
      expect(
        isAllowedWebhookUrlSync("data:text/html,<script>alert(1)</script>"),
      ).toBe(false);
    });
  });

  describe("allows valid public URLs", () => {
    it("allows https public URL", () => {
      expect(isAllowedWebhookUrlSync("https://example.com/webhook")).toBe(true);
    });

    it("allows http public URL", () => {
      expect(isAllowedWebhookUrlSync("http://example.com/webhook")).toBe(true);
    });

    it("allows public IP", () => {
      expect(isAllowedWebhookUrlSync("http://8.8.8.8/hook")).toBe(true);
    });

    it("allows URL with port", () => {
      expect(
        isAllowedWebhookUrlSync("https://hooks.example.com:9000/webhook"),
      ).toBe(true);
    });

    it("allows URL with path", () => {
      expect(
        isAllowedWebhookUrlSync("https://api.example.com/v1/hooks/receive"),
      ).toBe(true);
    });
  });

  describe("edge cases", () => {
    it("rejects empty string", () => {
      expect(isAllowedWebhookUrlSync("")).toBe(false);
    });

    it("rejects invalid URL", () => {
      expect(isAllowedWebhookUrlSync("not-a-url")).toBe(false);
    });
  });
});