@prosopo/provider 2.1.1 → 2.1.2

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 (162) hide show
  1. package/package.json +11 -11
  2. package/.dockerignore +0 -5
  3. package/coverage/base.css +0 -224
  4. package/coverage/block-navigation.js +0 -87
  5. package/coverage/clover.xml +0 -6
  6. package/coverage/coverage-final.json +0 -1
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/index.html +0 -101
  9. package/coverage/prettify.css +0 -1
  10. package/coverage/prettify.js +0 -2
  11. package/coverage/sort-arrow-sprite.png +0 -0
  12. package/coverage/sorter.js +0 -196
  13. package/dist/api/admin.d.ts +0 -4
  14. package/dist/api/admin.d.ts.map +0 -1
  15. package/dist/api/admin.js +0 -37
  16. package/dist/api/admin.js.map +0 -1
  17. package/dist/api/authMiddleware.d.ts +0 -6
  18. package/dist/api/authMiddleware.d.ts.map +0 -1
  19. package/dist/api/authMiddleware.js +0 -57
  20. package/dist/api/authMiddleware.js.map +0 -1
  21. package/dist/api/captcha.d.ts +0 -4
  22. package/dist/api/captcha.d.ts.map +0 -1
  23. package/dist/api/captcha.js +0 -161
  24. package/dist/api/captcha.js.map +0 -1
  25. package/dist/api/errorHandler.d.ts +0 -5
  26. package/dist/api/errorHandler.d.ts.map +0 -1
  27. package/dist/api/errorHandler.js +0 -14
  28. package/dist/api/errorHandler.js.map +0 -1
  29. package/dist/api/verify.d.ts +0 -4
  30. package/dist/api/verify.d.ts.map +0 -1
  31. package/dist/api/verify.js +0 -127
  32. package/dist/api/verify.js.map +0 -1
  33. package/dist/cjs/api/admin.cjs +0 -38
  34. package/dist/cjs/api/authMiddleware.cjs +0 -57
  35. package/dist/cjs/api/captcha.cjs +0 -210
  36. package/dist/cjs/api/errorHandler.cjs +0 -14
  37. package/dist/cjs/api/verify.cjs +0 -140
  38. package/dist/cjs/index.cjs +0 -21
  39. package/dist/cjs/schedulers/captchaScheduler.cjs +0 -33
  40. package/dist/cjs/schedulers/getClientList.cjs +0 -31
  41. package/dist/cjs/tasks/client/clientTasks.cjs +0 -148
  42. package/dist/cjs/tasks/dataset/datasetTasks.cjs +0 -30
  43. package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +0 -34
  44. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +0 -281
  45. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +0 -25
  46. package/dist/cjs/tasks/index.cjs +0 -4
  47. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +0 -133
  48. package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +0 -26
  49. package/dist/cjs/tasks/tasks.cjs +0 -40
  50. package/dist/cjs/util.cjs +0 -45
  51. package/dist/index.d.ts +0 -9
  52. package/dist/index.d.ts.map +0 -1
  53. package/dist/index.js +0 -9
  54. package/dist/index.js.map +0 -1
  55. package/dist/schedulers/captchaScheduler.d.ts +0 -4
  56. package/dist/schedulers/captchaScheduler.d.ts.map +0 -1
  57. package/dist/schedulers/captchaScheduler.js +0 -28
  58. package/dist/schedulers/captchaScheduler.js.map +0 -1
  59. package/dist/schedulers/getClientList.d.ts +0 -4
  60. package/dist/schedulers/getClientList.d.ts.map +0 -1
  61. package/dist/schedulers/getClientList.js +0 -28
  62. package/dist/schedulers/getClientList.js.map +0 -1
  63. package/dist/tasks/client/clientTasks.d.ts +0 -13
  64. package/dist/tasks/client/clientTasks.d.ts.map +0 -1
  65. package/dist/tasks/client/clientTasks.js +0 -87
  66. package/dist/tasks/client/clientTasks.js.map +0 -1
  67. package/dist/tasks/dataset/datasetTasks.d.ts +0 -13
  68. package/dist/tasks/dataset/datasetTasks.d.ts.map +0 -1
  69. package/dist/tasks/dataset/datasetTasks.js +0 -19
  70. package/dist/tasks/dataset/datasetTasks.js.map +0 -1
  71. package/dist/tasks/dataset/datasetTasksUtils.d.ts +0 -3
  72. package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +0 -1
  73. package/dist/tasks/dataset/datasetTasksUtils.js +0 -34
  74. package/dist/tasks/dataset/datasetTasksUtils.js.map +0 -1
  75. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +0 -28
  76. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +0 -1
  77. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +0 -208
  78. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +0 -1
  79. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +0 -7
  80. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +0 -1
  81. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +0 -18
  82. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +0 -1
  83. package/dist/tasks/index.d.ts +0 -2
  84. package/dist/tasks/index.d.ts.map +0 -1
  85. package/dist/tasks/index.js +0 -2
  86. package/dist/tasks/index.js.map +0 -1
  87. package/dist/tasks/powCaptcha/powTasks.d.ts +0 -13
  88. package/dist/tasks/powCaptcha/powTasks.d.ts.map +0 -1
  89. package/dist/tasks/powCaptcha/powTasks.js +0 -83
  90. package/dist/tasks/powCaptcha/powTasks.js.map +0 -1
  91. package/dist/tasks/powCaptcha/powTasksUtils.d.ts +0 -3
  92. package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +0 -1
  93. package/dist/tasks/powCaptcha/powTasksUtils.js +0 -22
  94. package/dist/tasks/powCaptcha/powTasksUtils.js.map +0 -1
  95. package/dist/tasks/tasks.d.ts +0 -22
  96. package/dist/tasks/tasks.d.ts.map +0 -1
  97. package/dist/tasks/tasks.js +0 -24
  98. package/dist/tasks/tasks.js.map +0 -1
  99. package/dist/tests/index.d.ts +0 -2
  100. package/dist/tests/index.d.ts.map +0 -1
  101. package/dist/tests/index.js +0 -2
  102. package/dist/tests/index.js.map +0 -1
  103. package/dist/tests/integration/imgCaptcha.integration.test.d.ts +0 -2
  104. package/dist/tests/integration/imgCaptcha.integration.test.d.ts.map +0 -1
  105. package/dist/tests/integration/imgCaptcha.integration.test.js +0 -133
  106. package/dist/tests/integration/imgCaptcha.integration.test.js.map +0 -1
  107. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts +0 -32
  108. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts.map +0 -1
  109. package/dist/tests/integration/mocks/solvedTestCaptchas.js +0 -1046
  110. package/dist/tests/integration/mocks/solvedTestCaptchas.js.map +0 -1
  111. package/dist/tests/integration/powCaptcha.integration.test.d.ts +0 -2
  112. package/dist/tests/integration/powCaptcha.integration.test.d.ts.map +0 -1
  113. package/dist/tests/integration/powCaptcha.integration.test.js +0 -229
  114. package/dist/tests/integration/powCaptcha.integration.test.js.map +0 -1
  115. package/dist/tests/integration/registerSitekey.d.ts +0 -2
  116. package/dist/tests/integration/registerSitekey.d.ts.map +0 -1
  117. package/dist/tests/integration/registerSitekey.js +0 -17
  118. package/dist/tests/integration/registerSitekey.js.map +0 -1
  119. package/dist/tests/unit/api/authMiddleware.unit.test.d.ts +0 -2
  120. package/dist/tests/unit/api/authMiddleware.unit.test.d.ts.map +0 -1
  121. package/dist/tests/unit/api/authMiddleware.unit.test.js +0 -87
  122. package/dist/tests/unit/api/authMiddleware.unit.test.js.map +0 -1
  123. package/dist/tests/unit/api/errorHandler.unit.test.d.ts +0 -2
  124. package/dist/tests/unit/api/errorHandler.unit.test.d.ts.map +0 -1
  125. package/dist/tests/unit/api/errorHandler.unit.test.js +0 -65
  126. package/dist/tests/unit/api/errorHandler.unit.test.js.map +0 -1
  127. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts +0 -2
  128. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts.map +0 -1
  129. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +0 -63
  130. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +0 -1
  131. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts +0 -2
  132. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts.map +0 -1
  133. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +0 -172
  134. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +0 -1
  135. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts +0 -2
  136. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts.map +0 -1
  137. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js +0 -86
  138. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js.map +0 -1
  139. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts +0 -2
  140. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts.map +0 -1
  141. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +0 -75
  142. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +0 -1
  143. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts +0 -2
  144. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts.map +0 -1
  145. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +0 -266
  146. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +0 -1
  147. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts +0 -2
  148. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts.map +0 -1
  149. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +0 -46
  150. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +0 -1
  151. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts +0 -2
  152. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts.map +0 -1
  153. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +0 -209
  154. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +0 -1
  155. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts +0 -2
  156. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts.map +0 -1
  157. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +0 -65
  158. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +0 -1
  159. package/dist/util.d.ts +0 -6
  160. package/dist/util.d.ts.map +0 -1
  161. package/dist/util.js +0 -34
  162. package/dist/util.js.map +0 -1
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const env = require("@prosopo/env");
4
- const types = require("@prosopo/types");
5
- const cron = require("cron");
6
- const tasks = require("../tasks/tasks.cjs");
7
- const util = require("../util.cjs");
8
- async function getClientList(pair, config) {
9
- const env$1 = new env.ProviderEnvironment(config, pair);
10
- await env$1.isReady();
11
- const tasks$1 = new tasks.Tasks(env$1);
12
- const defaultSchedule = "0 * * * *";
13
- const cronSchedule = config.scheduledTasks?.clientListScheduler ? config.scheduledTasks.clientListScheduler.schedule ? config.scheduledTasks.clientListScheduler.schedule : defaultSchedule : defaultSchedule;
14
- const job = new cron.CronJob(cronSchedule, async () => {
15
- const taskRunning = await util.checkIfTaskIsRunning(
16
- types.ScheduledTaskNames.GetClientList,
17
- env$1.getDb()
18
- );
19
- env$1.logger.info(
20
- `${types.ScheduledTaskNames.GetClientList} task running: ${taskRunning}`
21
- );
22
- if (!taskRunning) {
23
- env$1.logger.info(`${types.ScheduledTaskNames.GetClientList} task....`);
24
- await tasks$1.clientTaskManager.getClientList().catch((err) => {
25
- env$1.logger.error(err);
26
- });
27
- }
28
- });
29
- job.start();
30
- }
31
- exports.getClientList = getClientList;
@@ -1,148 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const database = require("@prosopo/database");
4
- const types = require("@prosopo/types");
5
- class ClientTaskManager {
6
- constructor(config, logger, db) {
7
- this.config = config;
8
- this.logger = logger;
9
- this.providerDB = db;
10
- }
11
- /**
12
- * @description Store commitments externally in the database
13
- * @returns Promise<void>
14
- */
15
- async storeCommitmentsExternal() {
16
- if (!this.config.mongoCaptchaUri) {
17
- this.logger.info("Mongo env not set");
18
- return;
19
- }
20
- const lastTask = await this.providerDB.getLastScheduledTaskStatus(
21
- types.ScheduledTaskNames.StoreCommitmentsExternal,
22
- types.ScheduledTaskStatus.Completed
23
- );
24
- const taskID = await this.providerDB.createScheduledTaskStatus(
25
- types.ScheduledTaskNames.StoreCommitmentsExternal,
26
- types.ScheduledTaskStatus.Running
27
- );
28
- try {
29
- let commitments = await this.providerDB.getUnstoredDappUserCommitments();
30
- let powRecords = await this.providerDB.getUnstoredDappUserPoWCommitments();
31
- if (lastTask) {
32
- this.logger.info(
33
- `Filtering records to only get updated records: ${JSON.stringify(lastTask)}`
34
- );
35
- this.logger.info(
36
- "Last task ran at ",
37
- new Date(lastTask.updated || 0),
38
- "Task ID",
39
- taskID
40
- );
41
- commitments = commitments.filter(
42
- (commitment) => lastTask.updated && commitment.lastUpdatedTimestamp && (commitment.lastUpdatedTimestamp > lastTask.updated || !commitment.lastUpdatedTimestamp)
43
- );
44
- powRecords = powRecords.filter((commitment) => {
45
- return lastTask.updated && commitment.lastUpdatedTimestamp && // either the update stamp is more recent than the last time this task ran or there is no update stamp,
46
- // so it is a new record
47
- (commitment.lastUpdatedTimestamp > lastTask.updated || !commitment.lastUpdatedTimestamp);
48
- });
49
- }
50
- if (commitments.length || powRecords.length) {
51
- this.logger.info(
52
- `Storing ${commitments.length} commitments externally`
53
- );
54
- this.logger.info(
55
- `Storing ${powRecords.length} pow challenges externally`
56
- );
57
- const captchaDB = new database.CaptchaDatabase(
58
- this.config.mongoCaptchaUri,
59
- void 0,
60
- void 0,
61
- this.logger
62
- );
63
- await captchaDB.saveCaptchas(commitments, powRecords);
64
- await this.providerDB.markDappUserCommitmentsStored(
65
- commitments.map((commitment) => commitment.id)
66
- );
67
- await this.providerDB.markDappUserPoWCommitmentsStored(
68
- powRecords.map((powRecords2) => powRecords2.challenge)
69
- );
70
- }
71
- await this.providerDB.updateScheduledTaskStatus(
72
- taskID,
73
- types.ScheduledTaskStatus.Completed,
74
- {
75
- data: {
76
- commitments: commitments.map((c) => c.id),
77
- powRecords: powRecords.map((pr) => pr.challenge)
78
- }
79
- }
80
- );
81
- } catch (e) {
82
- this.logger.error(e);
83
- await this.providerDB.updateScheduledTaskStatus(
84
- taskID,
85
- types.ScheduledTaskStatus.Failed,
86
- { error: String(e) }
87
- );
88
- }
89
- }
90
- /**
91
- * @description Get a list of client accounts and their settings from the client database
92
- * @returns Promise<void>
93
- */
94
- async getClientList() {
95
- if (!this.config.mongoClientUri) {
96
- this.logger.info("Mongo env not set");
97
- return;
98
- }
99
- const lastTask = await this.providerDB.getLastScheduledTaskStatus(
100
- types.ScheduledTaskNames.GetClientList,
101
- types.ScheduledTaskStatus.Completed
102
- );
103
- const taskID = await this.providerDB.createScheduledTaskStatus(
104
- types.ScheduledTaskNames.GetClientList,
105
- types.ScheduledTaskStatus.Running
106
- );
107
- try {
108
- const clientDB = new database.ClientDatabase(
109
- this.config.mongoClientUri,
110
- void 0,
111
- // expected to come from URI
112
- void 0,
113
- // expected to come from URI
114
- this.logger
115
- );
116
- const updatedAtTimestamp = lastTask ? lastTask.updated || 0 : 0;
117
- console.log("updatedAtTimestamp", updatedAtTimestamp);
118
- const newClientRecords = await clientDB.getUpdatedClients(updatedAtTimestamp);
119
- if (newClientRecords) {
120
- await this.providerDB.updateClientRecords(newClientRecords);
121
- }
122
- await this.providerDB.updateScheduledTaskStatus(
123
- taskID,
124
- types.ScheduledTaskStatus.Completed,
125
- {
126
- data: {
127
- clientRecords: newClientRecords.map((c) => c.account)
128
- }
129
- }
130
- );
131
- } catch (e) {
132
- this.logger.error(e);
133
- await this.providerDB.updateScheduledTaskStatus(
134
- taskID,
135
- types.ScheduledTaskStatus.Failed,
136
- { error: String(e) }
137
- );
138
- }
139
- }
140
- async registerSiteKey(siteKey) {
141
- await this.providerDB.updateClientRecords([
142
- {
143
- account: siteKey
144
- }
145
- ]);
146
- }
147
- }
148
- exports.ClientTaskManager = ClientTaskManager;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const datasets = require("@prosopo/datasets");
4
- const datasetTasksUtils = require("./datasetTasksUtils.cjs");
5
- class DatasetManager {
6
- constructor(config, logger, captchaConfig, db) {
7
- this.config = config;
8
- this.logger = logger;
9
- this.captchaConfig = captchaConfig;
10
- this.db = db;
11
- }
12
- /**
13
- * @description Set the provider dataset from a file
14
- *
15
- * @param file JSON of the captcha dataset
16
- */
17
- async providerSetDatasetFromFile(file) {
18
- const datasetRaw = datasets.parseCaptchaDataset(file);
19
- return await this.providerSetDataset(datasetRaw);
20
- }
21
- async providerSetDataset(datasetRaw) {
22
- const dataset = await datasetTasksUtils.providerValidateDataset(
23
- datasetRaw,
24
- this.captchaConfig.solved.count,
25
- this.captchaConfig.unsolved.count
26
- );
27
- await this.db?.storeDataset(dataset);
28
- }
29
- }
30
- exports.DatasetManager = DatasetManager;
@@ -1,34 +0,0 @@
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;
@@ -1,281 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const util$1 = require("@polkadot/util");
4
- const utilCrypto = require("@polkadot/util-crypto");
5
- const common = require("@prosopo/common");
6
- const datasets = require("@prosopo/datasets");
7
- const types = require("@prosopo/types");
8
- const util$2 = require("@prosopo/util");
9
- const util = require("../../util.cjs");
10
- const imgCaptchaTasksUtils = require("./imgCaptchaTasksUtils.cjs");
11
- class ImgCaptchaManager {
12
- constructor(db, pair, logger, captchaConfig) {
13
- this.db = db;
14
- this.pair = pair;
15
- this.logger = logger;
16
- this.captchaConfig = captchaConfig;
17
- }
18
- async getCaptchaWithProof(datasetId, solved, size) {
19
- const captchaDocs = await this.db.getRandomCaptcha(solved, datasetId, size);
20
- if (!captchaDocs) {
21
- throw new common.ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED", {
22
- context: {
23
- failedFuncName: this.getCaptchaWithProof.name,
24
- datasetId,
25
- solved,
26
- size
27
- }
28
- });
29
- }
30
- return captchaDocs;
31
- }
32
- async getRandomCaptchasAndRequestHash(datasetId, userAccount, ipAddress, headers) {
33
- const dataset = await this.db.getDatasetDetails(datasetId);
34
- if (!dataset) {
35
- throw new common.ProsopoEnvError("DATABASE.DATASET_GET_FAILED", {
36
- context: {
37
- failedFuncName: this.getRandomCaptchasAndRequestHash.name,
38
- dataset,
39
- datasetId
40
- }
41
- });
42
- }
43
- const unsolvedCount = Math.abs(
44
- Math.trunc(this.captchaConfig.unsolved.count)
45
- );
46
- const solvedCount = Math.abs(
47
- Math.trunc(this.captchaConfig.solved.count)
48
- );
49
- if (!solvedCount) {
50
- throw new common.ProsopoEnvError("CONFIG.INVALID_CAPTCHA_NUMBER");
51
- }
52
- const solved = await this.getCaptchaWithProof(datasetId, true, solvedCount);
53
- let unsolved = [];
54
- if (unsolvedCount) {
55
- unsolved = await this.getCaptchaWithProof(
56
- datasetId,
57
- false,
58
- unsolvedCount
59
- );
60
- }
61
- const captchas = util.shuffleArray([...solved, ...unsolved]);
62
- const salt = utilCrypto.randomAsHex();
63
- const requestHash = datasets.computePendingRequestHash(
64
- captchas.map((c) => c.captchaId),
65
- userAccount,
66
- salt
67
- );
68
- const currentTime = Date.now();
69
- const signedRequestHash = util$1.u8aToHex(
70
- this.pair.sign(util$1.stringToHex(requestHash))
71
- );
72
- const timeLimit = captchas.map((captcha) => captcha.timeLimitMs || types.DEFAULT_IMAGE_CAPTCHA_TIMEOUT).reduce((a, b) => a + b, 0);
73
- const deadlineTs = timeLimit + currentTime;
74
- const currentBlockNumber = 0;
75
- await this.db.storeDappUserPending(
76
- userAccount,
77
- requestHash,
78
- salt,
79
- deadlineTs,
80
- currentTime,
81
- ipAddress,
82
- headers
83
- );
84
- return {
85
- captchas,
86
- requestHash,
87
- timestamp: currentTime,
88
- signedRequestHash
89
- };
90
- }
91
- /**
92
- * Validate and store the text captcha solution(s) from the Dapp User in a web2 environment
93
- * @param {string} userAccount
94
- * @param {string} dappAccount
95
- * @param {string} requestHash
96
- * @param {JSON} captchas
97
- * @param {string} userRequestHashSignature
98
- * @param timestamp
99
- * @param providerRequestHashSignature
100
- * @param ipAddress
101
- * @param headers
102
- * @return {Promise<DappUserSolutionResult>} result containing the contract event
103
- */
104
- async dappUserSolution(userAccount, dappAccount, requestHash, captchas, userRequestHashSignature, timestamp, providerRequestHashSignature, ipAddress, headers) {
105
- const verification = utilCrypto.signatureVerify(
106
- util$1.stringToHex(requestHash),
107
- userRequestHashSignature,
108
- userAccount
109
- );
110
- if (!verification.isValid) {
111
- this.logger.info("Invalid user requestHash signature");
112
- throw new common.ProsopoEnvError("GENERAL.INVALID_SIGNATURE", {
113
- context: { failedFuncName: this.dappUserSolution.name, userAccount }
114
- });
115
- }
116
- const providerRequestHashSignatureVerify = utilCrypto.signatureVerify(
117
- util$1.stringToHex(requestHash.toString()),
118
- providerRequestHashSignature,
119
- this.pair.address
120
- );
121
- if (!providerRequestHashSignatureVerify.isValid) {
122
- this.logger.info("Invalid provider requestHash signature");
123
- throw new common.ProsopoEnvError("GENERAL.INVALID_SIGNATURE", {
124
- context: {
125
- failedFuncName: this.dappUserSolution.name,
126
- userAccount,
127
- error: "requestHash signature is invalid"
128
- }
129
- });
130
- }
131
- let response = {
132
- captchas: [],
133
- verified: false
134
- };
135
- const pendingRecord = await this.db.getDappUserPending(requestHash);
136
- const unverifiedCaptchaIds = captchas.map((captcha) => captcha.captchaId);
137
- const pendingRequest = await this.validateDappUserSolutionRequestIsPending(
138
- requestHash,
139
- pendingRecord,
140
- userAccount,
141
- unverifiedCaptchaIds
142
- );
143
- if (pendingRequest) {
144
- const { storedCaptchas, receivedCaptchas, captchaIds } = await this.validateReceivedCaptchasAgainstStoredCaptchas(captchas);
145
- const { tree, commitmentId } = imgCaptchaTasksUtils.buildTreeAndGetCommitmentId(receivedCaptchas);
146
- const datasetId = util$2.at(storedCaptchas, 0).datasetId;
147
- if (!datasetId) {
148
- throw new common.ProsopoEnvError("CAPTCHA.ID_MISMATCH", {
149
- context: { failedFuncName: this.dappUserSolution.name }
150
- });
151
- }
152
- await this.db.updateDappUserPendingStatus(requestHash);
153
- const commit = {
154
- id: commitmentId,
155
- userAccount,
156
- dappAccount,
157
- providerAccount: this.pair.address,
158
- datasetId,
159
- result: { status: types.CaptchaStatus.pending },
160
- userSignature: userRequestHashSignature,
161
- userSubmitted: true,
162
- serverChecked: false,
163
- requestedAtTimestamp: timestamp,
164
- ipAddress,
165
- headers
166
- };
167
- await this.db.storeDappUserSolution(receivedCaptchas, commit);
168
- if (datasets.compareCaptchaSolutions(receivedCaptchas, storedCaptchas)) {
169
- response = {
170
- captchas: captchaIds.map((id) => ({
171
- captchaId: id,
172
- proof: tree.proof(id)
173
- })),
174
- verified: true
175
- };
176
- await this.db.approveDappUserCommitment(commitmentId);
177
- } else {
178
- await this.db.disapproveDappUserCommitment(
179
- commitmentId,
180
- "CAPTCHA.INVALID_SOLUTION"
181
- );
182
- response = {
183
- captchas: captchaIds.map((id) => ({
184
- captchaId: id,
185
- proof: [[]]
186
- })),
187
- verified: false
188
- };
189
- }
190
- } else {
191
- this.logger.info("Request hash not found");
192
- }
193
- return response;
194
- }
195
- /**
196
- * Validate length of received captchas array matches length of captchas found in database
197
- * Validate that the datasetId is the same for all captchas and is equal to the datasetId on the stored captchas
198
- */
199
- async validateReceivedCaptchasAgainstStoredCaptchas(captchas) {
200
- const receivedCaptchas = datasets.parseAndSortCaptchaSolutions(captchas);
201
- const captchaIds = receivedCaptchas.map((captcha) => captcha.captchaId);
202
- const storedCaptchas = await this.db.getCaptchaById(captchaIds);
203
- if (!storedCaptchas || receivedCaptchas.length !== storedCaptchas.length) {
204
- throw new common.ProsopoEnvError("CAPTCHA.INVALID_CAPTCHA_ID", {
205
- context: {
206
- failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
207
- captchas
208
- }
209
- });
210
- }
211
- if (!storedCaptchas.every(
212
- (captcha) => captcha.datasetId === util$2.at(storedCaptchas, 0).datasetId
213
- )) {
214
- throw new common.ProsopoEnvError("CAPTCHA.DIFFERENT_DATASET_IDS", {
215
- context: {
216
- failedFuncName: this.validateReceivedCaptchasAgainstStoredCaptchas.name,
217
- captchas
218
- }
219
- });
220
- }
221
- return { storedCaptchas, receivedCaptchas, captchaIds };
222
- }
223
- /**
224
- * Validate that a Dapp User is responding to their own pending captcha request
225
- * @param {string} requestHash
226
- * @param {PendingCaptchaRequest} pendingRecord
227
- * @param {string} userAccount
228
- * @param {string[]} captchaIds
229
- */
230
- async validateDappUserSolutionRequestIsPending(requestHash, pendingRecord, userAccount, captchaIds) {
231
- const currentTime = Date.now();
232
- if (!pendingRecord) {
233
- this.logger.info("No pending record found");
234
- return false;
235
- }
236
- if (pendingRecord.deadlineTimestamp < currentTime) {
237
- this.logger.info("Deadline for responding to captcha has expired");
238
- return false;
239
- }
240
- if (pendingRecord) {
241
- const pendingHashComputed = datasets.computePendingRequestHash(
242
- captchaIds,
243
- userAccount,
244
- pendingRecord.salt
245
- );
246
- return requestHash === pendingHashComputed;
247
- }
248
- return false;
249
- }
250
- /*
251
- * Get dapp user solution from database
252
- */
253
- async getDappUserCommitmentById(commitmentId) {
254
- const dappUserSolution = await this.db.getDappUserCommitmentById(commitmentId);
255
- if (!dappUserSolution) {
256
- throw new common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", {
257
- context: {
258
- failedFuncName: this.getDappUserCommitmentById.name,
259
- commitmentId
260
- }
261
- });
262
- }
263
- return dappUserSolution;
264
- }
265
- /* Check if dapp user has verified solution in cache */
266
- async getDappUserCommitmentByAccount(userAccount, dappAccount) {
267
- const dappUserSolutions = await this.db.getDappUserCommitmentByAccount(
268
- userAccount,
269
- dappAccount
270
- );
271
- if (dappUserSolutions.length > 0) {
272
- for (const dappUserSolution of dappUserSolutions) {
273
- if (dappUserSolution.result.status === types.CaptchaStatus.approved) {
274
- return dappUserSolution;
275
- }
276
- }
277
- }
278
- return void 0;
279
- }
280
- }
281
- exports.ImgCaptchaManager = ImgCaptchaManager;
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const common = require("@prosopo/common");
4
- const datasets = require("@prosopo/datasets");
5
- const buildTreeAndGetCommitmentId = (captchaSolutions) => {
6
- const tree = new datasets.CaptchaMerkleTree();
7
- const solutionsHashed = captchaSolutions.map(
8
- (captcha) => datasets.computeCaptchaSolutionHash(captcha)
9
- );
10
- tree.build(solutionsHashed);
11
- const commitmentId = tree.root?.hash;
12
- if (!commitmentId) {
13
- throw new common.ProsopoEnvError(
14
- "CONTRACT.CAPTCHA_SOLUTION_COMMITMENT_DOES_NOT_EXIST",
15
- {
16
- context: {
17
- failedFuncName: buildTreeAndGetCommitmentId.name,
18
- commitmentId
19
- }
20
- }
21
- );
22
- }
23
- return { tree, commitmentId };
24
- };
25
- exports.buildTreeAndGetCommitmentId = buildTreeAndGetCommitmentId;
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const tasks = require("./tasks.cjs");
4
- exports.Tasks = tasks.Tasks;
@@ -1,133 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const util = require("@polkadot/util");
4
- const common = require("@prosopo/common");
5
- const types = require("@prosopo/types");
6
- const util$1 = require("@prosopo/util");
7
- const powTasksUtils = require("./powTasksUtils.cjs");
8
- const logger = common.getLoggerDefault();
9
- class PowCaptchaManager {
10
- constructor(pair, db) {
11
- this.pair = pair;
12
- this.db = db;
13
- this.POW_SEPARATOR = types.POW_SEPARATOR;
14
- }
15
- /**
16
- * @description Generates a PoW Captcha for a given user and dapp
17
- *
18
- * @param {string} userAccount - user that is solving the captcha
19
- * @param {string} dappAccount - dapp that is requesting the captcha
20
- * @param origin - not currently used
21
- */
22
- async getPowCaptchaChallenge(userAccount, dappAccount, origin) {
23
- const difficulty = 4;
24
- const requestedAtTimestamp = Date.now();
25
- const challenge = `${requestedAtTimestamp}___${userAccount}___${dappAccount}`;
26
- const challengeSignature = util.u8aToHex(this.pair.sign(util.stringToHex(challenge)));
27
- return {
28
- challenge,
29
- difficulty,
30
- providerSignature: challengeSignature,
31
- requestedAtTimestamp
32
- };
33
- }
34
- /**
35
- * @description Verifies a PoW Captcha for a given user and dapp
36
- *
37
- * @param {string} challenge - the starting string for the PoW challenge
38
- * @param {string} difficulty - how many leading zeroes the solution must have
39
- * @param {string} providerChallengeSignature - proof that the Provider provided the challenge
40
- * @param {string} nonce - the string that the user has found that satisfies the PoW challenge
41
- * @param {number} timeout - the time in milliseconds since the Provider was selected to provide the PoW captcha
42
- * @param {string} userTimestampSignature
43
- * @param ipAddress
44
- * @param headers
45
- */
46
- async verifyPowCaptchaSolution(challenge, difficulty, providerChallengeSignature, nonce, timeout, userTimestampSignature, ipAddress, headers) {
47
- powTasksUtils.checkPowSignature(
48
- challenge,
49
- providerChallengeSignature,
50
- this.pair.address,
51
- types.ApiParams.challenge
52
- );
53
- const challengeSplit = challenge.split(this.POW_SEPARATOR);
54
- const timestamp = Number.parseInt(util$1.at(challengeSplit, 0));
55
- const userAccount = util$1.at(challengeSplit, 1);
56
- powTasksUtils.checkPowSignature(
57
- timestamp.toString(),
58
- userTimestampSignature,
59
- userAccount,
60
- types.ApiParams.timestamp
61
- );
62
- const challengeRecord = await this.db.getPowCaptchaRecordByChallenge(challenge);
63
- if (!challengeRecord) {
64
- logger.debug("No record of this challenge");
65
- return false;
66
- }
67
- if (!util$1.verifyRecency(challenge, timeout)) {
68
- await this.db.updatePowCaptchaRecord(
69
- challenge,
70
- {
71
- status: types.CaptchaStatus.disapproved,
72
- reason: "CAPTCHA.INVALID_TIMESTAMP"
73
- },
74
- false,
75
- true,
76
- userTimestampSignature
77
- );
78
- return false;
79
- }
80
- const correct = powTasksUtils.validateSolution(nonce, challenge, difficulty);
81
- let result = { status: types.CaptchaStatus.approved };
82
- if (!correct) {
83
- result = {
84
- status: types.CaptchaStatus.disapproved,
85
- reason: "CAPTCHA.INVALID_SOLUTION"
86
- };
87
- }
88
- await this.db.updatePowCaptchaRecord(
89
- challenge,
90
- result,
91
- false,
92
- true,
93
- userTimestampSignature
94
- );
95
- return correct;
96
- }
97
- /**
98
- * @description Verifies a PoW Captcha for a given user and dapp. This is called by the server to verify the user's solution
99
- * and update the record in the database to show that the user has solved the captcha
100
- *
101
- * @param {string} dappAccount - the dapp that is requesting the captcha
102
- * @param {string} challenge - the starting string for the PoW challenge
103
- * @param {number} timeout - the time in milliseconds since the Provider was selected to provide the PoW captcha
104
- */
105
- async serverVerifyPowCaptchaSolution(dappAccount, challenge, timeout) {
106
- const challengeRecord = await this.db.getPowCaptchaRecordByChallenge(challenge);
107
- if (!challengeRecord) {
108
- throw new common.ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED", {
109
- context: {
110
- failedFuncName: this.serverVerifyPowCaptchaSolution.name,
111
- challenge
112
- }
113
- });
114
- }
115
- if (challengeRecord.serverChecked) return false;
116
- const challengeDappAccount = challengeRecord.dappAccount;
117
- if (dappAccount !== challengeDappAccount) {
118
- throw new common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", {
119
- context: {
120
- failedFuncName: this.serverVerifyPowCaptchaSolution.name,
121
- dappAccount,
122
- challengeDappAccount
123
- }
124
- });
125
- }
126
- util$1.verifyRecency(challenge, timeout);
127
- await this.db.markDappUserPoWCommitmentsChecked([
128
- challengeRecord.challenge
129
- ]);
130
- return true;
131
- }
132
- }
133
- exports.PowCaptchaManager = PowCaptchaManager;