@prosopo/provider 1.0.2 → 2.0.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/README.md +0 -258
- package/dist/api/admin.d.ts +2 -2
- package/dist/api/admin.d.ts.map +1 -1
- package/dist/api/admin.js +5 -64
- package/dist/api/admin.js.map +1 -1
- package/dist/api/authMiddleware.d.ts +4 -4
- package/dist/api/authMiddleware.d.ts.map +1 -1
- package/dist/api/authMiddleware.js +15 -29
- package/dist/api/authMiddleware.js.map +1 -1
- package/dist/api/captcha.d.ts +2 -2
- package/dist/api/captcha.d.ts.map +1 -1
- package/dist/api/captcha.js +64 -55
- package/dist/api/captcha.js.map +1 -1
- package/dist/api/captchaScheduler.d.ts +2 -2
- package/dist/api/captchaScheduler.d.ts.map +1 -1
- package/dist/api/captchaScheduler.js +11 -10
- package/dist/api/captchaScheduler.js.map +1 -1
- package/dist/api/errorHandler.d.ts +3 -3
- package/dist/api/errorHandler.d.ts.map +1 -1
- package/dist/api/errorHandler.js +7 -3
- package/dist/api/errorHandler.js.map +1 -1
- package/dist/api/verify.d.ts +2 -2
- package/dist/api/verify.d.ts.map +1 -1
- package/dist/api/verify.js +37 -29
- package/dist/api/verify.js.map +1 -1
- package/dist/cjs/api/admin.cjs +2 -89
- package/dist/cjs/api/authMiddleware.cjs +1 -15
- package/dist/cjs/api/captcha.cjs +89 -52
- package/dist/cjs/api/captchaScheduler.cjs +4 -7
- package/dist/cjs/api/errorHandler.cjs +3 -1
- package/dist/cjs/api/verify.cjs +54 -28
- package/dist/cjs/index.cjs +0 -3
- package/dist/cjs/tasks/dataset/datasetTasks.cjs +68 -0
- package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +34 -0
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +277 -0
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +25 -0
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +107 -0
- package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +55 -0
- package/dist/cjs/tasks/tasks.cjs +21 -524
- package/dist/cjs/util.cjs +32 -19
- package/dist/index.d.ts +7 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -8
- package/dist/index.js.map +1 -1
- package/dist/tasks/dataset/datasetTasks.d.ts +15 -0
- package/dist/tasks/dataset/datasetTasks.d.ts.map +1 -0
- package/dist/tasks/dataset/datasetTasks.js +40 -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/imgCaptcha/imgCaptchaTasks.d.ts +28 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +212 -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 +1 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/tasks/index.js.map +1 -1
- 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 +66 -0
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts +5 -0
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +1 -0
- package/dist/tasks/powCaptcha/powTasksUtils.js +49 -0
- package/dist/tasks/powCaptcha/powTasksUtils.js.map +1 -0
- package/dist/tasks/tasks.d.ts +12 -43
- package/dist/tasks/tasks.d.ts.map +1 -1
- package/dist/tasks/tasks.js +13 -431
- package/dist/tasks/tasks.js.map +1 -1
- 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.test.d.ts +2 -0
- package/dist/tests/integration/imgCaptcha.test.d.ts.map +1 -0
- package/dist/tests/integration/imgCaptcha.test.js +111 -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 +1042 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.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 +171 -0
- package/dist/tests/integration/powCaptcha.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/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/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 +88 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.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/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 +260 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.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 +46 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.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 +133 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.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/util.d.ts +2 -2
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +10 -8
- package/dist/util.js.map +1 -1
- package/package.json +74 -86
- package/vite.cjs.config.ts +3 -3
- package/vite.test.config.ts +12 -12
- package/dist/batch/commitments.d.ts +0 -24
- package/dist/batch/commitments.d.ts.map +0 -1
- package/dist/batch/commitments.js +0 -130
- package/dist/batch/commitments.js.map +0 -1
- package/dist/batch/index.d.ts +0 -2
- package/dist/batch/index.d.ts.map +0 -1
- package/dist/batch/index.js +0 -2
- package/dist/batch/index.js.map +0 -1
- package/dist/cjs/batch/commitments.cjs +0 -158
- package/dist/cjs/batch/index.cjs +0 -4
- package/dist/scheduler.d.ts +0 -4
- package/dist/scheduler.d.ts.map +0 -1
- package/dist/scheduler.js +0 -21
- package/dist/scheduler.js.map +0 -1
- package/dist/tests/accounts.d.ts +0 -12
- package/dist/tests/accounts.d.ts.map +0 -1
- package/dist/tests/accounts.js +0 -35
- package/dist/tests/accounts.js.map +0 -1
- package/dist/tests/contract/helpers.test.d.ts +0 -6
- package/dist/tests/contract/helpers.test.d.ts.map +0 -1
- package/dist/tests/contract/helpers.test.js +0 -54
- package/dist/tests/contract/helpers.test.js.map +0 -1
- package/dist/tests/dataUtils/DatabaseAccounts.d.ts +0 -35
- package/dist/tests/dataUtils/DatabaseAccounts.d.ts.map +0 -1
- package/dist/tests/dataUtils/DatabaseAccounts.js +0 -84
- package/dist/tests/dataUtils/DatabaseAccounts.js.map +0 -1
- package/dist/tests/dataUtils/DatabasePopulator.d.ts +0 -73
- package/dist/tests/dataUtils/DatabasePopulator.d.ts.map +0 -1
- package/dist/tests/dataUtils/DatabasePopulator.js +0 -326
- package/dist/tests/dataUtils/DatabasePopulator.js.map +0 -1
- package/dist/tests/dataUtils/dapp-example-contract/dapp.json +0 -648
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.d.ts +0 -4
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.d.ts.map +0 -1
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.js +0 -27
- package/dist/tests/dataUtils/dapp-example-contract/loadFiles.js.map +0 -1
- package/dist/tests/dataUtils/funds.d.ts +0 -9
- package/dist/tests/dataUtils/funds.d.ts.map +0 -1
- package/dist/tests/dataUtils/funds.js +0 -105
- package/dist/tests/dataUtils/funds.js.map +0 -1
- package/dist/tests/dataUtils/populateDatabase.d.ts +0 -16
- package/dist/tests/dataUtils/populateDatabase.d.ts.map +0 -1
- package/dist/tests/dataUtils/populateDatabase.js +0 -72
- package/dist/tests/dataUtils/populateDatabase.js.map +0 -1
- package/dist/tests/getUser.d.ts +0 -4
- package/dist/tests/getUser.d.ts.map +0 -1
- package/dist/tests/getUser.js +0 -18
- package/dist/tests/getUser.js.map +0 -1
- package/dist/tests/tasks/tasks.test.d.ts +0 -6
- package/dist/tests/tasks/tasks.test.d.ts.map +0 -1
- package/dist/tests/tasks/tasks.test.js +0 -636
- package/dist/tests/tasks/tasks.test.js.map +0 -1
- package/dist/tests/util.test.d.ts +0 -2
- package/dist/tests/util.test.d.ts.map +0 -1
- package/dist/tests/util.test.js +0 -23
- package/dist/tests/util.test.js.map +0 -1
package/dist/cjs/tasks/tasks.cjs
CHANGED
|
@@ -1,537 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const types = require("@prosopo/types");
|
|
4
|
-
const datasets = require("@prosopo/datasets");
|
|
5
|
-
const typesReturns = require("@prosopo/captcha-contract/types-returns");
|
|
6
3
|
const common = require("@prosopo/common");
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const random = require("@polkadot/util-crypto/random");
|
|
11
|
-
const database = require("@prosopo/database");
|
|
12
|
-
const sha256 = require("@noble/hashes/sha256");
|
|
13
|
-
const util = require("../util.cjs");
|
|
14
|
-
const signature = require("@polkadot/util-crypto/signature");
|
|
15
|
-
const string = require("@polkadot/util/string");
|
|
16
|
-
const util$1 = require("@polkadot/util");
|
|
17
|
-
const POW_SEPARATOR = "___";
|
|
4
|
+
const datasetTasks = require("./dataset/datasetTasks.cjs");
|
|
5
|
+
const imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
|
|
6
|
+
const powTasks = require("./powCaptcha/powTasks.cjs");
|
|
18
7
|
class Tasks {
|
|
19
8
|
constructor(env) {
|
|
20
|
-
if (!env.contractInterface) {
|
|
21
|
-
throw new common.ProsopoEnvError("CONTRACT.CONTRACT_UNDEFINED", {
|
|
22
|
-
context: { failedFuncName: this.constructor.name, contractAddress: env.contractAddress }
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
9
|
this.config = env.config;
|
|
26
|
-
this.
|
|
27
|
-
this.db = env.db;
|
|
10
|
+
this.db = env.getDb();
|
|
28
11
|
this.captchaConfig = env.config.captchas;
|
|
29
|
-
this.captchaSolutionConfig = env.config.captchaSolutions;
|
|
30
12
|
this.logger = common.getLogger(env.config.logLevel, "Tasks");
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const solutions = datasetRaw.captchas.map((captcha) => captcha.solution ? 1 : 0).reduce((partialSum, b) => partialSum + b, 0);
|
|
44
|
-
if (solutions < this.config.captchas.solved.count) {
|
|
45
|
-
throw new common.ProsopoEnvError("DATASET.SOLUTIONS_COUNT_LESS_THAN_CONFIGURED", {
|
|
46
|
-
context: { failedFuncName: this.providerSetDataset.name }
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
if (solutions < this.config.captchas.unsolved.count) {
|
|
50
|
-
throw new common.ProsopoEnvError("DATASET.SOLUTIONS_COUNT_LESS_THAN_CONFIGURED", {
|
|
51
|
-
context: { failedFuncName: this.providerSetDataset.name }
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
const dataset = await datasets.buildDataset(datasetRaw);
|
|
55
|
-
if (!dataset.datasetId || !dataset.datasetContentId) {
|
|
56
|
-
throw new common.ProsopoEnvError("DATASET.DATASET_ID_UNDEFINED", {
|
|
57
|
-
context: { failedFuncName: this.providerSetDataset.name }
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
await this.db?.storeDataset(dataset);
|
|
61
|
-
await contract.wrapQuery(this.contract.query.providerSetDataset, this.contract.query)(
|
|
62
|
-
dataset.datasetId,
|
|
63
|
-
dataset.datasetContentId
|
|
64
|
-
);
|
|
65
|
-
const txResult = await this.contract.methods.providerSetDataset(dataset.datasetId, dataset.datasetContentId, {
|
|
66
|
-
value: 0
|
|
67
|
-
});
|
|
68
|
-
return txResult.result;
|
|
69
|
-
}
|
|
70
|
-
// Other tasks
|
|
71
|
-
/**
|
|
72
|
-
* @description Get random captchas that are solved or not solved, along with the merkle proof for each
|
|
73
|
-
* @param {string} datasetId the id of the data set
|
|
74
|
-
* @param {boolean} solved `true` when captcha is solved
|
|
75
|
-
* @param {number} size the number of records to be returned
|
|
76
|
-
*/
|
|
77
|
-
async getCaptchaWithProof(datasetId, solved, size) {
|
|
78
|
-
const captchaDocs = await this.db.getRandomCaptcha(solved, datasetId, size);
|
|
79
|
-
if (captchaDocs) {
|
|
80
|
-
const captchas = [];
|
|
81
|
-
for (const captcha of captchaDocs) {
|
|
82
|
-
const datasetDetails = await this.db.getDatasetDetails(datasetId);
|
|
83
|
-
const tree = new datasets.CaptchaMerkleTree();
|
|
84
|
-
if (datasetDetails.contentTree) {
|
|
85
|
-
tree.layers = datasetDetails.contentTree;
|
|
86
|
-
const proof = tree.proof(captcha.captchaContentId);
|
|
87
|
-
delete captcha.solution;
|
|
88
|
-
captcha.items = util.shuffleArray(captcha.items);
|
|
89
|
-
captchas.push({ captcha, proof });
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return captchas;
|
|
93
|
-
}
|
|
94
|
-
throw new common.ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
95
|
-
context: { failedFuncName: this.getCaptchaWithProof.name, datasetId, solved, size }
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* @description Generates a PoW Captcha for a given user and dapp
|
|
100
|
-
*
|
|
101
|
-
* @param {string} userAccount - user that is solving the captcha
|
|
102
|
-
* @param {string} dappAccount - dapp that is requesting the captcha
|
|
103
|
-
*/
|
|
104
|
-
async getPowCaptchaChallenge(userAccount, dappAccount, origin) {
|
|
105
|
-
const difficulty = 4;
|
|
106
|
-
const latestHeader = await this.contract.api.rpc.chain.getHeader();
|
|
107
|
-
const latestBlockNumber = latestHeader.number.toNumber();
|
|
108
|
-
const challenge = `${latestBlockNumber}___${userAccount}___${dappAccount}`;
|
|
109
|
-
const signature2 = util$1.u8aToHex(this.contract.pair.sign(string.stringToHex(challenge)));
|
|
110
|
-
return { challenge, difficulty, signature: signature2 };
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* @description Verifies a PoW Captcha for a given user and dapp
|
|
114
|
-
*
|
|
115
|
-
* @param {string} blockNumber - the block at which the Provider was selected
|
|
116
|
-
* @param {string} challenge - the starting string for the PoW challenge
|
|
117
|
-
* @param {string} difficulty - how many leading zeroes the solution must have
|
|
118
|
-
* @param {string} signature - proof that the Provider provided the challenge
|
|
119
|
-
* @param {string} nonce - the string that the user has found that satisfies the PoW challenge
|
|
120
|
-
* @param {number} timeout - the time in milliseconds since the Provider was selected to provide the PoW captcha
|
|
121
|
-
*/
|
|
122
|
-
async verifyPowCaptchaSolution(blockNumber, challenge, difficulty, signature$1, nonce, timeout) {
|
|
123
|
-
const recent = contract.verifyRecency(this.contract.api, blockNumber, timeout);
|
|
124
|
-
if (!recent) {
|
|
125
|
-
throw new common.ProsopoContractError("CONTRACT.INVALID_BLOCKHASH", {
|
|
126
|
-
context: {
|
|
127
|
-
ERROR: `Block in which the Provider was selected must be within the last ${timeout / 1e3} seconds`,
|
|
128
|
-
failedFuncName: this.verifyPowCaptchaSolution.name,
|
|
129
|
-
blockNumber
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
const signatureVerification = signature.signatureVerify(string.stringToHex(challenge), signature$1, this.contract.pair.address);
|
|
134
|
-
if (!signatureVerification.isValid) {
|
|
135
|
-
throw new common.ProsopoContractError("GENERAL.INVALID_SIGNATURE", {
|
|
136
|
-
context: {
|
|
137
|
-
ERROR: "Provider signature is invalid for this message",
|
|
138
|
-
failedFuncName: this.verifyPowCaptchaSolution.name,
|
|
139
|
-
signature: signature$1
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
const solutionValid = Array.from(sha256.sha256(new TextEncoder().encode(nonce + challenge))).map((byte) => byte.toString(16).padStart(2, "0")).join("").startsWith("0".repeat(difficulty));
|
|
144
|
-
if (!solutionValid) {
|
|
145
|
-
throw new common.ProsopoContractError("API.CAPTCHA_FAILED", {
|
|
146
|
-
context: {
|
|
147
|
-
ERROR: "Captcha solution is invalid",
|
|
148
|
-
failedFuncName: this.verifyPowCaptchaSolution.name,
|
|
149
|
-
nonce,
|
|
150
|
-
challenge,
|
|
151
|
-
difficulty
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
await this.db.storePowCaptchaRecord(challenge, false);
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
async serverVerifyPowCaptchaSolution(dappAccount, challenge, timeout) {
|
|
159
|
-
const challengeRecord = await this.db.getPowCaptchaRecordByChallenge(challenge);
|
|
160
|
-
if (!challengeRecord) {
|
|
161
|
-
throw new common.ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
162
|
-
context: { failedFuncName: this.serverVerifyPowCaptchaSolution.name, challenge }
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
if (challengeRecord.checked) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
const [blocknumber, userAccount, challengeDappAccount] = challengeRecord.challenge.split(POW_SEPARATOR);
|
|
169
|
-
if (dappAccount !== challengeDappAccount) {
|
|
170
|
-
throw new common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", {
|
|
171
|
-
context: {
|
|
172
|
-
failedFuncName: this.serverVerifyPowCaptchaSolution.name,
|
|
173
|
-
dappAccount,
|
|
174
|
-
challengeDappAccount
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
if (!blocknumber) {
|
|
179
|
-
throw new common.ProsopoContractError("CONTRACT.INVALID_BLOCKHASH", {
|
|
180
|
-
context: {
|
|
181
|
-
ERROR: "Block number not provided",
|
|
182
|
-
failedFuncName: this.verifyPowCaptchaSolution.name,
|
|
183
|
-
blocknumber
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
const recent = contract.verifyRecency(this.contract.api, parseInt(blocknumber), timeout);
|
|
188
|
-
if (!recent) {
|
|
189
|
-
throw new common.ProsopoContractError("CONTRACT.INVALID_BLOCKHASH", {
|
|
190
|
-
context: {
|
|
191
|
-
ERROR: `Block in which the Provider was selected must be within the last ${timeout / 1e3} seconds`,
|
|
192
|
-
failedFuncName: this.verifyPowCaptchaSolution.name,
|
|
193
|
-
blocknumber
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
await this.db.updatePowCaptchaRecord(challengeRecord.challenge, true);
|
|
198
|
-
return true;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Validate and store the text captcha solution(s) from the Dapp User in a web2 environment
|
|
202
|
-
* @param {string} userAccount
|
|
203
|
-
* @param {string} dappAccount
|
|
204
|
-
* @param {string} requestHash
|
|
205
|
-
* @param {JSON} captchas
|
|
206
|
-
* @param {string} signature
|
|
207
|
-
* @return {Promise<DappUserSolutionResult>} result containing the contract event
|
|
208
|
-
*/
|
|
209
|
-
async dappUserSolution(userAccount, dappAccount, requestHash, captchas, signature$1) {
|
|
210
|
-
if (!await this.dappIsActive(dappAccount)) {
|
|
211
|
-
throw new common.ProsopoEnvError("CONTRACT.DAPP_NOT_ACTIVE", {
|
|
212
|
-
context: { failedFuncName: this.getPaymentInfo.name, dappAccount }
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
const verification = signature.signatureVerify(string.stringToHex(requestHash), signature$1, userAccount);
|
|
216
|
-
if (!verification.isValid) {
|
|
217
|
-
throw new common.ProsopoEnvError("GENERAL.INVALID_SIGNATURE", {
|
|
218
|
-
context: { failedFuncName: this.dappUserSolution.name, userAccount }
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
let response = {
|
|
222
|
-
captchas: [],
|
|
223
|
-
verified: false
|
|
224
|
-
};
|
|
225
|
-
const { storedCaptchas, receivedCaptchas, captchaIds } = await this.validateReceivedCaptchasAgainstStoredCaptchas(captchas);
|
|
226
|
-
const { tree, commitmentId } = await this.buildTreeAndGetCommitmentId(receivedCaptchas);
|
|
227
|
-
const provider = (await this.contract.methods.getProvider(this.contract.pair.address, {})).value.unwrap().unwrap();
|
|
228
|
-
const pendingRecord = await this.db.getDappUserPending(requestHash);
|
|
229
|
-
const pendingRequest = await this.validateDappUserSolutionRequestIsPending(
|
|
230
|
-
requestHash,
|
|
231
|
-
pendingRecord,
|
|
232
|
-
userAccount,
|
|
233
|
-
captchaIds
|
|
234
|
-
);
|
|
235
|
-
const userSignature = hex.hexToU8a(signature$1);
|
|
236
|
-
const blockNumber = await contract.getCurrentBlockNumber(this.contract.api);
|
|
237
|
-
if (pendingRequest) {
|
|
238
|
-
await this.db.updateDappUserPendingStatus(requestHash);
|
|
239
|
-
const commit = {
|
|
240
|
-
id: commitmentId,
|
|
241
|
-
userAccount,
|
|
242
|
-
dappContract: dappAccount,
|
|
243
|
-
providerAccount: this.contract.pair.address,
|
|
244
|
-
datasetId: provider.datasetId.toString(),
|
|
245
|
-
status: typesReturns.CaptchaStatus.pending,
|
|
246
|
-
userSignature: Array.from(userSignature),
|
|
247
|
-
requestedAt: pendingRecord.requestedAtBlock,
|
|
248
|
-
// TODO is this correct or should it be block number?
|
|
249
|
-
completedAt: blockNumber,
|
|
250
|
-
processed: false,
|
|
251
|
-
batched: false,
|
|
252
|
-
stored: false
|
|
253
|
-
};
|
|
254
|
-
await this.db.storeDappUserSolution(receivedCaptchas, commit);
|
|
255
|
-
if (datasets.compareCaptchaSolutions(receivedCaptchas, storedCaptchas)) {
|
|
256
|
-
response = {
|
|
257
|
-
captchas: captchaIds.map((id) => ({
|
|
258
|
-
captchaId: id,
|
|
259
|
-
proof: tree.proof(id)
|
|
260
|
-
})),
|
|
261
|
-
verified: true
|
|
262
|
-
};
|
|
263
|
-
await this.db.approveDappUserCommitment(commitmentId);
|
|
264
|
-
} else {
|
|
265
|
-
response = {
|
|
266
|
-
captchas: captchaIds.map((id) => ({
|
|
267
|
-
captchaId: id,
|
|
268
|
-
proof: [[]]
|
|
269
|
-
})),
|
|
270
|
-
verified: false
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
return response;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Validate that the dapp is active in the contract
|
|
278
|
-
*/
|
|
279
|
-
async dappIsActive(dappAccount) {
|
|
280
|
-
const dapp = await contract.wrapQuery(this.contract.query.getDapp, this.contract.query)(dappAccount);
|
|
281
|
-
return dapp.status.toString() === "Active";
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Gets provider status in contract
|
|
285
|
-
*/
|
|
286
|
-
async providerStatus() {
|
|
287
|
-
try {
|
|
288
|
-
const provider = await contract.wrapQuery(
|
|
289
|
-
this.contract.query.getProvider,
|
|
290
|
-
this.contract.query
|
|
291
|
-
)(this.contract.pair.address);
|
|
292
|
-
return { status: provider.status ? "Registered" : "Unregistered" };
|
|
293
|
-
} catch (e) {
|
|
294
|
-
return { status: "Unregistered" };
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* Validate length of received captchas array matches length of captchas found in database
|
|
299
|
-
* Validate that the datasetId is the same for all captchas and is equal to the datasetId on the stored captchas
|
|
300
|
-
*/
|
|
301
|
-
async validateReceivedCaptchasAgainstStoredCaptchas(captchas) {
|
|
302
|
-
const receivedCaptchas = datasets.parseAndSortCaptchaSolutions(captchas);
|
|
303
|
-
const captchaIds = receivedCaptchas.map((captcha) => captcha.captchaId);
|
|
304
|
-
const storedCaptchas = await this.db.getCaptchaById(captchaIds);
|
|
305
|
-
if (!storedCaptchas || receivedCaptchas.length !== storedCaptchas.length) {
|
|
306
|
-
throw new common.ProsopoEnvError("CAPTCHA.INVALID_CAPTCHA_ID", {
|
|
307
|
-
context: {
|
|
308
|
-
failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
|
|
309
|
-
captchas
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
if (!storedCaptchas.every((captcha) => captcha.datasetId === util$2.at(storedCaptchas, 0).datasetId)) {
|
|
314
|
-
throw new common.ProsopoEnvError("CAPTCHA.DIFFERENT_DATASET_IDS", {
|
|
315
|
-
context: {
|
|
316
|
-
failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
|
|
317
|
-
captchas
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
return { storedCaptchas, receivedCaptchas, captchaIds };
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Build merkle tree and get commitment from contract, returning the tree, commitment, and commitmentId
|
|
325
|
-
* @param {CaptchaSolution[]} captchaSolutions
|
|
326
|
-
* @returns {Promise<{ tree: CaptchaMerkleTree, commitment: CaptchaSolutionCommitment, commitmentId: string }>}
|
|
327
|
-
*/
|
|
328
|
-
async buildTreeAndGetCommitmentId(captchaSolutions) {
|
|
329
|
-
const tree = new datasets.CaptchaMerkleTree();
|
|
330
|
-
const solutionsHashed = captchaSolutions.map((captcha) => datasets.computeCaptchaSolutionHash(captcha));
|
|
331
|
-
tree.build(solutionsHashed);
|
|
332
|
-
const commitmentId = tree.root?.hash;
|
|
333
|
-
if (!commitmentId) {
|
|
334
|
-
throw new common.ProsopoEnvError("CONTRACT.CAPTCHA_SOLUTION_COMMITMENT_DOES_NOT_EXIST", {
|
|
335
|
-
context: {
|
|
336
|
-
failedFuncName: this.buildTreeAndGetCommitmentId.name,
|
|
337
|
-
commitmentId
|
|
338
|
-
}
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
return { tree, commitmentId };
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Validate that a Dapp User is responding to their own pending captcha request
|
|
345
|
-
* @param {string} requestHash
|
|
346
|
-
* @param {PendingCaptchaRequest} pendingRecord
|
|
347
|
-
* @param {string} userAccount
|
|
348
|
-
* @param {string[]} captchaIds
|
|
349
|
-
*/
|
|
350
|
-
async validateDappUserSolutionRequestIsPending(requestHash, pendingRecord, userAccount, captchaIds) {
|
|
351
|
-
const currentTime = Date.now();
|
|
352
|
-
if (pendingRecord.deadlineTimestamp < currentTime) {
|
|
353
|
-
this.logger.info("Deadline for responding to captcha has expired");
|
|
354
|
-
return false;
|
|
355
|
-
}
|
|
356
|
-
if (pendingRecord) {
|
|
357
|
-
const pendingHashComputed = datasets.computePendingRequestHash(captchaIds, userAccount, pendingRecord.salt);
|
|
358
|
-
return requestHash === pendingHashComputed;
|
|
359
|
-
}
|
|
360
|
-
return false;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Get two random captchas from specified dataset, create the response and store a hash of it, marked as pending
|
|
364
|
-
* @param {string} datasetId
|
|
365
|
-
* @param {string} userAccount
|
|
366
|
-
*/
|
|
367
|
-
async getRandomCaptchasAndRequestHash(datasetId, userAccount) {
|
|
368
|
-
const dataset = await this.db.getDatasetDetails(datasetId);
|
|
369
|
-
if (!dataset) {
|
|
370
|
-
throw new common.ProsopoEnvError("DATABASE.DATASET_GET_FAILED");
|
|
371
|
-
}
|
|
372
|
-
const unsolvedCount = Math.abs(Math.trunc(this.captchaConfig.unsolved.count));
|
|
373
|
-
const solvedCount = Math.abs(Math.trunc(this.captchaConfig.solved.count));
|
|
374
|
-
if (!solvedCount) {
|
|
375
|
-
throw new common.ProsopoEnvError("CONFIG.INVALID_CAPTCHA_NUMBER");
|
|
376
|
-
}
|
|
377
|
-
const solved = await this.getCaptchaWithProof(datasetId, true, solvedCount);
|
|
378
|
-
let unsolved = [];
|
|
379
|
-
if (unsolvedCount) {
|
|
380
|
-
unsolved = await this.getCaptchaWithProof(datasetId, false, unsolvedCount);
|
|
381
|
-
}
|
|
382
|
-
const captchas = util.shuffleArray([...solved, ...unsolved]);
|
|
383
|
-
const salt = random.randomAsHex();
|
|
384
|
-
const requestHash = datasets.computePendingRequestHash(
|
|
385
|
-
captchas.map((c) => c.captcha.captchaId),
|
|
386
|
-
userAccount,
|
|
387
|
-
salt
|
|
388
|
-
);
|
|
389
|
-
const currentTime = Date.now();
|
|
390
|
-
const timeLimit = captchas.map((captcha) => captcha.captcha.timeLimitMs || types.DEFAULT_IMAGE_CAPTCHA_TIMEOUT).reduce((a, b) => a + b, 0);
|
|
391
|
-
const deadlineTs = timeLimit + currentTime;
|
|
392
|
-
const currentBlockNumber = await contract.getCurrentBlockNumber(this.contract.api);
|
|
393
|
-
await this.db.storeDappUserPending(userAccount, requestHash, salt, deadlineTs, currentBlockNumber);
|
|
394
|
-
return { captchas, requestHash };
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Block by block search for blockNo
|
|
398
|
-
*/
|
|
399
|
-
async isRecentBlock(contract2, header, blockNo, depth = this.captchaSolutionConfig.captchaBlockRecency) {
|
|
400
|
-
if (depth == 0) {
|
|
401
|
-
return false;
|
|
402
|
-
}
|
|
403
|
-
const headerBlockNo = header.number.toPrimitive();
|
|
404
|
-
if (headerBlockNo === blockNo) {
|
|
405
|
-
return true;
|
|
406
|
-
}
|
|
407
|
-
const parent = await contract2.api.rpc.chain.getBlock(header.parentHash);
|
|
408
|
-
return this.isRecentBlock(contract2, parent.block.header, blockNo, depth - 1);
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Validate that provided `datasetId` was a result of calling `get_random_provider` method
|
|
412
|
-
* @param {string} userAccount - Same user that called `get_random_provider`
|
|
413
|
-
* @param {string} dappContractAccount - account of dapp that is requesting captcha
|
|
414
|
-
* @param {string} datasetId - `captcha_dataset_id` from the result of `get_random_provider`
|
|
415
|
-
* @param {string} blockNumber - Block on which `get_random_provider` was called
|
|
416
|
-
*/
|
|
417
|
-
async validateProviderWasRandomlyChosen(userAccount, dappContractAccount, datasetId, blockNumber) {
|
|
418
|
-
const contract2 = await this.contract.contract;
|
|
419
|
-
if (!contract2) {
|
|
420
|
-
throw new common.ProsopoEnvError("CONTRACT.CONTRACT_UNDEFINED", {
|
|
421
|
-
context: { failedFuncName: this.validateProviderWasRandomlyChosen.name }
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
const header = await contract2.api.rpc.chain.getHeader();
|
|
425
|
-
const isBlockNoValid = await this.isRecentBlock(contract2, header, blockNumber);
|
|
426
|
-
if (!isBlockNoValid) {
|
|
427
|
-
throw new common.ProsopoEnvError("CAPTCHA.INVALID_BLOCK_NO", {
|
|
428
|
-
context: {
|
|
429
|
-
failedFuncName: this.validateProviderWasRandomlyChosen.name,
|
|
430
|
-
userAccount,
|
|
431
|
-
dappContractAccount,
|
|
432
|
-
datasetId,
|
|
433
|
-
header,
|
|
434
|
-
blockNumber
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
const block = await contract2.api.rpc.chain.getBlockHash(blockNumber);
|
|
439
|
-
const randomProviderAndBlockNo = await this.contract.queryAtBlock(
|
|
440
|
-
block,
|
|
441
|
-
"getRandomActiveProvider",
|
|
442
|
-
[userAccount, dappContractAccount]
|
|
13
|
+
if (!env.pair) {
|
|
14
|
+
throw new common.ProsopoEnvError("DEVELOPER.MISSING_PROVIDER_PAIR", {
|
|
15
|
+
context: { failedFuncName: "Tasks.constructor" }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
this.pair = env.pair;
|
|
19
|
+
this.powCaptchaManager = new powTasks.PowCaptchaManager(this.pair, this.db);
|
|
20
|
+
this.datasetManager = new datasetTasks.DatasetManager(
|
|
21
|
+
this.config,
|
|
22
|
+
this.logger,
|
|
23
|
+
this.captchaConfig,
|
|
24
|
+
this.db
|
|
443
25
|
);
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
}
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* Get payment info for a transaction
|
|
455
|
-
* @param {string} userAccount
|
|
456
|
-
* @param {string} blockHash
|
|
457
|
-
* @param {string} txHash
|
|
458
|
-
* @returns {Promise<RuntimeDispatchInfo|null>}
|
|
459
|
-
*/
|
|
460
|
-
async getPaymentInfo(userAccount, blockHash, txHash) {
|
|
461
|
-
const signedBlock = await this.contract.api.rpc.chain.getBlock(blockHash);
|
|
462
|
-
if (!signedBlock) {
|
|
463
|
-
return null;
|
|
464
|
-
}
|
|
465
|
-
const extrinsic = signedBlock.block.extrinsics.find((extrinsic2) => extrinsic2.hash.toString() === txHash);
|
|
466
|
-
if (!extrinsic || extrinsic.signer.toString() !== userAccount) {
|
|
467
|
-
return null;
|
|
468
|
-
}
|
|
469
|
-
const paymentInfo = await this.contract.api.rpc.payment.queryInfo(
|
|
470
|
-
extrinsic.toHex(),
|
|
471
|
-
blockHash
|
|
26
|
+
this.imgCaptchaManager = new imgCaptchaTasks.ImgCaptchaManager(
|
|
27
|
+
this.db,
|
|
28
|
+
this.pair,
|
|
29
|
+
this.logger,
|
|
30
|
+
this.captchaConfig
|
|
472
31
|
);
|
|
473
|
-
if (!paymentInfo) {
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
return paymentInfo;
|
|
477
|
-
}
|
|
478
|
-
/*
|
|
479
|
-
* Get dapp user solution from database
|
|
480
|
-
*/
|
|
481
|
-
async getDappUserCommitmentById(commitmentId) {
|
|
482
|
-
const dappUserSolution = await this.db.getDappUserCommitmentById(commitmentId);
|
|
483
|
-
if (!dappUserSolution) {
|
|
484
|
-
throw new common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", {
|
|
485
|
-
context: {
|
|
486
|
-
failedFuncName: this.getDappUserCommitmentById.name,
|
|
487
|
-
commitmentId
|
|
488
|
-
}
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
return dappUserSolution;
|
|
492
|
-
}
|
|
493
|
-
/* Check if dapp user has verified solution in cache */
|
|
494
|
-
async getDappUserCommitmentByAccount(userAccount) {
|
|
495
|
-
const dappUserSolutions = await this.db.getDappUserCommitmentByAccount(userAccount);
|
|
496
|
-
if (dappUserSolutions.length > 0) {
|
|
497
|
-
for (const dappUserSolution of dappUserSolutions) {
|
|
498
|
-
if (dappUserSolution.status === typesReturns.CaptchaStatus.approved) {
|
|
499
|
-
return dappUserSolution;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
return void 0;
|
|
504
|
-
}
|
|
505
|
-
/* Returns public details of provider */
|
|
506
|
-
async getProviderDetails() {
|
|
507
|
-
const provider = await contract.wrapQuery(
|
|
508
|
-
this.contract.query.getProvider,
|
|
509
|
-
this.contract.query
|
|
510
|
-
)(this.contract.pair.address);
|
|
511
|
-
const dbConnectionOk = await this.getCaptchaWithProof(provider.datasetId, true, 1).then(() => true).catch(() => false);
|
|
512
|
-
return { provider, dbConnectionOk };
|
|
513
|
-
}
|
|
514
|
-
/** Get the dataset from the database */
|
|
515
|
-
async getProviderDataset(datasetId) {
|
|
516
|
-
return await this.db.getDataset(datasetId);
|
|
517
|
-
}
|
|
518
|
-
async saveCaptchaEvent(events, accountId) {
|
|
519
|
-
if (!this.config.devOnlyWatchEvents || !this.config.mongoEventsUri) {
|
|
520
|
-
this.logger.info("Dev watch events not set to true, not saving events");
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
await database.saveCaptchaEvent(events, accountId, this.config.mongoEventsUri);
|
|
524
|
-
}
|
|
525
|
-
async storeCommitmentsExternal() {
|
|
526
|
-
if (!this.config.mongoCaptchaUri) {
|
|
527
|
-
this.logger.info("Mongo env not set");
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
const commitments = await this.db.getUnstoredDappUserCommitments();
|
|
531
|
-
this.logger.info(`Storing ${commitments.length} commitments externally`);
|
|
532
|
-
await database.saveCaptchas(commitments, this.config.mongoCaptchaUri);
|
|
533
|
-
const commitIds = commitments.map((commitment) => commitment.id);
|
|
534
|
-
await this.db.markDappUserCommitmentsStored(commitIds);
|
|
535
32
|
}
|
|
536
33
|
}
|
|
537
34
|
exports.Tasks = Tasks;
|
package/dist/cjs/util.cjs
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const common = require("@prosopo/common");
|
|
4
|
-
const types = require("@prosopo/types");
|
|
5
|
-
const util = require("@prosopo/util");
|
|
6
3
|
const address = require("@polkadot/util-crypto/address");
|
|
7
4
|
const hex = require("@polkadot/util/hex");
|
|
8
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
9
|
function encodeStringAddress(address$1) {
|
|
10
10
|
try {
|
|
11
|
-
return address.encodeAddress(
|
|
11
|
+
return address.encodeAddress(
|
|
12
|
+
is.isHex(address$1) ? hex.hexToU8a(address$1) : address.decodeAddress(address$1)
|
|
13
|
+
);
|
|
12
14
|
} catch (err) {
|
|
13
|
-
throw new common.ProsopoContractError("CONTRACT.INVALID_ADDRESS", {
|
|
15
|
+
throw new common.ProsopoContractError("CONTRACT.INVALID_ADDRESS", {
|
|
16
|
+
context: { address: address$1 }
|
|
17
|
+
});
|
|
14
18
|
}
|
|
15
19
|
}
|
|
16
20
|
function shuffleArray(array) {
|
|
@@ -24,26 +28,35 @@ function shuffleArray(array) {
|
|
|
24
28
|
}
|
|
25
29
|
async function promiseQueue(array) {
|
|
26
30
|
const ret = [];
|
|
27
|
-
await [...array, () => Promise.resolve(void 0)].reduce(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
await [...array, () => Promise.resolve(void 0)].reduce(
|
|
32
|
+
(promise, curr, i) => {
|
|
33
|
+
return promise.then((res) => {
|
|
34
|
+
if (res) {
|
|
35
|
+
ret.push({ data: res });
|
|
36
|
+
}
|
|
37
|
+
return curr();
|
|
38
|
+
}).catch((err) => {
|
|
39
|
+
ret.push({ data: err });
|
|
40
|
+
return curr();
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
Promise.resolve(void 0)
|
|
44
|
+
);
|
|
38
45
|
return ret;
|
|
39
46
|
}
|
|
40
47
|
function parseBlockNumber(blockNumberString) {
|
|
41
|
-
return parseInt(blockNumberString.replace(/,/g, ""));
|
|
48
|
+
return Number.parseInt(blockNumberString.replace(/,/g, ""));
|
|
42
49
|
}
|
|
43
50
|
async function checkIfTaskIsRunning(taskName, db) {
|
|
44
|
-
const runningTask = await db.getLastScheduledTaskStatus(
|
|
51
|
+
const runningTask = await db.getLastScheduledTaskStatus(
|
|
52
|
+
taskName,
|
|
53
|
+
types.ScheduledTaskStatus.Running
|
|
54
|
+
);
|
|
45
55
|
if (runningTask) {
|
|
46
|
-
const completedTask = await db.getScheduledTaskStatus(
|
|
56
|
+
const completedTask = await db.getScheduledTaskStatus(
|
|
57
|
+
runningTask.taskId,
|
|
58
|
+
types.ScheduledTaskStatus.Completed
|
|
59
|
+
);
|
|
47
60
|
return !completedTask;
|
|
48
61
|
}
|
|
49
62
|
return false;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from './api/captchaScheduler.js';
|
|
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/captchaScheduler.js";
|
|
9
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kBAAkB,
|
|
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,2BAA2B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from './api/captchaScheduler.js';
|
|
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/captchaScheduler.js";
|
|
9
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kBAAkB,
|
|
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,2BAA2B,CAAC"}
|