@prosopo/provider 5.19.3 → 5.20.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 +45 -40
- package/.turbo/turbo-build$colon$tsc.log +28 -28
- package/.turbo/turbo-build.log +48 -40
- package/CHANGELOG.md +167 -0
- package/dist/api/admin/apiClearAllCountersEndpoint.js.map +1 -1
- package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.js.map +1 -1
- package/dist/api/admin/apiGetDecisionMachineEndpoint.js.map +1 -1
- package/dist/api/admin/apiGetSessionEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveDecisionMachineEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveSiteKeyEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveSiteKeysEndpoint.js.map +1 -1
- package/dist/api/admin/apiReplaceDetectorPoolEndpoint.js.map +1 -1
- package/dist/api/admin/apiUpdateDecisionMachineEndpoint.js.map +1 -1
- package/dist/api/blacklistRequestInspector.d.ts.map +1 -1
- package/dist/api/blacklistRequestInspector.js +9 -8
- package/dist/api/blacklistRequestInspector.js.map +1 -1
- package/dist/api/captcha/checkSpamEmail.d.ts.map +1 -1
- package/dist/api/captcha/checkSpamEmail.js +19 -26
- package/dist/api/captcha/checkSpamEmail.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js +11 -2
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +6 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +30 -27
- 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 +32 -43
- 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 +27 -32
- package/dist/api/captcha/getPoWCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts +3 -0
- package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/getPuzzleCaptchaChallenge.js +23 -5
- package/dist/api/captcha/getPuzzleCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/interactiveCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/interactiveCaptchaChallenge.js +27 -32
- package/dist/api/captcha/interactiveCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/interactiveCaptchaSolution.d.ts.map +1 -1
- package/dist/api/captcha/interactiveCaptchaSolution.js +18 -24
- package/dist/api/captcha/interactiveCaptchaSolution.js.map +1 -1
- package/dist/api/captcha/submitImageCaptchaSolution.d.ts.map +1 -1
- package/dist/api/captcha/submitImageCaptchaSolution.js +18 -24
- package/dist/api/captcha/submitImageCaptchaSolution.js.map +1 -1
- package/dist/api/captcha/submitPoWCaptchaSolution.d.ts.map +1 -1
- package/dist/api/captcha/submitPoWCaptchaSolution.js +35 -27
- package/dist/api/captcha/submitPoWCaptchaSolution.js.map +1 -1
- package/dist/api/domainMiddleware.d.ts.map +1 -1
- package/dist/api/domainMiddleware.js +39 -47
- package/dist/api/domainMiddleware.js.map +1 -1
- package/dist/api/errorCodeForReason.d.ts +3 -0
- package/dist/api/errorCodeForReason.d.ts.map +1 -0
- package/dist/api/errorCodeForReason.js +22 -0
- package/dist/api/errorCodeForReason.js.map +1 -0
- package/dist/api/headerCheckMiddleware.d.ts.map +1 -1
- package/dist/api/headerCheckMiddleware.js +14 -9
- package/dist/api/headerCheckMiddleware.js.map +1 -1
- package/dist/api/ipInfoMiddleware.d.ts +1 -1
- package/dist/api/ipInfoMiddleware.d.ts.map +1 -1
- package/dist/api/ipInfoMiddleware.js +5 -1
- package/dist/api/ipInfoMiddleware.js.map +1 -1
- package/dist/api/metrics.d.ts.map +1 -1
- package/dist/api/metrics.js +9 -1
- package/dist/api/metrics.js.map +1 -1
- package/dist/api/public.d.ts.map +1 -1
- package/dist/api/public.js +6 -2
- package/dist/api/public.js.map +1 -1
- package/dist/api/rateLimitHandler.d.ts +4 -0
- package/dist/api/rateLimitHandler.d.ts.map +1 -0
- package/dist/api/rateLimitHandler.js +20 -0
- package/dist/api/rateLimitHandler.js.map +1 -0
- package/dist/api/startProviderApi.d.ts +1 -0
- package/dist/api/startProviderApi.d.ts.map +1 -1
- package/dist/api/startProviderApi.js +8 -17
- package/dist/api/startProviderApi.js.map +1 -1
- package/dist/api/validateAddress.d.ts +3 -4
- package/dist/api/validateAddress.d.ts.map +1 -1
- package/dist/api/validateAddress.js +13 -19
- package/dist/api/validateAddress.js.map +1 -1
- package/dist/api/verify.d.ts.map +1 -1
- package/dist/api/verify.js +73 -96
- package/dist/api/verify.js.map +1 -1
- package/dist/cjs/api/blacklistRequestInspector.cjs +9 -8
- package/dist/cjs/api/captcha/checkSpamEmail.cjs +18 -25
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs +11 -2
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +6 -1
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +29 -26
- package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +31 -42
- package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +26 -31
- package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +22 -3
- package/dist/cjs/api/captcha/interactiveCaptchaChallenge.cjs +26 -31
- package/dist/cjs/api/captcha/interactiveCaptchaSolution.cjs +17 -23
- package/dist/cjs/api/captcha/submitImageCaptchaSolution.cjs +17 -23
- package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +34 -26
- package/dist/cjs/api/domainMiddleware.cjs +38 -46
- package/dist/cjs/api/errorCodeForReason.cjs +22 -0
- package/dist/cjs/api/headerCheckMiddleware.cjs +13 -8
- package/dist/cjs/api/ipInfoMiddleware.cjs +5 -1
- package/dist/cjs/api/metrics.cjs +9 -1
- package/dist/cjs/api/public.cjs +5 -1
- package/dist/cjs/api/rateLimitHandler.cjs +20 -0
- package/dist/cjs/api/startProviderApi.cjs +8 -16
- package/dist/cjs/api/validateAddress.cjs +12 -18
- package/dist/cjs/api/verify.cjs +72 -95
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/tasks/captchaManager.cjs +6 -8
- package/dist/cjs/tasks/client/clientTasks.cjs +26 -13
- package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +28 -8
- package/dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs +21 -19
- package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +1 -1
- package/dist/cjs/tasks/frictionless/routingMachine.cjs +13 -4
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +89 -40
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +18 -8
- package/dist/cjs/tasks/interactiveCaptcha/interactiveCaptchaManager.cjs +21 -13
- package/dist/cjs/tasks/powCaptcha/backgroundWrites.cjs +24 -0
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +44 -19
- package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +14 -10
- package/dist/cjs/tasks/puzzle/puzzleRenderer.cjs +17 -8
- package/dist/cjs/tasks/signatureCheck.cjs +12 -0
- package/dist/cjs/tasks/tasks.cjs +6 -1
- package/dist/cjs/util/usageCounters.cjs +26 -3
- package/dist/cjs/util.cjs +14 -3
- package/dist/cjs/utils/devicePlatform.cjs +9 -5
- package/dist/cjs/utils/mobileSignals.cjs +69 -0
- package/dist/errorSites.d.ts +98 -0
- package/dist/errorSites.d.ts.map +1 -0
- package/dist/errorSites.js +2 -0
- package/dist/errorSites.js.map +1 -0
- package/dist/fingerprint/dist/merkle.js +69 -0
- package/dist/fingerprint/dist/proof.js +95 -0
- package/dist/fingerprint/dist/summary.js +73 -0
- package/dist/index.js +2 -2
- package/dist/tasks/captchaManager.d.ts +2 -3
- package/dist/tasks/captchaManager.d.ts.map +1 -1
- package/dist/tasks/captchaManager.js +6 -7
- package/dist/tasks/captchaManager.js.map +1 -1
- package/dist/tasks/client/clientTasks.d.ts.map +1 -1
- package/dist/tasks/client/clientTasks.js +27 -14
- package/dist/tasks/client/clientTasks.js.map +1 -1
- package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +1 -1
- package/dist/tasks/dataset/datasetTasksUtils.js +29 -9
- package/dist/tasks/dataset/datasetTasksUtils.js.map +1 -1
- package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts +1 -3
- package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts.map +1 -1
- package/dist/tasks/decisionMachine/decisionMachineRunner.js +21 -19
- package/dist/tasks/decisionMachine/decisionMachineRunner.js.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.js +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
- package/dist/tasks/frictionless/routingMachine.d.ts.map +1 -1
- package/dist/tasks/frictionless/routingMachine.js +13 -4
- package/dist/tasks/frictionless/routingMachine.js.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +91 -42
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +19 -9
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +1 -1
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts.map +1 -1
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js +22 -14
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js.map +1 -1
- package/dist/tasks/powCaptcha/backgroundWrites.d.ts +7 -0
- package/dist/tasks/powCaptcha/backgroundWrites.d.ts.map +1 -0
- package/dist/tasks/powCaptcha/backgroundWrites.js +24 -0
- package/dist/tasks/powCaptcha/backgroundWrites.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasks.d.ts +3 -3
- package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
- package/dist/tasks/powCaptcha/powTasks.js +45 -20
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +1 -1
- package/dist/tasks/powCaptcha/powTasksUtils.js +15 -11
- package/dist/tasks/powCaptcha/powTasksUtils.js.map +1 -1
- package/dist/tasks/puzzle/puzzleRenderer.d.ts +8 -1
- package/dist/tasks/puzzle/puzzleRenderer.d.ts.map +1 -1
- package/dist/tasks/puzzle/puzzleRenderer.js +16 -8
- package/dist/tasks/puzzle/puzzleRenderer.js.map +1 -1
- package/dist/tasks/signatureCheck.d.ts +2 -0
- package/dist/tasks/signatureCheck.d.ts.map +1 -0
- package/dist/tasks/signatureCheck.js +12 -0
- package/dist/tasks/signatureCheck.js.map +1 -0
- package/dist/tasks/tasks.d.ts.map +1 -1
- package/dist/tasks/tasks.js +7 -2
- package/dist/tasks/tasks.js.map +1 -1
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +3 -1
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +1 -1
- package/dist/tests/integration/api/admin/apiRegisterSiteKeysEndpoint.integration.test.js +6 -2
- package/dist/tests/integration/api/admin/apiRegisterSiteKeysEndpoint.integration.test.js.map +1 -1
- package/dist/tests/integration/escalationPeekBeforeConsume.integration.test.js +1 -1
- package/dist/tests/integration/escalationPeekBeforeConsume.integration.test.js.map +1 -1
- package/dist/tests/integration/imgCaptcha.integration.test.js +6 -5
- package/dist/tests/integration/imgCaptcha.integration.test.js.map +1 -1
- package/dist/tests/integration/ipValidation.integration.test.js +1 -1
- package/dist/tests/integration/ipValidation.integration.test.js.map +1 -1
- package/dist/tests/integration/powCaptcha.integration.test.js +2 -2
- package/dist/tests/integration/powCaptcha.integration.test.js.map +1 -1
- package/dist/tests/integration/routingDecisionMachines.integration.test.js.map +1 -1
- package/dist/tests/integration/testUtils.d.ts +2 -2
- package/dist/tests/integration/testUtils.d.ts.map +1 -1
- package/dist/tests/integration/testUtils.js +1 -1
- package/dist/tests/integration/testUtils.js.map +1 -1
- package/dist/tests/integration/webBotAuthAuthenticated.integration.test.js +3 -1
- package/dist/tests/integration/webBotAuthAuthenticated.integration.test.js.map +1 -1
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js +26 -10
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.js +4 -4
- package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/puzzleTouchFloors.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/captcha/puzzleTouchFloors.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/captcha/puzzleTouchFloors.unit.test.js +210 -0
- package/dist/tests/unit/api/captcha/puzzleTouchFloors.unit.test.js.map +1 -0
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.js +153 -0
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.js.map +1 -0
- package/dist/tests/unit/api/domainMiddlewareErrorBody.unit.test.js +6 -2
- package/dist/tests/unit/api/domainMiddlewareErrorBody.unit.test.js.map +1 -1
- package/dist/tests/unit/api/errorCodeForReason.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/errorCodeForReason.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/errorCodeForReason.unit.test.js +23 -0
- package/dist/tests/unit/api/errorCodeForReason.unit.test.js.map +1 -0
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +6 -1
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
- package/dist/tests/unit/api/headerCheckMiddleware.unit.test.js +16 -7
- package/dist/tests/unit/api/headerCheckMiddleware.unit.test.js.map +1 -1
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.js +46 -0
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.js.map +1 -0
- package/dist/tests/unit/api/public.unit.test.js +45 -10
- package/dist/tests/unit/api/public.unit.test.js.map +1 -1
- package/dist/tests/unit/api/rateLimitHandler.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/rateLimitHandler.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/rateLimitHandler.unit.test.js +39 -0
- package/dist/tests/unit/api/rateLimitHandler.unit.test.js.map +1 -0
- package/dist/tests/unit/api/validateAddress.unit.test.js +41 -115
- package/dist/tests/unit/api/validateAddress.unit.test.js.map +1 -1
- package/dist/tests/unit/api/verifyMalformedToken.unit.test.js +3 -3
- package/dist/tests/unit/api/verifyMalformedToken.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/captchaManager.unit.test.js +22 -18
- package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +25 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +25 -20
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js +31 -0
- package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.js +80 -0
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/frictionless/routingMachine.unit.test.js +48 -0
- package/dist/tests/unit/tasks/frictionless/routingMachine.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +20 -28
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +2 -2
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.js +44 -0
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +78 -43
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +7 -6
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js +2 -2
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/util/usageCounters.unit.test.js +20 -0
- package/dist/tests/unit/util/usageCounters.unit.test.js.map +1 -1
- package/dist/tests/unit/util.unit.test.js +7 -7
- package/dist/tests/unit/util.unit.test.js.map +1 -1
- package/dist/tests/unit/utils/devicePlatform.unit.test.js +9 -8
- package/dist/tests/unit/utils/devicePlatform.unit.test.js.map +1 -1
- package/dist/tests/unit/utils/mobileSignals.unit.test.d.ts +2 -0
- package/dist/tests/unit/utils/mobileSignals.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/utils/mobileSignals.unit.test.js +161 -0
- package/dist/tests/unit/utils/mobileSignals.unit.test.js.map +1 -0
- package/dist/util/usageCounters.d.ts +1 -1
- package/dist/util/usageCounters.d.ts.map +1 -1
- package/dist/util/usageCounters.js +26 -3
- package/dist/util/usageCounters.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +15 -4
- package/dist/util.js.map +1 -1
- package/dist/utils/devicePlatform.d.ts +3 -3
- package/dist/utils/devicePlatform.d.ts.map +1 -1
- package/dist/utils/devicePlatform.js +9 -5
- package/dist/utils/devicePlatform.js.map +1 -1
- package/dist/utils/mobileSignals.d.ts +32 -0
- package/dist/utils/mobileSignals.d.ts.map +1 -0
- package/dist/utils/mobileSignals.js +68 -0
- package/dist/utils/mobileSignals.js.map +1 -0
- package/package.json +44 -43
|
@@ -8,6 +8,7 @@ const require_enrichDnsEvent = require("../dnsEvent/enrichDnsEvent.cjs");
|
|
|
8
8
|
const require_captchaManager = require("../captchaManager.cjs");
|
|
9
9
|
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
10
10
|
const require_frictionlessTasksUtils = require("../frictionless/frictionlessTasksUtils.cjs");
|
|
11
|
+
const require_signatureCheck = require("../signatureCheck.cjs");
|
|
11
12
|
const require_evaluateEmailSpamRules = require("../spam/evaluateEmailSpamRules.cjs");
|
|
12
13
|
const require_lang = require("../../rules/lang.cjs");
|
|
13
14
|
const require_pairs = require("../../pairs.cjs");
|
|
@@ -29,24 +30,38 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
29
30
|
}
|
|
30
31
|
async getCaptchaWithProof(datasetId, solved, size) {
|
|
31
32
|
const captchaDocs = await this.db.getRandomCaptcha(solved, datasetId, size);
|
|
32
|
-
if (!captchaDocs) throw new _prosopo_common.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
if (!captchaDocs) throw new _prosopo_common.ProsopoError({
|
|
34
|
+
code: "DB_QUERY_FAILED",
|
|
35
|
+
errorSite: "PROV-59",
|
|
36
|
+
message: "Failed to get captcha",
|
|
37
|
+
context: {
|
|
38
|
+
failedFuncName: this.getCaptchaWithProof.name,
|
|
39
|
+
datasetId,
|
|
40
|
+
solved,
|
|
41
|
+
size
|
|
42
|
+
}
|
|
43
|
+
});
|
|
38
44
|
return captchaDocs;
|
|
39
45
|
}
|
|
40
46
|
async getRandomCaptchasAndRequestHash(datasetId, userAccount, ipAddress, captchaConfig, threshold, sessionId, ipInfo) {
|
|
41
47
|
const dataset = await this.db.getDatasetDetails(datasetId);
|
|
42
|
-
if (!dataset) throw new _prosopo_common.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
if (!dataset) throw new _prosopo_common.ProsopoError({
|
|
49
|
+
code: "DB_QUERY_FAILED",
|
|
50
|
+
errorSite: "PROV-60",
|
|
51
|
+
message: "Failed to get dataset",
|
|
52
|
+
context: {
|
|
53
|
+
failedFuncName: this.getRandomCaptchasAndRequestHash.name,
|
|
54
|
+
dataset,
|
|
55
|
+
datasetId
|
|
56
|
+
}
|
|
57
|
+
});
|
|
47
58
|
const unsolvedCount = Math.abs(Math.trunc(captchaConfig.unsolved.count));
|
|
48
59
|
const solvedCount = Math.abs(Math.trunc(captchaConfig.solved.count));
|
|
49
|
-
if (!solvedCount) throw new _prosopo_common.
|
|
60
|
+
if (!solvedCount) throw new _prosopo_common.ProsopoError({
|
|
61
|
+
code: "CONFIG_INVALID",
|
|
62
|
+
errorSite: "PROV-61",
|
|
63
|
+
message: "Please configure captchas configurations correctly"
|
|
64
|
+
});
|
|
50
65
|
const solved = await this.getCaptchaWithProof(datasetId, true, solvedCount);
|
|
51
66
|
let unsolved = [];
|
|
52
67
|
if (unsolvedCount) unsolved = await this.getCaptchaWithProof(datasetId, false, unsolvedCount);
|
|
@@ -81,23 +96,33 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
81
96
|
* @return {Promise<DappUserSolutionResult>} result containing the contract event
|
|
82
97
|
*/
|
|
83
98
|
async dappUserSolution(userAccount, dappAccount, requestHash, captchas, userTimestampSignature, timestamp, providerRequestHashSignature, ipAddress, headers, ja4, behavioralData, ipInfo, simdReadings, clientMetaData) {
|
|
84
|
-
if (!
|
|
85
|
-
const err = new _prosopo_common.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
if (!require_signatureCheck.isSignatureValid(timestamp.toString(), userTimestampSignature, userAccount)) {
|
|
100
|
+
const err = new _prosopo_common.ProsopoError({
|
|
101
|
+
code: "UNAUTHORIZED",
|
|
102
|
+
errorSite: "PROV-62",
|
|
103
|
+
message: "Invalid signature",
|
|
104
|
+
context: {
|
|
105
|
+
failedFuncName: this.dappUserSolution.name,
|
|
106
|
+
userAccount
|
|
107
|
+
}
|
|
108
|
+
});
|
|
89
109
|
this.logger.info(() => ({
|
|
90
110
|
err,
|
|
91
111
|
msg: "Invalid user timestamp signature"
|
|
92
112
|
}));
|
|
93
113
|
throw err;
|
|
94
114
|
}
|
|
95
|
-
if (!
|
|
96
|
-
const err = new _prosopo_common.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
115
|
+
if (!require_signatureCheck.isSignatureValid(requestHash.toString(), providerRequestHashSignature, this.pair.address)) {
|
|
116
|
+
const err = new _prosopo_common.ProsopoError({
|
|
117
|
+
code: "UNAUTHORIZED",
|
|
118
|
+
errorSite: "PROV-63",
|
|
119
|
+
message: "Invalid signature",
|
|
120
|
+
context: {
|
|
121
|
+
failedFuncName: this.dappUserSolution.name,
|
|
122
|
+
userAccount,
|
|
123
|
+
error: "requestHash signature is invalid"
|
|
124
|
+
}
|
|
125
|
+
});
|
|
101
126
|
this.logger.info(() => ({
|
|
102
127
|
err,
|
|
103
128
|
msg: "Invalid provider requestHash signature"
|
|
@@ -130,7 +155,12 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
130
155
|
const inputMethodsDeclared = receivedCaptchas.some((c) => c.inputMethods !== void 0);
|
|
131
156
|
const { tree, commitmentId } = require_imgCaptchaTasksUtils.buildTreeAndGetCommitmentId(receivedCaptchas);
|
|
132
157
|
const datasetId = (0, _prosopo_util.at)(storedCaptchas, 0).datasetId;
|
|
133
|
-
if (!datasetId) throw new _prosopo_common.
|
|
158
|
+
if (!datasetId) throw new _prosopo_common.ProsopoError({
|
|
159
|
+
code: "INVALID_DATA",
|
|
160
|
+
errorSite: "PROV-64",
|
|
161
|
+
message: "captcha id mismatch",
|
|
162
|
+
context: { failedFuncName: this.dappUserSolution.name }
|
|
163
|
+
});
|
|
134
164
|
if (!await this.db.updatePendingImageCommitmentStatus(requestHash)) {
|
|
135
165
|
this.logger.info(() => ({ msg: "Request hash already consumed by a concurrent submission" }));
|
|
136
166
|
return response;
|
|
@@ -198,7 +228,11 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
198
228
|
await this.db.storeUserImageCaptchaSolution(receivedCaptchas, commit);
|
|
199
229
|
const solutionRecords = await Promise.all(storedCaptchas.map(async (captcha) => {
|
|
200
230
|
const solutionRecord = await this.db.getSolutionByCaptchaId(captcha.captchaId);
|
|
201
|
-
if (!solutionRecord) throw new _prosopo_common.
|
|
231
|
+
if (!solutionRecord) throw new _prosopo_common.ProsopoError({
|
|
232
|
+
code: "SOLUTION_NOT_FOUND",
|
|
233
|
+
errorSite: "PROV-65",
|
|
234
|
+
context: { failedFuncName: this.dappUserSolution.name }
|
|
235
|
+
});
|
|
202
236
|
return solutionRecord;
|
|
203
237
|
}));
|
|
204
238
|
const totalImages = storedCaptchas[0]?.items.length || 0;
|
|
@@ -276,14 +310,24 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
276
310
|
const receivedCaptchas = (0, _prosopo_datasets.parseAndSortCaptchaSolutions)(captchas);
|
|
277
311
|
const captchaIds = receivedCaptchas.map((captcha) => captcha.captchaId);
|
|
278
312
|
const storedCaptchas = await this.db.getCaptchaById(captchaIds);
|
|
279
|
-
if (!storedCaptchas || receivedCaptchas.length !== storedCaptchas.length) throw new _prosopo_common.
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
313
|
+
if (!storedCaptchas || receivedCaptchas.length !== storedCaptchas.length) throw new _prosopo_common.ProsopoError({
|
|
314
|
+
code: "INVALID_DATA",
|
|
315
|
+
errorSite: "PROV-66",
|
|
316
|
+
message: "Invalid captcha id",
|
|
317
|
+
context: {
|
|
318
|
+
failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
|
|
319
|
+
captchas
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
if (!storedCaptchas.every((captcha) => captcha.datasetId === (0, _prosopo_util.at)(storedCaptchas, 0).datasetId)) throw new _prosopo_common.ProsopoError({
|
|
323
|
+
code: "INVALID_DATA",
|
|
324
|
+
errorSite: "PROV-67",
|
|
325
|
+
message: "Dataset ids do not match",
|
|
326
|
+
context: {
|
|
327
|
+
failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
|
|
328
|
+
captchas
|
|
329
|
+
}
|
|
330
|
+
});
|
|
287
331
|
return {
|
|
288
332
|
storedCaptchas,
|
|
289
333
|
receivedCaptchas,
|
|
@@ -312,10 +356,15 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
312
356
|
}
|
|
313
357
|
async getDappUserCommitmentById(commitmentId) {
|
|
314
358
|
const dappUserSolution = await this.db.getDappUserCommitmentById(commitmentId);
|
|
315
|
-
if (!dappUserSolution) throw new _prosopo_common.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
359
|
+
if (!dappUserSolution) throw new _prosopo_common.ProsopoError({
|
|
360
|
+
code: "SOLUTION_NOT_FOUND",
|
|
361
|
+
errorSite: "PROV-68",
|
|
362
|
+
message: "Dapp user solution not found",
|
|
363
|
+
context: {
|
|
364
|
+
failedFuncName: this.getDappUserCommitmentById.name,
|
|
365
|
+
commitmentId
|
|
366
|
+
}
|
|
367
|
+
});
|
|
319
368
|
return dappUserSolution;
|
|
320
369
|
}
|
|
321
370
|
async verifyImageCaptchaSolution(user, dapp, commitmentId, env, maxVerifiedTime, ip, disallowWebView, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled = false, spamFilter, trafficFilter, storeMetadata = false, clientSessionId) {
|
|
@@ -378,8 +427,9 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
378
427
|
};
|
|
379
428
|
failStatus = _prosopo_types.ResultReason.CLIENT_SESSION_MISMATCH;
|
|
380
429
|
}
|
|
430
|
+
const sessionRecord = solution.sessionId ? await this.getSessionRecordWithOriginFallback(solution.sessionId) : void 0;
|
|
381
431
|
if (!failStatus && userAccessRulesStorage) try {
|
|
382
|
-
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, solution, solution.userAccount, solution.headers, solution.coords, solution.ipInfo?.isValid ? solution.ipInfo.countryCode : void 0, solution.ipInfo?.isValid ? solution.ipInfo.asnNumber : void 0);
|
|
432
|
+
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, solution, solution.userAccount, solution.headers, sessionRecord?.decryptedHeadHash, solution.coords, solution.ipInfo?.isValid ? solution.ipInfo.countryCode : void 0, solution.ipInfo?.isValid ? solution.ipInfo.asnNumber : void 0);
|
|
383
433
|
if (blockPolicy) {
|
|
384
434
|
logger.info(() => ({
|
|
385
435
|
msg: "User blocked by access policy in server image verification",
|
|
@@ -462,10 +512,9 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
462
512
|
}));
|
|
463
513
|
}
|
|
464
514
|
}
|
|
465
|
-
const sessionRecord = solution.sessionId ? await this.getSessionRecordWithOriginFallback(solution.sessionId) : void 0;
|
|
466
515
|
const enrichedDnsEvent = await require_enrichDnsEvent.enrichDnsEvent(sessionRecord?.dnsEvent, env.ipInfoService, ip ?? solution.ipInfo?.ip);
|
|
467
516
|
if (!failStatus) {
|
|
468
|
-
const check = await this.resolveTrafficFilterCheck(
|
|
517
|
+
const check = await this.resolveTrafficFilterCheck(solution.ipInfo, trafficFilter, ip ? await env.ipInfoService.lookup(ip) : void 0, enrichedDnsEvent);
|
|
469
518
|
if (check.isBlocked) {
|
|
470
519
|
logger.info(() => ({
|
|
471
520
|
msg: "Traffic filter rejected request",
|
|
@@ -17,10 +17,15 @@ var nativeMerkle = (() => {
|
|
|
17
17
|
* CaptchaMerkleTree so callers can still generate proofs.
|
|
18
18
|
*/
|
|
19
19
|
var buildTreeAndGetCommitmentId = (captchaSolutions) => {
|
|
20
|
-
if (captchaSolutions.length === 0) throw new _prosopo_common.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
if (captchaSolutions.length === 0) throw new _prosopo_common.ProsopoError({
|
|
21
|
+
code: "RECORD_NOT_FOUND",
|
|
22
|
+
errorSite: "PROV-69",
|
|
23
|
+
message: "Captcha solution commitment does not exist",
|
|
24
|
+
context: {
|
|
25
|
+
failedFuncName: buildTreeAndGetCommitmentId.name,
|
|
26
|
+
commitmentId: null
|
|
27
|
+
}
|
|
28
|
+
});
|
|
24
29
|
const layers = require_metrics.measureSync("merkle_build", () => {
|
|
25
30
|
const solutionsHashed = captchaSolutions.map((captcha) => nativeMerkle.computeCaptchaSolutionHash(captcha.captchaId, captcha.captchaContentId, captcha.solution, captcha.salt));
|
|
26
31
|
return nativeMerkle.buildMerkleLayers(solutionsHashed);
|
|
@@ -28,10 +33,15 @@ var buildTreeAndGetCommitmentId = (captchaSolutions) => {
|
|
|
28
33
|
const tree = new _prosopo_datasets.CaptchaMerkleTree();
|
|
29
34
|
tree.hydrateFromLayers(layers);
|
|
30
35
|
const commitmentId = tree.root?.hash;
|
|
31
|
-
if (!commitmentId) throw new _prosopo_common.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
if (!commitmentId) throw new _prosopo_common.ProsopoError({
|
|
37
|
+
code: "RECORD_NOT_FOUND",
|
|
38
|
+
errorSite: "PROV-70",
|
|
39
|
+
message: "Captcha solution commitment does not exist",
|
|
40
|
+
context: {
|
|
41
|
+
failedFuncName: buildTreeAndGetCommitmentId.name,
|
|
42
|
+
commitmentId
|
|
43
|
+
}
|
|
44
|
+
});
|
|
35
45
|
return {
|
|
36
46
|
tree,
|
|
37
47
|
commitmentId
|
|
@@ -183,18 +183,26 @@ var InteractiveCaptchaManager = class extends require_captchaManager.CaptchaMana
|
|
|
183
183
|
return notVerifiedResponse;
|
|
184
184
|
}
|
|
185
185
|
notVerifiedResponse.sessionId = challengeRecord.sessionId;
|
|
186
|
-
if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.
|
|
187
|
-
code:
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.ProsopoError({
|
|
187
|
+
code: "INVALID_SOLUTION",
|
|
188
|
+
errorSite: "PROV-71",
|
|
189
|
+
context: {
|
|
190
|
+
failedFuncName: this.serverVerifyInteractiveCaptchaSolution.name,
|
|
191
|
+
challenge
|
|
192
|
+
}
|
|
193
|
+
});
|
|
191
194
|
if (challengeRecord.serverChecked) return notVerifiedResponse;
|
|
192
195
|
const challengeDappAccount = challengeRecord.dappAccount;
|
|
193
|
-
if (dappAccount !== challengeDappAccount) throw new _prosopo_common.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
if (dappAccount !== challengeDappAccount) throw new _prosopo_common.ProsopoError({
|
|
197
|
+
code: "SOLUTION_NOT_FOUND",
|
|
198
|
+
errorSite: "PROV-72",
|
|
199
|
+
message: "Dapp user solution not found",
|
|
200
|
+
context: {
|
|
201
|
+
failedFuncName: this.serverVerifyInteractiveCaptchaSolution.name,
|
|
202
|
+
dappAccount,
|
|
203
|
+
challengeDappAccount
|
|
204
|
+
}
|
|
205
|
+
});
|
|
198
206
|
if (!await this.markRecordChecked(challengeRecord.challenge)) return notVerifiedResponse;
|
|
199
207
|
const submittedAt = challengeRecord.submittedAtTimestamp;
|
|
200
208
|
if ((submittedAt instanceof Date ? Date.now() - submittedAt.getTime() : Number.POSITIVE_INFINITY) > timeout) {
|
|
@@ -209,8 +217,9 @@ var InteractiveCaptchaManager = class extends require_captchaManager.CaptchaMana
|
|
|
209
217
|
await this.disapproveVerification(challengeRecord, _prosopo_types.ResultReason.CLIENT_SESSION_MISMATCH);
|
|
210
218
|
return notVerifiedResponse;
|
|
211
219
|
}
|
|
220
|
+
const sessionRecord = challengeRecord.sessionId ? await this.getSessionRecordWithOriginFallback(challengeRecord.sessionId) : void 0;
|
|
212
221
|
if (userAccessRulesStorage) try {
|
|
213
|
-
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, challengeRecord, challengeRecord.userAccount, challengeRecord.headers, challengeRecord.coords, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.asnNumber : void 0);
|
|
222
|
+
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, challengeRecord, challengeRecord.userAccount, challengeRecord.headers, sessionRecord?.decryptedHeadHash, challengeRecord.coords, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.asnNumber : void 0);
|
|
214
223
|
if (blockPolicy) {
|
|
215
224
|
logger.info(() => ({
|
|
216
225
|
msg: `User blocked by access policy in server ${this.logLabel} verification`,
|
|
@@ -268,10 +277,9 @@ var InteractiveCaptchaManager = class extends require_captchaManager.CaptchaMana
|
|
|
268
277
|
}));
|
|
269
278
|
}
|
|
270
279
|
}
|
|
271
|
-
const sessionRecord = challengeRecord.sessionId ? await this.getSessionRecordWithOriginFallback(challengeRecord.sessionId) : void 0;
|
|
272
280
|
const enrichedDnsEvent = await require_enrichDnsEvent.enrichDnsEvent(sessionRecord?.dnsEvent, env.ipInfoService, ip ?? challengeRecord.ipInfo?.ip);
|
|
273
281
|
{
|
|
274
|
-
const check = await this.resolveTrafficFilterCheck(
|
|
282
|
+
const check = await this.resolveTrafficFilterCheck(challengeRecord.ipInfo, trafficFilter, ip ? await env.ipInfoService.lookup(ip) : void 0, enrichedDnsEvent);
|
|
275
283
|
if (check.isBlocked) {
|
|
276
284
|
logger.info(() => ({
|
|
277
285
|
msg: `Traffic filter rejected request in ${this.logLabel} verification`,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/tasks/powCaptcha/backgroundWrites.ts
|
|
2
|
+
/**
|
|
3
|
+
* Lets writes finish after the response, but once `limit` are still pending
|
|
4
|
+
* the caller waits for its own, so a slow database cannot pile them up.
|
|
5
|
+
*/
|
|
6
|
+
var BackgroundWrites = class {
|
|
7
|
+
constructor(limit) {
|
|
8
|
+
this.limit = limit;
|
|
9
|
+
this.pending = 0;
|
|
10
|
+
}
|
|
11
|
+
async add(writes, onError) {
|
|
12
|
+
const settled = writes.then(() => void 0, onError);
|
|
13
|
+
if (this.pending >= this.limit) {
|
|
14
|
+
await settled;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
this.pending++;
|
|
18
|
+
settled.finally(() => {
|
|
19
|
+
this.pending--;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
exports.BackgroundWrites = BackgroundWrites;
|
|
@@ -11,6 +11,7 @@ const require_frictionlessTasksUtils = require("../frictionless/frictionlessTask
|
|
|
11
11
|
const require_powTasksUtils = require("./powTasksUtils.cjs");
|
|
12
12
|
const require_evaluateEmailSpamRules = require("../spam/evaluateEmailSpamRules.cjs");
|
|
13
13
|
const require_routingMachine = require("../frictionless/routingMachine.cjs");
|
|
14
|
+
const require_backgroundWrites = require("./backgroundWrites.cjs");
|
|
14
15
|
let _prosopo_common = require("@prosopo/common");
|
|
15
16
|
let _prosopo_types = require("@prosopo/types");
|
|
16
17
|
let _polkadot_util = require("@polkadot/util");
|
|
@@ -18,6 +19,7 @@ let _prosopo_user_access_policy = require("@prosopo/user-access-policy");
|
|
|
18
19
|
let _prosopo_util = require("@prosopo/util");
|
|
19
20
|
//#region src/tasks/powCaptcha/powTasks.ts
|
|
20
21
|
var DEFAULT_POW_DIFFICULTY = 4;
|
|
22
|
+
var verifyOutcomeWrites = new require_backgroundWrites.BackgroundWrites(500);
|
|
21
23
|
var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
22
24
|
constructor(db, pair, config, logger, writeQueue, usageCounters) {
|
|
23
25
|
super(db, pair, config, logger, writeQueue);
|
|
@@ -65,7 +67,7 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
65
67
|
* @param behavioralData
|
|
66
68
|
* @param salt
|
|
67
69
|
*/
|
|
68
|
-
async verifyPowCaptchaSolution(challenge, providerChallengeSignature, nonce, timeout, userTimestampSignature, ipAddress, headers, behavioralData, salt, simdReadings, clientMetaData) {
|
|
70
|
+
async verifyPowCaptchaSolution(challenge, providerChallengeSignature, nonce, timeout, userTimestampSignature, ipAddress, headers, behavioralData, salt, simdReadings, clientMetaData, fingerprintSummary) {
|
|
69
71
|
require_powTasksUtils.checkPowSignature(challenge, providerChallengeSignature, this.pair.address, _prosopo_types.ApiParams.challenge);
|
|
70
72
|
const challengeSplit = challenge.split(this.POW_SEPARATOR);
|
|
71
73
|
const timestamp = Number.parseInt((0, _prosopo_util.at)(challengeSplit, 0));
|
|
@@ -134,7 +136,7 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
134
136
|
};
|
|
135
137
|
if (correct && this.usageCounters) {
|
|
136
138
|
const dappAccount = (0, _prosopo_util.at)(challengeSplit, 2);
|
|
137
|
-
this.usageCounters.incrManyAsync(dappAccount, require_usageCounters.buildAllWindowIncrements("solved", _prosopo_types.CaptchaType.pow, ipAddress.address, userAccount));
|
|
139
|
+
this.usageCounters.incrManyAsync(dappAccount, require_usageCounters.buildAllWindowIncrements("solved", _prosopo_types.CaptchaType.pow, ipAddress.address, userAccount, void 0, fingerprintSummary?.bucketId));
|
|
138
140
|
}
|
|
139
141
|
let behavioralUpdates = {};
|
|
140
142
|
let decryptedBehavioralDataPacked;
|
|
@@ -180,6 +182,7 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
180
182
|
}));
|
|
181
183
|
}
|
|
182
184
|
const recordUpdates = { ...behavioralUpdates };
|
|
185
|
+
if (fingerprintSummary) recordUpdates.fingerprintSummary = fingerprintSummary;
|
|
183
186
|
const storedClientMetaData = require_clientMetaData.toStoredClientMetaData(clientMetaData);
|
|
184
187
|
if (storedClientMetaData) recordUpdates.clientMetaData = storedClientMetaData;
|
|
185
188
|
if (Object.keys(recordUpdates).length > 0) await this.db.updatePowCaptchaRecord(challenge, recordUpdates);
|
|
@@ -294,8 +297,10 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
294
297
|
* @param clientSessionId - the session id the site rendered the widget
|
|
295
298
|
* with. When supplied, the solve must carry the same value in its
|
|
296
299
|
* `clientMetaData` or it is disapproved.
|
|
300
|
+
* @param ipValidationRules - the site's rules for comparing `ip` with the
|
|
301
|
+
* ip the challenge was issued to.
|
|
297
302
|
*/
|
|
298
|
-
async serverVerifyPowCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled = false, spamFilter, trafficFilter, storeMetadata = false, clientSessionId) {
|
|
303
|
+
async serverVerifyPowCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled = false, spamFilter, trafficFilter, storeMetadata = false, clientSessionId, ipValidationRules) {
|
|
299
304
|
const notVerified = (reason, sessionId) => ({
|
|
300
305
|
verified: false,
|
|
301
306
|
reason,
|
|
@@ -310,18 +315,26 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
310
315
|
logger.debug(() => ({ msg: `No record of this challenge: ${challenge}` }));
|
|
311
316
|
return notVerified("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND");
|
|
312
317
|
}
|
|
313
|
-
if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.
|
|
314
|
-
code:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
+
if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.ProsopoError({
|
|
319
|
+
code: "INVALID_SOLUTION",
|
|
320
|
+
errorSite: "PROV-73",
|
|
321
|
+
context: {
|
|
322
|
+
failedFuncName: this.serverVerifyPowCaptchaSolution.name,
|
|
323
|
+
challenge
|
|
324
|
+
}
|
|
325
|
+
});
|
|
318
326
|
if (challengeRecord.serverChecked) return notVerified("API.USER_ALREADY_VERIFIED", challengeRecord.sessionId);
|
|
319
327
|
const challengeDappAccount = challengeRecord.dappAccount;
|
|
320
|
-
if (dappAccount !== challengeDappAccount) throw new _prosopo_common.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
328
|
+
if (dappAccount !== challengeDappAccount) throw new _prosopo_common.ProsopoError({
|
|
329
|
+
code: "SOLUTION_NOT_FOUND",
|
|
330
|
+
errorSite: "PROV-74",
|
|
331
|
+
message: "Dapp user solution not found",
|
|
332
|
+
context: {
|
|
333
|
+
failedFuncName: this.serverVerifyPowCaptchaSolution.name,
|
|
334
|
+
dappAccount,
|
|
335
|
+
challengeDappAccount
|
|
336
|
+
}
|
|
337
|
+
});
|
|
325
338
|
if (await this.db.markDappUserPoWCommitmentsChecked([challengeRecord.challenge]) === 0) return notVerified("API.USER_ALREADY_VERIFIED", challengeRecord.sessionId);
|
|
326
339
|
const powRecordUpdates = {};
|
|
327
340
|
let failResult;
|
|
@@ -346,8 +359,16 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
346
359
|
};
|
|
347
360
|
failReason = "API.CLIENT_SESSION_MISMATCH";
|
|
348
361
|
}
|
|
362
|
+
const sessionRecordRead = challengeRecord.sessionId ? this.getSessionRecordWithOriginFallback(challengeRecord.sessionId) : Promise.resolve(void 0);
|
|
363
|
+
const enrichedDnsEventRead = sessionRecordRead.then((sessionRecord) => require_enrichDnsEvent.enrichDnsEvent(sessionRecord?.dnsEvent, env.ipInfoService, ip ?? challengeRecord.ipInfo?.ip));
|
|
364
|
+
const currentIpInfoRead = ip && !failResult ? env.ipInfoService.lookup(ip) : Promise.resolve(void 0);
|
|
365
|
+
for (const read of [
|
|
366
|
+
sessionRecordRead,
|
|
367
|
+
enrichedDnsEventRead,
|
|
368
|
+
currentIpInfoRead
|
|
369
|
+
]) read.catch(() => void 0);
|
|
349
370
|
if (!failResult && userAccessRulesStorage) try {
|
|
350
|
-
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, challengeRecord, challengeRecord.userAccount, challengeRecord.headers, challengeRecord.coords, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.asnNumber : void 0);
|
|
371
|
+
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, challengeRecord, challengeRecord.userAccount, challengeRecord.headers, (await sessionRecordRead)?.decryptedHeadHash, challengeRecord.coords, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.asnNumber : void 0);
|
|
351
372
|
if (blockPolicy) {
|
|
352
373
|
logger.info(() => ({
|
|
353
374
|
msg: "User blocked by access policy in server PoW verification",
|
|
@@ -429,10 +450,10 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
429
450
|
}));
|
|
430
451
|
}
|
|
431
452
|
}
|
|
432
|
-
const sessionRecord =
|
|
433
|
-
const enrichedDnsEvent = await
|
|
453
|
+
const sessionRecord = await sessionRecordRead;
|
|
454
|
+
const enrichedDnsEvent = await enrichedDnsEventRead;
|
|
434
455
|
if (!failResult) {
|
|
435
|
-
const check = await this.resolveTrafficFilterCheck(
|
|
456
|
+
const check = await this.resolveTrafficFilterCheck(challengeRecord.ipInfo, trafficFilter, await currentIpInfoRead, enrichedDnsEvent);
|
|
436
457
|
if (check.isBlocked) {
|
|
437
458
|
logger.info(() => ({
|
|
438
459
|
msg: "Traffic filter rejected request in PoW verification",
|
|
@@ -459,7 +480,6 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
459
480
|
};
|
|
460
481
|
if (!failResult && ip) {
|
|
461
482
|
const challengeIpAddress = require_compositeIpAddress.getIpAddressFromComposite(challengeRecord.ipAddress);
|
|
462
|
-
const ipValidationRules = (await this.db.getClientRecord(dappAccount))?.settings?.ipValidationRules;
|
|
463
483
|
powRecordUpdates.providedIp = require_compositeIpAddress.getCompositeIpAddress(ip);
|
|
464
484
|
if (ipValidationRules?.enabled === true) {
|
|
465
485
|
const ipValidation = await require_util.deepValidateIpAddress(ip, challengeIpAddress, logger, env.ipInfoService, ipValidationRules, enrichedDnsEvent?.peerIp);
|
|
@@ -569,7 +589,12 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
569
589
|
...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.pow, finalResult) && { blocked: true },
|
|
570
590
|
...matchedRule && { matchedRule }
|
|
571
591
|
}, true));
|
|
572
|
-
|
|
592
|
+
await verifyOutcomeWrites.add(Promise.all(writePromises), (err) => {
|
|
593
|
+
logger.error(() => ({
|
|
594
|
+
msg: "Failed to record the outcome of a PoW verification",
|
|
595
|
+
err
|
|
596
|
+
}));
|
|
597
|
+
});
|
|
573
598
|
if (failReason) return notVerified(failReason, challengeRecord.sessionId);
|
|
574
599
|
return {
|
|
575
600
|
verified: true,
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
+
const require_signatureCheck = require("../signatureCheck.cjs");
|
|
1
2
|
let _prosopo_common = require("@prosopo/common");
|
|
2
|
-
let _polkadot_util = require("@polkadot/util");
|
|
3
3
|
let _prosopo_util = require("@prosopo/util");
|
|
4
|
-
let _prosopo_util_crypto = require("@prosopo/util-crypto");
|
|
5
4
|
let _noble_hashes_sha2_js = require("@noble/hashes/sha2.js");
|
|
6
5
|
//#region src/tasks/powCaptcha/powTasksUtils.ts
|
|
7
6
|
var validateSolution = (nonce, challenge, difficulty) => (0, _prosopo_util.hashMeetsDifficulty)((0, _noble_hashes_sha2_js.sha256)(new TextEncoder().encode(nonce + challenge)), difficulty);
|
|
8
7
|
var checkPowSignature = (message, signature, address, signatureType) => {
|
|
9
|
-
if (!
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
if (!require_signatureCheck.isSignatureValid(message, signature, address)) throw new _prosopo_common.ProsopoError({
|
|
9
|
+
code: "UNAUTHORIZED",
|
|
10
|
+
errorSite: "PROV-75",
|
|
11
|
+
message: "Invalid signature",
|
|
12
|
+
context: {
|
|
13
|
+
ERROR: `Signature is invalid for this message: ${signatureType}`,
|
|
14
|
+
failedFuncName: checkPowSignature.name,
|
|
15
|
+
address,
|
|
16
|
+
message,
|
|
17
|
+
signature,
|
|
18
|
+
signatureType
|
|
19
|
+
}
|
|
20
|
+
});
|
|
17
21
|
};
|
|
18
22
|
var isCoordsAllZero = (coords) => coords !== void 0 && coords.length > 0 && coords.every((group) => group.length > 0 && group.every(([x, y]) => x === 0 && y === 0));
|
|
19
23
|
//#endregion
|
|
@@ -46,13 +46,9 @@ var resolvePuzzleRenderSettings = (...overrides) => {
|
|
|
46
46
|
var pieceSizeSampler = require_stratifiedSampler.createStratifiedSampler();
|
|
47
47
|
/**
|
|
48
48
|
* Resolve the effective piece scale range from the same layered
|
|
49
|
-
* client-settings / traffic-filter overrides used for render settings
|
|
50
|
-
* draw a per-challenge piece size in pixels. Stratified so the distribution
|
|
51
|
-
* is evenly spread across the range even for short bursts of requests.
|
|
52
|
-
* Rounded to an integer because the pixel buffer is allocated as
|
|
53
|
-
* `size * size * 4`.
|
|
49
|
+
* client-settings / traffic-filter overrides used for render settings.
|
|
54
50
|
*/
|
|
55
|
-
var
|
|
51
|
+
var resolvePuzzlePieceScaleRange = (...overrides) => {
|
|
56
52
|
let min = _prosopo_types.puzzlePieceScaleMinDefault;
|
|
57
53
|
let max = _prosopo_types.puzzlePieceScaleMaxDefault;
|
|
58
54
|
for (const override of overrides) {
|
|
@@ -61,7 +57,19 @@ var resolvePuzzlePieceSize = (...overrides) => {
|
|
|
61
57
|
if (override.pieceScale.max !== void 0) max = override.pieceScale.max;
|
|
62
58
|
}
|
|
63
59
|
if (min > max) min = max;
|
|
64
|
-
|
|
60
|
+
return {
|
|
61
|
+
min,
|
|
62
|
+
max
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Draw a per-challenge piece size in pixels from a scale range. Stratified so
|
|
67
|
+
* the distribution is evenly spread across the range even for short bursts of
|
|
68
|
+
* requests. Rounded to an integer because the pixel buffer is allocated as
|
|
69
|
+
* `size * size * 4`.
|
|
70
|
+
*/
|
|
71
|
+
var samplePuzzlePieceSize = (range) => {
|
|
72
|
+
const scale = pieceSizeSampler.sample(range.min, range.max);
|
|
65
73
|
return Math.max(1, Math.round(_prosopo_puzzle_assets.DEFAULT_GEOMETRY.width * scale));
|
|
66
74
|
};
|
|
67
75
|
/**
|
|
@@ -94,5 +102,6 @@ var renderPuzzleImages = async (placement, settings = _prosopo_puzzle_assets.DEF
|
|
|
94
102
|
//#endregion
|
|
95
103
|
exports.isPuzzleRenderAvailable = isPuzzleRenderAvailable;
|
|
96
104
|
exports.renderPuzzleImages = renderPuzzleImages;
|
|
97
|
-
exports.
|
|
105
|
+
exports.resolvePuzzlePieceScaleRange = resolvePuzzlePieceScaleRange;
|
|
98
106
|
exports.resolvePuzzleRenderSettings = resolvePuzzleRenderSettings;
|
|
107
|
+
exports.samplePuzzlePieceSize = samplePuzzlePieceSize;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
let _polkadot_util = require("@polkadot/util");
|
|
2
|
+
let _prosopo_util_crypto = require("@prosopo/util-crypto");
|
|
3
|
+
//#region src/tasks/signatureCheck.ts
|
|
4
|
+
var isSignatureValid = (message, signature, address) => {
|
|
5
|
+
try {
|
|
6
|
+
return (0, _prosopo_util_crypto.signatureVerify)((0, _polkadot_util.stringToHex)(message), signature, address).isValid;
|
|
7
|
+
} catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
exports.isSignatureValid = isSignatureValid;
|
package/dist/cjs/tasks/tasks.cjs
CHANGED
|
@@ -23,7 +23,12 @@ var Tasks = class {
|
|
|
23
23
|
this.db = env.getDb();
|
|
24
24
|
this.captchaConfig = env.config.captchas;
|
|
25
25
|
this.logger = logger || (0, _prosopo_logger.getLogger)((0, _prosopo_logger.parseLogLevel)(env.config.logLevel), "Tasks");
|
|
26
|
-
if (!env.pair) throw new _prosopo_common.
|
|
26
|
+
if (!env.pair) throw new _prosopo_common.ProsopoError({
|
|
27
|
+
code: "CONFIG_INVALID",
|
|
28
|
+
errorSite: "PROV-76",
|
|
29
|
+
message: "Missing provider pair",
|
|
30
|
+
context: { failedFuncName: "Tasks.constructor" }
|
|
31
|
+
});
|
|
27
32
|
this.pair = env.pair;
|
|
28
33
|
if (this.config.mongoCaptchaUri && this.db instanceof _prosopo_database.ProviderDatabase && !this.db.hasCentralDbStreamer()) {
|
|
29
34
|
const streamer = new _prosopo_database.CentralDbStreamer(this.config.mongoCaptchaUri, this.logger);
|
|
@@ -152,10 +152,15 @@ var UsageCounters = class {
|
|
|
152
152
|
}
|
|
153
153
|
};
|
|
154
154
|
/**
|
|
155
|
-
* Helper: produce the standard
|
|
156
|
-
*
|
|
155
|
+
* Helper: produce the standard served/solved write set for a given captcha
|
|
156
|
+
* challenge. Used by both served (post-session) and solved hooks.
|
|
157
|
+
*
|
|
158
|
+
* `deviceBucket` is only written when the caller knows one, which for now is
|
|
159
|
+
* the PoW solve path with a verified proof of fingerprint. Omitting it leaves
|
|
160
|
+
* the key absent rather than at zero, so a bucket's count is over the requests
|
|
161
|
+
* that actually proved it.
|
|
157
162
|
*/
|
|
158
|
-
var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp) => {
|
|
163
|
+
var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp, deviceBucket) => {
|
|
159
164
|
const out = [];
|
|
160
165
|
for (const window of [
|
|
161
166
|
"1m",
|
|
@@ -191,6 +196,15 @@ var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp) => {
|
|
|
191
196
|
},
|
|
192
197
|
value: peerIp
|
|
193
198
|
});
|
|
199
|
+
if (deviceBucket) out.push({
|
|
200
|
+
spec: {
|
|
201
|
+
kind,
|
|
202
|
+
captchaType,
|
|
203
|
+
dimension: "deviceBucket",
|
|
204
|
+
window
|
|
205
|
+
},
|
|
206
|
+
value: deviceBucket
|
|
207
|
+
});
|
|
194
208
|
if (captchaType !== "any") {
|
|
195
209
|
out.push({
|
|
196
210
|
spec: {
|
|
@@ -218,6 +232,15 @@ var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp) => {
|
|
|
218
232
|
},
|
|
219
233
|
value: peerIp
|
|
220
234
|
});
|
|
235
|
+
if (deviceBucket) out.push({
|
|
236
|
+
spec: {
|
|
237
|
+
kind,
|
|
238
|
+
captchaType: "any",
|
|
239
|
+
dimension: "deviceBucket",
|
|
240
|
+
window
|
|
241
|
+
},
|
|
242
|
+
value: deviceBucket
|
|
243
|
+
});
|
|
221
244
|
}
|
|
222
245
|
}
|
|
223
246
|
return out;
|