@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
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const require_audioRenderer = require("../audio/audioRenderer.cjs");
|
|
2
|
+
const require_interactiveCaptchaManager = require("../interactiveCaptcha/interactiveCaptchaManager.cjs");
|
|
3
|
+
const require_audioTasksUtils = require("./audioTasksUtils.cjs");
|
|
4
|
+
let _prosopo_types = require("@prosopo/types");
|
|
5
|
+
//#region src/tasks/audioCaptcha/audioTasks.ts
|
|
6
|
+
var AudioCaptchaManager = class extends require_interactiveCaptchaManager.InteractiveCaptchaManager {
|
|
7
|
+
constructor(..._args) {
|
|
8
|
+
super(..._args);
|
|
9
|
+
this.captchaType = _prosopo_types.CaptchaType.audio;
|
|
10
|
+
this.logLabel = "audio";
|
|
11
|
+
}
|
|
12
|
+
getRecordByChallenge(challenge) {
|
|
13
|
+
return this.db.getAudioCaptchaRecordByChallenge(challenge);
|
|
14
|
+
}
|
|
15
|
+
updateRecord(challenge, updates) {
|
|
16
|
+
return this.db.updateAudioCaptchaRecord(challenge, updates);
|
|
17
|
+
}
|
|
18
|
+
updateSubmissionResult(challenge, result, userSignature, coords) {
|
|
19
|
+
return this.db.updateAudioCaptchaRecordResult(challenge, result, false, true, userSignature, coords);
|
|
20
|
+
}
|
|
21
|
+
/** Atomic, so concurrent submissions cannot each be graded. */
|
|
22
|
+
claimSubmission(record) {
|
|
23
|
+
return this.db.claimAudioCaptchaSubmission(record.challenge);
|
|
24
|
+
}
|
|
25
|
+
markRecordChecked(challenge) {
|
|
26
|
+
return this.db.markAudioCaptchaRecordChecked(challenge);
|
|
27
|
+
}
|
|
28
|
+
decisionMachineEventFields(record) {
|
|
29
|
+
return {
|
|
30
|
+
audioEvents: record.audioEvents,
|
|
31
|
+
audioReplays: record.replays
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The renderer picks the digits, so the answer only exists once the clip
|
|
36
|
+
* does; the caller must store `answer` before responding.
|
|
37
|
+
*/
|
|
38
|
+
getAudioCaptchaChallenge(userAccount, dappAccount, settings) {
|
|
39
|
+
return {
|
|
40
|
+
...this.mintChallenge(userAccount, dappAccount),
|
|
41
|
+
...require_audioRenderer.renderAudioClip(settings)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async verifyAudioCaptchaSolution(challenge, providerChallengeSignature, submittedAnswer, replays, audioEvents, timeout, userTimestampSignature, ipAddress, behavioralData, salt, simdReadings, clientMetaData) {
|
|
45
|
+
return this.submitInteractiveCaptchaSolution({
|
|
46
|
+
challenge,
|
|
47
|
+
providerChallengeSignature,
|
|
48
|
+
timeout,
|
|
49
|
+
userTimestampSignature,
|
|
50
|
+
ipAddress,
|
|
51
|
+
behavioralData,
|
|
52
|
+
salt,
|
|
53
|
+
simdReadings,
|
|
54
|
+
clientMetaData,
|
|
55
|
+
isCorrect: (record) => require_audioTasksUtils.validateAudioSolution(submittedAnswer, record.answer),
|
|
56
|
+
persistInteraction: () => this.db.updateAudioCaptchaRecord(challenge, {
|
|
57
|
+
audioEvents,
|
|
58
|
+
replays,
|
|
59
|
+
submittedAnswer: require_audioTasksUtils.normaliseAudioAnswer(submittedAnswer)
|
|
60
|
+
})
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
exports.AudioCaptchaManager = AudioCaptchaManager;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/tasks/audioCaptcha/audioTasksUtils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Keeps only the digits, in order: "1 2 3", "1-2-3" and screen-reader inserted
|
|
4
|
+
* separators all grade the same, and no different digit sequence can pass.
|
|
5
|
+
*/
|
|
6
|
+
var normaliseAudioAnswer = (raw) => raw.replace(/\D/g, "");
|
|
7
|
+
/**
|
|
8
|
+
* Exact match after normalisation. No edit-distance slack: one substitution
|
|
9
|
+
* widens the accepted set far more than it helps a listener, and a wrong
|
|
10
|
+
* answer only costs a fresh challenge.
|
|
11
|
+
*/
|
|
12
|
+
var validateAudioSolution = (submitted, expected) => {
|
|
13
|
+
const normalised = normaliseAudioAnswer(submitted);
|
|
14
|
+
if (normalised.length === 0 || expected.length === 0) return false;
|
|
15
|
+
return normalised === expected;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.normaliseAudioAnswer = normaliseAudioAnswer;
|
|
19
|
+
exports.validateAudioSolution = validateAudioSolution;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require_compositeIpAddress = require("../compositeIpAddress.cjs");
|
|
2
2
|
const require_blacklistRequestInspector = require("../api/blacklistRequestInspector.cjs");
|
|
3
|
+
const require_audioAlternative = require("./audioAlternative.cjs");
|
|
3
4
|
const require_bundlePool = require("./detection/bundlePool.cjs");
|
|
4
5
|
const require_decoderPool = require("./detection/decoderPool.cjs");
|
|
5
6
|
const require_checkTrafficFilter = require("./spam/checkTrafficFilter.cjs");
|
|
@@ -225,7 +226,7 @@ var CaptchaManager = class CaptchaManager {
|
|
|
225
226
|
sessionId
|
|
226
227
|
}
|
|
227
228
|
}));
|
|
228
|
-
if (!(0, _prosopo_types.isCaptchaTypeFeatureEnabled)(requestedCaptchaType, clientSettings.settings?.captchaTypeFeatureFlags)) {
|
|
229
|
+
if (!(requestedCaptchaType === _prosopo_types.CaptchaType.audio ? require_audioAlternative.isAudioAlternativeEnabled(clientSettings.settings) : (0, _prosopo_types.isCaptchaTypeFeatureEnabled)(requestedCaptchaType, clientSettings.settings?.captchaTypeFeatureFlags))) {
|
|
229
230
|
this.logger.warn(() => ({
|
|
230
231
|
msg: "Captcha type is switched off for this site",
|
|
231
232
|
data: {
|
|
@@ -332,7 +333,7 @@ var CaptchaManager = class CaptchaManager {
|
|
|
332
333
|
type: requestedCaptchaType
|
|
333
334
|
};
|
|
334
335
|
}
|
|
335
|
-
if (sessionRecord.captchaType !== requestedCaptchaType) {
|
|
336
|
+
if (sessionRecord.captchaType !== requestedCaptchaType && !require_audioAlternative.isAudioAlternativeAllowed(requestedCaptchaType, sessionRecord.captchaType, clientSettings.settings)) {
|
|
336
337
|
this.logger.warn(() => ({
|
|
337
338
|
msg: "Session captcha type does not match requested type",
|
|
338
339
|
data: {
|
|
@@ -357,6 +358,17 @@ var CaptchaManager = class CaptchaManager {
|
|
|
357
358
|
ipInfo: sessionRecord.ipInfo
|
|
358
359
|
};
|
|
359
360
|
}
|
|
361
|
+
if (requestedCaptchaType === _prosopo_types.CaptchaType.audio) {
|
|
362
|
+
this.logger.warn(() => ({
|
|
363
|
+
msg: "Sessionless audio captcha request rejected",
|
|
364
|
+
data: { account: clientSettings.account }
|
|
365
|
+
}));
|
|
366
|
+
return {
|
|
367
|
+
valid: false,
|
|
368
|
+
reason: _prosopo_types.ResultReason.INCORRECT_CAPTCHA_TYPE,
|
|
369
|
+
type: requestedCaptchaType
|
|
370
|
+
};
|
|
371
|
+
}
|
|
360
372
|
if (userAccessPolicy?.captchaType !== void 0 && userAccessPolicy.captchaType !== requestedCaptchaType) {
|
|
361
373
|
this.logger.warn(() => ({
|
|
362
374
|
msg: "Invalid captcha type for user access policy (sessionless)",
|
|
@@ -20,16 +20,18 @@ let _prosopo_types = require("@prosopo/types");
|
|
|
20
20
|
*
|
|
21
21
|
* Pass `allowedTypes` from `resolveAllowedCaptchaTypes`, so Prosopo's
|
|
22
22
|
* per-site captcha type feature flags are applied alongside the site owner's
|
|
23
|
-
* own `frictionlessTypes`. Absent means
|
|
23
|
+
* own `frictionlessTypes`. Absent means the defaults for both, so icon-order
|
|
24
|
+
* stays off.
|
|
24
25
|
*
|
|
25
26
|
* Coercion only ever narrows. A disabled type falls back to the other
|
|
26
27
|
* interactive type if that is permitted, and to PoW otherwise — never the
|
|
27
28
|
* reverse, so this can't hand a user a harder challenge than was asked for.
|
|
28
29
|
*/
|
|
29
30
|
var coerceToEnabledCaptchaType = (requested, allowedTypes, logger) => {
|
|
30
|
-
const types = (0, _prosopo_types.resolveFrictionlessTypes)(allowedTypes);
|
|
31
|
+
const types = allowedTypes ? (0, _prosopo_types.resolveFrictionlessTypes)(allowedTypes) : (0, _prosopo_types.resolveAllowedCaptchaTypes)(void 0);
|
|
31
32
|
const puzzleAllowed = types.puzzle && require_puzzleRenderer.isPuzzleRenderAvailable();
|
|
32
33
|
const imageAllowed = types.image;
|
|
34
|
+
const iconOrderAllowed = types.iconOrder;
|
|
33
35
|
const resolved = (() => {
|
|
34
36
|
switch (requested) {
|
|
35
37
|
case _prosopo_types.CaptchaType.pow: return _prosopo_types.CaptchaType.pow;
|
|
@@ -39,6 +41,10 @@ var coerceToEnabledCaptchaType = (requested, allowedTypes, logger) => {
|
|
|
39
41
|
case _prosopo_types.CaptchaType.image:
|
|
40
42
|
if (imageAllowed) return _prosopo_types.CaptchaType.image;
|
|
41
43
|
return puzzleAllowed ? _prosopo_types.CaptchaType.puzzle : _prosopo_types.CaptchaType.pow;
|
|
44
|
+
case _prosopo_types.CaptchaType.iconOrder:
|
|
45
|
+
if (iconOrderAllowed) return _prosopo_types.CaptchaType.iconOrder;
|
|
46
|
+
if (puzzleAllowed) return _prosopo_types.CaptchaType.puzzle;
|
|
47
|
+
return imageAllowed ? _prosopo_types.CaptchaType.image : _prosopo_types.CaptchaType.pow;
|
|
42
48
|
}
|
|
43
49
|
})();
|
|
44
50
|
if (resolved !== requested) logger?.info(() => ({
|
|
@@ -48,7 +54,8 @@ var coerceToEnabledCaptchaType = (requested, allowedTypes, logger) => {
|
|
|
48
54
|
served: resolved,
|
|
49
55
|
imageEnabled: types.image,
|
|
50
56
|
puzzleEnabled: types.puzzle,
|
|
51
|
-
puzzleRenderable: require_puzzleRenderer.isPuzzleRenderAvailable()
|
|
57
|
+
puzzleRenderable: require_puzzleRenderer.isPuzzleRenderAvailable(),
|
|
58
|
+
iconOrderEnabled: types.iconOrder
|
|
52
59
|
}
|
|
53
60
|
}));
|
|
54
61
|
return resolved;
|
|
@@ -69,6 +76,16 @@ var coerceToEnabledCaptchaType = (requested, allowedTypes, logger) => {
|
|
|
69
76
|
* turned off is exactly what `coerceToEnabledCaptchaType` exists to stop.
|
|
70
77
|
*/
|
|
71
78
|
var switchTypeAfterRefreshes = (resolved, refreshCount, allowedTypes) => _prosopo_types.CaptchaType.puzzle === resolved && (refreshCount ?? 0) >= 3 && (0, _prosopo_types.resolveFrictionlessTypes)(allowedTypes).image ? _prosopo_types.CaptchaType.image : resolved;
|
|
79
|
+
/**
|
|
80
|
+
* Swap a puzzle for an image challenge because the user asked for one.
|
|
81
|
+
*
|
|
82
|
+
* Same one-way rule as `switchTypeAfterRefreshes`: the request is
|
|
83
|
+
* client-reported, so it may only ever earn a harder challenge. Whatever the
|
|
84
|
+
* routing settled on other than a puzzle stands, and so does a site that may
|
|
85
|
+
* not be served image challenges.
|
|
86
|
+
*/
|
|
87
|
+
var switchTypeOnUserRequest = (resolved, switchToImage, allowedTypes) => _prosopo_types.CaptchaType.puzzle === resolved && true === switchToImage && (0, _prosopo_types.resolveFrictionlessTypes)(allowedTypes).image ? _prosopo_types.CaptchaType.image : resolved;
|
|
72
88
|
//#endregion
|
|
73
89
|
exports.coerceToEnabledCaptchaType = coerceToEnabledCaptchaType;
|
|
74
90
|
exports.switchTypeAfterRefreshes = switchTypeAfterRefreshes;
|
|
91
|
+
exports.switchTypeOnUserRequest = switchTypeOnUserRequest;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const require_validateAddress = require("../../api/validateAddress.cjs");
|
|
2
1
|
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
2
|
+
const require_validateAddress = require("../../api/validateAddress.cjs");
|
|
3
3
|
let _prosopo_common = require("@prosopo/common");
|
|
4
4
|
let _prosopo_database = require("@prosopo/database");
|
|
5
5
|
let _prosopo_types = require("@prosopo/types");
|
|
6
|
-
require("node:crypto");
|
|
7
6
|
let _prosopo_util = require("@prosopo/util");
|
|
7
|
+
require("node:crypto");
|
|
8
8
|
/**
|
|
9
9
|
* Matches `text` against a pattern where `*` matches any run of characters.
|
|
10
10
|
* Greedy two-pointer match, retrying from the last `*` on mismatch, so time
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const require_usageCounters = require("../../util/usageCounters.cjs");
|
|
2
|
-
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
3
|
-
const require_dnsEventUrl = require("../../api/dnsEventUrl.cjs");
|
|
4
2
|
const require_rawTlsSignalsMiddleware = require("../../api/rawTlsSignalsMiddleware.cjs");
|
|
5
|
-
const require_lang = require("../../rules/lang.cjs");
|
|
6
3
|
const require_clientMetaData = require("../../utils/clientMetaData.cjs");
|
|
4
|
+
const require_audioAlternative = require("../audioAlternative.cjs");
|
|
7
5
|
const require_captchaManager = require("../captchaManager.cjs");
|
|
6
|
+
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
7
|
+
const require_dnsEventUrl = require("../../api/dnsEventUrl.cjs");
|
|
8
|
+
const require_lang = require("../../rules/lang.cjs");
|
|
8
9
|
const require_captchaTypeSelection = require("../captchaTypeSelection.cjs");
|
|
9
10
|
const require_getBotScore = require("../detection/getBotScore.cjs");
|
|
10
11
|
const require_puzzleDifficulty = require("../puzzle/puzzleDifficulty.cjs");
|
|
@@ -21,6 +22,8 @@ var getSessionIDPrefix = (host) => {
|
|
|
21
22
|
var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
22
23
|
constructor(db, pair, config, logger, writeQueue, decisionMachineRunner, usageCounters) {
|
|
23
24
|
super(db, pair, config, logger, writeQueue);
|
|
25
|
+
this.audioAlternativeEnabled = false;
|
|
26
|
+
this.imageSwitchRequested = false;
|
|
24
27
|
this.config = config;
|
|
25
28
|
this.decisionMachineRunner = decisionMachineRunner ?? new require_decisionMachineRunner.DecisionMachineRunner(db);
|
|
26
29
|
this.usageCounters = usageCounters ?? null;
|
|
@@ -33,16 +36,28 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
33
36
|
setRoutingContext(ctx) {
|
|
34
37
|
this.routingContext = ctx;
|
|
35
38
|
}
|
|
39
|
+
/** Separate from `setSessionParams`, which the short-circuit path bypasses. */
|
|
40
|
+
setAudioAlternativeEnabled(enabled) {
|
|
41
|
+
this.audioAlternativeEnabled = enabled;
|
|
42
|
+
}
|
|
36
43
|
/**
|
|
37
44
|
* The types this site may be served, from `resolveAllowedCaptchaTypes`.
|
|
38
45
|
* Set before any path can mint a session, including the short-circuits
|
|
39
46
|
* that skip routing, so the site's feature flags hold on every path.
|
|
40
|
-
* Unset means
|
|
47
|
+
* Unset means the default flags and preferences.
|
|
41
48
|
*/
|
|
42
49
|
setAllowedCaptchaTypes(allowed) {
|
|
43
50
|
this.allowedCaptchaTypes = allowed;
|
|
44
51
|
}
|
|
45
52
|
/**
|
|
53
|
+
* Record that the user asked to swap their puzzle for an image challenge.
|
|
54
|
+
* Only call this once the request has been checked as a refresh of a
|
|
55
|
+
* puzzle on a site with the switch enabled.
|
|
56
|
+
*/
|
|
57
|
+
setImageSwitchRequested(requested) {
|
|
58
|
+
this.imageSwitchRequested = requested;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
46
61
|
* Evaluate the configured routing machine without going through
|
|
47
62
|
* `sendCaptcha`. Returns the supplied baseline on any failure (no machine,
|
|
48
63
|
* machine throws, counter fetch failure), matching applyRouter's contract.
|
|
@@ -96,7 +111,7 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
96
111
|
return require_lang.checkLangRules(this.config, acceptLanguage);
|
|
97
112
|
}
|
|
98
113
|
async createSession(input) {
|
|
99
|
-
const { token, score, threshold, scoreComponents, ipAddress, captchaType, siteKey, mode, solvedImagesCount, powDifficulty, userSitekeyIpHash, reason, blocked, deleted, ipInfo, headers, bundleId, currentUrl, iframeUrl, d, tcpToChelloUs, chelloToHandshakeUs, simdReadings, puzzleTolerance, puzzle, isEscalation, originSessionId, refreshOf, refreshCount, refreshedAfterMs, isProtect, matchedRule, clientMetaData, webView = false, iFrame = false, decryptedHeadHash = "" } = input;
|
|
114
|
+
const { token, score, threshold, scoreComponents, ipAddress, captchaType, siteKey, mode, solvedImagesCount, powDifficulty, userSitekeyIpHash, reason, blocked, deleted, ipInfo, headers, bundleId, currentUrl, iframeUrl, d, tcpToChelloUs, chelloToHandshakeUs, simdReadings, puzzleTolerance, puzzle, iconOrderTolerance, iconOrder, isEscalation, originSessionId, refreshOf, refreshCount, refreshedAfterMs, isProtect, matchedRule, clientMetaData, webView = false, iFrame = false, decryptedHeadHash = "" } = input;
|
|
100
115
|
const sessionRecord = {
|
|
101
116
|
sessionId: `${getSessionIDPrefix(this.config.host)}-${(0, uuid.v4)()}`,
|
|
102
117
|
createdAt: /* @__PURE__ */ new Date(),
|
|
@@ -111,6 +126,8 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
111
126
|
powDifficulty,
|
|
112
127
|
...puzzleTolerance !== void 0 && { puzzleTolerance },
|
|
113
128
|
...puzzle && { puzzle },
|
|
129
|
+
...iconOrderTolerance !== void 0 && { iconOrderTolerance },
|
|
130
|
+
...iconOrder && { iconOrder },
|
|
114
131
|
userSitekeyIpHash,
|
|
115
132
|
webView,
|
|
116
133
|
iFrame,
|
|
@@ -235,6 +252,9 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
235
252
|
async sendPuzzleCaptcha(params) {
|
|
236
253
|
return this.sendCaptcha(_prosopo_types.CaptchaType.puzzle, params);
|
|
237
254
|
}
|
|
255
|
+
async sendIconOrderCaptcha(params) {
|
|
256
|
+
return this.sendCaptcha(_prosopo_types.CaptchaType.iconOrder, params);
|
|
257
|
+
}
|
|
238
258
|
async sendCaptcha(captchaType, params) {
|
|
239
259
|
const effectiveParams = {
|
|
240
260
|
...this.sessionParams,
|
|
@@ -248,13 +268,15 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
248
268
|
};
|
|
249
269
|
const routed = this.routingContext ? await require_routingMachine.applyRouter(this.decisionMachineRunner, this.usageCounters, baseline, this.routingContext, this.logger) : baseline;
|
|
250
270
|
const enabledCaptchaType = require_captchaTypeSelection.coerceToEnabledCaptchaType(routed.captchaType, this.allowedCaptchaTypes, this.logger);
|
|
251
|
-
const
|
|
252
|
-
const
|
|
271
|
+
const userSwitchedCaptchaType = require_captchaTypeSelection.switchTypeOnUserRequest(enabledCaptchaType, this.imageSwitchRequested, this.allowedCaptchaTypes);
|
|
272
|
+
const switchedByUser = userSwitchedCaptchaType !== enabledCaptchaType;
|
|
273
|
+
const finalCaptchaType = require_captchaTypeSelection.switchTypeAfterRefreshes(userSwitchedCaptchaType, effectiveParams.refreshCount, this.allowedCaptchaTypes);
|
|
274
|
+
const switchedByRefreshes = finalCaptchaType !== userSwitchedCaptchaType;
|
|
253
275
|
const requestedSolvedImagesCount = routed.solvedImagesCount ?? effectiveParams.solvedImagesCount;
|
|
254
276
|
const imageRoundsBounds = this.routingContext ?? {};
|
|
255
277
|
const finalSolvedImagesCount = finalCaptchaType === _prosopo_types.CaptchaType.image ? requestedSolvedImagesCount !== void 0 ? (0, _prosopo_types.clampImageRounds)(requestedSolvedImagesCount, imageRoundsBounds) : requestedSolvedImagesCount : void 0;
|
|
256
278
|
const finalPowDifficulty = finalCaptchaType === _prosopo_types.CaptchaType.pow ? routed.powDifficulty ?? effectiveParams.powDifficulty : void 0;
|
|
257
|
-
const finalReason = switchedByRefreshes ? _prosopo_types.FrictionlessReason.PUZZLE_REFRESH_LIMIT : routed.reason ?? effectiveParams.reason;
|
|
279
|
+
const finalReason = switchedByUser ? _prosopo_types.FrictionlessReason.PUZZLE_USER_SWITCH : switchedByRefreshes ? _prosopo_types.FrictionlessReason.PUZZLE_REFRESH_LIMIT : routed.reason ?? effectiveParams.reason;
|
|
258
280
|
const finalPuzzleOverrides = finalCaptchaType === _prosopo_types.CaptchaType.puzzle ? (() => {
|
|
259
281
|
const maxLevel = (0, _prosopo_captcha_severity.resolveMaxEscalationLevel)(this.routingContext?.puzzleMaxDifficulty ?? _prosopo_types.puzzleMaxDifficultyDefault, this.routingContext?.platform.isMobile ?? false);
|
|
260
282
|
const level = finalReason !== void 0 && _prosopo_types.NO_MEASUREMENT_REASONS.has(finalReason) ? 0 : (0, _prosopo_captcha_severity.severityToPuzzleDifficulty)(requestedSolvedImagesCount, this.routingContext?.baseImageRounds ?? this.config.captchas.solved.count, maxLevel);
|
|
@@ -270,6 +292,10 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
270
292
|
...difficulty !== void 0 && { puzzleLevel: difficulty.level }
|
|
271
293
|
};
|
|
272
294
|
})() : {};
|
|
295
|
+
const finalIconOrderOverrides = finalCaptchaType === _prosopo_types.CaptchaType.iconOrder ? {
|
|
296
|
+
...routed.iconOrderTolerance !== void 0 && { iconOrderTolerance: routed.iconOrderTolerance },
|
|
297
|
+
...routed.iconOrder && { iconOrder: routed.iconOrder }
|
|
298
|
+
} : {};
|
|
273
299
|
const blocked = finalCaptchaType === _prosopo_types.CaptchaType.image ? effectiveParams.blocked : void 0;
|
|
274
300
|
const sessionRecord = await this.createSession({
|
|
275
301
|
...effectiveParams,
|
|
@@ -286,6 +312,8 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
286
312
|
blocked,
|
|
287
313
|
puzzleTolerance: finalPuzzleOverrides.puzzleTolerance,
|
|
288
314
|
puzzle: finalPuzzleOverrides.puzzle,
|
|
315
|
+
iconOrderTolerance: finalIconOrderOverrides.iconOrderTolerance,
|
|
316
|
+
iconOrder: finalIconOrderOverrides.iconOrder,
|
|
289
317
|
deleted: void 0,
|
|
290
318
|
isEscalation: void 0,
|
|
291
319
|
originSessionId: void 0
|
|
@@ -295,7 +323,8 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
295
323
|
[_prosopo_types.ApiParams.captchaType]: finalCaptchaType,
|
|
296
324
|
[_prosopo_types.ApiParams.sessionId]: sessionRecord.sessionId,
|
|
297
325
|
[_prosopo_types.ApiParams.status]: "ok",
|
|
298
|
-
dns_url: require_dnsEventUrl.buildDnsEventUrl(sessionRecord.sessionId)
|
|
326
|
+
dns_url: require_dnsEventUrl.buildDnsEventUrl(sessionRecord.sessionId),
|
|
327
|
+
...require_audioAlternative.offersAudioAlternative(finalCaptchaType, this.audioAlternativeEnabled) && { audioAlternativeAvailable: true }
|
|
299
328
|
};
|
|
300
329
|
}
|
|
301
330
|
async registerBlockedSession(params) {
|
|
@@ -318,6 +347,8 @@ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
|
|
|
318
347
|
deleted: true,
|
|
319
348
|
puzzleTolerance: void 0,
|
|
320
349
|
puzzle: void 0,
|
|
350
|
+
iconOrderTolerance: void 0,
|
|
351
|
+
iconOrder: void 0,
|
|
321
352
|
isEscalation: void 0,
|
|
322
353
|
originSessionId: void 0
|
|
323
354
|
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
let _prosopo_types = require("@prosopo/types");
|
|
2
|
+
let _prosopo_puzzle_assets = require("@prosopo/puzzle-assets");
|
|
3
|
+
let _prosopo_icon_order_assets = require("@prosopo/icon-order-assets");
|
|
4
|
+
//#region src/tasks/iconOrder/iconOrderRenderer.ts
|
|
5
|
+
/** Layers partial overrides onto the asset defaults; later sources win. */
|
|
6
|
+
var resolveIconOrderRenderSettings = (...overrides) => {
|
|
7
|
+
let resolved = { ..._prosopo_icon_order_assets.DEFAULT_RENDER_SETTINGS };
|
|
8
|
+
for (const override of overrides) resolved = {
|
|
9
|
+
targetCount: override?.targetCount ?? resolved.targetCount,
|
|
10
|
+
decoyCount: override?.decoyCount ?? resolved.decoyCount,
|
|
11
|
+
strokeWidth: override?.strokeWidth ?? resolved.strokeWidth,
|
|
12
|
+
iconOpacity: override?.iconOpacity ?? resolved.iconOpacity,
|
|
13
|
+
haloOpacity: override?.haloOpacity ?? resolved.haloOpacity,
|
|
14
|
+
backgroundClutter: override?.backgroundClutter ?? resolved.backgroundClutter
|
|
15
|
+
};
|
|
16
|
+
const decoyBudget = _prosopo_types.ICON_ORDER_GLYPH_VOCABULARY - resolved.targetCount;
|
|
17
|
+
if (resolved.decoyCount > decoyBudget) resolved = {
|
|
18
|
+
...resolved,
|
|
19
|
+
decoyCount: Math.max(0, decoyBudget)
|
|
20
|
+
};
|
|
21
|
+
return resolved;
|
|
22
|
+
};
|
|
23
|
+
/** Drops the render-only fields (rotation, hue); grading needs none of them. */
|
|
24
|
+
var toStoredTargets = (targets) => targets.map((target) => ({
|
|
25
|
+
x: target.x,
|
|
26
|
+
y: target.y,
|
|
27
|
+
size: target.size,
|
|
28
|
+
kind: target.kind
|
|
29
|
+
}));
|
|
30
|
+
var renderIconOrderImages = async (settings = _prosopo_icon_order_assets.DEFAULT_RENDER_SETTINGS) => {
|
|
31
|
+
const rendered = await (0, _prosopo_icon_order_assets.renderIconOrder)(_prosopo_icon_order_assets.DEFAULT_GEOMETRY, settings);
|
|
32
|
+
return {
|
|
33
|
+
background: (0, _prosopo_puzzle_assets.toDataUri)(rendered.background),
|
|
34
|
+
legend: (0, _prosopo_puzzle_assets.toDataUri)(rendered.legend),
|
|
35
|
+
legendIconSize: rendered.legendIconSize,
|
|
36
|
+
targets: rendered.targets
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
exports.renderIconOrderImages = renderIconOrderImages;
|
|
41
|
+
exports.resolveIconOrderRenderSettings = resolveIconOrderRenderSettings;
|
|
42
|
+
exports.toStoredTargets = toStoredTargets;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const require_interactiveCaptchaManager = require("../interactiveCaptcha/interactiveCaptchaManager.cjs");
|
|
2
|
+
const require_iconOrderRenderer = require("../iconOrder/iconOrderRenderer.cjs");
|
|
3
|
+
let _prosopo_types = require("@prosopo/types");
|
|
4
|
+
let _prosopo_icon_order_assets = require("@prosopo/icon-order-assets");
|
|
5
|
+
//#region src/tasks/iconOrderCaptcha/iconOrderTasks.ts
|
|
6
|
+
var IconOrderCaptchaManager = class extends require_interactiveCaptchaManager.InteractiveCaptchaManager {
|
|
7
|
+
constructor(..._args) {
|
|
8
|
+
super(..._args);
|
|
9
|
+
this.captchaType = _prosopo_types.CaptchaType.iconOrder;
|
|
10
|
+
this.logLabel = "icon-order";
|
|
11
|
+
}
|
|
12
|
+
getRecordByChallenge(challenge) {
|
|
13
|
+
return this.db.getIconOrderCaptchaRecordByChallenge(challenge);
|
|
14
|
+
}
|
|
15
|
+
updateRecord(challenge, updates) {
|
|
16
|
+
return this.db.updateIconOrderCaptchaRecord(challenge, updates);
|
|
17
|
+
}
|
|
18
|
+
updateSubmissionResult(challenge, result, userSignature, coords) {
|
|
19
|
+
return this.db.updateIconOrderCaptchaRecordResult(challenge, result, false, true, userSignature, coords);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* An atomic claim rather than a read of `userSubmitted`: concurrent
|
|
23
|
+
* submissions would all read it unset and each get a verdict, enough to
|
|
24
|
+
* enumerate the ordering of a handful of icons.
|
|
25
|
+
*/
|
|
26
|
+
claimSubmission(record) {
|
|
27
|
+
return this.db.claimIconOrderCaptchaSubmission(record.challenge);
|
|
28
|
+
}
|
|
29
|
+
markRecordChecked(challenge) {
|
|
30
|
+
return this.db.markIconOrderCaptchaRecordChecked(challenge);
|
|
31
|
+
}
|
|
32
|
+
decisionMachineEventFields(record) {
|
|
33
|
+
return { iconOrderEvents: record.iconOrderEvents };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The renderer decides where the icons land, so the answer only exists
|
|
37
|
+
* once the imagery does; the caller must store `targets` before responding.
|
|
38
|
+
*/
|
|
39
|
+
async getIconOrderCaptchaChallenge(userAccount, dappAccount, tolerance, renderImages) {
|
|
40
|
+
const minted = this.mintChallenge(userAccount, dappAccount);
|
|
41
|
+
const { targets, ...images } = await renderImages();
|
|
42
|
+
return {
|
|
43
|
+
...minted,
|
|
44
|
+
targets: require_iconOrderRenderer.toStoredTargets(targets),
|
|
45
|
+
tolerance: tolerance ?? _prosopo_types.iconOrderToleranceDefault,
|
|
46
|
+
images
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async verifyIconOrderCaptchaSolution(challenge, providerChallengeSignature, clicks, iconOrderEvents, timeout, userTimestampSignature, ipAddress, behavioralData, salt, simdReadings, clientMetaData) {
|
|
50
|
+
return this.submitInteractiveCaptchaSolution({
|
|
51
|
+
challenge,
|
|
52
|
+
providerChallengeSignature,
|
|
53
|
+
timeout,
|
|
54
|
+
userTimestampSignature,
|
|
55
|
+
ipAddress,
|
|
56
|
+
behavioralData,
|
|
57
|
+
salt,
|
|
58
|
+
simdReadings,
|
|
59
|
+
clientMetaData,
|
|
60
|
+
isCorrect: (record) => (0, _prosopo_icon_order_assets.gradeClicks)(record.targets, clicks, record.tolerance),
|
|
61
|
+
persistInteraction: () => this.db.updateIconOrderCaptchaRecord(challenge, {
|
|
62
|
+
clicks,
|
|
63
|
+
iconOrderEvents
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
//#endregion
|
|
69
|
+
exports.IconOrderCaptchaManager = IconOrderCaptchaManager;
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
const require_usageCounters = require("../../util/usageCounters.cjs");
|
|
2
|
-
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
3
2
|
const require_rawTlsSignalsMiddleware = require("../../api/rawTlsSignalsMiddleware.cjs");
|
|
4
|
-
const require_lang = require("../../rules/lang.cjs");
|
|
5
|
-
const require_clientMetaData = require("../../utils/clientMetaData.cjs");
|
|
6
3
|
const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
|
|
7
|
-
const require_enrichDnsEvent = require("../dnsEvent/enrichDnsEvent.cjs");
|
|
8
|
-
const require_captchaManager = require("../captchaManager.cjs");
|
|
9
|
-
const require_pairs = require("../../pairs.cjs");
|
|
10
4
|
const require_util = require("../../util.cjs");
|
|
5
|
+
const require_clientMetaData = require("../../utils/clientMetaData.cjs");
|
|
11
6
|
const require_devicePlatform = require("../../utils/devicePlatform.cjs");
|
|
7
|
+
const require_enrichDnsEvent = require("../dnsEvent/enrichDnsEvent.cjs");
|
|
8
|
+
const require_captchaManager = require("../captchaManager.cjs");
|
|
9
|
+
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
12
10
|
const require_frictionlessTasksUtils = require("../frictionless/frictionlessTasksUtils.cjs");
|
|
13
11
|
const require_evaluateEmailSpamRules = require("../spam/evaluateEmailSpamRules.cjs");
|
|
12
|
+
const require_lang = require("../../rules/lang.cjs");
|
|
13
|
+
const require_pairs = require("../../pairs.cjs");
|
|
14
14
|
const require_imgCaptchaTasksUtils = require("./imgCaptchaTasksUtils.cjs");
|
|
15
15
|
let _prosopo_common = require("@prosopo/common");
|
|
16
16
|
let _prosopo_types = require("@prosopo/types");
|
|
17
|
+
let _polkadot_util = require("@polkadot/util");
|
|
18
|
+
let _prosopo_user_access_policy = require("@prosopo/user-access-policy");
|
|
17
19
|
let _prosopo_util = require("@prosopo/util");
|
|
18
20
|
let _prosopo_util_crypto = require("@prosopo/util-crypto");
|
|
19
21
|
let _prosopo_datasets = require("@prosopo/datasets");
|
|
20
|
-
let _prosopo_user_access_policy = require("@prosopo/user-access-policy");
|
|
21
|
-
let _polkadot_util = require("@polkadot/util");
|
|
22
22
|
//#region src/tasks/imgCaptcha/imgCaptchaTasks.ts
|
|
23
23
|
var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
24
24
|
constructor(db, pair, config, logger, writeQueue, usageCounters) {
|