1 | |
2 | type Vercel = { |
3 | token: string; |
4 | }; |
5 | |
6 | * Put Firewall Configuration |
7 | * Set the firewall configuration to provided rules and settings. Creates or overwrite the existing firewall configuration. |
8 | */ |
9 | export async function main( |
10 | auth: Vercel, |
11 | projectId: string | undefined, |
12 | teamId: string | undefined, |
13 | slug: string | undefined, |
14 | body: { |
15 | firewallEnabled: false | true; |
16 | managedRules?: {}; |
17 | crs?: { |
18 | sd?: { active: false | true; action: "deny" | "log" }; |
19 | ma?: { active: false | true; action: "deny" | "log" }; |
20 | lfi?: { active: false | true; action: "deny" | "log" }; |
21 | rfi?: { active: false | true; action: "deny" | "log" }; |
22 | rce?: { active: false | true; action: "deny" | "log" }; |
23 | php?: { active: false | true; action: "deny" | "log" }; |
24 | gen?: { active: false | true; action: "deny" | "log" }; |
25 | xss?: { active: false | true; action: "deny" | "log" }; |
26 | sqli?: { active: false | true; action: "deny" | "log" }; |
27 | sf?: { active: false | true; action: "deny" | "log" }; |
28 | java?: { active: false | true; action: "deny" | "log" }; |
29 | }; |
30 | rules?: { |
31 | id?: string; |
32 | name: string; |
33 | description?: string; |
34 | active: false | true; |
35 | conditionGroup: { |
36 | conditions: { |
37 | type: |
38 | | "host" |
39 | | "path" |
40 | | "method" |
41 | | "header" |
42 | | "query" |
43 | | "cookie" |
44 | | "target_path" |
45 | | "raw_path" |
46 | | "ip_address" |
47 | | "region" |
48 | | "protocol" |
49 | | "scheme" |
50 | | "environment" |
51 | | "user_agent" |
52 | | "geo_continent" |
53 | | "geo_country" |
54 | | "geo_country_region" |
55 | | "geo_city" |
56 | | "geo_as_number" |
57 | | "ja4_digest" |
58 | | "ja3_digest" |
59 | | "rate_limit_api_id"; |
60 | op: |
61 | | "re" |
62 | | "eq" |
63 | | "neq" |
64 | | "ex" |
65 | | "nex" |
66 | | "inc" |
67 | | "ninc" |
68 | | "pre" |
69 | | "suf" |
70 | | "sub" |
71 | | "gt" |
72 | | "gte" |
73 | | "lt" |
74 | | "lte"; |
75 | neg?: false | true; |
76 | key?: string; |
77 | value?: string | number | string[]; |
78 | }[]; |
79 | }[]; |
80 | action: { |
81 | mitigate?: { |
82 | action: |
83 | | "deny" |
84 | | "log" |
85 | | "challenge" |
86 | | "bypass" |
87 | | "rate_limit" |
88 | | "redirect"; |
89 | rateLimit?: { |
90 | algo: "fixed_window" | "token_bucket"; |
91 | window: number; |
92 | limit: number; |
93 | keys: string[]; |
94 | action?: "deny" | "log" | "challenge" | "rate_limit"; |
95 | }; |
96 | redirect?: { location: string; permanent: false | true }; |
97 | actionDuration?: string; |
98 | bypassSystem?: false | true; |
99 | }; |
100 | }; |
101 | }[]; |
102 | ips?: { |
103 | id?: string; |
104 | hostname: string; |
105 | ip: string; |
106 | notes?: string; |
107 | action: "deny" | "log" | "challenge" | "bypass"; |
108 | }[]; |
109 | }, |
110 | ) { |
111 | const url = new URL(`https://api.vercel.com/v1/security/firewall/config`); |
112 | for (const [k, v] of [ |
113 | ["projectId", projectId], |
114 | ["teamId", teamId], |
115 | ["slug", slug], |
116 | ]) { |
117 | if (v !== undefined && v !== "" && k !== undefined) { |
118 | url.searchParams.append(k, v); |
119 | } |
120 | } |
121 | const response = await fetch(url, { |
122 | method: "PUT", |
123 | headers: { |
124 | "Content-Type": "application/json", |
125 | Authorization: "Bearer " + auth.token, |
126 | }, |
127 | body: JSON.stringify(body), |
128 | }); |
129 | if (!response.ok) { |
130 | const text = await response.text(); |
131 | throw new Error(`${response.status} ${text}`); |
132 | } |
133 | return await response.json(); |
134 | } |
135 |
|