@prosopo/database 3.4.5 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +108 -0
- package/dist/cjs/base/mongo.cjs +2 -1
- package/dist/cjs/databases/captcha.cjs +4 -3
- package/dist/cjs/databases/provider.cjs +143 -79
- package/dist/cjs/index.cjs +2 -0
- package/dist/databases/provider.js +143 -79
- package/dist/index.js +2 -0
- package/package.json +17 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,113 @@
|
|
|
1
1
|
# @prosopo/database
|
|
2
2
|
|
|
3
|
+
## 3.5.0
|
|
4
|
+
### Minor Changes
|
|
5
|
+
|
|
6
|
+
- bb5f41c: Context awareness
|
|
7
|
+
|
|
8
|
+
### Patch Changes
|
|
9
|
+
|
|
10
|
+
- 55a64c6: stop refresh image to pow
|
|
11
|
+
- 8ce9205: Change engine requirements
|
|
12
|
+
- b6e98b2: Run npm audit
|
|
13
|
+
- 55a64c6: Persist sessions for user ip combinations
|
|
14
|
+
- Updated dependencies [8ce9205]
|
|
15
|
+
- Updated dependencies [15ae7cf]
|
|
16
|
+
- Updated dependencies [bb5f41c]
|
|
17
|
+
- Updated dependencies [55a64c6]
|
|
18
|
+
- Updated dependencies [8ce9205]
|
|
19
|
+
- Updated dependencies [df79c03]
|
|
20
|
+
- Updated dependencies [8f22479]
|
|
21
|
+
- Updated dependencies [b6e98b2]
|
|
22
|
+
- Updated dependencies [55a64c6]
|
|
23
|
+
- @prosopo/user-access-policy@3.5.28
|
|
24
|
+
- @prosopo/types@3.6.0
|
|
25
|
+
- @prosopo/types-database@4.0.0
|
|
26
|
+
- @prosopo/redis-client@1.0.7
|
|
27
|
+
- @prosopo/common@3.1.22
|
|
28
|
+
- @prosopo/locale@3.1.22
|
|
29
|
+
- @prosopo/config@3.1.22
|
|
30
|
+
|
|
31
|
+
## 3.4.13
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [8f1773a]
|
|
35
|
+
- @prosopo/types@3.5.11
|
|
36
|
+
- @prosopo/types-database@3.3.13
|
|
37
|
+
- @prosopo/user-access-policy@3.5.27
|
|
38
|
+
|
|
39
|
+
## 3.4.12
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- Updated dependencies [cb8ab85]
|
|
43
|
+
- @prosopo/types-database@3.3.12
|
|
44
|
+
- @prosopo/types@3.5.10
|
|
45
|
+
- @prosopo/user-access-policy@3.5.26
|
|
46
|
+
|
|
47
|
+
## 3.4.11
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- 43907e8: Convert timestamp fields from numbers to Date objects throughout codebase
|
|
51
|
+
- b4639ec: Merge frictionless tokens into sessions
|
|
52
|
+
- Updated dependencies [43907e8]
|
|
53
|
+
- Updated dependencies [b4639ec]
|
|
54
|
+
- Updated dependencies [005ce66]
|
|
55
|
+
- Updated dependencies [7101036]
|
|
56
|
+
- @prosopo/types-database@3.3.11
|
|
57
|
+
- @prosopo/types@3.5.9
|
|
58
|
+
- @prosopo/user-access-policy@3.5.25
|
|
59
|
+
|
|
60
|
+
## 3.4.10
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- Updated dependencies [b10a65f]
|
|
64
|
+
- Updated dependencies [e5c259d]
|
|
65
|
+
- Updated dependencies [6420187]
|
|
66
|
+
- @prosopo/types-database@3.3.10
|
|
67
|
+
- @prosopo/types@3.5.8
|
|
68
|
+
- @prosopo/user-access-policy@3.5.24
|
|
69
|
+
|
|
70
|
+
## 3.4.9
|
|
71
|
+
### Patch Changes
|
|
72
|
+
|
|
73
|
+
- b8185a4: feat/uap-rules-syncer
|
|
74
|
+
- Updated dependencies [c9d8fdf]
|
|
75
|
+
- Updated dependencies [b8185a4]
|
|
76
|
+
- Updated dependencies [3a027ef]
|
|
77
|
+
- Updated dependencies [3a027ef]
|
|
78
|
+
- @prosopo/user-access-policy@3.5.23
|
|
79
|
+
- @prosopo/common@3.1.21
|
|
80
|
+
- @prosopo/config@3.1.21
|
|
81
|
+
- @prosopo/types-database@3.3.9
|
|
82
|
+
- @prosopo/redis-client@1.0.6
|
|
83
|
+
- @prosopo/locale@3.1.21
|
|
84
|
+
- @prosopo/types@3.5.7
|
|
85
|
+
|
|
86
|
+
## 3.4.8
|
|
87
|
+
### Patch Changes
|
|
88
|
+
|
|
89
|
+
- Updated dependencies [5d11a81]
|
|
90
|
+
- @prosopo/types@3.5.6
|
|
91
|
+
- @prosopo/types-database@3.3.8
|
|
92
|
+
- @prosopo/user-access-policy@3.5.22
|
|
93
|
+
|
|
94
|
+
## 3.4.7
|
|
95
|
+
### Patch Changes
|
|
96
|
+
|
|
97
|
+
- Updated dependencies [494c5a8]
|
|
98
|
+
- @prosopo/types-database@3.3.7
|
|
99
|
+
- @prosopo/types@3.5.5
|
|
100
|
+
- @prosopo/user-access-policy@3.5.21
|
|
101
|
+
|
|
102
|
+
## 3.4.6
|
|
103
|
+
### Patch Changes
|
|
104
|
+
|
|
105
|
+
- Updated dependencies [08ff50f]
|
|
106
|
+
- Updated dependencies [08ff50f]
|
|
107
|
+
- @prosopo/types-database@3.3.6
|
|
108
|
+
- @prosopo/types@3.5.4
|
|
109
|
+
- @prosopo/user-access-policy@3.5.20
|
|
110
|
+
|
|
3
111
|
## 3.4.5
|
|
4
112
|
### Patch Changes
|
|
5
113
|
|
package/dist/cjs/base/mongo.cjs
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const common = require("@prosopo/common");
|
|
4
4
|
const mongodb = require("mongodb");
|
|
5
5
|
const mongoose = require("mongoose");
|
|
6
|
+
var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
|
|
6
7
|
mongoose.set("strictQuery", false);
|
|
7
8
|
const DEFAULT_ENDPOINT = "mongodb://127.0.0.1:27017";
|
|
8
9
|
class MongoDatabase {
|
|
@@ -19,7 +20,7 @@ class MongoDatabase {
|
|
|
19
20
|
this._url = parsedUrl.toString();
|
|
20
21
|
this.safeURL = this.url.replace(/\w+:\w+/, "<Credentials>");
|
|
21
22
|
this.dbname = dbname || parsedUrl.pathname.replace("/", "");
|
|
22
|
-
this.logger = logger || common.getLogger("info",
|
|
23
|
+
this.logger = logger || common.getLogger("info", typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("base/mongo.cjs", document.baseURI).href);
|
|
23
24
|
}
|
|
24
25
|
get url() {
|
|
25
26
|
return this._url;
|
|
@@ -4,7 +4,8 @@ const common = require("@prosopo/common");
|
|
|
4
4
|
const typesDatabase = require("@prosopo/types-database");
|
|
5
5
|
require("../base/index.cjs");
|
|
6
6
|
const mongo = require("../base/mongo.cjs");
|
|
7
|
-
|
|
7
|
+
var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
|
|
8
|
+
const logger = common.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);
|
|
8
9
|
var TableNames = /* @__PURE__ */ ((TableNames2) => {
|
|
9
10
|
TableNames2["frictionlessToken"] = "frictionlessToken";
|
|
10
11
|
TableNames2["session"] = "session";
|
|
@@ -87,8 +88,8 @@ class CaptchaDatabase extends mongo.MongoDatabase {
|
|
|
87
88
|
await this.connect();
|
|
88
89
|
if (sessionEvents.length) {
|
|
89
90
|
const result = await this.tables.session.bulkWrite(
|
|
90
|
-
sessionEvents.map((
|
|
91
|
-
const { _id, ...safeDoc } =
|
|
91
|
+
sessionEvents.map((document2) => {
|
|
92
|
+
const { _id, ...safeDoc } = document2;
|
|
92
93
|
return {
|
|
93
94
|
insertOne: {
|
|
94
95
|
document: safeDoc
|
|
@@ -5,8 +5,9 @@ const common = require("@prosopo/common");
|
|
|
5
5
|
const redisClient = require("@prosopo/redis-client");
|
|
6
6
|
const types = require("@prosopo/types");
|
|
7
7
|
const typesDatabase = require("@prosopo/types-database");
|
|
8
|
-
const
|
|
8
|
+
const redis = require("@prosopo/user-access-policy/redis");
|
|
9
9
|
const mongo = require("../base/mongo.cjs");
|
|
10
|
+
const TWENTY_FOUR_HOURS_IN_MS = 24 * 60 * 60 * 1e3;
|
|
10
11
|
var TableNames = /* @__PURE__ */ ((TableNames2) => {
|
|
11
12
|
TableNames2["captcha"] = "captcha";
|
|
12
13
|
TableNames2["dataset"] = "dataset";
|
|
@@ -17,9 +18,9 @@ var TableNames = /* @__PURE__ */ ((TableNames2) => {
|
|
|
17
18
|
TableNames2["scheduler"] = "scheduler";
|
|
18
19
|
TableNames2["powcaptcha"] = "powcaptcha";
|
|
19
20
|
TableNames2["client"] = "client";
|
|
20
|
-
TableNames2["frictionlessToken"] = "frictionlessToken";
|
|
21
21
|
TableNames2["session"] = "session";
|
|
22
22
|
TableNames2["detector"] = "detector";
|
|
23
|
+
TableNames2["clientEntropy"] = "clientEntropy";
|
|
23
24
|
return TableNames2;
|
|
24
25
|
})(TableNames || {});
|
|
25
26
|
const PROVIDER_TABLES = [
|
|
@@ -68,11 +69,6 @@ const PROVIDER_TABLES = [
|
|
|
68
69
|
modelName: "Client",
|
|
69
70
|
schema: typesDatabase.ClientRecordSchema
|
|
70
71
|
},
|
|
71
|
-
{
|
|
72
|
-
collectionName: "frictionlessToken",
|
|
73
|
-
modelName: "FrictionlessToken",
|
|
74
|
-
schema: typesDatabase.FrictionlessTokenRecordSchema
|
|
75
|
-
},
|
|
76
72
|
{
|
|
77
73
|
collectionName: "session",
|
|
78
74
|
modelName: "Session",
|
|
@@ -82,6 +78,11 @@ const PROVIDER_TABLES = [
|
|
|
82
78
|
collectionName: "detector",
|
|
83
79
|
modelName: "Detector",
|
|
84
80
|
schema: typesDatabase.DetectorRecordSchema
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
collectionName: "clientEntropy",
|
|
84
|
+
modelName: "ClientEntropy",
|
|
85
|
+
schema: typesDatabase.ClientEntropyRecordSchema
|
|
85
86
|
}
|
|
86
87
|
];
|
|
87
88
|
class ProviderDatabase extends mongo.MongoDatabase {
|
|
@@ -114,12 +115,12 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
114
115
|
this.redisAccessRulesConnection = redisClient.setupRedisIndex(
|
|
115
116
|
this.redisConnection,
|
|
116
117
|
{
|
|
117
|
-
...
|
|
118
|
-
name: this.options.redis?.indexName ||
|
|
118
|
+
...redis.accessRulesRedisIndex,
|
|
119
|
+
name: this.options.redis?.indexName || redis.accessRulesRedisIndex.name
|
|
119
120
|
},
|
|
120
121
|
this.logger
|
|
121
122
|
);
|
|
122
|
-
this.userAccessRulesStorage =
|
|
123
|
+
this.userAccessRulesStorage = redis.createRedisAccessRulesStorage(
|
|
123
124
|
this.redisAccessRulesConnection,
|
|
124
125
|
this.logger
|
|
125
126
|
);
|
|
@@ -448,7 +449,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
448
449
|
async storeUserImageCaptchaSolution(captchas, commit) {
|
|
449
450
|
const commitmentRecord = typesDatabase.UserCommitmentSchema.parse({
|
|
450
451
|
...commit,
|
|
451
|
-
lastUpdatedTimestamp: Date
|
|
452
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
452
453
|
});
|
|
453
454
|
if (captchas.length) {
|
|
454
455
|
const filter = {
|
|
@@ -488,18 +489,20 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
488
489
|
* @param ipAddress
|
|
489
490
|
* @param headers
|
|
490
491
|
* @param ja4
|
|
491
|
-
* @param
|
|
492
|
+
* @param sessionId
|
|
492
493
|
* @param serverChecked
|
|
493
494
|
* @param userSubmitted
|
|
494
495
|
* @param storedStatus
|
|
495
496
|
* @param userSignature
|
|
496
497
|
* @returns {Promise<void>} A promise that resolves when the record is added.
|
|
497
498
|
*/
|
|
498
|
-
async storePowCaptchaRecord(challenge, components, difficulty, providerSignature, ipAddress, headers, ja4,
|
|
499
|
+
async storePowCaptchaRecord(challenge, components, difficulty, providerSignature, ipAddress, headers, ja4, sessionId, serverChecked = false, userSubmitted = false, storedStatus = types.StoredStatusNames.notStored, userSignature) {
|
|
499
500
|
const tables = this.getTables();
|
|
500
501
|
const powCaptchaRecord = {
|
|
501
502
|
challenge,
|
|
502
|
-
|
|
503
|
+
userAccount: components.userAccount,
|
|
504
|
+
dappAccount: components.dappAccount,
|
|
505
|
+
requestedAtTimestamp: new Date(components.requestedAtTimestamp),
|
|
503
506
|
ipAddress,
|
|
504
507
|
headers,
|
|
505
508
|
ja4,
|
|
@@ -509,8 +512,8 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
509
512
|
difficulty,
|
|
510
513
|
providerSignature,
|
|
511
514
|
userSignature,
|
|
512
|
-
lastUpdatedTimestamp: Date
|
|
513
|
-
|
|
515
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date(),
|
|
516
|
+
sessionId
|
|
514
517
|
};
|
|
515
518
|
try {
|
|
516
519
|
await tables.powcaptcha.create(powCaptchaRecord);
|
|
@@ -591,7 +594,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
591
594
|
*/
|
|
592
595
|
async updatePowCaptchaRecordResult(challenge, result, serverChecked = false, userSubmitted = false, userSignature) {
|
|
593
596
|
const tables = this.getTables();
|
|
594
|
-
const timestamp = Date
|
|
597
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
595
598
|
const update = {
|
|
596
599
|
result,
|
|
597
600
|
serverChecked,
|
|
@@ -692,7 +695,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
692
695
|
*/
|
|
693
696
|
async markDappUserCommitmentsStored(commitmentIds) {
|
|
694
697
|
const updateDoc = {
|
|
695
|
-
storedAtTimestamp: Date
|
|
698
|
+
storedAtTimestamp: /* @__PURE__ */ new Date()
|
|
696
699
|
};
|
|
697
700
|
await this.tables?.commitment.updateMany(
|
|
698
701
|
{ id: { $in: commitmentIds } },
|
|
@@ -705,7 +708,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
705
708
|
async markDappUserCommitmentsChecked(commitmentIds) {
|
|
706
709
|
const updateDoc = {
|
|
707
710
|
[types.StoredStatusNames.serverChecked]: true,
|
|
708
|
-
lastUpdatedTimestamp: Date
|
|
711
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
709
712
|
};
|
|
710
713
|
await this.tables?.commitment.updateMany(
|
|
711
714
|
{ id: { $in: commitmentIds } },
|
|
@@ -769,7 +772,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
769
772
|
*/
|
|
770
773
|
async markDappUserPoWCommitmentsStored(challenges) {
|
|
771
774
|
const updateDoc = {
|
|
772
|
-
storedAtTimestamp: Date
|
|
775
|
+
storedAtTimestamp: /* @__PURE__ */ new Date()
|
|
773
776
|
};
|
|
774
777
|
await this.tables?.powcaptcha.updateMany(
|
|
775
778
|
{ challenge: { $in: challenges } },
|
|
@@ -782,7 +785,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
782
785
|
async markDappUserPoWCommitmentsChecked(challenges) {
|
|
783
786
|
const updateDoc = {
|
|
784
787
|
[types.StoredStatusNames.serverChecked]: true,
|
|
785
|
-
lastUpdatedTimestamp: Date
|
|
788
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
786
789
|
};
|
|
787
790
|
await this.tables?.powcaptcha.updateMany(
|
|
788
791
|
{ challenge: { $in: challenges } },
|
|
@@ -792,46 +795,6 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
792
795
|
{ upsert: false }
|
|
793
796
|
);
|
|
794
797
|
}
|
|
795
|
-
/**
|
|
796
|
-
* Store a new frictionless token record
|
|
797
|
-
*/
|
|
798
|
-
async storeFrictionlessTokenRecord(tokenRecord) {
|
|
799
|
-
const doc = await this.tables.frictionlessToken.create(
|
|
800
|
-
tokenRecord
|
|
801
|
-
);
|
|
802
|
-
return doc._id;
|
|
803
|
-
}
|
|
804
|
-
/** Update a frictionless token record */
|
|
805
|
-
async updateFrictionlessTokenRecord(tokenId, updates) {
|
|
806
|
-
const filter = { _id: tokenId };
|
|
807
|
-
await this.tables.frictionlessToken.updateOne(filter, updates);
|
|
808
|
-
}
|
|
809
|
-
/** Get a frictionless token record */
|
|
810
|
-
async getFrictionlessTokenRecordByTokenId(tokenId) {
|
|
811
|
-
const filter = { _id: tokenId };
|
|
812
|
-
const doc = await this.tables.frictionlessToken.findOne(
|
|
813
|
-
filter
|
|
814
|
-
);
|
|
815
|
-
return doc ? doc : void 0;
|
|
816
|
-
}
|
|
817
|
-
/** Get many frictionless token records */
|
|
818
|
-
async getFrictionlessTokenRecordsByTokenIds(tokenId) {
|
|
819
|
-
const filter = {
|
|
820
|
-
_id: { $in: tokenId }
|
|
821
|
-
};
|
|
822
|
-
return this.tables.frictionlessToken.find(filter).lean();
|
|
823
|
-
}
|
|
824
|
-
/**
|
|
825
|
-
* Check if a frictionless token record exists.
|
|
826
|
-
* Used to ensure that a token is not used more than once.
|
|
827
|
-
*/
|
|
828
|
-
async getFrictionlessTokenRecordByToken(token) {
|
|
829
|
-
const filter = { token };
|
|
830
|
-
const record = await this.tables.frictionlessToken.findOne(
|
|
831
|
-
filter
|
|
832
|
-
);
|
|
833
|
-
return record || void 0;
|
|
834
|
-
}
|
|
835
798
|
/**
|
|
836
799
|
* Store a new session record
|
|
837
800
|
*/
|
|
@@ -848,6 +811,23 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
848
811
|
});
|
|
849
812
|
}
|
|
850
813
|
}
|
|
814
|
+
/**
|
|
815
|
+
* Get a session record by sessionId
|
|
816
|
+
*/
|
|
817
|
+
async getSessionRecordBySessionId(sessionId) {
|
|
818
|
+
const filter = { sessionId };
|
|
819
|
+
const doc = await this.tables.session.findOne(filter).lean();
|
|
820
|
+
return doc || void 0;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Get a session record by token
|
|
824
|
+
* Used to ensure that a token is not used more than once.
|
|
825
|
+
*/
|
|
826
|
+
async getSessionRecordByToken(token) {
|
|
827
|
+
const filter = { token };
|
|
828
|
+
const record = await this.tables.session.findOne(filter).lean();
|
|
829
|
+
return record || void 0;
|
|
830
|
+
}
|
|
851
831
|
/**
|
|
852
832
|
* Check if a session exists and mark it as removed
|
|
853
833
|
* @returns The session record if it existed, undefined otherwise
|
|
@@ -863,7 +843,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
863
843
|
try {
|
|
864
844
|
const session = await this.tables.session.findOneAndUpdate(filter, {
|
|
865
845
|
deleted: true,
|
|
866
|
-
lastUpdatedTimestamp: Date
|
|
846
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
867
847
|
}).lean();
|
|
868
848
|
return session || void 0;
|
|
869
849
|
} catch (err) {
|
|
@@ -873,6 +853,29 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
873
853
|
});
|
|
874
854
|
}
|
|
875
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* Get an active session by user IP hash
|
|
858
|
+
* @param userSitekeyIpHash The hash of user, IP and sitekey combination
|
|
859
|
+
* @returns The session record if it exists and is not deleted, undefined otherwise
|
|
860
|
+
*/
|
|
861
|
+
async getSessionByuserSitekeyIpHash(userSitekeyIpHash) {
|
|
862
|
+
this.logger.debug(() => ({
|
|
863
|
+
data: { action: "getting session by user IP hash", userSitekeyIpHash }
|
|
864
|
+
}));
|
|
865
|
+
const filter = {
|
|
866
|
+
userSitekeyIpHash,
|
|
867
|
+
deleted: { $exists: false }
|
|
868
|
+
};
|
|
869
|
+
try {
|
|
870
|
+
const session = await this.tables.session.findOne(filter).lean();
|
|
871
|
+
return session || void 0;
|
|
872
|
+
} catch (err) {
|
|
873
|
+
throw new common.ProsopoDBError("DATABASE.SESSION_GET_FAILED", {
|
|
874
|
+
context: { error: err, userSitekeyIpHash },
|
|
875
|
+
logger: this.logger
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
}
|
|
876
879
|
/** Get unstored session records
|
|
877
880
|
* @description Get session records that have not been stored yet
|
|
878
881
|
* @param limit
|
|
@@ -928,21 +931,10 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
928
931
|
{ upsert: false }
|
|
929
932
|
);
|
|
930
933
|
}
|
|
931
|
-
/** Mark a list of token records as stored */
|
|
932
|
-
async markFrictionlessTokenRecordsStored(tokenIds) {
|
|
933
|
-
const updateDoc = {
|
|
934
|
-
storedAtTimestamp: /* @__PURE__ */ new Date()
|
|
935
|
-
};
|
|
936
|
-
await this.tables?.frictionlessToken.updateMany(
|
|
937
|
-
{ _id: { $in: tokenIds } },
|
|
938
|
-
{ $set: updateDoc },
|
|
939
|
-
{ upsert: false }
|
|
940
|
-
);
|
|
941
|
-
}
|
|
942
934
|
/**
|
|
943
935
|
* @description Store a Dapp User's pending record
|
|
944
936
|
*/
|
|
945
|
-
async storePendingImageCommitment(userAccount, requestHash, salt, deadlineTimestamp, requestedAtTimestamp, ipAddress, threshold,
|
|
937
|
+
async storePendingImageCommitment(userAccount, requestHash, salt, deadlineTimestamp, requestedAtTimestamp, ipAddress, threshold, sessionId) {
|
|
946
938
|
if (!is.isHex(requestHash)) {
|
|
947
939
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
948
940
|
context: {
|
|
@@ -959,7 +951,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
959
951
|
deadlineTimestamp,
|
|
960
952
|
requestedAtTimestamp: new Date(requestedAtTimestamp),
|
|
961
953
|
ipAddress,
|
|
962
|
-
|
|
954
|
+
sessionId,
|
|
963
955
|
threshold
|
|
964
956
|
};
|
|
965
957
|
await this.tables?.pending.updateOne(
|
|
@@ -1162,7 +1154,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
1162
1154
|
const result = { status: types.CaptchaStatus.approved };
|
|
1163
1155
|
const updateDoc = {
|
|
1164
1156
|
result,
|
|
1165
|
-
lastUpdatedTimestamp: Date
|
|
1157
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date(),
|
|
1166
1158
|
...coords ? { coords } : {}
|
|
1167
1159
|
};
|
|
1168
1160
|
const filter = { id: commitmentId };
|
|
@@ -1183,7 +1175,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
1183
1175
|
try {
|
|
1184
1176
|
const updateDoc = {
|
|
1185
1177
|
result: { status: types.CaptchaStatus.disapproved, reason },
|
|
1186
|
-
lastUpdatedTimestamp: Date
|
|
1178
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date(),
|
|
1187
1179
|
...coords ? { coords } : {}
|
|
1188
1180
|
};
|
|
1189
1181
|
const filter = { id: commitmentId };
|
|
@@ -1258,7 +1250,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
1258
1250
|
* @description Create the status of a scheduled task
|
|
1259
1251
|
*/
|
|
1260
1252
|
async createScheduledTaskStatus(taskName, status) {
|
|
1261
|
-
const now =
|
|
1253
|
+
const now = /* @__PURE__ */ new Date();
|
|
1262
1254
|
const doc = typesDatabase.ScheduledTaskSchema.parse({
|
|
1263
1255
|
processName: taskName,
|
|
1264
1256
|
datetime: now,
|
|
@@ -1273,7 +1265,7 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
1273
1265
|
async updateScheduledTaskStatus(taskId, status, result) {
|
|
1274
1266
|
const update = {
|
|
1275
1267
|
status,
|
|
1276
|
-
updated:
|
|
1268
|
+
updated: /* @__PURE__ */ new Date(),
|
|
1277
1269
|
...result && { result }
|
|
1278
1270
|
};
|
|
1279
1271
|
const filter = { _id: taskId };
|
|
@@ -1319,6 +1311,13 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
1319
1311
|
});
|
|
1320
1312
|
await this.tables?.client.bulkWrite(ops);
|
|
1321
1313
|
}
|
|
1314
|
+
/**
|
|
1315
|
+
* @description Get all client records
|
|
1316
|
+
*/
|
|
1317
|
+
async getAllClientRecords() {
|
|
1318
|
+
const docs = await this.tables?.client.find().lean();
|
|
1319
|
+
return docs || [];
|
|
1320
|
+
}
|
|
1322
1321
|
/**
|
|
1323
1322
|
* @description Get a client record
|
|
1324
1323
|
*/
|
|
@@ -1362,5 +1361,70 @@ class ProviderDatabase extends mongo.MongoDatabase {
|
|
|
1362
1361
|
).sort({ createdAt: -1 }).lean();
|
|
1363
1362
|
return (keyRecords || []).map((record) => record.detectorKey);
|
|
1364
1363
|
}
|
|
1364
|
+
/**
|
|
1365
|
+
* @description set client entropy
|
|
1366
|
+
*/
|
|
1367
|
+
async setClientEntropy(account, entropy) {
|
|
1368
|
+
const filter = { account };
|
|
1369
|
+
await this.tables?.clientEntropy.updateOne(
|
|
1370
|
+
filter,
|
|
1371
|
+
{ $set: { entropy } },
|
|
1372
|
+
{ upsert: true }
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
/**
|
|
1376
|
+
* @description get client entropy
|
|
1377
|
+
*/
|
|
1378
|
+
async getClientEntropy(account) {
|
|
1379
|
+
const filter = { account };
|
|
1380
|
+
const doc = await this.tables?.clientEntropy.findOne(filter).lean();
|
|
1381
|
+
return doc ? doc.entropy : void 0;
|
|
1382
|
+
}
|
|
1383
|
+
/** Sample captcha records from the database */
|
|
1384
|
+
async sampleEntropy(sampleSize, siteKey) {
|
|
1385
|
+
const size = sampleSize ? Math.abs(Math.trunc(sampleSize)) : 1;
|
|
1386
|
+
const max = 1e4;
|
|
1387
|
+
if (size > max) {
|
|
1388
|
+
throw new common.ProsopoDBError("DATABASE.CAPTCHA_SAMPLE_SIZE_EXCEEDED", {
|
|
1389
|
+
context: {
|
|
1390
|
+
failedFuncName: this.sampleEntropy.name,
|
|
1391
|
+
sampleSize
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
const cursor = this.tables?.powcaptcha.aggregate([
|
|
1396
|
+
{
|
|
1397
|
+
$match: {
|
|
1398
|
+
dappAccount: siteKey,
|
|
1399
|
+
requestedAtTimestamp: {
|
|
1400
|
+
$gt: new Date((/* @__PURE__ */ new Date()).getTime() - TWENTY_FOUR_HOURS_IN_MS)
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
},
|
|
1404
|
+
{ $limit: max },
|
|
1405
|
+
{ $sample: { size } },
|
|
1406
|
+
{
|
|
1407
|
+
$project: {
|
|
1408
|
+
_id: 0,
|
|
1409
|
+
frictionlessTokenId: 1
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
]);
|
|
1413
|
+
const docs = await cursor;
|
|
1414
|
+
if (docs?.length === 0) {
|
|
1415
|
+
return [];
|
|
1416
|
+
}
|
|
1417
|
+
return (await Promise.all(
|
|
1418
|
+
docs.map(async (doc) => {
|
|
1419
|
+
if (doc.frictionlessTokenId) {
|
|
1420
|
+
const tokenRecord = await this.getSessionRecordByToken(
|
|
1421
|
+
doc.frictionlessTokenId
|
|
1422
|
+
);
|
|
1423
|
+
return tokenRecord?.decryptedHeadHash;
|
|
1424
|
+
}
|
|
1425
|
+
return void 0;
|
|
1426
|
+
})
|
|
1427
|
+
)).filter((headHash) => headHash !== void 0);
|
|
1428
|
+
}
|
|
1365
1429
|
}
|
|
1366
1430
|
exports.ProviderDatabase = ProviderDatabase;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const makeDir = require("make-dir");
|
|
3
4
|
require("./base/index.cjs");
|
|
4
5
|
const index = require("./databases/index.cjs");
|
|
5
6
|
const mongo = require("./base/mongo.cjs");
|
|
@@ -7,6 +8,7 @@ const mongoMemory = require("./base/mongoMemory.cjs");
|
|
|
7
8
|
const provider = require("./databases/provider.cjs");
|
|
8
9
|
const captcha = require("./databases/captcha.cjs");
|
|
9
10
|
const client = require("./databases/client.cjs");
|
|
11
|
+
console.debug(makeDir);
|
|
10
12
|
exports.Databases = index.Databases;
|
|
11
13
|
exports.MongoDatabase = mongo.MongoDatabase;
|
|
12
14
|
exports.MongoMemoryDatabase = mongoMemory.MongoMemoryDatabase;
|
|
@@ -2,9 +2,10 @@ import { isHex } from "@polkadot/util/is";
|
|
|
2
2
|
import { ProsopoDBError } from "@prosopo/common";
|
|
3
3
|
import { connectToRedis, setupRedisIndex } from "@prosopo/redis-client";
|
|
4
4
|
import { DatasetWithIdsAndTreeSchema, StoredStatusNames, CaptchaStatus, ApiParams, CaptchaStates } from "@prosopo/types";
|
|
5
|
-
import { CaptchaRecordSchema, PoWCaptchaRecordSchema, DatasetRecordSchema, SolutionRecordSchema, UserCommitmentRecordSchema, UserSolutionRecordSchema, PendingRecordSchema, ScheduledTaskRecordSchema, ClientRecordSchema,
|
|
6
|
-
import {
|
|
5
|
+
import { CaptchaRecordSchema, PoWCaptchaRecordSchema, DatasetRecordSchema, SolutionRecordSchema, UserCommitmentRecordSchema, UserSolutionRecordSchema, PendingRecordSchema, ScheduledTaskRecordSchema, ClientRecordSchema, SessionRecordSchema, DetectorRecordSchema, ClientEntropyRecordSchema, UserCommitmentSchema, ScheduledTaskSchema } from "@prosopo/types-database";
|
|
6
|
+
import { accessRulesRedisIndex, createRedisAccessRulesStorage } from "@prosopo/user-access-policy/redis";
|
|
7
7
|
import { MongoDatabase } from "../base/mongo.js";
|
|
8
|
+
const TWENTY_FOUR_HOURS_IN_MS = 24 * 60 * 60 * 1e3;
|
|
8
9
|
var TableNames = /* @__PURE__ */ ((TableNames2) => {
|
|
9
10
|
TableNames2["captcha"] = "captcha";
|
|
10
11
|
TableNames2["dataset"] = "dataset";
|
|
@@ -15,9 +16,9 @@ var TableNames = /* @__PURE__ */ ((TableNames2) => {
|
|
|
15
16
|
TableNames2["scheduler"] = "scheduler";
|
|
16
17
|
TableNames2["powcaptcha"] = "powcaptcha";
|
|
17
18
|
TableNames2["client"] = "client";
|
|
18
|
-
TableNames2["frictionlessToken"] = "frictionlessToken";
|
|
19
19
|
TableNames2["session"] = "session";
|
|
20
20
|
TableNames2["detector"] = "detector";
|
|
21
|
+
TableNames2["clientEntropy"] = "clientEntropy";
|
|
21
22
|
return TableNames2;
|
|
22
23
|
})(TableNames || {});
|
|
23
24
|
const PROVIDER_TABLES = [
|
|
@@ -66,11 +67,6 @@ const PROVIDER_TABLES = [
|
|
|
66
67
|
modelName: "Client",
|
|
67
68
|
schema: ClientRecordSchema
|
|
68
69
|
},
|
|
69
|
-
{
|
|
70
|
-
collectionName: "frictionlessToken",
|
|
71
|
-
modelName: "FrictionlessToken",
|
|
72
|
-
schema: FrictionlessTokenRecordSchema
|
|
73
|
-
},
|
|
74
70
|
{
|
|
75
71
|
collectionName: "session",
|
|
76
72
|
modelName: "Session",
|
|
@@ -80,6 +76,11 @@ const PROVIDER_TABLES = [
|
|
|
80
76
|
collectionName: "detector",
|
|
81
77
|
modelName: "Detector",
|
|
82
78
|
schema: DetectorRecordSchema
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
collectionName: "clientEntropy",
|
|
82
|
+
modelName: "ClientEntropy",
|
|
83
|
+
schema: ClientEntropyRecordSchema
|
|
83
84
|
}
|
|
84
85
|
];
|
|
85
86
|
class ProviderDatabase extends MongoDatabase {
|
|
@@ -112,8 +113,8 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
112
113
|
this.redisAccessRulesConnection = setupRedisIndex(
|
|
113
114
|
this.redisConnection,
|
|
114
115
|
{
|
|
115
|
-
...
|
|
116
|
-
name: this.options.redis?.indexName ||
|
|
116
|
+
...accessRulesRedisIndex,
|
|
117
|
+
name: this.options.redis?.indexName || accessRulesRedisIndex.name
|
|
117
118
|
},
|
|
118
119
|
this.logger
|
|
119
120
|
);
|
|
@@ -446,7 +447,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
446
447
|
async storeUserImageCaptchaSolution(captchas, commit) {
|
|
447
448
|
const commitmentRecord = UserCommitmentSchema.parse({
|
|
448
449
|
...commit,
|
|
449
|
-
lastUpdatedTimestamp: Date
|
|
450
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
450
451
|
});
|
|
451
452
|
if (captchas.length) {
|
|
452
453
|
const filter = {
|
|
@@ -486,18 +487,20 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
486
487
|
* @param ipAddress
|
|
487
488
|
* @param headers
|
|
488
489
|
* @param ja4
|
|
489
|
-
* @param
|
|
490
|
+
* @param sessionId
|
|
490
491
|
* @param serverChecked
|
|
491
492
|
* @param userSubmitted
|
|
492
493
|
* @param storedStatus
|
|
493
494
|
* @param userSignature
|
|
494
495
|
* @returns {Promise<void>} A promise that resolves when the record is added.
|
|
495
496
|
*/
|
|
496
|
-
async storePowCaptchaRecord(challenge, components, difficulty, providerSignature, ipAddress, headers, ja4,
|
|
497
|
+
async storePowCaptchaRecord(challenge, components, difficulty, providerSignature, ipAddress, headers, ja4, sessionId, serverChecked = false, userSubmitted = false, storedStatus = StoredStatusNames.notStored, userSignature) {
|
|
497
498
|
const tables = this.getTables();
|
|
498
499
|
const powCaptchaRecord = {
|
|
499
500
|
challenge,
|
|
500
|
-
|
|
501
|
+
userAccount: components.userAccount,
|
|
502
|
+
dappAccount: components.dappAccount,
|
|
503
|
+
requestedAtTimestamp: new Date(components.requestedAtTimestamp),
|
|
501
504
|
ipAddress,
|
|
502
505
|
headers,
|
|
503
506
|
ja4,
|
|
@@ -507,8 +510,8 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
507
510
|
difficulty,
|
|
508
511
|
providerSignature,
|
|
509
512
|
userSignature,
|
|
510
|
-
lastUpdatedTimestamp: Date
|
|
511
|
-
|
|
513
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date(),
|
|
514
|
+
sessionId
|
|
512
515
|
};
|
|
513
516
|
try {
|
|
514
517
|
await tables.powcaptcha.create(powCaptchaRecord);
|
|
@@ -589,7 +592,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
589
592
|
*/
|
|
590
593
|
async updatePowCaptchaRecordResult(challenge, result, serverChecked = false, userSubmitted = false, userSignature) {
|
|
591
594
|
const tables = this.getTables();
|
|
592
|
-
const timestamp = Date
|
|
595
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
593
596
|
const update = {
|
|
594
597
|
result,
|
|
595
598
|
serverChecked,
|
|
@@ -690,7 +693,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
690
693
|
*/
|
|
691
694
|
async markDappUserCommitmentsStored(commitmentIds) {
|
|
692
695
|
const updateDoc = {
|
|
693
|
-
storedAtTimestamp: Date
|
|
696
|
+
storedAtTimestamp: /* @__PURE__ */ new Date()
|
|
694
697
|
};
|
|
695
698
|
await this.tables?.commitment.updateMany(
|
|
696
699
|
{ id: { $in: commitmentIds } },
|
|
@@ -703,7 +706,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
703
706
|
async markDappUserCommitmentsChecked(commitmentIds) {
|
|
704
707
|
const updateDoc = {
|
|
705
708
|
[StoredStatusNames.serverChecked]: true,
|
|
706
|
-
lastUpdatedTimestamp: Date
|
|
709
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
707
710
|
};
|
|
708
711
|
await this.tables?.commitment.updateMany(
|
|
709
712
|
{ id: { $in: commitmentIds } },
|
|
@@ -767,7 +770,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
767
770
|
*/
|
|
768
771
|
async markDappUserPoWCommitmentsStored(challenges) {
|
|
769
772
|
const updateDoc = {
|
|
770
|
-
storedAtTimestamp: Date
|
|
773
|
+
storedAtTimestamp: /* @__PURE__ */ new Date()
|
|
771
774
|
};
|
|
772
775
|
await this.tables?.powcaptcha.updateMany(
|
|
773
776
|
{ challenge: { $in: challenges } },
|
|
@@ -780,7 +783,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
780
783
|
async markDappUserPoWCommitmentsChecked(challenges) {
|
|
781
784
|
const updateDoc = {
|
|
782
785
|
[StoredStatusNames.serverChecked]: true,
|
|
783
|
-
lastUpdatedTimestamp: Date
|
|
786
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
784
787
|
};
|
|
785
788
|
await this.tables?.powcaptcha.updateMany(
|
|
786
789
|
{ challenge: { $in: challenges } },
|
|
@@ -790,46 +793,6 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
790
793
|
{ upsert: false }
|
|
791
794
|
);
|
|
792
795
|
}
|
|
793
|
-
/**
|
|
794
|
-
* Store a new frictionless token record
|
|
795
|
-
*/
|
|
796
|
-
async storeFrictionlessTokenRecord(tokenRecord) {
|
|
797
|
-
const doc = await this.tables.frictionlessToken.create(
|
|
798
|
-
tokenRecord
|
|
799
|
-
);
|
|
800
|
-
return doc._id;
|
|
801
|
-
}
|
|
802
|
-
/** Update a frictionless token record */
|
|
803
|
-
async updateFrictionlessTokenRecord(tokenId, updates) {
|
|
804
|
-
const filter = { _id: tokenId };
|
|
805
|
-
await this.tables.frictionlessToken.updateOne(filter, updates);
|
|
806
|
-
}
|
|
807
|
-
/** Get a frictionless token record */
|
|
808
|
-
async getFrictionlessTokenRecordByTokenId(tokenId) {
|
|
809
|
-
const filter = { _id: tokenId };
|
|
810
|
-
const doc = await this.tables.frictionlessToken.findOne(
|
|
811
|
-
filter
|
|
812
|
-
);
|
|
813
|
-
return doc ? doc : void 0;
|
|
814
|
-
}
|
|
815
|
-
/** Get many frictionless token records */
|
|
816
|
-
async getFrictionlessTokenRecordsByTokenIds(tokenId) {
|
|
817
|
-
const filter = {
|
|
818
|
-
_id: { $in: tokenId }
|
|
819
|
-
};
|
|
820
|
-
return this.tables.frictionlessToken.find(filter).lean();
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
|
-
* Check if a frictionless token record exists.
|
|
824
|
-
* Used to ensure that a token is not used more than once.
|
|
825
|
-
*/
|
|
826
|
-
async getFrictionlessTokenRecordByToken(token) {
|
|
827
|
-
const filter = { token };
|
|
828
|
-
const record = await this.tables.frictionlessToken.findOne(
|
|
829
|
-
filter
|
|
830
|
-
);
|
|
831
|
-
return record || void 0;
|
|
832
|
-
}
|
|
833
796
|
/**
|
|
834
797
|
* Store a new session record
|
|
835
798
|
*/
|
|
@@ -846,6 +809,23 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
846
809
|
});
|
|
847
810
|
}
|
|
848
811
|
}
|
|
812
|
+
/**
|
|
813
|
+
* Get a session record by sessionId
|
|
814
|
+
*/
|
|
815
|
+
async getSessionRecordBySessionId(sessionId) {
|
|
816
|
+
const filter = { sessionId };
|
|
817
|
+
const doc = await this.tables.session.findOne(filter).lean();
|
|
818
|
+
return doc || void 0;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Get a session record by token
|
|
822
|
+
* Used to ensure that a token is not used more than once.
|
|
823
|
+
*/
|
|
824
|
+
async getSessionRecordByToken(token) {
|
|
825
|
+
const filter = { token };
|
|
826
|
+
const record = await this.tables.session.findOne(filter).lean();
|
|
827
|
+
return record || void 0;
|
|
828
|
+
}
|
|
849
829
|
/**
|
|
850
830
|
* Check if a session exists and mark it as removed
|
|
851
831
|
* @returns The session record if it existed, undefined otherwise
|
|
@@ -861,7 +841,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
861
841
|
try {
|
|
862
842
|
const session = await this.tables.session.findOneAndUpdate(filter, {
|
|
863
843
|
deleted: true,
|
|
864
|
-
lastUpdatedTimestamp: Date
|
|
844
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date()
|
|
865
845
|
}).lean();
|
|
866
846
|
return session || void 0;
|
|
867
847
|
} catch (err) {
|
|
@@ -871,6 +851,29 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
871
851
|
});
|
|
872
852
|
}
|
|
873
853
|
}
|
|
854
|
+
/**
|
|
855
|
+
* Get an active session by user IP hash
|
|
856
|
+
* @param userSitekeyIpHash The hash of user, IP and sitekey combination
|
|
857
|
+
* @returns The session record if it exists and is not deleted, undefined otherwise
|
|
858
|
+
*/
|
|
859
|
+
async getSessionByuserSitekeyIpHash(userSitekeyIpHash) {
|
|
860
|
+
this.logger.debug(() => ({
|
|
861
|
+
data: { action: "getting session by user IP hash", userSitekeyIpHash }
|
|
862
|
+
}));
|
|
863
|
+
const filter = {
|
|
864
|
+
userSitekeyIpHash,
|
|
865
|
+
deleted: { $exists: false }
|
|
866
|
+
};
|
|
867
|
+
try {
|
|
868
|
+
const session = await this.tables.session.findOne(filter).lean();
|
|
869
|
+
return session || void 0;
|
|
870
|
+
} catch (err) {
|
|
871
|
+
throw new ProsopoDBError("DATABASE.SESSION_GET_FAILED", {
|
|
872
|
+
context: { error: err, userSitekeyIpHash },
|
|
873
|
+
logger: this.logger
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
}
|
|
874
877
|
/** Get unstored session records
|
|
875
878
|
* @description Get session records that have not been stored yet
|
|
876
879
|
* @param limit
|
|
@@ -926,21 +929,10 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
926
929
|
{ upsert: false }
|
|
927
930
|
);
|
|
928
931
|
}
|
|
929
|
-
/** Mark a list of token records as stored */
|
|
930
|
-
async markFrictionlessTokenRecordsStored(tokenIds) {
|
|
931
|
-
const updateDoc = {
|
|
932
|
-
storedAtTimestamp: /* @__PURE__ */ new Date()
|
|
933
|
-
};
|
|
934
|
-
await this.tables?.frictionlessToken.updateMany(
|
|
935
|
-
{ _id: { $in: tokenIds } },
|
|
936
|
-
{ $set: updateDoc },
|
|
937
|
-
{ upsert: false }
|
|
938
|
-
);
|
|
939
|
-
}
|
|
940
932
|
/**
|
|
941
933
|
* @description Store a Dapp User's pending record
|
|
942
934
|
*/
|
|
943
|
-
async storePendingImageCommitment(userAccount, requestHash, salt, deadlineTimestamp, requestedAtTimestamp, ipAddress, threshold,
|
|
935
|
+
async storePendingImageCommitment(userAccount, requestHash, salt, deadlineTimestamp, requestedAtTimestamp, ipAddress, threshold, sessionId) {
|
|
944
936
|
if (!isHex(requestHash)) {
|
|
945
937
|
throw new ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
946
938
|
context: {
|
|
@@ -957,7 +949,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
957
949
|
deadlineTimestamp,
|
|
958
950
|
requestedAtTimestamp: new Date(requestedAtTimestamp),
|
|
959
951
|
ipAddress,
|
|
960
|
-
|
|
952
|
+
sessionId,
|
|
961
953
|
threshold
|
|
962
954
|
};
|
|
963
955
|
await this.tables?.pending.updateOne(
|
|
@@ -1160,7 +1152,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
1160
1152
|
const result = { status: CaptchaStatus.approved };
|
|
1161
1153
|
const updateDoc = {
|
|
1162
1154
|
result,
|
|
1163
|
-
lastUpdatedTimestamp: Date
|
|
1155
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date(),
|
|
1164
1156
|
...coords ? { coords } : {}
|
|
1165
1157
|
};
|
|
1166
1158
|
const filter = { id: commitmentId };
|
|
@@ -1181,7 +1173,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
1181
1173
|
try {
|
|
1182
1174
|
const updateDoc = {
|
|
1183
1175
|
result: { status: CaptchaStatus.disapproved, reason },
|
|
1184
|
-
lastUpdatedTimestamp: Date
|
|
1176
|
+
lastUpdatedTimestamp: /* @__PURE__ */ new Date(),
|
|
1185
1177
|
...coords ? { coords } : {}
|
|
1186
1178
|
};
|
|
1187
1179
|
const filter = { id: commitmentId };
|
|
@@ -1256,7 +1248,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
1256
1248
|
* @description Create the status of a scheduled task
|
|
1257
1249
|
*/
|
|
1258
1250
|
async createScheduledTaskStatus(taskName, status) {
|
|
1259
|
-
const now =
|
|
1251
|
+
const now = /* @__PURE__ */ new Date();
|
|
1260
1252
|
const doc = ScheduledTaskSchema.parse({
|
|
1261
1253
|
processName: taskName,
|
|
1262
1254
|
datetime: now,
|
|
@@ -1271,7 +1263,7 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
1271
1263
|
async updateScheduledTaskStatus(taskId, status, result) {
|
|
1272
1264
|
const update = {
|
|
1273
1265
|
status,
|
|
1274
|
-
updated:
|
|
1266
|
+
updated: /* @__PURE__ */ new Date(),
|
|
1275
1267
|
...result && { result }
|
|
1276
1268
|
};
|
|
1277
1269
|
const filter = { _id: taskId };
|
|
@@ -1317,6 +1309,13 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
1317
1309
|
});
|
|
1318
1310
|
await this.tables?.client.bulkWrite(ops);
|
|
1319
1311
|
}
|
|
1312
|
+
/**
|
|
1313
|
+
* @description Get all client records
|
|
1314
|
+
*/
|
|
1315
|
+
async getAllClientRecords() {
|
|
1316
|
+
const docs = await this.tables?.client.find().lean();
|
|
1317
|
+
return docs || [];
|
|
1318
|
+
}
|
|
1320
1319
|
/**
|
|
1321
1320
|
* @description Get a client record
|
|
1322
1321
|
*/
|
|
@@ -1360,6 +1359,71 @@ class ProviderDatabase extends MongoDatabase {
|
|
|
1360
1359
|
).sort({ createdAt: -1 }).lean();
|
|
1361
1360
|
return (keyRecords || []).map((record) => record.detectorKey);
|
|
1362
1361
|
}
|
|
1362
|
+
/**
|
|
1363
|
+
* @description set client entropy
|
|
1364
|
+
*/
|
|
1365
|
+
async setClientEntropy(account, entropy) {
|
|
1366
|
+
const filter = { account };
|
|
1367
|
+
await this.tables?.clientEntropy.updateOne(
|
|
1368
|
+
filter,
|
|
1369
|
+
{ $set: { entropy } },
|
|
1370
|
+
{ upsert: true }
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* @description get client entropy
|
|
1375
|
+
*/
|
|
1376
|
+
async getClientEntropy(account) {
|
|
1377
|
+
const filter = { account };
|
|
1378
|
+
const doc = await this.tables?.clientEntropy.findOne(filter).lean();
|
|
1379
|
+
return doc ? doc.entropy : void 0;
|
|
1380
|
+
}
|
|
1381
|
+
/** Sample captcha records from the database */
|
|
1382
|
+
async sampleEntropy(sampleSize, siteKey) {
|
|
1383
|
+
const size = sampleSize ? Math.abs(Math.trunc(sampleSize)) : 1;
|
|
1384
|
+
const max = 1e4;
|
|
1385
|
+
if (size > max) {
|
|
1386
|
+
throw new ProsopoDBError("DATABASE.CAPTCHA_SAMPLE_SIZE_EXCEEDED", {
|
|
1387
|
+
context: {
|
|
1388
|
+
failedFuncName: this.sampleEntropy.name,
|
|
1389
|
+
sampleSize
|
|
1390
|
+
}
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
const cursor = this.tables?.powcaptcha.aggregate([
|
|
1394
|
+
{
|
|
1395
|
+
$match: {
|
|
1396
|
+
dappAccount: siteKey,
|
|
1397
|
+
requestedAtTimestamp: {
|
|
1398
|
+
$gt: new Date((/* @__PURE__ */ new Date()).getTime() - TWENTY_FOUR_HOURS_IN_MS)
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
},
|
|
1402
|
+
{ $limit: max },
|
|
1403
|
+
{ $sample: { size } },
|
|
1404
|
+
{
|
|
1405
|
+
$project: {
|
|
1406
|
+
_id: 0,
|
|
1407
|
+
frictionlessTokenId: 1
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
]);
|
|
1411
|
+
const docs = await cursor;
|
|
1412
|
+
if (docs?.length === 0) {
|
|
1413
|
+
return [];
|
|
1414
|
+
}
|
|
1415
|
+
return (await Promise.all(
|
|
1416
|
+
docs.map(async (doc) => {
|
|
1417
|
+
if (doc.frictionlessTokenId) {
|
|
1418
|
+
const tokenRecord = await this.getSessionRecordByToken(
|
|
1419
|
+
doc.frictionlessTokenId
|
|
1420
|
+
);
|
|
1421
|
+
return tokenRecord?.decryptedHeadHash;
|
|
1422
|
+
}
|
|
1423
|
+
return void 0;
|
|
1424
|
+
})
|
|
1425
|
+
)).filter((headHash) => headHash !== void 0);
|
|
1426
|
+
}
|
|
1363
1427
|
}
|
|
1364
1428
|
export {
|
|
1365
1429
|
ProviderDatabase
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import makeDir from "make-dir";
|
|
1
2
|
import "./base/index.js";
|
|
2
3
|
import { Databases } from "./databases/index.js";
|
|
3
4
|
import { MongoDatabase } from "./base/mongo.js";
|
|
@@ -5,6 +6,7 @@ import { MongoMemoryDatabase } from "./base/mongoMemory.js";
|
|
|
5
6
|
import { ProviderDatabase } from "./databases/provider.js";
|
|
6
7
|
import { CaptchaDatabase } from "./databases/captcha.js";
|
|
7
8
|
import { ClientDatabase } from "./databases/client.js";
|
|
9
|
+
console.debug(makeDir);
|
|
8
10
|
export {
|
|
9
11
|
CaptchaDatabase,
|
|
10
12
|
ClientDatabase,
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosopo/database",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
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": "
|
|
10
|
-
"npm": "10.
|
|
9
|
+
"node": ">=v20.0.0",
|
|
10
|
+
"npm": ">=10.6.0"
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
@@ -34,29 +34,30 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/prosopo/captcha#readme",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@polkadot/util": "
|
|
38
|
-
"@prosopo/common": "3.1.
|
|
39
|
-
"@prosopo/config": "3.1.
|
|
40
|
-
"@prosopo/locale": "3.1.
|
|
41
|
-
"@prosopo/
|
|
42
|
-
"@prosopo/types
|
|
43
|
-
"@prosopo/
|
|
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",
|
|
45
|
+
"make-dir": "3.1.0",
|
|
44
46
|
"mongodb": "6.15.0",
|
|
45
|
-
"mongodb-memory-server": "10.
|
|
46
|
-
"mongoose": "8.13.0"
|
|
47
|
-
"@prosopo/redis-client": "1.0.5"
|
|
47
|
+
"mongodb-memory-server": "10.3.0",
|
|
48
|
+
"mongoose": "8.13.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@types/node": "22.10.2",
|
|
51
|
-
"@vitest/coverage-v8": "3.
|
|
52
|
+
"@vitest/coverage-v8": "3.2.4",
|
|
52
53
|
"concurrently": "9.0.1",
|
|
53
54
|
"del-cli": "6.0.0",
|
|
54
55
|
"npm-run-all": "4.1.5",
|
|
55
56
|
"tslib": "2.7.0",
|
|
56
57
|
"tsx": "4.20.3",
|
|
57
58
|
"typescript": "5.6.2",
|
|
58
|
-
"vite": "6.
|
|
59
|
-
"vitest": "3.
|
|
59
|
+
"vite": "6.4.1",
|
|
60
|
+
"vitest": "3.2.4"
|
|
60
61
|
},
|
|
61
62
|
"sideEffects": false
|
|
62
63
|
}
|