Skip to content
File

Blob: tests/worker/runtime/routing/host.test.ts

typescript141 lines
1import { describe, expect, it } from "vitest";
2 
3import { HOST_WORDS } from "@/worker/auth/host-wordlist";
4import { classifyHost } from "@/worker/routes/host";
5 
6const env = {
7 CONTROL_PLANE_HOST: "dav.example.com",
8 SUBJECT_HOST_SUFFIX: ".dav.example.com",
9} as Env;
10 
11const blockedHostWords = [
12 "abbot",
13 "acne",
14 "acolyte",
15 "allergy",
16 "alleluia",
17 "altar",
18 "anal",
19 "anatomy",
20 "anarchic",
21 "anarchy",
22 "anathema",
23 "anatomic",
24 "aneurysm",
25 "angel",
26 "angelic",
27 "apostle",
28 "artery",
29 "baptist",
30 "baptize",
31 "bladder",
32 "bone",
33 "bonehead",
34 "boner",
35 "bondage",
36 "brothel",
37 "cardiac",
38 "chapel",
39 "chaplain",
40 "chaplet",
41 "cholera",
42 "choir",
43 "clinic",
44 "coke",
45 "coital",
46 "cough",
47 "crania",
48 "cranium",
49 "crazy",
50 "crucifix",
51 "crozier",
52 "deify",
53 "deism",
54 "deity",
55 "diocese",
56 "dioxin",
57 "divine",
58 "divinely",
59 "divinity",
60 "dumb",
61 "erotica",
62 "fart",
63 "fat",
64 "fatter",
65 "fattest",
66 "fascism",
67 "fascist",
68 "genital",
69 "genetic",
70 "genome",
71 "gonad",
72 "hiccough",
73 "hormone",
74 "hormonal",
75 "horniest",
76 "jeep",
77 "lama",
78 "lavatory",
79 "lunatic",
80 "lust",
81 "lustful",
82 "lustily",
83 "messiah",
84 "monk",
85 "moron",
86 "morphine",
87 "nipple",
88 "opioid",
89 "organ",
90 "organist",
91 "papal",
92 "pastor",
93 "pepsin",
94 "plague",
95 "pope",
96 "prayer",
97 "psalmist",
98 "religion",
99 "saintly",
100 "semen",
101 "senator",
102 "shaman",
103 "soviet",
104 "tendon",
105 "therapy",
106 "vicar",
107 "wishbone",
108 "wimp",
109 "wound",
110] as const;
111 
112describe("host classification", () => {
113 it("classifies the control-plane host", () => {
114 const request = new Request("https://dav.example.com/healthz", { headers: { host: "dav.example.com" } });
115 expect(classifyHost(request, env)).toMatchObject({ kind: "control", normalizedHost: "dav.example.com" });
116 });
117 
118 it("accepts valid five-word subject labels", () => {
119 const request = new Request("https://river-copper-lantern-velvet-maple.dav.example.com/files/", {
120 headers: { host: "river-copper-lantern-velvet-maple.dav.example.com" },
121 });
122 expect(classifyHost(request, env)).toMatchObject({
123 kind: "subject",
124 hostLabel: "river-copper-lantern-velvet-maple",
125 });
126 });
127 
128 it("rejects malformed subject labels", () => {
129 const request = new Request("https://not-enough-words.dav.example.com/files/", {
130 headers: { host: "not-enough-words.dav.example.com" },
131 });
132 expect(classifyHost(request, env)).toMatchObject({ kind: "unknown" });
133 });
134 
135 it("keeps the host wordlist at the required size without blocked terms", () => {
136 expect(HOST_WORDS).toHaveLength(8192);
137 expect(new Set(HOST_WORDS).size).toBe(HOST_WORDS.length);
138 expect(HOST_WORDS).not.toEqual(expect.arrayContaining([...blockedHostWords]));
139 });
140});