@flowerforce/flowerbase 1.7.5 → 1.7.6-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +125 -1
  2. package/dist/auth/controller.d.ts.map +1 -1
  3. package/dist/auth/controller.js +11 -10
  4. package/dist/auth/plugins/jwt.js +1 -1
  5. package/dist/auth/providers/anon-user/controller.js +1 -1
  6. package/dist/auth/providers/custom-function/controller.d.ts.map +1 -1
  7. package/dist/auth/providers/custom-function/controller.js +28 -7
  8. package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
  9. package/dist/auth/providers/local-userpass/controller.js +15 -14
  10. package/dist/auth/utils.d.ts +1 -0
  11. package/dist/auth/utils.d.ts.map +1 -1
  12. package/dist/constants.d.ts +11 -0
  13. package/dist/constants.d.ts.map +1 -1
  14. package/dist/constants.js +14 -3
  15. package/dist/features/encryption/interface.d.ts +36 -0
  16. package/dist/features/encryption/interface.d.ts.map +1 -0
  17. package/dist/features/encryption/interface.js +2 -0
  18. package/dist/features/encryption/utils.d.ts +9 -0
  19. package/dist/features/encryption/utils.d.ts.map +1 -0
  20. package/dist/features/encryption/utils.js +34 -0
  21. package/dist/features/rules/utils.d.ts.map +1 -1
  22. package/dist/features/rules/utils.js +1 -11
  23. package/dist/features/triggers/index.d.ts.map +1 -1
  24. package/dist/features/triggers/index.js +5 -1
  25. package/dist/features/triggers/utils.js +3 -3
  26. package/dist/index.d.ts +3 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +9 -4
  29. package/dist/monitoring/plugin.d.ts.map +1 -1
  30. package/dist/monitoring/plugin.js +31 -0
  31. package/dist/monitoring/routes/users.d.ts.map +1 -1
  32. package/dist/monitoring/routes/users.js +7 -6
  33. package/dist/monitoring/utils.d.ts.map +1 -1
  34. package/dist/monitoring/utils.js +5 -4
  35. package/dist/services/api/index.d.ts +4 -0
  36. package/dist/services/api/index.d.ts.map +1 -1
  37. package/dist/services/api/utils.d.ts +1 -0
  38. package/dist/services/api/utils.d.ts.map +1 -1
  39. package/dist/services/index.d.ts +4 -0
  40. package/dist/services/index.d.ts.map +1 -1
  41. package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
  42. package/dist/services/mongodb-atlas/index.js +9 -7
  43. package/dist/services/mongodb-atlas/model.d.ts +2 -1
  44. package/dist/services/mongodb-atlas/model.d.ts.map +1 -1
  45. package/dist/shared/handleUserDeletion.js +1 -1
  46. package/dist/shared/handleUserRegistration.js +2 -2
  47. package/dist/utils/context/helpers.d.ts +12 -0
  48. package/dist/utils/context/helpers.d.ts.map +1 -1
  49. package/dist/utils/index.d.ts +1 -0
  50. package/dist/utils/index.d.ts.map +1 -1
  51. package/dist/utils/index.js +14 -3
  52. package/dist/utils/initializer/exposeRoutes.js +1 -1
  53. package/dist/utils/initializer/mongodbCSFLE.d.ts +69 -0
  54. package/dist/utils/initializer/mongodbCSFLE.d.ts.map +1 -0
  55. package/dist/utils/initializer/mongodbCSFLE.js +131 -0
  56. package/dist/utils/initializer/registerPlugins.d.ts +5 -1
  57. package/dist/utils/initializer/registerPlugins.d.ts.map +1 -1
  58. package/dist/utils/initializer/registerPlugins.js +27 -5
  59. package/dist/utils/rules-matcher/interface.d.ts +5 -1
  60. package/dist/utils/rules-matcher/interface.d.ts.map +1 -1
  61. package/dist/utils/rules-matcher/interface.js +2 -0
  62. package/dist/utils/rules-matcher/utils.d.ts.map +1 -1
  63. package/dist/utils/rules-matcher/utils.js +51 -16
  64. package/package.json +4 -2
  65. package/src/auth/__tests__/controller.test.ts +1 -0
  66. package/src/auth/controller.ts +12 -11
  67. package/src/auth/plugins/jwt.ts +2 -2
  68. package/src/auth/providers/anon-user/__tests__/controller.test.ts +1 -0
  69. package/src/auth/providers/anon-user/controller.ts +2 -2
  70. package/src/auth/providers/custom-function/controller.ts +29 -8
  71. package/src/auth/providers/local-userpass/controller.ts +16 -15
  72. package/src/auth/utils.ts +1 -0
  73. package/src/constants.ts +14 -4
  74. package/src/features/encryption/interface.ts +46 -0
  75. package/src/features/encryption/utils.ts +22 -0
  76. package/src/features/rules/utils.ts +1 -11
  77. package/src/features/triggers/__tests__/index.test.ts +1 -0
  78. package/src/features/triggers/index.ts +6 -2
  79. package/src/features/triggers/utils.ts +4 -4
  80. package/src/index.ts +10 -2
  81. package/src/monitoring/plugin.ts +33 -0
  82. package/src/monitoring/routes/users.ts +8 -7
  83. package/src/monitoring/ui.collections.js +7 -10
  84. package/src/monitoring/ui.css +383 -1
  85. package/src/monitoring/ui.endpoints.js +5 -10
  86. package/src/monitoring/ui.events.js +4 -6
  87. package/src/monitoring/ui.functions.js +64 -71
  88. package/src/monitoring/ui.html +8 -0
  89. package/src/monitoring/ui.js +189 -0
  90. package/src/monitoring/ui.shared.js +239 -3
  91. package/src/monitoring/ui.triggers.js +2 -3
  92. package/src/monitoring/ui.users.js +5 -9
  93. package/src/monitoring/utils.ts +6 -5
  94. package/src/services/mongodb-atlas/index.ts +10 -13
  95. package/src/services/mongodb-atlas/model.ts +3 -1
  96. package/src/shared/handleUserDeletion.ts +2 -2
  97. package/src/shared/handleUserRegistration.ts +3 -3
  98. package/src/types/fastify-raw-body.d.ts +0 -9
  99. package/src/utils/__tests__/mongodbCSFLE.test.ts +105 -0
  100. package/src/utils/__tests__/operators.test.ts +24 -0
  101. package/src/utils/__tests__/rule.test.ts +39 -0
  102. package/src/utils/__tests__/rulesMatcherInterfaces.test.ts +2 -0
  103. package/src/utils/index.ts +12 -1
  104. package/src/utils/initializer/exposeRoutes.ts +2 -2
  105. package/src/utils/initializer/mongodbCSFLE.ts +224 -0
  106. package/src/utils/initializer/registerPlugins.ts +45 -10
  107. package/src/utils/rules-matcher/interface.ts +5 -1
  108. package/src/utils/rules-matcher/utils.ts +78 -32
