@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,3 +1,4 @@
|
|
|
1
|
+
let _prosopo_types = require("@prosopo/types");
|
|
1
2
|
//#region src/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.ts
|
|
2
3
|
/**
|
|
3
4
|
* Work out where a refresh sits in its chain from the session it replaced.
|
|
@@ -11,10 +12,20 @@ var resolveRefreshLineage = async (db, refreshOf, siteKey, now) => {
|
|
|
11
12
|
const replaced = await db.getSessionRecordBySessionId(refreshOf);
|
|
12
13
|
if (!replaced || replaced.siteKey !== siteKey) return void 0;
|
|
13
14
|
return {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
lineage: {
|
|
16
|
+
refreshOf,
|
|
17
|
+
refreshCount: (replaced.refreshCount ?? 0) + 1,
|
|
18
|
+
refreshedAfterMs: Math.max(0, now.getTime() - new Date(replaced.createdAt).getTime())
|
|
19
|
+
},
|
|
20
|
+
replacedCaptchaType: replaced.captchaType
|
|
17
21
|
};
|
|
18
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Whether to honour the user's request to swap their puzzle for an image
|
|
25
|
+
* challenge: the request must be a genuine refresh of a puzzle session on
|
|
26
|
+
* this site, and the site must have the switch enabled.
|
|
27
|
+
*/
|
|
28
|
+
var isImageSwitchRequestValid = (switchToImage, refresh, switchEnabled) => true === switchToImage && switchEnabled && _prosopo_types.CaptchaType.puzzle === refresh?.replacedCaptchaType;
|
|
19
29
|
//#endregion
|
|
30
|
+
exports.isImageSwitchRequestValid = isImageSwitchRequestValid;
|
|
20
31
|
exports.resolveRefreshLineage = resolveRefreshLineage;
|
|
@@ -68,6 +68,7 @@ var runConfiguredCaptchaTypeShortCircuit = async (input, res) => {
|
|
|
68
68
|
}));
|
|
69
69
|
case _prosopo_types.CaptchaType.pow: return res.json(await input.tasks.frictionlessManager.sendPowCaptcha(sessionParams));
|
|
70
70
|
case _prosopo_types.CaptchaType.puzzle: return res.json(await input.tasks.frictionlessManager.sendPuzzleCaptcha(sessionParams));
|
|
71
|
+
case _prosopo_types.CaptchaType.iconOrder: return res.json(await input.tasks.frictionlessManager.sendIconOrderCaptcha(sessionParams));
|
|
71
72
|
default: throw new Error(`Unhandled configured captchaType in /frictionless short-circuit: ${configuredType}`);
|
|
72
73
|
}
|
|
73
74
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const require_iconOrderRenderer = require("../../tasks/iconOrder/iconOrderRenderer.cjs");
|
|
2
|
+
const require_interactiveCaptchaChallenge = require("./interactiveCaptchaChallenge.cjs");
|
|
3
|
+
const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
|
|
4
|
+
let _prosopo_types = require("@prosopo/types");
|
|
5
|
+
//#region src/api/captcha/getIconOrderCaptchaChallenge.ts
|
|
6
|
+
var issueIconOrderChallenge = async ({ tasks, user, dapp, clientSettings, sessionRecord, trafficVerdict, provenance }) => {
|
|
7
|
+
const challengeVerdict = trafficVerdict.kind === "challenge" ? trafficVerdict : void 0;
|
|
8
|
+
const tolerance = challengeVerdict?.iconOrderTolerance ?? sessionRecord?.iconOrderTolerance ?? clientSettings?.settings?.iconOrderTolerance;
|
|
9
|
+
const renderSettings = require_iconOrderRenderer.resolveIconOrderRenderSettings(clientSettings?.settings?.iconOrder, challengeVerdict?.iconOrderSettings ?? sessionRecord?.iconOrder);
|
|
10
|
+
const challenge = await tasks.iconOrderCaptchaManager.getIconOrderCaptchaChallenge(user, dapp, tolerance, () => require_iconOrderRenderer.renderIconOrderImages(renderSettings));
|
|
11
|
+
await tasks.db.storeIconOrderCaptchaRecord(challenge.challenge, {
|
|
12
|
+
requestedAtTimestamp: challenge.requestedAtTimestamp,
|
|
13
|
+
userAccount: user,
|
|
14
|
+
dappAccount: dapp
|
|
15
|
+
}, challenge.targets, challenge.tolerance, challenge.providerSignature, provenance.ipAddress, provenance.headers, provenance.ja4, provenance.sessionId, provenance.ipInfo);
|
|
16
|
+
return {
|
|
17
|
+
logData: { tolerance: challenge.tolerance },
|
|
18
|
+
response: {
|
|
19
|
+
[_prosopo_types.ApiParams.status]: "ok",
|
|
20
|
+
[_prosopo_types.ApiParams.challenge]: challenge.challenge,
|
|
21
|
+
[_prosopo_types.ApiParams.background]: challenge.images.background,
|
|
22
|
+
[_prosopo_types.ApiParams.legend]: challenge.images.legend,
|
|
23
|
+
[_prosopo_types.ApiParams.legendIconSize]: challenge.images.legendIconSize,
|
|
24
|
+
[_prosopo_types.ApiParams.timestamp]: challenge.requestedAtTimestamp.toString(),
|
|
25
|
+
[_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: challenge.providerSignature } }
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
var getIconOrderCaptchaChallenge_default = (env, userAccessRulesStorage) => require_interactiveCaptchaChallenge.interactiveChallengeHandler(env, userAccessRulesStorage, {
|
|
30
|
+
captchaType: _prosopo_types.CaptchaType.iconOrder,
|
|
31
|
+
label: "icon-order",
|
|
32
|
+
manager: (tasks) => tasks.iconOrderCaptchaManager,
|
|
33
|
+
maintenanceResponse: require_maintenanceModeResponses.buildIconOrderMaintenanceResponse,
|
|
34
|
+
issue: issueIconOrderChallenge
|
|
35
|
+
});
|
|
36
|
+
//#endregion
|
|
37
|
+
exports.default = getIconOrderCaptchaChallenge_default;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const require_validateAddress = require("../validateAddress.cjs");
|
|
2
1
|
const require_metrics = require("../metrics.cjs");
|
|
3
2
|
const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
|
|
3
|
+
const require_validateAddress = require("../validateAddress.cjs");
|
|
4
4
|
const require_tasks = require("../../tasks/tasks.cjs");
|
|
5
5
|
const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
|
|
6
6
|
const require_testSiteKey = require("../testSiteKey.cjs");
|
|
7
7
|
const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
|
|
8
|
-
const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
|
|
9
8
|
const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
|
|
9
|
+
const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
|
|
10
10
|
const require_sealedAssetsResolver = require("./sealedAssetsResolver.cjs");
|
|
11
11
|
const require_signedAssetsResolver = require("./signedAssetsResolver.cjs");
|
|
12
12
|
let _prosopo_common = require("@prosopo/common");
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
const require_validateAddress = require("../validateAddress.cjs");
|
|
2
|
-
const require_metrics = require("../metrics.cjs");
|
|
3
1
|
const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
|
|
2
|
+
const require_metrics = require("../metrics.cjs");
|
|
4
3
|
const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
|
|
4
|
+
const require_validateAddress = require("../validateAddress.cjs");
|
|
5
5
|
const require_tasks = require("../../tasks/tasks.cjs");
|
|
6
6
|
const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
|
|
7
7
|
const require_testSiteKey = require("../testSiteKey.cjs");
|
|
8
8
|
const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
|
|
9
|
-
const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
|
|
10
|
-
const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
|
|
11
9
|
const require_requestBodySummary = require("../requestBodySummary.cjs");
|
|
10
|
+
const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
|
|
11
|
+
const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
|
|
12
12
|
let _prosopo_common = require("@prosopo/common");
|
|
13
13
|
let _prosopo_types = require("@prosopo/types");
|
|
14
14
|
let _prosopo_util = require("@prosopo/util");
|
|
@@ -1,144 +1,52 @@
|
|
|
1
|
-
const require_validateAddress = require("../validateAddress.cjs");
|
|
2
|
-
const require_metrics = require("../metrics.cjs");
|
|
3
|
-
const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
|
|
4
|
-
const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
|
|
5
1
|
const require_puzzleRenderer = require("../../tasks/puzzle/puzzleRenderer.cjs");
|
|
6
|
-
const
|
|
7
|
-
const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
|
|
8
|
-
const require_testSiteKey = require("../testSiteKey.cjs");
|
|
9
|
-
const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
|
|
2
|
+
const require_interactiveCaptchaChallenge = require("./interactiveCaptchaChallenge.cjs");
|
|
10
3
|
const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
|
|
11
|
-
const
|
|
12
|
-
const require_requestBodySummary = require("../requestBodySummary.cjs");
|
|
13
|
-
let _prosopo_common = require("@prosopo/common");
|
|
4
|
+
const require_constants = require("./getFrictionlessCaptchaChallenge/constants.cjs");
|
|
14
5
|
let _prosopo_types = require("@prosopo/types");
|
|
15
|
-
let _prosopo_util = require("@prosopo/util");
|
|
16
6
|
let _prosopo_puzzle_assets = require("@prosopo/puzzle-assets");
|
|
17
7
|
//#region src/api/captcha/getPuzzleCaptchaChallenge.ts
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
8
|
+
var issuePuzzleChallenge = async ({ tasks, user, dapp, origin, clientSettings, sessionRecord, trafficVerdict, provenance }) => {
|
|
9
|
+
const challengeVerdict = trafficVerdict.kind === "challenge" ? trafficVerdict : void 0;
|
|
10
|
+
const tolerance = challengeVerdict?.puzzleTolerance ?? sessionRecord?.puzzleTolerance ?? clientSettings?.settings?.puzzleTolerance;
|
|
11
|
+
const routedPuzzleSettings = challengeVerdict?.puzzleSettings ?? sessionRecord?.puzzle;
|
|
12
|
+
const effectivePuzzleSettings = require_puzzleRenderer.resolvePuzzleRenderSettings(clientSettings?.settings?.puzzle, routedPuzzleSettings);
|
|
13
|
+
const effectivePieceSize = require_puzzleRenderer.resolvePuzzlePieceSize(clientSettings?.settings?.puzzle, routedPuzzleSettings);
|
|
14
|
+
const challenge = await tasks.puzzleCaptchaManager.getPuzzleCaptchaChallenge(user, dapp, origin, tolerance);
|
|
15
|
+
await tasks.db.storePuzzleCaptchaRecord(challenge.challenge, {
|
|
16
|
+
requestedAtTimestamp: challenge.requestedAtTimestamp,
|
|
17
|
+
userAccount: user,
|
|
18
|
+
dappAccount: dapp
|
|
19
|
+
}, challenge.targetX, challenge.targetY, challenge.originX, challenge.originY, challenge.tolerance, challenge.providerSignature, provenance.ipAddress, provenance.headers, provenance.ja4, provenance.sessionId, provenance.ipInfo);
|
|
20
|
+
const images = await require_puzzleRenderer.renderPuzzleImages({
|
|
21
|
+
targetX: challenge.targetX,
|
|
22
|
+
targetY: challenge.targetY
|
|
23
|
+
}, effectivePuzzleSettings, effectivePieceSize);
|
|
24
|
+
await tasks.db.updatePuzzleCaptchaRecord(challenge.challenge, { render: {
|
|
25
|
+
...sessionRecord?.puzzleLevel !== void 0 && { level: sessionRecord.puzzleLevel },
|
|
26
|
+
pieceSize: images.pieceSize,
|
|
27
|
+
geometry: {
|
|
28
|
+
width: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.width,
|
|
29
|
+
height: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.height,
|
|
30
|
+
notchSize: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.notchSize
|
|
31
|
+
},
|
|
32
|
+
settings: {
|
|
33
|
+
decoyCount: effectivePuzzleSettings.decoyCount,
|
|
34
|
+
decoyEdgeDarkness: effectivePuzzleSettings.decoyEdgeDarkness,
|
|
35
|
+
decoyBodyBrightness: effectivePuzzleSettings.decoyBodyBrightness,
|
|
36
|
+
holeDarken: effectivePuzzleSettings.holeDarken,
|
|
37
|
+
decoyHoleDarken: effectivePuzzleSettings.decoyHoleDarken
|
|
38
|
+
},
|
|
39
|
+
backgroundSeed: images.backgroundSeed,
|
|
40
|
+
renderSeed: images.renderSeed
|
|
41
|
+
} }).catch((updateErr) => {
|
|
42
|
+
tasks.logger.warn(() => ({
|
|
43
|
+
err: updateErr,
|
|
44
|
+
msg: "Failed to patch puzzle render inputs onto the challenge record"
|
|
30
45
|
}));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
|
|
36
|
-
req.logger.info(() => ({
|
|
37
|
-
msg: "Maintenance mode active - returning dummy puzzle challenge",
|
|
38
|
-
data: {
|
|
39
|
-
dapp,
|
|
40
|
-
user,
|
|
41
|
-
sessionId
|
|
42
|
-
}
|
|
43
|
-
}));
|
|
44
|
-
return res.json(await require_maintenanceModeResponses.buildPuzzleMaintenanceResponse(user, dapp));
|
|
45
|
-
}
|
|
46
|
-
if (require_testSiteKey.isReservedTestSiteKey(dapp)) {
|
|
47
|
-
req.logger.warn(() => ({
|
|
48
|
-
msg: "Reserved TEST site key - returning dummy puzzle challenge",
|
|
49
|
-
data: {
|
|
50
|
-
dapp,
|
|
51
|
-
user,
|
|
52
|
-
sessionId
|
|
53
|
-
}
|
|
54
|
-
}));
|
|
55
|
-
return res.json(await require_maintenanceModeResponses.buildPuzzleMaintenanceResponse(user, dapp));
|
|
56
|
-
}
|
|
57
|
-
const tasks = new require_tasks.Tasks(env, req.logger);
|
|
58
|
-
try {
|
|
59
|
-
const clientSettings = await tasks.db.getClientRecord(dapp);
|
|
60
|
-
if (!clientSettings) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
|
|
61
|
-
context: {
|
|
62
|
-
code: 400,
|
|
63
|
-
siteKey: dapp
|
|
64
|
-
},
|
|
65
|
-
i18n: req.i18n,
|
|
66
|
-
logger: req.logger
|
|
67
|
-
}));
|
|
68
|
-
const normalizedIp = require_normalizeRequestIp.normalizeRequestIp(req.ip, req.logger);
|
|
69
|
-
if (!normalizedIp) req.logger.warn(() => ({ msg: "Request missing IP; geoblocking will be skipped" }));
|
|
70
|
-
const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
|
|
71
|
-
const asn = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.asnNumber : void 0;
|
|
72
|
-
const sessionRecord = sessionId ? await tasks.db.getSessionRecordBySessionId(sessionId) : void 0;
|
|
73
|
-
const userScope = require_blacklistRequestInspector.getRequestUserScope((0, _prosopo_util.flatten)(req.headers), req.ja4, normalizedIp, user, sessionRecord?.decryptedHeadHash, void 0, countryCode, asn);
|
|
74
|
-
const userAccessPolicy = (await tasks.puzzleCaptchaManager.getPrioritisedAccessPolicies(userAccessRulesStorage, dapp, userScope, require_blacklistRequestInspector.normalizeHeadersForMatching(req.headers))).find((p) => !p.deferToVerify);
|
|
75
|
-
const { valid, reason, sessionId: validSessionId } = await tasks.puzzleCaptchaManager.isValidRequest(clientSettings, _prosopo_types.CaptchaType.puzzle, env, sessionId, userAccessPolicy, normalizedIp);
|
|
76
|
-
if (!valid) return next(new _prosopo_common.ProsopoApiError(reason || "API.BAD_REQUEST", {
|
|
77
|
-
context: {
|
|
78
|
-
code: 400,
|
|
79
|
-
siteKey: dapp,
|
|
80
|
-
user
|
|
81
|
-
},
|
|
82
|
-
i18n: req.i18n,
|
|
83
|
-
logger: req.logger
|
|
84
|
-
}));
|
|
85
|
-
const origin = req.headers.origin;
|
|
86
|
-
if (!origin) return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
|
|
87
|
-
context: {
|
|
88
|
-
error: "Origin header not found",
|
|
89
|
-
code: 400,
|
|
90
|
-
siteKey: dapp,
|
|
91
|
-
user
|
|
92
|
-
},
|
|
93
|
-
i18n: req.i18n,
|
|
94
|
-
logger: req.logger
|
|
95
|
-
}));
|
|
96
|
-
const trafficVerdict = require_trafficFilterRequestTime.applyTrafficFilterAtRequestTime(req.ipInfo, clientSettings.settings?.trafficFilter, req.logger);
|
|
97
|
-
const tolerance = (trafficVerdict.kind === "challenge" ? trafficVerdict.puzzleTolerance : void 0) ?? sessionRecord?.puzzleTolerance ?? clientSettings?.settings?.puzzleTolerance;
|
|
98
|
-
const routedPuzzleSettings = (trafficVerdict.kind === "challenge" ? trafficVerdict.puzzleSettings : void 0) ?? sessionRecord?.puzzle;
|
|
99
|
-
const effectivePuzzleSettings = require_puzzleRenderer.resolvePuzzleRenderSettings(clientSettings?.settings?.puzzle, routedPuzzleSettings);
|
|
100
|
-
const effectivePieceSize = require_puzzleRenderer.resolvePuzzlePieceSize(clientSettings?.settings?.puzzle, routedPuzzleSettings);
|
|
101
|
-
const challenge = await tasks.puzzleCaptchaManager.getPuzzleCaptchaChallenge(user, dapp, origin, tolerance);
|
|
102
|
-
if (validSessionId && simdReadings) await tasks.frictionlessManager.decryptAndAttachSimdReadingsIfAbsent(validSessionId, simdReadings, _prosopo_types.SimdReadingsStage.challenge).catch((updateErr) => {
|
|
103
|
-
req.logger.warn(() => ({
|
|
104
|
-
err: updateErr,
|
|
105
|
-
msg: "Failed to patch session with SIMD readings on puzzle challenge"
|
|
106
|
-
}));
|
|
107
|
-
});
|
|
108
|
-
await tasks.db.storePuzzleCaptchaRecord(challenge.challenge, {
|
|
109
|
-
requestedAtTimestamp: challenge.requestedAtTimestamp,
|
|
110
|
-
userAccount: user,
|
|
111
|
-
dappAccount: dapp
|
|
112
|
-
}, challenge.targetX, challenge.targetY, challenge.originX, challenge.originY, challenge.tolerance, challenge.providerSignature, require_compositeIpAddress.getCompositeIpAddress(normalizedIp), (0, _prosopo_util.flatten)(req.headers), req.ja4, validSessionId, req.ipInfo);
|
|
113
|
-
const images = await require_puzzleRenderer.renderPuzzleImages({
|
|
114
|
-
targetX: challenge.targetX,
|
|
115
|
-
targetY: challenge.targetY
|
|
116
|
-
}, effectivePuzzleSettings, effectivePieceSize);
|
|
117
|
-
await tasks.db.updatePuzzleCaptchaRecord(challenge.challenge, { render: {
|
|
118
|
-
...sessionRecord?.puzzleLevel !== void 0 && { level: sessionRecord.puzzleLevel },
|
|
119
|
-
pieceSize: images.pieceSize,
|
|
120
|
-
geometry: {
|
|
121
|
-
width: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.width,
|
|
122
|
-
height: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.height,
|
|
123
|
-
notchSize: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.notchSize
|
|
124
|
-
},
|
|
125
|
-
settings: {
|
|
126
|
-
decoyCount: effectivePuzzleSettings.decoyCount,
|
|
127
|
-
decoyEdgeDarkness: effectivePuzzleSettings.decoyEdgeDarkness,
|
|
128
|
-
decoyBodyBrightness: effectivePuzzleSettings.decoyBodyBrightness,
|
|
129
|
-
holeDarken: effectivePuzzleSettings.holeDarken,
|
|
130
|
-
decoyHoleDarken: effectivePuzzleSettings.decoyHoleDarken
|
|
131
|
-
},
|
|
132
|
-
backgroundSeed: images.backgroundSeed,
|
|
133
|
-
renderSeed: images.renderSeed
|
|
134
|
-
} }).catch((updateErr) => {
|
|
135
|
-
req.logger.warn(() => ({
|
|
136
|
-
err: updateErr,
|
|
137
|
-
msg: "Failed to patch puzzle render inputs onto the challenge record"
|
|
138
|
-
}));
|
|
139
|
-
});
|
|
140
|
-
const padBytes = trafficVerdict.padBytes;
|
|
141
|
-
const getPuzzleCaptchaResponse = {
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
logData: { tolerance: challenge.tolerance },
|
|
49
|
+
response: {
|
|
142
50
|
[_prosopo_types.ApiParams.status]: "ok",
|
|
143
51
|
[_prosopo_types.ApiParams.challenge]: challenge.challenge,
|
|
144
52
|
[_prosopo_types.ApiParams.background]: images.background,
|
|
@@ -147,40 +55,17 @@ var getPuzzleCaptchaChallenge_default = (env, userAccessRulesStorage) => async (
|
|
|
147
55
|
[_prosopo_types.ApiParams.originX]: challenge.originX,
|
|
148
56
|
[_prosopo_types.ApiParams.originY]: challenge.originY,
|
|
149
57
|
[_prosopo_types.ApiParams.timestamp]: challenge.requestedAtTimestamp.toString(),
|
|
150
|
-
[_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: challenge.providerSignature } }
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
data: {
|
|
155
|
-
captchaType: _prosopo_types.CaptchaType.puzzle,
|
|
156
|
-
challenge: challenge.challenge,
|
|
157
|
-
tolerance: challenge.tolerance,
|
|
158
|
-
user,
|
|
159
|
-
dapp,
|
|
160
|
-
session: sessionId
|
|
161
|
-
}
|
|
162
|
-
}));
|
|
163
|
-
res.locals.padBytes = padBytes;
|
|
164
|
-
require_metrics.recordCaptchaIssued(_prosopo_types.CaptchaType.puzzle);
|
|
165
|
-
return res.json(getPuzzleCaptchaResponse);
|
|
166
|
-
} catch (err) {
|
|
167
|
-
require_metrics.recordCaptchaIssueError(_prosopo_types.CaptchaType.puzzle);
|
|
168
|
-
req.logger.error(() => ({
|
|
169
|
-
err,
|
|
170
|
-
body: require_requestBodySummary.summariseRequestBody(req),
|
|
171
|
-
msg: "Error in puzzle captcha challenge request"
|
|
172
|
-
}));
|
|
173
|
-
return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
|
|
174
|
-
context: {
|
|
175
|
-
code: 500,
|
|
176
|
-
siteKey: req.body.dapp,
|
|
177
|
-
user: req.body.user,
|
|
178
|
-
error: err
|
|
179
|
-
},
|
|
180
|
-
i18n: req.i18n,
|
|
181
|
-
logger: req.logger
|
|
182
|
-
}));
|
|
183
|
-
}
|
|
58
|
+
[_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: challenge.providerSignature } },
|
|
59
|
+
...require_constants.isPuzzleImageSwitchAvailable(clientSettings?.settings ?? {}) && { [_prosopo_types.ApiParams.imageSwitchAvailable]: true }
|
|
60
|
+
}
|
|
61
|
+
};
|
|
184
62
|
};
|
|
63
|
+
var getPuzzleCaptchaChallenge_default = (env, userAccessRulesStorage) => require_interactiveCaptchaChallenge.interactiveChallengeHandler(env, userAccessRulesStorage, {
|
|
64
|
+
captchaType: _prosopo_types.CaptchaType.puzzle,
|
|
65
|
+
label: "puzzle",
|
|
66
|
+
manager: (tasks) => tasks.puzzleCaptchaManager,
|
|
67
|
+
maintenanceResponse: require_maintenanceModeResponses.buildPuzzleMaintenanceResponse,
|
|
68
|
+
issue: issuePuzzleChallenge
|
|
69
|
+
});
|
|
185
70
|
//#endregion
|
|
186
71
|
exports.default = getPuzzleCaptchaChallenge_default;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
|
|
2
|
+
const require_metrics = require("../metrics.cjs");
|
|
3
|
+
const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
|
|
4
|
+
const require_validateAddress = require("../validateAddress.cjs");
|
|
5
|
+
const require_tasks = require("../../tasks/tasks.cjs");
|
|
6
|
+
const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
|
|
7
|
+
const require_testSiteKey = require("../testSiteKey.cjs");
|
|
8
|
+
const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
|
|
9
|
+
const require_requestBodySummary = require("../requestBodySummary.cjs");
|
|
10
|
+
const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
|
|
11
|
+
let _prosopo_common = require("@prosopo/common");
|
|
12
|
+
let _prosopo_types = require("@prosopo/types");
|
|
13
|
+
let _prosopo_util = require("@prosopo/util");
|
|
14
|
+
//#region src/api/captcha/interactiveCaptchaChallenge.ts
|
|
15
|
+
var capitalise = (text) => text.charAt(0).toUpperCase() + text.slice(1);
|
|
16
|
+
/** Request handling shared by the challenge endpoints of the interactive types. */
|
|
17
|
+
var interactiveChallengeHandler = (env, userAccessRulesStorage, spec) => async (req, res, next) => {
|
|
18
|
+
const { captchaType, label } = spec;
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = _prosopo_types.GetPuzzleCaptchaChallengeRequestBody.parse(req.body);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
|
|
24
|
+
context: {
|
|
25
|
+
code: 400,
|
|
26
|
+
error: err
|
|
27
|
+
},
|
|
28
|
+
i18n: req.i18n,
|
|
29
|
+
logger: req.logger
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
const { user, dapp, sessionId, simdReadings } = parsed;
|
|
33
|
+
require_validateAddress.validateSiteKey(dapp);
|
|
34
|
+
require_validateAddress.validateAddr(user);
|
|
35
|
+
if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
|
|
36
|
+
req.logger.info(() => ({
|
|
37
|
+
msg: `Maintenance mode active - returning dummy ${label} challenge`,
|
|
38
|
+
data: {
|
|
39
|
+
dapp,
|
|
40
|
+
user,
|
|
41
|
+
sessionId
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
return res.json(await spec.maintenanceResponse(user, dapp));
|
|
45
|
+
}
|
|
46
|
+
if (require_testSiteKey.isReservedTestSiteKey(dapp)) {
|
|
47
|
+
req.logger.warn(() => ({
|
|
48
|
+
msg: `Reserved TEST site key - returning dummy ${label} challenge`,
|
|
49
|
+
data: {
|
|
50
|
+
dapp,
|
|
51
|
+
user,
|
|
52
|
+
sessionId
|
|
53
|
+
}
|
|
54
|
+
}));
|
|
55
|
+
return res.json(await spec.maintenanceResponse(user, dapp));
|
|
56
|
+
}
|
|
57
|
+
const tasks = new require_tasks.Tasks(env, req.logger);
|
|
58
|
+
const manager = spec.manager(tasks);
|
|
59
|
+
try {
|
|
60
|
+
const clientSettings = await tasks.db.getClientRecord(dapp);
|
|
61
|
+
if (!clientSettings) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
|
|
62
|
+
context: {
|
|
63
|
+
code: 400,
|
|
64
|
+
siteKey: dapp
|
|
65
|
+
},
|
|
66
|
+
i18n: req.i18n,
|
|
67
|
+
logger: req.logger
|
|
68
|
+
}));
|
|
69
|
+
const normalizedIp = require_normalizeRequestIp.normalizeRequestIp(req.ip, req.logger);
|
|
70
|
+
if (!normalizedIp) req.logger.warn(() => ({ msg: "Request missing IP; geoblocking will be skipped" }));
|
|
71
|
+
const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
|
|
72
|
+
const asn = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.asnNumber : void 0;
|
|
73
|
+
const sessionRecord = sessionId ? await tasks.db.getSessionRecordBySessionId(sessionId) : void 0;
|
|
74
|
+
const userScope = require_blacklistRequestInspector.getRequestUserScope((0, _prosopo_util.flatten)(req.headers), req.ja4, normalizedIp, user, sessionRecord?.decryptedHeadHash, void 0, countryCode, asn);
|
|
75
|
+
const userAccessPolicy = (await manager.getPrioritisedAccessPolicies(userAccessRulesStorage, dapp, userScope, require_blacklistRequestInspector.normalizeHeadersForMatching(req.headers))).find((p) => !p.deferToVerify);
|
|
76
|
+
const { valid, reason, sessionId: validSessionId } = await manager.isValidRequest(clientSettings, captchaType, env, sessionId, userAccessPolicy, normalizedIp);
|
|
77
|
+
if (!valid) return next(new _prosopo_common.ProsopoApiError(reason || "API.BAD_REQUEST", {
|
|
78
|
+
context: {
|
|
79
|
+
code: 400,
|
|
80
|
+
siteKey: dapp,
|
|
81
|
+
user
|
|
82
|
+
},
|
|
83
|
+
i18n: req.i18n,
|
|
84
|
+
logger: req.logger
|
|
85
|
+
}));
|
|
86
|
+
const origin = req.headers.origin;
|
|
87
|
+
if (!origin) return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
|
|
88
|
+
context: {
|
|
89
|
+
error: "Origin header not found",
|
|
90
|
+
code: 400,
|
|
91
|
+
siteKey: dapp,
|
|
92
|
+
user
|
|
93
|
+
},
|
|
94
|
+
i18n: req.i18n,
|
|
95
|
+
logger: req.logger
|
|
96
|
+
}));
|
|
97
|
+
const trafficVerdict = require_trafficFilterRequestTime.applyTrafficFilterAtRequestTime(req.ipInfo, clientSettings.settings?.trafficFilter, req.logger);
|
|
98
|
+
if (validSessionId && simdReadings) await tasks.frictionlessManager.decryptAndAttachSimdReadingsIfAbsent(validSessionId, simdReadings, _prosopo_types.SimdReadingsStage.challenge).catch((updateErr) => {
|
|
99
|
+
req.logger.warn(() => ({
|
|
100
|
+
err: updateErr,
|
|
101
|
+
msg: `Failed to patch session with SIMD readings on ${label} challenge`
|
|
102
|
+
}));
|
|
103
|
+
});
|
|
104
|
+
const { response, logData } = await spec.issue({
|
|
105
|
+
tasks,
|
|
106
|
+
user,
|
|
107
|
+
dapp,
|
|
108
|
+
origin,
|
|
109
|
+
clientSettings,
|
|
110
|
+
sessionRecord,
|
|
111
|
+
trafficVerdict,
|
|
112
|
+
provenance: {
|
|
113
|
+
ipAddress: require_compositeIpAddress.getCompositeIpAddress(normalizedIp),
|
|
114
|
+
headers: (0, _prosopo_util.flatten)(req.headers),
|
|
115
|
+
ja4: req.ja4,
|
|
116
|
+
sessionId: validSessionId,
|
|
117
|
+
ipInfo: req.ipInfo
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
req.logger.info(() => ({
|
|
121
|
+
msg: `${capitalise(label)} captcha challenge issued`,
|
|
122
|
+
data: {
|
|
123
|
+
captchaType,
|
|
124
|
+
challenge: response.challenge,
|
|
125
|
+
...logData,
|
|
126
|
+
user,
|
|
127
|
+
dapp,
|
|
128
|
+
session: sessionId
|
|
129
|
+
}
|
|
130
|
+
}));
|
|
131
|
+
res.locals.padBytes = trafficVerdict.padBytes;
|
|
132
|
+
require_metrics.recordCaptchaIssued(captchaType);
|
|
133
|
+
return res.json(response);
|
|
134
|
+
} catch (err) {
|
|
135
|
+
require_metrics.recordCaptchaIssueError(captchaType);
|
|
136
|
+
req.logger.error(() => ({
|
|
137
|
+
err,
|
|
138
|
+
body: require_requestBodySummary.summariseRequestBody(req),
|
|
139
|
+
msg: `Error in ${label} captcha challenge request`
|
|
140
|
+
}));
|
|
141
|
+
return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
|
|
142
|
+
context: {
|
|
143
|
+
code: 500,
|
|
144
|
+
siteKey: req.body.dapp,
|
|
145
|
+
user: req.body.user,
|
|
146
|
+
error: err
|
|
147
|
+
},
|
|
148
|
+
i18n: req.i18n,
|
|
149
|
+
logger: req.logger
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
//#endregion
|
|
154
|
+
exports.interactiveChallengeHandler = interactiveChallengeHandler;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const require_validateAddress = require("../validateAddress.cjs");
|
|
2
|
+
const require_tasks = require("../../tasks/tasks.cjs");
|
|
3
|
+
const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
|
|
4
|
+
const require_testSiteKey = require("../testSiteKey.cjs");
|
|
5
|
+
const require_requestBodySummary = require("../requestBodySummary.cjs");
|
|
6
|
+
let _prosopo_common = require("@prosopo/common");
|
|
7
|
+
//#region src/api/captcha/interactiveCaptchaSolution.ts
|
|
8
|
+
/** Request handling shared by the solution endpoints of the interactive types. */
|
|
9
|
+
var interactiveSolutionHandler = (env, spec) => async (req, res, next) => {
|
|
10
|
+
if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
|
|
11
|
+
req.logger.info(() => ({ msg: "Maintenance mode active - returning verified" }));
|
|
12
|
+
return res.json({
|
|
13
|
+
status: "ok",
|
|
14
|
+
verified: true
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
let parsed;
|
|
18
|
+
const tasks = new require_tasks.Tasks(env, req.logger);
|
|
19
|
+
try {
|
|
20
|
+
parsed = spec.parse(req.body);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
|
|
23
|
+
context: {
|
|
24
|
+
code: 400,
|
|
25
|
+
error: err,
|
|
26
|
+
body: require_requestBodySummary.summariseRequestBody(req)
|
|
27
|
+
},
|
|
28
|
+
i18n: req.i18n,
|
|
29
|
+
logger: req.logger
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
const { dapp, user } = parsed;
|
|
33
|
+
require_validateAddress.validateSiteKey(dapp);
|
|
34
|
+
require_validateAddress.validateAddr(user);
|
|
35
|
+
const testVerdict = require_testSiteKey.resolveTestSiteKeyVerdict(dapp, req.logger);
|
|
36
|
+
if (testVerdict !== null) {
|
|
37
|
+
const response = {
|
|
38
|
+
status: "ok",
|
|
39
|
+
verified: testVerdict
|
|
40
|
+
};
|
|
41
|
+
return res.json(response);
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const clientRecord = await tasks.db.getClientRecord(dapp);
|
|
45
|
+
if (!clientRecord) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
|
|
46
|
+
context: {
|
|
47
|
+
code: 400,
|
|
48
|
+
siteKey: dapp
|
|
49
|
+
},
|
|
50
|
+
i18n: req.i18n,
|
|
51
|
+
logger: req.logger
|
|
52
|
+
}));
|
|
53
|
+
const submitWindowMs = clientRecord.settings.solutionTimeout ?? clientRecord.settings.verifiedTimeout;
|
|
54
|
+
const response = {
|
|
55
|
+
status: "ok",
|
|
56
|
+
verified: await spec.verify(tasks, parsed, submitWindowMs, req)
|
|
57
|
+
};
|
|
58
|
+
return res.json(response);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
req.logger.error(() => ({
|
|
61
|
+
err,
|
|
62
|
+
body: require_requestBodySummary.summariseRequestBody(req),
|
|
63
|
+
msg: `Error in ${spec.label} captcha solution submission`
|
|
64
|
+
}));
|
|
65
|
+
return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
|
|
66
|
+
context: {
|
|
67
|
+
code: 500,
|
|
68
|
+
siteKey: req.body.dapp,
|
|
69
|
+
error: err
|
|
70
|
+
},
|
|
71
|
+
i18n: req.i18n,
|
|
72
|
+
logger: req.logger
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
exports.interactiveSolutionHandler = interactiveSolutionHandler;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
const require_audioRenderer = require("../../tasks/audio/audioRenderer.cjs");
|
|
1
2
|
const require_puzzleRenderer = require("../../tasks/puzzle/puzzleRenderer.cjs");
|
|
3
|
+
const require_iconOrderRenderer = require("../../tasks/iconOrder/iconOrderRenderer.cjs");
|
|
2
4
|
let _prosopo_types = require("@prosopo/types");
|
|
3
5
|
let node_crypto = require("node:crypto");
|
|
4
6
|
//#region src/api/captcha/maintenanceModeResponses.ts
|
|
@@ -49,8 +51,35 @@ var buildPuzzleMaintenanceResponse = async (user, dapp) => {
|
|
|
49
51
|
[_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: "" } }
|
|
50
52
|
};
|
|
51
53
|
};
|
|
54
|
+
var buildAudioMaintenanceResponse = async (user, dapp) => {
|
|
55
|
+
const timestamp = Date.now();
|
|
56
|
+
const rendered = require_audioRenderer.renderAudioClip(require_audioRenderer.resolveAudioRenderSettings());
|
|
57
|
+
return {
|
|
58
|
+
[_prosopo_types.ApiParams.status]: "ok",
|
|
59
|
+
[_prosopo_types.ApiParams.challenge]: buildChallenge(user, dapp),
|
|
60
|
+
[_prosopo_types.ApiParams.clip]: rendered.clip,
|
|
61
|
+
[_prosopo_types.ApiParams.characterCount]: rendered.characterCount,
|
|
62
|
+
[_prosopo_types.ApiParams.timestamp]: timestamp.toString(),
|
|
63
|
+
[_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: "" } }
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
var buildIconOrderMaintenanceResponse = async (user, dapp) => {
|
|
67
|
+
const timestamp = Date.now();
|
|
68
|
+
const images = await require_iconOrderRenderer.renderIconOrderImages();
|
|
69
|
+
return {
|
|
70
|
+
[_prosopo_types.ApiParams.status]: "ok",
|
|
71
|
+
[_prosopo_types.ApiParams.challenge]: buildChallenge(user, dapp),
|
|
72
|
+
[_prosopo_types.ApiParams.background]: images.background,
|
|
73
|
+
[_prosopo_types.ApiParams.legend]: images.legend,
|
|
74
|
+
[_prosopo_types.ApiParams.legendIconSize]: images.legendIconSize,
|
|
75
|
+
[_prosopo_types.ApiParams.timestamp]: timestamp.toString(),
|
|
76
|
+
[_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: "" } }
|
|
77
|
+
};
|
|
78
|
+
};
|
|
52
79
|
//#endregion
|
|
80
|
+
exports.buildAudioMaintenanceResponse = buildAudioMaintenanceResponse;
|
|
53
81
|
exports.buildFrictionlessMaintenanceResponse = buildFrictionlessMaintenanceResponse;
|
|
82
|
+
exports.buildIconOrderMaintenanceResponse = buildIconOrderMaintenanceResponse;
|
|
54
83
|
exports.buildImageMaintenanceResponse = buildImageMaintenanceResponse;
|
|
55
84
|
exports.buildMaintenanceVerificationResponse = buildMaintenanceVerificationResponse;
|
|
56
85
|
exports.buildPowMaintenanceResponse = buildPowMaintenanceResponse;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const require_interactiveCaptchaSolution = require("./interactiveCaptchaSolution.cjs");
|
|
2
|
+
let _prosopo_types = require("@prosopo/types");
|
|
3
|
+
let _prosopo_util = require("@prosopo/util");
|
|
4
|
+
//#region src/api/captcha/submitAudioCaptchaSolution.ts
|
|
5
|
+
var submitAudioCaptchaSolution_default = (env) => require_interactiveCaptchaSolution.interactiveSolutionHandler(env, {
|
|
6
|
+
label: "audio",
|
|
7
|
+
parse: (body) => _prosopo_types.SubmitAudioCaptchaSolutionBody.parse(body),
|
|
8
|
+
verify: (tasks, body, submitWindowMs, req) => tasks.audioCaptchaManager.verifyAudioCaptchaSolution(body.challenge, body.signature.provider.challenge, body.answer, body.replays ?? 0, body.audioEvents ?? [], submitWindowMs, body.signature.user.timestamp, (0, _prosopo_util.getIPAddress)(req.ip || ""), body.behavioralData, body.salt, body.simdReadings, body.clientMetaData)
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
exports.default = submitAudioCaptchaSolution_default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const require_interactiveCaptchaSolution = require("./interactiveCaptchaSolution.cjs");
|
|
2
|
+
let _prosopo_types = require("@prosopo/types");
|
|
3
|
+
let _prosopo_util = require("@prosopo/util");
|
|
4
|
+
//#region src/api/captcha/submitIconOrderCaptchaSolution.ts
|
|
5
|
+
var submitIconOrderCaptchaSolution_default = (env) => require_interactiveCaptchaSolution.interactiveSolutionHandler(env, {
|
|
6
|
+
label: "icon-order",
|
|
7
|
+
parse: (body) => _prosopo_types.SubmitIconOrderCaptchaSolutionBody.parse(body),
|
|
8
|
+
verify: (tasks, body, submitWindowMs, req) => tasks.iconOrderCaptchaManager.verifyIconOrderCaptchaSolution(body.challenge, body.signature.provider.challenge, body.clicks, body.iconOrderEvents, submitWindowMs, body.signature.user.timestamp, (0, _prosopo_util.getIPAddress)(req.ip || ""), body.behavioralData, body.salt, body.simdReadings, body.clientMetaData)
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
exports.default = submitIconOrderCaptchaSolution_default;
|