@prosopo/database 1.0.2 → 2.0.1
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 +1 -1
- package/dist/captchaDatabase/index.d.ts.map +1 -1
- package/dist/captchaDatabase/index.js +1 -1
- package/dist/captchaDatabase/index.js.map +1 -1
- package/dist/cjs/captchaDatabase/captchaDatabase.cjs +37 -0
- package/dist/cjs/captchaDatabase/index.cjs +2 -2
- package/dist/cjs/databases/mongo.cjs +176 -69
- package/dist/cjs/databases/mongoMemory.cjs +1 -1
- package/dist/cjs/index.cjs +2 -2
- 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 +8 -7
- package/dist/databases/mongo.d.ts.map +1 -1
- package/dist/databases/mongo.js +191 -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 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +44 -53
- package/vite.cjs.config.ts +3 -3
- package/dist/captchaDatabase/captchaDatabse.d.ts +0 -3
- package/dist/captchaDatabase/captchaDatabse.d.ts.map +0 -1
- package/dist/captchaDatabase/captchaDatabse.js +0 -12
- package/dist/captchaDatabase/captchaDatabse.js.map +0 -1
- package/dist/cjs/captchaDatabase/captchaDatabse.cjs +0 -14
|
@@ -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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./captchaDatabase.js";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/captchaDatabase/index.ts"],"names":[],"mappings":"AAaA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/captchaDatabase/index.ts"],"names":[],"mappings":"AAaA,cAAc,sBAAsB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./captchaDatabase.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/captchaDatabase/index.ts"],"names":[],"mappings":"AAaA,cAAc,
|
|
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,4 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const
|
|
4
|
-
exports.saveCaptchas =
|
|
3
|
+
const captchaDatabase = require("./captchaDatabase.cjs");
|
|
4
|
+
exports.saveCaptchas = captchaDatabase.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,31 @@ 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, stored = false) {
|
|
369
|
+
const tables = this.getTables();
|
|
350
370
|
const powCaptchaRecord = {
|
|
351
371
|
challenge,
|
|
352
|
-
|
|
372
|
+
...components,
|
|
373
|
+
checked,
|
|
374
|
+
stored
|
|
353
375
|
};
|
|
354
376
|
try {
|
|
355
|
-
await
|
|
356
|
-
this.logger.info("PowCaptcha record added successfully", {
|
|
377
|
+
await tables.powCaptcha.create(powCaptchaRecord);
|
|
378
|
+
this.logger.info("PowCaptcha record added successfully", {
|
|
379
|
+
challenge,
|
|
380
|
+
checked,
|
|
381
|
+
stored
|
|
382
|
+
});
|
|
357
383
|
} catch (error) {
|
|
358
|
-
this.logger.error("Failed to add PowCaptcha record", {
|
|
384
|
+
this.logger.error("Failed to add PowCaptcha record", {
|
|
385
|
+
error,
|
|
386
|
+
challenge,
|
|
387
|
+
checked
|
|
388
|
+
});
|
|
359
389
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
360
390
|
context: { error, challenge, checked },
|
|
361
391
|
logger: this.logger
|
|
@@ -377,14 +407,18 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
377
407
|
try {
|
|
378
408
|
const record = await this.tables.powCaptcha.findOne({ challenge }).lean();
|
|
379
409
|
if (record) {
|
|
380
|
-
this.logger.info("PowCaptcha record retrieved successfully", {
|
|
410
|
+
this.logger.info("PowCaptcha record retrieved successfully", {
|
|
411
|
+
challenge
|
|
412
|
+
});
|
|
381
413
|
return record;
|
|
382
|
-
} else {
|
|
383
|
-
this.logger.info("No PowCaptcha record found", { challenge });
|
|
384
|
-
return null;
|
|
385
414
|
}
|
|
415
|
+
this.logger.info("No PowCaptcha record found", { challenge });
|
|
416
|
+
return null;
|
|
386
417
|
} catch (error) {
|
|
387
|
-
this.logger.error("Failed to retrieve PowCaptcha record", {
|
|
418
|
+
this.logger.error("Failed to retrieve PowCaptcha record", {
|
|
419
|
+
error,
|
|
420
|
+
challenge
|
|
421
|
+
});
|
|
388
422
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
389
423
|
context: { error, challenge },
|
|
390
424
|
logger: this.logger
|
|
@@ -398,25 +432,32 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
398
432
|
* @returns {Promise<void>} A promise that resolves when the record is updated.
|
|
399
433
|
*/
|
|
400
434
|
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
|
-
}
|
|
435
|
+
const tables = this.getTables();
|
|
407
436
|
try {
|
|
408
|
-
const updateResult = await
|
|
437
|
+
const updateResult = await tables.powCaptcha.updateOne(
|
|
438
|
+
{ challenge },
|
|
439
|
+
{ $set: { checked } }
|
|
440
|
+
);
|
|
409
441
|
if (updateResult.matchedCount === 0) {
|
|
410
|
-
this.logger.info("No PowCaptcha record found to update", {
|
|
442
|
+
this.logger.info("No PowCaptcha record found to update", {
|
|
443
|
+
challenge,
|
|
444
|
+
checked
|
|
445
|
+
});
|
|
411
446
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
412
447
|
context: { challenge, checked },
|
|
413
448
|
logger: this.logger
|
|
414
449
|
});
|
|
415
|
-
} else {
|
|
416
|
-
this.logger.info("PowCaptcha record updated successfully", { challenge, checked });
|
|
417
450
|
}
|
|
451
|
+
this.logger.info("PowCaptcha record updated successfully", {
|
|
452
|
+
challenge,
|
|
453
|
+
checked
|
|
454
|
+
});
|
|
418
455
|
} catch (error) {
|
|
419
|
-
this.logger.error("Failed to update PowCaptcha record", {
|
|
456
|
+
this.logger.error("Failed to update PowCaptcha record", {
|
|
457
|
+
error,
|
|
458
|
+
challenge,
|
|
459
|
+
checked
|
|
460
|
+
});
|
|
420
461
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
421
462
|
context: { error, challenge, checked },
|
|
422
463
|
logger: this.logger
|
|
@@ -441,7 +482,8 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
441
482
|
const docs = await this.tables?.commitment.find({ batched: false }).lean();
|
|
442
483
|
return docs ? docs.map((doc) => typesDatabase.UserCommitmentSchema.parse(doc)) : [];
|
|
443
484
|
}
|
|
444
|
-
/** @description Get Dapp User captcha commitments from the commitments table that have not been
|
|
485
|
+
/** @description Get Dapp User captcha commitments from the commitments table that have not been counted towards the
|
|
486
|
+
* client's total
|
|
445
487
|
*/
|
|
446
488
|
async getUnstoredDappUserCommitments() {
|
|
447
489
|
const docs = await this.tables?.commitment.find({
|
|
@@ -458,6 +500,23 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
458
500
|
{ upsert: false }
|
|
459
501
|
);
|
|
460
502
|
}
|
|
503
|
+
/** @description Get Dapp User PoW captcha commitments that have not been counted towards the client's total
|
|
504
|
+
*/
|
|
505
|
+
async getUnstoredDappUserPoWCommitments() {
|
|
506
|
+
const docs = await this.tables?.powCaptcha.find({
|
|
507
|
+
$or: [{ stored: false }, { stored: { $exists: false } }]
|
|
508
|
+
}).lean();
|
|
509
|
+
return docs || [];
|
|
510
|
+
}
|
|
511
|
+
/** @description Mark a list of PoW captcha commits as stored
|
|
512
|
+
*/
|
|
513
|
+
async markDappUserPoWCommitmentsStored(challenges) {
|
|
514
|
+
await this.tables?.powCaptcha.updateMany(
|
|
515
|
+
{ challenge: { $in: challenges } },
|
|
516
|
+
{ $set: { stored: true } },
|
|
517
|
+
{ upsert: false }
|
|
518
|
+
);
|
|
519
|
+
}
|
|
461
520
|
/** @description Get Dapp User captcha commitments from the commitments table that have been batched on-chain
|
|
462
521
|
*/
|
|
463
522
|
async getBatchedDappUserCommitments() {
|
|
@@ -467,12 +526,18 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
467
526
|
/** @description Remove processed Dapp User captcha solutions from the user solution table
|
|
468
527
|
*/
|
|
469
528
|
async removeProcessedDappUserSolutions(commitmentIds) {
|
|
470
|
-
return await this.tables?.usersolution.deleteMany({
|
|
529
|
+
return await this.tables?.usersolution.deleteMany({
|
|
530
|
+
processed: true,
|
|
531
|
+
commitmentId: { $in: commitmentIds }
|
|
532
|
+
});
|
|
471
533
|
}
|
|
472
534
|
/** @description Remove processed Dapp User captcha commitments from the user commitments table
|
|
473
535
|
*/
|
|
474
536
|
async removeProcessedDappUserCommitments(commitmentIds) {
|
|
475
|
-
return await this.tables?.commitment.deleteMany({
|
|
537
|
+
return await this.tables?.commitment.deleteMany({
|
|
538
|
+
processed: true,
|
|
539
|
+
id: { $in: commitmentIds }
|
|
540
|
+
});
|
|
476
541
|
}
|
|
477
542
|
/**
|
|
478
543
|
* @description Store a Dapp User's pending record
|
|
@@ -480,7 +545,10 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
480
545
|
async storeDappUserPending(userAccount, requestHash, salt, deadlineTimestamp, requestedAtBlock) {
|
|
481
546
|
if (!is.isHex(requestHash)) {
|
|
482
547
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
483
|
-
context: {
|
|
548
|
+
context: {
|
|
549
|
+
failedFuncName: this.storeDappUserPending.name,
|
|
550
|
+
requestHash
|
|
551
|
+
}
|
|
484
552
|
});
|
|
485
553
|
}
|
|
486
554
|
const pendingRecord = {
|
|
@@ -491,7 +559,11 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
491
559
|
deadlineTimestamp,
|
|
492
560
|
requestedAtBlock
|
|
493
561
|
};
|
|
494
|
-
await this.tables?.pending.updateOne(
|
|
562
|
+
await this.tables?.pending.updateOne(
|
|
563
|
+
{ requestHash },
|
|
564
|
+
{ $set: pendingRecord },
|
|
565
|
+
{ upsert: true }
|
|
566
|
+
);
|
|
495
567
|
}
|
|
496
568
|
/**
|
|
497
569
|
* @description Get a Dapp user's pending record
|
|
@@ -516,7 +588,10 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
516
588
|
async updateDappUserPendingStatus(requestHash) {
|
|
517
589
|
if (!is.isHex(requestHash)) {
|
|
518
590
|
throw new common.ProsopoEnvError("DATABASE.INVALID_HASH", {
|
|
519
|
-
context: {
|
|
591
|
+
context: {
|
|
592
|
+
failedFuncName: this.updateDappUserPendingStatus.name,
|
|
593
|
+
requestHash
|
|
594
|
+
}
|
|
520
595
|
});
|
|
521
596
|
}
|
|
522
597
|
await this.tables?.pending.updateOne(
|
|
@@ -550,7 +625,9 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
550
625
|
const cursor = this.tables?.usersolution?.find({ captchaId: { $in: captchaId } }).lean();
|
|
551
626
|
const docs = await cursor;
|
|
552
627
|
if (docs) {
|
|
553
|
-
return docs.map(
|
|
628
|
+
return docs.map(
|
|
629
|
+
({ _id, ...keepAttrs }) => keepAttrs
|
|
630
|
+
);
|
|
554
631
|
}
|
|
555
632
|
throw new common.ProsopoEnvError("DATABASE.SOLUTION_GET_FAILED");
|
|
556
633
|
}
|
|
@@ -575,7 +652,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
575
652
|
}
|
|
576
653
|
]);
|
|
577
654
|
const docs = await cursor;
|
|
578
|
-
if (docs
|
|
655
|
+
if (docs?.length) {
|
|
579
656
|
return docs[0]._id;
|
|
580
657
|
}
|
|
581
658
|
throw new common.ProsopoDBError("DATABASE.DATASET_WITH_SOLUTIONS_GET_FAILED");
|
|
@@ -583,7 +660,10 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
583
660
|
async getRandomSolvedCaptchasFromSingleDataset(datasetId, size) {
|
|
584
661
|
if (!is.isHex(datasetId)) {
|
|
585
662
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
586
|
-
context: {
|
|
663
|
+
context: {
|
|
664
|
+
failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
|
|
665
|
+
datasetId
|
|
666
|
+
}
|
|
587
667
|
});
|
|
588
668
|
}
|
|
589
669
|
const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
|
|
@@ -599,11 +679,15 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
599
679
|
}
|
|
600
680
|
]);
|
|
601
681
|
const docs = await cursor;
|
|
602
|
-
if (docs
|
|
682
|
+
if (docs?.length) {
|
|
603
683
|
return docs;
|
|
604
684
|
}
|
|
605
685
|
throw new common.ProsopoDBError("DATABASE.SOLUTION_GET_FAILED", {
|
|
606
|
-
context: {
|
|
686
|
+
context: {
|
|
687
|
+
failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
|
|
688
|
+
datasetId,
|
|
689
|
+
size
|
|
690
|
+
}
|
|
607
691
|
});
|
|
608
692
|
}
|
|
609
693
|
/**
|
|
@@ -650,11 +734,13 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
650
734
|
try {
|
|
651
735
|
await this.tables?.commitment?.findOneAndUpdate(
|
|
652
736
|
{ id: commitmentId },
|
|
653
|
-
{ $set: { status:
|
|
737
|
+
{ $set: { status: types.CaptchaStatus.approved } },
|
|
654
738
|
{ upsert: false }
|
|
655
739
|
).lean();
|
|
656
740
|
} catch (err) {
|
|
657
|
-
throw new common.ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", {
|
|
741
|
+
throw new common.ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", {
|
|
742
|
+
context: { error: err, commitmentId }
|
|
743
|
+
});
|
|
658
744
|
}
|
|
659
745
|
}
|
|
660
746
|
/**
|
|
@@ -663,9 +749,15 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
663
749
|
*/
|
|
664
750
|
async flagProcessedDappUserSolutions(captchaIds) {
|
|
665
751
|
try {
|
|
666
|
-
await this.tables?.usersolution?.updateMany(
|
|
752
|
+
await this.tables?.usersolution?.updateMany(
|
|
753
|
+
{ captchaId: { $in: captchaIds } },
|
|
754
|
+
{ $set: { processed: true } },
|
|
755
|
+
{ upsert: false }
|
|
756
|
+
).lean();
|
|
667
757
|
} catch (err) {
|
|
668
|
-
throw new common.ProsopoDBError("DATABASE.SOLUTION_FLAG_FAILED", {
|
|
758
|
+
throw new common.ProsopoDBError("DATABASE.SOLUTION_FLAG_FAILED", {
|
|
759
|
+
context: { error: err, captchaIds }
|
|
760
|
+
});
|
|
669
761
|
}
|
|
670
762
|
}
|
|
671
763
|
/**
|
|
@@ -675,9 +767,15 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
675
767
|
async flagProcessedDappUserCommitments(commitmentIds) {
|
|
676
768
|
try {
|
|
677
769
|
const distinctCommitmentIds = [...new Set(commitmentIds)];
|
|
678
|
-
await this.tables?.commitment?.updateMany(
|
|
770
|
+
await this.tables?.commitment?.updateMany(
|
|
771
|
+
{ id: { $in: distinctCommitmentIds } },
|
|
772
|
+
{ $set: { processed: true } },
|
|
773
|
+
{ upsert: false }
|
|
774
|
+
).lean();
|
|
679
775
|
} catch (err) {
|
|
680
|
-
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
776
|
+
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
777
|
+
context: { error: err, commitmentIds }
|
|
778
|
+
});
|
|
681
779
|
}
|
|
682
780
|
}
|
|
683
781
|
/**
|
|
@@ -687,16 +785,25 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
687
785
|
async flagBatchedDappUserCommitments(commitmentIds) {
|
|
688
786
|
try {
|
|
689
787
|
const distinctCommitmentIds = [...new Set(commitmentIds)];
|
|
690
|
-
await this.tables?.commitment?.updateMany(
|
|
788
|
+
await this.tables?.commitment?.updateMany(
|
|
789
|
+
{ id: { $in: distinctCommitmentIds } },
|
|
790
|
+
{ $set: { batched: true } },
|
|
791
|
+
{ upsert: false }
|
|
792
|
+
).lean();
|
|
691
793
|
} catch (err) {
|
|
692
|
-
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
794
|
+
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", {
|
|
795
|
+
context: { error: err, commitmentIds }
|
|
796
|
+
});
|
|
693
797
|
}
|
|
694
798
|
}
|
|
695
799
|
/**
|
|
696
800
|
* @description Get the last batch commit time or return 0 if none
|
|
697
801
|
*/
|
|
698
802
|
async getLastBatchCommitTime() {
|
|
699
|
-
const cursor = this.tables?.scheduler?.findOne({
|
|
803
|
+
const cursor = this.tables?.scheduler?.findOne({
|
|
804
|
+
processName: types.ScheduledTaskNames.BatchCommitment,
|
|
805
|
+
status: types.ScheduledTaskStatus.Completed
|
|
806
|
+
}).sort({ timestamp: -1 });
|
|
700
807
|
const doc = await cursor?.lean();
|
|
701
808
|
if (doc) {
|
|
702
809
|
return doc.datetime;
|
|
@@ -716,7 +823,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
716
823
|
async getLastScheduledTaskStatus(task, status) {
|
|
717
824
|
const lookup = { processName: task };
|
|
718
825
|
if (status) {
|
|
719
|
-
lookup
|
|
826
|
+
lookup.status = status;
|
|
720
827
|
}
|
|
721
828
|
const cursor = await this.tables?.scheduler?.findOne(lookup).sort({ datetime: -1 }).lean();
|
|
722
829
|
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
|
@@ -4,7 +4,7 @@ const index = require("./databases/index.cjs");
|
|
|
4
4
|
require("./eventsDatabase/index.cjs");
|
|
5
5
|
require("./captchaDatabase/index.cjs");
|
|
6
6
|
const eventsDatabase = require("./eventsDatabase/eventsDatabase.cjs");
|
|
7
|
-
const
|
|
7
|
+
const captchaDatabase = require("./captchaDatabase/captchaDatabase.cjs");
|
|
8
8
|
exports.Databases = index.Databases;
|
|
9
9
|
exports.saveCaptchaEvent = eventsDatabase.saveCaptchaEvent;
|
|
10
|
-
exports.saveCaptchas =
|
|
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,
|