@prosopo/database 3.5.0 → 3.5.6

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.
@@ -0,0 +1,48 @@
1
+
2
+ > @prosopo/database@3.5.6 build:cjs
3
+ > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
+
5
+ ViteCommonJSConfig: .
6
+ {
7
+ tsConfigPaths: [
8
+ '/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
9
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
10
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
11
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
12
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json',
13
+ '/home/runner/work/captcha/captcha/packages/types-database/tsconfig.json',
14
+ '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json',
15
+ '/home/runner/work/captcha/captcha/packages/api-route/tsconfig.json',
16
+ '/home/runner/work/captcha/captcha/packages/redis-client/tsconfig.json',
17
+ '/home/runner/work/captcha/captcha/packages/api/tsconfig.json'
18
+ ]
19
+ }
20
+ {
21
+ externals: [
22
+ '@prosopo/common',
23
+ '@prosopo/locale',
24
+ '@prosopo/types',
25
+ '@prosopo/util',
26
+ '@prosopo/util-crypto',
27
+ '@prosopo/types-database',
28
+ '@prosopo/user-access-policy',
29
+ '@prosopo/api-route',
30
+ '@prosopo/redis-client',
31
+ '@prosopo/api'
32
+ ]
33
+ }
34
+ vite v6.4.1 building SSR bundle for production...
35
+ Bundle build started
36
+ transforming...
37
+ Build end
38
+ ✓ 8 modules transformed.
39
+ rendering chunks...
40
+ dist/cjs/base/index.cjs  0.28 kB
41
+ dist/cjs/base/mongoMemory.cjs  0.71 kB
42
+ dist/cjs/index.cjs  0.78 kB
43
+ dist/cjs/databases/index.cjs  0.89 kB
44
+ dist/cjs/databases/client.cjs  1.91 kB
45
+ dist/cjs/base/mongo.cjs  4.48 kB
46
+ dist/cjs/databases/captcha.cjs  5.82 kB
47
+ dist/cjs/databases/provider.cjs 43.19 kB
48
+ ✓ built in 227ms
@@ -0,0 +1,48 @@
1
+
2
+ > @prosopo/database@3.5.6 build
3
+ > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.esm.config.ts --mode $NODE_ENV
4
+
5
+ ViteEsmConfig: .
6
+ {
7
+ tsConfigPaths: [
8
+ '/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
9
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
10
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
11
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
12
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json',
13
+ '/home/runner/work/captcha/captcha/packages/types-database/tsconfig.json',
14
+ '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json',
15
+ '/home/runner/work/captcha/captcha/packages/api-route/tsconfig.json',
16
+ '/home/runner/work/captcha/captcha/packages/redis-client/tsconfig.json',
17
+ '/home/runner/work/captcha/captcha/packages/api/tsconfig.json'
18
+ ]
19
+ }
20
+ {
21
+ externals: [
22
+ '@prosopo/common',
23
+ '@prosopo/locale',
24
+ '@prosopo/types',
25
+ '@prosopo/util',
26
+ '@prosopo/util-crypto',
27
+ '@prosopo/types-database',
28
+ '@prosopo/user-access-policy',
29
+ '@prosopo/api-route',
30
+ '@prosopo/redis-client',
31
+ '@prosopo/api'
32
+ ]
33
+ }
34
+ vite v6.4.1 building SSR bundle for production...
35
+ Bundle build started
36
+ transforming...
37
+ Build end
38
+ ✓ 8 modules transformed.
39
+ rendering chunks...
40
+ dist/base/index.js  0.15 kB
41
+ dist/index.js  0.54 kB
42
+ dist/base/mongoMemory.js  0.59 kB
43
+ dist/databases/index.js  0.67 kB
44
+ dist/databases/client.js  1.79 kB
45
+ dist/base/mongo.js  4.06 kB
46
+ dist/databases/captcha.js  5.41 kB
47
+ dist/databases/provider.js 42.97 kB
48
+ ✓ built in 412ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # @prosopo/database
2
2
 
