@prosopo/database 4.2.6 → 4.2.8

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 (36) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +13 -12
  2. package/.turbo/turbo-build$colon$tsc.log +16 -16
  3. package/.turbo/turbo-build.log +14 -13
  4. package/CHANGELOG.md +72 -0
  5. package/dist/base/mongo.d.ts.map +1 -1
  6. package/dist/base/mongo.js +6 -4
  7. package/dist/base/mongo.js.map +1 -1
  8. package/dist/cjs/base/mongo.cjs +5 -3
  9. package/dist/cjs/databases/captcha.cjs +10 -7
  10. package/dist/cjs/databases/client.cjs +5 -3
  11. package/dist/cjs/databases/clientRecordCache.cjs +43 -0
  12. package/dist/cjs/databases/provider.cjs +338 -185
  13. package/dist/cjs/redisCache.cjs +1 -1
  14. package/dist/databases/captcha.d.ts.map +1 -1
  15. package/dist/databases/captcha.js +11 -8
  16. package/dist/databases/captcha.js.map +1 -1
  17. package/dist/databases/client.d.ts.map +1 -1
  18. package/dist/databases/client.js +6 -4
  19. package/dist/databases/client.js.map +1 -1
  20. package/dist/databases/clientRecordCache.d.ts +11 -0
  21. package/dist/databases/clientRecordCache.d.ts.map +1 -0
  22. package/dist/databases/clientRecordCache.js +42 -0
  23. package/dist/databases/clientRecordCache.js.map +1 -0
  24. package/dist/databases/provider.d.ts.map +1 -1
  25. package/dist/databases/provider.js +339 -186
  26. package/dist/databases/provider.js.map +1 -1
  27. package/dist/errorSites.d.ts +57 -0
  28. package/dist/errorSites.d.ts.map +1 -0
  29. package/dist/errorSites.js +2 -0
  30. package/dist/errorSites.js.map +1 -0
  31. package/dist/redisCache.js +1 -1
  32. package/dist/tests/integration/clientRecordCache.integration.test.d.ts +2 -0
  33. package/dist/tests/integration/clientRecordCache.integration.test.d.ts.map +1 -0
  34. package/dist/tests/integration/clientRecordCache.integration.test.js +87 -0
  35. package/dist/tests/integration/clientRecordCache.integration.test.js.map +1 -0
  36. package/package.json +13 -13
@@ -1,4 +1,5 @@
1
1
  const require_mongo = require("../base/mongo.cjs");
2
+ const require_clientRecordCache = require("./clientRecordCache.cjs");
2
3
  let _prosopo_common = require("@prosopo/common");
3
4
  let _prosopo_types = require("@prosopo/types");
4
5
  let _prosopo_types_database = require("@prosopo/types-database");
@@ -121,18 +122,28 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
121
122
  this.tables = tables;
122
123
  }
