@prosopo/provider 5.19.4 → 5.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$cjs.log +40 -36
- package/.turbo/turbo-build$colon$tsc.log +28 -28
- package/.turbo/turbo-build.log +43 -36
- package/CHANGELOG.md +135 -0
- package/dist/api/admin/apiClearAllCountersEndpoint.js.map +1 -1
- package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.js.map +1 -1
- package/dist/api/admin/apiGetDecisionMachineEndpoint.js.map +1 -1
- package/dist/api/admin/apiGetSessionEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveDecisionMachineEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveSiteKeyEndpoint.js.map +1 -1
- package/dist/api/admin/apiRemoveSiteKeysEndpoint.js.map +1 -1
- package/dist/api/admin/apiReplaceDetectorPoolEndpoint.js.map +1 -1
- package/dist/api/admin/apiUpdateDecisionMachineEndpoint.js.map +1 -1
- package/dist/api/blacklistRequestInspector.d.ts.map +1 -1
- package/dist/api/blacklistRequestInspector.js +9 -8
- package/dist/api/blacklistRequestInspector.js.map +1 -1
- package/dist/api/captcha/checkSpamEmail.d.ts.map +1 -1
- package/dist/api/captcha/checkSpamEmail.js +19 -26
- package/dist/api/captcha/checkSpamEmail.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js +11 -2
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +6 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +20 -25
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
- package/dist/api/captcha/getImageCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/getImageCaptchaChallenge.js +32 -43
- package/dist/api/captcha/getImageCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/getPoWCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/getPoWCaptchaChallenge.js +27 -32
- package/dist/api/captcha/getPoWCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/interactiveCaptchaChallenge.d.ts.map +1 -1
- package/dist/api/captcha/interactiveCaptchaChallenge.js +27 -32
- package/dist/api/captcha/interactiveCaptchaChallenge.js.map +1 -1
- package/dist/api/captcha/interactiveCaptchaSolution.d.ts.map +1 -1
- package/dist/api/captcha/interactiveCaptchaSolution.js +18 -24
- package/dist/api/captcha/interactiveCaptchaSolution.js.map +1 -1
- package/dist/api/captcha/submitImageCaptchaSolution.d.ts.map +1 -1
- package/dist/api/captcha/submitImageCaptchaSolution.js +18 -24
- package/dist/api/captcha/submitImageCaptchaSolution.js.map +1 -1
- package/dist/api/captcha/submitPoWCaptchaSolution.d.ts.map +1 -1
- package/dist/api/captcha/submitPoWCaptchaSolution.js +23 -25
- package/dist/api/captcha/submitPoWCaptchaSolution.js.map +1 -1
- package/dist/api/domainMiddleware.d.ts.map +1 -1
- package/dist/api/domainMiddleware.js +39 -47
- package/dist/api/domainMiddleware.js.map +1 -1
- package/dist/api/errorCodeForReason.d.ts +3 -0
- package/dist/api/errorCodeForReason.d.ts.map +1 -0
- package/dist/api/errorCodeForReason.js +22 -0
- package/dist/api/errorCodeForReason.js.map +1 -0
- package/dist/api/headerCheckMiddleware.d.ts.map +1 -1
- package/dist/api/headerCheckMiddleware.js +14 -9
- package/dist/api/headerCheckMiddleware.js.map +1 -1
- package/dist/api/ipInfoMiddleware.d.ts +1 -1
- package/dist/api/ipInfoMiddleware.d.ts.map +1 -1
- package/dist/api/ipInfoMiddleware.js +5 -1
- package/dist/api/ipInfoMiddleware.js.map +1 -1
- package/dist/api/metrics.d.ts.map +1 -1
- package/dist/api/metrics.js +9 -1
- package/dist/api/metrics.js.map +1 -1
- package/dist/api/public.d.ts.map +1 -1
- package/dist/api/public.js +6 -2
- package/dist/api/public.js.map +1 -1
- package/dist/api/rateLimitHandler.d.ts +4 -0
- package/dist/api/rateLimitHandler.d.ts.map +1 -0
- package/dist/api/rateLimitHandler.js +20 -0
- package/dist/api/rateLimitHandler.js.map +1 -0
- package/dist/api/startProviderApi.d.ts +1 -0
- package/dist/api/startProviderApi.d.ts.map +1 -1
- package/dist/api/startProviderApi.js +8 -17
- package/dist/api/startProviderApi.js.map +1 -1
- package/dist/api/validateAddress.d.ts +3 -4
- package/dist/api/validateAddress.d.ts.map +1 -1
- package/dist/api/validateAddress.js +13 -19
- package/dist/api/validateAddress.js.map +1 -1
- package/dist/api/verify.d.ts.map +1 -1
- package/dist/api/verify.js +73 -96
- package/dist/api/verify.js.map +1 -1
- package/dist/cjs/api/blacklistRequestInspector.cjs +9 -8
- package/dist/cjs/api/captcha/checkSpamEmail.cjs +18 -25
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs +11 -2
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +6 -1
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +19 -24
- package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +31 -42
- package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +26 -31
- package/dist/cjs/api/captcha/interactiveCaptchaChallenge.cjs +26 -31
- package/dist/cjs/api/captcha/interactiveCaptchaSolution.cjs +17 -23
- package/dist/cjs/api/captcha/submitImageCaptchaSolution.cjs +17 -23
- package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +22 -24
- package/dist/cjs/api/domainMiddleware.cjs +38 -46
- package/dist/cjs/api/errorCodeForReason.cjs +22 -0
- package/dist/cjs/api/headerCheckMiddleware.cjs +13 -8
- package/dist/cjs/api/ipInfoMiddleware.cjs +5 -1
- package/dist/cjs/api/metrics.cjs +9 -1
- package/dist/cjs/api/public.cjs +5 -1
- package/dist/cjs/api/rateLimitHandler.cjs +20 -0
- package/dist/cjs/api/startProviderApi.cjs +8 -16
- package/dist/cjs/api/validateAddress.cjs +12 -18
- package/dist/cjs/api/verify.cjs +72 -95
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/tasks/captchaManager.cjs +6 -8
- package/dist/cjs/tasks/client/clientTasks.cjs +26 -13
- package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +28 -8
- package/dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs +21 -19
- package/dist/cjs/tasks/frictionless/routingMachine.cjs +13 -4
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +89 -40
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +18 -8
- package/dist/cjs/tasks/interactiveCaptcha/interactiveCaptchaManager.cjs +21 -13
- package/dist/cjs/tasks/powCaptcha/backgroundWrites.cjs +24 -0
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +44 -19
- package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +14 -10
- package/dist/cjs/tasks/signatureCheck.cjs +12 -0
- package/dist/cjs/tasks/tasks.cjs +6 -1
- package/dist/cjs/util/usageCounters.cjs +26 -3
- package/dist/cjs/util.cjs +14 -3
- package/dist/errorSites.d.ts +98 -0
- package/dist/errorSites.d.ts.map +1 -0
- package/dist/errorSites.js +2 -0
- package/dist/errorSites.js.map +1 -0
- package/dist/fingerprint/dist/merkle.js +69 -0
- package/dist/fingerprint/dist/proof.js +95 -0
- package/dist/fingerprint/dist/summary.js +73 -0
- package/dist/index.js +2 -2
- package/dist/tasks/captchaManager.d.ts +2 -3
- package/dist/tasks/captchaManager.d.ts.map +1 -1
- package/dist/tasks/captchaManager.js +6 -7
- package/dist/tasks/captchaManager.js.map +1 -1
- package/dist/tasks/client/clientTasks.d.ts.map +1 -1
- package/dist/tasks/client/clientTasks.js +27 -14
- package/dist/tasks/client/clientTasks.js.map +1 -1
- package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +1 -1
- package/dist/tasks/dataset/datasetTasksUtils.js +29 -9
- package/dist/tasks/dataset/datasetTasksUtils.js.map +1 -1
- package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts +1 -3
- package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts.map +1 -1
- package/dist/tasks/decisionMachine/decisionMachineRunner.js +21 -19
- package/dist/tasks/decisionMachine/decisionMachineRunner.js.map +1 -1
- package/dist/tasks/frictionless/routingMachine.d.ts.map +1 -1
- package/dist/tasks/frictionless/routingMachine.js +13 -4
- package/dist/tasks/frictionless/routingMachine.js.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +91 -42
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +19 -9
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +1 -1
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts.map +1 -1
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js +22 -14
- package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js.map +1 -1
- package/dist/tasks/powCaptcha/backgroundWrites.d.ts +7 -0
- package/dist/tasks/powCaptcha/backgroundWrites.d.ts.map +1 -0
- package/dist/tasks/powCaptcha/backgroundWrites.js +24 -0
- package/dist/tasks/powCaptcha/backgroundWrites.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasks.d.ts +3 -3
- package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
- package/dist/tasks/powCaptcha/powTasks.js +45 -20
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +1 -1
- package/dist/tasks/powCaptcha/powTasksUtils.js +15 -11
- package/dist/tasks/powCaptcha/powTasksUtils.js.map +1 -1
- package/dist/tasks/signatureCheck.d.ts +2 -0
- package/dist/tasks/signatureCheck.d.ts.map +1 -0
- package/dist/tasks/signatureCheck.js +12 -0
- package/dist/tasks/signatureCheck.js.map +1 -0
- package/dist/tasks/tasks.d.ts.map +1 -1
- package/dist/tasks/tasks.js +7 -2
- package/dist/tasks/tasks.js.map +1 -1
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +3 -1
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +1 -1
- package/dist/tests/integration/api/admin/apiRegisterSiteKeysEndpoint.integration.test.js +6 -2
- package/dist/tests/integration/api/admin/apiRegisterSiteKeysEndpoint.integration.test.js.map +1 -1
- package/dist/tests/integration/escalationPeekBeforeConsume.integration.test.js +1 -1
- package/dist/tests/integration/escalationPeekBeforeConsume.integration.test.js.map +1 -1
- package/dist/tests/integration/imgCaptcha.integration.test.js +6 -5
- package/dist/tests/integration/imgCaptcha.integration.test.js.map +1 -1
- package/dist/tests/integration/ipValidation.integration.test.js +1 -1
- package/dist/tests/integration/ipValidation.integration.test.js.map +1 -1
- package/dist/tests/integration/powCaptcha.integration.test.js +2 -2
- package/dist/tests/integration/powCaptcha.integration.test.js.map +1 -1
- package/dist/tests/integration/routingDecisionMachines.integration.test.js.map +1 -1
- package/dist/tests/integration/testUtils.d.ts +2 -2
- package/dist/tests/integration/testUtils.d.ts.map +1 -1
- package/dist/tests/integration/testUtils.js +1 -1
- package/dist/tests/integration/testUtils.js.map +1 -1
- package/dist/tests/integration/webBotAuthAuthenticated.integration.test.js +3 -1
- package/dist/tests/integration/webBotAuthAuthenticated.integration.test.js.map +1 -1
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js +26 -10
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.js +4 -4
- package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.js.map +1 -1
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.js +153 -0
- package/dist/tests/unit/api/captcha/submitSolutionBadSignature.unit.test.js.map +1 -0
- package/dist/tests/unit/api/domainMiddlewareErrorBody.unit.test.js +6 -2
- package/dist/tests/unit/api/domainMiddlewareErrorBody.unit.test.js.map +1 -1
- package/dist/tests/unit/api/errorCodeForReason.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/errorCodeForReason.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/errorCodeForReason.unit.test.js +23 -0
- package/dist/tests/unit/api/errorCodeForReason.unit.test.js.map +1 -0
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +6 -1
- package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
- package/dist/tests/unit/api/headerCheckMiddleware.unit.test.js +16 -7
- package/dist/tests/unit/api/headerCheckMiddleware.unit.test.js.map +1 -1
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.js +46 -0
- package/dist/tests/unit/api/ipInfoMiddleware.unit.test.js.map +1 -0
- package/dist/tests/unit/api/public.unit.test.js +45 -10
- package/dist/tests/unit/api/public.unit.test.js.map +1 -1
- package/dist/tests/unit/api/rateLimitHandler.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/rateLimitHandler.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/rateLimitHandler.unit.test.js +39 -0
- package/dist/tests/unit/api/rateLimitHandler.unit.test.js.map +1 -0
- package/dist/tests/unit/api/validateAddress.unit.test.js +41 -115
- package/dist/tests/unit/api/validateAddress.unit.test.js.map +1 -1
- package/dist/tests/unit/api/verifyMalformedToken.unit.test.js +3 -3
- package/dist/tests/unit/api/verifyMalformedToken.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/captchaManager.unit.test.js +22 -18
- package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +25 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +25 -20
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js +31 -0
- package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.js +80 -0
- package/dist/tests/unit/tasks/frictionless/fingerprintBucketFlow.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/frictionless/routingMachine.unit.test.js +48 -0
- package/dist/tests/unit/tasks/frictionless/routingMachine.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +20 -28
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +2 -2
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.js +44 -0
- package/dist/tests/unit/tasks/powCaptcha/backgroundWrites.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +78 -43
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +7 -6
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js +2 -2
- package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/util/usageCounters.unit.test.js +20 -0
- package/dist/tests/unit/util/usageCounters.unit.test.js.map +1 -1
- package/dist/tests/unit/util.unit.test.js +7 -7
- package/dist/tests/unit/util.unit.test.js.map +1 -1
- package/dist/util/usageCounters.d.ts +1 -1
- package/dist/util/usageCounters.d.ts.map +1 -1
- package/dist/util/usageCounters.js +26 -3
- package/dist/util/usageCounters.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +15 -4
- package/dist/util.js.map +1 -1
- package/package.json +44 -43
|
@@ -11,6 +11,7 @@ const require_frictionlessTasksUtils = require("../frictionless/frictionlessTask
|
|
|
11
11
|
const require_powTasksUtils = require("./powTasksUtils.cjs");
|
|
12
12
|
const require_evaluateEmailSpamRules = require("../spam/evaluateEmailSpamRules.cjs");
|
|
13
13
|
const require_routingMachine = require("../frictionless/routingMachine.cjs");
|
|
14
|
+
const require_backgroundWrites = require("./backgroundWrites.cjs");
|
|
14
15
|
let _prosopo_common = require("@prosopo/common");
|
|
15
16
|
let _prosopo_types = require("@prosopo/types");
|
|
16
17
|
let _polkadot_util = require("@polkadot/util");
|
|
@@ -18,6 +19,7 @@ let _prosopo_user_access_policy = require("@prosopo/user-access-policy");
|
|
|
18
19
|
let _prosopo_util = require("@prosopo/util");
|
|
19
20
|
//#region src/tasks/powCaptcha/powTasks.ts
|
|
20
21
|
var DEFAULT_POW_DIFFICULTY = 4;
|
|
22
|
+
var verifyOutcomeWrites = new require_backgroundWrites.BackgroundWrites(500);
|
|
21
23
|
var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
22
24
|
constructor(db, pair, config, logger, writeQueue, usageCounters) {
|
|
23
25
|
super(db, pair, config, logger, writeQueue);
|
|
@@ -65,7 +67,7 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
65
67
|
* @param behavioralData
|
|
66
68
|
* @param salt
|
|
67
69
|
*/
|
|
68
|
-
async verifyPowCaptchaSolution(challenge, providerChallengeSignature, nonce, timeout, userTimestampSignature, ipAddress, headers, behavioralData, salt, simdReadings, clientMetaData) {
|
|
70
|
+
async verifyPowCaptchaSolution(challenge, providerChallengeSignature, nonce, timeout, userTimestampSignature, ipAddress, headers, behavioralData, salt, simdReadings, clientMetaData, fingerprintSummary) {
|
|
69
71
|
require_powTasksUtils.checkPowSignature(challenge, providerChallengeSignature, this.pair.address, _prosopo_types.ApiParams.challenge);
|
|
70
72
|
const challengeSplit = challenge.split(this.POW_SEPARATOR);
|
|
71
73
|
const timestamp = Number.parseInt((0, _prosopo_util.at)(challengeSplit, 0));
|
|
@@ -134,7 +136,7 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
134
136
|
};
|
|
135
137
|
if (correct && this.usageCounters) {
|
|
136
138
|
const dappAccount = (0, _prosopo_util.at)(challengeSplit, 2);
|
|
137
|
-
this.usageCounters.incrManyAsync(dappAccount, require_usageCounters.buildAllWindowIncrements("solved", _prosopo_types.CaptchaType.pow, ipAddress.address, userAccount));
|
|
139
|
+
this.usageCounters.incrManyAsync(dappAccount, require_usageCounters.buildAllWindowIncrements("solved", _prosopo_types.CaptchaType.pow, ipAddress.address, userAccount, void 0, fingerprintSummary?.bucketId));
|
|
138
140
|
}
|
|
139
141
|
let behavioralUpdates = {};
|
|
140
142
|
let decryptedBehavioralDataPacked;
|
|
@@ -180,6 +182,7 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
180
182
|
}));
|
|
181
183
|
}
|
|
182
184
|
const recordUpdates = { ...behavioralUpdates };
|
|
185
|
+
if (fingerprintSummary) recordUpdates.fingerprintSummary = fingerprintSummary;
|
|
183
186
|
const storedClientMetaData = require_clientMetaData.toStoredClientMetaData(clientMetaData);
|
|
184
187
|
if (storedClientMetaData) recordUpdates.clientMetaData = storedClientMetaData;
|
|
185
188
|
if (Object.keys(recordUpdates).length > 0) await this.db.updatePowCaptchaRecord(challenge, recordUpdates);
|
|
@@ -294,8 +297,10 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
294
297
|
* @param clientSessionId - the session id the site rendered the widget
|
|
295
298
|
* with. When supplied, the solve must carry the same value in its
|
|
296
299
|
* `clientMetaData` or it is disapproved.
|
|
300
|
+
* @param ipValidationRules - the site's rules for comparing `ip` with the
|
|
301
|
+
* ip the challenge was issued to.
|
|
297
302
|
*/
|
|
298
|
-
async serverVerifyPowCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled = false, spamFilter, trafficFilter, storeMetadata = false, clientSessionId) {
|
|
303
|
+
async serverVerifyPowCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled = false, spamFilter, trafficFilter, storeMetadata = false, clientSessionId, ipValidationRules) {
|
|
299
304
|
const notVerified = (reason, sessionId) => ({
|
|
300
305
|
verified: false,
|
|
301
306
|
reason,
|
|
@@ -310,18 +315,26 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
310
315
|
logger.debug(() => ({ msg: `No record of this challenge: ${challenge}` }));
|
|
311
316
|
return notVerified("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND");
|
|
312
317
|
}
|
|
313
|
-
if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.
|
|
314
|
-
code:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
+
if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.ProsopoError({
|
|
319
|
+
code: "INVALID_SOLUTION",
|
|
320
|
+
errorSite: "PROV-73",
|
|
321
|
+
context: {
|
|
322
|
+
failedFuncName: this.serverVerifyPowCaptchaSolution.name,
|
|
323
|
+
challenge
|
|
324
|
+
}
|
|
325
|
+
});
|
|
318
326
|
if (challengeRecord.serverChecked) return notVerified("API.USER_ALREADY_VERIFIED", challengeRecord.sessionId);
|
|
319
327
|
const challengeDappAccount = challengeRecord.dappAccount;
|
|
320
|
-
if (dappAccount !== challengeDappAccount) throw new _prosopo_common.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
328
|
+
if (dappAccount !== challengeDappAccount) throw new _prosopo_common.ProsopoError({
|
|
329
|
+
code: "SOLUTION_NOT_FOUND",
|
|
330
|
+
errorSite: "PROV-74",
|
|
331
|
+
message: "Dapp user solution not found",
|
|
332
|
+
context: {
|
|
333
|
+
failedFuncName: this.serverVerifyPowCaptchaSolution.name,
|
|
334
|
+
dappAccount,
|
|
335
|
+
challengeDappAccount
|
|
336
|
+
}
|
|
337
|
+
});
|
|
325
338
|
if (await this.db.markDappUserPoWCommitmentsChecked([challengeRecord.challenge]) === 0) return notVerified("API.USER_ALREADY_VERIFIED", challengeRecord.sessionId);
|
|
326
339
|
const powRecordUpdates = {};
|
|
327
340
|
let failResult;
|
|
@@ -346,8 +359,16 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
346
359
|
};
|
|
347
360
|
failReason = "API.CLIENT_SESSION_MISMATCH";
|
|
348
361
|
}
|
|
362
|
+
const sessionRecordRead = challengeRecord.sessionId ? this.getSessionRecordWithOriginFallback(challengeRecord.sessionId) : Promise.resolve(void 0);
|
|
363
|
+
const enrichedDnsEventRead = sessionRecordRead.then((sessionRecord) => require_enrichDnsEvent.enrichDnsEvent(sessionRecord?.dnsEvent, env.ipInfoService, ip ?? challengeRecord.ipInfo?.ip));
|
|
364
|
+
const currentIpInfoRead = ip && !failResult ? env.ipInfoService.lookup(ip) : Promise.resolve(void 0);
|
|
365
|
+
for (const read of [
|
|
366
|
+
sessionRecordRead,
|
|
367
|
+
enrichedDnsEventRead,
|
|
368
|
+
currentIpInfoRead
|
|
369
|
+
]) read.catch(() => void 0);
|
|
349
370
|
if (!failResult && userAccessRulesStorage) try {
|
|
350
|
-
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, challengeRecord, challengeRecord.userAccount, challengeRecord.headers, challengeRecord.coords, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.asnNumber : void 0);
|
|
371
|
+
const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, challengeRecord, challengeRecord.userAccount, challengeRecord.headers, (await sessionRecordRead)?.decryptedHeadHash, challengeRecord.coords, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.asnNumber : void 0);
|
|
351
372
|
if (blockPolicy) {
|
|
352
373
|
logger.info(() => ({
|
|
353
374
|
msg: "User blocked by access policy in server PoW verification",
|
|
@@ -429,10 +450,10 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
429
450
|
}));
|
|
430
451
|
}
|
|
431
452
|
}
|
|
432
|
-
const sessionRecord =
|
|
433
|
-
const enrichedDnsEvent = await
|
|
453
|
+
const sessionRecord = await sessionRecordRead;
|
|
454
|
+
const enrichedDnsEvent = await enrichedDnsEventRead;
|
|
434
455
|
if (!failResult) {
|
|
435
|
-
const check = await this.resolveTrafficFilterCheck(
|
|
456
|
+
const check = await this.resolveTrafficFilterCheck(challengeRecord.ipInfo, trafficFilter, await currentIpInfoRead, enrichedDnsEvent);
|
|
436
457
|
if (check.isBlocked) {
|
|
437
458
|
logger.info(() => ({
|
|
438
459
|
msg: "Traffic filter rejected request in PoW verification",
|
|
@@ -459,7 +480,6 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
459
480
|
};
|
|
460
481
|
if (!failResult && ip) {
|
|
461
482
|
const challengeIpAddress = require_compositeIpAddress.getIpAddressFromComposite(challengeRecord.ipAddress);
|
|
462
|
-
const ipValidationRules = (await this.db.getClientRecord(dappAccount))?.settings?.ipValidationRules;
|
|
463
483
|
powRecordUpdates.providedIp = require_compositeIpAddress.getCompositeIpAddress(ip);
|
|
464
484
|
if (ipValidationRules?.enabled === true) {
|
|
465
485
|
const ipValidation = await require_util.deepValidateIpAddress(ip, challengeIpAddress, logger, env.ipInfoService, ipValidationRules, enrichedDnsEvent?.peerIp);
|
|
@@ -569,7 +589,12 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
569
589
|
...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.pow, finalResult) && { blocked: true },
|
|
570
590
|
...matchedRule && { matchedRule }
|
|
571
591
|
}, true));
|
|
572
|
-
|
|
592
|
+
await verifyOutcomeWrites.add(Promise.all(writePromises), (err) => {
|
|
593
|
+
logger.error(() => ({
|
|
594
|
+
msg: "Failed to record the outcome of a PoW verification",
|
|
595
|
+
err
|
|
596
|
+
}));
|
|
597
|
+
});
|
|
573
598
|
if (failReason) return notVerified(failReason, challengeRecord.sessionId);
|
|
574
599
|
return {
|
|
575
600
|
verified: true,
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
+
const require_signatureCheck = require("../signatureCheck.cjs");
|
|
1
2
|
let _prosopo_common = require("@prosopo/common");
|
|
2
|
-
let _polkadot_util = require("@polkadot/util");
|
|
3
3
|
let _prosopo_util = require("@prosopo/util");
|
|
4
|
-
let _prosopo_util_crypto = require("@prosopo/util-crypto");
|
|
5
4
|
let _noble_hashes_sha2_js = require("@noble/hashes/sha2.js");
|
|
6
5
|
//#region src/tasks/powCaptcha/powTasksUtils.ts
|
|
7
6
|
var validateSolution = (nonce, challenge, difficulty) => (0, _prosopo_util.hashMeetsDifficulty)((0, _noble_hashes_sha2_js.sha256)(new TextEncoder().encode(nonce + challenge)), difficulty);
|
|
8
7
|
var checkPowSignature = (message, signature, address, signatureType) => {
|
|
9
|
-
if (!
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
if (!require_signatureCheck.isSignatureValid(message, signature, address)) throw new _prosopo_common.ProsopoError({
|
|
9
|
+
code: "UNAUTHORIZED",
|
|
10
|
+
errorSite: "PROV-75",
|
|
11
|
+
message: "Invalid signature",
|
|
12
|
+
context: {
|
|
13
|
+
ERROR: `Signature is invalid for this message: ${signatureType}`,
|
|
14
|
+
failedFuncName: checkPowSignature.name,
|
|
15
|
+
address,
|
|
16
|
+
message,
|
|
17
|
+
signature,
|
|
18
|
+
signatureType
|
|
19
|
+
}
|
|
20
|
+
});
|
|
17
21
|
};
|
|
18
22
|
var isCoordsAllZero = (coords) => coords !== void 0 && coords.length > 0 && coords.every((group) => group.length > 0 && group.every(([x, y]) => x === 0 && y === 0));
|
|
19
23
|
//#endregion
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
let _polkadot_util = require("@polkadot/util");
|
|
2
|
+
let _prosopo_util_crypto = require("@prosopo/util-crypto");
|
|
3
|
+
//#region src/tasks/signatureCheck.ts
|
|
4
|
+
var isSignatureValid = (message, signature, address) => {
|
|
5
|
+
try {
|
|
6
|
+
return (0, _prosopo_util_crypto.signatureVerify)((0, _polkadot_util.stringToHex)(message), signature, address).isValid;
|
|
7
|
+
} catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
exports.isSignatureValid = isSignatureValid;
|
package/dist/cjs/tasks/tasks.cjs
CHANGED
|
@@ -23,7 +23,12 @@ var Tasks = class {
|
|
|
23
23
|
this.db = env.getDb();
|
|
24
24
|
this.captchaConfig = env.config.captchas;
|
|
25
25
|
this.logger = logger || (0, _prosopo_logger.getLogger)((0, _prosopo_logger.parseLogLevel)(env.config.logLevel), "Tasks");
|
|
26
|
-
if (!env.pair) throw new _prosopo_common.
|
|
26
|
+
if (!env.pair) throw new _prosopo_common.ProsopoError({
|
|
27
|
+
code: "CONFIG_INVALID",
|
|
28
|
+
errorSite: "PROV-76",
|
|
29
|
+
message: "Missing provider pair",
|
|
30
|
+
context: { failedFuncName: "Tasks.constructor" }
|
|
31
|
+
});
|
|
27
32
|
this.pair = env.pair;
|
|
28
33
|
if (this.config.mongoCaptchaUri && this.db instanceof _prosopo_database.ProviderDatabase && !this.db.hasCentralDbStreamer()) {
|
|
29
34
|
const streamer = new _prosopo_database.CentralDbStreamer(this.config.mongoCaptchaUri, this.logger);
|
|
@@ -152,10 +152,15 @@ var UsageCounters = class {
|
|
|
152
152
|
}
|
|
153
153
|
};
|
|
154
154
|
/**
|
|
155
|
-
* Helper: produce the standard
|
|
156
|
-
*
|
|
155
|
+
* Helper: produce the standard served/solved write set for a given captcha
|
|
156
|
+
* challenge. Used by both served (post-session) and solved hooks.
|
|
157
|
+
*
|
|
158
|
+
* `deviceBucket` is only written when the caller knows one, which for now is
|
|
159
|
+
* the PoW solve path with a verified proof of fingerprint. Omitting it leaves
|
|
160
|
+
* the key absent rather than at zero, so a bucket's count is over the requests
|
|
161
|
+
* that actually proved it.
|
|
157
162
|
*/
|
|
158
|
-
var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp) => {
|
|
163
|
+
var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp, deviceBucket) => {
|
|
159
164
|
const out = [];
|
|
160
165
|
for (const window of [
|
|
161
166
|
"1m",
|
|
@@ -191,6 +196,15 @@ var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp) => {
|
|
|
191
196
|
},
|
|
192
197
|
value: peerIp
|
|
193
198
|
});
|
|
199
|
+
if (deviceBucket) out.push({
|
|
200
|
+
spec: {
|
|
201
|
+
kind,
|
|
202
|
+
captchaType,
|
|
203
|
+
dimension: "deviceBucket",
|
|
204
|
+
window
|
|
205
|
+
},
|
|
206
|
+
value: deviceBucket
|
|
207
|
+
});
|
|
194
208
|
if (captchaType !== "any") {
|
|
195
209
|
out.push({
|
|
196
210
|
spec: {
|
|
@@ -218,6 +232,15 @@ var buildAllWindowIncrements = (kind, captchaType, ip, userAccount, peerIp) => {
|
|
|
218
232
|
},
|
|
219
233
|
value: peerIp
|
|
220
234
|
});
|
|
235
|
+
if (deviceBucket) out.push({
|
|
236
|
+
spec: {
|
|
237
|
+
kind,
|
|
238
|
+
captchaType: "any",
|
|
239
|
+
dimension: "deviceBucket",
|
|
240
|
+
window
|
|
241
|
+
},
|
|
242
|
+
value: deviceBucket
|
|
243
|
+
});
|
|
221
244
|
}
|
|
222
245
|
}
|
|
223
246
|
return out;
|
package/dist/cjs/util.cjs
CHANGED
|
@@ -11,7 +11,12 @@ function encodeStringAddress(address) {
|
|
|
11
11
|
try {
|
|
12
12
|
return (0, _prosopo_util_crypto.encodeAddress)((0, _polkadot_util_is.isHex)(address) ? (0, _polkadot_util_hex.hexToU8a)(address) : (0, _prosopo_util_crypto.decodeAddress)(address));
|
|
13
13
|
} catch (err) {
|
|
14
|
-
throw new _prosopo_common.
|
|
14
|
+
throw new _prosopo_common.ProsopoError({
|
|
15
|
+
code: "INVALID_DATA",
|
|
16
|
+
errorSite: "PROV-77",
|
|
17
|
+
message: "Failed to encode invalid address",
|
|
18
|
+
context: { address }
|
|
19
|
+
});
|
|
15
20
|
}
|
|
16
21
|
}
|
|
17
22
|
function shuffleArray(array) {
|
|
@@ -43,7 +48,10 @@ var getIPAddress = (ipAddressString) => {
|
|
|
43
48
|
return new ip_address.Address6(ipAddressString);
|
|
44
49
|
}
|
|
45
50
|
} catch (e) {
|
|
46
|
-
throw new _prosopo_common.
|
|
51
|
+
throw new _prosopo_common.ProsopoError({
|
|
52
|
+
code: "INVALID_IP",
|
|
53
|
+
errorSite: "PROV-78"
|
|
54
|
+
});
|
|
47
55
|
}
|
|
48
56
|
};
|
|
49
57
|
var getIPAddressFromBigInt = (ipAddressBigInt) => {
|
|
@@ -51,7 +59,10 @@ var getIPAddressFromBigInt = (ipAddressBigInt) => {
|
|
|
51
59
|
if (ipAddressBigInt > 4228250626n) return ip_address.Address6.fromBigInt(BigInt(ipAddressBigInt));
|
|
52
60
|
return ip_address.Address4.fromBigInt(BigInt(ipAddressBigInt));
|
|
53
61
|
} catch (e) {
|
|
54
|
-
throw new _prosopo_common.
|
|
62
|
+
throw new _prosopo_common.ProsopoError({
|
|
63
|
+
code: "INVALID_IP",
|
|
64
|
+
errorSite: "PROV-79"
|
|
65
|
+
});
|
|
55
66
|
}
|
|
56
67
|
};
|
|
57
68
|
/**
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
declare module "@prosopo/common" {
|
|
2
|
+
interface ErrorSites {
|
|
3
|
+
"PROV-1": true;
|
|
4
|
+
"PROV-2": true;
|
|
5
|
+
"PROV-3": true;
|
|
6
|
+
"PROV-4": true;
|
|
7
|
+
"PROV-5": true;
|
|
8
|
+
"PROV-6": true;
|
|
9
|
+
"PROV-7": true;
|
|
10
|
+
"PROV-8": true;
|
|
11
|
+
"PROV-9": true;
|
|
12
|
+
"PROV-10": true;
|
|
13
|
+
"PROV-11": true;
|
|
14
|
+
"PROV-12": true;
|
|
15
|
+
"PROV-13": true;
|
|
16
|
+
"PROV-14": true;
|
|
17
|
+
"PROV-15": true;
|
|
18
|
+
"PROV-16": true;
|
|
19
|
+
"PROV-17": true;
|
|
20
|
+
"PROV-18": true;
|
|
21
|
+
"PROV-19": true;
|
|
22
|
+
"PROV-20": true;
|
|
23
|
+
"PROV-21": true;
|
|
24
|
+
"PROV-22": true;
|
|
25
|
+
"PROV-23": true;
|
|
26
|
+
"PROV-24": true;
|
|
27
|
+
"PROV-25": true;
|
|
28
|
+
"PROV-26": true;
|
|
29
|
+
"PROV-27": true;
|
|
30
|
+
"PROV-28": true;
|
|
31
|
+
"PROV-29": true;
|
|
32
|
+
"PROV-30": true;
|
|
33
|
+
"PROV-31": true;
|
|
34
|
+
"PROV-32": true;
|
|
35
|
+
"PROV-33": true;
|
|
36
|
+
"PROV-34": true;
|
|
37
|
+
"PROV-35": true;
|
|
38
|
+
"PROV-37": true;
|
|
39
|
+
"PROV-38": true;
|
|
40
|
+
"PROV-39": true;
|
|
41
|
+
"PROV-40": true;
|
|
42
|
+
"PROV-41": true;
|
|
43
|
+
"PROV-42": true;
|
|
44
|
+
"PROV-43": true;
|
|
45
|
+
"PROV-44": true;
|
|
46
|
+
"PROV-45": true;
|
|
47
|
+
"PROV-46": true;
|
|
48
|
+
"PROV-47": true;
|
|
49
|
+
"PROV-48": true;
|
|
50
|
+
"PROV-49": true;
|
|
51
|
+
"PROV-50": true;
|
|
52
|
+
"PROV-51": true;
|
|
53
|
+
"PROV-52": true;
|
|
54
|
+
"PROV-53": true;
|
|
55
|
+
"PROV-54": true;
|
|
56
|
+
"PROV-55": true;
|
|
57
|
+
"PROV-56": true;
|
|
58
|
+
"PROV-57": true;
|
|
59
|
+
"PROV-58": true;
|
|
60
|
+
"PROV-59": true;
|
|
61
|
+
"PROV-60": true;
|
|
62
|
+
"PROV-61": true;
|
|
63
|
+
"PROV-62": true;
|
|
64
|
+
"PROV-63": true;
|
|
65
|
+
"PROV-64": true;
|
|
66
|
+
"PROV-65": true;
|
|
67
|
+
"PROV-66": true;
|
|
68
|
+
"PROV-67": true;
|
|
69
|
+
"PROV-68": true;
|
|
70
|
+
"PROV-69": true;
|
|
71
|
+
"PROV-70": true;
|
|
72
|
+
"PROV-71": true;
|
|
73
|
+
"PROV-72": true;
|
|
74
|
+
"PROV-73": true;
|
|
75
|
+
"PROV-74": true;
|
|
76
|
+
"PROV-75": true;
|
|
77
|
+
"PROV-76": true;
|
|
78
|
+
"PROV-77": true;
|
|
79
|
+
"PROV-78": true;
|
|
80
|
+
"PROV-79": true;
|
|
81
|
+
"PROV-80": true;
|
|
82
|
+
"PROV-81": true;
|
|
83
|
+
"PROV-82": true;
|
|
84
|
+
"PROV-83": true;
|
|
85
|
+
"PROV-84": true;
|
|
86
|
+
"PROV-85": true;
|
|
87
|
+
"PROV-86": true;
|
|
88
|
+
"PROV-87": true;
|
|
89
|
+
"PROV-88": true;
|
|
90
|
+
"PROV-89": true;
|
|
91
|
+
"PROV-90": true;
|
|
92
|
+
"PROV-91": true;
|
|
93
|
+
"PROV-92": true;
|
|
94
|
+
"PROV-93": true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=errorSites.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorSites.d.ts","sourceRoot":"","sources":["../src/errorSites.ts"],"names":[],"mappings":"AAcA,OAAO,QAAQ,iBAAiB,CAAC;IAChC,UAAU,UAAU;QACnB,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,QAAQ,EAAE,IAAI,CAAC;QACf,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,EAAE,IAAI,CAAC;KAChB;CACD;AAED,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorSites.js","sourceRoot":"","sources":["../src/errorSites.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { hexHashArray } from "@prosopo/util-crypto";
|
|
2
|
+
//#region ../fingerprint/dist/merkle.js
|
|
3
|
+
var at = (arr, index) => {
|
|
4
|
+
const value = arr[index];
|
|
5
|
+
if (value === void 0) throw new Error(`merkle: index ${index} out of range (length ${arr.length})`);
|
|
6
|
+
return value;
|
|
7
|
+
};
|
|
8
|
+
/** Hash a pair of child hashes into their parent. */
|
|
9
|
+
var hashMerklePair = (left, right) => hexHashArray([left, right]);
|
|
10
|
+
/**
|
|
11
|
+
* Build every layer of the Merkle tree, bottom-up. Layer 0 is the leaf hashes,
|
|
12
|
+
* the final layer is `[root]`. An odd node at the end of a layer is paired with
|
|
13
|
+
* itself.
|
|
14
|
+
*/
|
|
15
|
+
var buildMerkleLayers = (leafHashes) => {
|
|
16
|
+
if (leafHashes.length === 0) throw new Error("merkle: cannot build a tree with no leaves");
|
|
17
|
+
const layers = [[...leafHashes]];
|
|
18
|
+
let current = leafHashes;
|
|
19
|
+
while (current.length > 1) {
|
|
20
|
+
const next = [];
|
|
21
|
+
for (let i = 0; i < current.length; i += 2) {
|
|
22
|
+
const left = at(current, i);
|
|
23
|
+
const right = i + 1 < current.length ? at(current, i + 1) : left;
|
|
24
|
+
next.push(hashMerklePair(left, right));
|
|
25
|
+
}
|
|
26
|
+
layers.push(next);
|
|
27
|
+
current = next;
|
|
28
|
+
}
|
|
29
|
+
return layers;
|
|
30
|
+
};
|
|
31
|
+
var merkleRootFromLayers = (layers) => at(at(layers, layers.length - 1), 0);
|
|
32
|
+
/** Produce the sibling path proving `leafHash` belongs to the tree. */
|
|
33
|
+
var merkleProofFromLayers = (layers, leafHash) => {
|
|
34
|
+
const proof = [];
|
|
35
|
+
let hash = leafHash;
|
|
36
|
+
for (let layerNum = 0; layerNum < layers.length - 1; layerNum++) {
|
|
37
|
+
const layer = at(layers, layerNum);
|
|
38
|
+
const index = layer.indexOf(hash);
|
|
39
|
+
if (index === -1) throw new Error("merkle: leaf hash not present in layer");
|
|
40
|
+
let partnerIndex = index % 2 === 1 ? index - 1 : index + 1;
|
|
41
|
+
if (partnerIndex > layer.length - 1) partnerIndex = index;
|
|
42
|
+
const partner = at(layer, partnerIndex);
|
|
43
|
+
const pair = partnerIndex > index ? [hash, partner] : [partner, hash];
|
|
44
|
+
proof.push(pair);
|
|
45
|
+
hash = hashMerklePair(pair[0], pair[1]);
|
|
46
|
+
}
|
|
47
|
+
return [...proof, [merkleRootFromLayers(layers)]];
|
|
48
|
+
};
|
|
49
|
+
/** Verify a leaf + sibling path recomputes to the proof's embedded root. */
|
|
50
|
+
var verifyMerkleProof = (leafHash, proof) => {
|
|
51
|
+
try {
|
|
52
|
+
const firstLayer = proof[0];
|
|
53
|
+
if (firstLayer === void 0 || firstLayer.indexOf(leafHash) === -1) return false;
|
|
54
|
+
if (proof.length === 1) return at(firstLayer, 0) === leafHash;
|
|
55
|
+
const root = at(at(proof, proof.length - 1), 0);
|
|
56
|
+
let hash = leafHash;
|
|
57
|
+
for (let i = 0; i < proof.length - 1; i++) {
|
|
58
|
+
const layer = at(proof, i);
|
|
59
|
+
if (layer.indexOf(hash) === -1) return false;
|
|
60
|
+
hash = hashMerklePair(at(layer, 0), at(layer, 1));
|
|
61
|
+
if (at(proof, i + 1).indexOf(hash) === -1) return false;
|
|
62
|
+
}
|
|
63
|
+
return hash === root;
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
//#endregion
|
|
69
|
+
export { buildMerkleLayers, hashMerklePair, merkleProofFromLayers, merkleRootFromLayers, verifyMerkleProof };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { buildMerkleLayers, merkleProofFromLayers, merkleRootFromLayers, verifyMerkleProof } from "./merkle.js";
|
|
2
|
+
import { hexHash } from "@prosopo/util-crypto";
|
|
3
|
+
/**
|
|
4
|
+
* The fixed set of components the client discloses in a proof of fingerprint.
|
|
5
|
+
* Disclosing every component (the previous default) made the proof enormous —
|
|
6
|
+
* each disclosure carries a full Merkle path and its raw value, and components
|
|
7
|
+
* like webgl/audio/fonts have very large values. Selective disclosure keeps the
|
|
8
|
+
* commitment (`root`) over the whole component set while only these cheap,
|
|
9
|
+
* stable scalar components carry a path + value, shrinking the payload ~10x.
|
|
10
|
+
*
|
|
11
|
+
* The provider-side validator's bounds MUST be a subset of these keys: a bounded
|
|
12
|
+
* key that isn't disclosed would always fail validation as `missing:<key>`.
|
|
13
|
+
*/
|
|
14
|
+
var FINGERPRINT_DISCLOSURE_KEYS = [
|
|
15
|
+
"colorDepth",
|
|
16
|
+
"cookiesEnabled",
|
|
17
|
+
"sessionStorage",
|
|
18
|
+
"localStorage",
|
|
19
|
+
"timezone",
|
|
20
|
+
"hardwareConcurrency",
|
|
21
|
+
"languages",
|
|
22
|
+
"architecture",
|
|
23
|
+
"deviceBucket"
|
|
24
|
+
];
|
|
25
|
+
var escapeKey = (key) => key.replace(/([:|\\])/g, "\\$1");
|
|
26
|
+
var componentLeafContent = (key, component) => {
|
|
27
|
+
const serialized = "error" in component ? "error" : JSON.stringify(component.value);
|
|
28
|
+
return `${escapeKey(key)}:${serialized}`;
|
|
29
|
+
};
|
|
30
|
+
var disclosureLeafContent = (disclosure) => {
|
|
31
|
+
const serialized = disclosure.error ? "error" : JSON.stringify(disclosure.value);
|
|
32
|
+
return `${escapeKey(disclosure.key)}:${serialized}`;
|
|
33
|
+
};
|
|
34
|
+
var leafHashForContent = (content) => hexHash(content);
|
|
35
|
+
/**
|
|
36
|
+
* Build a {@link FingerprintProof} from an already-resolved FingerprintJS
|
|
37
|
+
* components map. The commitment always covers every component (in sorted key
|
|
38
|
+
* order); `discloseKeys` selects which components are revealed (defaulting to
|
|
39
|
+
* all). Keys that are not present in the fingerprint are skipped — a validator
|
|
40
|
+
* should treat an expected-but-absent disclosure as a failure.
|
|
41
|
+
*/
|
|
42
|
+
var buildFingerprintProofFromComponents = (components, discloseKeys) => {
|
|
43
|
+
const keys = Object.keys(components).sort();
|
|
44
|
+
if (keys.length === 0) throw new Error("fingerprint proof: no components to commit to");
|
|
45
|
+
const leafHashes = keys.map((key) => {
|
|
46
|
+
const component = components[key];
|
|
47
|
+
if (component === void 0) throw new Error(`fingerprint proof: missing component ${key}`);
|
|
48
|
+
return leafHashForContent(componentLeafContent(key, component));
|
|
49
|
+
});
|
|
50
|
+
const layers = buildMerkleLayers(leafHashes);
|
|
51
|
+
const root = merkleRootFromLayers(layers);
|
|
52
|
+
const disclose = discloseKeys ?? keys;
|
|
53
|
+
const disclosures = [];
|
|
54
|
+
for (const key of disclose) {
|
|
55
|
+
const index = keys.indexOf(key);
|
|
56
|
+
if (index === -1) continue;
|
|
57
|
+
const component = components[key];
|
|
58
|
+
const leafHash = leafHashes[index];
|
|
59
|
+
if (component === void 0 || leafHash === void 0) continue;
|
|
60
|
+
const proof = merkleProofFromLayers(layers, leafHash);
|
|
61
|
+
disclosures.push("error" in component ? {
|
|
62
|
+
key,
|
|
63
|
+
error: true,
|
|
64
|
+
proof
|
|
65
|
+
} : {
|
|
66
|
+
key,
|
|
67
|
+
value: component.value,
|
|
68
|
+
proof
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
v: 1,
|
|
73
|
+
root,
|
|
74
|
+
disclosures
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Structural verification of a proof: every disclosed `(key, value)` re-hashes
|
|
79
|
+
* to a leaf that is proven to belong to the single committed `root`. This is
|
|
80
|
+
* the non-secret half of validation — the value-bounding rules live in the
|
|
81
|
+
* provider-side (closed-source) validator and are layered on top of this.
|
|
82
|
+
*/
|
|
83
|
+
var verifyFingerprintProofStructure = (proof) => {
|
|
84
|
+
if (proof.v !== 1) return false;
|
|
85
|
+
if (typeof proof.root !== "string" || proof.disclosures.length === 0) return false;
|
|
86
|
+
for (const disclosure of proof.disclosures) {
|
|
87
|
+
if (!verifyMerkleProof(leafHashForContent(disclosureLeafContent(disclosure)), disclosure.proof)) return false;
|
|
88
|
+
const rootLayer = disclosure.proof[disclosure.proof.length - 1];
|
|
89
|
+
if (rootLayer === void 0 || rootLayer[0] !== proof.root) return false;
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
};
|
|
93
|
+
var encodeFingerprintProof = (proof) => JSON.stringify(proof);
|
|
94
|
+
//#endregion
|
|
95
|
+
export { FINGERPRINT_DISCLOSURE_KEYS, buildFingerprintProofFromComponents, encodeFingerprintProof, leafHashForContent, verifyFingerprintProofStructure };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { verifyFingerprintProofStructure } from "./proof.js";
|
|
2
|
+
import { hexHash } from "@prosopo/util-crypto";
|
|
3
|
+
//#region ../fingerprint/dist/summary.js
|
|
4
|
+
/**
|
|
5
|
+
* The disclosed keys that are fixed by the installation and the host. A hash
|
|
6
|
+
* over them names a cohort of devices.
|
|
7
|
+
*
|
|
8
|
+
* `colorDepth` and `hardwareConcurrency` are disclosed too but kept out of the
|
|
9
|
+
* hash and stored beside it, so that the values can be read per cohort rather
|
|
10
|
+
* than only folded into it.
|
|
11
|
+
*/
|
|
12
|
+
var GROUP_KEYS = [
|
|
13
|
+
"cookiesEnabled",
|
|
14
|
+
"sessionStorage",
|
|
15
|
+
"localStorage",
|
|
16
|
+
"timezone",
|
|
17
|
+
"languages",
|
|
18
|
+
"architecture"
|
|
19
|
+
];
|
|
20
|
+
var asNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
21
|
+
/**
|
|
22
|
+
* Reduce an encoded proof to the fields worth storing, or `undefined` when it
|
|
23
|
+
* is absent, unparseable, or fails structural verification.
|
|
24
|
+
*
|
|
25
|
+
* Structural verification is not optional here: an unverified disclosure is a
|
|
26
|
+
* client-asserted value with a decorative Merkle path beside it, and storing
|
|
27
|
+
* one would put a forgeable field into an aggregation that reads as
|
|
28
|
+
* tamper-evident. Whether the values are *plausible* is a separate concern and
|
|
29
|
+
* stays in the routing machine's validator; this only refuses what does not
|
|
30
|
+
* hash together.
|
|
31
|
+
*/
|
|
32
|
+
var summariseFingerprintProof = (encoded) => {
|
|
33
|
+
if (!encoded) return void 0;
|
|
34
|
+
let proof;
|
|
35
|
+
try {
|
|
36
|
+
proof = JSON.parse(encoded);
|
|
37
|
+
} catch {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (typeof proof !== "object" || proof === null || typeof proof.root !== "string" || !Array.isArray(proof.disclosures)) return;
|
|
41
|
+
if (!verifyFingerprintProofStructure(proof)) return void 0;
|
|
42
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
43
|
+
for (const disclosure of proof.disclosures) if (!disclosure.error) byKey.set(disclosure.key, disclosure.value);
|
|
44
|
+
const groupInput = GROUP_KEYS.map((key) => `${key}:${JSON.stringify(byKey.get(key) ?? null)}`).join("|");
|
|
45
|
+
const disclosed = {};
|
|
46
|
+
const timezone = byKey.get("timezone");
|
|
47
|
+
if (typeof timezone === "string") disclosed.timezone = timezone;
|
|
48
|
+
const languages = byKey.get("languages");
|
|
49
|
+
if (languages !== void 0) disclosed.languages = JSON.stringify(languages);
|
|
50
|
+
const architecture = asNumber(byKey.get("architecture"));
|
|
51
|
+
if (architecture !== void 0) disclosed.architecture = architecture;
|
|
52
|
+
for (const key of [
|
|
53
|
+
"cookiesEnabled",
|
|
54
|
+
"sessionStorage",
|
|
55
|
+
"localStorage"
|
|
56
|
+
]) {
|
|
57
|
+
const value = byKey.get(key);
|
|
58
|
+
if (typeof value === "boolean") disclosed[key] = value;
|
|
59
|
+
}
|
|
60
|
+
const bucketId = byKey.get("deviceBucket");
|
|
61
|
+
const colorDepth = asNumber(byKey.get("colorDepth"));
|
|
62
|
+
const hardwareConcurrency = asNumber(byKey.get("hardwareConcurrency"));
|
|
63
|
+
return {
|
|
64
|
+
root: proof.root,
|
|
65
|
+
groupHash: hexHash(groupInput),
|
|
66
|
+
...typeof bucketId === "string" && bucketId !== "" && { bucketId },
|
|
67
|
+
...colorDepth !== void 0 && { colorDepth },
|
|
68
|
+
...hardwareConcurrency !== void 0 && { hardwareConcurrency },
|
|
69
|
+
...Object.keys(disclosed).length > 0 && { disclosed }
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
export { summariseFingerprintProof };
|
package/dist/index.js
CHANGED
|
@@ -17,9 +17,9 @@ import { createApiAdminRoutesProvider } from "./api/admin/createApiAdminRoutesPr
|
|
|
17
17
|
import { headerCheckMiddleware } from "./api/headerCheckMiddleware.js";
|
|
18
18
|
import { ignoreMiddleware } from "./api/ignoreMiddleware.js";
|
|
19
19
|
import { robotsMiddleware } from "./api/robotsMiddleware.js";
|
|
20
|
-
import { getClientApiPathsExpectingProsopoHeaders, getUserFromJWT, isTlsAvailable, providerCorsOptions, startProviderApi } from "./api/startProviderApi.js";
|
|
20
|
+
import { getClientApiPathsExpectingProsopoHeaders, getServerVerifyPaths, getUserFromJWT, isTlsAvailable, providerCorsOptions, startProviderApi } from "./api/startProviderApi.js";
|
|
21
21
|
import { migrateFrictionlessLadder, runFrictionlessLadderMigration } from "./migrations/frictionlessLadder.js";
|
|
22
22
|
import { storeCaptchasExternally } from "./schedulers/captchaScheduler.js";
|
|
23
23
|
import { getClientList } from "./schedulers/getClientList.js";
|
|
24
24
|
import { updateSpamEmailDomainsScheduler } from "./schedulers/updateSpamEmailDomains.js";
|
|
25
|
-
export { BlacklistRequestInspector, DEFAULT_JA4, FrictionlessReason, Tasks, asyncHandler, blockMiddleware, checkIfTaskIsRunning, compareIPs, createApiAdminRoutesProvider, deepValidateIpAddress, domainMiddleware, encodeStringAddress, evaluateIpValidationRules, getClientApiPathsExpectingProsopoHeaders, getClientList, getCompositeIpAddress, getHandshakeTiming, getIPAddress, getIPAddressFromBigInt, getIpAddressFromComposite, getJA4, getPrioritisedAccessRule, getRequestUserScope, getUserFromJWT, getVerdictCache, handshakeTimingMiddleware, headerCheckMiddleware, ignoreMiddleware, isSameIpOrigin, isTlsAvailable, ja4Middleware, migrateFrictionlessLadder, normalizeHeadersForMatching, prosopoRouter, prosopoVerifyRouter, providerCorsOptions, publicRouter, rankCandidateRules, robotsMiddleware, runFrictionlessLadderMigration, shuffleArray, startProviderApi, storeCaptchasExternally, updateSpamEmailDomains, updateSpamEmailDomainsScheduler, validateIpAddress };
|
|
25
|
+
export { BlacklistRequestInspector, DEFAULT_JA4, FrictionlessReason, Tasks, asyncHandler, blockMiddleware, checkIfTaskIsRunning, compareIPs, createApiAdminRoutesProvider, deepValidateIpAddress, domainMiddleware, encodeStringAddress, evaluateIpValidationRules, getClientApiPathsExpectingProsopoHeaders, getClientList, getCompositeIpAddress, getHandshakeTiming, getIPAddress, getIPAddressFromBigInt, getIpAddressFromComposite, getJA4, getPrioritisedAccessRule, getRequestUserScope, getServerVerifyPaths, getUserFromJWT, getVerdictCache, handshakeTimingMiddleware, headerCheckMiddleware, ignoreMiddleware, isSameIpOrigin, isTlsAvailable, ja4Middleware, migrateFrictionlessLadder, normalizeHeadersForMatching, prosopoRouter, prosopoVerifyRouter, providerCorsOptions, publicRouter, rankCandidateRules, robotsMiddleware, runFrictionlessLadderMigration, shuffleArray, startProviderApi, storeCaptchasExternally, updateSpamEmailDomains, updateSpamEmailDomainsScheduler, validateIpAddress };
|