@prosopo/provider 5.19.4 → 5.20.1
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 +40 -36
- package/.turbo/turbo-build$colon$tsc.log +28 -28
- package/.turbo/turbo-build.log +43 -36
- package/CHANGELOG.md +155 -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 +20 -25
- 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/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 +23 -25
- 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 +19 -24
- package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +31 -42
- package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +26 -31
- 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 +22 -24
- 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/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/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/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/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/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/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/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/package.json +44 -43
package/dist/cjs/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ exports.getIpAddressFromComposite = require_compositeIpAddress.getIpAddressFromC
|
|
|
45
45
|
exports.getJA4 = require_ja4Middleware.getJA4;
|
|
46
46
|
exports.getPrioritisedAccessRule = require_blacklistRequestInspector.getPrioritisedAccessRule;
|
|
47
47
|
exports.getRequestUserScope = require_blacklistRequestInspector.getRequestUserScope;
|
|
48
|
+
exports.getServerVerifyPaths = require_startProviderApi.getServerVerifyPaths;
|
|
48
49
|
exports.getUserFromJWT = require_startProviderApi.getUserFromJWT;
|
|
49
50
|
exports.getVerdictCache = require_blacklistRequestInspector.getVerdictCache;
|
|
50
51
|
exports.handshakeTimingMiddleware = require_handshakeTimingMiddleware.handshakeTimingMiddleware;
|
|
@@ -552,9 +552,7 @@ var CaptchaManager = class CaptchaManager {
|
|
|
552
552
|
*
|
|
553
553
|
* @returns The blocking policy if user should be blocked, undefined otherwise
|
|
554
554
|
*/
|
|
555
|
-
async checkForHardBlock(userAccessRulesStorage, challengeRecord, userAccount, headers, coords, countryCode, asn) {
|
|
556
|
-
let headHash;
|
|
557
|
-
if (challengeRecord.sessionId) headHash = (await this.db.getSessionRecordBySessionId(challengeRecord.sessionId))?.decryptedHeadHash;
|
|
555
|
+
async checkForHardBlock(userAccessRulesStorage, challengeRecord, userAccount, headers, headHash, coords, countryCode, asn) {
|
|
558
556
|
const coordsString = coords ? JSON.stringify(coords) : void 0;
|
|
559
557
|
const ipAddressRecord = require_compositeIpAddress.getIpAddressFromComposite(challengeRecord.ipAddress);
|
|
560
558
|
const userScope = require_blacklistRequestInspector.getRequestUserScope(headers, challengeRecord.ja4, ipAddressRecord.address, userAccount, headHash, coordsString, countryCode, asn);
|
|
@@ -581,8 +579,9 @@ var CaptchaManager = class CaptchaManager {
|
|
|
581
579
|
* time (ipInfoMiddleware → storeXxxRecord), so by default we reuse it
|
|
582
580
|
* instead of hitting the sidecar again.
|
|
583
581
|
* - If the dapp's server passed up the end user's current IP via the
|
|
584
|
-
* verify call,
|
|
585
|
-
*
|
|
582
|
+
* verify call, the caller looks that up fresh and passes the result as
|
|
583
|
+
* `currentIpInfo` — it's the "now" IP for filtering and may differ from
|
|
584
|
+
* the IP that originally requested the captcha.
|
|
586
585
|
* - When the session carries a `dnsEvent`, its `peerIp` and `resolverIp`
|
|
587
586
|
* are enriched and passed alongside the primary IP.
|
|
588
587
|
* - The abuser category defaults to `{action:"block"}` so abusive
|
|
@@ -595,7 +594,7 @@ var CaptchaManager = class CaptchaManager {
|
|
|
595
594
|
* updates record / session state differently); this helper just returns
|
|
596
595
|
* the verdict.
|
|
597
596
|
*/
|
|
598
|
-
async resolveTrafficFilterCheck(
|
|
597
|
+
async resolveTrafficFilterCheck(recordIpInfo, trafficFilter, currentIpInfo, enrichedDnsEvent) {
|
|
599
598
|
const effective = {
|
|
600
599
|
abuser: { action: _prosopo_types.TrafficFilterAction.Block },
|
|
601
600
|
...trafficFilter
|
|
@@ -604,8 +603,7 @@ var CaptchaManager = class CaptchaManager {
|
|
|
604
603
|
isBlocked: false,
|
|
605
604
|
matches: []
|
|
606
605
|
};
|
|
607
|
-
|
|
608
|
-
return require_checkTrafficFilter.checkTrafficFilter(ipInfo, effective, require_enrichDnsEvent.extraIpInfosFromEnrichedDnsEvent(enrichedDnsEvent), enrichedDnsEvent?.pathValid);
|
|
606
|
+
return require_checkTrafficFilter.checkTrafficFilter(currentIpInfo ?? recordIpInfo, effective, require_enrichDnsEvent.extraIpInfosFromEnrichedDnsEvent(enrichedDnsEvent), enrichedDnsEvent?.pathValid);
|
|
609
607
|
}
|
|
610
608
|
/**
|
|
611
609
|
* Does this client's tier entitle it to the bot score, and is there one?
|
|
@@ -126,9 +126,11 @@ var ClientTaskManager = class {
|
|
|
126
126
|
if (newClientRecords) await this.providerDB.updateClientRecords(newClientRecords);
|
|
127
127
|
await this.providerDB.updateScheduledTaskStatus(taskID, _prosopo_types.ScheduledTaskStatus.Completed, { data: { clientRecords: newClientRecords.length } });
|
|
128
128
|
} catch (e) {
|
|
129
|
-
const getClientListError = new _prosopo_common.
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
const getClientListError = new _prosopo_common.ProsopoError({
|
|
130
|
+
code: "DB_QUERY_FAILED",
|
|
131
|
+
errorSite: "PROV-51",
|
|
132
|
+
message: "Unknown database error",
|
|
133
|
+
cause: e
|
|
132
134
|
});
|
|
133
135
|
this.logger.error(() => ({
|
|
134
136
|
err: getClientListError,
|
|
@@ -170,12 +172,14 @@ var ClientTaskManager = class {
|
|
|
170
172
|
await this.providerDB.removeClientRecords(accounts);
|
|
171
173
|
}
|
|
172
174
|
async updateDecisionMachine(scope, runtime, source, dappAccount, language, name, version, captchaType, kind) {
|
|
173
|
-
if (scope === _prosopo_types.DecisionMachineScope.Dapp && !dappAccount) throw new _prosopo_common.
|
|
175
|
+
if (scope === _prosopo_types.DecisionMachineScope.Dapp && !dappAccount) throw new _prosopo_common.ProsopoError({
|
|
176
|
+
code: "INVALID_REQUEST",
|
|
177
|
+
errorSite: "PROV-52",
|
|
178
|
+
message: "BadRequest",
|
|
174
179
|
context: {
|
|
175
180
|
scope,
|
|
176
181
|
dappAccount
|
|
177
|
-
}
|
|
178
|
-
logger: this.logger
|
|
182
|
+
}
|
|
179
183
|
});
|
|
180
184
|
const now = /* @__PURE__ */ new Date();
|
|
181
185
|
await this.providerDB.upsertDecisionMachineArtifact({
|
|
@@ -218,9 +222,11 @@ var ClientTaskManager = class {
|
|
|
218
222
|
}
|
|
219
223
|
async getDecisionMachine(id) {
|
|
220
224
|
const artifact = await this.providerDB.getDecisionMachineArtifactById(id);
|
|
221
|
-
if (!artifact) throw new _prosopo_common.
|
|
222
|
-
|
|
223
|
-
|
|
225
|
+
if (!artifact) throw new _prosopo_common.ProsopoError({
|
|
226
|
+
code: "INVALID_REQUEST",
|
|
227
|
+
errorSite: "PROV-53",
|
|
228
|
+
message: "BadRequest",
|
|
229
|
+
context: { id }
|
|
224
230
|
});
|
|
225
231
|
return {
|
|
226
232
|
_id: artifact._id.toString(),
|
|
@@ -239,22 +245,29 @@ var ClientTaskManager = class {
|
|
|
239
245
|
}
|
|
240
246
|
async removeDecisionMachine(id) {
|
|
241
247
|
const success = await this.providerDB.removeDecisionMachineArtifact(id);
|
|
242
|
-
if (!success) throw new _prosopo_common.
|
|
248
|
+
if (!success) throw new _prosopo_common.ProsopoError({
|
|
249
|
+
code: "INVALID_REQUEST",
|
|
250
|
+
errorSite: "PROV-54",
|
|
251
|
+
message: "BadRequest",
|
|
243
252
|
context: {
|
|
244
253
|
id,
|
|
245
254
|
message: "Decision machine not found"
|
|
246
|
-
}
|
|
247
|
-
logger: this.logger
|
|
255
|
+
}
|
|
248
256
|
});
|
|
257
|
+
require_decisionMachineRunner.invalidateAllDecisionMachineArtifactCaches();
|
|
258
|
+
require_decisionMachineRunner.invalidateDecisionMachineScriptCache();
|
|
249
259
|
return {
|
|
250
260
|
success,
|
|
251
261
|
deletedId: id
|
|
252
262
|
};
|
|
253
263
|
}
|
|
254
264
|
async removeAllDecisionMachines() {
|
|
265
|
+
const deletedCount = await this.providerDB.removeAllDecisionMachineArtifacts();
|
|
266
|
+
require_decisionMachineRunner.invalidateAllDecisionMachineArtifactCaches();
|
|
267
|
+
require_decisionMachineRunner.invalidateDecisionMachineScriptCache();
|
|
255
268
|
return {
|
|
256
269
|
success: true,
|
|
257
|
-
deletedCount
|
|
270
|
+
deletedCount
|
|
258
271
|
};
|
|
259
272
|
}
|
|
260
273
|
/**
|
|
@@ -2,16 +2,36 @@ let _prosopo_common = require("@prosopo/common");
|
|
|
2
2
|
let _prosopo_datasets = require("@prosopo/datasets");
|
|
3
3
|
//#region src/tasks/dataset/datasetTasksUtils.ts
|
|
4
4
|
var providerValidateDataset = async (datasetRaw, minSolvedCaptchas, minUnsolvedCaptchas) => {
|
|
5
|
-
if (datasetRaw.captchas.length < minSolvedCaptchas + minUnsolvedCaptchas) throw new _prosopo_common.
|
|
5
|
+
if (datasetRaw.captchas.length < minSolvedCaptchas + minUnsolvedCaptchas) throw new _prosopo_common.ProsopoError({
|
|
6
|
+
code: "DATASET_INVALID",
|
|
7
|
+
errorSite: "PROV-55",
|
|
8
|
+
message: "Number of captchas in dataset is less than configured number of captchas",
|
|
9
|
+
context: { failedFuncName: providerValidateDataset.name }
|
|
10
|
+
});
|
|
6
11
|
const solutions = datasetRaw.captchas.map((captcha) => captcha.solution ? 1 : 0).reduce((partialSum, b) => partialSum + b, 0);
|
|
7
|
-
if (solutions < minSolvedCaptchas) throw new _prosopo_common.
|
|
8
|
-
|
|
12
|
+
if (solutions < minSolvedCaptchas) throw new _prosopo_common.ProsopoError({
|
|
13
|
+
code: "DATASET_INVALID",
|
|
14
|
+
errorSite: "PROV-56",
|
|
15
|
+
message: "Number of solutions in dataset is less than configured number of solutions",
|
|
16
|
+
context: { failedFuncName: providerValidateDataset.name }
|
|
17
|
+
});
|
|
18
|
+
if (datasetRaw.captchas.length - solutions < minUnsolvedCaptchas) throw new _prosopo_common.ProsopoError({
|
|
19
|
+
code: "DATASET_INVALID",
|
|
20
|
+
errorSite: "PROV-57",
|
|
21
|
+
message: "Number of captchas in dataset is less than configured number of captchas",
|
|
22
|
+
context: { failedFuncName: providerValidateDataset.name }
|
|
23
|
+
});
|
|
9
24
|
const dataset = await (0, _prosopo_datasets.buildDataset)(datasetRaw);
|
|
10
|
-
if (!dataset.datasetId || !dataset.datasetContentId) throw new _prosopo_common.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
25
|
+
if (!dataset.datasetId || !dataset.datasetContentId) throw new _prosopo_common.ProsopoError({
|
|
26
|
+
code: "DATASET_INVALID",
|
|
27
|
+
errorSite: "PROV-58",
|
|
28
|
+
message: "Dataset id undefined",
|
|
29
|
+
context: {
|
|
30
|
+
failedFuncName: providerValidateDataset.name,
|
|
31
|
+
datasetId: dataset.datasetId,
|
|
32
|
+
datasetContentId: dataset.datasetContentId
|
|
33
|
+
}
|
|
34
|
+
});
|
|
15
35
|
return dataset;
|
|
16
36
|
};
|
|
17
37
|
//#endregion
|
|
@@ -44,18 +44,20 @@ var ARTIFACT_CACHE_TTL_MS = Number.parseInt(process.env.DECISION_MACHINE_ARTIFAC
|
|
|
44
44
|
var DEFAULT_DECISION = { decision: _prosopo_types.DecisionMachineDecision.Allow };
|
|
45
45
|
var RequiredCountersSchema = zod.z.array(_prosopo_types.CounterSpecSchema);
|
|
46
46
|
/**
|
|
47
|
-
* Bumped by {@link invalidateAllDecisionMachineArtifactCaches}.
|
|
48
|
-
*
|
|
49
|
-
* diverge, which flushes every
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* This replaces a registry of live runners, which assumed runners were built
|
|
53
|
-
* once per process. They are built per request, so the registry grew without
|
|
54
|
-
* bound and construction eventually began to fail. `WeakRef` did not bound
|
|
55
|
-
* it: the set held the wrapper, which outlives its referent.
|
|
47
|
+
* Bumped by {@link invalidateAllDecisionMachineArtifactCaches}. Each cache
|
|
48
|
+
* records the generation it was filled under and is discarded once the two
|
|
49
|
+
* diverge, which flushes every cache without holding a reference to any of
|
|
50
|
+
* them.
|
|
56
51
|
*/
|
|
57
52
|
var artifactCacheGeneration = 0;
|
|
58
53
|
/**
|
|
54
|
+
* Runners are built per request, so a cache owned by the runner never served
|
|
55
|
+
* a second lookup and every decision paid two Mongo reads. The cache lives
|
|
56
|
+
* with the database the runner reads from instead: one per process in
|
|
57
|
+
* production, and still isolated between test doubles.
|
|
58
|
+
*/
|
|
59
|
+
var artifactCaches = /* @__PURE__ */ new WeakMap();
|
|
60
|
+
/**
|
|
59
61
|
* Flush every runner's in-memory artifact cache. Companion to
|
|
60
62
|
* {@link invalidateDecisionMachineScriptCache}. Call both after any
|
|
61
63
|
* `upsertDecisionMachineArtifact` upload.
|
|
@@ -66,19 +68,20 @@ var invalidateAllDecisionMachineArtifactCaches = () => {
|
|
|
66
68
|
var DecisionMachineRunner = class DecisionMachineRunner {
|
|
67
69
|
constructor(db) {
|
|
68
70
|
this.db = db;
|
|
69
|
-
this.artifactCache = /* @__PURE__ */ new Map();
|
|
70
|
-
this.seenArtifactCacheGeneration = artifactCacheGeneration;
|
|
71
71
|
}
|
|
72
|
-
/** Drop every
|
|
72
|
+
/** Drop every cached artifact read from this runner's database. */
|
|
73
73
|
invalidateArtifactCache() {
|
|
74
74
|
this.artifactCache.clear();
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
get artifactCache() {
|
|
77
|
+
const cache = artifactCaches.get(this.db);
|
|
78
|
+
if (cache && cache.generation === artifactCacheGeneration) return cache.entries;
|
|
79
|
+
const fresh = {
|
|
80
|
+
generation: artifactCacheGeneration,
|
|
81
|
+
entries: /* @__PURE__ */ new Map()
|
|
82
|
+
};
|
|
83
|
+
artifactCaches.set(this.db, fresh);
|
|
84
|
+
return fresh.entries;
|
|
82
85
|
}
|
|
83
86
|
/** Build a cache key for a given scope + kind + dappAccount tuple. */
|
|
84
87
|
static cacheKey(scope, kind, dappAccount) {
|
|
@@ -86,7 +89,6 @@ var DecisionMachineRunner = class DecisionMachineRunner {
|
|
|
86
89
|
}
|
|
87
90
|
/** Return a cached artifact if still fresh, or undefined. */
|
|
88
91
|
getCachedArtifact(scope, kind, dappAccount) {
|
|
89
|
-
this.dropArtifactCacheIfStale();
|
|
90
92
|
const entry = this.artifactCache.get(DecisionMachineRunner.cacheKey(scope, kind, dappAccount));
|
|
91
93
|
if (!entry) return null;
|
|
92
94
|
if (Date.now() - entry.cachedAt > ARTIFACT_CACHE_TTL_MS) {
|
|
@@ -56,14 +56,15 @@ var applyRouter = async (runner, counters, baseline, ctx, logger, phase = "route
|
|
|
56
56
|
};
|
|
57
57
|
/**
|
|
58
58
|
* Map machine-declared CounterSpecs onto the values that the provider knows
|
|
59
|
-
* how to read
|
|
60
|
-
*
|
|
59
|
+
* how to read. Specs whose dimension we cannot resolve are silently skipped,
|
|
60
|
+
* so a rule naming `deviceBucket` on a request that disclosed no proof of
|
|
61
|
+
* fingerprint simply does not get that key.
|
|
61
62
|
*/
|
|
62
63
|
var specsToReads = (specs, ctx) => {
|
|
63
64
|
const out = [];
|
|
64
65
|
for (const spec of specs) {
|
|
65
|
-
const value = spec.dimension
|
|
66
|
-
if (value === void 0) continue;
|
|
66
|
+
const value = resolveDimension(spec.dimension, ctx);
|
|
67
|
+
if (value === void 0 || value === "") continue;
|
|
67
68
|
out.push({
|
|
68
69
|
spec,
|
|
69
70
|
value
|
|
@@ -71,5 +72,13 @@ var specsToReads = (specs, ctx) => {
|
|
|
71
72
|
}
|
|
72
73
|
return out;
|
|
73
74
|
};
|
|
75
|
+
var resolveDimension = (dimension, ctx) => {
|
|
76
|
+
switch (dimension) {
|
|
77
|
+
case "ip": return ctx.ip;
|
|
78
|
+
case "userAccount": return ctx.userAccount;
|
|
79
|
+
case "deviceBucket": return ctx.raw.fingerprintSummary?.bucketId;
|
|
80
|
+
case "peerIp": return;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
74
83
|
//#endregion
|
|
75
84
|
exports.applyRouter = applyRouter;
|
|
@@ -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;
|