package/README.md CHANGED
@@ -265,8 +265,132 @@ Example
265
265
  ```
266
266
  If you're configuring the project from scratch, you can skip ahead to the [Build](#build) step.
267
267
 
268
- --------
268
+ ## 🔐 7 Client-Side Field Level Encryption (CSFLE)
269
269
 
270
+ Flowerbase supports MongoDB Client-Side Field Level Encryption. When enabled, sensitive fields are encrypted by the MongoDB driver before writing to MongoDB and decrypted automatically when reading.
271
+
272
+ What Flowerbase does for you:
273
+
274
+ - Loads all `encryption.json` files under `data_sources/mongodb-atlas/**`.
275
+ - Builds the MongoDB `schemaMap` automatically from those files.
276
+ - Resolves each `keyAlias` in your schemas to a real Data Encryption Key (DEK) `keyId`.
277
+ - Ensures DEKs exist in the key vault (creates them if missing).
278
+ - Configures Fastify MongoDB plugin `autoEncryption` with the generated `schemaMap`.
279
+
280
+ ### 1. Install encryption drivers
281
+
282
+ Refer to the official MongoDB documentation for CSFLE installation requirements: https://www.mongodb.com/docs/manual/core/csfle/install.
283
+
284
+ It is recommended to use the [**Automatic Encryption Shared Library**](https://www.mongodb.com/docs/manual/core/csfle/reference/install-library/?encryption-component=crypt_shared#std-label-csfle-reference-shared-library-download) instead of mongocryptd.
285
+
286
+ Note that the project should also install [mongodb-client-encryption](https://www.npmjs.com/package/mongodb-client-encryption), matching the mongodb driver version.
287
+
288
+ ### 2. Add encryption schema files
289
+
290
+ Create one `encryption.json` per collection you want to encrypt:
291
+
292
+ Path example:
293
+
294
+ ```text
295
+ src/data_sources/mongodb-atlas/<database>/<collection>/encryption.json
296
+ ```
297
+
298
+ Example:
299
+
300
+ ```json
301
+ {
302
+ "database": "appDb",
303
+ "collection": "records",
304
+ "schema": {
305
+ "bsonType": "object",
306
+ "encryptMetadata": {
307
+ "keyAlias": "root-key"
308
+ },
309
+ "properties": {
310
+ "protectedField1": {
311
+ "encrypt": {
312
+ "bsonType": "string",
313
+ "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
314
+ }
315
+ },
316
+ "protectedField2": {
317
+ "encrypt": {
318
+ "bsonType": "string",
319
+ "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
320
+ "keyAlias": "deep-key"
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+ ```
327
+
328
+ Notes:
329
+
330
+ - `encryptMetadata.keyAlias` applies as default key for that object level.
331
+ - `encrypt.keyAlias` overrides key selection for a specific field.
332
+ - If a field has `encrypt` but no `keyAlias`, MongoDB uses nearest `encryptMetadata`.
333
+
334
+ ### 3. Pass `mongodbEncryptionConfig` to `initialize()`
335
+
336
+ `initialize()` accepts `mongodbEncryptionConfig` to configure KMS providers and key vault settings.
337
+
338
+ #### Local KMS provider example (development)
339
+
340
+ ```ts
341
+ import { initialize } from "@flowerforce/flowerbase";
342
+
343
+ await initialize({
344
+ projectId: "my-project-id",
345
+ mongodbUrl: process.env.MONGODB_URL,
346
+ jwtSecret: process.env.JWT_SECRET,
347
+ mongodbEncryptionConfig: {
348
+ kmsProviders: [
349
+ {
350
+ provider: "local",
351
+ keyAlias: "root-key",
352
+ config: {
353
+ // 96-byte local master key encoded as base64
354
+ key: process.env.LOCAL_MASTER_KEY_BASE64,
355
+ },
356
+ },
357
+ {
358
+ provider: "local",
359
+ keyAlias: "deep-key",
360
+ config: { key: process.env.LOCAL_MASTER_KEY_BASE64 },
361
+ },
362
+ ],
363
+ keyVaultDb: "encryption",
364
+ keyVaultCollection: "__keyVault",
365
+ extraOptions: {
366
+ // Optional: path to crypt shared library
367
+ // cryptSharedLibPath: '/opt/mongo_crypt_v1/lib/mongo_crypt_v1.so'
368
+ },
369
+ },
370
+ });
371
+ ```
372
+
373
+ #### AWS KMS provider example
374
+
375
+ ```ts
376
+ mongodbEncryptionConfig: {
377
+ kmsProviders: [
378
+ {
379
+ provider: "aws",
380
+ keyAlias: "root-key",
381
+ config: {
382
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
383
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
384
+ },
385
+ masterKey: {
386
+ key: process.env.AWS_KMS_KEY_ARN,
387
+ region: process.env.AWS_REGION,
388
+ },
389
+ },
390
+ ];
391
+ }
392
+ ```
393
+ ---
270
394
 
271
395
  <a id="migration"></a>
272
396
  ## 🔄 [Migration Guide](#migration) - Migrating Your Realm Project
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAgBzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,iBA0LxD"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAgBzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,iBA2LxD"}
@@ -30,16 +30,17 @@ const unauthorizedSessionError = {
30
30
  function authController(app) {
31
31
  return __awaiter(this, void 0, void 0, function* () {
32
32
  const { authCollection, userCollection, refreshTokensCollection } = constants_1.AUTH_CONFIG;
33
- const db = app.mongo.client.db(constants_1.DB_NAME);
33
+ const authDb = app.mongo.client.db(constants_1.AUTH_DB_NAME);
34
+ const customUserDb = app.mongo.client.db(constants_1.DB_NAME);
34
35
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
35
36
  try {
36
- yield db.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
37
+ yield authDb.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
37
38
  }
38
39
  catch (error) {
39
40
  console.error('Failed to ensure refresh token TTL index', error);
40
41
  }
41
42
  try {
42
- yield db.collection(authCollection).createIndex({ email: 1 }, {
43
+ yield authDb.collection(authCollection).createIndex({ email: 1 }, {
43
44
  unique: true
44
45
  });
45
46
  }
@@ -64,11 +65,11 @@ function authController(app) {
64
65
  if (req.user.typ !== 'access') {
65
66
  throw new Error('Access token required');
66
67
  }
67
- const authUser = yield db
68
+ const authUser = yield authDb
68
69
  .collection(authCollection)
69
70
  .findOne({ _id: bson_1.ObjectId.createFromHexString(req.user.id) });
70
71
  const customData = userCollection && constants_1.AUTH_CONFIG.user_id_field
71
- ? yield db
72
+ ? yield customUserDb
72
73
  .collection(userCollection)
73
74
  .findOne({ [constants_1.AUTH_CONFIG.user_id_field]: req.user.id })
74
75
  : null;
@@ -112,7 +113,7 @@ function authController(app) {
112
113
  }
113
114
  const refreshToken = authHeader.slice('Bearer '.length).trim();
114
115
  const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
115
- const storedToken = yield db.collection(refreshTokensCollection).findOne({
116
+ const storedToken = yield authDb.collection(refreshTokensCollection).findOne({
116
117
  tokenHash: refreshTokenHash,
117
118
  revokedAt: null,
118
119
  expiresAt: { $gt: new Date() }
@@ -121,13 +122,13 @@ function authController(app) {
121
122
  res.code(401).send(unauthorizedSessionError);
122
123
  return;
123
124
  }
124
- const auth_user = yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).findOne({ _id: new this.mongo.ObjectId(req.user.sub) }));
125
+ const auth_user = yield (authDb === null || authDb === void 0 ? void 0 : authDb.collection(authCollection).findOne({ _id: new this.mongo.ObjectId(req.user.sub) }));
125
126
  if (!auth_user) {
126
127
  res.code(401).send(unauthorizedSessionError);
127
128
  return;
128
129
  }
129
130
  const user = userCollection && constants_1.AUTH_CONFIG.user_id_field
130
- ? (yield db.collection(userCollection).findOne({ [constants_1.AUTH_CONFIG.user_id_field]: req.user.sub }))
131
+ ? (yield customUserDb.collection(userCollection).findOne({ [constants_1.AUTH_CONFIG.user_id_field]: req.user.sub }))
131
132
  : {};
132
133
  res.status(201);
133
134
  return {
@@ -154,7 +155,7 @@ function authController(app) {
154
155
  const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
155
156
  const now = new Date();
156
157
  const expiresAt = new Date(Date.now() + refreshTokenTtlMs);
157
- const updateResult = yield db.collection(refreshTokensCollection).findOneAndUpdate({ tokenHash: refreshTokenHash }, {
158
+ const updateResult = yield authDb.collection(refreshTokensCollection).findOneAndUpdate({ tokenHash: refreshTokenHash }, {
158
159
  $set: {
159
160
  revokedAt: now,
160
161
  expiresAt
@@ -171,7 +172,7 @@ function authController(app) {
171
172
  }
172
173
  }
173
174
  if (userId && authCollection) {
174
- yield db.collection(authCollection).updateOne({ _id: userId }, { $set: { lastLogoutAt: now } });
175
+ yield authDb.collection(authCollection).updateOne({ _id: userId }, { $set: { lastLogoutAt: now } });
175
176
  }
176
177
  return { status: 'ok' };
177
178
  });
@@ -51,7 +51,7 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
51
51
  if (((_a = request.user) === null || _a === void 0 ? void 0 : _a.typ) !== 'access') {
52
52
  return;
53
53
  }
54
- const db = (_c = (_b = fastify.mongo) === null || _b === void 0 ? void 0 : _b.client) === null || _c === void 0 ? void 0 : _c.db(constants_1.DB_NAME);
54
+ const db = (_c = (_b = fastify.mongo) === null || _b === void 0 ? void 0 : _b.client) === null || _c === void 0 ? void 0 : _c.db(constants_1.AUTH_DB_NAME);
55
55
  if (!db) {
56
56
  fastify.log.warn('Mongo client unavailable while checking logout state');
57
57
  return;
@@ -22,7 +22,7 @@ const utils_1 = require("../../utils");
22
22
  */