123
124
  getTables() {
124
- if (!this.tables) throw new _prosopo_common.ProsopoDBError("DATABASE.TABLES_UNDEFINED", {
125
- context: { failedFuncName: this.getTables.name },
126
- logger: this.logger
125
+ if (!this.tables) throw new _prosopo_common.ProsopoError({
126
+ code: "DB_UNAVAILABLE",
127
+ errorSite: "DBSE-5",
128
+ message: "Tables undefined",
129
+ context: { failedFuncName: this.getTables.name }
127
130
  });
128
131
  return this.tables;
129
132
  }
130
133
  getRedisAccessRulesConnection() {
131
- if (null === this.redisAccessRulesConnection) throw new _prosopo_common.ProsopoDBError("DATABASE.REDIS_ACCESS_RULES_CONNECTION_UNDEFINED");
134
+ if (null === this.redisAccessRulesConnection) throw new _prosopo_common.ProsopoError({
135
+ code: "DB_UNAVAILABLE",
136
+ errorSite: "DBSE-6",
137
+ message: "Redis access rules connection undefined"
138
+ });
132
139
  return this.redisAccessRulesConnection;
133
140
  }
134
141
  getRedisConnection() {
135
- if (null === this.redisConnection) throw new _prosopo_common.ProsopoDBError("DATABASE.REDIS_ACCESS_RULES_CONNECTION_UNDEFINED");
142
+ if (null === this.redisConnection) throw new _prosopo_common.ProsopoError({
143
+ code: "DB_UNAVAILABLE",
144
+ errorSite: "DBSE-7",
145
+ message: "Redis access rules connection undefined"
146
+ });
136
147
  return this.redisConnection;
137
148
  }
138
149
  async ensureIndexes() {
@@ -161,7 +172,11 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
161
172
  this.indexesEnsured = true;
162
173
  }
163
174
  getUserAccessRulesStorage() {
164
- if (null === this.userAccessRulesStorage) throw new _prosopo_common.ProsopoDBError("DATABASE.USER_ACCESS_RULES_STORAGE_UNDEFINED");
175
+ if (null === this.userAccessRulesStorage) throw new _prosopo_common.ProsopoError({
176
+ code: "DB_UNAVAILABLE",
177
+ errorSite: "DBSE-8",
178
+ message: "User access rules storage undefined"
179
+ });
165
180
  return this.userAccessRulesStorage;
166
181
  }
167
182
  /**
@@ -216,12 +231,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
216
231
  } })));
217
232
  this.logger.debug(() => ({ msg: "Dataset stored in database" }));
218
233
  } catch (err) {
219
- throw new _prosopo_common.ProsopoDBError("DATABASE.DATASET_LOAD_FAILED", {
220
- context: {
221
- failedFuncName: this.storeDataset.name,
222
- error: err
223
- },
224
- logger: this.logger
234
+ throw new _prosopo_common.ProsopoError({
235
+ code: "DB_QUERY_FAILED",
236
+ errorSite: "DBSE-9",
237
+ message: "Data set load failed",
238
+ cause: err,
239
+ context: { failedFuncName: this.storeDataset.name }
225
240
  });
226
241
  }
227
242
  }
@@ -273,10 +288,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
273
288
  })
274
289
  };
275
290
  }
276
- throw new _prosopo_common.ProsopoDBError("DATABASE.DATASET_GET_FAILED", { context: {
277
- failedFuncName: this.getDataset.name,
278
- datasetId
279
- } });
291
+ throw new _prosopo_common.ProsopoError({
292
+ code: "DB_QUERY_FAILED",
293
+ errorSite: "DBSE-10",
294
+ message: "Failed to get dataset",
295
+ context: {
296
+ failedFuncName: this.getDataset.name,
297
+ datasetId
298
+ }
299
+ });
280
300
  }
281
301
  /**
282
302
  * @description Get random captchas that are solved or not solved
@@ -285,10 +305,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
285
305
  * @param {number} size the number of records to be returned
286
306
  */
287
307
  async getRandomCaptcha(solved, datasetId, size) {
288
- if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoDBError("DATABASE.INVALID_HASH", { context: {
289
- failedFuncName: this.getRandomCaptcha.name,
290
- datasetId
291
- } });
308
+ if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoError({
309
+ code: "INVALID_DATA",
310
+ errorSite: "DBSE-11",
311
+ message: "Invalid hash",
312
+ context: {
313
+ failedFuncName: this.getRandomCaptcha.name,
314
+ datasetId
315
+ }
316
+ });
292
317
  const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
293
318
  const projection = {
294
319
  _id: 0,
@@ -324,12 +349,17 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
324
349
  if (fallback.length > 0) return fallback.map(({ _id, ...keep }) => keep);
325
350
  }
326
351
  if (docs.length > 0) return docs;
327
- throw new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", { context: {
328
- failedFuncName: this.getRandomCaptcha.name,
329
- solved,
330
- datasetId,
331
- size
332
- } });
352
+ throw new _prosopo_common.ProsopoError({
353
+ code: "DB_QUERY_FAILED",
354
+ errorSite: "DBSE-12",
355
+ message: "Failed to get captcha",
356
+ context: {
357
+ failedFuncName: this.getRandomCaptcha.name,
358
+ solved,
359
+ datasetId,
360
+ size
361
+ }
362
+ });
333
363
  }
334
364
  /**
335
365
  * @description Get captchas by id
@@ -344,10 +374,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
344
374
  items: 1
345
375
  }).lean();
346
376
  if (docs?.length) return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
347
- throw new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", { context: {
348
- failedFuncName: this.getCaptchaById.name,
349
- captchaId
350
- } });
377
+ throw new _prosopo_common.ProsopoError({
378
+ code: "DB_QUERY_FAILED",
379
+ errorSite: "DBSE-13",
380
+ message: "Failed to get captcha",
381
+ context: {
382
+ failedFuncName: this.getCaptchaById.name,
383
+ captchaId
384
+ }
385
+ });
351
386
  }
352
387
  /**
353
388
  * @description Update a captcha
@@ -355,18 +390,26 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
355
390
  * @param {string} datasetId the id of the data set
356
391
  */
357
392
  async updateCaptcha(captcha, datasetId) {
358
- if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoDBError("DATABASE.INVALID_HASH", { context: {
359
- failedFuncName: this.updateCaptcha.name,
360
- datasetId
361
- } });
393
+ if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoError({
394
+ code: "INVALID_DATA",
395
+ errorSite: "DBSE-14",
396
+ message: "Invalid hash",
397
+ context: {
398
+ failedFuncName: this.updateCaptcha.name,
399
+ datasetId
400
+ }
401
+ });
362
402
  try {
363
403
  const filter = { datasetId };
364
404
  await this.tables?.captcha.updateOne(filter, { $set: captcha }, { upsert: false });
365
405
  } catch (err) {
366
- throw new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", { context: {
367
- failedFuncName: this.getDatasetDetails.name,
368
- error: err
369
- } });
406
+ throw new _prosopo_common.ProsopoError({
407
+ code: "DB_QUERY_FAILED",
408
+ errorSite: "DBSE-15",
409
+ message: "Failed to update captcha",
410
+ cause: err,
411
+ context: { failedFuncName: this.getDatasetDetails.name }
412
+ });
370
413
  }
