@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.
Files changed (191) hide show
  1. package/README.md +0 -258
  2. package/dist/api/admin.d.ts +2 -2
  3. package/dist/api/admin.d.ts.map +1 -1
  4. package/dist/api/admin.js +5 -64
  5. package/dist/api/admin.js.map +1 -1
  6. package/dist/api/authMiddleware.d.ts +4 -4
  7. package/dist/api/authMiddleware.d.ts.map +1 -1
  8. package/dist/api/authMiddleware.js +15 -29
  9. package/dist/api/authMiddleware.js.map +1 -1
  10. package/dist/api/captcha.d.ts +2 -2
  11. package/dist/api/captcha.d.ts.map +1 -1
  12. package/dist/api/captcha.js +64 -55
  13. package/dist/api/captcha.js.map +1 -1
  14. package/dist/api/captchaScheduler.d.ts +4 -0
  15. package/dist/api/captchaScheduler.d.ts.map +1 -0
  16. package/dist/api/captchaScheduler.js +22 -0
  17. package/dist/api/captchaScheduler.js.map +1 -0
  18. package/dist/api/errorHandler.d.ts +3 -3
  19. package/dist/api/errorHandler.d.ts.map +1 -1
  20. package/dist/api/errorHandler.js +7 -3
  21. package/dist/api/errorHandler.js.map +1 -1
  22. package/dist/api/verify.d.ts +2 -2
  23. package/dist/api/verify.d.ts.map +1 -1
  24. package/dist/api/verify.js +37 -29
  25. package/dist/api/verify.js.map +1 -1
  26. package/dist/cjs/api/admin.cjs +2 -89
  27. package/dist/cjs/api/authMiddleware.cjs +1 -15
  28. package/dist/cjs/api/captcha.cjs +89 -52
  29. package/dist/cjs/api/captchaScheduler.cjs +20 -0
  30. package/dist/cjs/api/errorHandler.cjs +3 -1
  31. package/dist/cjs/api/verify.cjs +54 -28
  32. package/dist/cjs/index.cjs +2 -3
  33. package/dist/cjs/tasks/dataset/datasetTasks.cjs +68 -0
  34. package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +34 -0
  35. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +277 -0
  36. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +25 -0
  37. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +107 -0
  38. package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +55 -0
  39. package/dist/cjs/tasks/tasks.cjs +21 -512
  40. package/dist/cjs/util.cjs +32 -19
  41. package/dist/index.d.ts +7 -7
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +7 -7
  44. package/dist/index.js.map +1 -1
  45. package/dist/tasks/dataset/datasetTasks.d.ts +15 -0
  46. package/dist/tasks/dataset/datasetTasks.d.ts.map +1 -0
  47. package/dist/tasks/dataset/datasetTasks.js +40 -0
  48. package/dist/tasks/dataset/datasetTasks.js.map +1 -0
  49. package/dist/tasks/dataset/datasetTasksUtils.d.ts +3 -0
  50. package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +1 -0
  51. package/dist/tasks/dataset/datasetTasksUtils.js +34 -0
  52. package/dist/tasks/dataset/datasetTasksUtils.js.map +1 -0
  53. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +28 -0
  54. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -0
  55. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +212 -0
  56. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -0
  57. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +7 -0
  58. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +1 -0
  59. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +18 -0
  60. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +1 -0
  61. package/dist/tasks/index.d.ts +1 -1
  62. package/dist/tasks/index.d.ts.map +1 -1
  63. package/dist/tasks/index.js +1 -1
  64. package/dist/tasks/index.js.map +1 -1
  65. package/dist/tasks/powCaptcha/powTasks.d.ts +13 -0
  66. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -0
  67. package/dist/tasks/powCaptcha/powTasks.js +66 -0
  68. package/dist/tasks/powCaptcha/powTasks.js.map +1 -0
  69. package/dist/tasks/powCaptcha/powTasksUtils.d.ts +5 -0
  70. package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +1 -0
  71. package/dist/tasks/powCaptcha/powTasksUtils.js +49 -0
  72. package/dist/tasks/powCaptcha/powTasksUtils.js.map +1 -0
  73. package/dist/tasks/tasks.d.ts +12 -42
  74. package/dist/tasks/tasks.d.ts.map +1 -1
  75. package/dist/tasks/tasks.js +13 -419
  76. package/dist/tasks/tasks.js.map +1 -1
  77. package/dist/tests/index.d.ts +2 -0
  78. package/dist/tests/index.d.ts.map +1 -0
  79. package/dist/tests/index.js +2 -0
  80. package/dist/tests/index.js.map +1 -0
  81. package/dist/tests/integration/imgCaptcha.test.d.ts +2 -0
  82. package/dist/tests/integration/imgCaptcha.test.d.ts.map +1 -0
  83. package/dist/tests/integration/imgCaptcha.test.js +111 -0
  84. package/dist/tests/integration/imgCaptcha.test.js.map +1 -0
  85. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts +32 -0
  86. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts.map +1 -0
  87. package/dist/tests/integration/mocks/solvedTestCaptchas.js +1042 -0
  88. package/dist/tests/integration/mocks/solvedTestCaptchas.js.map +1 -0
  89. package/dist/tests/integration/powCaptcha.test.d.ts +2 -0
  90. package/dist/tests/integration/powCaptcha.test.d.ts.map +1 -0
  91. package/dist/tests/integration/powCaptcha.test.js +171 -0
  92. package/dist/tests/integration/powCaptcha.test.js.map +1 -0
  93. package/dist/tests/unit/api/authMiddleware.test.d.ts +2 -0
  94. package/dist/tests/unit/api/authMiddleware.test.d.ts.map +1 -0
  95. package/dist/tests/unit/api/authMiddleware.test.js +87 -0
  96. package/dist/tests/unit/api/authMiddleware.test.js.map +1 -0
  97. package/dist/tests/unit/api/captchaScheduler.test.d.ts +2 -0
  98. package/dist/tests/unit/api/captchaScheduler.test.d.ts.map +1 -0
  99. package/dist/tests/unit/api/captchaScheduler.test.js +47 -0
  100. package/dist/tests/unit/api/captchaScheduler.test.js.map +1 -0
  101. package/dist/tests/unit/api/errorHandler.test.d.ts +2 -0
  102. package/dist/tests/unit/api/errorHandler.test.d.ts.map +1 -0
  103. package/dist/tests/unit/api/errorHandler.test.js +65 -0
  104. package/dist/tests/unit/api/errorHandler.test.js.map +1 -0
  105. package/dist/tests/unit/tasks/dataset/datasetTasks.test.d.ts +2 -0
  106. package/dist/tests/unit/tasks/dataset/datasetTasks.test.d.ts.map +1 -0
  107. package/dist/tests/unit/tasks/dataset/datasetTasks.test.js +88 -0
  108. package/dist/tests/unit/tasks/dataset/datasetTasks.test.js.map +1 -0
  109. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.d.ts +2 -0
  110. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.d.ts.map +1 -0
  111. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.js +75 -0
  112. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.test.js.map +1 -0
  113. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.d.ts +2 -0
  114. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.d.ts.map +1 -0
  115. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.js +260 -0
  116. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.test.js.map +1 -0
  117. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.d.ts +2 -0
  118. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.d.ts.map +1 -0
  119. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.js +46 -0
  120. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.test.js.map +1 -0
  121. package/dist/tests/unit/tasks/powCaptcha/powTasks.test.d.ts +2 -0
  122. package/dist/tests/unit/tasks/powCaptcha/powTasks.test.d.ts.map +1 -0
  123. package/dist/tests/unit/tasks/powCaptcha/powTasks.test.js +133 -0
  124. package/dist/tests/unit/tasks/powCaptcha/powTasks.test.js.map +1 -0
  125. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.d.ts +2 -0
  126. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.d.ts.map +1 -0
  127. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.js +94 -0
  128. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.test.js.map +1 -0
  129. package/dist/util.d.ts +2 -2
  130. package/dist/util.d.ts.map +1 -1
  131. package/dist/util.js +10 -8
  132. package/dist/util.js.map +1 -1
  133. package/package.json +74 -86
  134. package/vite.cjs.config.ts +3 -3
  135. package/vite.test.config.ts +12 -12
  136. package/dist/batch/commitments.d.ts +0 -24
  137. package/dist/batch/commitments.d.ts.map +0 -1
  138. package/dist/batch/commitments.js +0 -130
  139. package/dist/batch/commitments.js.map +0 -1
  140. package/dist/batch/index.d.ts +0 -2
  141. package/dist/batch/index.d.ts.map +0 -1
  142. package/dist/batch/index.js +0 -2
  143. package/dist/batch/index.js.map +0 -1
  144. package/dist/cjs/batch/commitments.cjs +0 -158
  145. package/dist/cjs/batch/index.cjs +0 -4
  146. package/dist/scheduler.d.ts +0 -4
  147. package/dist/scheduler.d.ts.map +0 -1
  148. package/dist/scheduler.js +0 -21
  149. package/dist/scheduler.js.map +0 -1
  150. package/dist/tests/accounts.d.ts +0 -12
  151. package/dist/tests/accounts.d.ts.map +0 -1
  152. package/dist/tests/accounts.js +0 -35
  153. package/dist/tests/accounts.js.map +0 -1
  154. package/dist/tests/contract/helpers.test.d.ts +0 -6
  155. package/dist/tests/contract/helpers.test.d.ts.map +0 -1
  156. package/dist/tests/contract/helpers.test.js +0 -54
  157. package/dist/tests/contract/helpers.test.js.map +0 -1
  158. package/dist/tests/dataUtils/DatabaseAccounts.d.ts +0 -35
  159. package/dist/tests/dataUtils/DatabaseAccounts.d.ts.map +0 -1
  160. package/dist/tests/dataUtils/DatabaseAccounts.js +0 -84
  161. package/dist/tests/dataUtils/DatabaseAccounts.js.map +0 -1
  162. package/dist/tests/dataUtils/DatabasePopulator.d.ts +0 -73
  163. package/dist/tests/dataUtils/DatabasePopulator.d.ts.map +0 -1
  164. package/dist/tests/dataUtils/DatabasePopulator.js +0 -326
  165. package/dist/tests/dataUtils/DatabasePopulator.js.map +0 -1
  166. package/dist/tests/dataUtils/dapp-example-contract/dapp.json +0 -648
  167. package/dist/tests/dataUtils/dapp-example-contract/loadFiles.d.ts +0 -4
  168. package/dist/tests/dataUtils/dapp-example-contract/loadFiles.d.ts.map +0 -1
  169. package/dist/tests/dataUtils/dapp-example-contract/loadFiles.js +0 -27
  170. package/dist/tests/dataUtils/dapp-example-contract/loadFiles.js.map +0 -1
  171. package/dist/tests/dataUtils/funds.d.ts +0 -9
  172. package/dist/tests/dataUtils/funds.d.ts.map +0 -1
  173. package/dist/tests/dataUtils/funds.js +0 -105
  174. package/dist/tests/dataUtils/funds.js.map +0 -1
  175. package/dist/tests/dataUtils/populateDatabase.d.ts +0 -16
  176. package/dist/tests/dataUtils/populateDatabase.d.ts.map +0 -1
  177. package/dist/tests/dataUtils/populateDatabase.js +0 -72
  178. package/dist/tests/dataUtils/populateDatabase.js.map +0 -1
  179. package/dist/tests/getUser.d.ts +0 -4
  180. package/dist/tests/getUser.d.ts.map +0 -1
  181. package/dist/tests/getUser.js +0 -18
  182. package/dist/tests/getUser.js.map +0 -1
  183. package/dist/tests/tasks/tasks.test.d.ts +0 -6
  184. package/dist/tests/tasks/tasks.test.d.ts.map +0 -1
  185. package/dist/tests/tasks/tasks.test.js +0 -635
  186. package/dist/tests/tasks/tasks.test.js.map +0 -1
  187. package/dist/tests/util.test.d.ts +0 -2
  188. package/dist/tests/util.test.d.ts.map +0 -1
  189. package/dist/tests/util.test.js +0 -23
  190. package/dist/tests/util.test.js.map +0 -1
  191. 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)) {
@@ -1,14 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const types = require("@prosopo/types");
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 address = require("@polkadot/util-crypto/address");
10
- const util$1 = require("@prosopo/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 { blockNumber, datasetId, user, dapp } = types.CaptchaRequestBody.parse(req.params);
20
- const api = env.api;
21
- if (api === void 0) {
22
- throw new common.ProsopoApiError("DEVELOPER.METHOD_NOT_IMPLEMENTED", {
23
- context: { error: "api not setup", env }
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((cwp) => ({
31
- ...cwp,
32
- captcha: {
33
- ...cwp.captcha,
34
- items: cwp.captcha.items.map((item) => datasets.parseCaptchaAssets(item, env.assetsResolver))
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(new common.ProsopoApiError("API.BAD_REQUEST", { context: { error: err, code: 400 } }));
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(new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", { context: { code: 400, error: err } }));
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(result.verified ? "API.CAPTCHA_PASSED" : "API.CAPTCHA_FAILED"),
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(new common.ProsopoApiError("API.UNKNOWN", { context: { code: 400, error: err } }));
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(user, dapp, origin);
81
- return res.json(challenge);
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(new common.ProsopoApiError("API.BAD_REQUEST", { context: { code: 400, error: err } }));
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 { blockNumber, challenge, difficulty, signature, nonce, verifiedTimeout } = types.SubmitPowCaptchaSolutionBody.parse(req.body);
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(new common.ProsopoApiError("API.BAD_REQUEST", { context: { code: 400, error: err } }));
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(new common.ProsopoApiError("API.BAD_REQUEST", { context: { code: 400, error: err } }));
113
- }
114
- });
115
- router.get(types.ApiPaths.GetProviderStatus, async (req, res, next) => {
116
- try {
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
- const details = await tasks$1.getProviderDetails();
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(new common.ProsopoApiError("API.BAD_REQUEST", { context: { code: 400, error: err } }));
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), { "content-type": "application/json" }).end();
10
+ response.writeHead(code, JSON.stringify(message), {
11
+ "content-type": "application/json"
12
+ }).end();
11
13
  };
12
14
  exports.handleErrors = handleErrors;
@@ -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 express = require("express");
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 === typesReturns.CaptchaStatus.disapproved) {
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
- if (parsed.maxVerifiedTime) {
38
- const currentBlockNumber = await contract.getCurrentBlockNumber(tasks$1.contract.api);
39
- const blockTimeMs = contract.getBlockTimeMs(tasks$1.contract.api);
40
- const timeSinceCompletion = (currentBlockNumber - solution.completedAt) * blockTimeMs;
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 === typesReturns.CaptchaStatus.approved;
48
+ const isApproved = solution.status === types.CaptchaStatus.approved;
51
49
  const response = {
52
- [types.ApiParams.status]: req.t(isApproved ? "API.USER_VERIFIED" : "API.USER_NOT_VERIFIED"),
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(new common.ProsopoApiError("API.BAD_REQUEST", { context: { code: 400, error: err } }));
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(types.ApiPaths.VerifyImageCaptchaSolutionDapp, async (req, res, next) => {
63
- try {
64
- await verifyImageSolution(res, req, next, true);
65
- } catch (err) {
66
- return next(new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", { context: { code: 400, error: err } }));
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(types.ApiPaths.VerifyImageCaptchaSolutionUser, async (req, res, next) => {
70
- try {
71
- await verifyImageSolution(res, req, next, false);
72
- } catch (err) {
73
- return next(new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", { context: { code: 400, error: err } }));
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(dapp, challenge, verifiedTimeout);
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(new common.ProsopoApiError("API.BAD_REQUEST", { context: { code: 400, error: err } }));
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);
@@ -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;