23
23
  function anonUserController(app) {
24
24
  return __awaiter(this, void 0, void 0, function* () {
25
- const db = app.mongo.client.db(constants_1.DB_NAME);
25
+ const db = app.mongo.client.db(constants_1.AUTH_DB_NAME);
26
26
  const { authCollection, refreshTokensCollection } = constants_1.AUTH_CONFIG;
27
27
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
28
28
  const anonUserTtlSeconds = constants_1.DEFAULT_CONFIG.ANON_USER_TTL_SECONDS;
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AASzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBAiHlE"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAUzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBAqIlE"}
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.customFunctionController = customFunctionController;
13
+ const mongodb_1 = require("mongodb");
13
14
  const constants_1 = require("../../../constants");
14
15
  const state_1 = require("../../../state");
15
16
  const context_1 = require("../../../utils/context");
@@ -25,7 +26,8 @@ function customFunctionController(app) {
25
26
  return __awaiter(this, void 0, void 0, function* () {
26
27
  const functionsList = state_1.StateManager.select('functions');
27
28
  const services = state_1.StateManager.select('services');
28
- const db = app.mongo.client.db(constants_1.DB_NAME);
29
+ const authDb = app.mongo.client.db(constants_1.AUTH_DB_NAME);
30
+ const customUserDb = app.mongo.client.db(constants_1.DB_NAME);
29
31
  const { authCollection, refreshTokensCollection, userCollection, user_id_field } = constants_1.AUTH_CONFIG;
30
32
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
31
33
  /**
@@ -39,7 +41,7 @@ function customFunctionController(app) {
39
41
  schema: schema_1.LOGIN_SCHEMA
40
42
  }, function (req, reply) {
41
43
  return __awaiter(this, void 0, void 0, function* () {
42
- var _a, _b;
44
+ var _a, _b, _c;
43
45
  const customFunctionProvider = (_a = constants_1.AUTH_CONFIG.authProviders) === null || _a === void 0 ? void 0 : _a['custom-function'];
44
46
  if (!customFunctionProvider || customFunctionProvider.disabled) {
45
47
  throw new Error('Custom function authentication disabled');
@@ -75,13 +77,32 @@ function customFunctionController(app) {
75
77
  reply.code(401).send({ message: 'Unauthorized' });
76
78
  return;
77
79
  }
78
- const authUser = yield db.collection(authCollection).findOne({ email: authResult.id });
80
+ const email = (_c = authResult.email) !== null && _c !== void 0 ? _c : authResult.id;
81
+ let authUser = yield authDb.collection(authCollection).findOne({ email });
79
82
  if (!authUser) {
80
- reply.code(401).send({ message: 'Unauthorized' });
81
- return;
83
+ const authUserId = new mongodb_1.ObjectId();
84
+ yield authDb.collection(authCollection).insertOne({
85
+ _id: authUserId,
86
+ email,
87
+ status: 'confirmed',
88
+ createdAt: new Date(),
89
+ custom_data: {},
90
+ identities: [
91
+ {
92
+ id: authResult.id.toString(),
93
+ provider_id: authResult.id.toString(),
94
+ provider_type: 'custom-function',
95
+ provider_data: { email }
96
+ }
97
+ ]
98
+ });
99
+ authUser = {
100
+ _id: authUserId,
101
+ email
102
+ };
82
103
  }
83
104
  const user = user_id_field && userCollection
84
- ? yield db
105
+ ? yield customUserDb
85
106
  .collection(userCollection)
86
107
  .findOne({ [user_id_field]: authUser._id.toString() })
87
108
  : {};
@@ -92,7 +113,7 @@ function customFunctionController(app) {
92
113
  };
93
114
  const refreshToken = this.createRefreshToken(currentUserData);
94
115
  const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
95
- yield db.collection(refreshTokensCollection).insertOne({
116
+ yield authDb.collection(refreshTokensCollection).insertOne({
96
117
  userId: authUser._id,
97
118
  tokenHash: refreshTokenHash,
98
119
  createdAt: new Date(),
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAqCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAoXjE"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAqCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAqXjE"}
@@ -40,7 +40,8 @@ function localUserPassController(app) {
40
40
  const { authCollection, userCollection, user_id_field } = constants_1.AUTH_CONFIG;
41
41
  const { resetPasswordCollection } = constants_1.AUTH_CONFIG;
42
42
  const { refreshTokensCollection } = constants_1.AUTH_CONFIG;
43
- const db = app.mongo.client.db(constants_1.DB_NAME);
43
+ const authDb = app.mongo.client.db(constants_1.AUTH_DB_NAME);
44
+ const customUserDb = app.mongo.client.db(constants_1.DB_NAME);
44
45
  const resetPasswordTtlSeconds = constants_1.DEFAULT_CONFIG.RESET_PASSWORD_TTL_SECONDS;
45
46
  const rateLimitWindowMs = constants_1.DEFAULT_CONFIG.AUTH_RATE_LIMIT_WINDOW_MS;
46
47
  const loginMaxAttempts = constants_1.DEFAULT_CONFIG.AUTH_LOGIN_MAX_ATTEMPTS;
@@ -49,20 +50,20 @@ function localUserPassController(app) {
49
50
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
50
51
  const resolveLocalUserpassProvider = () => { var _a; return (_a = constants_1.AUTH_CONFIG.authProviders) === null || _a === void 0 ? void 0 : _a['local-userpass']; };
51
52
  try {
52
- yield db.collection(resetPasswordCollection).createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
53
+ yield authDb.collection(resetPasswordCollection).createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
53
54
  }
54
55
  catch (error) {
55
56
  console.error('Failed to ensure reset password TTL index', error);
56
57
  }
57
58
  try {
58
- yield db.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
59
+ yield authDb.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
59
60
  }
60
61
  catch (error) {
61
62
  console.error('Failed to ensure refresh token TTL index', error);
62
63
  }
63
64
  const handleResetPasswordRequest = (email, password, extraArguments) => __awaiter(this, void 0, void 0, function* () {
64
65
  const { resetPasswordConfig } = constants_1.AUTH_CONFIG;
65
- const authUser = yield db.collection(authCollection).findOne({
66
+ const authUser = yield authDb.collection(authCollection).findOne({
66
67
  email
67
68
  });
68
69
  if (!authUser) {
@@ -70,7 +71,7 @@ function localUserPassController(app) {
70
71
  }
71
72
  const token = (0, crypto_1.generateToken)();
72
73
  const tokenId = (0, crypto_1.generateToken)();
73
- yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).updateOne({ email }, { $set: { token, tokenId, email, createdAt: new Date() } }, { upsert: true }));
74
+ yield (authDb === null || authDb === void 0 ? void 0 : authDb.collection(resetPasswordCollection).updateOne({ email }, { $set: { token, tokenId, email, createdAt: new Date() } }, { upsert: true }));
74
75
  if (!resetPasswordConfig.runResetFunction && !resetPasswordConfig.resetFunctionName) {
75
76
  throw new Error(utils_1.AUTH_ERRORS.MISSING_RESET_FUNCTION);
76
77
  }
@@ -156,7 +157,7 @@ function localUserPassController(app) {
156
157
  res.status(429).send({ message: 'Too many requests' });
157
158
  return;
158
159
  }
159
- const existing = yield db.collection(authCollection).findOne({
160
+ const existing = yield authDb.collection(authCollection).findOne({
160
161
  confirmationToken: req.body.token,
161
162
  confirmationTokenId: req.body.tokenId
162
163
  });
@@ -165,7 +166,7 @@ function localUserPassController(app) {
165
166
  throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
166
167
  }
167
168
  if (existing.status !== 'confirmed') {
168
- yield db.collection(authCollection).updateOne({ _id: existing._id }, {
169
+ yield authDb.collection(authCollection).updateOne({ _id: existing._id }, {
169
170
  $set: { status: 'confirmed' },
170
171
  $unset: { confirmationToken: '', confirmationTokenId: '' }
171
172
  });
@@ -193,7 +194,7 @@ function localUserPassController(app) {
193
194
  res.status(429).send({ message: 'Too many requests' });
194
195
  return;
195
196
  }
196
- const authUser = yield db.collection(authCollection).findOne({
197
+ const authUser = yield authDb.collection(authCollection).findOne({
197
198
  email: req.body.username
198
199
  });
199
200
  if (!authUser) {
@@ -204,7 +205,7 @@ function localUserPassController(app) {
204
205
  throw new Error(utils_1.AUTH_ERRORS.INVALID_CREDENTIALS);
205
206
  }
206
207
  const user = user_id_field && userCollection
207
- ? yield db
208
+ ? yield customUserDb
208
209
  .collection(userCollection)
209
210
  .findOne({ [user_id_field]: authUser._id.toString() })
210
211
  : {};
@@ -215,7 +216,7 @@ function localUserPassController(app) {
215
216
  }
216
217
  const refreshToken = this.createRefreshToken(userWithCustomData);
217
218
  const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
218
- yield db.collection(refreshTokensCollection).insertOne({
219
+ yield authDb.collection(refreshTokensCollection).insertOne({
219
220
  userId: authUser._id,
220
221
  tokenHash: refreshTokenHash,
221
222
  createdAt: new Date(),
@@ -298,7 +299,7 @@ function localUserPassController(app) {
298
299
  return { message: 'Too many requests' };
299
300
  }
300
301
  const { token, tokenId, password } = req.body;
301
- const resetRequest = yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).findOne({ token, tokenId }));
302
+ const resetRequest = yield (authDb === null || authDb === void 0 ? void 0 : authDb.collection(resetPasswordCollection).findOne({ token, tokenId }));
302
303
  if (!resetRequest) {
303
304
  throw new Error(utils_1.AUTH_ERRORS.INVALID_RESET_PARAMS);
304
305
  }
@@ -307,16 +308,16 @@ function localUserPassController(app) {
307
308
  Number.isNaN(createdAt.getTime()) ||
308
309
  Date.now() - createdAt.getTime() > resetPasswordTtlSeconds * 1000;
309
310
  if (isExpired) {
310
- yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).deleteOne({ _id: resetRequest._id }));
311
+ yield (authDb === null || authDb === void 0 ? void 0 : authDb.collection(resetPasswordCollection).deleteOne({ _id: resetRequest._id }));
311
312
  throw new Error(utils_1.AUTH_ERRORS.INVALID_RESET_PARAMS);
312
313
  }
313
314
  const hashedPassword = yield (0, crypto_1.hashPassword)(password);
314
- yield db.collection(authCollection).updateOne({ email: resetRequest.email }, {
315
+ yield authDb.collection(authCollection).updateOne({ email: resetRequest.email }, {
315
316
  $set: {
316
317
  password: hashedPassword
317
318
  }
318
319
  });
319
- yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).deleteOne({ _id: resetRequest._id }));
320
+ yield (authDb === null || authDb === void 0 ? void 0 : authDb.collection(resetPasswordCollection).deleteOne({ _id: resetRequest._id }));
320
321
  });
321
322
  });
322
323
  });
@@ -150,6 +150,7 @@ export declare enum AUTH_ERRORS {
150
150
  }
151
151
  export interface AuthConfig {
152
152
  auth_collection?: string;
153
+ auth_database?: string;
153
154
  'api-key': ApiKey;
154
155
  'local-userpass': LocalUserpass;
155
156
  'custom-function': CustomFunction;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc;;;CAA4C,CAAC;AACxE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;CAexB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;CAc7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;CAgB7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;CAWhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;CAU/B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;CAe/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;IAC/B,iBAAiB,EAAE,cAAc,CAAA;IACjC,WAAW,CAAC,EAAE,QAAQ,CAAA;CACvB;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAA;KAC3B,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,8BAA8B,EAAE,MAAM,CAAA;CACvC;AAMD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAuCjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAarC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc;;;CAA4C,CAAC;AACxE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;CAexB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;CAc7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;CAgB7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;CAWhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;CAU/B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;CAe/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;IAC/B,iBAAiB,EAAE,cAAc,CAAA;IACjC,WAAW,CAAC,EAAE,QAAQ,CAAA;CACvB;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAA;KAC3B,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,8BAA8B,EAAE,MAAM,CAAA;CACvC;AAMD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAuCjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAarC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
@@ -33,10 +33,15 @@ export declare const DEFAULT_CONFIG: {
33
33
  origin: string;
34
34
  methods: ALLOWED_METHODS[];
35
35
  };
36
+ MONGODB_ENCRYPTION_CONFIG: {
37
+ keyVaultDb: string;
38
+ keyVaultCollection: string;
39
+ };
36
40
  };
37
41
  export declare const API_VERSION: string;
38
42
  export declare const HTTPS_SCHEMA: string;
39
43
  export declare const DB_NAME: string;
44
+ export declare const AUTH_DB_NAME: string;
40
45
  type AuthProviders = Record<string, {
41
46
  disabled?: boolean;
42
47
  config?: unknown;
@@ -62,5 +67,11 @@ export declare const S3_CONFIG: {
62
67
  ACCESS_KEY_ID: string | undefined;
63
68
  SECRET_ACCESS_KEY: string | undefined;
64
69
  };
70
+ /**
71
+ * Name of the MongoDB client to use for change streams.
72
+ * This may be a separate instance because streams do not work
73
+ * when the main client has auto encryption enabled.
74
+ */
75
+ export declare const CHANGESTREAM = "changestream";
65
76
  export {};
66
77
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAsBpC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmCsB,eAAe,EAAE;;CAEjE,CAAA;AACD,eAAO,MAAM,WAAW,QAA8C,CAAA;AACtE,eAAO,MAAM,YAAY,QAA8B,CAAA;AACvD,eAAO,MAAM,OAAO,QAAgB,CAAA;AAEpC,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAE7E,eAAO,MAAM,WAAW;;;;;;;mBAOqB,aAAa;;;;;;;;;CAOzD,CAAA;AAID,eAAO,MAAM,SAAS;;;CAGrB,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAsBpC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmCsB,eAAe,EAAE;;;;;;CAMjE,CAAA;AACD,eAAO,MAAM,WAAW,QAA8C,CAAA;AACtE,eAAO,MAAM,YAAY,QAA8B,CAAA;AACvD,eAAO,MAAM,OAAO,QAAgB,CAAA;AACpC,eAAO,MAAM,YAAY,QAAiC,CAAA;AAE1D,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAE7E,eAAO,MAAM,WAAW;;;;;;;mBAOqB,aAAa;;;;;;;;;CAOzD,CAAA;AAED,eAAO,MAAM,SAAS;;;CAGrB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAA"}
package/dist/constants.js CHANGED
@@ -12,7 +12,7 @@ var __rest = (this && this.__rest) || function (s, e) {
12
12
  };
13
13
  var _a, _b, _c, _d, _e, _f, _g, _h;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.S3_CONFIG = exports.AUTH_CONFIG = exports.DB_NAME = exports.HTTPS_SCHEMA = exports.API_VERSION = exports.DEFAULT_CONFIG = void 0;
15
+ exports.CHANGESTREAM = exports.S3_CONFIG = exports.AUTH_CONFIG = exports.AUTH_DB_NAME = exports.DB_NAME = exports.HTTPS_SCHEMA = exports.API_VERSION = exports.DEFAULT_CONFIG = void 0;
16
16
  const utils_1 = require("./auth/utils");
17
17
  const parseBoolean = (value) => {
18
18
  if (!value)
@@ -25,8 +25,8 @@ const monitEnabledEnv = process.env.MONIT_ENABLED;
25
25
  const monitEnabled = typeof monitEnabledEnv === 'string'
26
26
  ? parseBoolean(monitEnabledEnv)
27
27
  : false;
28
- const { database_name, collection_name = 'users', user_id_field = 'id', on_user_creation_function_name } = (0, utils_1.loadCustomUserData)();
29
- const _j = (0, utils_1.loadAuthConfig)(), { auth_collection = 'auth_users' } = _j, configuration = __rest(_j, ["auth_collection"]);
28
+ const { database_name = 'main', collection_name = 'users', user_id_field = 'id', on_user_creation_function_name } = (0, utils_1.loadCustomUserData)();
29
+ const _j = (0, utils_1.loadAuthConfig)(), { auth_collection = 'auth_users', auth_database } = _j, configuration = __rest(_j, ["auth_collection", "auth_database"]);
30
30
  exports.DEFAULT_CONFIG = {
31
31
  PORT: Number(process.env.PORT) || 3000,
32
32
  MONGODB_URL: process.env.MONGODB_URL || '',
@@ -63,11 +63,16 @@ exports.DEFAULT_CONFIG = {
63
63
  CORS_OPTIONS: {
64
64
  origin: "*",
65
65
  methods: ["GET", "POST", "PUT", "DELETE"]
66
+ },
67
+ MONGODB_ENCRYPTION_CONFIG: {
68
+ keyVaultDb: "encryption",
69
+ keyVaultCollection: "__keyVault"
66
70
  }
67
71
  };
68
72
  exports.API_VERSION = `/api/client/${exports.DEFAULT_CONFIG.API_VERSION}`;
69
73
  exports.HTTPS_SCHEMA = exports.DEFAULT_CONFIG.HTTPS_SCHEMA;
70
74
  exports.DB_NAME = database_name;
75
+ exports.AUTH_DB_NAME = auth_database !== null && auth_database !== void 0 ? auth_database : database_name;
71
76
  // TODO spostare nell'oggetto providers anche le altre configurazioni
72
77
  exports.AUTH_CONFIG = {
73
78
  authCollection: auth_collection,
@@ -88,3 +93,9 @@ exports.S3_CONFIG = {
88
93
  ACCESS_KEY_ID: process.env.S3_ACCESS_KEY_ID,
89
94
  SECRET_ACCESS_KEY: process.env.S3_SECRET_ACCESS_KEY
90
95
  };
96
+ /**
97
+ * Name of the MongoDB client to use for change streams.
98
+ * This may be a separate instance because streams do not work
99
+ * when the main client has auto encryption enabled.
100
+ */
101
+ exports.CHANGESTREAM = "changestream";
@@ -0,0 +1,36 @@
1
+ import type { UUID } from "mongodb";
2
+ export type EncryptionSchemaProperty = EncryptionSchema | {
3
+ encrypt: {
4
+ algorithm: string;
5
+ bsonType: string;
6
+ keyAlias?: string;
7
+ };
8
+ };
9
+ export type EncryptionSchema = {
10
+ bsonType: "object";
11
+ properties: Record<string, EncryptionSchemaProperty>;
12
+ encryptMetadata?: {
13
+ keyAlias: string;
14
+ };
15
+ };
16
+ export type MappedEncryptionSchemaProperty = MappedEncryptionSchema | {
17
+ encrypt: {
18
+ algorithm: string;
19
+ bsonType: string;
20
+ keyId?: [UUID];
21
+ };
22
+ };
23
+ export type MappedEncryptionSchema = {
24
+ bsonType: "object";
25
+ properties: Record<string, MappedEncryptionSchemaProperty>;
26
+ encryptMetadata?: {
27
+ keyId: [UUID];
28
+ };
29
+ };
30
+ export type EncryptionSchemaFile = {
31
+ database: string;
32
+ collection: string;
33
+ schema: EncryptionSchema;
34
+ };
35
+ export type EncryptionSchemas = Record<string, EncryptionSchema>;
36
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/features/encryption/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAEnC,MAAM,MAAM,wBAAwB,GAChC,gBAAgB,GAChB;IACA,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,CAAA;CACF,CAAA;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,QAAQ,CAAA;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;IACpD,eAAe,CAAC,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAC;CACH,CAAA;AAGD,MAAM,MAAM,8BAA8B,GACtC,sBAAsB,GACtB;IACA,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,EAAE,MAAM,CAAA;QAChB,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;KACf,CAAA;CACF,CAAA;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,QAAQ,CAAA;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAA;IAC1D,eAAe,CAAC,EAAE;QAChB,KAAK,EAAE,CAAC,IAAI,CAAC,CAAA;KACd,CAAC;CACH,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,gBAAgB,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import { EncryptionSchemas } from "./interface";
2
+ /**
3
+ * @experimental
4
+ * Schemas used for Client-Side Level Encryption configuration.
5
+ *
6
+ * **Important:** These schemas do not perform JSON validation.
7
+ */
8
+ export declare const loadEncryptionSchemas: (rootDir?: string) => Promise<EncryptionSchemas>;
9
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/encryption/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAErE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAU,gBAAuB,KAAG,OAAO,CAAC,iBAAiB,CAW9F,CAAA"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.loadEncryptionSchemas = void 0;
16
+ const node_path_1 = __importDefault(require("node:path"));
17
+ const utils_1 = require("../../utils");
18
+ /**
19
+ * @experimental
20
+ * Schemas used for Client-Side Level Encryption configuration.
21
+ *
22
+ * **Important:** These schemas do not perform JSON validation.
23
+ */
24
+ const loadEncryptionSchemas = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (rootDir = process.cwd()) {
25
+ const schemasRoot = node_path_1.default.join(rootDir, 'data_sources', 'mongodb-atlas');
26
+ const files = (0, utils_1.recursivelyCollectFiles)(schemasRoot);
27
+ const schemaFiles = files.filter((x) => x.endsWith('encryption.json'));
28
+ return schemaFiles.reduce((acc, filePath) => {
29
+ const { collection, database, schema } = (0, utils_1.readJsonContent)(filePath);
30
+ acc[`${database}.${collection}`] = schema;
31
+ return acc;
32
+ }, {});
33
+ });
34
+ exports.loadEncryptionSchemas = loadEncryptionSchemas;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/rules/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAe,MAAM,aAAa,CAAA;AAEhD,eAAO,MAAM,SAAS,GAAU,gBAAuB,KAAG,OAAO,CAAC,KAAK,CAsCtE,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/rules/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAe,MAAM,aAAa,CAAA;AAEhD,eAAO,MAAM,SAAS,GAAU,gBAAuB,KAAG,OAAO,CAAC,KAAK,CA6BtE,CAAA"}