371
414
  }
372
415
  /**
@@ -389,17 +432,27 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
389
432
  return typeof datasetId === "string" ? datasetId : void 0;
390
433
  }
391
434
  async getDatasetDetails(datasetId) {
392
- if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoDBError("DATABASE.INVALID_HASH", { context: {
393
- failedFuncName: this.getDatasetDetails.name,
394
- datasetId
395
- } });
435
+ if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoError({
436
+ code: "INVALID_DATA",
437
+ errorSite: "DBSE-16",
438
+ message: "Invalid hash",
439
+ context: {
440
+ failedFuncName: this.getDatasetDetails.name,
441
+ datasetId
442
+ }
443
+ });
396
444
  const filter = { datasetId };
397
445
  const doc = await this.tables?.dataset.findOne(filter).lean();
398
446
  if (doc) return doc;
399
- throw new _prosopo_common.ProsopoDBError("DATABASE.DATASET_GET_FAILED", { context: {
400
- failedFuncName: this.getDatasetDetails.name,
401
- datasetId
402
- } });
447
+ throw new _prosopo_common.ProsopoError({
448
+ code: "DB_QUERY_FAILED",
449
+ errorSite: "DBSE-17",
450
+ message: "Failed to get dataset",
451
+ context: {
452
+ failedFuncName: this.getDatasetDetails.name,
453
+ datasetId
454
+ }
455
+ });
403
456
  }
404
457
  /**
405
458
  * @description Store a Dapp User's captcha solution commitment
@@ -488,15 +541,17 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
488
541
  $unset: { pendingStage: 1 }
489
542
  }).then(() => {}));
490
543
  } catch (error) {
491
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
544
+ const err = new _prosopo_common.ProsopoError({
545
+ code: "DB_QUERY_FAILED",
546
+ errorSite: "DBSE-18",
547
+ message: "Failed to update captcha",
548
+ cause: error,
492
549
  context: {
493
- error,
494
550
  challenge,
495
551
  userSubmitted,
496
552
  serverChecked,
497
553
  ipInfo
498
- },
499
- logger: this.logger
554
+ }
500
555
  });
501
556
  this.logger.error(() => ({
502
557
  err: error,
@@ -511,9 +566,11 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
511
566
  * @returns {Promise<PoWCaptchaRecord | null>} A promise that resolves with the found record or null if not found.
512
567
  */
