@prosopo/provider 4.15.14 → 4.15.16
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 +106 -106
- package/.turbo/turbo-build$colon$tsc.log +24 -24
- package/.turbo/turbo-build.log +107 -104
- package/CHANGELOG.md +63 -0
- package/dist/_virtual/_rolldown/runtime.js +3 -0
- package/dist/api/admin/apiAdminRoutesProvider.js +27 -46
- package/dist/api/admin/apiClearAllCountersEndpoint.js +62 -57
- package/dist/api/admin/apiDnsEventEndpoint.js +79 -92
- package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.js +43 -45
- package/dist/api/admin/apiGetDecisionMachineEndpoint.js +40 -40
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.js +23 -22
- package/dist/api/admin/apiRegisterSiteKeysEndpoint.js +26 -30
- package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js +35 -37
- package/dist/api/admin/apiRemoveDecisionMachineEndpoint.js +40 -40
- package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +1 -1
- package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js +29 -31
- package/dist/api/admin/apiRemoveSiteKeyEndpoint.js +33 -29
- package/dist/api/admin/apiRemoveSiteKeysEndpoint.js +32 -31
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js +43 -35
- package/dist/api/admin/apiUpdateDecisionMachineEndpoint.js +43 -63
- package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js +36 -35
- package/dist/api/admin/createApiAdminRoutesProvider.js +6 -8
- package/dist/api/blacklistRequestInspector.js +285 -377
- package/dist/api/block.js +17 -30
- package/dist/api/captcha/checkSpamEmail.js +88 -98
- package/dist/api/captcha/contextAwareValidation.js +21 -15
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js +126 -140
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js +11 -12
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +236 -299
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decryptSimdReadings.js +10 -13
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +336 -462
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.js +17 -14
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/sessionDedup.js +27 -27
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js +42 -63
- package/dist/api/captcha/getFrictionlessCaptchaChallenge.js +2 -4
- package/dist/api/captcha/getImageCaptchaChallenge.js +136 -207
- package/dist/api/captcha/getPoWCaptchaChallenge.js +128 -198
- package/dist/api/captcha/getPuzzleCaptchaChallenge.js +132 -201
- package/dist/api/captcha/maintenanceModeResponses.js +38 -47
- package/dist/api/captcha/submitImageCaptchaSolution.js +75 -101
- package/dist/api/captcha/submitPoWCaptchaSolution.js +137 -207
- package/dist/api/captcha/submitPuzzleCaptchaSolution.js +73 -105
- package/dist/api/captcha.js +76 -58
- package/dist/api/dnsEventUrl.js +20 -22
- package/dist/api/domainMiddleware.js +104 -115
- package/dist/api/forwardVerify.js +62 -48
- package/dist/api/handshakeTimingMiddleware.js +43 -62
- package/dist/api/hardBlockVerdictCache.js +114 -117
- package/dist/api/headerCheckMiddleware.js +34 -34
- package/dist/api/ignoreMiddleware.js +13 -15
- package/dist/api/ipInfoMiddleware.js +17 -19
- package/dist/api/ja4.js +149 -188
- package/dist/api/ja4Middleware.js +39 -54
- package/dist/api/metrics.js +245 -257
- package/dist/api/public.js +52 -54
- package/dist/api/robotsMiddleware.js +10 -10
- package/dist/api/startProviderApi.js +205 -232
- package/dist/api/testSiteKey.js +16 -16
- package/dist/api/validateAddress.js +23 -21
- package/dist/api/verify.js +334 -377
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/cjs/api/admin/apiAdminRoutesProvider.cjs +40 -59
- package/dist/cjs/api/admin/apiClearAllCountersEndpoint.cjs +63 -58
- package/dist/cjs/api/admin/apiDnsEventEndpoint.cjs +82 -93
- package/dist/cjs/api/admin/apiGetAllDecisionMachinesEndpoint.cjs +46 -48
- package/dist/cjs/api/admin/apiGetDecisionMachineEndpoint.cjs +41 -41
- package/dist/cjs/api/admin/apiRegisterSiteKeyEndpoint.cjs +25 -24
- package/dist/cjs/api/admin/apiRegisterSiteKeysEndpoint.cjs +28 -32
- package/dist/cjs/api/admin/apiRemoveAllDecisionMachinesEndpoint.cjs +38 -40
- package/dist/cjs/api/admin/apiRemoveDecisionMachineEndpoint.cjs +41 -41
- package/dist/cjs/api/admin/apiRemoveDetectorKeyEndpoint.cjs +31 -33
- package/dist/cjs/api/admin/apiRemoveSiteKeyEndpoint.cjs +35 -31
- package/dist/cjs/api/admin/apiRemoveSiteKeysEndpoint.cjs +34 -33
- package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +45 -35
- package/dist/cjs/api/admin/apiUpdateDecisionMachineEndpoint.cjs +45 -65
- package/dist/cjs/api/admin/apiUpdateDetectorKeyEndpoint.cjs +38 -37
- package/dist/cjs/api/admin/createApiAdminRoutesProvider.cjs +7 -8
- package/dist/cjs/api/blacklistRequestInspector.cjs +288 -376
- package/dist/cjs/api/block.cjs +18 -30
- package/dist/cjs/api/captcha/checkSpamEmail.cjs +90 -100
- package/dist/cjs/api/captcha/contextAwareValidation.cjs +21 -14
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs +125 -140
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/constants.cjs +10 -10
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +238 -301
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decryptSimdReadings.cjs +9 -12
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +349 -473
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.cjs +18 -14
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/sessionDedup.cjs +26 -26
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs +42 -63
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge.cjs +2 -3
- package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +138 -208
- package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +131 -200
- package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +135 -203
- package/dist/cjs/api/captcha/maintenanceModeResponses.cjs +38 -44
- package/dist/cjs/api/captcha/submitImageCaptchaSolution.cjs +77 -102
- package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +140 -209
- package/dist/cjs/api/captcha/submitPuzzleCaptchaSolution.cjs +76 -107
- package/dist/cjs/api/captcha.cjs +79 -58
- package/dist/cjs/api/dnsEventUrl.cjs +20 -21
- package/dist/cjs/api/domainMiddleware.cjs +106 -117
- package/dist/cjs/api/forwardVerify.cjs +63 -49
- package/dist/cjs/api/handshakeTimingMiddleware.cjs +43 -61
- package/dist/cjs/api/hardBlockVerdictCache.cjs +114 -114
- package/dist/cjs/api/headerCheckMiddleware.cjs +34 -34
- package/dist/cjs/api/ignoreMiddleware.cjs +12 -14
- package/dist/cjs/api/ipInfoMiddleware.cjs +16 -18
- package/dist/cjs/api/ja4.cjs +149 -187
- package/dist/cjs/api/ja4Middleware.cjs +40 -53
- package/dist/cjs/api/metrics.cjs +229 -228
- package/dist/cjs/api/public.cjs +57 -57
- package/dist/cjs/api/robotsMiddleware.cjs +9 -9
- package/dist/cjs/api/startProviderApi.cjs +219 -237
- package/dist/cjs/api/testSiteKey.cjs +15 -14
- package/dist/cjs/api/validateAddress.cjs +24 -21
- package/dist/cjs/api/verify.cjs +338 -379
- package/dist/cjs/compositeIpAddress.cjs +40 -47
- package/dist/cjs/index.cjs +65 -71
- package/dist/cjs/pairs.cjs +31 -35
- package/dist/cjs/rules/lang.cjs +10 -14
- package/dist/cjs/schedulers/captchaScheduler.cjs +26 -32
- package/dist/cjs/schedulers/getClientList.cjs +35 -33
- package/dist/cjs/schedulers/setClientEntropy.cjs +35 -33
- package/dist/cjs/schedulers/updateSpamEmailDomains.cjs +39 -43
- package/dist/cjs/services/ipComparison.cjs +122 -119
- package/dist/cjs/tasks/captchaManager.cjs +407 -486
- package/dist/cjs/tasks/client/clientTasks.cjs +347 -470
- package/dist/cjs/tasks/dataset/datasetTasks.cjs +25 -29
- package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +16 -32
- package/dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs +220 -307
- package/dist/cjs/tasks/detection/decodeBehavior.cjs +408 -317
- package/dist/cjs/tasks/detection/decodePayload.cjs +686 -468
- package/dist/cjs/tasks/detection/decodeSimd.cjs +462 -304
- package/dist/cjs/tasks/detection/getBotScore.cjs +37 -43
- package/dist/cjs/tasks/dnsEvent/enrichDnsEvent.cjs +88 -71
- package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +348 -486
- package/dist/cjs/tasks/frictionless/frictionlessTasksUtils.cjs +13 -30
- package/dist/cjs/tasks/frictionless/routingMachine.cjs +71 -55
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +555 -806
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +22 -23
- package/dist/cjs/tasks/index.cjs +2 -4
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +491 -687
- package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +17 -29
- package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +422 -591
- package/dist/cjs/tasks/puzzleCaptcha/puzzleTasksUtils.cjs +8 -5
- package/dist/cjs/tasks/spam/checkSpamEmail.cjs +133 -141
- package/dist/cjs/tasks/spam/checkTrafficFilter.cjs +118 -76
- package/dist/cjs/tasks/spam/evaluateEmailSpamRules.cjs +75 -84
- package/dist/cjs/tasks/spam/updateSpamEmailDomains.cjs +40 -56
- package/dist/cjs/tasks/tasks.cjs +107 -158
- package/dist/cjs/util/usageCounters.cjs +220 -211
- package/dist/cjs/util.cjs +329 -359
- package/dist/cjs/utils/devicePlatform.cjs +14 -8
- package/dist/cjs/utils/dns.cjs +68 -93
- package/dist/cjs/utils/hashUserAgent.cjs +14 -7
- package/dist/cjs/utils/hashUserIp.cjs +14 -6
- package/dist/cjs/utils/honeypot/encoders.cjs +74 -80
- package/dist/cjs/utils/honeypot/phraseBank.cjs +51 -44
- package/dist/cjs/utils/normalizeRequestIp.cjs +33 -25
- package/dist/compositeIpAddress.js +38 -46
- package/dist/index.js +12 -56
- package/dist/pairs.js +31 -37
- package/dist/rules/lang.js +11 -15
- package/dist/schedulers/captchaScheduler.js +25 -31
- package/dist/schedulers/getClientList.js +34 -32
- package/dist/schedulers/setClientEntropy.js +34 -32
- package/dist/schedulers/updateSpamEmailDomains.js +38 -42
- package/dist/services/ipComparison.js +122 -119
- package/dist/tasks/captchaManager.js +403 -483
- package/dist/tasks/client/clientTasks.js +343 -467
- package/dist/tasks/dataset/datasetTasks.js +24 -28
- package/dist/tasks/dataset/datasetTasksUtils.js +15 -31
- package/dist/tasks/decisionMachine/decisionMachineRunner.js +217 -306
- package/dist/tasks/detection/getBotScore.js +37 -43
- package/dist/tasks/dnsEvent/enrichDnsEvent.d.ts.map +1 -1
- package/dist/tasks/dnsEvent/enrichDnsEvent.js +88 -74
- package/dist/tasks/dnsEvent/enrichDnsEvent.js.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.js +342 -479
- package/dist/tasks/frictionless/frictionlessTasksUtils.js +14 -32
- package/dist/tasks/frictionless/routingMachine.js +72 -56
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +550 -801
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +21 -22
- package/dist/tasks/index.js +1 -3
- package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
- package/dist/tasks/powCaptcha/powTasks.js +486 -682
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
- package/dist/tasks/powCaptcha/powTasksUtils.js +15 -28
- package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js +417 -586
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasksUtils.js +9 -6
- package/dist/tasks/spam/checkSpamEmail.js +133 -141
- package/dist/tasks/spam/checkTrafficFilter.d.ts +1 -0
- package/dist/tasks/spam/checkTrafficFilter.d.ts.map +1 -1
- package/dist/tasks/spam/checkTrafficFilter.js +117 -77
- package/dist/tasks/spam/checkTrafficFilter.js.map +1 -1
- package/dist/tasks/spam/evaluateEmailSpamRules.js +75 -86
- package/dist/tasks/spam/updateSpamEmailDomains.js +36 -54
- package/dist/tasks/tasks.js +98 -150
- package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js +4 -1
- package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js.map +1 -1
- package/dist/tests/unit/api/block.unit.test.js +8 -4
- package/dist/tests/unit/api/block.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js +8 -6
- package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js.map +1 -1
- package/dist/tests/unit/api/forwardVerify.unit.test.js +3 -1
- package/dist/tests/unit/api/forwardVerify.unit.test.js.map +1 -1
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +15 -7
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +24 -18
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +1 -1
- package/dist/tests/unit/schedulers/getClientList.unit.test.js +19 -13
- package/dist/tests/unit/schedulers/getClientList.unit.test.js.map +1 -1
- package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js +19 -13
- package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +22 -16
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js +140 -0
- package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js.map +1 -1
- package/dist/tests/unit/testUtils/mockProviderEnv.d.ts +7 -7
- package/dist/util/usageCounters.js +220 -212
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +327 -364
- package/dist/util.js.map +1 -1
- package/dist/utils/devicePlatform.js +15 -9
- package/dist/utils/dns.js +64 -77
- package/dist/utils/hashUserAgent.js +14 -7
- package/dist/utils/hashUserIp.js +14 -6
- package/dist/utils/honeypot/encoders.js +74 -80
- package/dist/utils/honeypot/phraseBank.js +49 -44
- package/dist/utils/normalizeRequestIp.js +34 -26
- package/package.json +24 -24
|
@@ -1,391 +1,303 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// trusted from a client hint. Present unconditionally so an OS
|
|
22
|
-
// allow-list (block everything not on the list) still matches requests
|
|
23
|
-
// whose UA we can't classify.
|
|
24
|
-
os: userAccessPolicy.classifyOs(userAgent)
|
|
25
|
-
};
|
|
1
|
+
const require_compositeIpAddress = require("../compositeIpAddress.cjs");
|
|
2
|
+
const require_hardBlockVerdictCache = require("./hardBlockVerdictCache.cjs");
|
|
3
|
+
const require_metrics = require("./metrics.cjs");
|
|
4
|
+
let _prosopo_types = require("@prosopo/types");
|
|
5
|
+
let node_crypto = require("node:crypto");
|
|
6
|
+
let _prosopo_user_access_policy = require("@prosopo/user-access-policy");
|
|
7
|
+
//#region src/api/blacklistRequestInspector.ts
|
|
8
|
+
var getRequestUserScope = (requestHeaders, ja4, ip, user, headHash, coords, countryCode, asn) => {
|
|
9
|
+
const userAgent = requestHeaders["user-agent"] ? requestHeaders["user-agent"].toString() : void 0;
|
|
10
|
+
return {
|
|
11
|
+
...user && { userId: user },
|
|
12
|
+
...ja4 && { ja4Hash: ja4 },
|
|
13
|
+
...userAgent && { userAgent },
|
|
14
|
+
...ip && { ip },
|
|
15
|
+
...headHash && { headHash },
|
|
16
|
+
...coords && { coords },
|
|
17
|
+
...countryCode && { countryCode },
|
|
18
|
+
...typeof asn === "number" && { asn },
|
|
19
|
+
os: (0, _prosopo_user_access_policy.classifyOs)(userAgent)
|
|
20
|
+
};
|
|
26
21
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
22
|
+
var SCALAR_USER_SCOPE_FIELDS = [
|
|
23
|
+
"userId",
|
|
24
|
+
"ja4Hash",
|
|
25
|
+
"headersHash",
|
|
26
|
+
"userAgentHash",
|
|
27
|
+
"headHash",
|
|
28
|
+
"coords",
|
|
29
|
+
"countryCode",
|
|
30
|
+
"asn",
|
|
31
|
+
"os"
|
|
37
32
|
];
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
if (rule.numericIp !== void 0) {
|
|
46
|
-
fields.push("ip");
|
|
47
|
-
} else if (rule.numericIpMaskMin !== void 0 && rule.numericIpMaskMax !== void 0) {
|
|
48
|
-
fields.push("ipMask");
|
|
49
|
-
}
|
|
50
|
-
return fields;
|
|
33
|
+
var deriveRuleType = (rule) => {
|
|
34
|
+
const fields = [];
|
|
35
|
+
for (const f of SCALAR_USER_SCOPE_FIELDS) if (rule[f] !== void 0) fields.push(f);
|
|
36
|
+
if (rule.numericIp !== void 0) fields.push("ip");
|
|
37
|
+
else if (rule.numericIpMaskMin !== void 0 && rule.numericIpMaskMax !== void 0) fields.push("ipMask");
|
|
38
|
+
return fields;
|
|
51
39
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
} else if (Array.isArray(v)) {
|
|
58
|
-
out[k] = v.map((x) => String(x)).join(", ");
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return out;
|
|
40
|
+
var sanitizeRequestHeaders = (headers) => {
|
|
41
|
+
const out = {};
|
|
42
|
+
for (const [k, v] of Object.entries(headers)) if (typeof v === "string") out[k] = v;
|
|
43
|
+
else if (Array.isArray(v)) out[k] = v.map((x) => String(x)).join(", ");
|
|
44
|
+
return out;
|
|
62
45
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
if (rule.numericIp !== void 0) {
|
|
72
|
-
return requestIp === rule.numericIp;
|
|
73
|
-
}
|
|
74
|
-
return requestIp >= rule.numericIpMaskMin && requestIp <= rule.numericIpMaskMax;
|
|
46
|
+
var ruleHasIpConstraint = (rule) => rule.numericIp !== void 0 || rule.numericIpMaskMin !== void 0 && rule.numericIpMaskMax !== void 0;
|
|
47
|
+
var ruleIpMatchesRequest = (rule, requestIp) => {
|
|
48
|
+
if (!ruleHasIpConstraint(rule)) return true;
|
|
49
|
+
if (requestIp === void 0) return false;
|
|
50
|
+
if (rule.numericIp !== void 0) return requestIp === rule.numericIp;
|
|
51
|
+
return requestIp >= rule.numericIpMaskMin && requestIp <= rule.numericIpMaskMax;
|
|
75
52
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
if (ruleValue !== request[field]) {
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return ruleIpMatchesRequest(rule, request.numericIp);
|
|
53
|
+
var ruleApplies = (rule, request, requestClientId) => {
|
|
54
|
+
if (rule.clientId !== void 0 && rule.clientId !== requestClientId) return false;
|
|
55
|
+
for (const field of SCALAR_USER_SCOPE_FIELDS) {
|
|
56
|
+
const ruleValue = rule[field];
|
|
57
|
+
if (ruleValue === void 0) continue;
|
|
58
|
+
if (ruleValue !== request[field]) return false;
|
|
59
|
+
}
|
|
60
|
+
return ruleIpMatchesRequest(rule, request.numericIp);
|
|
90
61
|
};
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (rule[field] !== void 0) {
|
|
98
|
-
score += 1;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (ruleHasIpConstraint(rule)) {
|
|
102
|
-
score += 1;
|
|
103
|
-
}
|
|
104
|
-
return score;
|
|
62
|
+
var ruleSpecificity = (rule, requestClientId) => {
|
|
63
|
+
let score = 0;
|
|
64
|
+
if (rule.clientId !== void 0 && rule.clientId === requestClientId) score += 1;
|
|
65
|
+
for (const field of SCALAR_USER_SCOPE_FIELDS) if (rule[field] !== void 0) score += 1;
|
|
66
|
+
if (ruleHasIpConstraint(rule)) score += 1;
|
|
67
|
+
return score;
|
|
105
68
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// so the Record is total over CaptchaType — keeps the type-checker honest
|
|
112
|
-
// if the enum grows. Restrict-with-frictionless wouldn't make operational
|
|
113
|
-
// sense and ranks at the bottom of the captcha tiers if it ever appears.
|
|
114
|
-
[types.CaptchaType.frictionless]: 0
|
|
69
|
+
var CAPTCHA_TYPE_HARSHNESS = {
|
|
70
|
+
[_prosopo_types.CaptchaType.image]: 30,
|
|
71
|
+
[_prosopo_types.CaptchaType.puzzle]: 20,
|
|
72
|
+
[_prosopo_types.CaptchaType.pow]: 10,
|
|
73
|
+
[_prosopo_types.CaptchaType.frictionless]: 0
|
|
115
74
|
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (rule.captchaType === void 0) {
|
|
121
|
-
return 0;
|
|
122
|
-
}
|
|
123
|
-
const base = CAPTCHA_TYPE_HARSHNESS[rule.captchaType];
|
|
124
|
-
const rounds = rule.solvedImagesCount ?? 0;
|
|
125
|
-
return base + rounds;
|
|
75
|
+
var ruleHarshness = (rule) => {
|
|
76
|
+
if (rule.type === _prosopo_user_access_policy.AccessPolicyType.Block) return Number.MAX_SAFE_INTEGER;
|
|
77
|
+
if (rule.captchaType === void 0) return 0;
|
|
78
|
+
return CAPTCHA_TYPE_HARSHNESS[rule.captchaType] + (rule.solvedImagesCount ?? 0);
|
|
126
79
|
};
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Rank the candidate rules a single Redis query returned. A rule "applies" iff
|
|
82
|
+
* every populated field on the rule equals the corresponding request field
|
|
83
|
+
* (IP fields use range semantics).
|
|
84
|
+
*
|
|
85
|
+
* Ordering: specificity DESC primary, harshness DESC as the equal-specificity
|
|
86
|
+
* tiebreaker (issue #3713). The most specific applicable rule wins; on tie,
|
|
87
|
+
* the harshest matching rule wins — Block > Restrict[image, rounds DESC] >
|
|
88
|
+
* Restrict[puzzle] > Restrict[pow]. Client-scoped rules outrank global rules
|
|
89
|
+
* of equal user-scope specificity.
|
|
90
|
+
*/
|
|
91
|
+
var rankCandidateRules = (rules, request, requestClientId) => rules.filter((rule) => ruleApplies(rule, request, requestClientId)).sort((a, b) => {
|
|
92
|
+
const specDelta = ruleSpecificity(b, requestClientId) - ruleSpecificity(a, requestClientId);
|
|
93
|
+
if (specDelta !== 0) return specDelta;
|
|
94
|
+
return ruleHarshness(b) - ruleHarshness(a);
|
|
133
95
|
});
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Fetch the access rules that apply to a request, most specific first.
|
|
98
|
+
*
|
|
99
|
+
* Evolution of this lookup:
|
|
100
|
+
*
|
|
101
|
+
* - Original: 2 × (2^n − 1) `FT.SEARCH` round trips, one per non-empty
|
|
102
|
+
* subset of the populated user-scope fields × {clientId, undefined}.
|
|
103
|
+
* n=6 fields ⇒ 126 RTTs per request.
|
|
104
|
+
* - #2657 (greedy): one OR-of-fields `FT.SEARCH`, JS-side rank picks
|
|
105
|
+
* the most-specific. 1 RTT but pulled hundreds of irrelevant hashes
|
|
106
|
+
* every request.
|
|
107
|
+
* - #2689 / 3.6.38: greedy + FT.AGGREGATE+CURSOR to defeat the silent
|
|
108
|
+
* 1000-cap truncation. Tipped CPU into 125% peg in production.
|
|
109
|
+
* - 3.6.38.1 hotfix: reverted to greedy + FT.SEARCH (this file's old
|
|
110
|
+
* shape with the truncation bug back).
|
|
111
|
+
* - Now (this fix): strict-match query so every returned candidate
|
|
112
|
+
* actually applies, with specificity ranked server-side via
|
|
113
|
+
* FT.AGGREGATE+APPLY+SORTBY+LIMIT in the storage layer. Node receives
|
|
114
|
+
* at most 20 already-ranked rules — no JS sort needed for
|
|
115
|
+
* correctness, but `rankCandidateRules` is kept as defence so any
|
|
116
|
+
* mismatch between the Redis-side score and the JS semantics surfaces
|
|
117
|
+
* as ordering rather than letting traffic through.
|
|
118
|
+
*/
|
|
119
|
+
var verdictCache = new require_hardBlockVerdictCache.HardBlockVerdictCache();
|
|
120
|
+
var getVerdictCache = () => verdictCache;
|
|
121
|
+
var REQUEST_MEMO_SYMBOL = Symbol.for("prosopo.accessRuleRequestMemo");
|
|
122
|
+
var getOrCreateRequestMemo = (requestMemoHost) => {
|
|
123
|
+
let memo = requestMemoHost[REQUEST_MEMO_SYMBOL];
|
|
124
|
+
if (memo === void 0) {
|
|
125
|
+
memo = /* @__PURE__ */ new Map();
|
|
126
|
+
requestMemoHost[REQUEST_MEMO_SYMBOL] = memo;
|
|
127
|
+
}
|
|
128
|
+
return memo;
|
|
144
129
|
};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
filter,
|
|
172
|
-
true,
|
|
173
|
-
// matchingFieldsOnly — engages the split-query hot path
|
|
174
|
-
true
|
|
175
|
-
);
|
|
176
|
-
return rankCandidateRules(candidates, parsedUserScope, clientId);
|
|
177
|
-
};
|
|
178
|
-
let ranked;
|
|
179
|
-
if (skipCache) {
|
|
180
|
-
ranked = await compute();
|
|
181
|
-
} else {
|
|
182
|
-
ranked = await verdictCache.getOrCompute(cacheKey, compute);
|
|
183
|
-
}
|
|
184
|
-
requestMemo?.set(cacheKey, ranked);
|
|
185
|
-
return ranked;
|
|
130
|
+
var getPrioritisedAccessRule = async (userAccessRulesStorage, userScope, clientId, options) => {
|
|
131
|
+
const parsedUserScope = _prosopo_user_access_policy.userScopeInput.parse(userScope);
|
|
132
|
+
const blockOnly = options?.blockOnly ?? false;
|
|
133
|
+
const skipCache = options?.skipCache ?? false;
|
|
134
|
+
const requestMemoHost = options?.requestMemoHost;
|
|
135
|
+
const cacheKey = require_hardBlockVerdictCache.hardBlockCacheKey(clientId, parsedUserScope, blockOnly);
|
|
136
|
+
const requestMemo = requestMemoHost ? getOrCreateRequestMemo(requestMemoHost) : void 0;
|
|
137
|
+
if (requestMemo !== void 0) {
|
|
138
|
+
const memoHit = requestMemo.get(cacheKey);
|
|
139
|
+
if (memoHit !== void 0) return memoHit;
|
|
140
|
+
}
|
|
141
|
+
const filter = {
|
|
142
|
+
...clientId && { policyScope: { clientId } },
|
|
143
|
+
policyScopeMatch: _prosopo_user_access_policy.FilterScopeMatch.Greedy,
|
|
144
|
+
userScope: parsedUserScope,
|
|
145
|
+
userScopeMatch: _prosopo_user_access_policy.FilterScopeMatch.Greedy,
|
|
146
|
+
...blockOnly && { blockOnly: true }
|
|
147
|
+
};
|
|
148
|
+
const compute = async () => {
|
|
149
|
+
return rankCandidateRules(await userAccessRulesStorage.findRules(filter, true, true), parsedUserScope, clientId);
|
|
150
|
+
};
|
|
151
|
+
let ranked;
|
|
152
|
+
if (skipCache) ranked = await compute();
|
|
153
|
+
else ranked = await verdictCache.getOrCompute(cacheKey, compute);
|
|
154
|
+
requestMemo?.set(cacheKey, ranked);
|
|
155
|
+
return ranked;
|
|
186
156
|
};
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
}));
|
|
333
|
-
if (!this.db) {
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
const ipAddress = ctx.rawIp ? compositeIpAddress.getCompositeIpAddress(ctx.rawIp) : void 0;
|
|
337
|
-
if (!ipAddress) {
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
const headers = sanitizeRequestHeaders(ctx.requestHeaders);
|
|
341
|
-
const session = {
|
|
342
|
-
sessionId: `blocked-${node_crypto.randomUUID()}`,
|
|
343
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
344
|
-
// Sentinel values for schema-required fields the blocked request
|
|
345
|
-
// never reached the point of populating.
|
|
346
|
-
token: "",
|
|
347
|
-
score: 1,
|
|
348
|
-
threshold: 0,
|
|
349
|
-
scoreComponents: { baseScore: 1 },
|
|
350
|
-
captchaType: types.CaptchaType.frictionless,
|
|
351
|
-
webView: false,
|
|
352
|
-
iFrame: false,
|
|
353
|
-
decryptedHeadHash: "",
|
|
354
|
-
// Real data the inspector did collect.
|
|
355
|
-
siteKey: ctx.clientId,
|
|
356
|
-
ipAddress,
|
|
357
|
-
ipInfo: ctx.ipInfo,
|
|
358
|
-
headers,
|
|
359
|
-
reason: types.FrictionlessReason.ACCESS_POLICY_BLOCK,
|
|
360
|
-
result: {
|
|
361
|
-
status: types.CaptchaStatus.disapproved,
|
|
362
|
-
reason: types.ResultReason.ACCESS_POLICY_BLOCK
|
|
363
|
-
},
|
|
364
|
-
// Rule identity — the whole point of writing this record.
|
|
365
|
-
ruleHash,
|
|
366
|
-
ruleType,
|
|
367
|
-
ruleDescription
|
|
368
|
-
// blocked + deleted are stamped inside storeBlockedSession so
|
|
369
|
-
// the synthetic record is unmistakably a block-middleware
|
|
370
|
-
// artefact and can never be picked up by the captcha flow.
|
|
371
|
-
};
|
|
372
|
-
void this.db.storeBlockedSession(session);
|
|
373
|
-
}
|
|
374
|
-
isApiUnrelatedRoute(url) {
|
|
375
|
-
return !url.includes(types.ApiPrefix);
|
|
376
|
-
}
|
|
377
|
-
extractIdsFromRequest(requestHeaders, requestBody) {
|
|
378
|
-
const userId = this.getObjectValue(requestHeaders, "Prosopo-User") || this.getObjectValue(requestBody, "user");
|
|
379
|
-
const clientId = this.getObjectValue(requestHeaders, "Prosopo-Site-Key") || this.getObjectValue(requestBody, "dapp");
|
|
380
|
-
return {
|
|
381
|
-
userId: "string" === typeof userId ? userId : void 0,
|
|
382
|
-
clientId: "string" === typeof clientId ? clientId : void 0
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
getObjectValue(object, key) {
|
|
386
|
-
return object[key];
|
|
387
|
-
}
|
|
388
|
-
}
|
|
157
|
+
var BlacklistRequestInspector = class {
|
|
158
|
+
constructor(userAccessRulesStorage, environmentReadinessWaiter, db) {
|
|
159
|
+
this.userAccessRulesStorage = userAccessRulesStorage;
|
|
160
|
+
this.environmentReadinessWaiter = environmentReadinessWaiter;
|
|
161
|
+
this.db = db;
|
|
162
|
+
}
|
|
163
|
+
async abortRequestForBlockedUsers(request, res, next) {
|
|
164
|
+
const rawIp = request.ip || "";
|
|
165
|
+
request.logger.debug(() => ({ data: { ja4: request.ja4 } }));
|
|
166
|
+
if (await this.shouldAbortRequest(request.url, rawIp, request.ja4, request.headers, request.body, request.logger, request.ipInfo, request)) {
|
|
167
|
+
res.status(403).json({ error: "Forbidden" });
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
next();
|
|
171
|
+
}
|
|
172
|
+
async shouldAbortRequest(requestedRoute, rawIp, ja4, requestHeaders, requestBody, logger, ipInfo, requestMemoHost) {
|
|
173
|
+
if (this.isApiUnrelatedRoute(requestedRoute)) return false;
|
|
174
|
+
if (!rawIp) {
|
|
175
|
+
logger.info(() => ({
|
|
176
|
+
data: {
|
|
177
|
+
requestedRoute,
|
|
178
|
+
requestHeaders,
|
|
179
|
+
requestBody
|
|
180
|
+
},
|
|
181
|
+
msg: "Request without IP"
|
|
182
|
+
}));
|
|
183
|
+
require_metrics.recordBlockedRequest("no_ip");
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
await this.environmentReadinessWaiter();
|
|
187
|
+
try {
|
|
188
|
+
const { userId, clientId } = this.extractIdsFromRequest(requestHeaders, requestBody);
|
|
189
|
+
const countryCode = ipInfo?.isValid ? ipInfo.countryCode : void 0;
|
|
190
|
+
const asn = ipInfo?.isValid ? ipInfo.asnNumber : void 0;
|
|
191
|
+
const enforceable = (await getPrioritisedAccessRule(this.userAccessRulesStorage, getRequestUserScope(requestHeaders, ja4, rawIp, userId, void 0, void 0, countryCode, asn), clientId, {
|
|
192
|
+
blockOnly: true,
|
|
193
|
+
requestMemoHost
|
|
194
|
+
}) ?? []).filter((p) => !p.deferToVerify);
|
|
195
|
+
if (enforceable.length === 0 || !enforceable[0]) return false;
|
|
196
|
+
const accessPolicy = enforceable[0];
|
|
197
|
+
const isBlock = _prosopo_user_access_policy.AccessPolicyType.Block === accessPolicy.type;
|
|
198
|
+
if (isBlock) {
|
|
199
|
+
require_metrics.recordBlockedRequest("access_policy");
|
|
200
|
+
this.recordBlockDecision(accessPolicy, {
|
|
201
|
+
userId,
|
|
202
|
+
clientId,
|
|
203
|
+
rawIp,
|
|
204
|
+
ja4,
|
|
205
|
+
requestHeaders,
|
|
206
|
+
ipInfo,
|
|
207
|
+
countryCode,
|
|
208
|
+
asn
|
|
209
|
+
}, logger);
|
|
210
|
+
}
|
|
211
|
+
return isBlock;
|
|
212
|
+
} catch (err) {
|
|
213
|
+
logger.error(() => ({
|
|
214
|
+
err,
|
|
215
|
+
msg: "Block Middleware Error"
|
|
216
|
+
}));
|
|
217
|
+
require_metrics.recordBlockedRequest("error");
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Emit a structured log line and (if a DB is wired) persist a synthetic
|
|
223
|
+
* Session record for the request we're about to block (403). Fire-and-forget on
|
|
224
|
+
* the Mongo side — the structured log line is the source of truth and
|
|
225
|
+
* the 403 response is never delayed by a persistence failure.
|
|
226
|
+
*
|
|
227
|
+
* Carries the matched rule's identity (hash + ruleType + description)
|
|
228
|
+
* so the Traffic page can surface "what's blocking traffic for this
|
|
229
|
+
* site" without re-reading the rules collection.
|
|
230
|
+
*/
|
|
231
|
+
recordBlockDecision(accessPolicy, ctx, logger) {
|
|
232
|
+
const ruleHash = (0, _prosopo_user_access_policy.makeAccessRuleHash)(accessPolicy);
|
|
233
|
+
const ruleType = deriveRuleType(accessPolicy);
|
|
234
|
+
const ruleDescription = accessPolicy.description;
|
|
235
|
+
const userAgent = typeof ctx.requestHeaders["user-agent"] === "string" ? ctx.requestHeaders["user-agent"] : void 0;
|
|
236
|
+
logger.info(() => ({
|
|
237
|
+
msg: "Access policy block",
|
|
238
|
+
data: {
|
|
239
|
+
ruleHash,
|
|
240
|
+
ruleType,
|
|
241
|
+
ruleDescription,
|
|
242
|
+
policyType: accessPolicy.type,
|
|
243
|
+
clientId: ctx.clientId,
|
|
244
|
+
userScope: {
|
|
245
|
+
userId: ctx.userId,
|
|
246
|
+
ja4: ctx.ja4,
|
|
247
|
+
ip: ctx.rawIp,
|
|
248
|
+
userAgent,
|
|
249
|
+
countryCode: ctx.countryCode,
|
|
250
|
+
asn: ctx.asn,
|
|
251
|
+
os: (0, _prosopo_user_access_policy.classifyOs)(userAgent)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}));
|
|
255
|
+
if (!this.db) return;
|
|
256
|
+
const ipAddress = ctx.rawIp ? require_compositeIpAddress.getCompositeIpAddress(ctx.rawIp) : void 0;
|
|
257
|
+
if (!ipAddress) return;
|
|
258
|
+
const headers = sanitizeRequestHeaders(ctx.requestHeaders);
|
|
259
|
+
const session = {
|
|
260
|
+
sessionId: `blocked-${(0, node_crypto.randomUUID)()}`,
|
|
261
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
262
|
+
token: "",
|
|
263
|
+
score: 1,
|
|
264
|
+
threshold: 0,
|
|
265
|
+
scoreComponents: { baseScore: 1 },
|
|
266
|
+
captchaType: _prosopo_types.CaptchaType.frictionless,
|
|
267
|
+
webView: false,
|
|
268
|
+
iFrame: false,
|
|
269
|
+
decryptedHeadHash: "",
|
|
270
|
+
siteKey: ctx.clientId,
|
|
271
|
+
ipAddress,
|
|
272
|
+
ipInfo: ctx.ipInfo,
|
|
273
|
+
headers,
|
|
274
|
+
reason: _prosopo_types.FrictionlessReason.ACCESS_POLICY_BLOCK,
|
|
275
|
+
result: {
|
|
276
|
+
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
277
|
+
reason: _prosopo_types.ResultReason.ACCESS_POLICY_BLOCK
|
|
278
|
+
},
|
|
279
|
+
ruleHash,
|
|
280
|
+
ruleType,
|
|
281
|
+
ruleDescription
|
|
282
|
+
};
|
|
283
|
+
this.db.storeBlockedSession(session);
|
|
284
|
+
}
|
|
285
|
+
isApiUnrelatedRoute(url) {
|
|
286
|
+
return !url.includes(_prosopo_types.ApiPrefix);
|
|
287
|
+
}
|
|
288
|
+
extractIdsFromRequest(requestHeaders, requestBody) {
|
|
289
|
+
const userId = this.getObjectValue(requestHeaders, "Prosopo-User") || this.getObjectValue(requestBody, "user");
|
|
290
|
+
const clientId = this.getObjectValue(requestHeaders, "Prosopo-Site-Key") || this.getObjectValue(requestBody, "dapp");
|
|
291
|
+
return {
|
|
292
|
+
userId: "string" === typeof userId ? userId : void 0,
|
|
293
|
+
clientId: "string" === typeof clientId ? clientId : void 0
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
getObjectValue(object, key) {
|
|
297
|
+
return object[key];
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
//#endregion
|
|
389
301
|
exports.BlacklistRequestInspector = BlacklistRequestInspector;
|
|
390
302
|
exports.getPrioritisedAccessRule = getPrioritisedAccessRule;
|
|
391
303
|
exports.getRequestUserScope = getRequestUserScope;
|