@prosopo/provider 1.0.1 → 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 +4 -0
- package/dist/api/captchaScheduler.d.ts.map +1 -0
- package/dist/api/captchaScheduler.js +22 -0
- package/dist/api/captchaScheduler.js.map +1 -0
- 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 +20 -0
- package/dist/cjs/api/errorHandler.cjs +3 -1
- package/dist/cjs/api/verify.cjs +54 -28
- package/dist/cjs/index.cjs +2 -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 -512
- package/dist/cjs/util.cjs +32 -19
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -7
- 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 -42
- package/dist/tasks/tasks.d.ts.map +1 -1
- package/dist/tasks/tasks.js +13 -419
- 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 -635
- 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/typedoc.config.js +0 -19
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const common = require("@prosopo/common");
|
|
4
|
-
const contract = require("@prosopo/contract");
|
|
5
3
|
const util = require("@polkadot/util");
|
|
4
|
+
const common = require("@prosopo/common");
|
|
6
5
|
const authMiddleware = (tasks, env) => {
|
|
7
6
|
return async (req, res, next) => {
|
|
8
7
|
try {
|
|
@@ -11,7 +10,6 @@ const authMiddleware = (tasks, env) => {
|
|
|
11
10
|
throw new common.ProsopoEnvError("CONTRACT.CANNOT_FIND_KEYPAIR");
|
|
12
11
|
}
|
|
13
12
|
verifyEnvironmentKeyPair(env);
|
|
14
|
-
await verifyBlockNumber(blocknumber, tasks);
|
|
15
13
|
verifySignature(signature, blocknumber, env.pair);
|
|
16
14
|
next();
|
|
17
15
|
} catch (err) {
|
|
@@ -40,18 +38,6 @@ const verifyEnvironmentKeyPair = (env) => {
|
|
|
40
38
|
throw new common.ProsopoEnvError("CONTRACT.CANNOT_FIND_KEYPAIR");
|
|
41
39
|
}
|
|
42
40
|
};
|
|
43
|
-
const verifyBlockNumber = async (blockNumber, tasks) => {
|
|
44
|
-
const parsedBlockNumber = parseInt(blockNumber);
|
|
45
|
-
const currentBlockNumber = await contract.getCurrentBlockNumber(tasks.contract.api);
|
|
46
|
-
if (isNaN(parsedBlockNumber) || parsedBlockNumber < currentBlockNumber - 500 || parsedBlockNumber > currentBlockNumber) {
|
|
47
|
-
throw new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
48
|
-
context: {
|
|
49
|
-
error: `Invalid block number ${parsedBlockNumber}, current block number is ${currentBlockNumber}`,
|
|
50
|
-
code: 400
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
41
|
const verifySignature = (signature, blockNumber, pair) => {
|
|
56
42
|
const u8Sig = util.hexToU8a(signature);
|
|
57
43
|
if (!pair.verify(blockNumber, u8Sig, pair.publicKey)) {
|
package/dist/cjs/api/captcha.cjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const
|
|
3
|
+
const address = require("@polkadot/util-crypto/address");
|
|
4
4
|
const common = require("@prosopo/common");
|
|
5
|
-
const tasks = require("../tasks/tasks.cjs");
|
|
6
|
-
const errorHandler = require("./errorHandler.cjs");
|
|
7
|
-
const util = require("../util.cjs");
|
|
8
5
|
const datasets = require("@prosopo/datasets");
|
|
9
|
-
const
|
|
10
|
-
const util
|
|
6
|
+
const types = require("@prosopo/types");
|
|
7
|
+
const util = require("@prosopo/util");
|
|
11
8
|
const express = require("express");
|
|
9
|
+
const tasks = require("../tasks/tasks.cjs");
|
|
10
|
+
const errorHandler = require("./errorHandler.cjs");
|
|
12
11
|
function prosopoRouter(env) {
|
|
13
12
|
const router = express.Router();
|
|
14
13
|
const tasks$1 = new tasks.Tasks(env);
|
|
@@ -16,30 +15,35 @@ function prosopoRouter(env) {
|
|
|
16
15
|
`${types.ApiPaths.GetImageCaptchaChallenge}/:${types.ApiParams.datasetId}/:${types.ApiParams.user}/:${types.ApiParams.dapp}/:${types.ApiParams.blockNumber}`,
|
|
17
16
|
async (req, res, next) => {
|
|
18
17
|
try {
|
|
19
|
-
const {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
address.validateAddress(user, false, api.registry.chainSS58);
|
|
27
|
-
const blockNumberParsed = util.parseBlockNumber(blockNumber);
|
|
28
|
-
const taskData = await tasks$1.getRandomCaptchasAndRequestHash(datasetId, user);
|
|
18
|
+
const { datasetId, user } = types.CaptchaRequestBody.parse(req.params);
|
|
19
|
+
address.validateAddress(user, false, 42);
|
|
20
|
+
const taskData = await tasks$1.imgCaptchaManager.getRandomCaptchasAndRequestHash(
|
|
21
|
+
datasetId,
|
|
22
|
+
user
|
|
23
|
+
);
|
|
29
24
|
const captchaResponse = {
|
|
30
|
-
captchas: taskData.captchas.map((
|
|
31
|
-
...
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
25
|
+
captchas: taskData.captchas.map((captcha) => ({
|
|
26
|
+
...captcha,
|
|
27
|
+
items: captcha.items.map(
|
|
28
|
+
(item) => datasets.parseCaptchaAssets(item, env.assetsResolver)
|
|
29
|
+
)
|
|
36
30
|
})),
|
|
37
|
-
requestHash: taskData.requestHash
|
|
31
|
+
[types.ApiParams.requestHash]: taskData.requestHash,
|
|
32
|
+
[types.ApiParams.timestamp]: taskData.timestamp.toString(),
|
|
33
|
+
[types.ApiParams.signature]: {
|
|
34
|
+
[types.ApiParams.provider]: {
|
|
35
|
+
[types.ApiParams.timestamp]: taskData.signedTimestamp
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
38
|
};
|
|
39
39
|
return res.json(captchaResponse);
|
|
40
40
|
} catch (err) {
|
|
41
41
|
tasks$1.logger.error(err);
|
|
42
|
-
return next(
|
|
42
|
+
return next(
|
|
43
|
+
new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
44
|
+
context: { error: err, code: 400 }
|
|
45
|
+
})
|
|
46
|
+
);
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
49
|
);
|
|
@@ -48,24 +52,36 @@ function prosopoRouter(env) {
|
|
|
48
52
|
try {
|
|
49
53
|
parsed = types.CaptchaSolutionBody.parse(req.body);
|
|
50
54
|
} catch (err) {
|
|
51
|
-
return next(
|
|
55
|
+
return next(
|
|
56
|
+
new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
|
|
57
|
+
context: { code: 400, error: err }
|
|
58
|
+
})
|
|
59
|
+
);
|
|
52
60
|
}
|
|
53
61
|
try {
|
|
54
|
-
const result = await tasks$1.dappUserSolution(
|
|
62
|
+
const result = await tasks$1.imgCaptchaManager.dappUserSolution(
|
|
55
63
|
parsed[types.ApiParams.user],
|
|
56
64
|
parsed[types.ApiParams.dapp],
|
|
57
65
|
parsed[types.ApiParams.requestHash],
|
|
58
66
|
parsed[types.ApiParams.captchas],
|
|
59
|
-
parsed[types.ApiParams.signature]
|
|
67
|
+
parsed[types.ApiParams.signature].user.requestHash,
|
|
68
|
+
parseInt(parsed[types.ApiParams.timestamp]),
|
|
69
|
+
parsed[types.ApiParams.signature].provider.timestamp
|
|
60
70
|
);
|
|
61
71
|
const returnValue = {
|
|
62
|
-
status: req.i18n.t(
|
|
72
|
+
status: req.i18n.t(
|
|
73
|
+
result.verified ? "API.CAPTCHA_PASSED" : "API.CAPTCHA_FAILED"
|
|
74
|
+
),
|
|
63
75
|
...result
|
|
64
76
|
};
|
|
65
77
|
return res.json(returnValue);
|
|
66
78
|
} catch (err) {
|
|
67
79
|
tasks$1.logger.error(err);
|
|
68
|
-
return next(
|
|
80
|
+
return next(
|
|
81
|
+
new common.ProsopoApiError("API.UNKNOWN", {
|
|
82
|
+
context: { code: 400, error: err }
|
|
83
|
+
})
|
|
84
|
+
);
|
|
69
85
|
}
|
|
70
86
|
});
|
|
71
87
|
router.post(types.ApiPaths.GetPowCaptchaChallenge, async (req, res, next) => {
|
|
@@ -77,57 +93,78 @@ function prosopoRouter(env) {
|
|
|
77
93
|
context: { code: 400, error: "origin header not found" }
|
|
78
94
|
});
|
|
79
95
|
}
|
|
80
|
-
const challenge = await tasks$1.getPowCaptchaChallenge(
|
|
81
|
-
|
|
96
|
+
const challenge = await tasks$1.powCaptchaManager.getPowCaptchaChallenge(
|
|
97
|
+
user,
|
|
98
|
+
dapp,
|
|
99
|
+
origin
|
|
100
|
+
);
|
|
101
|
+
const getPowCaptchaResponse = {
|
|
102
|
+
challenge: challenge.challenge,
|
|
103
|
+
difficulty: challenge.difficulty,
|
|
104
|
+
timestamp: challenge.timestamp.toString(),
|
|
105
|
+
signature: {
|
|
106
|
+
provider: {
|
|
107
|
+
timestamp: challenge.timestampSignature,
|
|
108
|
+
challenge: challenge.signature
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
return res.json(getPowCaptchaResponse);
|
|
82
113
|
} catch (err) {
|
|
83
114
|
tasks$1.logger.error(err);
|
|
84
|
-
return next(
|
|
115
|
+
return next(
|
|
116
|
+
new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
117
|
+
context: { code: 400, error: err }
|
|
118
|
+
})
|
|
119
|
+
);
|
|
85
120
|
}
|
|
86
121
|
});
|
|
87
122
|
router.post(types.ApiPaths.SubmitPowCaptchaSolution, async (req, res, next) => {
|
|
88
123
|
try {
|
|
89
|
-
const {
|
|
90
|
-
const verified = await tasks$1.verifyPowCaptchaSolution(
|
|
91
|
-
blockNumber,
|
|
124
|
+
const { challenge, difficulty, signature, nonce, verifiedTimeout } = types.SubmitPowCaptchaSolutionBody.parse(req.body);
|
|
125
|
+
const verified = await tasks$1.powCaptchaManager.verifyPowCaptchaSolution(
|
|
92
126
|
challenge,
|
|
93
127
|
difficulty,
|
|
94
|
-
signature,
|
|
128
|
+
signature.provider.challenge,
|
|
95
129
|
nonce,
|
|
96
|
-
verifiedTimeout
|
|
130
|
+
verifiedTimeout,
|
|
131
|
+
signature.user.timestamp
|
|
97
132
|
);
|
|
98
133
|
const response = { verified };
|
|
99
134
|
return res.json(response);
|
|
100
135
|
} catch (err) {
|
|
101
136
|
tasks$1.logger.error(err);
|
|
102
|
-
return next(
|
|
137
|
+
return next(
|
|
138
|
+
new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
139
|
+
context: { code: 400, error: err }
|
|
140
|
+
})
|
|
141
|
+
);
|
|
103
142
|
}
|
|
104
143
|
});
|
|
105
144
|
router.post(types.ApiPaths.SubmitUserEvents, async (req, res, next) => {
|
|
106
145
|
try {
|
|
107
146
|
const { events, accountId } = req.body;
|
|
108
|
-
await tasks$1.saveCaptchaEvent(events, accountId);
|
|
147
|
+
await tasks$1.datasetManager.saveCaptchaEvent(events, accountId);
|
|
109
148
|
return res.json({ status: "success" });
|
|
110
149
|
} catch (err) {
|
|
111
150
|
tasks$1.logger.error(err);
|
|
112
|
-
return next(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const status = await tasks$1.providerStatus();
|
|
118
|
-
return res.json({ status });
|
|
119
|
-
} catch (err) {
|
|
120
|
-
tasks$1.logger.error(err);
|
|
121
|
-
return next(new common.ProsopoApiError("API.BAD_REQUEST", { context: { code: 400, error: err } }));
|
|
151
|
+
return next(
|
|
152
|
+
new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
153
|
+
context: { code: 400, error: err }
|
|
154
|
+
})
|
|
155
|
+
);
|
|
122
156
|
}
|
|
123
157
|
});
|
|
124
158
|
router.get(types.ApiPaths.GetProviderDetails, async (req, res, next) => {
|
|
125
159
|
try {
|
|
126
|
-
|
|
127
|
-
return res.json({ version: util$1.version, ...details });
|
|
160
|
+
return res.json({ version: util.version, ...{ message: "Provider online" } });
|
|
128
161
|
} catch (err) {
|
|
129
162
|
tasks$1.logger.error(err);
|
|
130
|
-
return next(
|
|
163
|
+
return next(
|
|
164
|
+
new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
165
|
+
context: { code: 400, error: err }
|
|
166
|
+
})
|
|
167
|
+
);
|
|
131
168
|
}
|
|
132
169
|
});
|
|
133
170
|
router.use(errorHandler.handleErrors);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const env = require("@prosopo/env");
|
|
4
|
+
const cron = require("cron");
|
|
5
|
+
const tasks = require("../tasks/tasks.cjs");
|
|
6
|
+
async function storeCaptchasExternally(pair, config) {
|
|
7
|
+
const env$1 = new env.ProviderEnvironment(config, pair);
|
|
8
|
+
await env$1.isReady();
|
|
9
|
+
const tasks$1 = new tasks.Tasks(env$1);
|
|
10
|
+
const defaultSchedule = "0 * * * *";
|
|
11
|
+
const cronSchedule = config.captchaScheduler ? config.captchaScheduler.schedule ? config.captchaScheduler.schedule : defaultSchedule : defaultSchedule;
|
|
12
|
+
const job = new cron.CronJob(cronSchedule, async () => {
|
|
13
|
+
env$1.logger.log("storeCommitmentsExternal task....");
|
|
14
|
+
await tasks$1.datasetManager.storeCommitmentsExternal().catch((err) => {
|
|
15
|
+
env$1.logger.error(err);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
job.start();
|
|
19
|
+
}
|
|
20
|
+
exports.storeCaptchasExternally = storeCaptchasExternally;
|
|
@@ -7,6 +7,8 @@ const handleErrors = (err, request, response, next) => {
|
|
|
7
7
|
err = err.context.error;
|
|
8
8
|
}
|
|
9
9
|
const message = err.message;
|
|
10
|
-
response.writeHead(code, JSON.stringify(message), {
|
|
10
|
+
response.writeHead(code, JSON.stringify(message), {
|
|
11
|
+
"content-type": "application/json"
|
|
12
|
+
}).end();
|
|
11
13
|
};
|
|
12
14
|
exports.handleErrors = handleErrors;
|
package/dist/cjs/api/verify.cjs
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const types = require("@prosopo/types");
|
|
4
|
-
const typesReturns = require("@prosopo/captcha-contract/types-returns");
|
|
5
3
|
const common = require("@prosopo/common");
|
|
4
|
+
const types = require("@prosopo/types");
|
|
5
|
+
const express = require("express");
|
|
6
6
|
const tasks = require("../tasks/tasks.cjs");
|
|
7
|
-
const contract = require("@prosopo/contract");
|
|
8
|
-
const errorHandler = require("./errorHandler.cjs");
|
|
9
7
|
const authMiddleware = require("./authMiddleware.cjs");
|
|
10
|
-
const
|
|
8
|
+
const errorHandler = require("./errorHandler.cjs");
|
|
11
9
|
function prosopoVerifyRouter(env) {
|
|
12
10
|
const router = express.Router();
|
|
13
11
|
const tasks$1 = new tasks.Tasks(env);
|
|
@@ -18,7 +16,7 @@ function prosopoVerifyRouter(env) {
|
|
|
18
16
|
const { user, dapp, blockNumber, commitmentId } = types.decodeProcaptchaOutput(token);
|
|
19
17
|
const keyPair = isDapp ? env.keyring.addFromAddress(dapp) : env.keyring.addFromAddress(user);
|
|
20
18
|
authMiddleware.verifySignature(dappUserSignature, blockNumber.toString(), keyPair);
|
|
21
|
-
const solution = await (commitmentId ? tasks$1.getDappUserCommitmentById(commitmentId) : tasks$1.getDappUserCommitmentByAccount(user));
|
|
19
|
+
const solution = await (commitmentId ? tasks$1.imgCaptchaManager.getDappUserCommitmentById(commitmentId) : tasks$1.imgCaptchaManager.getDappUserCommitmentByAccount(user));
|
|
22
20
|
if (!solution) {
|
|
23
21
|
tasks$1.logger.debug("Not verified - no solution found");
|
|
24
22
|
const noSolutionResponse = {
|
|
@@ -27,17 +25,17 @@ function prosopoVerifyRouter(env) {
|
|
|
27
25
|
};
|
|
28
26
|
return res.json(noSolutionResponse);
|
|
29
27
|
}
|
|
30
|
-
if (solution.status ===
|
|
28
|
+
if (solution.status === types.CaptchaStatus.disapproved) {
|
|
31
29
|
const disapprovedResponse = {
|
|
32
30
|
[types.ApiParams.status]: req.t("API.USER_NOT_VERIFIED"),
|
|
33
31
|
[types.ApiParams.verified]: false
|
|
34
32
|
};
|
|
35
33
|
return res.json(disapprovedResponse);
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
const timeSinceCompletion =
|
|
35
|
+
const maxVerifiedTime = parsed.maxVerifiedTime || 60 * 1e3;
|
|
36
|
+
if (maxVerifiedTime) {
|
|
37
|
+
const currentTime = Date.now();
|
|
38
|
+
const timeSinceCompletion = currentTime - solution.requestedAtTimestamp;
|
|
41
39
|
if (timeSinceCompletion > parsed.maxVerifiedTime) {
|
|
42
40
|
const expiredResponse = {
|
|
43
41
|
[types.ApiParams.status]: req.t("API.USER_NOT_VERIFIED_TIME_EXPIRED"),
|
|
@@ -47,32 +45,52 @@ function prosopoVerifyRouter(env) {
|
|
|
47
45
|
return res.json(expiredResponse);
|
|
48
46
|
}
|
|
49
47
|
}
|
|
50
|
-
const isApproved = solution.status ===
|
|
48
|
+
const isApproved = solution.status === types.CaptchaStatus.approved;
|
|
51
49
|
const response = {
|
|
52
|
-
[types.ApiParams.status]: req.t(
|
|
50
|
+
[types.ApiParams.status]: req.t(
|
|
51
|
+
isApproved ? "API.USER_VERIFIED" : "API.USER_NOT_VERIFIED"
|
|
52
|
+
),
|
|
53
53
|
[types.ApiParams.verified]: isApproved,
|
|
54
54
|
[types.ApiParams.commitmentId]: solution.id.toString(),
|
|
55
55
|
[types.ApiParams.blockNumber]: solution.requestedAt
|
|
56
56
|
};
|
|
57
57
|
return res.json(response);
|
|
58
58
|
} catch (err) {
|
|
59
|
-
return next(
|
|
59
|
+
return next(
|
|
60
|
+
new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
61
|
+
context: { code: 400, error: err }
|
|
62
|
+
})
|
|
63
|
+
);
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
|
-
router.post(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
router.post(
|
|
67
|
+
types.ApiPaths.VerifyImageCaptchaSolutionDapp,
|
|
68
|
+
async (req, res, next) => {
|
|
69
|
+
try {
|
|
70
|
+
await verifyImageSolution(res, req, next, true);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return next(
|
|
73
|
+
new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
|
|
74
|
+
context: { code: 400, error: err }
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
}
|
|
67
78
|
}
|
|
68
|
-
|
|
69
|
-
router.post(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
);
|
|
80
|
+
router.post(
|
|
81
|
+
types.ApiPaths.VerifyImageCaptchaSolutionUser,
|
|
82
|
+
async (req, res, next) => {
|
|
83
|
+
try {
|
|
84
|
+
await verifyImageSolution(res, req, next, false);
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return next(
|
|
87
|
+
new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
|
|
88
|
+
context: { code: 400, error: err }
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
}
|
|
74
92
|
}
|
|
75
|
-
|
|
93
|
+
);
|
|
76
94
|
router.post(types.ApiPaths.VerifyPowCaptchaSolution, async (req, res, next) => {
|
|
77
95
|
try {
|
|
78
96
|
const { token, dappSignature, verifiedTimeout } = types.ServerPowCaptchaVerifyRequestBody.parse(req.body);
|
|
@@ -86,7 +104,11 @@ function prosopoVerifyRouter(env) {
|
|
|
86
104
|
}
|
|
87
105
|
const dappPair = env.keyring.addFromAddress(dapp);
|
|
88
106
|
authMiddleware.verifySignature(dappSignature, blockNumber.toString(), dappPair);
|
|
89
|
-
const approved = await tasks$1.serverVerifyPowCaptchaSolution(
|
|
107
|
+
const approved = await tasks$1.powCaptchaManager.serverVerifyPowCaptchaSolution(
|
|
108
|
+
dapp,
|
|
109
|
+
challenge,
|
|
110
|
+
verifiedTimeout
|
|
111
|
+
);
|
|
90
112
|
const verificationResponse = {
|
|
91
113
|
status: req.t(approved ? "API.USER_VERIFIED" : "API.USER_NOT_VERIFIED"),
|
|
92
114
|
[types.ApiParams.verified]: approved
|
|
@@ -94,7 +116,11 @@ function prosopoVerifyRouter(env) {
|
|
|
94
116
|
return res.json(verificationResponse);
|
|
95
117
|
} catch (err) {
|
|
96
118
|
tasks$1.logger.error(err);
|
|
97
|
-
return next(
|
|
119
|
+
return next(
|
|
120
|
+
new common.ProsopoApiError("API.BAD_REQUEST", {
|
|
121
|
+
context: { code: 400, error: err }
|
|
122
|
+
})
|
|
123
|
+
);
|
|
98
124
|
}
|
|
99
125
|
});
|
|
100
126
|
router.use(errorHandler.handleErrors);
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
require("./tasks/index.cjs");
|
|
4
4
|
const util = require("./util.cjs");
|
|
5
|
-
require("./batch/index.cjs");
|
|
6
5
|
const captcha = require("./api/captcha.cjs");
|
|
7
6
|
const verify = require("./api/verify.cjs");
|
|
8
7
|
const admin = require("./api/admin.cjs");
|
|
9
8
|
const errorHandler = require("./api/errorHandler.cjs");
|
|
9
|
+
const captchaScheduler = require("./api/captchaScheduler.cjs");
|
|
10
10
|
const tasks = require("./tasks/tasks.cjs");
|
|
11
|
-
const commitments = require("./batch/commitments.cjs");
|
|
12
11
|
exports.checkIfTaskIsRunning = util.checkIfTaskIsRunning;
|
|
13
12
|
exports.encodeStringAddress = util.encodeStringAddress;
|
|
14
13
|
exports.parseBlockNumber = util.parseBlockNumber;
|
|
@@ -18,5 +17,5 @@ exports.prosopoRouter = captcha.prosopoRouter;
|
|
|
18
17
|
exports.prosopoVerifyRouter = verify.prosopoVerifyRouter;
|
|
19
18
|
exports.prosopoAdminRouter = admin.prosopoAdminRouter;
|
|
20
19
|
exports.handleErrors = errorHandler.handleErrors;
|
|
20
|
+
exports.storeCaptchasExternally = captchaScheduler.storeCaptchasExternally;
|
|
21
21
|
exports.Tasks = tasks.Tasks;
|
|
22
|
-
exports.BatchCommitmentsTask = commitments.BatchCommitmentsTask;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const database = require("@prosopo/database");
|
|
4
|
+
const datasets = require("@prosopo/datasets");
|
|
5
|
+
const datasetTasksUtils = require("./datasetTasksUtils.cjs");
|
|
6
|
+
class DatasetManager {
|
|
7
|
+
constructor(config, logger, captchaConfig, db) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
this.captchaConfig = captchaConfig;
|
|
11
|
+
this.db = db;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @description Set the provider dataset from a file
|
|
15
|
+
*
|
|
16
|
+
* @param file JSON of the captcha dataset
|
|
17
|
+
*/
|
|
18
|
+
async providerSetDatasetFromFile(file) {
|
|
19
|
+
const datasetRaw = datasets.parseCaptchaDataset(file);
|
|
20
|
+
return await this.providerSetDataset(datasetRaw);
|
|
21
|
+
}
|
|
22
|
+
async providerSetDataset(datasetRaw) {
|
|
23
|
+
const dataset = await datasetTasksUtils.providerValidateDataset(
|
|
24
|
+
datasetRaw,
|
|
25
|
+
this.captchaConfig.solved.count,
|
|
26
|
+
this.captchaConfig.unsolved.count
|
|
27
|
+
);
|
|
28
|
+
await this.db?.storeDataset(dataset);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @description Save captcha user events to external db
|
|
32
|
+
*
|
|
33
|
+
* **Note:** This is only used in development mode
|
|
34
|
+
*
|
|
35
|
+
* @param events
|
|
36
|
+
* @param accountId
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
async saveCaptchaEvent(events, accountId) {
|
|
40
|
+
if (!this.config.devOnlyWatchEvents || !this.config.mongoEventsUri) {
|
|
41
|
+
this.logger.info("Dev watch events not set to true, not saving events");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
await database.saveCaptchaEvent(events, accountId, this.config.mongoEventsUri);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* @description Store commitments externally in the database, clear them from local cache
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
async storeCommitmentsExternal() {
|
|
51
|
+
if (!this.config.mongoCaptchaUri) {
|
|
52
|
+
this.logger.info("Mongo env not set");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const commitments = await this.db.getUnstoredDappUserCommitments();
|
|
56
|
+
this.logger.info(`Storing ${commitments.length} commitments externally`);
|
|
57
|
+
const powRecords = await this.db.getUnstoredDappUserPoWCommitments();
|
|
58
|
+
this.logger.info(`Storing ${powRecords.length} pow challenges externally`);
|
|
59
|
+
await database.saveCaptchas(commitments, powRecords, this.config.mongoCaptchaUri);
|
|
60
|
+
await this.db.markDappUserCommitmentsStored(
|
|
61
|
+
commitments.map((commitment) => commitment.id)
|
|
62
|
+
);
|
|
63
|
+
await this.db.markDappUserPoWCommitmentsStored(
|
|
64
|
+
powRecords.map((powRecords2) => powRecords2.challenge)
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.DatasetManager = DatasetManager;
|
|
@@ -0,0 +1,34 @@
|
|
|
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 providerValidateDataset = async (datasetRaw, minSolvedCaptchas, minUnsolvedCaptchas) => {
|
|
6
|
+
if (datasetRaw.captchas.length < minSolvedCaptchas + minUnsolvedCaptchas) {
|
|
7
|
+
throw new common.ProsopoEnvError("DATASET.CAPTCHAS_COUNT_LESS_THAN_CONFIGURED", {
|
|
8
|
+
context: { failedFuncName: providerValidateDataset.name }
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const solutions = datasetRaw.captchas.map((captcha) => captcha.solution ? 1 : 0).reduce((partialSum, b) => partialSum + b, 0);
|
|
12
|
+
if (solutions < minSolvedCaptchas) {
|
|
13
|
+
throw new common.ProsopoEnvError("DATASET.SOLUTIONS_COUNT_LESS_THAN_CONFIGURED", {
|
|
14
|
+
context: { failedFuncName: providerValidateDataset.name }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (solutions < minUnsolvedCaptchas) {
|
|
18
|
+
throw new common.ProsopoEnvError("DATASET.SOLUTIONS_COUNT_LESS_THAN_CONFIGURED", {
|
|
19
|
+
context: { failedFuncName: providerValidateDataset.name }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const dataset = await datasets.buildDataset(datasetRaw);
|
|
23
|
+
if (!dataset.datasetId || !dataset.datasetContentId) {
|
|
24
|
+
throw new common.ProsopoEnvError("DATASET.DATASET_ID_UNDEFINED", {
|
|
25
|
+
context: {
|
|
26
|
+
failedFuncName: providerValidateDataset.name,
|
|
27
|
+
datasetId: dataset.datasetId,
|
|
28
|
+
datasetContentId: dataset.datasetContentId
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return dataset;
|
|
33
|
+
};
|
|
34
|
+
exports.providerValidateDataset = providerValidateDataset;
|