513
568
  async getPowCaptchaRecordByChallenge(challenge) {
514
- if (!this.tables) throw new _prosopo_common.ProsopoDBError("DATABASE.DATABASE_UNDEFINED", {
515
- context: { failedFuncName: this.getPowCaptchaRecordByChallenge.name },
516
- logger: this.logger
569
+ if (!this.tables) throw new _prosopo_common.ProsopoError({
570
+ code: "DB_QUERY_FAILED",
571
+ errorSite: "DBSE-19",
572
+ message: "Database client is not connected",
573
+ context: { failedFuncName: this.getPowCaptchaRecordByChallenge.name }
517
574
  });
518
575
  try {
519
576
  const filter = { challenge };
@@ -552,12 +609,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
552
609
  }));
553
610
  return null;
554
611
  } catch (error) {
555
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
556
- context: {
557
- error,
558
- challenge
559
- },
560
- logger: this.logger
612
+ const err = new _prosopo_common.ProsopoError({
613
+ code: "DB_QUERY_FAILED",
614
+ errorSite: "DBSE-20",
615
+ message: "Failed to get captcha",
616
+ cause: error,
617
+ context: { challenge }
561
618
  });
562
619
  this.logger.error(() => ({
563
620
  err,
@@ -594,12 +651,14 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
594
651
  if (isDisapproved) setStage.failedAtTimestamp = { $ifNull: ["$failedAtTimestamp", timestamp] };
595
652
  try {
596
653
  if ((await tables.powcaptcha.updateOne({ challenge }, [{ $set: setStage }], { updatePipeline: true })).matchedCount === 0) {
597
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
654
+ const err = new _prosopo_common.ProsopoError({
655
+ code: "DB_QUERY_FAILED",
656
+ errorSite: "DBSE-21",
657
+ message: "Failed to get captcha",
598
658
  context: {
599
659
  challenge,
600
660
  ...setStage
601
- },
602
- logger: this.logger
661
+ }
603
662
  });
604
663
  this.logger.info(() => ({
605
664
  err,
@@ -622,13 +681,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
622
681
  $unset: { pendingStage: 1 }
623
682
  }).then(() => {}));
624
683
  } catch (error) {
625
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
684
+ const err = new _prosopo_common.ProsopoError({
685
+ code: "DB_QUERY_FAILED",
686
+ errorSite: "DBSE-22",
687
+ message: "Failed to update captcha",
688
+ cause: error,
626
689
  context: {
627
- error,
628
690
  challenge,
629
691
  ...setStage
630
- },
631
- logger: this.logger
692
+ }
632
693
  });
633
694
  this.logger.error(() => ({
634
695
  err,
@@ -721,13 +782,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
721
782
  }));
722
783
  collection.streamRecord(record, this.markInteractiveRecordStored(collection, challenge));
723
784
  } catch (error) {
724
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
785
+ const err = new _prosopo_common.ProsopoError({
786
+ code: "DB_QUERY_FAILED",
787
+ errorSite: "DBSE-23",
788
+ message: "Failed to update captcha",
789
+ cause: error,
725
790
  context: {
726
- error,
727
791
  challenge,
728
792
  ipInfo
729
- },
730
- logger: this.logger
793
+ }
731
794
  });
732
795
  this.logger.error(() => ({
733
796
  err: error,
@@ -779,9 +842,11 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
779
842
  });
780
843
  }
781
844
  async getInteractiveCaptchaRecordByChallenge(collection, challenge, failedFuncName) {
782
- if (!this.tables) throw new _prosopo_common.ProsopoDBError("DATABASE.DATABASE_UNDEFINED", {
783
- context: { failedFuncName },
784
- logger: this.logger
845
+ if (!this.tables) throw new _prosopo_common.ProsopoError({
846
+ code: "DB_QUERY_FAILED",
847
+ errorSite: "DBSE-24",
848
+ message: "Database client is not connected",
849
+ context: { failedFuncName }
785
850
  });
786
851
  try {
787
852
  const record = await this.tables[collection.table].findOne({ challenge }, {
@@ -817,12 +882,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
817
882
  }));
818
883
  return null;
819
884
  } catch (error) {
820
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
821
- context: {
822
- error,
823
- challenge
824
- },
825
- logger: this.logger
885
+ const err = new _prosopo_common.ProsopoError({
886
+ code: "DB_QUERY_FAILED",
887
+ errorSite: "DBSE-25",
888
+ message: "Failed to get captcha",
889
+ cause: error,
890
+ context: { challenge }
826
891
  });
827
892
  this.logger.error(() => ({
828
893
  err,
@@ -870,12 +935,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
870
935
  }));
871
936
  return won;
872
937
  } catch (error) {
873
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
874
- context: {
875
- error,
876
- challenge
877
- },
878
- logger: this.logger
938
+ const err = new _prosopo_common.ProsopoError({
939
+ code: "DB_QUERY_FAILED",
940
+ errorSite: "DBSE-26",
941
+ message: "Failed to update captcha",
942
+ cause: error,
943
+ context: { challenge }
879
944
  });
880
945
  this.logger.error(() => ({
881
946
  err,
@@ -909,12 +974,14 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
909
974
  };
910
975
  try {
911
976
  if ((await tables[collection.table].updateOne({ challenge }, { $set: setStage })).matchedCount === 0) {
912
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
977
+ const err = new _prosopo_common.ProsopoError({
978
+ code: "DB_QUERY_FAILED",
979
+ errorSite: "DBSE-27",
980
+ message: "Failed to get captcha",
913
981
  context: {
914
982
  challenge,
915
983
  ...setStage
916
- },
917
- logger: this.logger
984
+ }
918
985
  });
919
986
  this.logger.info(() => ({
920
987
  err,
@@ -931,13 +998,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
931
998
  }));
932
999
  this.streamInteractiveUpdate(collection, challenge);
933
1000
  } catch (error) {
934
- const err = new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
1001
+ const err = new _prosopo_common.ProsopoError({
1002
+ code: "DB_QUERY_FAILED",
1003
+ errorSite: "DBSE-28",
1004
+ message: "Failed to update captcha",
1005
+ cause: error,
935
1006
  context: {
936
- error,
937
1007
  challenge,
938
1008
  ...setStage
939
- },
940
- logger: this.logger
1009
+ }
941
1010
  });
942
1011
  this.logger.error(() => ({
943
1012
  err,
@@ -1195,12 +1264,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1195
1264
  $unset: { pendingStage: 1 }
1196
1265
  }).then(() => {}));
1197
1266
  } catch (err) {
1198
- throw new _prosopo_common.ProsopoDBError("DATABASE.SESSION_STORE_FAILED", {
1199
- context: {
1200
- error: err,
1201
- sessionId: sessionRecord.sessionId
1202
- },
1203
- logger: this.logger
1267
+ throw new _prosopo_common.ProsopoError({
1268
+ code: "DB_QUERY_FAILED",
1269
+ errorSite: "DBSE-29",
1270
+ message: "Failed to store session",
1271
+ cause: err,
1272
+ context: { sessionId: sessionRecord.sessionId }
1204
1273
  });
1205
1274
  }
1206
1275
  }
@@ -1281,12 +1350,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1281
1350
  pendingStage: true
1282
1351
  }).lean() || void 0;
1283
1352
  } catch (err) {
1284
- throw new _prosopo_common.ProsopoDBError("DATABASE.SESSION_CHECK_REMOVE_FAILED", {
1285
- context: {
1286
- error: err,
1287
- sessionId
1288
- },
1289
- logger: this.logger
1353
+ throw new _prosopo_common.ProsopoError({
1354
+ code: "DB_QUERY_FAILED",
1355
+ errorSite: "DBSE-30",
1356
+ message: "Failed to check and remove session",
1357
+ cause: err,
1358
+ context: { sessionId }
1290
1359
  });
1291
1360
  }
1292
1361
  }
@@ -1301,12 +1370,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1301
1370
  pendingStage: true
1302
1371
  } })).modifiedCount > 0;
1303
1372
  } catch (err) {
1304
- throw new _prosopo_common.ProsopoDBError("DATABASE.SESSION_GET_FAILED", {
1305
- context: {
1306
- error: err,
1307
- sessionId
1308
- },
1309
- logger: this.logger
1373
+ throw new _prosopo_common.ProsopoError({
1374
+ code: "DB_QUERY_FAILED",
1375
+ errorSite: "DBSE-31",
1376
+ message: "Failed to get session",
1377
+ cause: err,
1378
+ context: { sessionId }
1310
1379
  });
1311
1380
  }
1312
1381
  }
@@ -1337,12 +1406,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1337
1406
  }).catch(() => {});
