@prosopo/database 2.5.5 → 2.6.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.
- package/CHANGELOG.md +35 -0
- package/dist/cjs/base/index.cjs +6 -0
- package/dist/cjs/base/mongo.cjs +102 -0
- package/dist/cjs/base/mongoMemory.cjs +28 -0
- package/dist/cjs/databases/captcha.cjs +125 -0
- package/dist/cjs/databases/client.cjs +63 -0
- package/dist/cjs/databases/index.cjs +19 -0
- package/dist/cjs/databases/provider.cjs +1230 -0
- package/dist/cjs/index.cjs +15 -0
- package/dist/databases/captcha.d.ts +9 -2
- package/dist/databases/captcha.d.ts.map +1 -1
- package/dist/databases/captcha.js +53 -4
- package/dist/databases/captcha.js.map +1 -1
- package/dist/databases/provider.d.ts +7 -3
- package/dist/databases/provider.d.ts.map +1 -1
- package/dist/databases/provider.js +70 -3
- package/dist/databases/provider.js.map +1 -1
- package/package.json +8 -7
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @prosopo/database
|
|
2
|
+
|
|
3
|
+
## 2.6.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [6ff193a]
|
|
8
|
+
- @prosopo/types@2.6.2
|
|
9
|
+
- @prosopo/types-database@2.6.2
|
|
10
|
+
- @prosopo/user-access-policy@2.6.2
|
|
11
|
+
|
|
12
|
+
## 2.6.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 52feffc: Adjustable difficulty img captcha
|
|
17
|
+
- Updated dependencies [52feffc]
|
|
18
|
+
- @prosopo/types-database@2.6.1
|
|
19
|
+
- @prosopo/types@2.6.1
|
|
20
|
+
- @prosopo/user-access-policy@2.6.1
|
|
21
|
+
|
|
22
|
+
## 2.6.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- a0bfc8a: bump all pkg versions since independent versioning applied
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [a0bfc8a]
|
|
31
|
+
- @prosopo/config@2.6.0
|
|
32
|
+
- @prosopo/common@2.6.0
|
|
33
|
+
- @prosopo/types@2.6.0
|
|
34
|
+
- @prosopo/types-database@2.6.0
|
|
35
|
+
- @prosopo/user-access-policy@2.6.0
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const mongo = require("./mongo.cjs");
|
|
4
|
+
const mongoMemory = require("./mongoMemory.cjs");
|
|
5
|
+
exports.MongoDatabase = mongo.MongoDatabase;
|
|
6
|
+
exports.MongoMemoryDatabase = mongoMemory.MongoMemoryDatabase;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@prosopo/common");
|
|
4
|
+
const mongodb = require("mongodb");
|
|
5
|
+
const mongoose = require("mongoose");
|
|
6
|
+
mongoose.set("strictQuery", false);
|
|
7
|
+
const DEFAULT_ENDPOINT = "mongodb://127.0.0.1:27017";
|
|
8
|
+
class MongoDatabase {
|
|
9
|
+
constructor(url, dbname, authSource, logger) {
|
|
10
|
+
this.connected = false;
|
|
11
|
+
const baseEndpoint = url || DEFAULT_ENDPOINT;
|
|
12
|
+
const parsedUrl = new URL(baseEndpoint);
|
|
13
|
+
if (dbname) {
|
|
14
|
+
parsedUrl.pathname = dbname;
|
|
15
|
+
}
|
|
16
|
+
if (authSource) {
|
|
17
|
+
parsedUrl.searchParams.set("authSource", authSource);
|
|
18
|
+
}
|
|
19
|
+
this._url = parsedUrl.toString();
|
|
20
|
+
this.safeURL = this.url.replace(/\w+:\w+/, "<Credentials>");
|
|
21
|
+
this.dbname = dbname || parsedUrl.pathname.replace("/", "");
|
|
22
|
+
this.logger = logger || common.getLoggerDefault();
|
|
23
|
+
}
|
|
24
|
+
get url() {
|
|
25
|
+
return this._url;
|
|
26
|
+
}
|
|
27
|
+
getConnection() {
|
|
28
|
+
if (!this.connection) {
|
|
29
|
+
throw new common.ProsopoDBError("DATABASE.CONNECTION_UNDEFINED", {
|
|
30
|
+
context: { failedFuncName: this.getConnection.name },
|
|
31
|
+
logger: this.logger
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return this.connection;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @description Connect to the database and set the various tables
|
|
38
|
+
*/
|
|
39
|
+
async connect() {
|
|
40
|
+
this.logger.info(`Mongo url: ${this.safeURL}`);
|
|
41
|
+
try {
|
|
42
|
+
if (this.connected) {
|
|
43
|
+
this.logger.info(`Database connection to ${this.safeURL} already open`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.connection = await new Promise((resolve, reject) => {
|
|
47
|
+
const connection = mongoose.createConnection(this.url, {
|
|
48
|
+
dbName: this.dbname,
|
|
49
|
+
serverApi: mongodb.ServerApiVersion.v1
|
|
50
|
+
});
|
|
51
|
+
connection.on("open", () => {
|
|
52
|
+
this.logger.info(`Database connection to ${this.safeURL} opened`);
|
|
53
|
+
this.connected = true;
|
|
54
|
+
resolve(connection);
|
|
55
|
+
});
|
|
56
|
+
connection.on("error", (err) => {
|
|
57
|
+
this.connected = false;
|
|
58
|
+
this.logger.error(`Database error: ${err}`);
|
|
59
|
+
reject(err);
|
|
60
|
+
});
|
|
61
|
+
connection.on("connected", () => {
|
|
62
|
+
this.logger.info(`Database connected to ${this.safeURL}`);
|
|
63
|
+
this.connected = true;
|
|
64
|
+
resolve(connection);
|
|
65
|
+
});
|
|
66
|
+
connection.on("disconnected", () => {
|
|
67
|
+
this.connected = false;
|
|
68
|
+
this.logger.info(`Database disconnected from ${this.safeURL}`);
|
|
69
|
+
});
|
|
70
|
+
connection.on("reconnected", () => {
|
|
71
|
+
this.logger.info(`Database reconnected to ${this.safeURL}`);
|
|
72
|
+
this.connected = true;
|
|
73
|
+
resolve(connection);
|
|
74
|
+
});
|
|
75
|
+
connection.on("reconnectFailed", () => {
|
|
76
|
+
this.connected = false;
|
|
77
|
+
this.logger.error(`Database reconnect failed to ${this.safeURL}`);
|
|
78
|
+
});
|
|
79
|
+
connection.on("close", () => {
|
|
80
|
+
this.connected = false;
|
|
81
|
+
this.logger.info(`Database connection to ${this.safeURL} closed`);
|
|
82
|
+
});
|
|
83
|
+
connection.on("fullsetup", () => {
|
|
84
|
+
this.connected = true;
|
|
85
|
+
this.logger.info(
|
|
86
|
+
`Database connection to ${this.safeURL} is fully setup`
|
|
87
|
+
);
|
|
88
|
+
resolve(connection);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
} catch (e) {
|
|
92
|
+
this.logger.error(`Database connection error: ${e}`);
|
|
93
|
+
throw e;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** Close connection to the database */
|
|
97
|
+
async close() {
|
|
98
|
+
this.logger.debug(`Closing connection to ${this.safeURL}`);
|
|
99
|
+
await this.connection?.close();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.MongoDatabase = MongoDatabase;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const mongodbMemoryServer = require("mongodb-memory-server");
|
|
4
|
+
const mongo = require("./mongo.cjs");
|
|
5
|
+
class MongoMemoryDatabase extends mongo.MongoDatabase {
|
|
6
|
+
constructor(url, dbname, logger, authSource) {
|
|
7
|
+
const mongod = new mongodbMemoryServer.MongoMemoryServer();
|
|
8
|
+
const mongoMemoryURL = mongod.getUri();
|
|
9
|
+
super(mongoMemoryURL, dbname, authSource, logger);
|
|
10
|
+
this.running = false;
|
|
11
|
+
this.mongod = mongod;
|
|
12
|
+
this._url = mongoMemoryURL;
|
|
13
|
+
}
|
|
14
|
+
connect() {
|
|
15
|
+
if (!this.running) {
|
|
16
|
+
this.mongod?.start();
|
|
17
|
+
this.running = true;
|
|
18
|
+
} else {
|
|
19
|
+
}
|
|
20
|
+
return super.connect();
|
|
21
|
+
}
|
|
22
|
+
async close() {
|
|
23
|
+
await super.close();
|
|
24
|
+
await this.mongod?.stop();
|
|
25
|
+
this.running = false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.MongoMemoryDatabase = MongoMemoryDatabase;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@prosopo/common");
|
|
4
|
+
const typesDatabase = require("@prosopo/types-database");
|
|
5
|
+
require("../base/index.cjs");
|
|
6
|
+
const mongo = require("../base/mongo.cjs");
|
|
7
|
+
const logger = common.getLoggerDefault();
|
|
8
|
+
var TableNames = /* @__PURE__ */ ((TableNames2) => {
|
|
9
|
+
TableNames2["frictionlessToken"] = "frictionlessToken";
|
|
10
|
+
TableNames2["session"] = "session";
|
|
11
|
+
TableNames2["commitment"] = "commitment";
|
|
12
|
+
TableNames2["powcaptcha"] = "powcaptcha";
|
|
13
|
+
return TableNames2;
|
|
14
|
+
})(TableNames || {});
|
|
15
|
+
const CAPTCHA_TABLES = [
|
|
16
|
+
{
|
|
17
|
+
collectionName: "session",
|
|
18
|
+
modelName: "Session",
|
|
19
|
+
schema: typesDatabase.StoredSessionRecordSchema
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
collectionName: "powcaptcha",
|
|
23
|
+
modelName: "PowCaptcha",
|
|
24
|
+
schema: typesDatabase.StoredPoWCaptchaRecordSchema
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
collectionName: "commitment",
|
|
28
|
+
modelName: "UserCommitment",
|
|
29
|
+
schema: typesDatabase.StoredUserCommitmentRecordSchema
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
class CaptchaDatabase extends mongo.MongoDatabase {
|
|
33
|
+
constructor(url, dbname, authSource, logger2) {
|
|
34
|
+
super(url, dbname, authSource, logger2);
|
|
35
|
+
this.tables = {};
|
|
36
|
+
}
|
|
37
|
+
async connect() {
|
|
38
|
+
await super.connect();
|
|
39
|
+
CAPTCHA_TABLES.map(({ collectionName, modelName, schema }) => {
|
|
40
|
+
if (this.connection) {
|
|
41
|
+
this.tables[collectionName] = this.connection.model(modelName, schema);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
getTables() {
|
|
46
|
+
if (!this.tables) {
|
|
47
|
+
throw new common.ProsopoDBError("DATABASE.TABLES_UNDEFINED", {
|
|
48
|
+
context: { failedFuncName: this.getTables.name },
|
|
49
|
+
logger: this.logger
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return this.tables;
|
|
53
|
+
}
|
|
54
|
+
async saveCaptchas(sessionEvents, imageCaptchaEvents, powCaptchaEvents) {
|
|
55
|
+
await this.connect();
|
|
56
|
+
if (sessionEvents.length) {
|
|
57
|
+
const result = await this.tables.session.bulkWrite(
|
|
58
|
+
sessionEvents.map((document) => {
|
|
59
|
+
const { _id, ...safeDoc } = document;
|
|
60
|
+
return {
|
|
61
|
+
insertOne: {
|
|
62
|
+
document: safeDoc
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
})
|
|
66
|
+
);
|
|
67
|
+
logger.info("Mongo Saved Session Events", result.insertedCount);
|
|
68
|
+
}
|
|
69
|
+
if (imageCaptchaEvents.length) {
|
|
70
|
+
const result = await this.tables.commitment.bulkWrite(
|
|
71
|
+
imageCaptchaEvents.map((doc) => {
|
|
72
|
+
const { _id, ...safeDoc } = doc;
|
|
73
|
+
return {
|
|
74
|
+
updateOne: {
|
|
75
|
+
filter: { id: safeDoc.id },
|
|
76
|
+
update: { $set: safeDoc },
|
|
77
|
+
upsert: true
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
})
|
|
81
|
+
);
|
|
82
|
+
logger.info("Mongo Saved Image Events", result.upsertedCount);
|
|
83
|
+
}
|
|
84
|
+
if (powCaptchaEvents.length) {
|
|
85
|
+
const result = await this.tables.powcaptcha.bulkWrite(
|
|
86
|
+
powCaptchaEvents.map((doc) => {
|
|
87
|
+
const { _id, ...safeDoc } = doc;
|
|
88
|
+
return {
|
|
89
|
+
updateOne: {
|
|
90
|
+
filter: { challenge: safeDoc.challenge },
|
|
91
|
+
update: { $set: safeDoc },
|
|
92
|
+
upsert: true
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
logger.info("Mongo Saved PoW Events", result.upsertedCount);
|
|
98
|
+
}
|
|
99
|
+
await this.close();
|
|
100
|
+
}
|
|
101
|
+
async getCaptchas(filter = {}, limit = 100) {
|
|
102
|
+
await this.connect();
|
|
103
|
+
try {
|
|
104
|
+
const commitmentResults = await this.tables.commitment.find(filter).limit(limit).lean();
|
|
105
|
+
const powCaptchaResults = await this.tables.powcaptcha.find(filter).limit(limit).lean();
|
|
106
|
+
return {
|
|
107
|
+
userCommitmentRecords: commitmentResults,
|
|
108
|
+
powCaptchaRecords: powCaptchaResults
|
|
109
|
+
};
|
|
110
|
+
} catch (error) {
|
|
111
|
+
throw new common.ProsopoDBError("DATABASE.QUERY_ERROR", {
|
|
112
|
+
context: {
|
|
113
|
+
error,
|
|
114
|
+
filter,
|
|
115
|
+
limit,
|
|
116
|
+
failedFuncName: this.getCaptchas.name
|
|
117
|
+
},
|
|
118
|
+
logger: this.logger
|
|
119
|
+
});
|
|
120
|
+
} finally {
|
|
121
|
+
await this.close();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.CaptchaDatabase = CaptchaDatabase;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const common = require("@prosopo/common");
|
|
4
|
+
const typesDatabase = require("@prosopo/types-database");
|
|
5
|
+
require("../base/index.cjs");
|
|
6
|
+
const mongo = require("../base/mongo.cjs");
|
|
7
|
+
const CLIENT_TABLES = [
|
|
8
|
+
{
|
|
9
|
+
collectionName: typesDatabase.TableNames.accounts,
|
|
10
|
+
modelName: "Account",
|
|
11
|
+
schema: typesDatabase.AccountSchema
|
|
12
|
+
}
|
|
13
|
+
];
|
|
14
|
+
class ClientDatabase extends mongo.MongoDatabase {
|
|
15
|
+
constructor(url, dbname, authSource, logger) {
|
|
16
|
+
super(url, dbname, authSource, logger);
|
|
17
|
+
this.tables = {};
|
|
18
|
+
}
|
|
19
|
+
async connect() {
|
|
20
|
+
await super.connect();
|
|
21
|
+
CLIENT_TABLES.map(({ collectionName, modelName, schema }) => {
|
|
22
|
+
if (this.connection) {
|
|
23
|
+
this.tables[collectionName] = this.connection.model(modelName, schema);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
getTables() {
|
|
28
|
+
if (!this.tables) {
|
|
29
|
+
throw new common.ProsopoDBError("DATABASE.TABLES_UNDEFINED", {
|
|
30
|
+
context: { failedFuncName: this.getTables.name },
|
|
31
|
+
logger: this.logger
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return this.tables;
|
|
35
|
+
}
|
|
36
|
+
async getUpdatedClients(updatedAtTimestamp) {
|
|
37
|
+
await this.connect();
|
|
38
|
+
const newClientRecords = await this.tables.accounts.find(
|
|
39
|
+
{
|
|
40
|
+
$or: [
|
|
41
|
+
{ "sites.updatedAt": { $gt: updatedAtTimestamp } },
|
|
42
|
+
{ "sites.updatedAt": { $exists: false } }
|
|
43
|
+
],
|
|
44
|
+
"users.status": "active"
|
|
45
|
+
},
|
|
46
|
+
{ "sites.siteKey": 1, "sites.settings": 1, "sites.tier": 1 }
|
|
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
|
+
}
|
|
63
|
+
exports.ClientDatabase = ClientDatabase;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const types = require("@prosopo/types");
|
|
4
|
+
const mongo = require("../base/mongo.cjs");
|
|
5
|
+
const mongoMemory = require("../base/mongoMemory.cjs");
|
|
6
|
+
const captcha = require("./captcha.cjs");
|
|
7
|
+
const client = require("./client.cjs");
|
|
8
|
+
const provider = require("./provider.cjs");
|
|
9
|
+
const Databases = {
|
|
10
|
+
[types.DatabaseTypes.Values.mongo]: mongo.MongoDatabase,
|
|
11
|
+
[types.DatabaseTypes.Values.provider]: provider.ProviderDatabase,
|
|
12
|
+
[types.DatabaseTypes.Values.client]: client.ClientDatabase,
|
|
13
|
+
[types.DatabaseTypes.Values.captcha]: captcha.CaptchaDatabase,
|
|
14
|
+
[types.DatabaseTypes.Values.mongoMemory]: mongoMemory.MongoMemoryDatabase
|
|
15
|
+
};
|
|
16
|
+
exports.CaptchaDatabase = captcha.CaptchaDatabase;
|
|
17
|
+
exports.ClientDatabase = client.ClientDatabase;
|
|
18
|
+
exports.ProviderDatabase = provider.ProviderDatabase;
|
|
19
|
+
exports.Databases = Databases;
|