@prosopo/provider 5.15.0 → 5.17.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 +52 -34
- package/.turbo/turbo-build$colon$tsc.log +36 -30
- package/.turbo/turbo-build.log +53 -35
- package/CHANGELOG.md +94 -0
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts +4 -0
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts.map +1 -1
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js +63 -3
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js.map +1 -1
- package/dist/api/blacklistRequestInspector.js +2 -2
- package/dist/api/captcha/getAudioCaptchaChallenge.d.ts +5 -0
- package/dist/api/captcha/getAudioCaptchaChallenge.d.ts.map +1 -0
- package/dist/api/captcha/getAudioCaptchaChallenge.js +37 -0
- package/dist/api/captcha/getAudioCaptchaChallenge.js.map +1 -0
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.d.ts +1 -0
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js +7 -2
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +17 -12
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.d.ts +7 -2
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.js +14 -4
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js +1 -0
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js.map +1 -1
- package/dist/api/captcha/getIconOrderCaptchaChallenge.d.ts +5 -0
- package/dist/api/captcha/getIconOrderCaptchaChallenge.d.ts.map +1 -0
- package/dist/api/captcha/getIconOrderCaptchaChallenge.js +37 -0
- package/dist/api/captcha/getIconOrderCaptchaChallenge.js.map +1 -0
- package/dist/api/captcha/getImageCaptchaChallenge.js +2 -2
- package/dist/api/captcha/getPoWCaptchaChallenge.js +4 -4
- package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts +1 -3
- package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/getPuzzleCaptchaChallenge.js +55 -170
- package/dist/api/captcha/getPuzzleCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/interactiveCaptchaChallenge.d.ts +42 -0
- package/dist/api/captcha/interactiveCaptchaChallenge.d.ts.map +1 -0
- package/dist/api/captcha/interactiveCaptchaChallenge.js +154 -0
- package/dist/api/captcha/interactiveCaptchaChallenge.js.map +1 -0
- package/dist/api/captcha/interactiveCaptchaSolution.d.ts +14 -0
- package/dist/api/captcha/interactiveCaptchaSolution.d.ts.map +1 -0
- package/dist/api/captcha/interactiveCaptchaSolution.js +77 -0
- package/dist/api/captcha/interactiveCaptchaSolution.js.map +1 -0
- package/dist/api/captcha/maintenanceModeResponses.d.ts +4 -2
- package/dist/api/captcha/maintenanceModeResponses.d.ts.map +1 -1
- package/dist/api/captcha/maintenanceModeResponses.js +28 -1
- package/dist/api/captcha/maintenanceModeResponses.js.map +1 -1
- package/dist/api/captcha/submitAudioCaptchaSolution.d.ts +4 -0
- package/dist/api/captcha/submitAudioCaptchaSolution.d.ts.map +1 -0
- package/dist/api/captcha/submitAudioCaptchaSolution.js +11 -0
- package/dist/api/captcha/submitAudioCaptchaSolution.js.map +1 -0
- package/dist/api/captcha/submitIconOrderCaptchaSolution.d.ts +4 -0
- package/dist/api/captcha/submitIconOrderCaptchaSolution.d.ts.map +1 -0
- package/dist/api/captcha/submitIconOrderCaptchaSolution.js +11 -0
- package/dist/api/captcha/submitIconOrderCaptchaSolution.js.map +1 -0
- package/dist/api/captcha/submitPoWCaptchaSolution.js +2 -2
- package/dist/api/captcha/submitPuzzleCaptchaSolution.d.ts +1 -3
- package/dist/api/captcha/submitPuzzleCaptchaSolution.d.ts.map +1 -1
- package/dist/api/captcha/submitPuzzleCaptchaSolution.js +6 -73
- package/dist/api/captcha/submitPuzzleCaptchaSolution.js.map +1 -1
- package/dist/api/captcha/trafficFilterRequestTime.d.ts +4 -1
- package/dist/api/captcha/trafficFilterRequestTime.d.ts.map +1 -1
- package/dist/api/captcha/trafficFilterRequestTime.js +3 -0
- package/dist/api/captcha/trafficFilterRequestTime.js.map +1 -1
- package/dist/api/captcha.d.ts.map +1 -1
- package/dist/api/captcha.js +8 -0
- package/dist/api/captcha.js.map +1 -1
- package/dist/api/domainMiddleware.js +1 -1
- package/dist/api/ja4Middleware.js +1 -1
- package/dist/api/startProviderApi.js +1 -1
- package/dist/api/verify.d.ts.map +1 -1
- package/dist/api/verify.js +153 -96
- package/dist/api/verify.js.map +1 -1
- package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +65 -2
- package/dist/cjs/api/blacklistRequestInspector.cjs +2 -2
- package/dist/cjs/api/captcha/getAudioCaptchaChallenge.cjs +37 -0
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/constants.cjs +6 -0
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +1 -1
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +15 -10
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.cjs +14 -3
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs +1 -0
- package/dist/cjs/api/captcha/getIconOrderCaptchaChallenge.cjs +37 -0
- package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +2 -2
- package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +4 -4
- package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +54 -169
- package/dist/cjs/api/captcha/interactiveCaptchaChallenge.cjs +154 -0
- package/dist/cjs/api/captcha/interactiveCaptchaSolution.cjs +77 -0
- package/dist/cjs/api/captcha/maintenanceModeResponses.cjs +29 -0
- package/dist/cjs/api/captcha/submitAudioCaptchaSolution.cjs +11 -0
- package/dist/cjs/api/captcha/submitIconOrderCaptchaSolution.cjs +11 -0
- package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +2 -2
- package/dist/cjs/api/captcha/submitPuzzleCaptchaSolution.cjs +6 -73
- package/dist/cjs/api/captcha/trafficFilterRequestTime.cjs +3 -0
- package/dist/cjs/api/captcha.cjs +8 -0
- package/dist/cjs/api/domainMiddleware.cjs +1 -1
- package/dist/cjs/api/ja4Middleware.cjs +1 -1
- package/dist/cjs/api/startProviderApi.cjs +1 -1
- package/dist/cjs/api/verify.cjs +152 -95
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/tasks/audio/audioBuffer.cjs +72 -0
- package/dist/cjs/tasks/audio/audioRenderer.cjs +32 -0
- package/dist/cjs/tasks/audioAlternative.cjs +23 -0
- package/dist/cjs/tasks/audioCaptcha/audioTasks.cjs +65 -0
- package/dist/cjs/tasks/audioCaptcha/audioTasksUtils.cjs +19 -0
- package/dist/cjs/tasks/captchaManager.cjs +14 -2
- package/dist/cjs/tasks/captchaTypeSelection.cjs +20 -3
- package/dist/cjs/tasks/client/clientTasks.cjs +2 -2
- package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +40 -9
- package/dist/cjs/tasks/iconOrder/iconOrderRenderer.cjs +42 -0
- package/dist/cjs/tasks/iconOrderCaptcha/iconOrderTasks.cjs +69 -0
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +8 -8
- package/dist/cjs/tasks/interactiveCaptcha/interactiveCaptchaManager.cjs +423 -0
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +8 -8
- package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +1 -1
- package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +40 -486
- package/dist/cjs/tasks/spam/checkTrafficFilter.cjs +18 -1
- package/dist/cjs/tasks/tasks.cjs +6 -0
- package/dist/cjs/util.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/tasks/audio/audioBuffer.d.ts +23 -0
- package/dist/tasks/audio/audioBuffer.d.ts.map +1 -0
- package/dist/tasks/audio/audioBuffer.js +70 -0
- package/dist/tasks/audio/audioBuffer.js.map +1 -0
- package/dist/tasks/audio/audioRenderer.d.ts +11 -0
- package/dist/tasks/audio/audioRenderer.d.ts.map +1 -0
- package/dist/tasks/audio/audioRenderer.js +31 -0
- package/dist/tasks/audio/audioRenderer.js.map +1 -0
- package/dist/tasks/audioAlternative.d.ts +8 -0
- package/dist/tasks/audioAlternative.d.ts.map +1 -0
- package/dist/tasks/audioAlternative.js +20 -0
- package/dist/tasks/audioAlternative.js.map +1 -0
- package/dist/tasks/audioCaptcha/audioTasks.d.ts +19 -0
- package/dist/tasks/audioCaptcha/audioTasks.d.ts.map +1 -0
- package/dist/tasks/audioCaptcha/audioTasks.js +65 -0
- package/dist/tasks/audioCaptcha/audioTasks.js.map +1 -0
- package/dist/tasks/audioCaptcha/audioTasksUtils.d.ts +3 -0
- package/dist/tasks/audioCaptcha/audioTasksUtils.d.ts.map +1 -0
- package/dist/tasks/audioCaptcha/audioTasksUtils.js +18 -0
- package/dist/tasks/audioCaptcha/audioTasksUtils.js.map +1 -0
- package/dist/tasks/captchaManager.d.ts +9 -3
- package/dist/tasks/captchaManager.d.ts.map +1 -1
- package/dist/tasks/captchaManager.js +15 -3
- package/dist/tasks/captchaManager.js.map +1 -1
- package/dist/tasks/captchaTypeSelection.d.ts +2 -1
- package/dist/tasks/captchaTypeSelection.d.ts.map +1 -1
- package/dist/tasks/captchaTypeSelection.js +21 -5
- package/dist/tasks/captchaTypeSelection.js.map +1 -1
- package/dist/tasks/client/clientTasks.js +2 -2
- package/dist/tasks/frictionless/frictionlessTasks.d.ts +5 -0
- package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.js +41 -10
- package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
- package/dist/tasks/iconOrder/iconOrderRenderer.d.ts +12 -0
- package/dist/tasks/iconOrder/iconOrderRenderer.d.ts.map +1 -0
- package/dist/tasks/iconOrder/iconOrderRenderer.js +40 -0
- package/dist/tasks/iconOrder/iconOrderRenderer.js.map +1 -0
- package/dist/tasks/iconOrderCaptcha/iconOrderTasks.d.ts +22 -0
- package/dist/tasks/iconOrderCaptcha/iconOrderTasks.d.ts.map +1 -0
- package/dist/tasks/iconOrderCaptcha/iconOrderTasks.js +69 -0
- package/dist/tasks/iconOrderCaptcha/iconOrderTasks.js.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +8 -8
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts +52 -0
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts.map +1 -0
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js +423 -0
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasks.js +8 -8
- package/dist/tasks/powCaptcha/powTasksUtils.js +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts +14 -16
- package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js +41 -487
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
- package/dist/tasks/spam/checkTrafficFilter.d.ts +4 -1
- package/dist/tasks/spam/checkTrafficFilter.d.ts.map +1 -1
- package/dist/tasks/spam/checkTrafficFilter.js +18 -1
- package/dist/tasks/spam/checkTrafficFilter.js.map +1 -1
- package/dist/tasks/tasks.d.ts +4 -0
- package/dist/tasks/tasks.d.ts.map +1 -1
- package/dist/tasks/tasks.js +6 -0
- package/dist/tasks/tasks.js.map +1 -1
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +7 -3
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +1 -1
- package/dist/tests/integration/clientSettingsPersistence.integration.test.js +45 -3
- package/dist/tests/integration/clientSettingsPersistence.integration.test.js.map +1 -1
- package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js +4 -2
- package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js.map +1 -1
- package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js +76 -1
- package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/constants.unit.test.js +27 -8
- package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/constants.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.js +29 -3
- package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js +20 -0
- package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js.map +1 -1
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +81 -2
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.js +105 -0
- package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/audioAlternative.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/audioAlternative.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/audioAlternative.unit.test.js +76 -0
- package/dist/tests/unit/tasks/audioAlternative.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.js +259 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.js +52 -0
- package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.js +120 -2
- package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/captchaTypeSelection.unit.test.js +65 -6
- package/dist/tests/unit/tasks/captchaTypeSelection.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.js +29 -0
- package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +31 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.js +27 -2
- package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/frictionless/routerPuzzleOverrides.unit.test.js +28 -0
- package/dist/tests/unit/tasks/frictionless/routerPuzzleOverrides.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.js +60 -0
- package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.js +225 -0
- package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.js.map +1 -0
- package/dist/util.js +1 -1
- package/package.json +19 -17
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
const
|
|
2
|
-
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
3
|
-
const require_rawTlsSignalsMiddleware = require("../../api/rawTlsSignalsMiddleware.cjs");
|
|
4
|
-
const require_clientMetaData = require("../../utils/clientMetaData.cjs");
|
|
5
|
-
const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
|
|
6
|
-
const require_enrichDnsEvent = require("../dnsEvent/enrichDnsEvent.cjs");
|
|
7
|
-
const require_captchaManager = require("../captchaManager.cjs");
|
|
8
|
-
const require_util = require("../../util.cjs");
|
|
9
|
-
const require_devicePlatform = require("../../utils/devicePlatform.cjs");
|
|
10
|
-
const require_frictionlessTasksUtils = require("../frictionless/frictionlessTasksUtils.cjs");
|
|
11
|
-
const require_evaluateEmailSpamRules = require("../spam/evaluateEmailSpamRules.cjs");
|
|
12
|
-
const require_powTasksUtils = require("../powCaptcha/powTasksUtils.cjs");
|
|
1
|
+
const require_interactiveCaptchaManager = require("../interactiveCaptcha/interactiveCaptchaManager.cjs");
|
|
13
2
|
const require_puzzleTasksUtils = require("./puzzleTasksUtils.cjs");
|
|
14
|
-
let _prosopo_common = require("@prosopo/common");
|
|
15
3
|
let _prosopo_types = require("@prosopo/types");
|
|
16
|
-
let _prosopo_util = require("@prosopo/util");
|
|
17
|
-
let _prosopo_user_access_policy = require("@prosopo/user-access-policy");
|
|
18
|
-
let _polkadot_util = require("@polkadot/util");
|
|
19
4
|
//#region src/tasks/puzzleCaptcha/puzzleTasks.ts
|
|
20
|
-
var PuzzleCaptchaManager = class extends
|
|
21
|
-
constructor(
|
|
22
|
-
super(
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
|
|
5
|
+
var PuzzleCaptchaManager = class extends require_interactiveCaptchaManager.InteractiveCaptchaManager {
|
|
6
|
+
constructor(..._args) {
|
|
7
|
+
super(..._args);
|
|
8
|
+
this.captchaType = _prosopo_types.CaptchaType.puzzle;
|
|
9
|
+
this.logLabel = "puzzle";
|
|
10
|
+
}
|
|
11
|
+
getRecordByChallenge(challenge) {
|
|
12
|
+
return this.db.getPuzzleCaptchaRecordByChallenge(challenge);
|
|
13
|
+
}
|
|
14
|
+
updateRecord(challenge, updates) {
|
|
15
|
+
return this.db.updatePuzzleCaptchaRecord(challenge, updates);
|
|
16
|
+
}
|
|
17
|
+
updateSubmissionResult(challenge, result, userSignature, coords) {
|
|
18
|
+
return this.db.updatePuzzleCaptchaRecordResult(challenge, result, false, true, userSignature, coords);
|
|
19
|
+
}
|
|
20
|
+
async claimSubmission(record) {
|
|
21
|
+
return !record.userSubmitted;
|
|
22
|
+
}
|
|
23
|
+
markRecordChecked(challenge) {
|
|
24
|
+
return this.db.markPuzzleCaptchaRecordChecked(challenge);
|
|
25
|
+
}
|
|
26
|
+
decisionMachineEventFields(record) {
|
|
27
|
+
return { puzzleEvents: record.puzzleEvents };
|
|
26
28
|
}
|
|
27
29
|
/**
|
|
28
30
|
* @description Generates a Puzzle Captcha challenge for a given user and dapp
|
|
@@ -33,18 +35,15 @@ var PuzzleCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
33
35
|
* @param tolerance
|
|
34
36
|
*/
|
|
35
37
|
async getPuzzleCaptchaChallenge(userAccount, dappAccount, origin, tolerance) {
|
|
36
|
-
const
|
|
37
|
-
const requestedAtTimestamp = Date.now();
|
|
38
|
-
const challenge = `${requestedAtTimestamp}___${userAccount}___${dappAccount}___${Math.floor(Math.random() * 1e6)}`;
|
|
39
|
-
const challengeSignature = (0, _polkadot_util.u8aToHex)(this.pair.sign((0, _polkadot_util.stringToHex)(challenge)));
|
|
38
|
+
const { challenge, providerSignature, requestedAtTimestamp } = this.mintChallenge(userAccount, dappAccount);
|
|
40
39
|
return {
|
|
41
40
|
challenge,
|
|
42
41
|
targetX: Math.floor(Math.random() * 131) + 150,
|
|
43
42
|
targetY: Math.floor(Math.random() * 141) + 30,
|
|
44
43
|
originX: Math.floor(Math.random() * 111) + 20,
|
|
45
44
|
originY: Math.floor(Math.random() * 141) + 30,
|
|
46
|
-
tolerance:
|
|
47
|
-
providerSignature
|
|
45
|
+
tolerance: tolerance ?? _prosopo_types.puzzleToleranceDefault,
|
|
46
|
+
providerSignature,
|
|
48
47
|
requestedAtTimestamp
|
|
49
48
|
};
|
|
50
49
|
}
|
|
@@ -63,467 +62,22 @@ var PuzzleCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
63
62
|
* @param behavioralData
|
|
64
63
|
*/
|
|
65
64
|
async verifyPuzzleCaptchaSolution(challenge, providerChallengeSignature, finalX, finalY, puzzleEvents, timeout, userTimestampSignature, ipAddress, headers, behavioralData, salt, simdReadings, clientMetaData) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (salt) try {
|
|
79
|
-
const extractedData = (0, _prosopo_util.extractData)(salt);
|
|
80
|
-
if (extractedData.length >= 2) {
|
|
81
|
-
const built = [[[extractedData[0], extractedData[1]]]];
|
|
82
|
-
(0, _prosopo_util.assertCoordsSafe)(built, "coords");
|
|
83
|
-
coords = built;
|
|
84
|
-
}
|
|
85
|
-
} catch (error) {
|
|
86
|
-
saltDecodeError = error;
|
|
87
|
-
this.logger.warn(() => ({
|
|
88
|
-
msg: "Failed to extract coordinates from salt",
|
|
89
|
-
error,
|
|
90
|
-
salt
|
|
91
|
-
}));
|
|
92
|
-
}
|
|
93
|
-
if (challengeRecord.userSubmitted) {
|
|
94
|
-
this.logger.debug(() => ({ msg: `Challenge already submitted: ${challenge}` }));
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
if (saltDecodeError) {
|
|
98
|
-
const badSaltResult = {
|
|
99
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
100
|
-
reason: _prosopo_types.ResultReason.CAPTCHA_INVALID_SALT
|
|
101
|
-
};
|
|
102
|
-
await this.db.updatePuzzleCaptchaRecordResult(challenge, badSaltResult, false, true, userTimestampSignature, void 0);
|
|
103
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
104
|
-
userSubmitted: true,
|
|
105
|
-
result: badSaltResult,
|
|
106
|
-
...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, badSaltResult) && { blocked: true }
|
|
107
|
-
});
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
if (!(0, _prosopo_util.verifyRecency)(challenge, timeout)) {
|
|
111
|
-
const timeoutResult = {
|
|
112
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
113
|
-
reason: _prosopo_types.ResultReason.CAPTCHA_INVALID_TIMESTAMP
|
|
114
|
-
};
|
|
115
|
-
await this.db.updatePuzzleCaptchaRecordResult(challenge, timeoutResult, false, true, userTimestampSignature, coords);
|
|
116
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
117
|
-
userSubmitted: true,
|
|
118
|
-
result: timeoutResult,
|
|
119
|
-
...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, timeoutResult) && { blocked: true }
|
|
120
|
-
});
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
const correct = require_puzzleTasksUtils.validatePuzzleSolution(finalX, finalY, challengeRecord.targetX, challengeRecord.targetY, challengeRecord.tolerance);
|
|
124
|
-
let result = { status: _prosopo_types.CaptchaStatus.approved };
|
|
125
|
-
if (!correct) result = {
|
|
126
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
127
|
-
reason: _prosopo_types.ResultReason.CAPTCHA_INVALID_SOLUTION
|
|
128
|
-
};
|
|
129
|
-
if (correct && this.usageCounters) {
|
|
130
|
-
const dappAccount = (0, _prosopo_util.at)(challengeSplit, 2);
|
|
131
|
-
this.usageCounters.incrManyAsync(dappAccount, require_usageCounters.buildAllWindowIncrements("solved", _prosopo_types.CaptchaType.puzzle, ipAddress.address, userAccount));
|
|
132
|
-
}
|
|
133
|
-
await this.db.updatePuzzleCaptchaRecord(challenge, { puzzleEvents });
|
|
134
|
-
const decodedPayloads = await this.decodeSubmissionPayloads(challengeRecord.sessionId, {
|
|
135
|
-
behavioural: behavioralData,
|
|
136
|
-
simd: simdReadings
|
|
65
|
+
return this.submitInteractiveCaptchaSolution({
|
|
66
|
+
challenge,
|
|
67
|
+
providerChallengeSignature,
|
|
68
|
+
timeout,
|
|
69
|
+
userTimestampSignature,
|
|
70
|
+
ipAddress,
|
|
71
|
+
behavioralData,
|
|
72
|
+
salt,
|
|
73
|
+
simdReadings,
|
|
74
|
+
clientMetaData,
|
|
75
|
+
isCorrect: (record) => require_puzzleTasksUtils.validatePuzzleSolution(finalX, finalY, record.targetX, record.targetY, record.tolerance),
|
|
76
|
+
persistInteraction: () => this.db.updatePuzzleCaptchaRecord(challenge, { puzzleEvents })
|
|
137
77
|
});
|
|
138
|
-
if (behavioralData) try {
|
|
139
|
-
const decryptedData = decodedPayloads.behavioural;
|
|
140
|
-
if (decryptedData) {
|
|
141
|
-
const dappAccount = (0, _prosopo_util.at)(challengeSplit, 2);
|
|
142
|
-
this.logger?.info(() => ({
|
|
143
|
-
msg: "Behavioral analysis completed",
|
|
144
|
-
data: {
|
|
145
|
-
userAccount,
|
|
146
|
-
dappAccount,
|
|
147
|
-
challenge,
|
|
148
|
-
mouseEventsCount: decryptedData.collector1?.length || 0,
|
|
149
|
-
touchEventsCount: decryptedData.collector2?.length || 0,
|
|
150
|
-
clickEventsCount: decryptedData.collector3?.length || 0,
|
|
151
|
-
scrollEventsCount: decryptedData.collector4?.length || 0,
|
|
152
|
-
deviceCapability: decryptedData.deviceCapability,
|
|
153
|
-
captchaResult: correct ? "passed" : "failed"
|
|
154
|
-
}
|
|
155
|
-
}));
|
|
156
|
-
const packedData = {
|
|
157
|
-
c1: decryptedData.collector1 || [],
|
|
158
|
-
c2: decryptedData.collector2 || [],
|
|
159
|
-
c3: decryptedData.collector3 || [],
|
|
160
|
-
c4: decryptedData.collector4 || [],
|
|
161
|
-
d: decryptedData.deviceCapability
|
|
162
|
-
};
|
|
163
|
-
await this.db.updatePuzzleCaptchaRecord(challenge, {
|
|
164
|
-
behavioralDataPacked: packedData,
|
|
165
|
-
deviceCapability: decryptedData.deviceCapability
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
} catch (error) {
|
|
169
|
-
this.logger?.error(() => ({
|
|
170
|
-
msg: "Failed to process behavioral data",
|
|
171
|
-
err: error
|
|
172
|
-
}));
|
|
173
|
-
}
|
|
174
|
-
const storedClientMetaData = require_clientMetaData.toStoredClientMetaData(clientMetaData);
|
|
175
|
-
if (storedClientMetaData) await this.db.updatePuzzleCaptchaRecord(challenge, { clientMetaData: storedClientMetaData });
|
|
176
|
-
await this.db.updatePuzzleCaptchaRecordResult(challenge, result, false, true, userTimestampSignature, coords);
|
|
177
|
-
if (challengeRecord.sessionId) {
|
|
178
|
-
const linkedSessionId = challengeRecord.sessionId;
|
|
179
|
-
await this.updateSessionRecordWithCache(linkedSessionId, {
|
|
180
|
-
userSubmitted: true,
|
|
181
|
-
result,
|
|
182
|
-
...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, result) && { blocked: true },
|
|
183
|
-
...storedClientMetaData && { clientMetaData: storedClientMetaData }
|
|
184
|
-
});
|
|
185
|
-
if (decodedPayloads.simd) await this.recordSessionSimdReadingsIfAbsentWithCache(linkedSessionId, decodedPayloads.simd, _prosopo_types.SimdReadingsStage.submit);
|
|
186
|
-
}
|
|
187
|
-
return correct;
|
|
188
78
|
}
|
|
189
|
-
/**
|
|
190
|
-
* @description Verifies a Puzzle Captcha for a given user and dapp. This is called by the server to verify the user's solution
|
|
191
|
-
* and update the record in the database to show that the user has solved the captcha
|
|
192
|
-
*
|
|
193
|
-
* @param {string} dappAccount - the dapp that is requesting the captcha
|
|
194
|
-
* @param {string} challenge - the challenge string
|
|
195
|
-
* @param {number} timeout - the time in milliseconds since the Provider was selected to provide the captcha
|
|
196
|
-
* @param env - provider environment
|
|
197
|
-
* @param ip - optional IP address for validation
|
|
198
|
-
* @param userAccessRulesStorage - storage for querying user access policies
|
|
199
|
-
* @param email
|
|
200
|
-
* @param spamEmailDomainCheckingEnabled
|
|
201
|
-
* @param spamFilter
|
|
202
|
-
* @param trafficFilter
|
|
203
|
-
* @param storeMetadata - when true, persists the dapp-server-provided
|
|
204
|
-
* `email` on the captcha record for spam-rate analysis.
|
|
205
|
-
* @param clientSessionId - the session id the site rendered the widget
|
|
206
|
-
* with. When supplied, the solve must carry the same value in its
|
|
207
|
-
* `clientMetaData` or it is disapproved.
|
|
208
|
-
*/
|
|
209
79
|
async serverVerifyPuzzleCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled = false, spamFilter, trafficFilter, storeMetadata = false, clientSessionId) {
|
|
210
|
-
|
|
211
|
-
const logger = this.logger.with({
|
|
212
|
-
challenge,
|
|
213
|
-
dappAccount
|
|
214
|
-
});
|
|
215
|
-
const challengeRecord = await this.db.getPuzzleCaptchaRecordByChallenge(challenge);
|
|
216
|
-
if (!challengeRecord) {
|
|
217
|
-
logger.debug(() => ({ msg: `No record of this challenge: ${challenge}` }));
|
|
218
|
-
return notVerifiedResponse;
|
|
219
|
-
}
|
|
220
|
-
notVerifiedResponse.sessionId = challengeRecord.sessionId;
|
|
221
|
-
if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.ProsopoApiError("CAPTCHA.INVALID_SOLUTION", { context: {
|
|
222
|
-
code: 400,
|
|
223
|
-
failedFuncName: this.serverVerifyPuzzleCaptchaSolution.name,
|
|
224
|
-
challenge
|
|
225
|
-
} });
|
|
226
|
-
if (challengeRecord.serverChecked) return notVerifiedResponse;
|
|
227
|
-
const challengeDappAccount = challengeRecord.dappAccount;
|
|
228
|
-
if (dappAccount !== challengeDappAccount) throw new _prosopo_common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", { context: {
|
|
229
|
-
failedFuncName: this.serverVerifyPuzzleCaptchaSolution.name,
|
|
230
|
-
dappAccount,
|
|
231
|
-
challengeDappAccount
|
|
232
|
-
} });
|
|
233
|
-
if (!await this.db.markPuzzleCaptchaRecordChecked(challengeRecord.challenge)) return notVerifiedResponse;
|
|
234
|
-
const submittedAt = challengeRecord.submittedAtTimestamp;
|
|
235
|
-
if ((submittedAt instanceof Date ? Date.now() - submittedAt.getTime() : Number.POSITIVE_INFINITY) > timeout) {
|
|
236
|
-
const disapprovedResult = {
|
|
237
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
238
|
-
reason: _prosopo_types.ResultReason.TIMESTAMP_TOO_OLD
|
|
239
|
-
};
|
|
240
|
-
const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, disapprovedResult);
|
|
241
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
242
|
-
result: disapprovedResult,
|
|
243
|
-
...isBlocked && { blocked: true }
|
|
244
|
-
});
|
|
245
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
246
|
-
serverChecked: true,
|
|
247
|
-
result: disapprovedResult,
|
|
248
|
-
...isBlocked && { blocked: true }
|
|
249
|
-
});
|
|
250
|
-
return notVerifiedResponse;
|
|
251
|
-
}
|
|
252
|
-
if (require_clientMetaData.isClientSessionMismatch(clientSessionId, challengeRecord.clientMetaData?.clientSessionId)) {
|
|
253
|
-
logger.info(() => ({
|
|
254
|
-
msg: "Client session mismatch in server puzzle verification",
|
|
255
|
-
data: { hasRecordedClientSessionId: Boolean(challengeRecord.clientMetaData?.clientSessionId) }
|
|
256
|
-
}));
|
|
257
|
-
const mismatchResult = {
|
|
258
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
259
|
-
reason: _prosopo_types.ResultReason.CLIENT_SESSION_MISMATCH
|
|
260
|
-
};
|
|
261
|
-
const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, mismatchResult);
|
|
262
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
263
|
-
result: mismatchResult,
|
|
264
|
-
...isBlocked && { blocked: true }
|
|
265
|
-
});
|
|
266
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
267
|
-
serverChecked: true,
|
|
268
|
-
result: mismatchResult,
|
|
269
|
-
...isBlocked && { blocked: true }
|
|
270
|
-
});
|
|
271
|
-
return notVerifiedResponse;
|
|
272
|
-
}
|
|
273
|
-
if (userAccessRulesStorage) try {
|
|
274
|
-
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);
|
|
275
|
-
if (blockPolicy) {
|
|
276
|
-
logger.info(() => ({
|
|
277
|
-
msg: "User blocked by access policy in server puzzle verification",
|
|
278
|
-
data: {
|
|
279
|
-
userAccount: challengeRecord.userAccount,
|
|
280
|
-
policy: blockPolicy
|
|
281
|
-
}
|
|
282
|
-
}));
|
|
283
|
-
const blockedResult = {
|
|
284
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
285
|
-
reason: _prosopo_types.ResultReason.ACCESS_POLICY_BLOCK
|
|
286
|
-
};
|
|
287
|
-
const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, blockedResult);
|
|
288
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
289
|
-
result: blockedResult,
|
|
290
|
-
...isBlocked && { blocked: true }
|
|
291
|
-
});
|
|
292
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
293
|
-
serverChecked: true,
|
|
294
|
-
result: blockedResult,
|
|
295
|
-
...isBlocked && { blocked: true },
|
|
296
|
-
matchedRule: (0, _prosopo_user_access_policy.describeMatchedRule)(blockPolicy)
|
|
297
|
-
});
|
|
298
|
-
return notVerifiedResponse;
|
|
299
|
-
}
|
|
300
|
-
} catch (error) {
|
|
301
|
-
logger.warn(() => ({
|
|
302
|
-
msg: "Failed to check user access policies in server puzzle verification",
|
|
303
|
-
error
|
|
304
|
-
}));
|
|
305
|
-
}
|
|
306
|
-
if (email && spamEmailDomainCheckingEnabled) try {
|
|
307
|
-
if (await this.checkSpamEmail(email)) {
|
|
308
|
-
const emailDomain = email.split("@")[1] || "unknown";
|
|
309
|
-
logger.info(() => ({
|
|
310
|
-
msg: "Spam email domain detected in server puzzle verification",
|
|
311
|
-
data: { emailDomain }
|
|
312
|
-
}));
|
|
313
|
-
const spamResult = {
|
|
314
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
315
|
-
reason: _prosopo_types.ResultReason.SPAM_EMAIL_DOMAIN
|
|
316
|
-
};
|
|
317
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
318
|
-
result: spamResult,
|
|
319
|
-
...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, spamResult) && { blocked: true }
|
|
320
|
-
});
|
|
321
|
-
return notVerifiedResponse;
|
|
322
|
-
}
|
|
323
|
-
} catch (error) {
|
|
324
|
-
logger.warn(() => ({
|
|
325
|
-
msg: "Failed to check spam email domain in server puzzle verification",
|
|
326
|
-
error
|
|
327
|
-
}));
|
|
328
|
-
}
|
|
329
|
-
const maxEmailSubmissionCount = spamFilter?.enabled && spamFilter.emailRules?.enabled ? spamFilter.emailRules.maxEmailSubmissionCount : void 0;
|
|
330
|
-
let emailNormalised;
|
|
331
|
-
if (maxEmailSubmissionCount !== void 0 && email && storeMetadata) {
|
|
332
|
-
emailNormalised = require_evaluateEmailSpamRules.normaliseEmailForMatching(email);
|
|
333
|
-
if (emailNormalised) try {
|
|
334
|
-
const priorCount = await this.db.countCommitmentsByNormalisedEmail(dappAccount, emailNormalised);
|
|
335
|
-
if (priorCount >= maxEmailSubmissionCount) {
|
|
336
|
-
logger.info(() => ({
|
|
337
|
-
msg: "Email submission count exceeded in server puzzle verification",
|
|
338
|
-
data: {
|
|
339
|
-
priorCount,
|
|
340
|
-
maxEmailSubmissionCount
|
|
341
|
-
}
|
|
342
|
-
}));
|
|
343
|
-
const spamCountResult = {
|
|
344
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
345
|
-
reason: _prosopo_types.ResultReason.SPAM_EMAIL_COUNT_EXCEEDED
|
|
346
|
-
};
|
|
347
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
348
|
-
result: spamCountResult,
|
|
349
|
-
...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, spamCountResult) && { blocked: true }
|
|
350
|
-
});
|
|
351
|
-
return notVerifiedResponse;
|
|
352
|
-
}
|
|
353
|
-
} catch (error) {
|
|
354
|
-
logger.warn(() => ({
|
|
355
|
-
msg: "Failed to check email submission count in server puzzle verification",
|
|
356
|
-
error
|
|
357
|
-
}));
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
const sessionRecord = challengeRecord.sessionId ? await this.getSessionRecordWithOriginFallback(challengeRecord.sessionId) : void 0;
|
|
361
|
-
const enrichedDnsEvent = await require_enrichDnsEvent.enrichDnsEvent(sessionRecord?.dnsEvent, env.ipInfoService, ip ?? challengeRecord.ipInfo?.ip);
|
|
362
|
-
{
|
|
363
|
-
const check = await this.resolveTrafficFilterCheck(env, challengeRecord.ipInfo, trafficFilter, ip, enrichedDnsEvent);
|
|
364
|
-
if (check.isBlocked) {
|
|
365
|
-
logger.info(() => ({
|
|
366
|
-
msg: "Traffic filter rejected request in puzzle verification",
|
|
367
|
-
data: {
|
|
368
|
-
ip,
|
|
369
|
-
reason: check.reason,
|
|
370
|
-
dnsPeerIp: enrichedDnsEvent?.peerIp,
|
|
371
|
-
dnsResolverIp: enrichedDnsEvent?.resolverIp,
|
|
372
|
-
dnsPeerAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.peerIpInfo),
|
|
373
|
-
dnsResolverAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.resolverIpInfo),
|
|
374
|
-
dnsPathValid: enrichedDnsEvent?.pathValid
|
|
375
|
-
}
|
|
376
|
-
}));
|
|
377
|
-
const blockedResult = {
|
|
378
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
379
|
-
reason: check.reason
|
|
380
|
-
};
|
|
381
|
-
const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, blockedResult);
|
|
382
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
383
|
-
result: blockedResult,
|
|
384
|
-
...isBlocked && { blocked: true }
|
|
385
|
-
});
|
|
386
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
387
|
-
serverChecked: true,
|
|
388
|
-
result: blockedResult,
|
|
389
|
-
...isBlocked && { blocked: true }
|
|
390
|
-
});
|
|
391
|
-
return notVerifiedResponse;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
if (storeMetadata && email) await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, { metadata: {
|
|
395
|
-
email,
|
|
396
|
-
emailNormalised: emailNormalised ?? require_evaluateEmailSpamRules.normaliseEmailForMatching(email)
|
|
397
|
-
} });
|
|
398
|
-
if (ip) {
|
|
399
|
-
const challengeIpAddress = require_compositeIpAddress.getIpAddressFromComposite(challengeRecord.ipAddress);
|
|
400
|
-
const ipValidationRules = (await this.db.getClientRecord(dappAccount))?.settings?.ipValidationRules;
|
|
401
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, { providedIp: require_compositeIpAddress.getCompositeIpAddress(ip) });
|
|
402
|
-
if (ipValidationRules?.enabled === true) {
|
|
403
|
-
const ipValidation = await require_util.deepValidateIpAddress(ip, challengeIpAddress, logger, env.ipInfoService, ipValidationRules, enrichedDnsEvent?.peerIp);
|
|
404
|
-
if (!ipValidation.isValid) {
|
|
405
|
-
logger.error(() => ({
|
|
406
|
-
msg: "IP validation failed for puzzle captcha",
|
|
407
|
-
data: {
|
|
408
|
-
ip,
|
|
409
|
-
challengeIp: challengeIpAddress.address,
|
|
410
|
-
error: ipValidation.errorMessage,
|
|
411
|
-
distanceKm: ipValidation.distanceKm
|
|
412
|
-
}
|
|
413
|
-
}));
|
|
414
|
-
const ipFailResult = {
|
|
415
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
416
|
-
reason: _prosopo_types.ResultReason.FAILED_IP_VALIDATION
|
|
417
|
-
};
|
|
418
|
-
const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, ipFailResult);
|
|
419
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
420
|
-
result: ipFailResult,
|
|
421
|
-
...isBlocked && { blocked: true }
|
|
422
|
-
});
|
|
423
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
424
|
-
serverChecked: true,
|
|
425
|
-
result: ipFailResult,
|
|
426
|
-
...isBlocked && { blocked: true }
|
|
427
|
-
});
|
|
428
|
-
return notVerifiedResponse;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
let score;
|
|
433
|
-
if (sessionRecord) {
|
|
434
|
-
const dnsAsymmetry = require_enrichDnsEvent.computeDnsAsymmetry(enrichedDnsEvent, challengeRecord.ipInfo, trafficFilter);
|
|
435
|
-
if (dnsAsymmetry > 0) sessionRecord.scoreComponents = {
|
|
436
|
-
...sessionRecord.scoreComponents,
|
|
437
|
-
dnsAsymmetry
|
|
438
|
-
};
|
|
439
|
-
score = require_frictionlessTasksUtils.computeFrictionlessScore(sessionRecord?.scoreComponents);
|
|
440
|
-
logger.info(() => ({ data: {
|
|
441
|
-
scoreComponents: { ...sessionRecord?.scoreComponents || {} },
|
|
442
|
-
score,
|
|
443
|
-
dnsPeerAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.peerIpInfo),
|
|
444
|
-
dnsResolverAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.resolverIpInfo)
|
|
445
|
-
} }));
|
|
446
|
-
}
|
|
447
|
-
try {
|
|
448
|
-
const decisionInput = {
|
|
449
|
-
userAccount: challengeRecord.userAccount,
|
|
450
|
-
dappAccount: challengeRecord.dappAccount,
|
|
451
|
-
captchaResult: "passed",
|
|
452
|
-
headers: challengeRecord.headers,
|
|
453
|
-
captchaType: _prosopo_types.CaptchaType.puzzle,
|
|
454
|
-
behavioralDataPacked: challengeRecord.behavioralDataPacked,
|
|
455
|
-
deviceCapability: challengeRecord.deviceCapability,
|
|
456
|
-
countryCode: challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0,
|
|
457
|
-
ipInfo: challengeRecord.ipInfo,
|
|
458
|
-
dnsEvent: enrichedDnsEvent,
|
|
459
|
-
score,
|
|
460
|
-
threshold: sessionRecord?.threshold,
|
|
461
|
-
scoreComponents: sessionRecord?.scoreComponents,
|
|
462
|
-
decryptedHeadHash: sessionRecord?.decryptedHeadHash,
|
|
463
|
-
userSitekeyIpHash: sessionRecord?.userSitekeyIpHash,
|
|
464
|
-
simdReadings: sessionRecord?.simdReadings,
|
|
465
|
-
d: sessionRecord?.d,
|
|
466
|
-
frictionlessReason: sessionRecord?.reason,
|
|
467
|
-
ruleType: sessionRecord?.ruleType,
|
|
468
|
-
webView: sessionRecord?.webView,
|
|
469
|
-
iFrame: sessionRecord?.iFrame,
|
|
470
|
-
currentUrl: sessionRecord?.currentUrl,
|
|
471
|
-
iframeUrl: sessionRecord?.iframeUrl,
|
|
472
|
-
coords: challengeRecord.coords,
|
|
473
|
-
puzzleEvents: challengeRecord.puzzleEvents,
|
|
474
|
-
...require_rawTlsSignalsMiddleware.rawTlsSignalsFromRecord(sessionRecord),
|
|
475
|
-
trafficPolicies: require_devicePlatform.deriveTrafficPolicies(trafficFilter)
|
|
476
|
-
};
|
|
477
|
-
const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
|
|
478
|
-
if (decision.decision === _prosopo_types.DecisionMachineDecision.Deny) {
|
|
479
|
-
logger.info(() => ({
|
|
480
|
-
msg: "Decision machine denied puzzle captcha in server verification",
|
|
481
|
-
data: {
|
|
482
|
-
userAccount: challengeRecord.userAccount,
|
|
483
|
-
reason: decision.reason,
|
|
484
|
-
score: decision.score,
|
|
485
|
-
tags: decision.tags
|
|
486
|
-
}
|
|
487
|
-
}));
|
|
488
|
-
const dmResult = {
|
|
489
|
-
status: _prosopo_types.CaptchaStatus.disapproved,
|
|
490
|
-
reason: decision.reason || _prosopo_types.ResultReason.CAPTCHA_DECISION_MACHINE_DENIED
|
|
491
|
-
};
|
|
492
|
-
const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, dmResult);
|
|
493
|
-
await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
|
|
494
|
-
result: dmResult,
|
|
495
|
-
...isBlocked && { blocked: true }
|
|
496
|
-
});
|
|
497
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
498
|
-
serverChecked: true,
|
|
499
|
-
result: dmResult,
|
|
500
|
-
...isBlocked && { blocked: true }
|
|
501
|
-
});
|
|
502
|
-
return notVerifiedResponse;
|
|
503
|
-
}
|
|
504
|
-
logger.debug(() => ({
|
|
505
|
-
msg: "Decision machine allowed puzzle captcha",
|
|
506
|
-
data: {
|
|
507
|
-
reason: decision.reason,
|
|
508
|
-
score: decision.score,
|
|
509
|
-
tags: decision.tags
|
|
510
|
-
}
|
|
511
|
-
}));
|
|
512
|
-
} catch (error) {
|
|
513
|
-
logger.error(() => ({
|
|
514
|
-
msg: "Failed to run decision machine in server puzzle verification",
|
|
515
|
-
err: error
|
|
516
|
-
}));
|
|
517
|
-
}
|
|
518
|
-
if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
|
|
519
|
-
serverChecked: true,
|
|
520
|
-
result: { status: _prosopo_types.CaptchaStatus.approved }
|
|
521
|
-
});
|
|
522
|
-
return {
|
|
523
|
-
verified: true,
|
|
524
|
-
...score ? { score } : {},
|
|
525
|
-
...challengeRecord.sessionId && { sessionId: challengeRecord.sessionId }
|
|
526
|
-
};
|
|
80
|
+
return this.serverVerifyInteractiveCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled, spamFilter, trafficFilter, storeMetadata, clientSessionId);
|
|
527
81
|
}
|
|
528
82
|
};
|
|
529
83
|
//#endregion
|
|
@@ -131,6 +131,8 @@ var checkTrafficFilter = (ipInfo, trafficFilter, extraIpInfos, dnsPathValid) =>
|
|
|
131
131
|
matches
|
|
132
132
|
};
|
|
133
133
|
};
|
|
134
|
+
/** A lower tolerance is a smaller hit radius, so the strictest is the minimum. */
|
|
135
|
+
var strictestTolerance = (current, next) => next === void 0 || current === void 0 ? next ?? current : Math.min(current, next);
|
|
134
136
|
/**
|
|
135
137
|
* Combine the `challenge` matches into a single effective policy: pick the
|
|
136
138
|
* strictest captcha type, then take the hardest params (max difficulty,
|
|
@@ -147,14 +149,26 @@ var resolveChallengePolicy = (matches) => {
|
|
|
147
149
|
let solvedImagesCount;
|
|
148
150
|
let puzzleTolerance;
|
|
149
151
|
let puzzleSettings;
|
|
152
|
+
let audioSettings;
|
|
153
|
+
let iconOrderTolerance;
|
|
154
|
+
let iconOrderSettings;
|
|
150
155
|
for (const m of challenges) {
|
|
151
156
|
if (m.policy.powDifficulty !== void 0) powDifficulty = powDifficulty === void 0 ? m.policy.powDifficulty : Math.max(powDifficulty, m.policy.powDifficulty);
|
|
152
157
|
if (m.policy.solvedImagesCount !== void 0) solvedImagesCount = solvedImagesCount === void 0 ? m.policy.solvedImagesCount : Math.max(solvedImagesCount, m.policy.solvedImagesCount);
|
|
153
|
-
|
|
158
|
+
puzzleTolerance = strictestTolerance(puzzleTolerance, m.policy.puzzleTolerance);
|
|
154
159
|
if (m.policy.puzzle) puzzleSettings = {
|
|
155
160
|
...puzzleSettings ?? {},
|
|
156
161
|
...m.policy.puzzle
|
|
157
162
|
};
|
|
163
|
+
if (m.policy.audio) audioSettings = {
|
|
164
|
+
...audioSettings ?? {},
|
|
165
|
+
...m.policy.audio
|
|
166
|
+
};
|
|
167
|
+
iconOrderTolerance = strictestTolerance(iconOrderTolerance, m.policy.iconOrderTolerance);
|
|
168
|
+
if (m.policy.iconOrder) iconOrderSettings = {
|
|
169
|
+
...iconOrderSettings ?? {},
|
|
170
|
+
...m.policy.iconOrder
|
|
171
|
+
};
|
|
158
172
|
}
|
|
159
173
|
return {
|
|
160
174
|
captchaType: winningCaptchaType,
|
|
@@ -162,6 +176,9 @@ var resolveChallengePolicy = (matches) => {
|
|
|
162
176
|
solvedImagesCount,
|
|
163
177
|
puzzleTolerance,
|
|
164
178
|
puzzleSettings,
|
|
179
|
+
audioSettings,
|
|
180
|
+
iconOrderTolerance,
|
|
181
|
+
iconOrderSettings,
|
|
165
182
|
sourceCategories: challenges.map((m) => m.category)
|
|
166
183
|
};
|
|
167
184
|
};
|
package/dist/cjs/tasks/tasks.cjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const require_usageCounters = require("../util/usageCounters.cjs");
|
|
2
2
|
const require_decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
|
|
3
|
+
const require_audioTasks = require("./audioCaptcha/audioTasks.cjs");
|
|
3
4
|
const require_clientTasks = require("./client/clientTasks.cjs");
|
|
4
5
|
const require_datasetTasks = require("./dataset/datasetTasks.cjs");
|
|
5
6
|
const require_frictionlessTasks = require("./frictionless/frictionlessTasks.cjs");
|
|
7
|
+
const require_iconOrderTasks = require("./iconOrderCaptcha/iconOrderTasks.cjs");
|
|
6
8
|
const require_imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
|
|
7
9
|
const require_powTasks = require("./powCaptcha/powTasks.cjs");
|
|
8
10
|
const require_puzzleTasks = require("./puzzleCaptcha/puzzleTasks.cjs");
|
|
@@ -33,6 +35,8 @@ var Tasks = class {
|
|
|
33
35
|
this.usageCounters = this.initUsageCounters();
|
|
34
36
|
this.powCaptchaManager = new require_powTasks.PowCaptchaManager(this.db, this.pair, this.config, this.logger, this.writeQueue, this.usageCounters);
|
|
35
37
|
this.puzzleCaptchaManager = new require_puzzleTasks.PuzzleCaptchaManager(this.db, this.pair, this.config, this.logger, this.usageCounters);
|
|
38
|
+
this.audioCaptchaManager = new require_audioTasks.AudioCaptchaManager(this.db, this.pair, this.config, this.logger, this.usageCounters);
|
|
39
|
+
this.iconOrderCaptchaManager = new require_iconOrderTasks.IconOrderCaptchaManager(this.db, this.pair, this.config, this.logger, this.usageCounters);
|
|
36
40
|
this.datasetManager = new require_datasetTasks.DatasetManager(this.config, this.logger, this.captchaConfig, this.db);
|
|
37
41
|
this.imgCaptchaManager = new require_imgCaptchaTasks.ImgCaptchaManager(this.db, this.pair, this.config, this.logger, this.writeQueue, this.usageCounters);
|
|
38
42
|
this.clientTaskManager = new require_clientTasks.ClientTaskManager(this.config, this.logger, this.db);
|
|
@@ -62,6 +66,8 @@ var Tasks = class {
|
|
|
62
66
|
this.logger = logger;
|
|
63
67
|
this.powCaptchaManager.logger = logger;
|
|
64
68
|
this.puzzleCaptchaManager.logger = logger;
|
|
69
|
+
this.audioCaptchaManager.logger = logger;
|
|
70
|
+
this.iconOrderCaptchaManager.logger = logger;
|
|
65
71
|
this.datasetManager.logger = logger;
|
|
66
72
|
this.imgCaptchaManager.logger = logger;
|
|
67
73
|
this.clientTaskManager.logger = logger;
|
package/dist/cjs/util.cjs
CHANGED
|
@@ -2,10 +2,10 @@ const require_ipComparison = require("./services/ipComparison.cjs");
|
|
|
2
2
|
let _prosopo_common = require("@prosopo/common");
|
|
3
3
|
let _prosopo_types = require("@prosopo/types");
|
|
4
4
|
let _prosopo_util = require("@prosopo/util");
|
|
5
|
-
let _prosopo_util_crypto = require("@prosopo/util-crypto");
|
|
6
5
|
let ip_address = require("ip-address");
|
|
7
6
|
let _polkadot_util_hex = require("@polkadot/util/hex");
|
|
8
7
|
let _polkadot_util_is = require("@polkadot/util/is");
|
|
8
|
+
let _prosopo_util_crypto = require("@prosopo/util-crypto");
|
|
9
9
|
//#region src/util.ts
|
|
10
10
|
function encodeStringAddress(address) {
|
|
11
11
|
try {
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getCompositeIpAddress, getIpAddressFromComposite, isSameIpOrigin } from "./compositeIpAddress.js";
|
|
3
|
-
import { BlacklistRequestInspector, getPrioritisedAccessRule, getRequestUserScope, getVerdictCache, normalizeHeadersForMatching, rankCandidateRules } from "./api/blacklistRequestInspector.js";
|
|
4
|
-
import { FrictionlessReason } from "./tasks/frictionless/frictionlessTasks.js";
|
|
5
3
|
import { compareIPs } from "./services/ipComparison.js";
|
|
6
4
|
import { checkIfTaskIsRunning, deepValidateIpAddress, encodeStringAddress, evaluateIpValidationRules, getIPAddress, getIPAddressFromBigInt, shuffleArray, validateIpAddress } from "./util.js";
|
|
5
|
+
import { BlacklistRequestInspector, getPrioritisedAccessRule, getRequestUserScope, getVerdictCache, normalizeHeadersForMatching, rankCandidateRules } from "./api/blacklistRequestInspector.js";
|
|
6
|
+
import { FrictionlessReason } from "./tasks/frictionless/frictionlessTasks.js";
|
|
7
7
|
import { Tasks } from "./tasks/tasks.js";
|
|
8
8
|
import { updateSpamEmailDomains } from "./tasks/spam/updateSpamEmailDomains.js";
|
|
9
9
|
import { blockMiddleware } from "./api/block.js";
|