@prosopo/database 3.14.0 → 3.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +4 -4
  2. package/.turbo/turbo-build$colon$tsc.log +16 -16
  3. package/.turbo/turbo-build.log +5 -5
  4. package/CHANGELOG.md +45 -0
  5. package/dist/cjs/databases/captcha.cjs +51 -5
  6. package/dist/cjs/databases/provider.cjs +96 -31
  7. package/dist/databases/captcha.d.ts +2 -0
  8. package/dist/databases/captcha.d.ts.map +1 -1
  9. package/dist/databases/captcha.js +51 -5
  10. package/dist/databases/captcha.js.map +1 -1
  11. package/dist/databases/provider.d.ts.map +1 -1
  12. package/dist/databases/provider.js +96 -31
  13. package/dist/databases/provider.js.map +1 -1
  14. package/dist/tests/integration/providedIpPipelineCast.integration.test.d.ts +2 -0
  15. package/dist/tests/integration/providedIpPipelineCast.integration.test.d.ts.map +1 -0
  16. package/dist/tests/integration/providedIpPipelineCast.integration.test.js +139 -0
  17. package/dist/tests/integration/providedIpPipelineCast.integration.test.js.map +1 -0
  18. package/dist/tests/integration/randomSamplingPerformance.integration.test.d.ts +2 -0
  19. package/dist/tests/integration/randomSamplingPerformance.integration.test.d.ts.map +1 -0
  20. package/dist/tests/integration/randomSamplingPerformance.integration.test.js +248 -0
  21. package/dist/tests/integration/randomSamplingPerformance.integration.test.js.map +1 -0
  22. package/dist/tests/integration/sessionRecordProjection.integration.test.d.ts +2 -0
  23. package/dist/tests/integration/sessionRecordProjection.integration.test.d.ts.map +1 -0
  24. package/dist/tests/integration/sessionRecordProjection.integration.test.js +156 -0
  25. package/dist/tests/integration/sessionRecordProjection.integration.test.js.map +1 -0
  26. package/package.json +10 -9
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/database@3.14.0 build:cjs
2
+ > @prosopo/database@3.14.2 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -46,7 +46,7 @@ rendering chunks...
46
46
  dist/cjs/databases/client.cjs  1.91 kB
47
47
  dist/cjs/databases/centralDbStreamer.cjs  4.20 kB
48
48
  dist/cjs/base/mongo.cjs  4.58 kB
49
- dist/cjs/databases/captcha.cjs  5.87 kB
49
+ dist/cjs/databases/captcha.cjs  7.87 kB
50
50
  dist/cjs/redisCache.cjs 12.40 kB
51
- dist/cjs/databases/provider.cjs 66.79 kB
52
- ✓ built in 528ms
51
+ dist/cjs/databases/provider.cjs 69.18 kB
52
+ ✓ built in 468ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/database@3.14.0 build:tsc
2
+ > @prosopo/database@3.14.2 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 2:03:36 PM - Projects in this build:
5
+ 1:48:40 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -17,31 +17,31 @@
17
17
  * ../types-database/tsconfig.json
18
18
  * tsconfig.json
19
19
 
20
- 2:03:36 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
20
+ 1:48:40 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
21
21
 
22
- 2:03:36 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/util.ts' is older than output '../locale/tsconfig.tsbuildinfo'
22
+ 1:48:40 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
23
23
 
24
- 2:03:36 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
24
+ 1:48:40 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
25
25
 
26
- 2:03:36 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
26
+ 1:48:40 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
27
27
 
28
- 2:03:36 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
28
+ 1:48:40 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
29
29
 
30
- 2:03:36 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
30
+ 1:48:40 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
31
31
 
32
- 2:03:36 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
32
+ 1:48:40 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
33
33
 
34
- 2:03:36 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
34
+ 1:48:40 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
35
35
 
36
- 2:03:36 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
36
+ 1:48:40 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/tests/testRedisConnection.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
37
37
 
38
- 2:03:37 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
38
+ 1:48:40 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
39
39
 
40
- 2:03:37 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/rule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
40
+ 1:48:40 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
41
41
 
42
- 2:03:37 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/types/bannedDomain.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
42
+ 1:48:40 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/index.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
43
43
 
44
- 2:03:37 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
44
+ 1:48:40 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
45
45
 
46
- 2:03:37 PM - Building project '/home/runner/work/captcha/captcha/packages/database/tsconfig.json'...
46
+ 1:48:40 PM - Building project '/home/runner/work/captcha/captcha/packages/database/tsconfig.json'...
47
47
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/database@3.14.0 build
2
+ > @prosopo/database@3.14.2 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/database@3.14.0 build:cross-env
6
+ > @prosopo/database@3.14.2 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -50,7 +50,7 @@ rendering chunks...
50
50
  dist/databases/client.js  1.79 kB
51
51
  dist/databases/centralDbStreamer.js  4.09 kB