1338
1407
  }
1339
1408
  } catch (err) {
1340
- throw new _prosopo_common.ProsopoDBError("DATABASE.SESSION_GET_FAILED", {
1341
- context: {
1342
- error: err,
1343
- sessionId
1344
- },
1345
- logger: this.logger
1409
+ throw new _prosopo_common.ProsopoError({
1410
+ code: "DB_QUERY_FAILED",
1411
+ errorSite: "DBSE-32",
1412
+ message: "Failed to get session",
1413
+ cause: err,
1414
+ context: { sessionId }
1346
1415
  });
1347
1416
  }
1348
1417
  }
@@ -1362,13 +1431,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1362
1431
  pendingStage: true
1363
1432
  } }], { updatePipeline: true });
1364
1433
  } catch (err) {
1365
- throw new _prosopo_common.ProsopoDBError("DATABASE.SESSION_GET_FAILED", {
1434
+ throw new _prosopo_common.ProsopoError({
1435
+ code: "DB_QUERY_FAILED",
1436
+ errorSite: "DBSE-33",
1437
+ message: "Failed to get session",
1438
+ cause: err,
1366
1439
  context: {
1367
- error: err,
1368
1440
  sessionId,
1369
1441
  stage
1370
- },
1371
- logger: this.logger
1442
+ }
1372
1443
  });
1373
1444
  }
1374
1445
  }
