@prosopo/provider 5.0.5 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$cjs.log +12 -11
- package/.turbo/turbo-build$colon$tsc.log +24 -24
- package/.turbo/turbo-build.log +13 -12
- package/CHANGELOG.md +37 -0
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +12 -0
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
- package/dist/api/captcha/getImageCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/getImageCaptchaChallenge.js +13 -1
- package/dist/api/captcha/getImageCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/getPoWCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/getPoWCaptchaChallenge.js +12 -1
- package/dist/api/captcha/getPoWCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/getPuzzleCaptchaChallenge.js +12 -1
- package/dist/api/captcha/getPuzzleCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/trafficFilterRequestTime.d.ts +38 -0
- package/dist/api/captcha/trafficFilterRequestTime.d.ts.map +1 -0
- package/dist/api/captcha/trafficFilterRequestTime.js +109 -0
- package/dist/api/captcha/trafficFilterRequestTime.js.map +1 -0
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +13 -0
- package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +13 -1
- package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +12 -1
- package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +12 -1
- package/dist/cjs/api/captcha/trafficFilterRequestTime.cjs +111 -0
- package/dist/cjs/tasks/captchaManager.cjs +13 -6
- package/dist/cjs/tasks/dnsEvent/enrichDnsEvent.cjs +10 -8
- package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +2 -3
- package/dist/cjs/tasks/spam/checkTrafficFilter.cjs +101 -75
- package/dist/tasks/captchaManager.d.ts.map +1 -1
- package/dist/tasks/captchaManager.js +14 -7
- package/dist/tasks/captchaManager.js.map +1 -1
- package/dist/tasks/dnsEvent/enrichDnsEvent.d.ts.map +1 -1
- package/dist/tasks/dnsEvent/enrichDnsEvent.js +10 -8
- package/dist/tasks/dnsEvent/enrichDnsEvent.js.map +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js +2 -3
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
- package/dist/tasks/spam/checkTrafficFilter.d.ts +18 -1
- package/dist/tasks/spam/checkTrafficFilter.d.ts.map +1 -1
- package/dist/tasks/spam/checkTrafficFilter.js +101 -77
- package/dist/tasks/spam/checkTrafficFilter.js.map +1 -1
- package/dist/tests/integration/clientSettingsPersistence.integration.test.js +24 -17
- package/dist/tests/integration/clientSettingsPersistence.integration.test.js.map +1 -1
- package/dist/tests/integration/trafficFilterHierarchy.integration.test.d.ts +2 -0
- package/dist/tests/integration/trafficFilterHierarchy.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/trafficFilterHierarchy.integration.test.js +215 -0
- package/dist/tests/integration/trafficFilterHierarchy.integration.test.js.map +1 -0
- package/dist/tests/unit/api/captcha/trafficFilterRequestTime.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/captcha/trafficFilterRequestTime.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/captcha/trafficFilterRequestTime.unit.test.js +255 -0
- package/dist/tests/unit/api/captcha/trafficFilterRequestTime.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/dnsEvent/enrichDnsEvent.unit.test.js +6 -9
- package/dist/tests/unit/tasks/dnsEvent/enrichDnsEvent.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js +95 -0
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js +272 -98
- package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js.map +1 -1
- package/package.json +13 -13
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { CaptchaType, TrafficFilterAction, } from "@prosopo/types";
|
|
1
2
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { checkTrafficFilter } from "../../../../tasks/spam/checkTrafficFilter.js";
|
|
3
|
+
import { checkTrafficFilter, resolveChallengePolicy, } from "../../../../tasks/spam/checkTrafficFilter.js";
|
|
3
4
|
const baseInfo = (overrides = {}) => ({
|
|
4
5
|
ip: "1.2.3.4",
|
|
5
6
|
isValid: true,
|
|
@@ -13,38 +14,54 @@ const baseInfo = (overrides = {}) => ({
|
|
|
13
14
|
isCrawler: false,
|
|
14
15
|
...overrides,
|
|
15
16
|
});
|
|
17
|
+
const block = { action: TrafficFilterAction.Block };
|
|
16
18
|
const allBlocked = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
vpn: block,
|
|
20
|
+
proxy: block,
|
|
21
|
+
tor: block,
|
|
22
|
+
abuser: block,
|
|
21
23
|
abuserScoreThreshold: 0,
|
|
22
|
-
|
|
24
|
+
datacenter: block,
|
|
23
25
|
skipExtrasOnValidDnsPath: false,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
mobile: block,
|
|
27
|
+
satellite: block,
|
|
28
|
+
crawler: block,
|
|
27
29
|
};
|
|
28
30
|
describe("checkTrafficFilter", () => {
|
|
29
31
|
it("blocks VPN when blockVpn is true", () => {
|
|
30
32
|
const result = checkTrafficFilter(baseInfo({ isVPN: true }), allBlocked);
|
|
31
|
-
expect(result).
|
|
33
|
+
expect(result).toMatchObject({
|
|
34
|
+
isBlocked: true,
|
|
35
|
+
reason: "API.VPN_BLOCKED",
|
|
36
|
+
});
|
|
32
37
|
});
|
|
33
38
|
it("blocks proxy when blockProxy is true", () => {
|
|
34
39
|
const result = checkTrafficFilter(baseInfo({ isProxy: true }), allBlocked);
|
|
35
|
-
expect(result).
|
|
40
|
+
expect(result).toMatchObject({
|
|
41
|
+
isBlocked: true,
|
|
42
|
+
reason: "API.PROXY_BLOCKED",
|
|
43
|
+
});
|
|
36
44
|
});
|
|
37
45
|
it("blocks Tor when blockTor is true", () => {
|
|
38
46
|
const result = checkTrafficFilter(baseInfo({ isTor: true }), allBlocked);
|
|
39
|
-
expect(result).
|
|
47
|
+
expect(result).toMatchObject({
|
|
48
|
+
isBlocked: true,
|
|
49
|
+
reason: "API.TOR_BLOCKED",
|
|
50
|
+
});
|
|
40
51
|
});
|
|
41
52
|
it("blocks abusive ASN when blockAbuser is true", () => {
|
|
42
53
|
const result = checkTrafficFilter(baseInfo({ isAbuser: true }), allBlocked);
|
|
43
|
-
expect(result).
|
|
54
|
+
expect(result).toMatchObject({
|
|
55
|
+
isBlocked: true,
|
|
56
|
+
reason: "API.ABUSER_BLOCKED",
|
|
57
|
+
});
|
|
44
58
|
});
|
|
45
59
|
it("blocks abuser when score meets threshold", () => {
|
|
46
60
|
const result = checkTrafficFilter(baseInfo({ isAbuser: true, abuserScore: 0.06, companyAbuserScore: 0.03 }), { ...allBlocked, abuserScoreThreshold: 0.05 });
|
|
47
|
-
expect(result).
|
|
61
|
+
expect(result).toMatchObject({
|
|
62
|
+
isBlocked: true,
|
|
63
|
+
reason: "API.ABUSER_BLOCKED",
|
|
64
|
+
});
|
|
48
65
|
});
|
|
49
66
|
it("allows abuser when score is below threshold", () => {
|
|
50
67
|
const result = checkTrafficFilter(baseInfo({
|
|
@@ -52,7 +69,7 @@ describe("checkTrafficFilter", () => {
|
|
|
52
69
|
abuserScore: 0.0052,
|
|
53
70
|
companyAbuserScore: 0.0273,
|
|
54
71
|
}), { ...allBlocked, abuserScoreThreshold: 0.05 });
|
|
55
|
-
expect(result).
|
|
72
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
56
73
|
});
|
|
57
74
|
it("uses company abuser score when it is higher than ASN score", () => {
|
|
58
75
|
const result = checkTrafficFilter(baseInfo({
|
|
@@ -60,81 +77,93 @@ describe("checkTrafficFilter", () => {
|
|
|
60
77
|
abuserScore: 0.01,
|
|
61
78
|
companyAbuserScore: 0.08,
|
|
62
79
|
}), { ...allBlocked, abuserScoreThreshold: 0.05 });
|
|
63
|
-
expect(result).
|
|
80
|
+
expect(result).toMatchObject({
|
|
81
|
+
isBlocked: true,
|
|
82
|
+
reason: "API.ABUSER_BLOCKED",
|
|
83
|
+
});
|
|
64
84
|
});
|
|
65
85
|
it("blocks datacenter when blockDatacenter is true", () => {
|
|
66
86
|
const result = checkTrafficFilter(baseInfo({ isDatacenter: true }), allBlocked);
|
|
67
|
-
expect(result).
|
|
87
|
+
expect(result).toMatchObject({
|
|
68
88
|
isBlocked: true,
|
|
69
89
|
reason: "API.DATACENTER_BLOCKED",
|
|
70
90
|
});
|
|
71
91
|
});
|
|
72
92
|
it("does not block VPN-on-datacenter IPs when blockDatacenter is on but blockVpn is off", () => {
|
|
73
|
-
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isVPN: true }), { ...allBlocked,
|
|
74
|
-
expect(result).
|
|
93
|
+
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isVPN: true }), { ...allBlocked, vpn: undefined });
|
|
94
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
75
95
|
});
|
|
76
96
|
it("does not block proxy-on-datacenter IPs when blockDatacenter is on but blockProxy is off", () => {
|
|
77
|
-
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isProxy: true }), { ...allBlocked,
|
|
78
|
-
expect(result).
|
|
97
|
+
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isProxy: true }), { ...allBlocked, proxy: undefined });
|
|
98
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
79
99
|
});
|
|
80
100
|
it("does not block Tor-on-datacenter IPs when blockDatacenter is on but blockTor is off", () => {
|
|
81
|
-
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isTor: true }), { ...allBlocked,
|
|
82
|
-
expect(result).
|
|
101
|
+
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isTor: true }), { ...allBlocked, tor: undefined });
|
|
102
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
83
103
|
});
|
|
84
104
|
it("does not block crawler-on-datacenter IPs when blockDatacenter is on but blockCrawler is off", () => {
|
|
85
|
-
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isCrawler: true }), { ...allBlocked,
|
|
86
|
-
expect(result).
|
|
105
|
+
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isCrawler: true }), { ...allBlocked, crawler: undefined });
|
|
106
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
87
107
|
});
|
|
88
108
|
it("still blocks raw datacenter (non-VPN) IPs when blockDatacenter is on and blockVpn is off", () => {
|
|
89
|
-
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isVPN: false }), { ...allBlocked,
|
|
90
|
-
expect(result).
|
|
109
|
+
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isVPN: false }), { ...allBlocked, vpn: undefined });
|
|
110
|
+
expect(result).toMatchObject({
|
|
91
111
|
isBlocked: true,
|
|
92
112
|
reason: "API.DATACENTER_BLOCKED",
|
|
93
113
|
});
|
|
94
114
|
});
|
|
95
115
|
it("blocks VPN-on-datacenter IPs as VPN when both filters are enabled", () => {
|
|
96
116
|
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, isVPN: true }), allBlocked);
|
|
97
|
-
expect(result).
|
|
117
|
+
expect(result).toMatchObject({
|
|
118
|
+
isBlocked: true,
|
|
119
|
+
reason: "API.VPN_BLOCKED",
|
|
120
|
+
});
|
|
98
121
|
});
|
|
99
122
|
it("blocks mobile when blockMobile is true", () => {
|
|
100
123
|
const result = checkTrafficFilter(baseInfo({ isMobile: true }), allBlocked);
|
|
101
|
-
expect(result).
|
|
124
|
+
expect(result).toMatchObject({
|
|
125
|
+
isBlocked: true,
|
|
126
|
+
reason: "API.MOBILE_BLOCKED",
|
|
127
|
+
});
|
|
102
128
|
});
|
|
103
129
|
it("blocks satellite when blockSatellite is true", () => {
|
|
104
130
|
const result = checkTrafficFilter(baseInfo({ isSatellite: true }), allBlocked);
|
|
105
|
-
expect(result).
|
|
131
|
+
expect(result).toMatchObject({
|
|
106
132
|
isBlocked: true,
|
|
107
133
|
reason: "API.SATELLITE_BLOCKED",
|
|
108
134
|
});
|
|
109
135
|
});
|
|
110
136
|
it("blocks crawler when blockCrawler is true", () => {
|
|
111
137
|
const result = checkTrafficFilter(baseInfo({ isCrawler: true }), allBlocked);
|
|
112
|
-
expect(result).
|
|
138
|
+
expect(result).toMatchObject({
|
|
139
|
+
isBlocked: true,
|
|
140
|
+
reason: "API.CRAWLER_BLOCKED",
|
|
141
|
+
});
|
|
113
142
|
});
|
|
114
143
|
it("allows traffic when all filters are disabled", () => {
|
|
115
144
|
const result = checkTrafficFilter(baseInfo({ isVPN: true }), {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
});
|
|
125
|
-
expect(result).
|
|
145
|
+
vpn: undefined,
|
|
146
|
+
proxy: undefined,
|
|
147
|
+
tor: undefined,
|
|
148
|
+
abuser: undefined,
|
|
149
|
+
datacenter: undefined,
|
|
150
|
+
mobile: undefined,
|
|
151
|
+
satellite: undefined,
|
|
152
|
+
crawler: undefined,
|
|
153
|
+
});
|
|
154
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
126
155
|
});
|
|
127
156
|
it("allows residential IPs through", () => {
|
|
128
157
|
const result = checkTrafficFilter(baseInfo(), allBlocked);
|
|
129
|
-
expect(result).
|
|
158
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
130
159
|
});
|
|
131
160
|
it("allows through if IP info is missing entirely", () => {
|
|
132
161
|
const result = checkTrafficFilter(undefined, allBlocked);
|
|
133
|
-
expect(result).
|
|
162
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
134
163
|
});
|
|
135
164
|
it("allows through if IP info is invalid", () => {
|
|
136
165
|
const result = checkTrafficFilter({ isValid: false, error: "lookup failed", ip: "1.2.3.4" }, allBlocked);
|
|
137
|
-
expect(result).
|
|
166
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
138
167
|
});
|
|
139
168
|
describe("extraIpInfos", () => {
|
|
140
169
|
const cleanPrimary = baseInfo({ ip: "192.0.2.1" });
|
|
@@ -142,7 +171,7 @@ describe("checkTrafficFilter", () => {
|
|
|
142
171
|
const result = checkTrafficFilter(cleanPrimary, allBlocked, [
|
|
143
172
|
baseInfo({ ip: "198.51.100.10", isDatacenter: true }),
|
|
144
173
|
]);
|
|
145
|
-
expect(result).
|
|
174
|
+
expect(result).toMatchObject({
|
|
146
175
|
isBlocked: true,
|
|
147
176
|
reason: "API.DATACENTER_BLOCKED",
|
|
148
177
|
});
|
|
@@ -155,13 +184,13 @@ describe("checkTrafficFilter", () => {
|
|
|
155
184
|
abuserScore: 95,
|
|
156
185
|
}),
|
|
157
186
|
]);
|
|
158
|
-
expect(result).
|
|
187
|
+
expect(result).toMatchObject({
|
|
159
188
|
isBlocked: true,
|
|
160
189
|
reason: "API.ABUSER_BLOCKED",
|
|
161
190
|
});
|
|
162
191
|
});
|
|
163
192
|
it("applies VPN-datacenter suppression to extra IPs when blockVpn is off", () => {
|
|
164
|
-
const noVpnBlock = { ...allBlocked,
|
|
193
|
+
const noVpnBlock = { ...allBlocked, vpn: undefined };
|
|
165
194
|
const result = checkTrafficFilter(cleanPrimary, noVpnBlock, [
|
|
166
195
|
baseInfo({
|
|
167
196
|
ip: "198.51.100.10",
|
|
@@ -169,10 +198,10 @@ describe("checkTrafficFilter", () => {
|
|
|
169
198
|
isDatacenter: true,
|
|
170
199
|
}),
|
|
171
200
|
]);
|
|
172
|
-
expect(result).
|
|
201
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
173
202
|
});
|
|
174
203
|
it("still blocks a datacenter extra that is not a VPN when blockVpn is off", () => {
|
|
175
|
-
const noVpnBlock = { ...allBlocked,
|
|
204
|
+
const noVpnBlock = { ...allBlocked, vpn: undefined };
|
|
176
205
|
const result = checkTrafficFilter(cleanPrimary, noVpnBlock, [
|
|
177
206
|
baseInfo({
|
|
178
207
|
ip: "198.51.100.10",
|
|
@@ -180,22 +209,22 @@ describe("checkTrafficFilter", () => {
|
|
|
180
209
|
isDatacenter: true,
|
|
181
210
|
}),
|
|
182
211
|
]);
|
|
183
|
-
expect(result).
|
|
212
|
+
expect(result).toMatchObject({
|
|
184
213
|
isBlocked: true,
|
|
185
214
|
reason: "API.DATACENTER_BLOCKED",
|
|
186
215
|
});
|
|
187
216
|
});
|
|
188
217
|
it("does apply VPN-datacenter suppression to the primary IP", () => {
|
|
189
|
-
const noVpnBlock = { ...allBlocked,
|
|
218
|
+
const noVpnBlock = { ...allBlocked, vpn: undefined };
|
|
190
219
|
const result = checkTrafficFilter(baseInfo({ isVPN: true, isDatacenter: true }), noVpnBlock);
|
|
191
|
-
expect(result).
|
|
220
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
192
221
|
});
|
|
193
222
|
it("allows through when extra IPs are clean", () => {
|
|
194
223
|
const result = checkTrafficFilter(cleanPrimary, allBlocked, [
|
|
195
224
|
baseInfo({ ip: "8.8.8.8" }),
|
|
196
225
|
baseInfo({ ip: "1.1.1.1" }),
|
|
197
226
|
]);
|
|
198
|
-
expect(result).
|
|
227
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
199
228
|
});
|
|
200
229
|
it("ignores undefined / invalid entries in the extras list", () => {
|
|
201
230
|
const result = checkTrafficFilter(cleanPrimary, allBlocked, [
|
|
@@ -203,7 +232,7 @@ describe("checkTrafficFilter", () => {
|
|
|
203
232
|
{ isValid: false, error: "lookup failed", ip: "1.2.3.4" },
|
|
204
233
|
baseInfo({ ip: "198.51.100.10", isDatacenter: true }),
|
|
205
234
|
]);
|
|
206
|
-
expect(result).
|
|
235
|
+
expect(result).toMatchObject({
|
|
207
236
|
isBlocked: true,
|
|
208
237
|
reason: "API.DATACENTER_BLOCKED",
|
|
209
238
|
});
|
|
@@ -212,23 +241,26 @@ describe("checkTrafficFilter", () => {
|
|
|
212
241
|
const result = checkTrafficFilter(baseInfo({ isTor: true }), allBlocked, [
|
|
213
242
|
baseInfo({ ip: "198.51.100.10", isDatacenter: true }),
|
|
214
243
|
]);
|
|
215
|
-
expect(result).
|
|
244
|
+
expect(result).toMatchObject({
|
|
245
|
+
isBlocked: true,
|
|
246
|
+
reason: "API.TOR_BLOCKED",
|
|
247
|
+
});
|
|
216
248
|
});
|
|
217
249
|
it("does not check the crawler flag on extra IPs even when blockCrawler is on", () => {
|
|
218
250
|
const result = checkTrafficFilter(cleanPrimary, allBlocked, [
|
|
219
251
|
baseInfo({ ip: "8.8.8.8", isCrawler: true }),
|
|
220
252
|
]);
|
|
221
|
-
expect(result).
|
|
253
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
222
254
|
});
|
|
223
255
|
it("still blocks the crawler flag on the primary IP when an extra is present", () => {
|
|
224
256
|
const result = checkTrafficFilter(baseInfo({ isCrawler: true }), allBlocked, [baseInfo({ ip: "8.8.8.8" })]);
|
|
225
|
-
expect(result).
|
|
257
|
+
expect(result).toMatchObject({
|
|
226
258
|
isBlocked: true,
|
|
227
259
|
reason: "API.CRAWLER_BLOCKED",
|
|
228
260
|
});
|
|
229
261
|
});
|
|
230
262
|
it("applies proxy-datacenter suppression to extra IPs when blockProxy is off", () => {
|
|
231
|
-
const noProxyBlock = { ...allBlocked,
|
|
263
|
+
const noProxyBlock = { ...allBlocked, proxy: undefined };
|
|
232
264
|
const result = checkTrafficFilter(cleanPrimary, noProxyBlock, [
|
|
233
265
|
baseInfo({
|
|
234
266
|
ip: "198.51.100.10",
|
|
@@ -236,10 +268,10 @@ describe("checkTrafficFilter", () => {
|
|
|
236
268
|
isDatacenter: true,
|
|
237
269
|
}),
|
|
238
270
|
]);
|
|
239
|
-
expect(result).
|
|
271
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
240
272
|
});
|
|
241
273
|
it("applies Tor-datacenter suppression to extra IPs when blockTor is off", () => {
|
|
242
|
-
const noTorBlock = { ...allBlocked,
|
|
274
|
+
const noTorBlock = { ...allBlocked, tor: undefined };
|
|
243
275
|
const result = checkTrafficFilter(cleanPrimary, noTorBlock, [
|
|
244
276
|
baseInfo({
|
|
245
277
|
ip: "198.51.100.10",
|
|
@@ -247,12 +279,12 @@ describe("checkTrafficFilter", () => {
|
|
|
247
279
|
isDatacenter: true,
|
|
248
280
|
}),
|
|
249
281
|
]);
|
|
250
|
-
expect(result).
|
|
282
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
251
283
|
});
|
|
252
284
|
it("applies crawler-datacenter suppression to extra IPs when blockCrawler is off", () => {
|
|
253
285
|
const noCrawlerBlock = {
|
|
254
286
|
...allBlocked,
|
|
255
|
-
|
|
287
|
+
crawler: undefined,
|
|
256
288
|
};
|
|
257
289
|
const result = checkTrafficFilter(cleanPrimary, noCrawlerBlock, [
|
|
258
290
|
baseInfo({
|
|
@@ -261,7 +293,7 @@ describe("checkTrafficFilter", () => {
|
|
|
261
293
|
isDatacenter: true,
|
|
262
294
|
}),
|
|
263
295
|
]);
|
|
264
|
-
expect(result).
|
|
296
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
265
297
|
});
|
|
266
298
|
});
|
|
267
299
|
describe("datacenterNameAllowlist", () => {
|
|
@@ -270,7 +302,7 @@ describe("checkTrafficFilter", () => {
|
|
|
270
302
|
isDatacenter: true,
|
|
271
303
|
datacenterName: "iCloud Private Relay",
|
|
272
304
|
}), { ...allBlocked, datacenterNameAllowlist: ["iCloud Private Relay"] });
|
|
273
|
-
expect(result).
|
|
305
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
274
306
|
});
|
|
275
307
|
it("matches the allowlist case-insensitively and ignores whitespace", () => {
|
|
276
308
|
const result = checkTrafficFilter(baseInfo({
|
|
@@ -280,11 +312,11 @@ describe("checkTrafficFilter", () => {
|
|
|
280
312
|
...allBlocked,
|
|
281
313
|
datacenterNameAllowlist: ["icloud private relay"],
|
|
282
314
|
});
|
|
283
|
-
expect(result).
|
|
315
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
284
316
|
});
|
|
285
317
|
it("still blocks datacenter IPs whose name does not match", () => {
|
|
286
318
|
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, datacenterName: "Amazon AWS" }), { ...allBlocked, datacenterNameAllowlist: ["iCloud Private Relay"] });
|
|
287
|
-
expect(result).
|
|
319
|
+
expect(result).toMatchObject({
|
|
288
320
|
isBlocked: true,
|
|
289
321
|
reason: "API.DATACENTER_BLOCKED",
|
|
290
322
|
});
|
|
@@ -294,7 +326,7 @@ describe("checkTrafficFilter", () => {
|
|
|
294
326
|
...allBlocked,
|
|
295
327
|
datacenterNameAllowlist: ["iCloud Private Relay"],
|
|
296
328
|
});
|
|
297
|
-
expect(result).
|
|
329
|
+
expect(result).toMatchObject({
|
|
298
330
|
isBlocked: true,
|
|
299
331
|
reason: "API.DATACENTER_BLOCKED",
|
|
300
332
|
});
|
|
@@ -304,7 +336,7 @@ describe("checkTrafficFilter", () => {
|
|
|
304
336
|
isDatacenter: true,
|
|
305
337
|
datacenterName: "iCloud Private Relay",
|
|
306
338
|
}), allBlocked);
|
|
307
|
-
expect(missing).
|
|
339
|
+
expect(missing).toMatchObject({
|
|
308
340
|
isBlocked: true,
|
|
309
341
|
reason: "API.DATACENTER_BLOCKED",
|
|
310
342
|
});
|
|
@@ -312,7 +344,7 @@ describe("checkTrafficFilter", () => {
|
|
|
312
344
|
isDatacenter: true,
|
|
313
345
|
datacenterName: "iCloud Private Relay",
|
|
314
346
|
}), { ...allBlocked, datacenterNameAllowlist: [] });
|
|
315
|
-
expect(empty).
|
|
347
|
+
expect(empty).toMatchObject({
|
|
316
348
|
isBlocked: true,
|
|
317
349
|
reason: "API.DATACENTER_BLOCKED",
|
|
318
350
|
});
|
|
@@ -323,7 +355,7 @@ describe("checkTrafficFilter", () => {
|
|
|
323
355
|
isDatacenter: true,
|
|
324
356
|
datacenterName: "iCloud Private Relay",
|
|
325
357
|
}), { ...allBlocked, datacenterNameAllowlist: ["iCloud Private Relay"] });
|
|
326
|
-
expect(torResult).
|
|
358
|
+
expect(torResult).toMatchObject({
|
|
327
359
|
isBlocked: true,
|
|
328
360
|
reason: "API.TOR_BLOCKED",
|
|
329
361
|
});
|
|
@@ -332,7 +364,7 @@ describe("checkTrafficFilter", () => {
|
|
|
332
364
|
isDatacenter: true,
|
|
333
365
|
datacenterName: "iCloud Private Relay",
|
|
334
366
|
}), { ...allBlocked, datacenterNameAllowlist: ["iCloud Private Relay"] });
|
|
335
|
-
expect(vpnResult).
|
|
367
|
+
expect(vpnResult).toMatchObject({
|
|
336
368
|
isBlocked: true,
|
|
337
369
|
reason: "API.VPN_BLOCKED",
|
|
338
370
|
});
|
|
@@ -345,28 +377,28 @@ describe("checkTrafficFilter", () => {
|
|
|
345
377
|
datacenterName: "iCloud Private Relay",
|
|
346
378
|
}),
|
|
347
379
|
]);
|
|
348
|
-
expect(result).
|
|
380
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
349
381
|
});
|
|
350
382
|
it("matches the allowlist against providerName when datacenterName is absent", () => {
|
|
351
383
|
const result = checkTrafficFilter(baseInfo({
|
|
352
384
|
isDatacenter: true,
|
|
353
385
|
providerName: "iCloud Private Relay",
|
|
354
386
|
}), { ...allBlocked, datacenterNameAllowlist: ["iCloud Private Relay"] });
|
|
355
|
-
expect(result).
|
|
387
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
356
388
|
});
|
|
357
389
|
it("matches the allowlist against asnOrganization when neither datacenterName nor providerName carries the operator", () => {
|
|
358
390
|
const result = checkTrafficFilter(baseInfo({
|
|
359
391
|
isDatacenter: true,
|
|
360
392
|
asnOrganization: "Cloudflare, Inc.",
|
|
361
393
|
}), { ...allBlocked, datacenterNameAllowlist: ["Cloudflare, Inc."] });
|
|
362
|
-
expect(result).
|
|
394
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
363
395
|
});
|
|
364
396
|
it("still blocks datacenter IPs that carry none of the three name fields", () => {
|
|
365
397
|
const result = checkTrafficFilter(baseInfo({ isDatacenter: true }), {
|
|
366
398
|
...allBlocked,
|
|
367
399
|
datacenterNameAllowlist: ["iCloud Private Relay"],
|
|
368
400
|
});
|
|
369
|
-
expect(result).
|
|
401
|
+
expect(result).toMatchObject({
|
|
370
402
|
isBlocked: true,
|
|
371
403
|
reason: "API.DATACENTER_BLOCKED",
|
|
372
404
|
});
|
|
@@ -380,18 +412,18 @@ describe("checkTrafficFilter", () => {
|
|
|
380
412
|
providerName: "afrihost.co.za",
|
|
381
413
|
asnOrganization: "AFRIHOST SP (PTY) LTD",
|
|
382
414
|
}), allBlocked);
|
|
383
|
-
expect(result).
|
|
415
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
384
416
|
});
|
|
385
417
|
it("still blocks datacenter IPs when providerType is 'hosting'", () => {
|
|
386
418
|
const result = checkTrafficFilter(baseInfo({ isDatacenter: true, providerType: "hosting" }), allBlocked);
|
|
387
|
-
expect(result).
|
|
419
|
+
expect(result).toMatchObject({
|
|
388
420
|
isBlocked: true,
|
|
389
421
|
reason: "API.DATACENTER_BLOCKED",
|
|
390
422
|
});
|
|
391
423
|
});
|
|
392
424
|
it("still blocks datacenter IPs when providerType is missing", () => {
|
|
393
425
|
const result = checkTrafficFilter(baseInfo({ isDatacenter: true }), allBlocked);
|
|
394
|
-
expect(result).
|
|
426
|
+
expect(result).toMatchObject({
|
|
395
427
|
isBlocked: true,
|
|
396
428
|
reason: "API.DATACENTER_BLOCKED",
|
|
397
429
|
});
|
|
@@ -402,7 +434,7 @@ describe("checkTrafficFilter", () => {
|
|
|
402
434
|
isDatacenter: true,
|
|
403
435
|
providerType: "isp",
|
|
404
436
|
}), allBlocked);
|
|
405
|
-
expect(torResult).
|
|
437
|
+
expect(torResult).toMatchObject({
|
|
406
438
|
isBlocked: true,
|
|
407
439
|
reason: "API.TOR_BLOCKED",
|
|
408
440
|
});
|
|
@@ -411,7 +443,7 @@ describe("checkTrafficFilter", () => {
|
|
|
411
443
|
isDatacenter: true,
|
|
412
444
|
providerType: "isp",
|
|
413
445
|
}), allBlocked);
|
|
414
|
-
expect(vpnResult).
|
|
446
|
+
expect(vpnResult).toMatchObject({
|
|
415
447
|
isBlocked: true,
|
|
416
448
|
reason: "API.VPN_BLOCKED",
|
|
417
449
|
});
|
|
@@ -424,7 +456,7 @@ describe("checkTrafficFilter", () => {
|
|
|
424
456
|
providerType: "isp",
|
|
425
457
|
}),
|
|
426
458
|
]);
|
|
427
|
-
expect(result).
|
|
459
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
428
460
|
});
|
|
429
461
|
});
|
|
430
462
|
describe("datacenterNameDenylist", () => {
|
|
@@ -437,7 +469,7 @@ describe("checkTrafficFilter", () => {
|
|
|
437
469
|
...allBlocked,
|
|
438
470
|
datacenterNameDenylist: ["proxy-lease-provider"],
|
|
439
471
|
});
|
|
440
|
-
expect(result).
|
|
472
|
+
expect(result).toMatchObject({
|
|
441
473
|
isBlocked: true,
|
|
442
474
|
reason: "API.DATACENTER_BLOCKED",
|
|
443
475
|
});
|
|
@@ -451,7 +483,7 @@ describe("checkTrafficFilter", () => {
|
|
|
451
483
|
...allBlocked,
|
|
452
484
|
datacenterNameDenylist: ["proxy-lease-provider"],
|
|
453
485
|
});
|
|
454
|
-
expect(result).
|
|
486
|
+
expect(result).toMatchObject({
|
|
455
487
|
isBlocked: true,
|
|
456
488
|
reason: "API.DATACENTER_BLOCKED",
|
|
457
489
|
});
|
|
@@ -465,7 +497,7 @@ describe("checkTrafficFilter", () => {
|
|
|
465
497
|
...allBlocked,
|
|
466
498
|
datacenterNameDenylist: ["proxy-lease-provider"],
|
|
467
499
|
});
|
|
468
|
-
expect(result).
|
|
500
|
+
expect(result).toMatchObject({
|
|
469
501
|
isBlocked: true,
|
|
470
502
|
reason: "API.DATACENTER_BLOCKED",
|
|
471
503
|
});
|
|
@@ -479,7 +511,7 @@ describe("checkTrafficFilter", () => {
|
|
|
479
511
|
...allBlocked,
|
|
480
512
|
datacenterNameDenylist: ["Proxy Lease Ltd"],
|
|
481
513
|
});
|
|
482
|
-
expect(result).
|
|
514
|
+
expect(result).toMatchObject({
|
|
483
515
|
isBlocked: true,
|
|
484
516
|
reason: "API.DATACENTER_BLOCKED",
|
|
485
517
|
});
|
|
@@ -493,7 +525,7 @@ describe("checkTrafficFilter", () => {
|
|
|
493
525
|
datacenterNameAllowlist: ["shared-name"],
|
|
494
526
|
datacenterNameDenylist: ["shared-name"],
|
|
495
527
|
});
|
|
496
|
-
expect(result).
|
|
528
|
+
expect(result).toMatchObject({
|
|
497
529
|
isBlocked: true,
|
|
498
530
|
reason: "API.DATACENTER_BLOCKED",
|
|
499
531
|
});
|
|
@@ -506,7 +538,7 @@ describe("checkTrafficFilter", () => {
|
|
|
506
538
|
...allBlocked,
|
|
507
539
|
datacenterNameDenylist: ["proxy-lease-provider"],
|
|
508
540
|
});
|
|
509
|
-
expect(result).
|
|
541
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
510
542
|
});
|
|
511
543
|
it("does not fire when blockDatacenter is off", () => {
|
|
512
544
|
const result = checkTrafficFilter(baseInfo({
|
|
@@ -515,10 +547,10 @@ describe("checkTrafficFilter", () => {
|
|
|
515
547
|
datacenterName: "proxy-lease-provider",
|
|
516
548
|
}), {
|
|
517
549
|
...allBlocked,
|
|
518
|
-
|
|
550
|
+
datacenter: undefined,
|
|
519
551
|
datacenterNameDenylist: ["proxy-lease-provider"],
|
|
520
552
|
});
|
|
521
|
-
expect(result).
|
|
553
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
522
554
|
});
|
|
523
555
|
it("preserves legacy behaviour when denylist is missing or empty", () => {
|
|
524
556
|
const missing = checkTrafficFilter(baseInfo({
|
|
@@ -526,13 +558,13 @@ describe("checkTrafficFilter", () => {
|
|
|
526
558
|
providerType: "isp",
|
|
527
559
|
datacenterName: "some-isp",
|
|
528
560
|
}), allBlocked);
|
|
529
|
-
expect(missing).
|
|
561
|
+
expect(missing).toMatchObject({ isBlocked: false });
|
|
530
562
|
const empty = checkTrafficFilter(baseInfo({
|
|
531
563
|
isDatacenter: true,
|
|
532
564
|
providerType: "isp",
|
|
533
565
|
datacenterName: "some-isp",
|
|
534
566
|
}), { ...allBlocked, datacenterNameDenylist: [] });
|
|
535
|
-
expect(empty).
|
|
567
|
+
expect(empty).toMatchObject({ isBlocked: false });
|
|
536
568
|
});
|
|
537
569
|
it("still lets earlier category rules fire before the datacenter check", () => {
|
|
538
570
|
const result = checkTrafficFilter(baseInfo({
|
|
@@ -544,7 +576,7 @@ describe("checkTrafficFilter", () => {
|
|
|
544
576
|
...allBlocked,
|
|
545
577
|
datacenterNameDenylist: ["proxy-lease-provider"],
|
|
546
578
|
});
|
|
547
|
-
expect(result).
|
|
579
|
+
expect(result).toMatchObject({
|
|
548
580
|
isBlocked: true,
|
|
549
581
|
reason: "API.TOR_BLOCKED",
|
|
550
582
|
});
|
|
@@ -561,7 +593,7 @@ describe("checkTrafficFilter", () => {
|
|
|
561
593
|
datacenterName: "proxy-lease-provider",
|
|
562
594
|
}),
|
|
563
595
|
]);
|
|
564
|
-
expect(result).
|
|
596
|
+
expect(result).toMatchObject({
|
|
565
597
|
isBlocked: true,
|
|
566
598
|
reason: "API.DATACENTER_BLOCKED",
|
|
567
599
|
});
|
|
@@ -576,7 +608,7 @@ describe("checkTrafficFilter", () => {
|
|
|
576
608
|
asnOrganization: "Cloudflare, Inc.",
|
|
577
609
|
}),
|
|
578
610
|
], true);
|
|
579
|
-
expect(result).
|
|
611
|
+
expect(result).toMatchObject({ isBlocked: false });
|
|
580
612
|
});
|
|
581
613
|
it("still evaluates extras when the setting is off, even if pathValid is true", () => {
|
|
582
614
|
const result = checkTrafficFilter(baseInfo({ ip: "192.0.2.1" }), { ...allBlocked, skipExtrasOnValidDnsPath: false }, [
|
|
@@ -586,7 +618,7 @@ describe("checkTrafficFilter", () => {
|
|
|
586
618
|
asnOrganization: "Cloudflare, Inc.",
|
|
587
619
|
}),
|
|
588
620
|
], true);
|
|
589
|
-
expect(result).
|
|
621
|
+
expect(result).toMatchObject({
|
|
590
622
|
isBlocked: true,
|
|
591
623
|
reason: "API.DATACENTER_BLOCKED",
|
|
592
624
|
});
|
|
@@ -599,7 +631,7 @@ describe("checkTrafficFilter", () => {
|
|
|
599
631
|
asnOrganization: "Cloudflare, Inc.",
|
|
600
632
|
}),
|
|
601
633
|
], false);
|
|
602
|
-
expect(result).
|
|
634
|
+
expect(result).toMatchObject({
|
|
603
635
|
isBlocked: true,
|
|
604
636
|
reason: "API.DATACENTER_BLOCKED",
|
|
605
637
|
});
|
|
@@ -612,7 +644,7 @@ describe("checkTrafficFilter", () => {
|
|
|
612
644
|
asnOrganization: "Cloudflare, Inc.",
|
|
613
645
|
}),
|
|
614
646
|
], undefined);
|
|
615
|
-
expect(result).
|
|
647
|
+
expect(result).toMatchObject({
|
|
616
648
|
isBlocked: true,
|
|
617
649
|
reason: "API.DATACENTER_BLOCKED",
|
|
618
650
|
});
|
|
@@ -622,11 +654,153 @@ describe("checkTrafficFilter", () => {
|
|
|
622
654
|
isDatacenter: true,
|
|
623
655
|
datacenterName: "Amazon AWS",
|
|
624
656
|
}), { ...allBlocked, skipExtrasOnValidDnsPath: true }, [], true);
|
|
625
|
-
expect(result).
|
|
657
|
+
expect(result).toMatchObject({
|
|
626
658
|
isBlocked: true,
|
|
627
659
|
reason: "API.DATACENTER_BLOCKED",
|
|
628
660
|
});
|
|
629
661
|
});
|
|
630
662
|
});
|
|
631
663
|
});
|
|
664
|
+
describe("resolveChallengePolicy", () => {
|
|
665
|
+
const challenge = (category, policy) => ({ category, policy });
|
|
666
|
+
it("returns undefined when there are no challenge matches", () => {
|
|
667
|
+
expect(resolveChallengePolicy([])).toBeUndefined();
|
|
668
|
+
expect(resolveChallengePolicy([
|
|
669
|
+
challenge("vpn", { action: TrafficFilterAction.Block }),
|
|
670
|
+
])).toBeUndefined();
|
|
671
|
+
});
|
|
672
|
+
it("returns the sole challenge policy verbatim when only one matches", () => {
|
|
673
|
+
const resolved = resolveChallengePolicy([
|
|
674
|
+
challenge("vpn", {
|
|
675
|
+
action: TrafficFilterAction.Challenge,
|
|
676
|
+
captchaType: CaptchaType.pow,
|
|
677
|
+
powDifficulty: 7,
|
|
678
|
+
}),
|
|
679
|
+
]);
|
|
680
|
+
expect(resolved).toEqual({
|
|
681
|
+
captchaType: CaptchaType.pow,
|
|
682
|
+
powDifficulty: 7,
|
|
683
|
+
solvedImagesCount: undefined,
|
|
684
|
+
puzzleTolerance: undefined,
|
|
685
|
+
sourceCategories: ["vpn"],
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
it("picks image over puzzle over pow when multiple categories name a captchaType", () => {
|
|
689
|
+
const resolved = resolveChallengePolicy([
|
|
690
|
+
challenge("vpn", {
|
|
691
|
+
action: TrafficFilterAction.Challenge,
|
|
692
|
+
captchaType: CaptchaType.pow,
|
|
693
|
+
}),
|
|
694
|
+
challenge("proxy", {
|
|
695
|
+
action: TrafficFilterAction.Challenge,
|
|
696
|
+
captchaType: CaptchaType.puzzle,
|
|
697
|
+
}),
|
|
698
|
+
challenge("datacenter", {
|
|
699
|
+
action: TrafficFilterAction.Challenge,
|
|
700
|
+
captchaType: CaptchaType.image,
|
|
701
|
+
}),
|
|
702
|
+
]);
|
|
703
|
+
expect(resolved?.captchaType).toBe(CaptchaType.image);
|
|
704
|
+
});
|
|
705
|
+
it("picks puzzle over pow when no image challenge is present", () => {
|
|
706
|
+
const resolved = resolveChallengePolicy([
|
|
707
|
+
challenge("vpn", {
|
|
708
|
+
action: TrafficFilterAction.Challenge,
|
|
709
|
+
captchaType: CaptchaType.pow,
|
|
710
|
+
}),
|
|
711
|
+
challenge("proxy", {
|
|
712
|
+
action: TrafficFilterAction.Challenge,
|
|
713
|
+
captchaType: CaptchaType.puzzle,
|
|
714
|
+
}),
|
|
715
|
+
]);
|
|
716
|
+
expect(resolved?.captchaType).toBe(CaptchaType.puzzle);
|
|
717
|
+
});
|
|
718
|
+
it("takes the highest pow difficulty across challenge matches", () => {
|
|
719
|
+
const resolved = resolveChallengePolicy([
|
|
720
|
+
challenge("vpn", {
|
|
721
|
+
action: TrafficFilterAction.Challenge,
|
|
722
|
+
captchaType: CaptchaType.pow,
|
|
723
|
+
powDifficulty: 4,
|
|
724
|
+
}),
|
|
725
|
+
challenge("proxy", {
|
|
726
|
+
action: TrafficFilterAction.Challenge,
|
|
727
|
+
captchaType: CaptchaType.pow,
|
|
728
|
+
powDifficulty: 9,
|
|
729
|
+
}),
|
|
730
|
+
challenge("datacenter", {
|
|
731
|
+
action: TrafficFilterAction.Challenge,
|
|
732
|
+
captchaType: CaptchaType.pow,
|
|
733
|
+
powDifficulty: 6,
|
|
734
|
+
}),
|
|
735
|
+
]);
|
|
736
|
+
expect(resolved?.powDifficulty).toBe(9);
|
|
737
|
+
});
|
|
738
|
+
it("takes the highest image count across challenge matches", () => {
|
|
739
|
+
const resolved = resolveChallengePolicy([
|
|
740
|
+
challenge("vpn", {
|
|
741
|
+
action: TrafficFilterAction.Challenge,
|
|
742
|
+
captchaType: CaptchaType.image,
|
|
743
|
+
solvedImagesCount: 3,
|
|
744
|
+
}),
|
|
745
|
+
challenge("datacenter", {
|
|
746
|
+
action: TrafficFilterAction.Challenge,
|
|
747
|
+
captchaType: CaptchaType.image,
|
|
748
|
+
solvedImagesCount: 8,
|
|
749
|
+
}),
|
|
750
|
+
]);
|
|
751
|
+
expect(resolved?.solvedImagesCount).toBe(8);
|
|
752
|
+
});
|
|
753
|
+
it("takes the lowest puzzle tolerance across challenge matches (stricter accuracy)", () => {
|
|
754
|
+
const resolved = resolveChallengePolicy([
|
|
755
|
+
challenge("vpn", {
|
|
756
|
+
action: TrafficFilterAction.Challenge,
|
|
757
|
+
captchaType: CaptchaType.puzzle,
|
|
758
|
+
puzzleTolerance: 40,
|
|
759
|
+
}),
|
|
760
|
+
challenge("datacenter", {
|
|
761
|
+
action: TrafficFilterAction.Challenge,
|
|
762
|
+
captchaType: CaptchaType.puzzle,
|
|
763
|
+
puzzleTolerance: 15,
|
|
764
|
+
}),
|
|
765
|
+
]);
|
|
766
|
+
expect(resolved?.puzzleTolerance).toBe(15);
|
|
767
|
+
});
|
|
768
|
+
it("ignores block matches when combining challenge params", () => {
|
|
769
|
+
const resolved = resolveChallengePolicy([
|
|
770
|
+
challenge("vpn", { action: TrafficFilterAction.Block }),
|
|
771
|
+
challenge("proxy", {
|
|
772
|
+
action: TrafficFilterAction.Challenge,
|
|
773
|
+
captchaType: CaptchaType.pow,
|
|
774
|
+
powDifficulty: 5,
|
|
775
|
+
}),
|
|
776
|
+
]);
|
|
777
|
+
expect(resolved?.sourceCategories).toEqual(["proxy"]);
|
|
778
|
+
expect(resolved?.powDifficulty).toBe(5);
|
|
779
|
+
});
|
|
780
|
+
it("leaves fields undefined when no matched policy sets them", () => {
|
|
781
|
+
const resolved = resolveChallengePolicy([
|
|
782
|
+
challenge("vpn", {
|
|
783
|
+
action: TrafficFilterAction.Challenge,
|
|
784
|
+
captchaType: CaptchaType.image,
|
|
785
|
+
}),
|
|
786
|
+
]);
|
|
787
|
+
expect(resolved).toEqual({
|
|
788
|
+
captchaType: CaptchaType.image,
|
|
789
|
+
powDifficulty: undefined,
|
|
790
|
+
solvedImagesCount: undefined,
|
|
791
|
+
puzzleTolerance: undefined,
|
|
792
|
+
sourceCategories: ["vpn"],
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
it("keeps captchaType undefined when no matched policy specifies one (falls through to site default)", () => {
|
|
796
|
+
const resolved = resolveChallengePolicy([
|
|
797
|
+
challenge("vpn", {
|
|
798
|
+
action: TrafficFilterAction.Challenge,
|
|
799
|
+
powDifficulty: 7,
|
|
800
|
+
}),
|
|
801
|
+
]);
|
|
802
|
+
expect(resolved?.captchaType).toBeUndefined();
|
|
803
|
+
expect(resolved?.powDifficulty).toBe(7);
|
|
804
|
+
});
|
|
805
|
+
});
|
|
632
806
|
//# sourceMappingURL=checkTrafficFilter.unit.test.js.map
|