52
52
  dist/base/mongo.js  4.14 kB
53
- dist/databases/captcha.js  5.45 kB
53
+ dist/databases/captcha.js  7.45 kB
54
54
  dist/redisCache.js 12.30 kB
55
- dist/databases/provider.js 66.57 kB
56
- ✓ built in 524ms
55
+ dist/databases/provider.js 68.96 kB
56
+ ✓ built in 472ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # @prosopo/database
2
2
 
3
+ ## 3.14.2
4
+ ### Patch Changes
5
+
6
+ - 4626340: perf(provider): cut p95 on /captcha/frictionless and /captcha/image
7
+
8
+ Replaces the `$match → $sample` random-captcha lookup with an indexed
9
+ range scan over a new `{datasetId, solved, randomKey}` compound index;
10
+ reorders the `sampleContextEntropy` aggregation so `$sample` runs
11
+ before `$lookup`; batches three pairs of independent awaits in the
12
+ frictionless handler via `Promise.all`. Adds an integration test
13
+ asserting via `.explain()` and wall-clock timing that the new paths
14
+ are quantifiably faster. The legacy aggregation remains as a fallback
15
+ in `getRandomCaptcha` so deployment can precede the
16
+ providerBackfillCaptchaRandomKey rollout.
17
+ - 5f47c42: fix(database): widen `getSessionRecordBySessionId` projection so post-PoW routing escalations stop failing with `DATABASE.SESSION_STORE_FAILED`. The projection added in #2393 dropped `token`, `score`, `threshold`, `providerSelectEntropy`, `ipAddress`, etc., which `buildEscalation` forwards into a new session via `frictionlessManager.createSession`. With routing machines enabled for edge (2026-06-16) every escalation 500'd. Headers are now enumerated key-by-key so `headers.x-tls-clienthello` (multi-KB TLS ClientHello) stays out of the read.
18
+ - Updated dependencies [4626340]
19
+ - Updated dependencies [6962179]
20
+ - @prosopo/types@4.6.1
21
+ - @prosopo/types-database@4.10.2
22
+ - @prosopo/user-access-policy@3.10.2
23
+
24
+ ## 3.14.1
25
+ ### Patch Changes
26
+
27
+ - 44eaebf: Fix `providedIp.lower` being persisted as BSON `Long` instead of `Decimal128` on `usercommitments`, which aborted the central-streaming sweep on a `CastError` and stopped *all* records from being streamed off the affected provider node.
28
+
29
+ Three changes, each addressing one half of the regression introduced by #2681 ("lifecycle timestamps + submit→verify recency window"):
30
+
31
+ - **provider.ts** — `updateDappUserCommitment` and `updatePuzzleCaptchaRecord` now branch between pipeline-form (`updateOne(filter, [{ $set: ... }])`) and ordinary `$set`. The pipeline form bypasses Mongoose schema casting, so a `bigint` IP half lands on disk as BSON Int64 (Long) rather than going through the `bigint → string → Decimal128` setter on `CompositeIpAddressRecordSchemaObj`. The pipeline form is only used when an `$ifNull` is genuinely required; the `imgCaptchaTasks` side-update call site only carries `providedIp`/`metadata`, so it now takes the ordinary path and the setter runs.
32
+ - **captcha.ts** — `CaptchaDatabase.saveCaptchas` normalises `ipAddress` / `providedIp` composite-IP halves on each lean doc before the `bulkWrite`. `Model.bulkWrite` skips setters, so a Long-typed `lower` (whose unsigned value exceeds `Number.MAX_SAFE_INTEGER` — every IPv6 lower with bit 63 set) hits the Decimal128 caster raw and the ordered bulkWrite aborts the entire batch. Normalisation converts the Long via `Long.fromBits(low, high, /*unsigned*/ true).toString() → Decimal128`, matching what the original schema setter would have produced.
33
+ - **types-database/provider.ts** — `CompositeIpAddressRecordSchemaObj.lower/upper` setters extracted into a shared `normaliseIpHalf` that also handles BSON `Long`. Defensive cover for the `updateOne`/`save`/`create` paths the streamer uses (those *do* run setters); does not run under `bulkWrite`, which is why the captcha.ts normalisation is also needed.
34
+
35
+ Long-class checks use duck-typed `_bsontype === "Long"` rather than `instanceof Long` to stay robust against hoisting differences between the top-level `bson` import and the copy the MongoDB driver uses for deserialisation.
36
+
37
+ Regression test under `packages/database/src/tests/integration/providedIpPipelineCast.integration.test.ts` pins both halves: ordinary `$set` writes Decimal128, `saveCaptchas` drains a Long-poisoned lean doc through to a clean Decimal128 at central, and a negative-control test keeps the underlying Mongoose pipeline-cast behaviour visible so a future regression on either side is unambiguous.
38
+ - Updated dependencies [55b1388]
39
+ - Updated dependencies [44eaebf]
40
+ - @prosopo/util@3.3.0
41
+ - @prosopo/types@4.6.0
42
+ - @prosopo/types-database@4.10.1
43
+ - @prosopo/logger@1.0.3
44
+ - @prosopo/user-access-policy@3.10.1
45
+ - @prosopo/common@3.1.39
46
+ - @prosopo/redis-client@1.0.24
47
+
3
48
  ## 3.14.0
