@prosopo/database 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/dist/captchaDatabase/captchaDatabase.d.ts +4 -0
- package/dist/captchaDatabase/captchaDatabase.d.ts.map +1 -0
- package/dist/captchaDatabase/captchaDatabase.js +31 -0
- package/dist/captchaDatabase/captchaDatabase.js.map +1 -0
- package/dist/captchaDatabase/index.d.ts +2 -0
- package/dist/captchaDatabase/index.d.ts.map +1 -0
- package/dist/captchaDatabase/index.js +2 -0
- package/dist/captchaDatabase/index.js.map +1 -0
- package/dist/cjs/captchaDatabase/captchaDatabase.cjs +37 -0
- package/dist/cjs/captchaDatabase/index.cjs +4 -0
- package/dist/cjs/databases/mongo.cjs +189 -67
- package/dist/cjs/databases/mongoMemory.cjs +1 -1
- package/dist/cjs/index.cjs +3 -0
- package/dist/databases/index.d.ts +2 -2
- package/dist/databases/index.d.ts.map +1 -1
- package/dist/databases/index.js +3 -3
- package/dist/databases/index.js.map +1 -1
- package/dist/databases/mongo.d.ts +10 -7
- package/dist/databases/mongo.d.ts.map +1 -1
- package/dist/databases/mongo.js +200 -119
- package/dist/databases/mongo.js.map +1 -1
- package/dist/databases/mongoMemory.d.ts +2 -2
- package/dist/databases/mongoMemory.d.ts.map +1 -1
- package/dist/databases/mongoMemory.js +2 -2
- package/dist/databases/mongoMemory.js.map +1 -1
- package/dist/eventsDatabase/eventsDatabase.d.ts +1 -1
- package/dist/eventsDatabase/eventsDatabase.d.ts.map +1 -1
- package/dist/eventsDatabase/eventsDatabase.js +8 -6
- package/dist/eventsDatabase/eventsDatabase.js.map +1 -1
- package/dist/eventsDatabase/index.d.ts +1 -1
- package/dist/eventsDatabase/index.d.ts.map +1 -1
- package/dist/eventsDatabase/index.js +1 -1
- package/dist/eventsDatabase/index.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +44 -53
- package/vite.cjs.config.ts +3 -3
- package/typedoc.config.js +0 -19
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type UserCommitmentRecord } from "@prosopo/types-database";
|
|
2
|
+
import { PowCaptcha } from "@prosopo/types";
|
|
3
|
+
export declare const saveCaptchas: (imageCaptchaEvents: UserCommitmentRecord[], powCaptchaEvents: PowCaptcha[], atlasUri: string) => Promise<void>;
|
|
4
|
+
//# sourceMappingURL=captchaDatabase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captchaDatabase.d.ts","sourceRoot":"","sources":["../../src/captchaDatabase/captchaDatabase.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAM5C,eAAO,MAAM,YAAY,uBACH,oBAAoB,EAAE,oBACxB,UAAU,EAAE,YACpB,MAAM,kBA+BjB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getLoggerDefault } from "@prosopo/common";
|
|
2
|
+
import { PowCaptchaRecordSchema, UserCommitmentRecordSchema, } from "@prosopo/types-database";
|
|
3
|
+
import mongoose from "mongoose";
|
|
4
|
+
const logger = getLoggerDefault();
|
|
5
|
+
let StoredImageCaptcha;
|
|
6
|
+
let StoredPoWCaptcha;
|
|
7
|
+
export const saveCaptchas = async (imageCaptchaEvents, powCaptchaEvents, atlasUri) => {
|
|
8
|
+
const connection = mongoose.createConnection(atlasUri, {
|
|
9
|
+
authSource: "admin",
|
|
10
|
+
});
|
|
11
|
+
await new Promise((resolve, reject) => {
|
|
12
|
+
connection
|
|
13
|
+
.once("open", () => {
|
|
14
|
+
logger.info("Connected to MongoDB Atlas");
|
|
15
|
+
StoredImageCaptcha = connection.model("StoredImageCaptcha", UserCommitmentRecordSchema);
|
|
16
|
+
StoredPoWCaptcha = connection.model("StoredPoWCaptcha", PowCaptchaRecordSchema);
|
|
17
|
+
resolve();
|
|
18
|
+
})
|
|
19
|
+
.on("error", reject);
|
|
20
|
+
});
|
|
21
|
+
if (imageCaptchaEvents.length) {
|
|
22
|
+
await StoredImageCaptcha.insertMany(imageCaptchaEvents);
|
|
23
|
+
logger.info("Mongo Saved Image Events");
|
|
24
|
+
}
|
|
25
|
+
if (powCaptchaEvents.length) {
|
|
26
|
+
await StoredPoWCaptcha.insertMany(powCaptchaEvents);
|
|
27
|
+
logger.info("Mongo Saved PoW Events");
|
|
28
|
+
}
|
|
29
|
+
await connection.close();
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=captchaDatabase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captchaDatabase.js","sourceRoot":"","sources":["../../src/captchaDatabase/captchaDatabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAcnD,OAAO,EACL,sBAAsB,EAEtB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;AAElC,IAAI,kBAAwD,CAAC;AAC7D,IAAI,gBAA4C,CAAC;AAEjD,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,kBAA0C,EAC1C,gBAA8B,EAC9B,QAAgB,EAChB,EAAE;IACF,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE;QACrD,UAAU,EAAE,OAAO;KACpB,CAAC,CAAC;IACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,UAAU;aACP,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;YACjB,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YAC1C,kBAAkB,GAAG,UAAU,CAAC,KAAK,CACnC,oBAAoB,EACpB,0BAA0B,CAC3B,CAAC;YACF,gBAAgB,GAAG,UAAU,CAAC,KAAK,CACjC,kBAAkB,EAClB,sBAAsB,CACvB,CAAC;YACF,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;aACD,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,IAAI,kBAAkB,CAAC,MAAM,EAAE;QAC7B,MAAM,kBAAkB,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;KACzC;IACD,IAAI,gBAAgB,CAAC,MAAM,EAAE;QAC3B,MAAM,gBAAgB,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;KACvC;IAED,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;AAC3B,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/captchaDatabase/index.ts"],"names":[],"mappings":"AAaA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/captchaDatabase/index.ts"],"names":[],"mappings":"AAaA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@prosopo/common");
|
|
4
|
+
const typesDatabase = require("@prosopo/types-database");
|
|
5
|
+
const mongoose = require("mongoose");
|
|
6
|
+
const logger = common.getLoggerDefault();
|
|
7
|
+
let StoredImageCaptcha;
|
|
8
|
+
let StoredPoWCaptcha;
|
|
9
|
+
const saveCaptchas = async (imageCaptchaEvents, powCaptchaEvents, atlasUri) => {
|
|
10
|
+
const connection = mongoose.createConnection(atlasUri, {
|
|
11
|
+
authSource: "admin"
|
|
12
|
+
});
|
|
13
|
+
await new Promise((resolve, reject) => {
|
|
14
|
+
connection.once("open", () => {
|
|
15
|
+
logger.info("Connected to MongoDB Atlas");
|
|
16
|
+
StoredImageCaptcha = connection.model(
|
|
17
|
+
"StoredImageCaptcha",
|
|
18
|
+
typesDatabase.UserCommitmentRecordSchema
|
|
19
|
+
);
|
|
20
|
+
StoredPoWCaptcha = connection.model(
|
|
21
|
+
"StoredPoWCaptcha",
|
|
22
|
+
typesDatabase.PowCaptchaRecordSchema
|
|
23
|
+
);
|
|
24
|
+
resolve();
|
|
25
|
+
}).on("error", reject);
|
|
26
|
+
});
|
|
27
|
+
if (imageCaptchaEvents.length) {
|
|
28
|
+
await StoredImageCaptcha.insertMany(imageCaptchaEvents);
|
|
29
|
+
logger.info("Mongo Saved Image Events");
|
|
30
|
+
}
|
|
31
|
+
if (powCaptchaEvents.length) {
|
|
32
|
+
await StoredPoWCaptcha.insertMany(powCaptchaEvents);
|
|
33
|
+
logger.info("Mongo Saved PoW Events");
|
|
34
|
+
}
|
|
35
|
+
await connection.close();
|
|
36
|
+
};
|
|
37
|
+
exports.saveCaptchas = saveCaptchas;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const is = require("@polkadot/util/is");
|
|
3
4
|
const common = require("@prosopo/common");
|
|
4
5
|
const types = require("@prosopo/types");
|
|
5
6
|
const typesDatabase = require("@prosopo/types-database");
|
|
6
|
-
const typesReturns = require("@prosopo/captcha-contract/types-returns");
|
|
7
7
|
const mongodb = require("mongodb");
|
|
8
|
-
const is = require("@polkadot/util/is");
|
|
9
8
|
const mongoose = require("mongoose");
|
|
10
9
|
mongoose.set("strictQuery", false);
|
|
11
10
|
const DEFAULT_ENDPOINT = "mongodb://127.0.0.1:27017";
|
|
@@ -50,7 +49,9 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
50
49
|
* @description Connect to the database and set the various tables
|
|
51
50
|
*/
|
|
52
51
|
async connect() {
|
|
53
|
-
this.logger.info(
|
|
52
|
+
this.logger.info(
|
|
53
|
+
`Mongo url: ${this.url.replace(/\w+:\w+/, "<Credentials>")}`
|
|
54
|
+
);
|
|
54
55
|
this.connection = await new Promise((resolve, reject) => {
|
|
55
56
|
const connection = mongoose.createConnection(this.url, {
|
|
56
57
|
dbName: this.dbname,
|
|
@@ -66,12 +67,14 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
66
67
|
});
|
|
67
68
|
connection.on("connected", () => {
|
|
68
69
|
this.logger.info(`Database connected to ${this.url}`);
|
|
70
|
+
resolve(connection);
|
|
69
71
|
});
|
|
70
72
|
connection.on("disconnected", () => {
|
|
71
73
|
this.logger.info(`Database disconnected from ${this.url}`);
|
|
72
74
|
});
|
|
73
75
|
connection.on("reconnected", () => {
|
|
74
76
|
this.logger.info(`Database reconnected to ${this.url}`);
|
|
77
|
+
resolve(connection);
|
|
75
78
|
});
|
|
76
79
|
connection.on("reconnectFailed", () => {
|
|
77
80
|
this.logger.error(`Database reconnect failed to ${this.url}`);
|
|
@@ -81,6 +84,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
81
84
|
});
|
|
82
85
|
connection.on("fullsetup", () => {
|
|
83
86
|
this.logger.info(`Database connection to ${this.url} is fully setup`);
|
|
87
|
+
resolve(connection);
|
|
84
88
|
});
|
|
85
89
|
});
|
|
86
90
|
this.tables = {
|
|
@@ -88,8 +92,14 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
88
92
|
powCaptcha: this.connection.model("PowCaptcha", typesDatabase.PowCaptchaRecordSchema),
|
|
89
93
|
dataset: this.connection.model("Dataset", typesDatabase.DatasetRecordSchema),
|
|
90
94
|
solution: this.connection.model("Solution", typesDatabase.SolutionRecordSchema),
|
|
91
|
-
commitment: this.connection.model(
|
|
92
|
-
|
|
95
|
+
commitment: this.connection.model(
|
|
96
|
+
"UserCommitment",
|
|
97
|
+
typesDatabase.UserCommitmentRecordSchema
|
|
98
|
+
),
|
|
99
|
+
usersolution: this.connection.model(
|
|
100
|
+
"UserSolution",
|
|
101
|
+
typesDatabase.UserSolutionRecordSchema
|
|
102
|
+
),
|
|
93
103
|
pending: this.connection.model("Pending", typesDatabase.PendingRecordSchema),
|
|
94
104
|
scheduler: this.connection.model("Scheduler", typesDatabase.ScheduledTaskRecordSchema)
|
|
95
105
|
};
|
|
@@ -105,7 +115,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
105
115
|
*/
|
|
106
116
|
async storeDataset(dataset) {
|
|
107
117
|
try {
|
|
108
|
-
this.logger.debug(
|
|
118
|
+
this.logger.debug("Storing dataset in database");
|
|
109
119
|
const parsedDataset = types.DatasetWithIdsAndTreeSchema.parse(dataset);
|
|
110
120
|
const datasetDoc = {
|
|
111
121
|
datasetId: parsedDataset.datasetId,
|
|
@@ -119,14 +129,16 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
119
129
|
{ $set: datasetDoc },
|
|
120
130
|
{ upsert: true }
|
|
121
131
|
);
|
|
122
|
-
const captchaDocs = parsedDataset.captchas.map(
|
|
123
|
-
...captcha,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
const captchaDocs = parsedDataset.captchas.map(
|
|
133
|
+
({ solution, ...captcha }, index) => ({
|
|
134
|
+
...captcha,
|
|
135
|
+
datasetId: parsedDataset.datasetId,
|
|
136
|
+
datasetContentId: parsedDataset.datasetContentId,
|
|
137
|
+
index,
|
|
138
|
+
solved: !!solution?.length
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
this.logger.debug("Inserting captcha records");
|
|
130
142
|
if (captchaDocs.length) {
|
|
131
143
|
await this.tables?.captcha.bulkWrite(
|
|
132
144
|
captchaDocs.map((captchaDoc) => ({
|
|
@@ -146,7 +158,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
146
158
|
datasetId: parsedDataset.datasetId,
|
|
147
159
|
datasetContentId: parsedDataset.datasetContentId
|
|
148
160
|
}));
|
|
149
|
-
this.logger.debug(
|
|
161
|
+
this.logger.debug("Inserting solution records");
|
|
150
162
|
if (captchaSolutionDocs.length) {
|
|
151
163
|
await this.tables?.solution.bulkWrite(
|
|
152
164
|
captchaSolutionDocs.map((captchaSolutionDoc) => ({
|
|
@@ -158,7 +170,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
158
170
|
}))
|
|
159
171
|
);
|
|
160
172
|
}
|
|
161
|
-
this.logger.debug(
|
|
173
|
+
this.logger.debug("Dataset stored in database");
|
|
162
174
|
} catch (err) {
|
|
163
175
|
throw new common.ProsopoDBError("DATABASE.DATASET_LOAD_FAILED", {
|
|
164
176
|
context: { failedFuncName: this.storeDataset.name, error: err },
|
|
@@ -239,11 +251,16 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
239
251
|
}
|
|
240
252
|
]);
|
|
241
253
|
const docs = await cursor;
|
|
242
|
-
if (docs
|
|
254
|
+
if (docs?.length) {
|
|
243
255
|
return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
|
|
244
256
|
}
|
|
245
257
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
246
|
-
context: {
|
|
258
|
+
context: {
|
|
259
|
+
failedFuncName: this.getRandomCaptcha.name,
|
|
260
|
+
solved,
|
|
261
|
+
datasetId,
|
|
262
|
+
size
|
|
263
|
+
}
|
|
247
264
|
});
|
|
248
265
|
}
|
|
249
266
|
/**
|
|
@@ -253,7 +270,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
253
270
|
async getCaptchaById(captchaId) {
|
|
254
271
|
const cursor = this.tables?.captcha.find({ captchaId: { $in: captchaId } }).lean();
|
|
255
272
|
const docs = await cursor;
|
|
256
|
-
if (docs
|
|
273
|
+
if (docs?.length) {
|
|
257
274
|
return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
|
|
258
275
|
}
|
|
259
276
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
@@ -272,7 +289,11 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
272
289
|
});
|
|
273
290
|
}
|
|
274
291
|
try {
|
|
275
|
-
await this.tables?.captcha.updateOne(
|
|
292
|
+
await this.tables?.captcha.updateOne(
|
|
293
|
+
{ datasetId },
|
|
294
|
+
{ $set: captcha },
|
|
295
|
+
{ upsert: false }
|
|
296
|
+
);
|
|
276
297
|
} catch (err) {
|
|
277
298
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
278
299
|
context: { failedFuncName: this.getDatasetDetails.name, error: err }
|
|
@@ -299,7 +320,10 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
299
320
|
return doc;
|
|
300
321
|
}
|
|
301
322
|
throw new common.ProsopoDBError("DATABASE.DATASET_GET_FAILED", {
|
|
302
|
-
context: {
|
|
323
|
+
context: {
|
|
324
|
+
failedFuncName: this.getDatasetDetails.name,
|
|
325
|
+
datasetId
|
|
326
|
+
}
|
|
303
327
|
});
|
|
304
328
|
}
|
|
305
329
|
/**
|
|
@@ -337,25 +361,29 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
337
361
|
/**
|
|
338
362
|
* @description Adds a new PoW Captcha record to the database.
|
|
339
363
|
* @param {string} challenge The challenge string for the captcha.
|
|
364
|
+
* @param components The components of the PoW challenge.
|
|
340
365
|
* @param {boolean} checked Indicates if the captcha has been checked.
|
|
341
366
|
* @returns {Promise<void>} A promise that resolves when the record is added.
|
|
342
367
|
*/
|
|
343
|
-
async storePowCaptchaRecord(challenge, checked) {
|
|
344
|
-
|
|
345
|
-
throw new common.ProsopoEnvError("DATABASE.DATABASE_UNDEFINED", {
|
|
346
|
-
context: { failedFuncName: this.storePowCaptchaRecord.name },
|
|
347
|
-
logger: this.logger
|
|
348
|
-
});
|
|
349
|
-
}
|
|
368
|
+
async storePowCaptchaRecord(challenge, components, checked) {
|
|
369
|
+
const tables = this.getTables();
|
|
350
370
|
const powCaptchaRecord = {
|
|
351
371
|
challenge,
|
|
372
|
+
...components,
|
|
352
373
|
checked
|
|
353
374
|
};
|
|
354
375
|
try {
|
|
355
|
-
await
|
|
356
|
-
this.logger.info("PowCaptcha record added successfully", {
|
|
376
|
+
await tables.powCaptcha.create(powCaptchaRecord);
|
|
377
|
+
this.logger.info("PowCaptcha record added successfully", {
|
|
378
|
+
challenge,
|
|
379
|
+
checked
|
|
380
|
+
});
|
|
357
381
|
} catch (error) {
|
|
358
|
-
this.logger.error("Failed to add PowCaptcha record", {
|
|
382
|
+
this.logger.error("Failed to add PowCaptcha record", {
|
|
383
|
+
error,
|
|
384
|
+
challenge,
|
|
385
|
+
checked
|
|
386
|
+
});
|
|
359
387
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
360
388
|
context: { error, challenge, checked },
|
|
361
389
|
logger: this.logger
|
|
@@ -377,14 +405,18 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
377
405
|
try {
|
|
378
406
|
const record = await this.tables.powCaptcha.findOne({ challenge }).lean();
|
|
379
407
|
if (record) {
|
|
380
|
-
this.logger.info("PowCaptcha record retrieved successfully", {
|
|
408
|
+
this.logger.info("PowCaptcha record retrieved successfully", {
|
|
409
|
+
challenge
|
|
410
|
+
});
|
|
381
411
|
return record;
|
|
382
|
-
} else {
|
|
383
|
-
this.logger.info("No PowCaptcha record found", { challenge });
|
|
384
|
-
return null;
|
|
385
412
|
}
|
|
413
|
+
this.logger.info("No PowCaptcha record found", { challenge });
|
|
414
|
+
return null;
|
|
386
415
|
} catch (error) {
|
|
387
|
-
this.logger.error("Failed to retrieve PowCaptcha record", {
|
|
416
|
+
this.logger.error("Failed to retrieve PowCaptcha record", {
|
|
417
|
+
error,
|
|
418
|
+
challenge
|
|
419
|
+
});
|
|
388
420
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
389
421
|
context: { error, challenge },
|
|
390
422
|
logger: this.logger
|
|
@@ -398,25 +430,32 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
398
430
|
* @returns {Promise<void>} A promise that resolves when the record is updated.
|
|
399
431
|
*/
|
|
400
432
|
async updatePowCaptchaRecord(challenge, checked) {
|
|
401
|
-
|
|
402
|
-
throw new common.ProsopoEnvError("DATABASE.DATABASE_UNDEFINED", {
|
|
403
|
-
context: { failedFuncName: this.updatePowCaptchaRecord.name },
|
|
404
|
-
logger: this.logger
|
|
405
|
-
});
|
|
406
|
-
}
|
|
433
|
+
const tables = this.getTables();
|
|
407
434
|
try {
|
|
408
|
-
const updateResult = await
|
|
435
|
+
const updateResult = await tables.powCaptcha.updateOne(
|
|
436
|
+
{ challenge },
|
|
437
|
+
{ $set: { checked } }
|
|
438
|
+
);
|
|
409
439
|
if (updateResult.matchedCount === 0) {
|
|
410
|
-
this.logger.info("No PowCaptcha record found to update", {
|
|
440
|
+
this.logger.info("No PowCaptcha record found to update", {
|
|
441
|
+
challenge,
|
|
442
|
+
checked
|
|
443
|
+
});
|
|
411
444
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
412
445
|
context: { challenge, checked },
|
|
413
446
|
logger: this.logger
|
|
414
447
|
});
|
|
415
|
-
} else {
|
|
416
|
-
this.logger.info("PowCaptcha record updated successfully", { challenge, checked });
|
|
417
448
|
}
|
|
449
|
+
this.logger.info("PowCaptcha record updated successfully", {
|
|
450
|
+
challenge,
|
|
451
|
+
checked
|
|
452
|
+
});
|
|
418
453
|
} catch (error) {
|
|
419
|
-
this.logger.error("Failed to update PowCaptcha record", {
|
|
454
|
+
this.logger.error("Failed to update PowCaptcha record", {
|
|
455
|
+
error,
|
|
456
|
+
challenge,
|
|
457
|
+
checked
|
|
458
|
+
});
|
|
420
459
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
421
460
|
context: { error, challenge, checked },
|
|
422
461
|
logger: this.logger
|
|
@@ -441,6 +480,41 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
441
480
|
const docs = await this.tables?.commitment.find({ batched: false }).lean();
|
|
442
481
|
return docs ? docs.map((doc) => typesDatabase.UserCommitmentSchema.parse(doc)) : [];
|
|
443
482
|
}
|
|
483
|
+
/** @description Get Dapp User captcha commitments from the commitments table that have not been counted towards the
|
|
484
|
+
* client's total
|
|
485
|
+
*/
|
|
486
|
+
async getUnstoredDappUserCommitments() {
|
|
487
|
+
const docs = await this.tables?.commitment.find({
|
|
488
|
+
$or: [{ stored: false }, { stored: { $exists: false } }]
|
|
489
|
+
}).lean();
|
|
490
|
+
return docs ? docs.map((doc) => typesDatabase.UserCommitmentSchema.parse(doc)) : [];
|
|
491
|
+
}
|
|
492
|
+
/** @description Mark a list of captcha commits as stored
|
|
493
|
+
*/
|
|
494
|
+
async markDappUserCommitmentsStored(commitmentIds) {
|
|
495
|
+
await this.tables?.commitment.updateMany(
|
|
496
|
+
{ id: { $in: commitmentIds } },
|
|
497
|
+
{ $set: { stored: true } },
|
|
498
|
+
{ upsert: false }
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
/** @description Get Dapp User PoW captcha commitments that have not been counted towards the client's total
|
|
502
|
+
*/
|
|
503
|
+
async getUnstoredDappUserPoWCommitments() {
|
|
504
|
+
const docs = await this.tables?.powCaptcha.find({
|
|
505
|
+
$or: [{ stored: false }, { stored: { $exists: false } }]
|
|
506
|
+
}).lean();
|
|
507
|
+
return docs || [];
|
|
508
|
+
}
|
|
509
|
+
/** @description Mark a list of PoW captcha commits as stored
|
|
510
|
+
*/
|
|
511
|
+
async markDappUserPoWCommitmentsStored(challengeIds) {
|
|
512
|
+
await this.tables?.powCaptcha.updateMany(
|
|
513
|
+
{ challenge: { $in: challengeIds } },
|
|
514
|
+
{ $set: { stored: true } },
|
|
515
|
+
{ upsert: false }
|
|
516
|
+
);
|
|
517
|
+
}
|
|
444
518
|
/** @description Get Dapp User captcha commitments from the commitments table that have been batched on-chain
|
|
445
519
|
*/
|
|
446
520
|
async getBatchedDappUserCommitments() {
|
|
@@ -450,12 +524,18 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
450
524
|
/** @description Remove processed Dapp User captcha solutions from the user solution table
|
|
451
525
|
*/
|
|
452
526
|
async removeProcessedDappUserSolutions(commitmentIds) {
|
|
453
|
-
return await this.tables?.usersolution.deleteMany({
|
|
527
|
+
return await this.tables?.usersolution.deleteMany({
|
|
528
|
+
processed: true,
|
|
529
|
+
commitmentId: { $in: commitmentIds }
|
|
530
|
+
});
|
|
454
531
|
}
|
|
455
532
|
/** @description Remove processed Dapp User captcha commitments from the user commitments table
|
|
456
533
|
*/
|
|
457
534
|
async removeProcessedDappUserCommitments(commitmentIds) {
|
|
458
|
-
return await this.tables?.commitment.deleteMany({
|
|
535
|
+
return await this.tables?.commitment.deleteMany({
|
|
536
|
+
processed: true,
|
|
537
|
+
id: { $in: commitmentIds }
|
|
538
|
+
});
|
|
459
539
|
}
|
|
460
540
|
/**
|
|
461
541
|
* @description Store a Dapp User's pending record
|
|
@@ -463,7 +543,10 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
463
543
|
async storeDappUserPending(userAccount, requestHash, salt, deadlineTimestamp, requestedAtBlock) {
|
|
464
544
|
if (!is.isHex(requestHash)) {
|
|
465
545
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
466
|
-
context: {
|
|
546
|
+
context: {
|
|
547
|
+
failedFuncName: this.storeDappUserPending.name,
|
|
548
|
+
requestHash
|
|
549
|
+
}
|
|
467
550
|
});
|
|
468
551
|
}
|
|
469
552
|
const pendingRecord = {
|
|
@@ -474,7 +557,11 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
474
557
|
deadlineTimestamp,
|
|
475
558
|
requestedAtBlock
|
|
476
559
|
};
|
|
477
|
-
await this.tables?.pending.updateOne(
|
|
560
|
+
await this.tables?.pending.updateOne(
|
|
561
|
+
{ requestHash },
|
|
562
|
+
{ $set: pendingRecord },
|
|
563
|
+
{ upsert: true }
|
|
564
|
+
);
|
|
478
565
|
}
|
|
479
566
|
/**
|
|
480
567
|
* @description Get a Dapp user's pending record
|
|
@@ -499,7 +586,10 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
499
586
|
async updateDappUserPendingStatus(requestHash) {
|
|
500
587
|
if (!is.isHex(requestHash)) {
|
|
501
588
|
throw new common.ProsopoEnvError("DATABASE.INVALID_HASH", {
|
|
502
|
-
context: {
|
|
589
|
+
context: {
|
|
590
|
+
failedFuncName: this.updateDappUserPendingStatus.name,
|
|
591
|
+
requestHash
|
|
592
|
+
}
|
|
503
593
|
});
|
|
504
594
|
}
|
|
505
595
|
await this.tables?.pending.updateOne(
|
|
@@ -533,7 +623,9 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
533
623
|
const cursor = this.tables?.usersolution?.find({ captchaId: { $in: captchaId } }).lean();
|
|
534
624
|
const docs = await cursor;
|
|
535
625
|
if (docs) {
|
|
536
|
-
return docs.map(
|
|
626
|
+
return docs.map(
|
|
627
|
+
({ _id, ...keepAttrs }) => keepAttrs
|
|
628
|
+
);
|
|
537
629
|
}
|
|
538
630
|
throw new common.ProsopoEnvError("DATABASE.SOLUTION_GET_FAILED");
|
|
539
631
|
}
|
|
@@ -558,7 +650,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
558
650
|
}
|
|
559
651
|
]);
|
|
560
652
|
const docs = await cursor;
|
|
561
|
-
if (docs
|
|
653
|
+
if (docs?.length) {
|
|
562
654
|
return docs[0]._id;
|
|
563
655
|
}
|
|
564
656
|
throw new common.ProsopoDBError("DATABASE.DATASET_WITH_SOLUTIONS_GET_FAILED");
|
|
@@ -566,7 +658,10 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
566
658
|
async getRandomSolvedCaptchasFromSingleDataset(datasetId, size) {
|
|
567
659
|
if (!is.isHex(datasetId)) {
|
|
568
660
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
569
|
-
context: {
|
|
661
|
+
context: {
|
|
662
|
+
failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
|
|
663
|
+
datasetId
|
|
664
|
+
}
|
|
570
665
|
});
|
|
571
666
|
}
|
|
572
667
|
const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
|
|
@@ -582,11 +677,15 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
582
677
|
}
|
|
583
678
|
]);
|
|
584
679
|
const docs = await cursor;
|
|
585
|
-
if (docs
|
|
680
|
+
if (docs?.length) {
|
|
586
681
|
return docs;
|
|
587
682
|
}
|
|
588
683
|
throw new common.ProsopoDBError("DATABASE.SOLUTION_GET_FAILED", {
|
|
589
|
-
context: {
|
|
684
|
+
context: {
|
|
685
|
+
failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
|
|
686
|
+
datasetId,
|
|
687
|
+
size
|
|
688
|
+
}
|
|
590
689
|
});
|
|
591
690
|
}
|
|
592
691
|
/**
|
|
@@ -633,11 +732,13 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
633
732
|
try {
|
|
634
733
|
await this.tables?.commitment?.findOneAndUpdate(
|
|
635
734
|
{ id: commitmentId },
|
|
636
|
-
{ $set: { status:
|
|
735
|
+
{ $set: { status: types.CaptchaStatus.approved } },
|
|
637
736
|
{ upsert: false }
|
|
638
737
|
).lean();
|
|
639
738
|
} catch (err) {
|
|
640
|
-
throw new common.ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", {
|
|
739
|
+
throw new common.ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", {
|
|
740
|
+
context: { error: err, commitmentId }
|
|
741
|
+
});
|
|
641
742
|
}
|
|
642
743
|
}
|
|
643
744
|
/**
|
|
@@ -646,9 +747,15 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
646
747
|
*/
|
|
647
748
|
async flagProcessedDappUserSolutions(captchaIds) {
|
|
648
749
|
try {
|
|
649
|
-
await this.tables?.usersolution?.updateMany(
|
|
750
|
+
await this.tables?.usersolution?.updateMany(
|
|
751
|
+
{ captchaId: { $in: captchaIds } },
|
|
752
|
+
{ $set: { processed: true } },
|
|
753
|
+
{ upsert: false }
|
|
754
|
+
).lean();
|
|
650
755
|
} catch (err) {
|
|
651
|
-
throw new common.ProsopoDBError("DATABASE.SOLUTION_FLAG_FAILED", {
|
|
756
|
+
throw new common.ProsopoDBError("DATABASE.SOLUTION_FLAG_FAILED", {
|
|
757
|
+
context: { error: err, captchaIds }
|
|
758
|
+
});
|
|
652
759
|
}
|
|
653
760
|
}
|
|
654
761
|
/**
|
|
@@ -658,9 +765,15 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
658
765
|
async flagProcessedDappUserCommitments(commitmentIds) {
|
|
659
766
|
try {
|
|
660
767
|
const distinctCommitmentIds = [...new Set(commitmentIds)];
|
|
661
|
-
await this.tables?.commitment?.updateMany(
|
|
768
|
+
await this.tables?.commitment?.updateMany(
|
|
769
|
+
{ id: { $in: distinctCommitmentIds } },
|
|
770
|
+
{ $set: { processed: true } },
|
|
771
|
+
{ upsert: false }
|
|
772
|
+
).lean();
|
|
662
773
|
} catch (err) {
|
|
663
|
-
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
774
|
+
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
775
|
+
context: { error: err, commitmentIds }
|
|
776
|
+
});
|
|
664
777
|
}
|
|
665
778
|
}
|
|
666
779
|
/**
|
|
@@ -670,16 +783,25 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
670
783
|
async flagBatchedDappUserCommitments(commitmentIds) {
|
|
671
784
|
try {
|
|
672
785
|
const distinctCommitmentIds = [...new Set(commitmentIds)];
|
|
673
|
-
await this.tables?.commitment?.updateMany(
|
|
786
|
+
await this.tables?.commitment?.updateMany(
|
|
787
|
+
{ id: { $in: distinctCommitmentIds } },
|
|
788
|
+
{ $set: { batched: true } },
|
|
789
|
+
{ upsert: false }
|
|
790
|
+
).lean();
|
|
674
791
|
} catch (err) {
|
|
675
|
-
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
792
|
+
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
793
|
+
context: { error: err, commitmentIds }
|
|
794
|
+
});
|
|
676
795
|
}
|
|
677
796
|
}
|
|
678
797
|
/**
|
|
679
798
|
* @description Get the last batch commit time or return 0 if none
|
|
680
799
|
*/
|
|
681
800
|
async getLastBatchCommitTime() {
|
|
682
|
-
const cursor = this.tables?.scheduler?.findOne({
|
|
801
|
+
const cursor = this.tables?.scheduler?.findOne({
|
|
802
|
+
processName: types.ScheduledTaskNames.BatchCommitment,
|
|
803
|
+
status: types.ScheduledTaskStatus.Completed
|
|
804
|
+
}).sort({ timestamp: -1 });
|
|
683
805
|
const doc = await cursor?.lean();
|
|
684
806
|
if (doc) {
|
|
685
807
|
return doc.datetime;
|
|
@@ -699,7 +821,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
699
821
|
async getLastScheduledTaskStatus(task, status) {
|
|
700
822
|
const lookup = { processName: task };
|
|
701
823
|
if (status) {
|
|
702
|
-
lookup
|
|
824
|
+
lookup.status = status;
|
|
703
825
|
}
|
|
704
826
|
const cursor = await this.tables?.scheduler?.findOne(lookup).sort({ datetime: -1 }).lean();
|
|
705
827
|
return cursor ? cursor : void 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const mongo = require("./mongo.cjs");
|
|
4
3
|
const mongodbMemoryServer = require("mongodb-memory-server");
|
|
4
|
+
const mongo = require("./mongo.cjs");
|
|
5
5
|
class MongoMemoryDatabase extends mongo.ProsopoDatabase {
|
|
6
6
|
constructor() {
|
|
7
7
|
super(...arguments);
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const index = require("./databases/index.cjs");
|
|
4
4
|
require("./eventsDatabase/index.cjs");
|
|
5
|
+
require("./captchaDatabase/index.cjs");
|
|
5
6
|
const eventsDatabase = require("./eventsDatabase/eventsDatabase.cjs");
|
|
7
|
+
const captchaDatabase = require("./captchaDatabase/captchaDatabase.cjs");
|
|
6
8
|
exports.Databases = index.Databases;
|
|
7
9
|
exports.saveCaptchaEvent = eventsDatabase.saveCaptchaEvent;
|
|
10
|
+
exports.saveCaptchas = captchaDatabase.saveCaptchas;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ProsopoDatabase as MongoDatabase } from
|
|
2
|
-
import { MongoMemoryDatabase } from
|
|
1
|
+
import { ProsopoDatabase as MongoDatabase } from "./mongo.js";
|
|
2
|
+
import { MongoMemoryDatabase } from "./mongoMemory.js";
|
|
3
3
|
export declare const Databases: {
|
|
4
4
|
mongo: typeof MongoDatabase;
|
|
5
5
|
mongoMemory: typeof MongoMemoryDatabase;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/databases/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,IAAI,aAAa,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/databases/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,eAAO,MAAM,SAAS;;;CAGrB,CAAC"}
|
package/dist/databases/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DatabaseTypes } from
|
|
2
|
-
import { ProsopoDatabase as MongoDatabase } from
|
|
3
|
-
import { MongoMemoryDatabase } from
|
|
1
|
+
import { DatabaseTypes } from "@prosopo/types";
|
|
2
|
+
import { ProsopoDatabase as MongoDatabase } from "./mongo.js";
|
|
3
|
+
import { MongoMemoryDatabase } from "./mongoMemory.js";
|
|
4
4
|
export const Databases = {
|
|
5
5
|
[DatabaseTypes.Values.mongo]: MongoDatabase,
|
|
6
6
|
[DatabaseTypes.Values.mongoMemory]: MongoMemoryDatabase,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/databases/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/databases/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,eAAe,IAAI,aAAa,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,MAAM,CAAC,MAAM,SAAS,GAAG;IACxB,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,aAAa;IAC3C,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,mBAAmB;CACvD,CAAC"}
|