3
+ ## 3.5.6
4
+ ### Patch Changes
5
+
6
+ - 7d5eb3f: bump
7
+ - Updated dependencies [7d5eb3f]
8
+ - @prosopo/common@3.1.26
9
+ - @prosopo/locale@3.1.26
10
+ - @prosopo/redis-client@1.0.11
11
+ - @prosopo/types@3.6.4
12
+ - @prosopo/types-database@4.0.6
13
+ - @prosopo/user-access-policy@3.5.32
14
+
15
+ ## 3.5.5
16
+ ### Patch Changes
17
+
18
+ - 93d92a7: little bump for publish all
19
+ - Updated dependencies [93d92a7]
20
+ - @prosopo/common@3.1.25
21
+ - @prosopo/locale@3.1.25
22
+ - @prosopo/redis-client@1.0.10
23
+ - @prosopo/types@3.6.3
24
+ - @prosopo/types-database@4.0.5
25
+ - @prosopo/user-access-policy@3.5.31
26
+
27
+ ## 3.5.4
28
+ ### Patch Changes
29
+
30
+ - 8ee8434: bump node engines to 24 and npm version to 11
31
+ - cfee479: make @prosopo/config a dev dep
32
+ - Updated dependencies [8ee8434]
33
+ - Updated dependencies [cfee479]
34
+ - @prosopo/user-access-policy@3.5.30
35
+ - @prosopo/types-database@4.0.4
36
+ - @prosopo/redis-client@1.0.9
37
+ - @prosopo/common@3.1.24
38
+ - @prosopo/locale@3.1.24
39
+ - @prosopo/types@3.6.2
40
+
41
+ ## 3.5.3
42
+ ### Patch Changes
43
+
44
+ - e926831: mega mini bump for all to trigger publish all
45
+ - Updated dependencies [e926831]
46
+ - @prosopo/config@3.1.23
47
+ - @prosopo/common@3.1.23
48
+ - @prosopo/locale@3.1.23
49
+ - @prosopo/redis-client@1.0.8
50
+ - @prosopo/types@3.6.1
51
+ - @prosopo/types-database@4.0.3
52
+ - @prosopo/user-access-policy@3.5.29
53
+
54
+ ## 3.5.2
55
+ ### Patch Changes
56
+
57
+ - Updated dependencies [0a9887c]
58
+ - @prosopo/types-database@4.0.2
59
+
60
+ ## 3.5.1
61
+ ### Patch Changes
62
+
63
+ - Updated dependencies [3e5d80a]
64
+ - @prosopo/types-database@4.0.1
65
+
3
66
  ## 3.5.0
4
67
  ### Minor Changes
5
68
 
@@ -20,7 +20,7 @@ var TableNames = /* @__PURE__ */ ((TableNames2) => {
20
20
  TableNames2["client"] = "client";
21
21
  TableNames2["session"] = "session";
22
22
  TableNames2["detector"] = "detector";
23
- TableNames2["clientEntropy"] = "clientEntropy";
23
+ TableNames2["clientContextEntropy"] = "clientContextEntropy";
24
24
  return TableNames2;
25
25
  })(TableNames || {});
26
26
  const PROVIDER_TABLES = [
@@ -80,9 +80,9 @@ const PROVIDER_TABLES = [
80
80
  schema: typesDatabase.DetectorRecordSchema
81
81
  },
82
82
  {
83
- collectionName: "clientEntropy",
84
- modelName: "ClientEntropy",
85
- schema: typesDatabase.ClientEntropyRecordSchema
83
+ collectionName: "clientContextEntropy",
84
+ modelName: "ClientContextEntropy",
85
+ schema: typesDatabase.ClientContextEntropyRecordSchema
86
86
  }
87
87
  ];
88
88
  class ProviderDatabase extends mongo.MongoDatabase {
@@ -1309,6 +1309,10 @@ class ProviderDatabase extends mongo.MongoDatabase {
1309
1309
  }
1310
1310
  };
1311
1311
  });
1312
+ if (!ops || ops.length === 0) {
1313
+ await this.logger.debug(() => ({ msg: "No client updates to apply" }));
1314
+ return;
1315
+ }
1312
1316
  await this.tables?.client.bulkWrite(ops);
1313
1317
  }
1314
1318
  /**
@@ -1362,37 +1366,37 @@ class ProviderDatabase extends mongo.MongoDatabase {
1362
1366
  return (keyRecords || []).map((record) => record.detectorKey);
1363
1367
  }
1364
1368
  /**
1365
- * @description set client entropy
1369
+ * @description set client context-specific entropy
1366
1370
  */
