@prosopo/database 3.15.19 → 3.15.21
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/.turbo/turbo-build$colon$cjs.log +20 -17
- package/.turbo/turbo-build$colon$tsc.log +16 -16
- package/.turbo/turbo-build.log +21 -18
- package/CHANGELOG.md +24 -0
- package/dist/_virtual/_rolldown/runtime.js +3 -0
- package/dist/base/index.js +1 -4
- package/dist/base/mongo.js +133 -137
- package/dist/base/mongoMemory.js +21 -21
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/cjs/base/index.cjs +4 -6
- package/dist/cjs/base/mongo.cjs +140 -143
- package/dist/cjs/base/mongoMemory.cjs +22 -22
- package/dist/cjs/databases/captcha.cjs +220 -256
- package/dist/cjs/databases/centralDbStreamer.cjs +148 -170
- package/dist/cjs/databases/client.cjs +46 -62
- package/dist/cjs/databases/index.cjs +19 -19
- package/dist/cjs/databases/provider.cjs +1827 -2251
- package/dist/cjs/index.cjs +25 -23
- package/dist/cjs/mongooseOptions.cjs +59 -58
- package/dist/cjs/redisCache.cjs +432 -474
- package/dist/databases/captcha.d.ts.map +1 -1
- package/dist/databases/captcha.js +217 -253
- package/dist/databases/captcha.js.map +1 -1
- package/dist/databases/centralDbStreamer.js +147 -169
- package/dist/databases/client.js +44 -60
- package/dist/databases/index.js +10 -14
- package/dist/databases/provider.d.ts +4 -4
- package/dist/databases/provider.d.ts.map +1 -1
- package/dist/databases/provider.js +1823 -2247
- package/dist/databases/provider.js.map +1 -1
- package/dist/index.js +9 -18
- package/dist/mongooseOptions.js +59 -59
- package/dist/redisCache.js +432 -474
- package/dist/tests/integration/saveCaptchasSessionUpsert.integration.test.d.ts +2 -0
- package/dist/tests/integration/saveCaptchasSessionUpsert.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/saveCaptchasSessionUpsert.integration.test.js +64 -0
- package/dist/tests/integration/saveCaptchasSessionUpsert.integration.test.js.map +1 -0
- package/package.json +14 -14
|
@@ -1,171 +1,149 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Stream a session record to the central DB.
|
|
152
|
-
* Fire-and-forget: errors are logged, never thrown.
|
|
153
|
-
*/
|
|
154
|
-
streamSessionRecord(record, markStored) {
|
|
155
|
-
const timestamp = this.getRecordTimestamp(record);
|
|
156
|
-
this.ensureConnected().then(() => {
|
|
157
|
-
const { _id, ...safeDoc } = record;
|
|
158
|
-
return this.db.tables.session.updateOne(
|
|
159
|
-
{ sessionId: safeDoc.sessionId },
|
|
160
|
-
{ $set: safeDoc },
|
|
161
|
-
{ upsert: true }
|
|
162
|
-
);
|
|
163
|
-
}).then(() => markStored?.(timestamp)).catch((err) => {
|
|
164
|
-
this.logger.error(() => ({
|
|
165
|
-
err,
|
|
166
|
-
msg: "Failed to stream session record to central DB"
|
|
167
|
-
}));
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
1
|
+
const require_captcha = require("./captcha.cjs");
|
|
2
|
+
let _prosopo_logger = require("@prosopo/logger");
|
|
3
|
+
//#region src/databases/centralDbStreamer.ts
|
|
4
|
+
/**
|
|
5
|
+
* Fire-and-forget streamer that sends captcha records to a central database
|
|
6
|
+
* in real-time. Errors are logged but never thrown, so local operations
|
|
7
|
+
* are never blocked or disrupted.
|
|
8
|
+
*
|
|
9
|
+
* Unlike the batch `saveCaptchas()` method on CaptchaDatabase, this maintains
|
|
10
|
+
* a persistent connection and upserts individual records as they arrive.
|
|
11
|
+
*
|
|
12
|
+
* After a successful central write, the provided `markStored` callback is
|
|
13
|
+
* called with the record's `lastUpdatedTimestamp` so the batch cron can
|
|
14
|
+
* determine whether the stored version is still current.
|
|
15
|
+
*/
|
|
16
|
+
var CentralDbStreamer = class CentralDbStreamer {
|
|
17
|
+
static {
|
|
18
|
+
this.RECONNECT_COOLDOWN_MS = 5e3;
|
|
19
|
+
}
|
|
20
|
+
constructor(mongoCaptchaUri, logger) {
|
|
21
|
+
this.lastFailureTime = 0;
|
|
22
|
+
this.logger = logger || (0, _prosopo_logger.getLogger)("info", "CentralDbStreamer");
|
|
23
|
+
this.db = new require_captcha.CaptchaDatabase(mongoCaptchaUri, void 0, void 0, this.logger);
|
|
24
|
+
}
|
|
25
|
+
ensureConnected() {
|
|
26
|
+
if (this.connectPromise && !this.db.connected) this.connectPromise = void 0;
|
|
27
|
+
if (!this.connectPromise) {
|
|
28
|
+
if (Date.now() - this.lastFailureTime < CentralDbStreamer.RECONNECT_COOLDOWN_MS) return Promise.reject(/* @__PURE__ */ new Error("CentralDbStreamer reconnect cooldown"));
|
|
29
|
+
this.connectPromise = this.db.connect().catch((err) => {
|
|
30
|
+
this.logger.error(() => ({
|
|
31
|
+
err,
|
|
32
|
+
msg: "CentralDbStreamer failed to connect"
|
|
33
|
+
}));
|
|
34
|
+
this.lastFailureTime = Date.now();
|
|
35
|
+
this.connectPromise = void 0;
|
|
36
|
+
throw err;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return this.connectPromise;
|
|
40
|
+
}
|
|
41
|
+
getRecordTimestamp(record) {
|
|
42
|
+
return record.lastUpdatedTimestamp ?? record.createdAt ?? record.requestedAtTimestamp ?? /* @__PURE__ */ new Date();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Stream a PoW captcha record (create or update) to the central DB.
|
|
46
|
+
* Fire-and-forget: errors are logged, never thrown.
|
|
47
|
+
*/
|
|
48
|
+
streamPowRecord(record, markStored) {
|
|
49
|
+
const timestamp = this.getRecordTimestamp(record);
|
|
50
|
+
this.ensureConnected().then(() => {
|
|
51
|
+
const { _id, ...safeDoc } = record;
|
|
52
|
+
return this.db.tables.powcaptcha.updateOne({ challenge: safeDoc.challenge }, { $set: safeDoc }, { upsert: true });
|
|
53
|
+
}).then(() => markStored?.(timestamp)).catch((err) => {
|
|
54
|
+
this.logger.error(() => ({
|
|
55
|
+
err,
|
|
56
|
+
msg: "Failed to stream PoW record to central DB"
|
|
57
|
+
}));
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Stream a partial PoW update by fetching the full record first, then upserting.
|
|
62
|
+
*/
|
|
63
|
+
streamPowUpdate(getFullRecord, markStored) {
|
|
64
|
+
getFullRecord().then((record) => {
|
|
65
|
+
if (record) this.streamPowRecord(record, markStored);
|
|
66
|
+
}).catch((err) => {
|
|
67
|
+
this.logger.error(() => ({
|
|
68
|
+
err,
|
|
69
|
+
msg: "Failed to fetch PoW record for central DB streaming"
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Stream an image captcha commitment record to the central DB.
|
|
75
|
+
* Fire-and-forget: errors are logged, never thrown.
|
|
76
|
+
*/
|
|
77
|
+
streamImageRecord(record, markStored) {
|
|
78
|
+
const timestamp = this.getRecordTimestamp(record);
|
|
79
|
+
this.ensureConnected().then(() => {
|
|
80
|
+
const { _id, ...safeDoc } = record;
|
|
81
|
+
return this.db.tables.commitment.updateOne({ id: safeDoc.id }, { $set: safeDoc }, { upsert: true });
|
|
82
|
+
}).then(() => markStored?.(timestamp)).catch((err) => {
|
|
83
|
+
this.logger.error(() => ({
|
|
84
|
+
err,
|
|
85
|
+
msg: "Failed to stream image record to central DB"
|
|
86
|
+
}));
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Stream an image captcha update by fetching the full record first.
|
|
91
|
+
*/
|
|
92
|
+
streamImageUpdate(getFullRecord, markStored) {
|
|
93
|
+
getFullRecord().then((record) => {
|
|
94
|
+
if (record) this.streamImageRecord(record, markStored);
|
|
95
|
+
}).catch((err) => {
|
|
96
|
+
this.logger.error(() => ({
|
|
97
|
+
err,
|
|
98
|
+
msg: "Failed to fetch image record for central DB streaming"
|
|
99
|
+
}));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Stream a puzzle captcha record (create or update) to the central DB.
|
|
104
|
+
* Fire-and-forget: errors are logged, never thrown.
|
|
105
|
+
*/
|
|
106
|
+
streamPuzzleRecord(record, markStored) {
|
|
107
|
+
const timestamp = this.getRecordTimestamp(record);
|
|
108
|
+
this.ensureConnected().then(() => {
|
|
109
|
+
const { _id, ...safeDoc } = record;
|
|
110
|
+
return this.db.tables.puzzlecaptcha.updateOne({ challenge: safeDoc.challenge }, { $set: safeDoc }, { upsert: true });
|
|
111
|
+
}).then(() => markStored?.(timestamp)).catch((err) => {
|
|
112
|
+
this.logger.error(() => ({
|
|
113
|
+
err,
|
|
114
|
+
msg: "Failed to stream puzzle record to central DB"
|
|
115
|
+
}));
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Stream a partial puzzle update by fetching the full record first, then upserting.
|
|
120
|
+
*/
|
|
121
|
+
streamPuzzleUpdate(getFullRecord, markStored) {
|
|
122
|
+
getFullRecord().then((record) => {
|
|
123
|
+
if (record) this.streamPuzzleRecord(record, markStored);
|
|
124
|
+
}).catch((err) => {
|
|
125
|
+
this.logger.error(() => ({
|
|
126
|
+
err,
|
|
127
|
+
msg: "Failed to fetch puzzle record for central DB streaming"
|
|
128
|
+
}));
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Stream a session record to the central DB.
|
|
133
|
+
* Fire-and-forget: errors are logged, never thrown.
|
|
134
|
+
*/
|
|
135
|
+
streamSessionRecord(record, markStored) {
|
|
136
|
+
const timestamp = this.getRecordTimestamp(record);
|
|
137
|
+
this.ensureConnected().then(() => {
|
|
138
|
+
const { _id, ...safeDoc } = record;
|
|
139
|
+
return this.db.tables.session.updateOne({ sessionId: safeDoc.sessionId }, { $set: safeDoc }, { upsert: true });
|
|
140
|
+
}).then(() => markStored?.(timestamp)).catch((err) => {
|
|
141
|
+
this.logger.error(() => ({
|
|
142
|
+
err,
|
|
143
|
+
msg: "Failed to stream session record to central DB"
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
//#endregion
|
|
171
149
|
exports.CentralDbStreamer = CentralDbStreamer;
|
|
@@ -1,63 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
).lean().then(
|
|
48
|
-
(records) => records.map(
|
|
49
|
-
(record) => ({
|
|
50
|
-
account: record.sites.siteKey,
|
|
51
|
-
// Rename "sites.siteKey" to "account"
|
|
52
|
-
settings: record.sites.settings,
|
|
53
|
-
// Rename "sites.settings" to "settings"
|
|
54
|
-
tier: record.tier
|
|
55
|
-
// Keep "tier" as is
|
|
56
|
-
})
|
|
57
|
-
)
|
|
58
|
-
);
|
|
59
|
-
await this.close();
|
|
60
|
-
return newClientRecords;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
1
|
+
const require_mongo = require("../base/mongo.cjs");
|
|
2
|
+
let _prosopo_common = require("@prosopo/common");
|
|
3
|
+
let _prosopo_types_database = require("@prosopo/types-database");
|
|
4
|
+
//#region src/databases/client.ts
|
|
5
|
+
var CLIENT_TABLES = [{
|
|
6
|
+
collectionName: _prosopo_types_database.TableNames.accounts,
|
|
7
|
+
modelName: "Account",
|
|
8
|
+
schema: _prosopo_types_database.AccountSchema
|
|
9
|
+
}];
|
|
10
|
+
var ClientDatabase = class extends require_mongo.MongoDatabase {
|
|
11
|
+
constructor(url, dbname, authSource, logger) {
|
|
12
|
+
super(url, dbname, authSource, logger);
|
|
13
|
+
this.tables = {};
|
|
14
|
+
}
|
|
15
|
+
async connect() {
|
|
16
|
+
await super.connect();
|
|
17
|
+
CLIENT_TABLES.map(({ collectionName, modelName, schema }) => {
|
|
18
|
+
if (this.connection) this.tables[collectionName] = this.connection.model(modelName, schema);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
getTables() {
|
|
22
|
+
if (!this.tables) throw new _prosopo_common.ProsopoDBError("DATABASE.TABLES_UNDEFINED", {
|
|
23
|
+
context: { failedFuncName: this.getTables.name },
|
|
24
|
+
logger: this.logger
|
|
25
|
+
});
|
|
26
|
+
return this.tables;
|
|
27
|
+
}
|
|
28
|
+
async getUpdatedClients(updatedAtTimestamp) {
|
|
29
|
+
await this.connect();
|
|
30
|
+
const newClientRecords = await this.tables.accounts.find({
|
|
31
|
+
$or: [{ "sites.updatedAt": { $gt: updatedAtTimestamp } }, { "sites.updatedAt": { $exists: false } }],
|
|
32
|
+
"users.status": "active"
|
|
33
|
+
}, {
|
|
34
|
+
"sites.siteKey": 1,
|
|
35
|
+
"sites.settings": 1,
|
|
36
|
+
"sites.tier": 1
|
|
37
|
+
}).lean().then((records) => records.map((record) => ({
|
|
38
|
+
account: record.sites.siteKey,
|
|
39
|
+
settings: record.sites.settings,
|
|
40
|
+
tier: record.tier
|
|
41
|
+
})));
|
|
42
|
+
await this.close();
|
|
43
|
+
return newClientRecords;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
63
47
|
exports.ClientDatabase = ClientDatabase;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
[types.DatabaseTypes.Values.mongoMemory]: mongoMemory.MongoMemoryDatabase
|
|
1
|
+
const require_mongo = require("../base/mongo.cjs");
|
|
2
|
+
const require_mongoMemory = require("../base/mongoMemory.cjs");
|
|
3
|
+
const require_captcha = require("./captcha.cjs");
|
|
4
|
+
const require_client = require("./client.cjs");
|
|
5
|
+
const require_provider = require("./provider.cjs");
|
|
6
|
+
const require_centralDbStreamer = require("./centralDbStreamer.cjs");
|
|
7
|
+
let _prosopo_types = require("@prosopo/types");
|
|
8
|
+
//#region src/databases/index.ts
|
|
9
|
+
var Databases = {
|
|
10
|
+
[_prosopo_types.DatabaseTypes.Values.mongo]: require_mongo.MongoDatabase,
|
|
11
|
+
[_prosopo_types.DatabaseTypes.Values.provider]: require_provider.ProviderDatabase,
|
|
12
|
+
[_prosopo_types.DatabaseTypes.Values.client]: require_client.ClientDatabase,
|
|
13
|
+
[_prosopo_types.DatabaseTypes.Values.captcha]: require_captcha.CaptchaDatabase,
|
|
14
|
+
[_prosopo_types.DatabaseTypes.Values.mongoMemory]: require_mongoMemory.MongoMemoryDatabase
|
|
16
15
|
};
|
|
17
|
-
|
|
18
|
-
exports.
|
|
19
|
-
exports.
|
|
20
|
-
exports.
|
|
16
|
+
//#endregion
|
|
17
|
+
exports.CaptchaDatabase = require_captcha.CaptchaDatabase;
|
|
18
|
+
exports.CentralDbStreamer = require_centralDbStreamer.CentralDbStreamer;
|
|
19
|
+
exports.ClientDatabase = require_client.ClientDatabase;
|
|
21
20
|
exports.Databases = Databases;
|
|
21
|
+
exports.ProviderDatabase = require_provider.ProviderDatabase;
|