@prosopo/provider 4.15.13 → 4.15.15
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 +78 -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/powCaptcha/powTasks.unit.test.js +6 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js +60 -1
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.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
package/dist/util.js
CHANGED
|
@@ -1,378 +1,341 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isHex } from "@polkadot/util/is";
|
|
1
|
+
import { compareIPs } from "./services/ipComparison.js";
|
|
3
2
|
import { ProsopoContractError, ProsopoEnvError } from "@prosopo/common";
|
|
4
|
-
import {
|
|
3
|
+
import { IPValidationAction, ScheduledTaskStatus } from "@prosopo/types";
|
|
5
4
|
import { at } from "@prosopo/util";
|
|
6
|
-
import {
|
|
5
|
+
import { decodeAddress, encodeAddress } from "@prosopo/util-crypto";
|
|
7
6
|
import { Address4, Address6 } from "ip-address";
|
|
8
|
-
import {
|
|
7
|
+
import { hexToU8a } from "@polkadot/util/hex";
|
|
8
|
+
import { isHex } from "@polkadot/util/is";
|
|
9
|
+
//#region src/util.ts
|
|
9
10
|
function encodeStringAddress(address) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
throw new ProsopoContractError("CONTRACT.INVALID_ADDRESS", {
|
|
16
|
-
context: { address }
|
|
17
|
-
});
|
|
18
|
-
}
|
|
11
|
+
try {
|
|
12
|
+
return encodeAddress(isHex(address) ? hexToU8a(address) : decodeAddress(address));
|
|
13
|
+
} catch (err) {
|
|
14
|
+
throw new ProsopoContractError("CONTRACT.INVALID_ADDRESS", { context: { address } });
|
|
15
|
+
}
|
|
19
16
|
}
|
|
20
17
|
function shuffleArray(array) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
for (let arrayIndex = array.length - 1; arrayIndex > 0; arrayIndex--) {
|
|
19
|
+
const randIndex = Math.floor(Math.random() * (arrayIndex + 1));
|
|
20
|
+
const tmp = at(array, randIndex);
|
|
21
|
+
array[randIndex] = at(array, arrayIndex);
|
|
22
|
+
array[arrayIndex] = tmp;
|
|
23
|
+
}
|
|
24
|
+
return array;
|
|
28
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if there is a scheduled task running.
|
|
28
|
+
* If the scheduled task is running and not completed, return true.
|
|
29
|
+
* If the scheduled task is running and completed, return false.
|
|
30
|
+
* Otherwise, the scheduled task is not running, return false.
|
|
31
|
+
*/
|
|
29
32
|
async function checkIfTaskIsRunning(taskName, db) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const twoMinutesAgo = (/* @__PURE__ */ new Date()).getTime() - 1e3 * 60 * 2;
|
|
35
|
-
if (runningTask && runningTask.datetime.getTime() > twoMinutesAgo) {
|
|
36
|
-
const completedTask = await db.getScheduledTaskStatus(
|
|
37
|
-
runningTask._id,
|
|
38
|
-
ScheduledTaskStatus.Completed
|
|
39
|
-
);
|
|
40
|
-
return !completedTask;
|
|
41
|
-
}
|
|
42
|
-
return false;
|
|
33
|
+
const runningTask = await db.getLastScheduledTaskStatus(taskName, ScheduledTaskStatus.Running);
|
|
34
|
+
const twoMinutesAgo = (/* @__PURE__ */ new Date()).getTime() - 1e3 * 60 * 2;
|
|
35
|
+
if (runningTask && runningTask.datetime.getTime() > twoMinutesAgo) return !await db.getScheduledTaskStatus(runningTask._id, ScheduledTaskStatus.Completed);
|
|
36
|
+
return false;
|
|
43
37
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
};
|
|
55
|
-
const getIPAddressFromBigInt = (ipAddressBigInt) => {
|
|
56
|
-
try {
|
|
57
|
-
if (ipAddressBigInt > 4228250626n) {
|
|
58
|
-
return Address6.fromBigInt(BigInt(ipAddressBigInt));
|
|
59
|
-
}
|
|
60
|
-
return Address4.fromBigInt(BigInt(ipAddressBigInt));
|
|
61
|
-
} catch (e) {
|
|
62
|
-
throw new ProsopoEnvError("API.INVALID_IP");
|
|
63
|
-
}
|
|
38
|
+
var getIPAddress$1 = (ipAddressString) => {
|
|
39
|
+
try {
|
|
40
|
+
try {
|
|
41
|
+
return new Address4(ipAddressString);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
return new Address6(ipAddressString);
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
throw new ProsopoEnvError("API.INVALID_IP");
|
|
47
|
+
}
|
|
64
48
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
logger.info(() => ({ data: { ipV4orV6Address } }));
|
|
73
|
-
} catch (e) {
|
|
74
|
-
const errorMessage = `Invalid IP address: ${ip}`;
|
|
75
|
-
logger.info(() => ({ msg: errorMessage }));
|
|
76
|
-
return { isValid: false, errorMessage };
|
|
77
|
-
}
|
|
78
|
-
ipV4orV6Address = "address4" in ipV4orV6Address && ipV4orV6Address.address4 ? ipV4orV6Address.address4 : ipV4orV6Address;
|
|
79
|
-
challengeIpAddress = "address4" in challengeIpAddress && challengeIpAddress.address4 ? challengeIpAddress.address4 : challengeIpAddress;
|
|
80
|
-
if (ipV4orV6Address.v4 && !challengeIpAddress.v4) {
|
|
81
|
-
challengeIpAddress = new Address4(
|
|
82
|
-
challengeIpAddress.to4().correctForm()
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
if (challengeIpAddress.bigInt() - ipV4orV6Address.bigInt() !== 0n) {
|
|
86
|
-
const errorMessage = `IP address mismatch: ${challengeIpAddress.address} !== ${ipV4orV6Address.address}`;
|
|
87
|
-
logger.info(() => ({
|
|
88
|
-
msg: errorMessage,
|
|
89
|
-
data: {
|
|
90
|
-
challengeIp: challengeIpAddress.address,
|
|
91
|
-
providedIp: ipV4orV6Address.address
|
|
92
|
-
}
|
|
93
|
-
}));
|
|
94
|
-
return { isValid: false, errorMessage };
|
|
95
|
-
}
|
|
96
|
-
return { isValid: true };
|
|
49
|
+
var getIPAddressFromBigInt = (ipAddressBigInt) => {
|
|
50
|
+
try {
|
|
51
|
+
if (ipAddressBigInt > 4228250626n) return Address6.fromBigInt(BigInt(ipAddressBigInt));
|
|
52
|
+
return Address4.fromBigInt(BigInt(ipAddressBigInt));
|
|
53
|
+
} catch (e) {
|
|
54
|
+
throw new ProsopoEnvError("API.INVALID_IP");
|
|
55
|
+
}
|
|
97
56
|
};
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const ip1Provider = comparison.comparison.ip1Details?.provider;
|
|
138
|
-
const ip2Provider = comparison.comparison.ip2Details?.provider;
|
|
139
|
-
const ip1ConnectionType = comparison.comparison.ip1Details?.connectionType;
|
|
140
|
-
const ip2ConnectionType = comparison.comparison.ip2Details?.connectionType;
|
|
141
|
-
const sameTrustedProvider = !comparison.comparison.differentProviders && !!ip1Provider && ip1Provider !== "Unknown" && ip1CountryCode === ip2CountryCode && ip1ConnectionType !== "datacenter" && ip2ConnectionType !== "datacenter";
|
|
142
|
-
if (sameTrustedProvider) {
|
|
143
|
-
logger.info(() => ({
|
|
144
|
-
msg: "Skipping city and distance IP validation rules for same trusted provider",
|
|
145
|
-
data: {
|
|
146
|
-
provider: ip1Provider,
|
|
147
|
-
countryCode: ip1CountryCode
|
|
148
|
-
}
|
|
149
|
-
}));
|
|
150
|
-
}
|
|
151
|
-
const ip1City = comparison.comparison.ip1Details?.city;
|
|
152
|
-
const ip2City = comparison.comparison.ip2Details?.city;
|
|
153
|
-
if (!sameTrustedProvider && ip1City !== ip2City) {
|
|
154
|
-
conditions.push({
|
|
155
|
-
met: true,
|
|
156
|
-
action: effectiveRules.actions.cityChangeAction,
|
|
157
|
-
message: `City changed from ${ip1City} to ${ip2City}`
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
if (comparison.comparison.differentProviders) {
|
|
161
|
-
conditions.push({
|
|
162
|
-
met: true,
|
|
163
|
-
action: effectiveRules.actions.ispChangeAction,
|
|
164
|
-
message: `ISP changed from ${ip1Provider} to ${ip2Provider}`
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
const distanceKm = comparison.comparison.distanceKm;
|
|
168
|
-
if (!sameTrustedProvider && distanceKm !== void 0 && distanceKm > effectiveRules.distanceThresholdKm) {
|
|
169
|
-
conditions.push({
|
|
170
|
-
met: true,
|
|
171
|
-
action: effectiveRules.actions.distanceExceedAction,
|
|
172
|
-
message: `IP addresses are ${distanceKm.toFixed(2)}km apart (>${effectiveRules.distanceThresholdKm}km limit)`
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
const ip2AbuseScore = comparison.comparison.ip2Details?.abuserScore;
|
|
176
|
-
if (ip2AbuseScore !== void 0 && ip2AbuseScore > effectiveRules.abuseScoreThreshold) {
|
|
177
|
-
conditions.push({
|
|
178
|
-
met: true,
|
|
179
|
-
action: effectiveRules.actions.abuseScoreExceedAction,
|
|
180
|
-
message: `Abuse score ${ip2AbuseScore.toFixed(4)} exceeds threshold ${effectiveRules.abuseScoreThreshold}`
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
const ip1AbuseScore = comparison.comparison.ip1Details?.abuserScore;
|
|
184
|
-
if (ip1AbuseScore !== void 0 && ip1AbuseScore > effectiveRules.abuseScoreThreshold) {
|
|
185
|
-
conditions.push({
|
|
186
|
-
met: true,
|
|
187
|
-
action: effectiveRules.actions.abuseScoreExceedAction,
|
|
188
|
-
message: `Abuse score ${ip1AbuseScore.toFixed(4)} exceeds threshold ${effectiveRules.abuseScoreThreshold}`
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
if (conditions.length === 0) {
|
|
192
|
-
return { action: IPValidationAction.Allow };
|
|
193
|
-
}
|
|
194
|
-
const errorMessages = [];
|
|
195
|
-
let finalAction = IPValidationAction.Allow;
|
|
196
|
-
let shouldFlag = false;
|
|
197
|
-
if (effectiveRules.requireAllConditions) {
|
|
198
|
-
const rejectConditions = conditions.filter(
|
|
199
|
-
(c) => c.action === IPValidationAction.Reject
|
|
200
|
-
);
|
|
201
|
-
if (rejectConditions.length > 0 && rejectConditions.length >= rejectActions.length) {
|
|
202
|
-
finalAction = IPValidationAction.Reject;
|
|
203
|
-
}
|
|
204
|
-
for (const condition of conditions) {
|
|
205
|
-
if (condition.action === IPValidationAction.Reject || condition.action === IPValidationAction.Flag) {
|
|
206
|
-
errorMessages.push(condition.message);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
} else {
|
|
210
|
-
for (const condition of conditions) {
|
|
211
|
-
if (condition.action === IPValidationAction.Reject) {
|
|
212
|
-
finalAction = IPValidationAction.Reject;
|
|
213
|
-
errorMessages.push(condition.message);
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
if (condition.action === IPValidationAction.Flag) {
|
|
217
|
-
finalAction = IPValidationAction.Flag;
|
|
218
|
-
shouldFlag = true;
|
|
219
|
-
}
|
|
220
|
-
errorMessages.push(condition.message);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
logger.info(() => ({
|
|
224
|
-
msg: `IP validation rules evaluated: ${finalAction}`,
|
|
225
|
-
data: {
|
|
226
|
-
conditions,
|
|
227
|
-
finalAction,
|
|
228
|
-
requireAllConditions: effectiveRules.requireAllConditions
|
|
229
|
-
}
|
|
230
|
-
}));
|
|
231
|
-
return {
|
|
232
|
-
action: finalAction,
|
|
233
|
-
errorMessage: errorMessages.length > 0 ? errorMessages.join("; ") : void 0,
|
|
234
|
-
shouldFlag
|
|
235
|
-
};
|
|
57
|
+
/**
|
|
58
|
+
* Validates that the provided IP address matches the challenge record's IP address
|
|
59
|
+
* @param ip - The IP address string to validate
|
|
60
|
+
* @param challengeIpAddress - The IP address from the challenge record
|
|
61
|
+
* @param logger - Logger instance for debug messages
|
|
62
|
+
* @returns Object with validation result and optional error message
|
|
63
|
+
*/
|
|
64
|
+
var validateIpAddress = (ip, challengeIpAddress, logger) => {
|
|
65
|
+
if (!ip) return { isValid: true };
|
|
66
|
+
let ipV4orV6Address;
|
|
67
|
+
try {
|
|
68
|
+
ipV4orV6Address = getIPAddress$1(ip);
|
|
69
|
+
logger.info(() => ({ data: { ipV4orV6Address } }));
|
|
70
|
+
} catch (e) {
|
|
71
|
+
const errorMessage = `Invalid IP address: ${ip}`;
|
|
72
|
+
logger.info(() => ({ msg: errorMessage }));
|
|
73
|
+
return {
|
|
74
|
+
isValid: false,
|
|
75
|
+
errorMessage
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
ipV4orV6Address = "address4" in ipV4orV6Address && ipV4orV6Address.address4 ? ipV4orV6Address.address4 : ipV4orV6Address;
|
|
79
|
+
challengeIpAddress = "address4" in challengeIpAddress && challengeIpAddress.address4 ? challengeIpAddress.address4 : challengeIpAddress;
|
|
80
|
+
if (ipV4orV6Address.v4 && !challengeIpAddress.v4) challengeIpAddress = new Address4(challengeIpAddress.to4().correctForm());
|
|
81
|
+
if (challengeIpAddress.bigInt() - ipV4orV6Address.bigInt() !== 0n) {
|
|
82
|
+
const errorMessage = `IP address mismatch: ${challengeIpAddress.address} !== ${ipV4orV6Address.address}`;
|
|
83
|
+
logger.info(() => ({
|
|
84
|
+
msg: errorMessage,
|
|
85
|
+
data: {
|
|
86
|
+
challengeIp: challengeIpAddress.address,
|
|
87
|
+
providedIp: ipV4orV6Address.address
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
return {
|
|
91
|
+
isValid: false,
|
|
92
|
+
errorMessage
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return { isValid: true };
|
|
236
96
|
};
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
distanceKm,
|
|
347
|
-
shouldFlag: true,
|
|
348
|
-
errorMessage: ruleEvaluation.errorMessage
|
|
349
|
-
};
|
|
350
|
-
default:
|
|
351
|
-
return {
|
|
352
|
-
isValid: true,
|
|
353
|
-
distanceKm
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
} catch (error) {
|
|
357
|
-
logger.error(() => ({
|
|
358
|
-
msg: "Error during IP distance validation",
|
|
359
|
-
err: error,
|
|
360
|
-
data: { challengeIp: challengeIpAddress.address, providedIp: ip }
|
|
361
|
-
}));
|
|
362
|
-
return {
|
|
363
|
-
isValid: true,
|
|
364
|
-
shouldFlag: true,
|
|
365
|
-
errorMessage: "IP distance validation error"
|
|
366
|
-
};
|
|
367
|
-
}
|
|
97
|
+
/**
|
|
98
|
+
* Evaluates IP validation rules based on IP comparison results
|
|
99
|
+
* @param comparison - IP comparison results from compareIPs
|
|
100
|
+
* @param rules - IP validation rules configuration
|
|
101
|
+
* @param logger - Logger instance
|
|
102
|
+
* @returns Validation result with action to take
|
|
103
|
+
*/
|
|
104
|
+
var evaluateIpValidationRules = (comparison, rules, logger) => {
|
|
105
|
+
if (!comparison.comparison) return { action: IPValidationAction.Allow };
|
|
106
|
+
const conditions = [];
|
|
107
|
+
const rejectActions = Object.values(rules.actions).filter((action) => action === IPValidationAction.Reject);
|
|
108
|
+
const ip1Country = comparison.comparison.ip1Details?.country;
|
|
109
|
+
const ip2Country = comparison.comparison.ip2Details?.country;
|
|
110
|
+
const ip1CountryCode = comparison.comparison.ip1Details?.countryCode;
|
|
111
|
+
const ip2CountryCode = comparison.comparison.ip2Details?.countryCode;
|
|
112
|
+
let effectiveRules = rules;
|
|
113
|
+
let countryOverride = void 0;
|
|
114
|
+
if (ip1CountryCode && rules.countryOverrides?.[ip1CountryCode]) countryOverride = rules.countryOverrides[ip1CountryCode];
|
|
115
|
+
if (ip2CountryCode && rules.countryOverrides?.[ip2CountryCode]) countryOverride = rules.countryOverrides[ip2CountryCode];
|
|
116
|
+
if (countryOverride) effectiveRules = {
|
|
117
|
+
...rules,
|
|
118
|
+
actions: {
|
|
119
|
+
...rules.actions,
|
|
120
|
+
...countryOverride.actions
|
|
121
|
+
},
|
|
122
|
+
distanceThresholdKm: countryOverride.distanceThresholdKm ?? rules.distanceThresholdKm,
|
|
123
|
+
abuseScoreThreshold: countryOverride.abuseScoreThreshold ?? rules.abuseScoreThreshold,
|
|
124
|
+
requireAllConditions: countryOverride.requireAllConditions ?? rules.requireAllConditions
|
|
125
|
+
};
|
|
126
|
+
if (ip1Country !== ip2Country) conditions.push({
|
|
127
|
+
met: true,
|
|
128
|
+
action: effectiveRules.actions.countryChangeAction,
|
|
129
|
+
message: `Country changed from ${ip1Country} to ${ip2Country}`
|
|
130
|
+
});
|
|
131
|
+
const ip1Provider = comparison.comparison.ip1Details?.provider;
|
|
132
|
+
const ip2Provider = comparison.comparison.ip2Details?.provider;
|
|
133
|
+
const ip1ConnectionType = comparison.comparison.ip1Details?.connectionType;
|
|
134
|
+
const ip2ConnectionType = comparison.comparison.ip2Details?.connectionType;
|
|
135
|
+
const sameTrustedProvider = !comparison.comparison.differentProviders && !!ip1Provider && ip1Provider !== "Unknown" && ip1CountryCode === ip2CountryCode && ip1ConnectionType !== "datacenter" && ip2ConnectionType !== "datacenter";
|
|
136
|
+
if (sameTrustedProvider) logger.info(() => ({
|
|
137
|
+
msg: "Skipping city and distance IP validation rules for same trusted provider",
|
|
138
|
+
data: {
|
|
139
|
+
provider: ip1Provider,
|
|
140
|
+
countryCode: ip1CountryCode
|
|
141
|
+
}
|
|
142
|
+
}));
|
|
143
|
+
const ip1City = comparison.comparison.ip1Details?.city;
|
|
144
|
+
const ip2City = comparison.comparison.ip2Details?.city;
|
|
145
|
+
if (!sameTrustedProvider && ip1City !== ip2City) conditions.push({
|
|
146
|
+
met: true,
|
|
147
|
+
action: effectiveRules.actions.cityChangeAction,
|
|
148
|
+
message: `City changed from ${ip1City} to ${ip2City}`
|
|
149
|
+
});
|
|
150
|
+
if (comparison.comparison.differentProviders) conditions.push({
|
|
151
|
+
met: true,
|
|
152
|
+
action: effectiveRules.actions.ispChangeAction,
|
|
153
|
+
message: `ISP changed from ${ip1Provider} to ${ip2Provider}`
|
|
154
|
+
});
|
|
155
|
+
const distanceKm = comparison.comparison.distanceKm;
|
|
156
|
+
if (!sameTrustedProvider && distanceKm !== void 0 && distanceKm > effectiveRules.distanceThresholdKm) conditions.push({
|
|
157
|
+
met: true,
|
|
158
|
+
action: effectiveRules.actions.distanceExceedAction,
|
|
159
|
+
message: `IP addresses are ${distanceKm.toFixed(2)}km apart (>${effectiveRules.distanceThresholdKm}km limit)`
|
|
160
|
+
});
|
|
161
|
+
const ip2AbuseScore = comparison.comparison.ip2Details?.abuserScore;
|
|
162
|
+
if (ip2AbuseScore !== void 0 && ip2AbuseScore > effectiveRules.abuseScoreThreshold) conditions.push({
|
|
163
|
+
met: true,
|
|
164
|
+
action: effectiveRules.actions.abuseScoreExceedAction,
|
|
165
|
+
message: `Abuse score ${ip2AbuseScore.toFixed(4)} exceeds threshold ${effectiveRules.abuseScoreThreshold}`
|
|
166
|
+
});
|
|
167
|
+
const ip1AbuseScore = comparison.comparison.ip1Details?.abuserScore;
|
|
168
|
+
if (ip1AbuseScore !== void 0 && ip1AbuseScore > effectiveRules.abuseScoreThreshold) conditions.push({
|
|
169
|
+
met: true,
|
|
170
|
+
action: effectiveRules.actions.abuseScoreExceedAction,
|
|
171
|
+
message: `Abuse score ${ip1AbuseScore.toFixed(4)} exceeds threshold ${effectiveRules.abuseScoreThreshold}`
|
|
172
|
+
});
|
|
173
|
+
if (conditions.length === 0) return { action: IPValidationAction.Allow };
|
|
174
|
+
const errorMessages = [];
|
|
175
|
+
let finalAction = IPValidationAction.Allow;
|
|
176
|
+
let shouldFlag = false;
|
|
177
|
+
if (effectiveRules.requireAllConditions) {
|
|
178
|
+
const rejectConditions = conditions.filter((c) => c.action === IPValidationAction.Reject);
|
|
179
|
+
if (rejectConditions.length > 0 && rejectConditions.length >= rejectActions.length) finalAction = IPValidationAction.Reject;
|
|
180
|
+
for (const condition of conditions) if (condition.action === IPValidationAction.Reject || condition.action === IPValidationAction.Flag) errorMessages.push(condition.message);
|
|
181
|
+
} else for (const condition of conditions) {
|
|
182
|
+
if (condition.action === IPValidationAction.Reject) {
|
|
183
|
+
finalAction = IPValidationAction.Reject;
|
|
184
|
+
errorMessages.push(condition.message);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
if (condition.action === IPValidationAction.Flag) {
|
|
188
|
+
finalAction = IPValidationAction.Flag;
|
|
189
|
+
shouldFlag = true;
|
|
190
|
+
}
|
|
191
|
+
errorMessages.push(condition.message);
|
|
192
|
+
}
|
|
193
|
+
logger.info(() => ({
|
|
194
|
+
msg: `IP validation rules evaluated: ${finalAction}`,
|
|
195
|
+
data: {
|
|
196
|
+
conditions,
|
|
197
|
+
finalAction,
|
|
198
|
+
requireAllConditions: effectiveRules.requireAllConditions
|
|
199
|
+
}
|
|
200
|
+
}));
|
|
201
|
+
return {
|
|
202
|
+
action: finalAction,
|
|
203
|
+
errorMessage: errorMessages.length > 0 ? errorMessages.join("; ") : void 0,
|
|
204
|
+
shouldFlag
|
|
205
|
+
};
|
|
368
206
|
};
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
207
|
+
/**
|
|
208
|
+
* @param ip - The IP address string to validate
|
|
209
|
+
* @param challengeIpAddress - The IP address from the challenge record
|
|
210
|
+
* @param logger - Logger instance for debug messages
|
|
211
|
+
* @param ipInfoService - IP info service for local lookups
|
|
212
|
+
* @param ipValidationRules - IP validation rules configuration
|
|
213
|
+
* @returns Object with validation result, optional error message, and distance info
|
|
214
|
+
*/
|
|
215
|
+
var deepValidateIpAddress = async (ip, challengeIpAddress, logger, ipInfoService, ipValidationRules, dnsPeerIp) => {
|
|
216
|
+
if (ipValidationRules?.forceConsistentIp === true && dnsPeerIp && dnsPeerIp !== ip) {
|
|
217
|
+
logger.info(() => ({
|
|
218
|
+
msg: "IP validation failed - dnsEvent.peerIp does not match client IP",
|
|
219
|
+
data: {
|
|
220
|
+
clientIp: ip,
|
|
221
|
+
dnsPeerIp
|
|
222
|
+
}
|
|
223
|
+
}));
|
|
224
|
+
return {
|
|
225
|
+
isValid: false,
|
|
226
|
+
errorMessage: `Client IP ${ip} does not match dnsEvent.peerIp ${dnsPeerIp}`
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
const standardValidation = validateIpAddress(ip, challengeIpAddress, logger);
|
|
230
|
+
if (!standardValidation.isValid) {
|
|
231
|
+
if (standardValidation.errorMessage?.includes("Invalid IP address")) return standardValidation;
|
|
232
|
+
if (ipValidationRules?.forceConsistentIp === true) {
|
|
233
|
+
logger.info(() => ({
|
|
234
|
+
msg: "IP validation failed - forceConsistentIp is true",
|
|
235
|
+
data: {
|
|
236
|
+
challengeIp: challengeIpAddress.address,
|
|
237
|
+
providedIp: ip
|
|
238
|
+
}
|
|
239
|
+
}));
|
|
240
|
+
return {
|
|
241
|
+
isValid: false,
|
|
242
|
+
errorMessage: standardValidation.errorMessage
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
} else return { isValid: true };
|
|
246
|
+
try {
|
|
247
|
+
const challengeIpString = challengeIpAddress.address;
|
|
248
|
+
const comparison = await compareIPs(challengeIpString, ip, ipInfoService);
|
|
249
|
+
if ("error" in comparison) {
|
|
250
|
+
logger.error(() => ({
|
|
251
|
+
msg: "Failed to get IP distance comparison",
|
|
252
|
+
data: {
|
|
253
|
+
error: comparison.error,
|
|
254
|
+
challengeIp: challengeIpString,
|
|
255
|
+
providedIp: ip
|
|
256
|
+
}
|
|
257
|
+
}));
|
|
258
|
+
return {
|
|
259
|
+
isValid: true,
|
|
260
|
+
errorMessage: "Could not determine IP distance"
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (comparison.ipsMatch) return { isValid: true };
|
|
264
|
+
const distanceKm = comparison.comparison?.distanceKm;
|
|
265
|
+
if (!ipValidationRules) {
|
|
266
|
+
logger.info(() => ({
|
|
267
|
+
msg: "No IP validation rules provided, using legacy logic",
|
|
268
|
+
data: {
|
|
269
|
+
challengeIp: challengeIpString,
|
|
270
|
+
providedIp: ip,
|
|
271
|
+
distanceKm
|
|
272
|
+
}
|
|
273
|
+
}));
|
|
274
|
+
if (distanceKm !== void 0 && distanceKm > 1e3) {
|
|
275
|
+
const errorMessage = `IP addresses are too far apart: ${distanceKm.toFixed(2)}km (>1000km limit)`;
|
|
276
|
+
logger.info(() => ({
|
|
277
|
+
msg: "IP validation failed - distance too great",
|
|
278
|
+
data: {
|
|
279
|
+
challengeIp: challengeIpString,
|
|
280
|
+
providedIp: ip,
|
|
281
|
+
distanceKm,
|
|
282
|
+
comparison: comparison.comparison
|
|
283
|
+
}
|
|
284
|
+
}));
|
|
285
|
+
return {
|
|
286
|
+
isValid: false,
|
|
287
|
+
errorMessage,
|
|
288
|
+
distanceKm
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
logger.info(() => ({
|
|
292
|
+
msg: "IP addresses differ but within acceptable distance",
|
|
293
|
+
data: {
|
|
294
|
+
challengeIp: challengeIpString,
|
|
295
|
+
providedIp: ip,
|
|
296
|
+
distanceKm,
|
|
297
|
+
comparison: comparison.comparison
|
|
298
|
+
}
|
|
299
|
+
}));
|
|
300
|
+
return {
|
|
301
|
+
isValid: true,
|
|
302
|
+
distanceKm,
|
|
303
|
+
shouldFlag: true
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const ruleEvaluation = evaluateIpValidationRules(comparison, ipValidationRules, logger);
|
|
307
|
+
switch (ruleEvaluation.action) {
|
|
308
|
+
case IPValidationAction.Reject: return {
|
|
309
|
+
isValid: false,
|
|
310
|
+
errorMessage: ruleEvaluation.errorMessage,
|
|
311
|
+
distanceKm
|
|
312
|
+
};
|
|
313
|
+
case IPValidationAction.Flag: return {
|
|
314
|
+
isValid: true,
|
|
315
|
+
distanceKm,
|
|
316
|
+
shouldFlag: true,
|
|
317
|
+
errorMessage: ruleEvaluation.errorMessage
|
|
318
|
+
};
|
|
319
|
+
default: return {
|
|
320
|
+
isValid: true,
|
|
321
|
+
distanceKm
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
} catch (error) {
|
|
325
|
+
logger.error(() => ({
|
|
326
|
+
msg: "Error during IP distance validation",
|
|
327
|
+
err: error,
|
|
328
|
+
data: {
|
|
329
|
+
challengeIp: challengeIpAddress.address,
|
|
330
|
+
providedIp: ip
|
|
331
|
+
}
|
|
332
|
+
}));
|
|
333
|
+
return {
|
|
334
|
+
isValid: true,
|
|
335
|
+
shouldFlag: true,
|
|
336
|
+
errorMessage: "IP distance validation error"
|
|
337
|
+
};
|
|
338
|
+
}
|
|
378
339
|
};
|
|
340
|
+
//#endregion
|
|
341
|
+
export { checkIfTaskIsRunning, deepValidateIpAddress, encodeStringAddress, evaluateIpValidationRules, getIPAddress$1 as getIPAddress, getIPAddressFromBigInt, shuffleArray, validateIpAddress };
|