@prosopo/provider 2.1.5 → 2.1.6
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/.dockerignore +5 -0
- package/dist/api/admin.d.ts +4 -0
- package/dist/api/admin.d.ts.map +1 -0
- package/dist/api/admin.js +36 -0
- package/dist/api/admin.js.map +1 -0
- package/dist/api/authMiddleware.d.ts +6 -0
- package/dist/api/authMiddleware.d.ts.map +1 -0
- package/dist/api/authMiddleware.js +66 -0
- package/dist/api/authMiddleware.js.map +1 -0
- package/dist/api/captcha.d.ts +4 -0
- package/dist/api/captcha.d.ts.map +1 -0
- package/dist/api/captcha.js +299 -0
- package/dist/api/captcha.js.map +1 -0
- package/dist/api/captchaScheduler.d.ts +4 -0
- package/dist/api/captchaScheduler.d.ts.map +1 -0
- package/dist/api/captchaScheduler.js +17 -0
- package/dist/api/captchaScheduler.js.map +1 -0
- package/dist/api/errorHandler.d.ts +11 -0
- package/dist/api/errorHandler.d.ts.map +1 -0
- package/dist/api/errorHandler.js +42 -0
- package/dist/api/errorHandler.js.map +1 -0
- package/dist/api/verify.d.ts +4 -0
- package/dist/api/verify.d.ts.map +1 -0
- package/dist/api/verify.js +98 -0
- package/dist/api/verify.js.map +1 -0
- package/dist/batch/commitments.d.ts +24 -0
- package/dist/batch/commitments.d.ts.map +1 -0
- package/dist/batch/commitments.js +130 -0
- package/dist/batch/commitments.js.map +1 -0
- package/dist/batch/index.d.ts +2 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/batch/index.js +2 -0
- package/dist/batch/index.js.map +1 -0
- package/dist/cjs/api/admin.cjs +37 -0
- package/dist/cjs/api/authMiddleware.cjs +66 -0
- package/dist/cjs/api/captcha.cjs +380 -0
- package/dist/cjs/api/errorHandler.cjs +42 -0
- package/dist/cjs/api/verify.cjs +120 -0
- package/dist/cjs/index.cjs +25 -0
- package/dist/cjs/schedulers/captchaScheduler.cjs +33 -0
- package/dist/cjs/schedulers/getClientList.cjs +31 -0
- package/dist/cjs/tasks/client/clientTasks.cjs +148 -0
- package/dist/cjs/tasks/dataset/datasetTasks.cjs +30 -0
- package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +34 -0
- package/dist/cjs/tasks/detection/decodePayload.cjs +549 -0
- package/dist/cjs/tasks/detection/getBotScore.cjs +18 -0
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +313 -0
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +25 -0
- package/dist/cjs/tasks/index.cjs +4 -0
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +134 -0
- package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +26 -0
- package/dist/cjs/tasks/tasks.cjs +40 -0
- package/dist/cjs/util.cjs +45 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/scheduler.d.ts +4 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +21 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/schedulers/captchaScheduler.d.ts +4 -0
- package/dist/schedulers/captchaScheduler.d.ts.map +1 -0
- package/dist/schedulers/captchaScheduler.js +28 -0
- package/dist/schedulers/captchaScheduler.js.map +1 -0
- package/dist/schedulers/getClientList.d.ts +4 -0
- package/dist/schedulers/getClientList.d.ts.map +1 -0
- package/dist/schedulers/getClientList.js +28 -0
- package/dist/schedulers/getClientList.js.map +1 -0
- package/dist/tasks/client/clientTasks.d.ts +13 -0
- package/dist/tasks/client/clientTasks.d.ts.map +1 -0
- package/dist/tasks/client/clientTasks.js +87 -0
- package/dist/tasks/client/clientTasks.js.map +1 -0
- package/dist/tasks/dataset/datasetTasks.d.ts +13 -0
- package/dist/tasks/dataset/datasetTasks.d.ts.map +1 -0
- package/dist/tasks/dataset/datasetTasks.js +19 -0
- package/dist/tasks/dataset/datasetTasks.js.map +1 -0
- package/dist/tasks/dataset/datasetTasksUtils.d.ts +3 -0
- package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +1 -0
- package/dist/tasks/dataset/datasetTasksUtils.js +34 -0
- package/dist/tasks/dataset/datasetTasksUtils.js.map +1 -0
- package/dist/tasks/detection/decodePayload.d.ts +3 -0
- package/dist/tasks/detection/decodePayload.d.ts.map +1 -0
- package/dist/tasks/detection/decodePayload.js +302 -0
- package/dist/tasks/detection/decodePayload.js.map +1 -0
- package/dist/tasks/detection/getBotScore.d.ts +2 -0
- package/dist/tasks/detection/getBotScore.d.ts.map +1 -0
- package/dist/tasks/detection/getBotScore.js +17 -0
- package/dist/tasks/detection/getBotScore.js.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +29 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +242 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +7 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +18 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +1 -0
- package/dist/tasks/index.d.ts +2 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +2 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasks.d.ts +13 -0
- package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -0
- package/dist/tasks/powCaptcha/powTasks.js +84 -0
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts +3 -0
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +1 -0
- package/dist/tasks/powCaptcha/powTasksUtils.js +22 -0
- package/dist/tasks/powCaptcha/powTasksUtils.js.map +1 -0
- package/dist/tasks/tasks.d.ts +22 -0
- package/dist/tasks/tasks.d.ts.map +1 -0
- package/dist/tasks/tasks.js +24 -0
- package/dist/tasks/tasks.js.map +1 -0
- package/dist/tests/accounts.d.ts +12 -0
- package/dist/tests/accounts.d.ts.map +1 -0
- package/dist/tests/accounts.js +35 -0
- package/dist/tests/accounts.js.map +1 -0
- package/dist/tests/contract/helpers.test.d.ts +6 -0
- package/dist/tests/contract/helpers.test.d.ts.map +1 -0
- package/dist/tests/contract/helpers.test.js +54 -0
- package/dist/tests/contract/helpers.test.js.map +1 -0
- package/dist/tests/dataUtils/DatabaseAccounts.d.ts +35 -0
- package/dist/tests/dataUtils/DatabaseAccounts.d.ts.map +1 -0
- package/dist/tests/dataUtils/DatabaseAccounts.js +84 -0
- package/dist/tests/dataUtils/DatabaseAccounts.js.map +1 -0
- package/dist/tests/dataUtils/DatabasePopulator.d.ts +73 -0
- package/dist/tests/dataUtils/DatabasePopulator.d.ts.map +1 -0
- package/dist/tests/dataUtils/DatabasePopulator.js +326 -0
- package/dist/tests/dataUtils/DatabasePopulator.js.map +1 -0
- package/dist/tests/dataUtils/dapp-example-contract/dapp.json +648 -0
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.d.ts +4 -0
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.d.ts.map +1 -0
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.js +27 -0
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.js.map +1 -0
- package/dist/tests/dataUtils/funds.d.ts +9 -0
- package/dist/tests/dataUtils/funds.d.ts.map +1 -0
- package/dist/tests/dataUtils/funds.js +105 -0
- package/dist/tests/dataUtils/funds.js.map +1 -0
- package/dist/tests/dataUtils/populateDatabase.d.ts +16 -0
- package/dist/tests/dataUtils/populateDatabase.d.ts.map +1 -0
- package/dist/tests/dataUtils/populateDatabase.js +72 -0
- package/dist/tests/dataUtils/populateDatabase.js.map +1 -0
- package/dist/tests/getUser.d.ts +4 -0
- package/dist/tests/getUser.d.ts.map +1 -0
- package/dist/tests/getUser.js +18 -0
- package/dist/tests/getUser.js.map +1 -0
- package/dist/tests/index.d.ts +2 -0
- package/dist/tests/index.d.ts.map +1 -0
- package/dist/tests/index.js +2 -0
- package/dist/tests/index.js.map +1 -0
- package/dist/tests/integration/imgCaptcha.integration.test.d.ts +2 -0
- package/dist/tests/integration/imgCaptcha.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/imgCaptcha.integration.test.js +137 -0
- package/dist/tests/integration/imgCaptcha.integration.test.js.map +1 -0
- package/dist/tests/integration/imgCaptcha.test.d.ts +2 -0
- package/dist/tests/integration/imgCaptcha.test.d.ts.map +1 -0
- package/dist/tests/integration/imgCaptcha.test.js +103 -0
- package/dist/tests/integration/imgCaptcha.test.js.map +1 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts +32 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts.map +1 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.js +1046 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.js.map +1 -0
- package/dist/tests/integration/powCaptcha.integration.test.d.ts +2 -0
- package/dist/tests/integration/powCaptcha.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/powCaptcha.integration.test.js +222 -0
- package/dist/tests/integration/powCaptcha.integration.test.js.map +1 -0
- package/dist/tests/integration/powCaptcha.test.d.ts +2 -0
- package/dist/tests/integration/powCaptcha.test.d.ts.map +1 -0
- package/dist/tests/integration/powCaptcha.test.js +133 -0
- package/dist/tests/integration/powCaptcha.test.js.map +1 -0
- package/dist/tests/integration/registerSitekey.d.ts +2 -0
- package/dist/tests/integration/registerSitekey.d.ts.map +1 -0
- package/dist/tests/integration/registerSitekey.js +28 -0
- package/dist/tests/integration/registerSitekey.js.map +1 -0
- package/dist/tests/tasks/tasks.test.d.ts +6 -0
- package/dist/tests/tasks/tasks.test.d.ts.map +1 -0
- package/dist/tests/tasks/tasks.test.js +636 -0
- package/dist/tests/tasks/tasks.test.js.map +1 -0
- package/dist/tests/unit/api/authMiddleware.test.d.ts +2 -0
- package/dist/tests/unit/api/authMiddleware.test.d.ts.map +1 -0
- package/dist/tests/unit/api/authMiddleware.test.js +87 -0
- package/dist/tests/unit/api/authMiddleware.test.js.map +1 -0
- package/dist/tests/unit/api/authMiddleware.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/authMiddleware.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/authMiddleware.unit.test.js +108 -0
- package/dist/tests/unit/api/authMiddleware.unit.test.js.map +1 -0
- package/dist/tests/unit/api/captchaScheduler.test.d.ts +2 -0
- package/dist/tests/unit/api/captchaScheduler.test.d.ts.map +1 -0
- package/dist/tests/unit/api/captchaScheduler.test.js +47 -0
- package/dist/tests/unit/api/captchaScheduler.test.js.map +1 -0
- package/dist/tests/unit/api/errorHandler.test.d.ts +2 -0
- package/dist/tests/unit/api/errorHandler.test.d.ts.map +1 -0
- package/dist/tests/unit/api/errorHandler.test.js +65 -0
- package/dist/tests/unit/api/errorHandler.test.js.map +1 -0
- package/dist/tests/unit/api/errorHandler.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/errorHandler.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/errorHandler.unit.test.js +100 -0
- package/dist/tests/unit/api/errorHandler.unit.test.js.map +1 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts +2 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +63 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +172 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.test.d.ts +2 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.test.js +82 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.test.js.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js +86 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.d.ts +2 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.js +75 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.js.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +75 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.d.ts +2 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.js +245 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.js.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +266 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.d.ts +2 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.js +45 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.js.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +46 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.test.js +121 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +209 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.js +94 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +65 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/util.test.d.ts +2 -0
- package/dist/tests/util.test.d.ts.map +1 -0
- package/dist/tests/util.test.js +23 -0
- package/dist/tests/util.test.js.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +34 -0
- package/dist/util.js.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const util$1 = require("@polkadot/util");
|
|
4
|
+
const utilCrypto = require("@polkadot/util-crypto");
|
|
5
|
+
const common = require("@prosopo/common");
|
|
6
|
+
const datasets = require("@prosopo/datasets");
|
|
7
|
+
const types = require("@prosopo/types");
|
|
8
|
+
const util$2 = require("@prosopo/util");
|
|
9
|
+
const util = require("../../util.cjs");
|
|
10
|
+
const imgCaptchaTasksUtils = require("./imgCaptchaTasksUtils.cjs");
|
|
11
|
+
class ImgCaptchaManager {
|
|
12
|
+
constructor(db, pair, logger, captchaConfig) {
|
|
13
|
+
this.db = db;
|
|
14
|
+
this.pair = pair;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
this.captchaConfig = captchaConfig;
|
|
17
|
+
}
|
|
18
|
+
async getCaptchaWithProof(datasetId, solved, size) {
|
|
19
|
+
const captchaDocs = await this.db.getRandomCaptcha(solved, datasetId, size);
|
|
20
|
+
if (!captchaDocs) {
|
|
21
|
+
throw new common.ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
22
|
+
context: {
|
|
23
|
+
failedFuncName: this.getCaptchaWithProof.name,
|
|
24
|
+
datasetId,
|
|
25
|
+
solved,
|
|
26
|
+
size
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return captchaDocs;
|
|
31
|
+
}
|
|
32
|
+
async getRandomCaptchasAndRequestHash(datasetId, userAccount, ipAddress, headers) {
|
|
33
|
+
const dataset = await this.db.getDatasetDetails(datasetId);
|
|
34
|
+
if (!dataset) {
|
|
35
|
+
throw new common.ProsopoEnvError("DATABASE.DATASET_GET_FAILED", {
|
|
36
|
+
context: {
|
|
37
|
+
failedFuncName: this.getRandomCaptchasAndRequestHash.name,
|
|
38
|
+
dataset,
|
|
39
|
+
datasetId
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const unsolvedCount = Math.abs(
|
|
44
|
+
Math.trunc(this.captchaConfig.unsolved.count)
|
|
45
|
+
);
|
|
46
|
+
const solvedCount = Math.abs(
|
|
47
|
+
Math.trunc(this.captchaConfig.solved.count)
|
|
48
|
+
);
|
|
49
|
+
if (!solvedCount) {
|
|
50
|
+
throw new common.ProsopoEnvError("CONFIG.INVALID_CAPTCHA_NUMBER");
|
|
51
|
+
}
|
|
52
|
+
const solved = await this.getCaptchaWithProof(datasetId, true, solvedCount);
|
|
53
|
+
let unsolved = [];
|
|
54
|
+
if (unsolvedCount) {
|
|
55
|
+
unsolved = await this.getCaptchaWithProof(
|
|
56
|
+
datasetId,
|
|
57
|
+
false,
|
|
58
|
+
unsolvedCount
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const captchas = util.shuffleArray([...solved, ...unsolved]);
|
|
62
|
+
const salt = utilCrypto.randomAsHex();
|
|
63
|
+
const requestHash = datasets.computePendingRequestHash(
|
|
64
|
+
captchas.map((c) => c.captchaId),
|
|
65
|
+
userAccount,
|
|
66
|
+
salt
|
|
67
|
+
);
|
|
68
|
+
const currentTime = Date.now();
|
|
69
|
+
const signedRequestHash = util$1.u8aToHex(
|
|
70
|
+
this.pair.sign(util$1.stringToHex(requestHash))
|
|
71
|
+
);
|
|
72
|
+
const timeLimit = captchas.map((captcha) => captcha.timeLimitMs || types.DEFAULT_IMAGE_CAPTCHA_TIMEOUT).reduce((a, b) => a + b, 0);
|
|
73
|
+
const deadlineTs = timeLimit + currentTime;
|
|
74
|
+
const currentBlockNumber = 0;
|
|
75
|
+
await this.db.storeDappUserPending(
|
|
76
|
+
userAccount,
|
|
77
|
+
requestHash,
|
|
78
|
+
salt,
|
|
79
|
+
deadlineTs,
|
|
80
|
+
currentTime,
|
|
81
|
+
ipAddress,
|
|
82
|
+
headers
|
|
83
|
+
);
|
|
84
|
+
return {
|
|
85
|
+
captchas,
|
|
86
|
+
requestHash,
|
|
87
|
+
timestamp: currentTime,
|
|
88
|
+
signedRequestHash
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validate and store the text captcha solution(s) from the Dapp User in a web2 environment
|
|
93
|
+
* @param {string} userAccount
|
|
94
|
+
* @param {string} dappAccount
|
|
95
|
+
* @param {string} requestHash
|
|
96
|
+
* @param {JSON} captchas
|
|
97
|
+
* @param {string} userRequestHashSignature
|
|
98
|
+
* @param timestamp
|
|
99
|
+
* @param providerRequestHashSignature
|
|
100
|
+
* @param ipAddress
|
|
101
|
+
* @param headers
|
|
102
|
+
* @return {Promise<DappUserSolutionResult>} result containing the contract event
|
|
103
|
+
*/
|
|
104
|
+
async dappUserSolution(userAccount, dappAccount, requestHash, captchas, userTimestampSignature, timestamp, providerRequestHashSignature, ipAddress, headers) {
|
|
105
|
+
const verification = utilCrypto.signatureVerify(
|
|
106
|
+
util$1.stringToHex(timestamp.toString()),
|
|
107
|
+
userTimestampSignature,
|
|
108
|
+
userAccount
|
|
109
|
+
);
|
|
110
|
+
if (!verification.isValid) {
|
|
111
|
+
this.logger.info("Invalid user timestamp signature");
|
|
112
|
+
throw new common.ProsopoEnvError("GENERAL.INVALID_SIGNATURE", {
|
|
113
|
+
context: { failedFuncName: this.dappUserSolution.name, userAccount }
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const providerRequestHashSignatureVerify = utilCrypto.signatureVerify(
|
|
117
|
+
util$1.stringToHex(requestHash.toString()),
|
|
118
|
+
providerRequestHashSignature,
|
|
119
|
+
this.pair.address
|
|
120
|
+
);
|
|
121
|
+
if (!providerRequestHashSignatureVerify.isValid) {
|
|
122
|
+
this.logger.info("Invalid provider requestHash signature");
|
|
123
|
+
throw new common.ProsopoEnvError("GENERAL.INVALID_SIGNATURE", {
|
|
124
|
+
context: {
|
|
125
|
+
failedFuncName: this.dappUserSolution.name,
|
|
126
|
+
userAccount,
|
|
127
|
+
error: "requestHash signature is invalid"
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
let response = {
|
|
132
|
+
captchas: [],
|
|
133
|
+
verified: false
|
|
134
|
+
};
|
|
135
|
+
const pendingRecord = await this.db.getDappUserPending(requestHash);
|
|
136
|
+
const unverifiedCaptchaIds = captchas.map((captcha) => captcha.captchaId);
|
|
137
|
+
const pendingRequest = await this.validateDappUserSolutionRequestIsPending(
|
|
138
|
+
requestHash,
|
|
139
|
+
pendingRecord,
|
|
140
|
+
userAccount,
|
|
141
|
+
unverifiedCaptchaIds
|
|
142
|
+
);
|
|
143
|
+
if (pendingRequest) {
|
|
144
|
+
const { storedCaptchas, receivedCaptchas, captchaIds } = await this.validateReceivedCaptchasAgainstStoredCaptchas(captchas);
|
|
145
|
+
const { tree, commitmentId } = imgCaptchaTasksUtils.buildTreeAndGetCommitmentId(receivedCaptchas);
|
|
146
|
+
const datasetId = util$2.at(storedCaptchas, 0).datasetId;
|
|
147
|
+
if (!datasetId) {
|
|
148
|
+
throw new common.ProsopoEnvError("CAPTCHA.ID_MISMATCH", {
|
|
149
|
+
context: { failedFuncName: this.dappUserSolution.name }
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
await this.db.updateDappUserPendingStatus(requestHash);
|
|
153
|
+
const commit = {
|
|
154
|
+
id: commitmentId,
|
|
155
|
+
userAccount,
|
|
156
|
+
dappAccount,
|
|
157
|
+
providerAccount: this.pair.address,
|
|
158
|
+
datasetId,
|
|
159
|
+
result: { status: types.CaptchaStatus.pending },
|
|
160
|
+
userSignature: userTimestampSignature,
|
|
161
|
+
userSubmitted: true,
|
|
162
|
+
serverChecked: false,
|
|
163
|
+
requestedAtTimestamp: timestamp,
|
|
164
|
+
ipAddress,
|
|
165
|
+
headers
|
|
166
|
+
};
|
|
167
|
+
await this.db.storeDappUserSolution(receivedCaptchas, commit);
|
|
168
|
+
if (datasets.compareCaptchaSolutions(receivedCaptchas, storedCaptchas)) {
|
|
169
|
+
response = {
|
|
170
|
+
captchas: captchaIds.map((id) => ({
|
|
171
|
+
captchaId: id,
|
|
172
|
+
proof: tree.proof(id)
|
|
173
|
+
})),
|
|
174
|
+
verified: true
|
|
175
|
+
};
|
|
176
|
+
await this.db.approveDappUserCommitment(commitmentId);
|
|
177
|
+
} else {
|
|
178
|
+
await this.db.disapproveDappUserCommitment(
|
|
179
|
+
commitmentId,
|
|
180
|
+
"CAPTCHA.INVALID_SOLUTION"
|
|
181
|
+
);
|
|
182
|
+
response = {
|
|
183
|
+
captchas: captchaIds.map((id) => ({
|
|
184
|
+
captchaId: id,
|
|
185
|
+
proof: [[]]
|
|
186
|
+
})),
|
|
187
|
+
verified: false
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
this.logger.info("Request hash not found");
|
|
192
|
+
}
|
|
193
|
+
return response;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Validate length of received captchas array matches length of captchas found in database
|
|
197
|
+
* Validate that the datasetId is the same for all captchas and is equal to the datasetId on the stored captchas
|
|
198
|
+
*/
|
|
199
|
+
async validateReceivedCaptchasAgainstStoredCaptchas(captchas) {
|
|
200
|
+
const receivedCaptchas = datasets.parseAndSortCaptchaSolutions(captchas);
|
|
201
|
+
const captchaIds = receivedCaptchas.map((captcha) => captcha.captchaId);
|
|
202
|
+
const storedCaptchas = await this.db.getCaptchaById(captchaIds);
|
|
203
|
+
if (!storedCaptchas || receivedCaptchas.length !== storedCaptchas.length) {
|
|
204
|
+
throw new common.ProsopoEnvError("CAPTCHA.INVALID_CAPTCHA_ID", {
|
|
205
|
+
context: {
|
|
206
|
+
failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
|
|
207
|
+
captchas
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (!storedCaptchas.every(
|
|
212
|
+
(captcha) => captcha.datasetId === util$2.at(storedCaptchas, 0).datasetId
|
|
213
|
+
)) {
|
|
214
|
+
throw new common.ProsopoEnvError("CAPTCHA.DIFFERENT_DATASET_IDS", {
|
|
215
|
+
context: {
|
|
216
|
+
failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
|
|
217
|
+
captchas
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return { storedCaptchas, receivedCaptchas, captchaIds };
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Validate that a Dapp User is responding to their own pending captcha request
|
|
225
|
+
* @param {string} requestHash
|
|
226
|
+
* @param {PendingCaptchaRequest} pendingRecord
|
|
227
|
+
* @param {string} userAccount
|
|
228
|
+
* @param {string[]} captchaIds
|
|
229
|
+
*/
|
|
230
|
+
async validateDappUserSolutionRequestIsPending(requestHash, pendingRecord, userAccount, captchaIds) {
|
|
231
|
+
const currentTime = Date.now();
|
|
232
|
+
if (!pendingRecord) {
|
|
233
|
+
this.logger.info("No pending record found");
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
if (pendingRecord.deadlineTimestamp < currentTime) {
|
|
237
|
+
this.logger.info("Deadline for responding to captcha has expired");
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
if (pendingRecord) {
|
|
241
|
+
const pendingHashComputed = datasets.computePendingRequestHash(
|
|
242
|
+
captchaIds,
|
|
243
|
+
userAccount,
|
|
244
|
+
pendingRecord.salt
|
|
245
|
+
);
|
|
246
|
+
return requestHash === pendingHashComputed;
|
|
247
|
+
}
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
/*
|
|
251
|
+
* Get dapp user solution from database
|
|
252
|
+
*/
|
|
253
|
+
async getDappUserCommitmentById(commitmentId) {
|
|
254
|
+
const dappUserSolution = await this.db.getDappUserCommitmentById(commitmentId);
|
|
255
|
+
if (!dappUserSolution) {
|
|
256
|
+
throw new common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", {
|
|
257
|
+
context: {
|
|
258
|
+
failedFuncName: this.getDappUserCommitmentById.name,
|
|
259
|
+
commitmentId
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return dappUserSolution;
|
|
264
|
+
}
|
|
265
|
+
/* Check if dapp user has verified solution in cache */
|
|
266
|
+
async getDappUserCommitmentByAccount(userAccount, dappAccount) {
|
|
267
|
+
const dappUserSolutions = await this.db.getDappUserCommitmentByAccount(
|
|
268
|
+
userAccount,
|
|
269
|
+
dappAccount
|
|
270
|
+
);
|
|
271
|
+
if (dappUserSolutions.length > 0) {
|
|
272
|
+
for (const dappUserSolution of dappUserSolutions) {
|
|
273
|
+
if (dappUserSolution.result.status === types.CaptchaStatus.approved) {
|
|
274
|
+
return dappUserSolution;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return void 0;
|
|
279
|
+
}
|
|
280
|
+
async verifyImageCaptchaSolution(user, dapp, commitmentId, maxVerifiedTime) {
|
|
281
|
+
const solution = await (commitmentId ? this.getDappUserCommitmentById(commitmentId) : this.getDappUserCommitmentByAccount(user, dapp));
|
|
282
|
+
if (!solution) {
|
|
283
|
+
this.logger.debug("Not verified - no solution found");
|
|
284
|
+
return { status: "API.USER_NOT_VERIFIED_NO_SOLUTION", verified: false };
|
|
285
|
+
}
|
|
286
|
+
if (solution.serverChecked) {
|
|
287
|
+
return { status: "API.USER_ALREADY_VERIFIED", verified: false };
|
|
288
|
+
}
|
|
289
|
+
await this.db.markDappUserCommitmentsChecked([solution.id]);
|
|
290
|
+
if (solution.result.status === types.CaptchaStatus.disapproved) {
|
|
291
|
+
return { status: "API.USER_NOT_VERIFIED", verified: false };
|
|
292
|
+
}
|
|
293
|
+
maxVerifiedTime = maxVerifiedTime || 60 * 1e3;
|
|
294
|
+
if (maxVerifiedTime) {
|
|
295
|
+
const currentTime = Date.now();
|
|
296
|
+
const timeSinceCompletion = currentTime - solution.requestedAtTimestamp;
|
|
297
|
+
if (timeSinceCompletion > maxVerifiedTime) {
|
|
298
|
+
this.logger.debug("Not verified - timed out");
|
|
299
|
+
return {
|
|
300
|
+
status: "API.USER_NOT_VERIFIED_TIME_EXPIRED",
|
|
301
|
+
verified: false
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const isApproved = solution.result.status === types.CaptchaStatus.approved;
|
|
306
|
+
return {
|
|
307
|
+
status: isApproved ? "API.USER_VERIFIED" : "API.USER_NOT_VERIFIED",
|
|
308
|
+
verified: isApproved,
|
|
309
|
+
commitmentId: solution.id.toString()
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
exports.ImgCaptchaManager = ImgCaptchaManager;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@prosopo/common");
|
|
4
|
+
const datasets = require("@prosopo/datasets");
|
|
5
|
+
const buildTreeAndGetCommitmentId = (captchaSolutions) => {
|
|
6
|
+
const tree = new datasets.CaptchaMerkleTree();
|
|
7
|
+
const solutionsHashed = captchaSolutions.map(
|
|
8
|
+
(captcha) => datasets.computeCaptchaSolutionHash(captcha)
|
|
9
|
+
);
|
|
10
|
+
tree.build(solutionsHashed);
|
|
11
|
+
const commitmentId = tree.root?.hash;
|
|
12
|
+
if (!commitmentId) {
|
|
13
|
+
throw new common.ProsopoEnvError(
|
|
14
|
+
"CONTRACT.CAPTCHA_SOLUTION_COMMITMENT_DOES_NOT_EXIST",
|
|
15
|
+
{
|
|
16
|
+
context: {
|
|
17
|
+
failedFuncName: buildTreeAndGetCommitmentId.name,
|
|
18
|
+
commitmentId
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
return { tree, commitmentId };
|
|
24
|
+
};
|
|
25
|
+
exports.buildTreeAndGetCommitmentId = buildTreeAndGetCommitmentId;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const util = require("@polkadot/util");
|
|
4
|
+
const common = require("@prosopo/common");
|
|
5
|
+
const types = require("@prosopo/types");
|
|
6
|
+
const util$1 = require("@prosopo/util");
|
|
7
|
+
const powTasksUtils = require("./powTasksUtils.cjs");
|
|
8
|
+
const logger = common.getLoggerDefault();
|
|
9
|
+
const DEFAULT_POW_DIFFICULTY = 4;
|
|
10
|
+
class PowCaptchaManager {
|
|
11
|
+
constructor(pair, db) {
|
|
12
|
+
this.pair = pair;
|
|
13
|
+
this.db = db;
|
|
14
|
+
this.POW_SEPARATOR = types.POW_SEPARATOR;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* @description Generates a PoW Captcha for a given user and dapp
|
|
18
|
+
*
|
|
19
|
+
* @param {string} userAccount - user that is solving the captcha
|
|
20
|
+
* @param {string} dappAccount - dapp that is requesting the captcha
|
|
21
|
+
* @param origin - not currently used
|
|
22
|
+
*/
|
|
23
|
+
async getPowCaptchaChallenge(userAccount, dappAccount, origin, powDifficulty) {
|
|
24
|
+
const difficulty = powDifficulty || DEFAULT_POW_DIFFICULTY;
|
|
25
|
+
const requestedAtTimestamp = Date.now();
|
|
26
|
+
const challenge = `${requestedAtTimestamp}___${userAccount}___${dappAccount}`;
|
|
27
|
+
const challengeSignature = util.u8aToHex(this.pair.sign(util.stringToHex(challenge)));
|
|
28
|
+
return {
|
|
29
|
+
challenge,
|
|
30
|
+
difficulty,
|
|
31
|
+
providerSignature: challengeSignature,
|
|
32
|
+
requestedAtTimestamp
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @description Verifies a PoW Captcha for a given user and dapp
|
|
37
|
+
*
|
|
38
|
+
* @param {string} challenge - the starting string for the PoW challenge
|
|
39
|
+
* @param {string} difficulty - how many leading zeroes the solution must have
|
|
40
|
+
* @param {string} providerChallengeSignature - proof that the Provider provided the challenge
|
|
41
|
+
* @param {string} nonce - the string that the user has found that satisfies the PoW challenge
|
|
42
|
+
* @param {number} timeout - the time in milliseconds since the Provider was selected to provide the PoW captcha
|
|
43
|
+
* @param {string} userTimestampSignature
|
|
44
|
+
* @param ipAddress
|
|
45
|
+
* @param headers
|
|
46
|
+
*/
|
|
47
|
+
async verifyPowCaptchaSolution(challenge, difficulty, providerChallengeSignature, nonce, timeout, userTimestampSignature, ipAddress, headers) {
|
|
48
|
+
powTasksUtils.checkPowSignature(
|
|
49
|
+
challenge,
|
|
50
|
+
providerChallengeSignature,
|
|
51
|
+
this.pair.address,
|
|
52
|
+
types.ApiParams.challenge
|
|
53
|
+
);
|
|
54
|
+
const challengeSplit = challenge.split(this.POW_SEPARATOR);
|
|
55
|
+
const timestamp = Number.parseInt(util$1.at(challengeSplit, 0));
|
|
56
|
+
const userAccount = util$1.at(challengeSplit, 1);
|
|
57
|
+
powTasksUtils.checkPowSignature(
|
|
58
|
+
timestamp.toString(),
|
|
59
|
+
userTimestampSignature,
|
|
60
|
+
userAccount,
|
|
61
|
+
types.ApiParams.timestamp
|
|
62
|
+
);
|
|
63
|
+
const challengeRecord = await this.db.getPowCaptchaRecordByChallenge(challenge);
|
|
64
|
+
if (!challengeRecord) {
|
|
65
|
+
logger.debug("No record of this challenge");
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (!util$1.verifyRecency(challenge, timeout)) {
|
|
69
|
+
await this.db.updatePowCaptchaRecord(
|
|
70
|
+
challenge,
|
|
71
|
+
{
|
|
72
|
+
status: types.CaptchaStatus.disapproved,
|
|
73
|
+
reason: "CAPTCHA.INVALID_TIMESTAMP"
|
|
74
|
+
},
|
|
75
|
+
false,
|
|
76
|
+
true,
|
|
77
|
+
userTimestampSignature
|
|
78
|
+
);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
const correct = powTasksUtils.validateSolution(nonce, challenge, difficulty);
|
|
82
|
+
let result = { status: types.CaptchaStatus.approved };
|
|
83
|
+
if (!correct) {
|
|
84
|
+
result = {
|
|
85
|
+
status: types.CaptchaStatus.disapproved,
|
|
86
|
+
reason: "CAPTCHA.INVALID_SOLUTION"
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
await this.db.updatePowCaptchaRecord(
|
|
90
|
+
challenge,
|
|
91
|
+
result,
|
|
92
|
+
false,
|
|
93
|
+
true,
|
|
94
|
+
userTimestampSignature
|
|
95
|
+
);
|
|
96
|
+
return correct;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* @description Verifies a PoW Captcha for a given user and dapp. This is called by the server to verify the user's solution
|
|
100
|
+
* and update the record in the database to show that the user has solved the captcha
|
|
101
|
+
*
|
|
102
|
+
* @param {string} dappAccount - the dapp that is requesting the captcha
|
|
103
|
+
* @param {string} challenge - the starting string for the PoW challenge
|
|
104
|
+
* @param {number} timeout - the time in milliseconds since the Provider was selected to provide the PoW captcha
|
|
105
|
+
*/
|
|
106
|
+
async serverVerifyPowCaptchaSolution(dappAccount, challenge, timeout) {
|
|
107
|
+
const challengeRecord = await this.db.getPowCaptchaRecordByChallenge(challenge);
|
|
108
|
+
if (!challengeRecord) {
|
|
109
|
+
throw new common.ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
110
|
+
context: {
|
|
111
|
+
failedFuncName: this.serverVerifyPowCaptchaSolution.name,
|
|
112
|
+
challenge
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (challengeRecord.serverChecked) return false;
|
|
117
|
+
const challengeDappAccount = challengeRecord.dappAccount;
|
|
118
|
+
if (dappAccount !== challengeDappAccount) {
|
|
119
|
+
throw new common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", {
|
|
120
|
+
context: {
|
|
121
|
+
failedFuncName: this.serverVerifyPowCaptchaSolution.name,
|
|
122
|
+
dappAccount,
|
|
123
|
+
challengeDappAccount
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
util$1.verifyRecency(challenge, timeout);
|
|
128
|
+
await this.db.markDappUserPoWCommitmentsChecked([
|
|
129
|
+
challengeRecord.challenge
|
|
130
|
+
]);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.PowCaptchaManager = PowCaptchaManager;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const sha256 = require("@noble/hashes/sha256");
|
|
4
|
+
const util = require("@polkadot/util");
|
|
5
|
+
const utilCrypto = require("@polkadot/util-crypto");
|
|
6
|
+
const common = require("@prosopo/common");
|
|
7
|
+
const validateSolution = (nonce, challenge, difficulty) => Array.from(sha256.sha256(new TextEncoder().encode(nonce + challenge))).map((byte) => byte.toString(16).padStart(2, "0")).join("").startsWith("0".repeat(difficulty));
|
|
8
|
+
const checkPowSignature = (challenge, signature, address, signatureType) => {
|
|
9
|
+
const signatureVerification = utilCrypto.signatureVerify(
|
|
10
|
+
util.stringToHex(challenge),
|
|
11
|
+
signature,
|
|
12
|
+
address
|
|
13
|
+
);
|
|
14
|
+
if (!signatureVerification.isValid) {
|
|
15
|
+
throw new common.ProsopoContractError("GENERAL.INVALID_SIGNATURE", {
|
|
16
|
+
context: {
|
|
17
|
+
ERROR: `Signature is invalid for this message: ${signatureType}`,
|
|
18
|
+
failedFuncName: checkPowSignature.name,
|
|
19
|
+
signature,
|
|
20
|
+
signatureType
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
exports.checkPowSignature = checkPowSignature;
|
|
26
|
+
exports.validateSolution = validateSolution;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@prosopo/common");
|
|
4
|
+
const clientTasks = require("./client/clientTasks.cjs");
|
|
5
|
+
const datasetTasks = require("./dataset/datasetTasks.cjs");
|
|
6
|
+
const imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
|
|
7
|
+
const powTasks = require("./powCaptcha/powTasks.cjs");
|
|
8
|
+
class Tasks {
|
|
9
|
+
constructor(env) {
|
|
10
|
+
this.config = env.config;
|
|
11
|
+
this.db = env.getDb();
|
|
12
|
+
this.captchaConfig = env.config.captchas;
|
|
13
|
+
this.logger = common.getLogger(env.config.logLevel, "Tasks");
|
|
14
|
+
if (!env.pair) {
|
|
15
|
+
throw new common.ProsopoEnvError("DEVELOPER.MISSING_PROVIDER_PAIR", {
|
|
16
|
+
context: { failedFuncName: "Tasks.constructor" }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
this.pair = env.pair;
|
|
20
|
+
this.powCaptchaManager = new powTasks.PowCaptchaManager(this.pair, this.db);
|
|
21
|
+
this.datasetManager = new datasetTasks.DatasetManager(
|
|
22
|
+
this.config,
|
|
23
|
+
this.logger,
|
|
24
|
+
this.captchaConfig,
|
|
25
|
+
this.db
|
|
26
|
+
);
|
|
27
|
+
this.imgCaptchaManager = new imgCaptchaTasks.ImgCaptchaManager(
|
|
28
|
+
this.db,
|
|
29
|
+
this.pair,
|
|
30
|
+
this.logger,
|
|
31
|
+
this.captchaConfig
|
|
32
|
+
);
|
|
33
|
+
this.clientTaskManager = new clientTasks.ClientTaskManager(
|
|
34
|
+
this.config,
|
|
35
|
+
this.logger,
|
|
36
|
+
this.db
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.Tasks = Tasks;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const address = require("@polkadot/util-crypto/address");
|
|
4
|
+
const hex = require("@polkadot/util/hex");
|
|
5
|
+
const is = require("@polkadot/util/is");
|
|
6
|
+
const common = require("@prosopo/common");
|
|
7
|
+
const types = require("@prosopo/types");
|
|
8
|
+
const util = require("@prosopo/util");
|
|
9
|
+
function encodeStringAddress(address$1) {
|
|
10
|
+
try {
|
|
11
|
+
return address.encodeAddress(
|
|
12
|
+
is.isHex(address$1) ? hex.hexToU8a(address$1) : address.decodeAddress(address$1)
|
|
13
|
+
);
|
|
14
|
+
} catch (err) {
|
|
15
|
+
throw new common.ProsopoContractError("CONTRACT.INVALID_ADDRESS", {
|
|
16
|
+
context: { address: address$1 }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function shuffleArray(array) {
|
|
21
|
+
for (let arrayIndex = array.length - 1; arrayIndex > 0; arrayIndex--) {
|
|
22
|
+
const randIndex = Math.floor(Math.random() * (arrayIndex + 1));
|
|
23
|
+
const tmp = util.at(array, randIndex);
|
|
24
|
+
array[randIndex] = util.at(array, arrayIndex);
|
|
25
|
+
array[arrayIndex] = tmp;
|
|
26
|
+
}
|
|
27
|
+
return array;
|
|
28
|
+
}
|
|
29
|
+
async function checkIfTaskIsRunning(taskName, db) {
|
|
30
|
+
const runningTask = await db.getLastScheduledTaskStatus(
|
|
31
|
+
taskName,
|
|
32
|
+
types.ScheduledTaskStatus.Running
|
|
33
|
+
);
|
|
34
|
+
if (runningTask) {
|
|
35
|
+
const completedTask = await db.getScheduledTaskStatus(
|
|
36
|
+
runningTask.id,
|
|
37
|
+
types.ScheduledTaskStatus.Completed
|
|
38
|
+
);
|
|
39
|
+
return !completedTask;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
exports.checkIfTaskIsRunning = checkIfTaskIsRunning;
|
|
44
|
+
exports.encodeStringAddress = encodeStringAddress;
|
|
45
|
+
exports.shuffleArray = shuffleArray;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./tasks/index.js";
|
|
2
|
+
export * from "./util.js";
|
|
3
|
+
export * from "./api/captcha.js";
|
|
4
|
+
export * from "./api/verify.js";
|
|
5
|
+
export * from "./api/admin.js";
|
|
6
|
+
export * from "./api/errorHandler.js";
|
|
7
|
+
export * from "./api/authMiddleware.js";
|
|
8
|
+
export * from "./schedulers/captchaScheduler.js";
|
|
9
|
+
export * from "./schedulers/getClientList.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./tasks/index.js";
|
|
2
|
+
export * from "./util.js";
|
|
3
|
+
export * from "./api/captcha.js";
|
|
4
|
+
export * from "./api/verify.js";
|
|
5
|
+
export * from "./api/admin.js";
|
|
6
|
+
export * from "./api/errorHandler.js";
|
|
7
|
+
export * from "./api/authMiddleware.js";
|
|
8
|
+
export * from "./schedulers/captchaScheduler.js";
|
|
9
|
+
export * from "./schedulers/getClientList.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAKpD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,iBAgBxF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BatchCommitmentsTask } from './batch/commitments.js';
|
|
2
|
+
import { CronJob } from 'cron';
|
|
3
|
+
import { ProsopoEnvError } from '@prosopo/common';
|
|
4
|
+
import { ProviderEnvironment } from '@prosopo/env';
|
|
5
|
+
import { at } from '@prosopo/util';
|
|
6
|
+
export async function batchCommitScheduler(pair, config) {
|
|
7
|
+
const env = new ProviderEnvironment(config, pair);
|
|
8
|
+
await env.isReady();
|
|
9
|
+
if (env.db === undefined) {
|
|
10
|
+
throw new ProsopoEnvError('DATABASE.DATABASE_UNDEFINED');
|
|
11
|
+
}
|
|
12
|
+
const tasks = new BatchCommitmentsTask(config.batchCommit, env.getContractInterface(), env.db, 0n, env.logger);
|
|
13
|
+
const job = new CronJob(at(process.argv, 2), () => {
|
|
14
|
+
env.logger.debug('BatchCommitmentsTask....');
|
|
15
|
+
tasks.run().catch((err) => {
|
|
16
|
+
env.logger.error(err);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
job.start();
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAG9B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAElC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAiB,EAAE,MAA2B;IACrF,MAAM,GAAG,GAAG,IAAI,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACjD,MAAM,GAAG,CAAC,OAAO,EAAE,CAAA;IACnB,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,EAAE;QACtB,MAAM,IAAI,eAAe,CAAC,6BAA6B,CAAC,CAAA;KAC3D;IAED,MAAM,KAAK,GAAG,IAAI,oBAAoB,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,oBAAoB,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9G,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE;QAC9C,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QAC5C,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACtB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,KAAK,EAAE,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { KeyringPair } from "@polkadot/keyring/types";
|
|
2
|
+
import { type ProsopoConfigOutput } from "@prosopo/types";
|
|
3
|
+
export declare function storeCaptchasExternally(pair: KeyringPair, config: ProsopoConfigOutput): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=captchaScheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captchaScheduler.d.ts","sourceRoot":"","sources":["../../src/schedulers/captchaScheduler.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,KAAK,mBAAmB,EAAsB,MAAM,gBAAgB,CAAC;AAK9E,wBAAsB,uBAAuB,CAC5C,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,mBAAmB,iBAkC3B"}
|