4
49
  ### Minor Changes
5
50
 
@@ -3,9 +3,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const common = require("@prosopo/common");
4
4
  const logger$1 = require("@prosopo/logger");
5
5
  const typesDatabase = require("@prosopo/types-database");
6
+ const bson = require("bson");
6
7
  require("../base/index.cjs");
7
8
  const mongo = require("../base/mongo.cjs");
8
9
  var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
10
+ const isBsonLong = (value) => typeof value === "object" && value !== null && "_bsontype" in value && value._bsontype === "Long";
9
11
  const logger = logger$1.getLogger("info", typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("databases/captcha.cjs", document.baseURI).href);
10
12
  var TableNames = /* @__PURE__ */ ((TableNames2) => {
11
13
  TableNames2["frictionlessToken"] = "frictionlessToken";
@@ -85,6 +87,48 @@ class CaptchaDatabase extends mongo.MongoDatabase {
85
87
  await Promise.all(indexPromises);
86
88
  this.indexesEnsured = true;
87
89
  }
90
+ /**
91
+ * Convert a BSON `Long` (which Mongoose's Decimal128 caster rejects)
92
+ * into a Decimal128 with the *unsigned* numeric value — so a Long
93
+ * representing an IPv6 lower half with bit 63 set (signed Long shows
94
+ * as a negative integer) converts to a positive Decimal128 that
95
+ * matches what `bigint→string→Decimal128` would have produced if the
96
+ * schema setter had run on the original write.
97
+ *
98
+ * Production background: pipeline-form updates (`updateOne(filter,
99
+ * [{ $set: ... }])`) bypass Mongoose schema casting, so a `bigint`
100
+ * passed for an IP half is serialised by the driver as BSON Int64
101
+ * (Long) instead of going through the `Decimal128` setter. The
102
+ * central-streaming sweep below reads those docs via `.lean()` and
103
+ * tries to replay them with `bulkWrite`, but `bulkWrite` also skips
104
+ * setters — so the cast fires raw and throws. Normalising the lean
105
+ * doc here is the only place that's guaranteed to run before the
106
+ * bulkWrite sees it.
107
+ */
108
+ static normaliseCompositeIp(ip) {
109
+ if (!ip) return ip;
110
+ const normaliseHalf = (v) => {
111
+ if (isBsonLong(v)) {
112
+ const lng = v;
113
+ return bson.Decimal128.fromString(
114
+ bson.Long.fromBits(lng.low, lng.high, true).toString()
115
+ );
116
+ }
117
+ return v;
118
+ };
119
+ return {
120
+ ...ip,
121
+ lower: normaliseHalf(ip.lower),
122
+ upper: normaliseHalf(ip.upper)
123
+ };
124
+ }
125
+ static normaliseDocCompositeIps(doc) {
126
+ return {
127
+ ...doc,
128
+ ipAddress: CaptchaDatabase.normaliseCompositeIp(doc.ipAddress),
129
+ providedIp: CaptchaDatabase.normaliseCompositeIp(doc.providedIp)
130
+ };
131
+ }
88
132
  async saveCaptchas(sessionEvents, imageCaptchaEvents, powCaptchaEvents) {
89
133
  await this.connect();
90
134
  if (sessionEvents.length) {
@@ -93,7 +137,7 @@ class CaptchaDatabase extends mongo.MongoDatabase {
93
137
  const { _id, ...safeDoc } = document2;
94
138
  return {
95
139
  insertOne: {
96
- document: safeDoc
140
+ document: CaptchaDatabase.normaliseDocCompositeIps(safeDoc)
97
141
  }
98
142
  };
99
143
  })
@@ -110,10 +154,11 @@ class CaptchaDatabase extends mongo.MongoDatabase {
110
154
  const result = await this.tables.commitment.bulkWrite(
111
155
  imageCaptchaEvents.map((doc) => {
112
156
  const { _id, ...safeDoc } = doc;
157
+ const normalised = CaptchaDatabase.normaliseDocCompositeIps(safeDoc);
113
158
  return {
114
159
  updateOne: {
115
- filter: { id: safeDoc.id },
116
- update: { $set: safeDoc },
160
+ filter: { id: normalised.id },
161
+ update: { $set: normalised },
117
162
  upsert: true
118
163
  }
119
164
  };
@@ -133,10 +178,11 @@ class CaptchaDatabase extends mongo.MongoDatabase {
133
178
  const result = await this.tables.powcaptcha.bulkWrite(
134
179
  powCaptchaEvents.map((doc) => {
135
180
  const { _id, ...safeDoc } = doc;
181
+ const normalised = CaptchaDatabase.normaliseDocCompositeIps(safeDoc);
136
182
  return {
137
183
  updateOne: {
138
- filter: { challenge: safeDoc.challenge },
139
- update: { $set: safeDoc },
184
+ filter: { challenge: normalised.challenge },
185
+ update: { $set: normalised },
140
186
  upsert: true
141
187
  }
142
188
  };
@@ -262,7 +262,17 @@ class ProviderDatabase extends mongo.MongoDatabase {
262
262
  captchaDocs.map((captchaDoc) => ({
263
263
  updateOne: {
264
264
  filter: { captchaId: captchaDoc.captchaId },
265
- update: { $set: captchaDoc },
265
+ // `$setOnInsert` stamps `randomKey` once on the
266
+ // initial insert and leaves it untouched on
267
+ // re-imports of the same captchaId. See
268
+ // `getRandomCaptcha` and the
269
+ // providerBackfillCaptchaRandomKey playbook for
270
+ // the corresponding read path and one-shot
271
+ // backfill of pre-existing rows.
272
+ update: {
273
+ $set: captchaDoc,
274
+ $setOnInsert: { randomKey: Math.random() }
275
+ },
266
276
  upsert: true
267
277
  }
268
278
  }))
@@ -368,24 +378,35 @@ class ProviderDatabase extends mongo.MongoDatabase {
368
378
  });
369
379
  }
370
380
  const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
371
- const filter = { datasetId, solved };
372
- const cursor = this.tables?.captcha.aggregate([
373
- { $match: filter },
374
- { $sample: { size: sampleSize } },
375
- {
376
- $project: {
377
- datasetId: 1,
378
- datasetContentId: 1,
379
- captchaId: 1,
380
- captchaContentId: 1,
381
- items: 1,
382
- target: 1
383
- }
381
+ const projection = {
382
+ _id: 0,
383
+ datasetId: 1,
384
+ datasetContentId: 1,
385
+ captchaId: 1,
386
+ captchaContentId: 1,
387
+ items: 1,
388
+ target: 1
389
+ };
390
+ const baseFilter = { datasetId, solved };
391
+ const pivot = Math.random();
392
+ const head = await this.tables?.captcha.find({ ...baseFilter, randomKey: { $gte: pivot } }, projection).sort({ randomKey: 1 }).limit(sampleSize).lean() ?? [];
393
+ let docs = head;
394
+ if (docs.length < sampleSize) {
395
+ const tail = await this.tables?.captcha.find({ ...baseFilter, randomKey: { $lt: pivot } }, projection).sort({ randomKey: 1 }).limit(sampleSize - docs.length).lean() ?? [];
396
+ docs = docs.concat(tail);
397
+ }
398
+ if (docs.length === 0) {
399
+ const fallback = await this.tables?.captcha.aggregate([
400
+ { $match: baseFilter },
401
+ { $sample: { size: sampleSize } },
402
+ { $project: projection }
403
+ ]).exec() ?? [];
404
+ if (fallback.length > 0) {
405
+ return fallback.map(({ _id, ...keep }) => keep);
384
406
  }
385
- ]);
386
- const docs = await cursor;
387
- if (docs?.length) {
388
- return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
407
+ }
408
+ if (docs.length > 0) {
409
+ return docs;
389
410
  }
390
411
  throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
391
412
  context: {
@@ -946,26 +967,33 @@ class ProviderDatabase extends mongo.MongoDatabase {
946
967
  async updatePuzzleCaptchaRecord(challenge, updates) {
947
968
  const tables = this.getTables();
948
969
  const timestamp = /* @__PURE__ */ new Date();
949
- const setStage = {
970
+ const baseSet = {
950
971
  ...updates,
951
972
  pendingStage: true
952
973
  };
974
+ const pipelineExprs = {};
953
975
  if (updates.serverChecked === true) {
954
- setStage.verifiedAtTimestamp = {
976
+ pipelineExprs.verifiedAtTimestamp = {
955
977
  $ifNull: ["$verifiedAtTimestamp", timestamp]
956
978
  };
957
979
  }
958
980
  if (updates.userSubmitted === true) {
959
- setStage.submittedAtTimestamp = {
981
+ pipelineExprs.submittedAtTimestamp = {
960
982
  $ifNull: ["$submittedAtTimestamp", timestamp]
961
983
  };
962
984
  }
963
985
  if (updates.result?.status === types.CaptchaStatus.disapproved) {
964
- setStage.failedAtTimestamp = {
986
+ pipelineExprs.failedAtTimestamp = {
965
987
  $ifNull: ["$failedAtTimestamp", timestamp]
966
988
  };
967
989
  }
968
- await tables.puzzlecaptcha.updateOne({ challenge }, [{ $set: setStage }]);
990
+ if (Object.keys(pipelineExprs).length === 0) {
991
+ await tables.puzzlecaptcha.updateOne({ challenge }, { $set: baseSet });
992
+ return;
993
+ }
994
+ await tables.puzzlecaptcha.updateOne({ challenge }, [
995
+ { $set: { ...baseSet, ...pipelineExprs } }
996
+ ]);
969
997
  }
970
998
  /** @description Get serverChecked Dapp User image captcha commitments from the commitments table
971
999
  */
@@ -1032,27 +1060,34 @@ class ProviderDatabase extends mongo.MongoDatabase {
1032
1060
  async updateDappUserCommitment(commitmentId, updates) {
1033
1061
  const filter = { id: commitmentId };
1034
1062
  const timestamp = /* @__PURE__ */ new Date();
1035
- const setStage = {
1063
+ const baseSet = {
1036
1064
  ...updates,
1037
1065
  lastUpdatedAtTimestamp: timestamp,
1038
1066
  pendingStage: true
1039
1067
  };
1068
+ const pipelineExprs = {};
1040
1069
  if (updates.userSubmitted === true) {
1041
- setStage.submittedAtTimestamp = {
1070
+ pipelineExprs.submittedAtTimestamp = {
1042
1071
  $ifNull: ["$submittedAtTimestamp", timestamp]
1043
1072
  };
1044
1073
  }
1045
1074
  if (updates.serverChecked === true) {
1046
- setStage.verifiedAtTimestamp = {
1075
+ pipelineExprs.verifiedAtTimestamp = {
1047
1076
  $ifNull: ["$verifiedAtTimestamp", timestamp]
1048
1077
  };
1049
1078
  }
1050
1079
  if (updates.result?.status === types.CaptchaStatus.disapproved) {
1051
- setStage.failedAtTimestamp = {
1080
+ pipelineExprs.failedAtTimestamp = {
1052
1081
  $ifNull: ["$failedAtTimestamp", timestamp]
1053
1082
  };
1054
1083
  }
1055
- await this.tables?.commitment.updateOne(filter, [{ $set: setStage }]);
1084
+ if (Object.keys(pipelineExprs).length === 0) {
1085
+ await this.tables?.commitment.updateOne(filter, { $set: baseSet });
1086
+ return;
1087
+ }
1088
+ await this.tables?.commitment.updateOne(filter, [
1089
+ { $set: { ...baseSet, ...pipelineExprs } }
1090
+ ]);
1056
1091
  }
1057
1092
  /**
1058
1093
  * @description Get Dapp User PoW captcha commitments that have not been counted towards the client's total
@@ -1194,11 +1229,41 @@ class ProviderDatabase extends mongo.MongoDatabase {
1194
1229
  const filter = { sessionId };
1195
1230
  const doc = await this.tables.session.findOne(filter, {
1196
1231
  sessionId: 1,
1197
- ipInfo: 1,
1232
+ token: 1,
1233
+ score: 1,
1234
+ threshold: 1,
1198
1235
  scoreComponents: 1,
1236
+ providerSelectEntropy: 1,
1237
+ ipAddress: 1,
1238
+ ipInfo: 1,
1199
1239
  webView: 1,
1240
+ iFrame: 1,
1241
+ decryptedHeadHash: 1,
1242
+ siteKey: 1,
1200
1243
  reason: 1,
1201
- decryptedHeadHash: 1
1244
+ mode: 1,
1245
+ solvedImagesCount: 1,
1246
+ userSitekeyIpHash: 1,
1247
+ simdReadings: 1,
1248
+ dnsEvent: 1,
1249
+ "headers.user-agent": 1,
1250
+ "headers.accept": 1,
1251
+ "headers.accept-language": 1,
1252
+ "headers.accept-encoding": 1,
1253
+ "headers.sec-ch-ua": 1,
1254
+ "headers.sec-ch-ua-mobile": 1,
1255
+ "headers.sec-ch-ua-platform": 1,
1256
+ "headers.sec-ch-ua-platform-version": 1,
1257
+ "headers.sec-fetch-dest": 1,
1258
+ "headers.sec-fetch-mode": 1,
1259
+ "headers.sec-fetch-site": 1,
1260
+ "headers.sec-fetch-user": 1,
1261
+ "headers.referer": 1,
1262
+ "headers.origin": 1,
1263
+ "headers.prosopo-user": 1,
1264
+ "headers.prosopo-site-key": 1,
1265
+ "headers.prosopo-type": 1,
1266
+ "headers.x-tls-version": 1
1202
1267
  }).lean();
1203
1268
  return doc || void 0;
1204
1269
  }
@@ -2052,6 +2117,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
2052
2117
  }
2053
2118
  }
2054
2119
  },
2120
+ { $sample: { size: max } },
2055
2121
  {
2056
2122
  $lookup: {
2057
2123
  from: "sessions",
@@ -2081,7 +2147,6 @@ class ProviderDatabase extends mongo.MongoDatabase {
2081
2147
  });
2082
2148
  }
2083
2149
  pipeline.push(
2084
- { $limit: max },
2085
2150
  { $sample: { size } },
2086
2151
  {
2087
2152
  $project: {
@@ -15,6 +15,8 @@ export declare class CaptchaDatabase extends MongoDatabase implements ICaptchaDa
15
15
  connect(): Promise<void>;
16
16
  getTables(): Tables<TableNames>;
17
17
  ensureIndexes(): Promise<void>;
18
+ private static normaliseCompositeIp;
19
+ private static normaliseDocCompositeIps;
18
20
  saveCaptchas(sessionEvents: StoredSession[], imageCaptchaEvents: UserCommitmentRecord[], powCaptchaEvents: PoWCaptchaRecord[]): Promise<void>;
19
21
  getCaptchas(filter?: RootFilterQuery<CaptchaProperties>, limit?: number): Promise<{
20
22
  userCommitmentRecords: UserCommitmentRecord[];
@@ -1 +1 @@
1
- {"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/databases/captcha.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,MAAM,EAAa,MAAM,iBAAiB,CAAC;AACzD,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EAErB,KAAK,aAAa,EAGlB,KAAK,MAAM,EACX,KAAK,oBAAoB,EACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD,aAAK,UAAU;IACd,iBAAiB,sBAAsB;IACvC,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,UAAU,eAAe;CACzB;AAoBD,qBAAa,eAAgB,SAAQ,aAAc,YAAW,gBAAgB;IAC7E,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,OAAO,CAAC,cAAc,CAAS;gBAG9B,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM;IAMD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC;IAUzB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC9B,YAAY,CACjB,aAAa,EAAE,aAAa,EAAE,EAC9B,kBAAkB,EAAE,oBAAoB,EAAE,EAC1C,gBAAgB,EAAE,gBAAgB,EAAE;IA2E/B,WAAW,CAChB,MAAM,GAAE,eAAe,CAAC,iBAAiB,CAAM,EAC/C,KAAK,SAAM,GACT,OAAO,CAAC;QACV,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;QAC9C,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;KACtC,CAAC;CAgCF"}
1
+ {"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/databases/captcha.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,MAAM,EAAa,MAAM,iBAAiB,CAAC;AACzD,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EAErB,KAAK,aAAa,EAGlB,KAAK,MAAM,EACX,KAAK,oBAAoB,EACzB,MAAM,yBAAyB,CAAC;AAajC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD,aAAK,UAAU;IACd,iBAAiB,sBAAsB;IACvC,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,UAAU,eAAe;CACzB;AAoBD,qBAAa,eAAgB,SAAQ,aAAc,YAAW,gBAAgB;IAC7E,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,OAAO,CAAC,cAAc,CAAS;gBAG9B,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM;IAMD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC;IAUzB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAqDpC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAoBnC,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAajC,YAAY,CACjB,aAAa,EAAE,aAAa,EAAE,EAC9B,kBAAkB,EAAE,oBAAoB,EAAE,EAC1C,gBAAgB,EAAE,gBAAgB,EAAE;IA6E/B,WAAW,CAChB,MAAM,GAAE,eAAe,CAAC,iBAAiB,CAAM,EAC/C,KAAK,SAAM,GACT,OAAO,CAAC;QACV,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;QAC9C,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;KACtC,CAAC;CAgCF"}
@@ -1,8 +1,10 @@
1
1
  import { ProsopoDBError } from "@prosopo/common";
2
2
  import { getLogger } from "@prosopo/logger";
3
3
  import { StoredSessionRecordSchema, StoredPoWCaptchaRecordSchema, StoredUserCommitmentRecordSchema } from "@prosopo/types-database";
4
+ import { Decimal128, Long } from "bson";
4
5
  import "../base/index.js";
5
6
  import { MongoDatabase } from "../base/mongo.js";
7
+ const isBsonLong = (value) => typeof value === "object" && value !== null && "_bsontype" in value && value._bsontype === "Long";
6
8
  const logger = getLogger("info", import.meta.url);
7
9
  var TableNames = /* @__PURE__ */ ((TableNames2) => {
8
10
  TableNames2["frictionlessToken"] = "frictionlessToken";
@@ -82,6 +84,48 @@ class CaptchaDatabase extends MongoDatabase {
82
84
  await Promise.all(indexPromises);
83
85
  this.indexesEnsured = true;
84
86
  }
87
+ /**
88
+ * Convert a BSON `Long` (which Mongoose's Decimal128 caster rejects)
89
+ * into a Decimal128 with the *unsigned* numeric value — so a Long
90
+ * representing an IPv6 lower half with bit 63 set (signed Long shows
91
+ * as a negative integer) converts to a positive Decimal128 that
92
+ * matches what `bigint→string→Decimal128` would have produced if the
93
+ * schema setter had run on the original write.
94
+ *
95
+ * Production background: pipeline-form updates (`updateOne(filter,
96
+ * [{ $set: ... }])`) bypass Mongoose schema casting, so a `bigint`
97
+ * passed for an IP half is serialised by the driver as BSON Int64
98
+ * (Long) instead of going through the `Decimal128` setter. The
99
+ * central-streaming sweep below reads those docs via `.lean()` and
100
+ * tries to replay them with `bulkWrite`, but `bulkWrite` also skips
101
+ * setters — so the cast fires raw and throws. Normalising the lean
102
+ * doc here is the only place that's guaranteed to run before the
103
+ * bulkWrite sees it.
104
+ */
105
+ static normaliseCompositeIp(ip) {
106
+ if (!ip) return ip;
107
+ const normaliseHalf = (v) => {
108
+ if (isBsonLong(v)) {
109
+ const lng = v;
110
+ return Decimal128.fromString(
111
+ Long.fromBits(lng.low, lng.high, true).toString()
112
+ );
113
+ }
114
+ return v;
115
+ };
116
+ return {
117
+ ...ip,
118
+ lower: normaliseHalf(ip.lower),
119
+ upper: normaliseHalf(ip.upper)
120
+ };
121
+ }
122
+ static normaliseDocCompositeIps(doc) {
123
+ return {
124
+ ...doc,
125
+ ipAddress: CaptchaDatabase.normaliseCompositeIp(doc.ipAddress),
126
+ providedIp: CaptchaDatabase.normaliseCompositeIp(doc.providedIp)
127
+ };
128
+ }
85
129
  async saveCaptchas(sessionEvents, imageCaptchaEvents, powCaptchaEvents) {
86
130
  await this.connect();
87
131
  if (sessionEvents.length) {
@@ -90,7 +134,7 @@ class CaptchaDatabase extends MongoDatabase {
90
134
  const { _id, ...safeDoc } = document;
91
135
  return {
92
136
  insertOne: {
93
- document: safeDoc
137
+ document: CaptchaDatabase.normaliseDocCompositeIps(safeDoc)
94
138
  }
95
139
  };
96
140
  })
@@ -107,10 +151,11 @@ class CaptchaDatabase extends MongoDatabase {
107
151
  const result = await this.tables.commitment.bulkWrite(
108
152
  imageCaptchaEvents.map((doc) => {
109
153
  const { _id, ...safeDoc } = doc;
154
+ const normalised = CaptchaDatabase.normaliseDocCompositeIps(safeDoc);
110
155
  return {
111
156
  updateOne: {
112
- filter: { id: safeDoc.id },
113
- update: { $set: safeDoc },
157
+ filter: { id: normalised.id },
158
+ update: { $set: normalised },
114
159
  upsert: true
115
160
  }
116
161
  };
@@ -130,10 +175,11 @@ class CaptchaDatabase extends MongoDatabase {
130
175
  const result = await this.tables.powcaptcha.bulkWrite(
131
176
  powCaptchaEvents.map((doc) => {
132
177
  const { _id, ...safeDoc } = doc;
178
+ const normalised = CaptchaDatabase.normaliseDocCompositeIps(safeDoc);
133
179
  return {
134
180
  updateOne: {
135
- filter: { challenge: safeDoc.challenge },
136
- update: { $set: safeDoc },
181
+ filter: { challenge: normalised.challenge },
182
+ update: { $set: normalised },
137
183
  upsert: true
138
184
  }
139
185
  };
@@ -1 +1 @@
1
- {"version":3,"file":"captcha.js","sourceRoot":"","sources":["../../src/databases/captcha.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAe,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAIN,4BAA4B,EAE5B,yBAAyB,EACzB,gCAAgC,GAGhC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAElD,IAAK,UAKJ;AALD,WAAK,UAAU;IACd,qDAAuC,CAAA;IACvC,iCAAmB,CAAA;IACnB,uCAAyB,CAAA;IACzB,uCAAyB,CAAA;AAC1B,CAAC,EALI,UAAU,KAAV,UAAU,QAKd;AAED,MAAM,cAAc,GAAG;IACtB;QACC,cAAc,EAAE,UAAU,CAAC,OAAO;QAClC,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,yBAAyB;KACjC;IACD;QACC,cAAc,EAAE,UAAU,CAAC,UAAU;QACrC,SAAS,EAAE,YAAY;QACvB,MAAM,EAAE,4BAA4B;KACpC;IACD;QACC,cAAc,EAAE,UAAU,CAAC,UAAU;QACrC,SAAS,EAAE,gBAAgB;QAC3B,MAAM,EAAE,gCAAgC;KACxC;CACD,CAAC;AAEF,MAAM,OAAO,eAAgB,SAAQ,aAAa;IAIjD,YACC,GAAW,EACX,MAAe,EACf,UAAmB,EACnB,MAAe;QAEf,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QARhC,mBAAc,GAAG,KAAK,CAAC;QAS9B,IAAI,CAAC,MAAM,GAAG,EAAwB,CAAC;IACxC,CAAC;IAEQ,KAAK,CAAC,OAAO;QACrB,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QAEtB,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE;YAC5D,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACxE,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,SAAS;QACR,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,cAAc,CAAC,2BAA2B,EAAE;gBACrD,OAAO,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;gBAChD,MAAM,EAAE,IAAI,CAAC,MAAM;aACnB,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,aAAa;QAClB,MAAM,aAAa,GAAoB,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE;gBACzC,aAAa,CAAC,IAAI,CACjB,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACvB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBACpB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;4BAC9D,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;iCACzB,aAAa,EAAE;iCACf,IAAI,CAAC,GAAG,EAAE;gCACV,OAAO,EAAE,CAAC;4BACX,CAAC,CAAC;iCACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gCACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;oCACvB,GAAG;oCACH,GAAG,EAAE,yCAAyC,cAAc,EAAE;iCAC9D,CAAC,CAAC,CAAC;gCACJ,OAAO,EAAE,CAAC;4BACX,CAAC,CAAC,CAAC;wBACL,CAAC,CAAC,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACP,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;4BACvB,GAAG,EAAE,0CAA0C,cAAc,mBAAmB;yBAChF,CAAC,CAAC,CAAC;wBACJ,OAAO,EAAE,CAAC;oBACX,CAAC;gBACF,CAAC,CAAC,CACF,CAAC;YACH,CAAC,CAAC,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,YAAY,CACjB,aAA8B,EAC9B,kBAA0C,EAC1C,gBAAoC;QAEpC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CACjD,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC9B,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,CAAC;gBACrC,OAAO;oBACN,SAAS,EAAE;wBACV,QAAQ,EAAE,OAAO;qBACjB;iBACD,CAAC;YACH,CAAC,CAAC,CACF,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAClB,IAAI,EAAE;oBACL,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,cAAc,EAAE,aAAa,CAAC,MAAM;iBACpC;gBACD,GAAG,EAAE,4BAA4B;aACjC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,kBAAkB,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CACpD,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBAE9B,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAC;gBAChC,OAAO;oBACN,SAAS,EAAE;wBACV,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE;wBAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;wBACzB,MAAM,EAAE,IAAI;qBACZ;iBACD,CAAC;YACH,CAAC,CAAC,CACF,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAClB,IAAI,EAAE;oBACL,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,YAAY,EAAE,MAAM,CAAC,YAAY;oBACjC,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,cAAc,EAAE,kBAAkB,CAAC,MAAM;iBACzC;gBACD,GAAG,EAAE,0BAA0B;aAC/B,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CACpD,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBAE5B,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,CAAC;gBAChC,OAAO;oBACN,SAAS,EAAE;wBACV,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE;wBACxC,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;wBACzB,MAAM,EAAE,IAAI;qBACZ;iBACD,CAAC;YACH,CAAC,CAAC,CACF,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAClB,IAAI,EAAE;oBACL,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,YAAY,EAAE,MAAM,CAAC,YAAY;oBACjC,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,cAAc,EAAE,gBAAgB,CAAC,MAAM;iBACvC;gBACD,GAAG,EAAE,wBAAwB;aAC7B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,WAAW,CAChB,SAA6C,EAAE,EAC/C,KAAK,GAAG,GAAG;QAKX,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAErB,IAAI,CAAC;YACJ,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU;iBACpD,IAAI,CAAC,MAAM,CAAC;iBACZ,KAAK,CAAC,KAAK,CAAC;iBACZ,IAAI,EAA0B,CAAC;YAEjC,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU;iBACpD,IAAI,CAAC,MAAM,CAAC;iBACZ,KAAK,CAAC,KAAK,CAAC;iBACZ,IAAI,EAAsB,CAAC;YAE7B,OAAO;gBACN,qBAAqB,EAAE,iBAAiB;gBACxC,iBAAiB,EAAE,iBAAiB;aACpC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,cAAc,CAAC,sBAAsB,EAAE;gBAChD,OAAO,EAAE;oBACR,KAAK;oBACL,MAAM;oBACN,KAAK;oBACL,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;iBACrC;gBACD,MAAM,EAAE,IAAI,CAAC,MAAM;aACnB,CAAC,CAAC;QACJ,CAAC;gBAAS,CAAC;YACV,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;IACF,CAAC;CACD"}
1
+ {"version":3,"file":"captcha.js","sourceRoot":"","sources":["../../src/databases/captcha.ts"],"names":[],"mappings":"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"}