@@ -1395,12 +1466,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1395
1466
  try {
1396
1467
  return (await this.tables.session.updateOne({ sessionId }, [{ $set: setStage }], { updatePipeline: true })).matchedCount > 0;
1397
1468
  } catch (err) {
1398
- throw new _prosopo_common.ProsopoDBError("DATABASE.SESSION_GET_FAILED", {
1399
- context: {
1400
- error: err,
1401
- sessionId
1402
- },
1403
- logger: this.logger
1469
+ throw new _prosopo_common.ProsopoError({
1470
+ code: "DB_QUERY_FAILED",
1471
+ errorSite: "DBSE-34",
1472
+ message: "Failed to get session",
1473
+ cause: err,
1474
+ context: { sessionId }
1404
1475
  });
1405
1476
  }
1406
1477
  }
@@ -1421,12 +1492,12 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1421
1492
  try {
1422
1493
  return await this.tables.session.findOne(filter).lean() || void 0;
1423
1494
  } catch (err) {
1424
- throw new _prosopo_common.ProsopoDBError("DATABASE.SESSION_GET_FAILED", {
1425
- context: {
1426
- error: err,
1427
- userSitekeyIpHash
1428
- },
1429
- logger: this.logger
1495
+ throw new _prosopo_common.ProsopoError({
1496
+ code: "DB_QUERY_FAILED",
1497
+ errorSite: "DBSE-35",
1498
+ message: "Failed to get session",
1499
+ cause: err,
1500
+ context: { userSitekeyIpHash }
1430
1501
  });
1431
1502
  }
1432
1503
  }
@@ -1463,10 +1534,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1463
1534
  * @description Store a Dapp User's pending record
1464
1535
  */
1465
1536
  async storePendingImageCommitment(userAccount, requestHash, salt, deadlineTimestamp, requestedAtTimestamp, ipAddress, threshold, sessionId, ipInfo) {
1466
- if (!(0, _polkadot_util_is.isHex)(requestHash)) throw new _prosopo_common.ProsopoDBError("DATABASE.INVALID_HASH", { context: {
1467
- failedFuncName: this.storePendingImageCommitment.name,
1468
- requestHash
1469
- } });
1537
+ if (!(0, _polkadot_util_is.isHex)(requestHash)) throw new _prosopo_common.ProsopoError({
1538
+ code: "INVALID_DATA",
1539
+ errorSite: "DBSE-36",
1540
+ message: "Invalid hash",
1541
+ context: {
1542
+ failedFuncName: this.storePendingImageCommitment.name,
1543
+ requestHash
1544
+ }
1545
+ });
1470
1546
  const pendingRecord = {
1471
1547
  userAccount,
1472
1548
  pending: true,
@@ -1495,10 +1571,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1495
1571
  * @description Get a user's pending record
1496
1572
  */
1497
1573
  async getPendingImageCommitment(requestHash) {
1498
- if (!(0, _polkadot_util_is.isHex)(requestHash)) throw new _prosopo_common.ProsopoDBError("DATABASE.INVALID_HASH", { context: {
1499
- failedFuncName: this.getPendingImageCommitment.name,
1500
- requestHash
1501
- } });
1574
+ if (!(0, _polkadot_util_is.isHex)(requestHash)) throw new _prosopo_common.ProsopoError({
1575
+ code: "INVALID_DATA",
1576
+ errorSite: "DBSE-37",
1577
+ message: "Invalid hash",
1578
+ context: {
1579
+ failedFuncName: this.getPendingImageCommitment.name,
1580
+ requestHash
1581
+ }
1582
+ });
1502
1583
  const doc = await this.tables?.commitment.findOne({
1503
1584
  requestHash,
1504
1585
  pending: true
@@ -1514,19 +1595,29 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1514
1595
  sessionId: doc.sessionId,
1515
1596
  threshold: doc.threshold
1516
1597
  };
1517
- throw new _prosopo_common.ProsopoDBError("DATABASE.PENDING_RECORD_NOT_FOUND", { context: {
1518
- failedFuncName: this.getPendingImageCommitment.name,
1519
- requestHash
1520
- } });
1598
+ throw new _prosopo_common.ProsopoError({
1599
+ code: "RECORD_NOT_FOUND",
1600
+ errorSite: "DBSE-38",
1601
+ message: "No pending record found",
1602
+ context: {
1603
+ failedFuncName: this.getPendingImageCommitment.name,
1604
+ requestHash
1605
+ }
1606
+ });
1521
1607
  }
1522
1608
  /**
1523
1609
  * @description Mark a pending request as used
1524
1610
  */
1525
1611
  async updatePendingImageCommitmentStatus(requestHash) {
1526
- if (!(0, _polkadot_util_is.isHex)(requestHash)) throw new _prosopo_common.ProsopoDBError("DATABASE.INVALID_HASH", { context: {
1527
- failedFuncName: this.updatePendingImageCommitmentStatus.name,
1528
- requestHash
1529
- } });
1612
+ if (!(0, _polkadot_util_is.isHex)(requestHash)) throw new _prosopo_common.ProsopoError({
1613
+ code: "INVALID_DATA",
1614
+ errorSite: "DBSE-39",
1615
+ message: "Invalid hash",
1616
+ context: {
1617
+ failedFuncName: this.updatePendingImageCommitmentStatus.name,
1618
+ requestHash
1619
+ }
1620
+ });
1530
1621
  return (await this.getTables().commitment.updateOne({
1531
1622
  requestHash,
1532
1623
  pending: true
@@ -1542,7 +1633,11 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1542
1633
  };
1543
1634
  const docs = await this.tables?.captcha.find(filter).lean();
1544
1635
  if (docs) return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
1545
- throw new _prosopo_common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED");
1636
+ throw new _prosopo_common.ProsopoError({
1637
+ code: "DB_QUERY_FAILED",
1638
+ errorSite: "DBSE-40",
1639
+ message: "Failed to get captcha"
1640
+ });
1546
1641
  }
1547
1642
  /**
1548
1643
  * @description Get all dapp user solutions by captchaIds
@@ -1551,7 +1646,11 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1551
1646
  const filter = { captchaId: { $in: captchaId } };
1552
1647
  const docs = await this.tables?.usersolution?.find(filter).lean();
1553
1648
  if (docs) return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
1554
- throw new _prosopo_common.ProsopoDBError("DATABASE.SOLUTION_GET_FAILED");
1649
+ throw new _prosopo_common.ProsopoError({
1650
+ code: "DB_QUERY_FAILED",
1651
+ errorSite: "DBSE-41",
1652
+ message: "Failed to get solution"
1653
+ });
1555
1654
  }
1556
1655
  async getDatasetIdWithSolvedCaptchasOfSizeN(solvedCaptchaCount) {
1557
1656
  const docs = await this.tables?.solution.aggregate([
@@ -1564,13 +1663,22 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1564
1663
  { $sample: { size: 1 } }
1565
1664
  ]);
1566
1665
  if (docs?.length) return docs[0]._id;
1567
- throw new _prosopo_common.ProsopoDBError("DATABASE.DATASET_WITH_SOLUTIONS_GET_FAILED");
1666
+ throw new _prosopo_common.ProsopoError({
1667
+ code: "DATASET_INVALID",
1668
+ errorSite: "DBSE-42",
1669
+ message: "No datasets found with required number of solutions"
1670
+ });
1568
1671
  }
1569
1672
  async getRandomSolvedCaptchasFromSingleDataset(datasetId, size) {
1570
- if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoDBError("DATABASE.INVALID_HASH", { context: {
1571
- failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
1572
- datasetId
1573
- } });
1673
+ if (!(0, _polkadot_util_is.isHex)(datasetId)) throw new _prosopo_common.ProsopoError({
1674
+ code: "INVALID_DATA",
1675
+ errorSite: "DBSE-43",
1676
+ message: "Invalid hash",
1677
+ context: {
1678
+ failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
1679
+ datasetId
1680
+ }
1681
+ });
1574
1682
  const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
1575
1683
  const docs = await this.tables?.solution.aggregate([
1576
1684
  { $match: { datasetId } },
@@ -1582,11 +1690,16 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1582
1690
  } }
1583
1691
  ]);
1584
1692
  if (docs?.length) return docs;
1585
- throw new _prosopo_common.ProsopoDBError("DATABASE.SOLUTION_GET_FAILED", { context: {
1586
- failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
1587
- datasetId,
1588
- size
1589
- } });
1693
+ throw new _prosopo_common.ProsopoError({
1694
+ code: "DB_QUERY_FAILED",
1695
+ errorSite: "DBSE-44",
1696
+ message: "Failed to get solution",
1697
+ context: {
1698
+ failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name,
1699
+ datasetId,
1700
+ size
1701
+ }
1702
+ });
1590
1703
  }
1591
1704
  /**
1592
1705
  * @description Get dapp user solution by ID
@@ -1596,10 +1709,15 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1596
1709
  const filter = { commitmentId };
1597
1710
  const doc = await this.tables?.usersolution?.findOne(filter, { _id: 0 }).lean();
1598
1711
  if (doc) return doc;
1599
- throw new _prosopo_common.ProsopoDBError("DATABASE.SOLUTION_GET_FAILED", { context: {
1600
- failedFuncName: this.getCaptchaById.name,
1601
- commitmentId
1602
- } });
1712
+ throw new _prosopo_common.ProsopoError({
1713
+ code: "DB_QUERY_FAILED",
1714
+ errorSite: "DBSE-45",
1715
+ message: "Failed to get solution",
1716
+ context: {
1717
+ failedFuncName: this.getCaptchaById.name,
1718
+ commitmentId
1719
+ }
1720
+ });
1603
1721
  }
1604
1722
  static {
1605
1723
  this.DAPP_USER_COMMITMENT_PROJECTION = {
@@ -1669,10 +1787,13 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1669
1787
  $unset: { pendingStage: 1 }
1670
1788
  }).then(() => {}));
1671
1789
  } catch (err) {
1672
- throw new _prosopo_common.ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", { context: {
1673
- error: err,
1674
- commitmentId
1675
- } });
1790
+ throw new _prosopo_common.ProsopoError({
1791
+ code: "DB_QUERY_FAILED",
1792
+ errorSite: "DBSE-46",
1793
+ message: "Failed to approve solution",
1794
+ cause: err,
1795
+ context: { commitmentId }
1796
+ });
1676
1797
  }
1677
1798
  }
1678
1799
  /**
@@ -1704,10 +1825,13 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1704
1825
  $unset: { pendingStage: 1 }
1705
1826
  }).then(() => {}));
1706
1827
  } catch (err) {
1707
- throw new _prosopo_common.ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", { context: {
1708
- error: err,
1709
- commitmentId
1710
- } });
1828
+ throw new _prosopo_common.ProsopoError({
1829
+ code: "DB_QUERY_FAILED",
1830
+ errorSite: "DBSE-47",
1831
+ message: "Failed to approve solution",
1832
+ cause: err,
1833
+ context: { commitmentId }
1834
+ });
1711
1835
  }
1712
1836
  }
1713
1837
  /**
@@ -1718,10 +1842,13 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1718
1842
  try {
1719
1843
  await this.tables?.usersolution?.updateMany({ captchaId: { $in: captchaIds } }, { $set: { processed: true } }, { upsert: false }).lean();
1720
1844
  } catch (err) {
1721
- throw new _prosopo_common.ProsopoDBError("DATABASE.SOLUTION_FLAG_FAILED", { context: {
1722
- error: err,
1723
- captchaIds
1724
- } });
1845
+ throw new _prosopo_common.ProsopoError({
1846
+ code: "DB_QUERY_FAILED",
1847
+ errorSite: "DBSE-48",
1848
+ message: "Failed to flag solution as processed",
1849
+ cause: err,
1850
+ context: { captchaIds }
1851
+ });
1725
1852
  }
1726
1853
  }
1727
1854
  /**
@@ -1733,10 +1860,13 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1733
1860
  const distinctCommitmentIds = [...new Set(commitmentIds)];
1734
1861
  await this.tables?.commitment?.updateMany({ id: { $in: distinctCommitmentIds } }, { $set: { processed: true } }, { upsert: false }).lean();
1735
1862
  } catch (err) {
1736
- throw new _prosopo_common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", { context: {
1737
- error: err,
1738
- commitmentIds
1739
- } });
1863
+ throw new _prosopo_common.ProsopoError({
1864
+ code: "DB_QUERY_FAILED",
1865
+ errorSite: "DBSE-49",
1866
+ message: "Failed to flag commitment as processed",
1867
+ cause: err,
1868
+ context: { commitmentIds }
1869
+ });
1740
1870
  }
1741
1871
  }
1742
1872
  /**
@@ -1819,14 +1949,22 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1819
1949
  await this.logger.debug(() => ({ msg: "No client updates to apply" }));
1820
1950
  return;
1821
1951
  }
1822
- await this.tables?.client.bulkWrite(ops);
1952
+ try {
1953
+ await this.tables?.client.bulkWrite(ops);
1954
+ } finally {
1955
+ require_clientRecordCache.clientRecordCache.clear();
1956
+ }
1823
1957
  }
1824
1958
  /**
1825
1959
  * @description Remove client records by account
1826
1960
  */
1827
1961
  async removeClientRecords(accounts) {
1828
1962
  if (!accounts || accounts.length === 0) return;
1829
- await this.tables?.client.deleteMany({ account: { $in: accounts } });
1963
+ try {
1964
+ await this.tables?.client.deleteMany({ account: { $in: accounts } });
1965
+ } finally {
1966
+ require_clientRecordCache.clientRecordCache.clear();
1967
+ }
1830
1968
  }
1831
1969
  /**
1832
1970
  * @description Get all client records
@@ -1838,13 +1976,18 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1838
1976
  * @description Get a client record
1839
1977
  */
1840
1978
  async getClientRecord(account) {
1979
+ const cacheKey = `${this.url}|${account}`;
1980
+ const cached = require_clientRecordCache.clientRecordCache.get(cacheKey);
1981
+ if (cached) return cached;
1841
1982
  const filter = { account };
1842
1983
  const doc = await this.tables?.client.findOne(filter, {
1843
1984
  account: 1,
1844
1985
  settings: 1,
1845
1986
  tier: 1
1846
1987
  }).lean();
1847
- return doc ? doc : void 0;
1988
+ if (!doc) return void 0;
1989
+ require_clientRecordCache.clientRecordCache.set(cacheKey, doc);
1990
+ return doc;
1848
1991
  }
1849
1992
  /**
1850
1993
  * Stores a decision machine artifact with a unique scope identifier.
@@ -1930,13 +2073,23 @@ var ProviderDatabase = class ProviderDatabase extends require_mongo.MongoDatabas
1930
2073
  return (await this.tables?.decisionMachine.deleteMany({}))?.deletedCount ?? 0;
1931
2074
  }
1932
2075
  async getSpamEmailDomain(domain) {
1933
- if (!this.tables?.spamEmailDomain) throw new _prosopo_common.ProsopoDBError("DATABASE.DATABASE_IMPORT_FAILED", { context: { failedFuncName: this.getSpamEmailDomain.name } });
2076
+ if (!this.tables?.spamEmailDomain) throw new _prosopo_common.ProsopoError({
2077
+ code: "DB_QUERY_FAILED",
2078
+ errorSite: "DBSE-50",
2079
+ message: "Failed to import database engine",
2080
+ context: { failedFuncName: this.getSpamEmailDomain.name }
2081
+ });
1934
2082
  const suffixCandidates = (0, _prosopo_util.buildDomainSuffixCandidates)(domain).slice(0, MAX_DOMAIN_SUFFIX_CANDIDATES);
1935
2083
  const query = suffixCandidates.length > 0 ? { domain: { $in: suffixCandidates } } : { domain };
1936
2084
  return await this.tables.spamEmailDomain.findOne(query).exec();
1937
2085
  }
1938
2086
  async bulkUpdateSpamEmailDomains(domains, upsert) {
1939
- if (!this.tables?.spamEmailDomain) throw new _prosopo_common.ProsopoDBError("DATABASE.DATABASE_IMPORT_FAILED", { context: { failedFuncName: this.bulkUpdateSpamEmailDomains.name } });
2087
+ if (!this.tables?.spamEmailDomain) throw new _prosopo_common.ProsopoError({
2088
+ code: "DB_QUERY_FAILED",
2089
+ errorSite: "DBSE-51",
2090
+ message: "Failed to import database engine",
2091
+ context: { failedFuncName: this.bulkUpdateSpamEmailDomains.name }
2092
+ });
1940
2093
  const bulkOps = domains.map((op) => ({ updateOne: {
1941
2094
  filter: op.filter,
1942
2095
  update: { $set: op.update },