1367
- async setClientEntropy(account, entropy) {
1368
- const filter = { account };
1369
- await this.tables?.clientEntropy.updateOne(
1371
+ async setClientContextEntropy(account, contextType, entropy) {
1372
+ const filter = { account, contextType };
1373
+ await this.tables?.clientContextEntropy.updateOne(
1370
1374
  filter,
1371
- { $set: { entropy } },
1375
+ { $set: { account, contextType, entropy } },
1372
1376
  { upsert: true }
1373
1377
  );
1374
1378
  }
1375
1379
  /**
1376
- * @description get client entropy
1380
+ * @description get client context-specific entropy
1377
1381
  */
1378
- async getClientEntropy(account) {
1379
- const filter = { account };
1380
- const doc = await this.tables?.clientEntropy.findOne(filter).lean();
1382
+ async getClientContextEntropy(account, contextType) {
1383
+ const filter = { account, contextType };
1384
+ const doc = await this.tables?.clientContextEntropy.findOne(filter).lean();
1381
1385
  return doc ? doc.entropy : void 0;
1382
1386
  }
1383
- /** Sample captcha records from the database */
1384
- async sampleEntropy(sampleSize, siteKey) {
1387
+ /** Sample captcha records from the database for a specific context */
1388
+ async sampleContextEntropy(sampleSize, siteKey, contextType) {
1385
1389
  const size = sampleSize ? Math.abs(Math.trunc(sampleSize)) : 1;
1386
1390
  const max = 1e4;
1387
1391
  if (size > max) {
1388
1392
  throw new common.ProsopoDBError("DATABASE.CAPTCHA_SAMPLE_SIZE_EXCEEDED", {
1389
1393
  context: {
1390
- failedFuncName: this.sampleEntropy.name,
1394
+ failedFuncName: this.sampleContextEntropy.name,
1391
1395
  sampleSize
1392
1396
  }
1393
1397
  });
1394
1398
  }
1395
- const cursor = this.tables?.powcaptcha.aggregate([
1399
+ const pipeline = [
1396
1400
  {
1397
1401
  $match: {
1398
1402
  dappAccount: siteKey,
@@ -1401,24 +1405,54 @@ class ProviderDatabase extends mongo.MongoDatabase {
1401
1405
  }
1402
1406
  }
1403
1407
  },
1408
+ {
1409
+ $lookup: {
1410
+ from: "session",
1411
+ localField: "sessionId",
1412
+ foreignField: "sessionId",
1413
+ as: "sessionData"
1414
+ }
1415
+ },
1416
+ {
1417
+ $unwind: {
1418
+ path: "$sessionData",
1419
+ preserveNullAndEmptyArrays: false
1420
+ }
1421
+ }
1422
+ ];
1423
+ if (contextType === types.ContextType.Webview) {
1424
+ pipeline.push({
1425
+ $match: {
1426
+ "sessionData.webView": true
1427
+ }
1428
+ });
1429
+ } else if (contextType === types.ContextType.Default) {
1430
+ pipeline.push({
1431
+ $match: {
1432
+ "sessionData.webView": false
1433
+ }
1434
+ });
1435
+ }
1436
+ pipeline.push(
1404
1437
  { $limit: max },
1405
1438
  { $sample: { size } },
1406
1439
  {
1407
1440
  $project: {
1408
1441
  _id: 0,
1409
- frictionlessTokenId: 1
1442
+ sessionId: 1
1410
1443
  }
1411
1444
  }
1412
- ]);
1445
+ );
1446
+ const cursor = this.tables?.powcaptcha.aggregate(pipeline);
1413
1447
  const docs = await cursor;
1414
1448
  if (docs?.length === 0) {
1415
1449
  return [];
1416
1450
  }
1417
1451
  return (await Promise.all(
1418
1452
  docs.map(async (doc) => {
1419
- if (doc.frictionlessTokenId) {
1420
- const tokenRecord = await this.getSessionRecordByToken(
1421
- doc.frictionlessTokenId
1453
+ if (doc.sessionId) {
1454
+ const tokenRecord = await this.getSessionRecordBySessionId(
1455
+ doc.sessionId
1422
1456
  );
1423
1457
  return tokenRecord?.decryptedHeadHash;
1424
1458
  }
@@ -1,8 +1,8 @@
1
1
  import { isHex } from "@polkadot/util/is";
2
2
  import { ProsopoDBError } from "@prosopo/common";
3
3
  import { connectToRedis, setupRedisIndex } from "@prosopo/redis-client";
4
- import { DatasetWithIdsAndTreeSchema, StoredStatusNames, CaptchaStatus, ApiParams, CaptchaStates } from "@prosopo/types";
5
- import { CaptchaRecordSchema, PoWCaptchaRecordSchema, DatasetRecordSchema, SolutionRecordSchema, UserCommitmentRecordSchema, UserSolutionRecordSchema, PendingRecordSchema, ScheduledTaskRecordSchema, ClientRecordSchema, SessionRecordSchema, DetectorRecordSchema, ClientEntropyRecordSchema, UserCommitmentSchema, ScheduledTaskSchema } from "@prosopo/types-database";
4
+ import { DatasetWithIdsAndTreeSchema, StoredStatusNames, CaptchaStatus, ApiParams, CaptchaStates, ContextType } from "@prosopo/types";
5
+ import { CaptchaRecordSchema, PoWCaptchaRecordSchema, DatasetRecordSchema, SolutionRecordSchema, UserCommitmentRecordSchema, UserSolutionRecordSchema, PendingRecordSchema, ScheduledTaskRecordSchema, ClientRecordSchema, SessionRecordSchema, DetectorRecordSchema, ClientContextEntropyRecordSchema, UserCommitmentSchema, ScheduledTaskSchema } from "@prosopo/types-database";
6
6
  import { accessRulesRedisIndex, createRedisAccessRulesStorage } from "@prosopo/user-access-policy/redis";
7
7
  import { MongoDatabase } from "../base/mongo.js";
8
8
  const TWENTY_FOUR_HOURS_IN_MS = 24 * 60 * 60 * 1e3;
@@ -18,7 +18,7 @@ var TableNames = /* @__PURE__ */ ((TableNames2) => {
18
18
  TableNames2["client"] = "client";
19
19
  TableNames2["session"] = "session";
20
20
  TableNames2["detector"] = "detector";
21
- TableNames2["clientEntropy"] = "clientEntropy";
21
+ TableNames2["clientContextEntropy"] = "clientContextEntropy";
22
22
  return TableNames2;
23
23
  })(TableNames || {});
24
24
  const PROVIDER_TABLES = [
@@ -78,9 +78,9 @@ const PROVIDER_TABLES = [
78
78
  schema: DetectorRecordSchema
79
79
  },
80
80
  {
81
- collectionName: "clientEntropy",
82
- modelName: "ClientEntropy",
83
- schema: ClientEntropyRecordSchema
81
+ collectionName: "clientContextEntropy",
82
+ modelName: "ClientContextEntropy",
83
+ schema: ClientContextEntropyRecordSchema
84
84
  }
85
85
  ];
86
86
  class ProviderDatabase extends MongoDatabase {
@@ -1307,6 +1307,10 @@ class ProviderDatabase extends MongoDatabase {
1307
1307
  }
1308
1308
  };
1309
1309
  });
1310
+ if (!ops || ops.length === 0) {
1311
+ await this.logger.debug(() => ({ msg: "No client updates to apply" }));
1312
+ return;
1313
+ }
1310
1314
  await this.tables?.client.bulkWrite(ops);
1311
1315
  }
1312
1316
  /**
@@ -1360,37 +1364,37 @@ class ProviderDatabase extends MongoDatabase {
1360
1364
  return (keyRecords || []).map((record) => record.detectorKey);
1361
1365
  }
1362
1366
  /**
1363
- * @description set client entropy
1367
+ * @description set client context-specific entropy
1364
1368
  */
1365
- async setClientEntropy(account, entropy) {
1366
- const filter = { account };
1367
- await this.tables?.clientEntropy.updateOne(
1369
+ async setClientContextEntropy(account, contextType, entropy) {
1370
+ const filter = { account, contextType };
1371
+ await this.tables?.clientContextEntropy.updateOne(
1368
1372
  filter,
1369
- { $set: { entropy } },
1373
+ { $set: { account, contextType, entropy } },
1370
1374
  { upsert: true }
1371
1375
  );
1372
1376
  }
1373
1377
  /**
1374
- * @description get client entropy
1378
+ * @description get client context-specific entropy
1375
1379
  */
1376
- async getClientEntropy(account) {
1377
- const filter = { account };
1378
- const doc = await this.tables?.clientEntropy.findOne(filter).lean();
1380
+ async getClientContextEntropy(account, contextType) {
1381
+ const filter = { account, contextType };
1382
+ const doc = await this.tables?.clientContextEntropy.findOne(filter).lean();
1379
1383
  return doc ? doc.entropy : void 0;
1380
1384
  }
1381
- /** Sample captcha records from the database */
1382
- async sampleEntropy(sampleSize, siteKey) {
1385
+ /** Sample captcha records from the database for a specific context */
1386
+ async sampleContextEntropy(sampleSize, siteKey, contextType) {
1383
1387
  const size = sampleSize ? Math.abs(Math.trunc(sampleSize)) : 1;
1384
1388
  const max = 1e4;
1385
1389
  if (size > max) {
1386
1390
  throw new ProsopoDBError("DATABASE.CAPTCHA_SAMPLE_SIZE_EXCEEDED", {
1387
1391
  context: {
1388
- failedFuncName: this.sampleEntropy.name,
1392
+ failedFuncName: this.sampleContextEntropy.name,
1389
1393
  sampleSize
1390
1394
  }
1391
1395
  });
1392
1396
  }
1393
- const cursor = this.tables?.powcaptcha.aggregate([
1397
+ const pipeline = [
1394
1398
  {
1395
1399
  $match: {
1396
1400
  dappAccount: siteKey,
@@ -1399,24 +1403,54 @@ class ProviderDatabase extends MongoDatabase {
1399
1403
  }
1400
1404
  }
1401
1405
  },
1406
+ {
1407
+ $lookup: {
1408
+ from: "session",
1409
+ localField: "sessionId",
1410
+ foreignField: "sessionId",
1411
+ as: "sessionData"
1412
+ }
1413
+ },
1414
+ {
1415
+ $unwind: {
1416
+ path: "$sessionData",
1417
+ preserveNullAndEmptyArrays: false
1418
+ }
1419
+ }
1420
+ ];
1421
+ if (contextType === ContextType.Webview) {
1422
+ pipeline.push({
1423
+ $match: {
1424
+ "sessionData.webView": true
1425
+ }
1426
+ });
1427
+ } else if (contextType === ContextType.Default) {
1428
+ pipeline.push({
1429
+ $match: {
1430
+ "sessionData.webView": false
1431
+ }
1432
+ });
1433
+ }
1434
+ pipeline.push(
1402
1435
  { $limit: max },
1403
1436
  { $sample: { size } },
1404
1437
  {
1405
1438
  $project: {
1406
1439
  _id: 0,
1407
- frictionlessTokenId: 1
1440
+ sessionId: 1
1408
1441
  }
1409
1442
  }
1410
- ]);
1443
+ );
1444
+ const cursor = this.tables?.powcaptcha.aggregate(pipeline);
1411
1445
  const docs = await cursor;
1412
1446
  if (docs?.length === 0) {
1413
1447
  return [];
1414
1448
  }
1415
1449
  return (await Promise.all(
1416
1450
  docs.map(async (doc) => {
1417
- if (doc.frictionlessTokenId) {
1418
- const tokenRecord = await this.getSessionRecordByToken(
1419
- doc.frictionlessTokenId
1451
+ if (doc.sessionId) {
1452
+ const tokenRecord = await this.getSessionRecordBySessionId(
1453
+ doc.sessionId
1420
1454
  );
1421
1455
  return tokenRecord?.decryptedHeadHash;
1422
1456
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@prosopo/database",
3
- "version": "3.5.0",
3
+ "version": "3.5.6",
4
4
  "description": "Prosopo database plugins for provider",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "engines": {
9
- "node": ">=v20.0.0",
10
- "npm": ">=10.6.0"
9
+ "node": "^24",
10
+ "npm": "^11"
11
11
  },
12
12
  "exports": {
13
13
  ".": {
@@ -35,19 +35,19 @@
35
35
  "homepage": "https://github.com/prosopo/captcha#readme",
36
36
  "dependencies": {
37
37
  "@polkadot/util": "13.5.7",
38
- "@prosopo/common": "3.1.22",
39
- "@prosopo/config": "3.1.22",
40
- "@prosopo/locale": "3.1.22",
41
- "@prosopo/redis-client": "1.0.7",
42
- "@prosopo/types": "3.6.0",
43
- "@prosopo/types-database": "4.0.0",
44
- "@prosopo/user-access-policy": "3.5.28",
38
+ "@prosopo/common": "3.1.26",
39
+ "@prosopo/locale": "3.1.26",
40
+ "@prosopo/redis-client": "1.0.11",
41
+ "@prosopo/types": "3.6.4",
42
+ "@prosopo/types-database": "4.0.6",
43
+ "@prosopo/user-access-policy": "3.5.32",
45
44
  "make-dir": "3.1.0",
46
45
  "mongodb": "6.15.0",
47
46
  "mongodb-memory-server": "10.3.0",
48
47
  "mongoose": "8.13.0"
49
48
  },
50
49
  "devDependencies": {
50
+ "@prosopo/config": "3.1.26",
51
51
  "@types/node": "22.10.2",
52
52
  "@vitest/coverage-v8": "3.2.4",
53
53
  "concurrently": "9.0.1",