@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.
- package/README.md +125 -1
- package/dist/auth/controller.d.ts.map +1 -1
- package/dist/auth/controller.js +11 -10
- package/dist/auth/plugins/jwt.js +1 -1
- package/dist/auth/providers/anon-user/controller.js +1 -1
- package/dist/auth/providers/custom-function/controller.d.ts.map +1 -1
- package/dist/auth/providers/custom-function/controller.js +28 -7
- package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
- package/dist/auth/providers/local-userpass/controller.js +15 -14
- package/dist/auth/utils.d.ts +1 -0
- package/dist/auth/utils.d.ts.map +1 -1
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +14 -3
- package/dist/features/encryption/interface.d.ts +36 -0
- package/dist/features/encryption/interface.d.ts.map +1 -0
- package/dist/features/encryption/interface.js +2 -0
- package/dist/features/encryption/utils.d.ts +9 -0
- package/dist/features/encryption/utils.d.ts.map +1 -0
- package/dist/features/encryption/utils.js +34 -0
- package/dist/features/rules/utils.d.ts.map +1 -1
- package/dist/features/rules/utils.js +1 -11
- package/dist/features/triggers/index.d.ts.map +1 -1
- package/dist/features/triggers/index.js +5 -1
- package/dist/features/triggers/utils.js +3 -3
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -4
- package/dist/monitoring/plugin.d.ts.map +1 -1
- package/dist/monitoring/plugin.js +31 -0
- package/dist/monitoring/routes/users.d.ts.map +1 -1
- package/dist/monitoring/routes/users.js +7 -6
- package/dist/monitoring/utils.d.ts.map +1 -1
- package/dist/monitoring/utils.js +5 -4
- package/dist/services/api/index.d.ts +4 -0
- package/dist/services/api/index.d.ts.map +1 -1
- package/dist/services/api/utils.d.ts +1 -0
- package/dist/services/api/utils.d.ts.map +1 -1
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/index.js +9 -7
- package/dist/services/mongodb-atlas/model.d.ts +2 -1
- package/dist/services/mongodb-atlas/model.d.ts.map +1 -1
- package/dist/shared/handleUserDeletion.js +1 -1
- package/dist/shared/handleUserRegistration.js +2 -2
- package/dist/utils/context/helpers.d.ts +12 -0
- package/dist/utils/context/helpers.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +14 -3
- package/dist/utils/initializer/exposeRoutes.js +1 -1
- package/dist/utils/initializer/mongodbCSFLE.d.ts +69 -0
- package/dist/utils/initializer/mongodbCSFLE.d.ts.map +1 -0
- package/dist/utils/initializer/mongodbCSFLE.js +131 -0
- package/dist/utils/initializer/registerPlugins.d.ts +5 -1
- package/dist/utils/initializer/registerPlugins.d.ts.map +1 -1
- package/dist/utils/initializer/registerPlugins.js +27 -5
- package/dist/utils/rules-matcher/interface.d.ts +5 -1
- package/dist/utils/rules-matcher/interface.d.ts.map +1 -1
- package/dist/utils/rules-matcher/interface.js +2 -0
- package/dist/utils/rules-matcher/utils.d.ts.map +1 -1
- package/dist/utils/rules-matcher/utils.js +51 -16
- package/package.json +4 -2
- package/src/auth/__tests__/controller.test.ts +1 -0
- package/src/auth/controller.ts +12 -11
- package/src/auth/plugins/jwt.ts +2 -2
- package/src/auth/providers/anon-user/__tests__/controller.test.ts +1 -0
- package/src/auth/providers/anon-user/controller.ts +2 -2
- package/src/auth/providers/custom-function/controller.ts +29 -8
- package/src/auth/providers/local-userpass/controller.ts +16 -15
- package/src/auth/utils.ts +1 -0
- package/src/constants.ts +14 -4
- package/src/features/encryption/interface.ts +46 -0
- package/src/features/encryption/utils.ts +22 -0
- package/src/features/rules/utils.ts +1 -11
- package/src/features/triggers/__tests__/index.test.ts +1 -0
- package/src/features/triggers/index.ts +6 -2
- package/src/features/triggers/utils.ts +4 -4
- package/src/index.ts +10 -2
- package/src/monitoring/plugin.ts +33 -0
- package/src/monitoring/routes/users.ts +8 -7
- package/src/monitoring/ui.collections.js +7 -10
- package/src/monitoring/ui.css +383 -1
- package/src/monitoring/ui.endpoints.js +5 -10
- package/src/monitoring/ui.events.js +4 -6
- package/src/monitoring/ui.functions.js +64 -71
- package/src/monitoring/ui.html +8 -0
- package/src/monitoring/ui.js +189 -0
- package/src/monitoring/ui.shared.js +239 -3
- package/src/monitoring/ui.triggers.js +2 -3
- package/src/monitoring/ui.users.js +5 -9
- package/src/monitoring/utils.ts +6 -5
- package/src/services/mongodb-atlas/index.ts +10 -13
- package/src/services/mongodb-atlas/model.ts +3 -1
- package/src/shared/handleUserDeletion.ts +2 -2
- package/src/shared/handleUserRegistration.ts +3 -3
- package/src/types/fastify-raw-body.d.ts +0 -9
- package/src/utils/__tests__/mongodbCSFLE.test.ts +105 -0
- package/src/utils/__tests__/operators.test.ts +24 -0
- package/src/utils/__tests__/rule.test.ts +39 -0
- package/src/utils/__tests__/rulesMatcherInterfaces.test.ts +2 -0
- package/src/utils/index.ts +12 -1
- package/src/utils/initializer/exposeRoutes.ts +2 -2
- package/src/utils/initializer/mongodbCSFLE.ts +224 -0
- package/src/utils/initializer/registerPlugins.ts +45 -10
- package/src/utils/rules-matcher/interface.ts +5 -1
- package/src/utils/rules-matcher/utils.ts +78 -32
package/dist/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,WAAuC,CAAA;AACvF,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,KACL,OAAO,CAAA;AAElD,eAAO,MAAM,uBAAuB,GAAI,KAAK,MAAM,KAAG,MAAM,EAQ3D,CAAA"}
|
package/dist/utils/index.js
CHANGED
|
@@ -3,9 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.readJsonContent = exports.readFileContent = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
exports.recursivelyCollectFiles = exports.readJsonContent = exports.readFileContent = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const readFileContent = (filePath) => node_fs_1.default.readFileSync(filePath, 'utf-8');
|
|
9
10
|
exports.readFileContent = readFileContent;
|
|
10
11
|
const readJsonContent = (filePath) => JSON.parse((0, exports.readFileContent)(filePath));
|
|
11
12
|
exports.readJsonContent = readJsonContent;
|
|
13
|
+
const recursivelyCollectFiles = (dir) => {
|
|
14
|
+
return node_fs_1.default.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
15
|
+
const fullPath = node_path_1.default.join(dir, entry.name);
|
|
16
|
+
if (entry.isDirectory()) {
|
|
17
|
+
return (0, exports.recursivelyCollectFiles)(fullPath);
|
|
18
|
+
}
|
|
19
|
+
return entry.isFile() ? [fullPath] : [];
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
exports.recursivelyCollectFiles = recursivelyCollectFiles;
|
|
@@ -56,7 +56,7 @@ const exposeRoutes = (fastify) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
56
56
|
}, function (req, res) {
|
|
57
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
58
|
const { authCollection } = constants_1.AUTH_CONFIG;
|
|
59
|
-
const db = fastify.mongo.client.db(constants_1.
|
|
59
|
+
const db = fastify.mongo.client.db(constants_1.AUTH_DB_NAME);
|
|
60
60
|
const { email, password } = req.body;
|
|
61
61
|
const hashedPassword = yield (0, crypto_1.hashPassword)(password);
|
|
62
62
|
const now = new Date();
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { UUID, type Document, type AWSEncryptionKeyOptions, type AWSKMSProviderConfiguration, type AzureEncryptionKeyOptions, type AzureKMSProviderConfiguration, type GCPKMSProviderConfiguration, type GCPEncryptionKeyOptions, type KMIPKMSProviderConfiguration, type KMIPEncryptionKeyOptions, type LocalKMSProviderConfiguration, type AutoEncryptionExtraOptions, type AutoEncryptionOptions } from "mongodb";
|
|
2
|
+
import { type EncryptionSchemas } from "../../features/encryption/interface";
|
|
3
|
+
type KMSProviderConfig = {
|
|
4
|
+
/**
|
|
5
|
+
* The alias of the key. It must be referenced in the schema map
|
|
6
|
+
* to select which key to use for encryption.
|
|
7
|
+
*/
|
|
8
|
+
keyAlias: string;
|
|
9
|
+
/**
|
|
10
|
+
* KMS Provider name.
|
|
11
|
+
*/
|
|
12
|
+
provider: "aws";
|
|
13
|
+
/**
|
|
14
|
+
* KMS Provider specific authorization configuration.
|
|
15
|
+
*/
|
|
16
|
+
config: AWSKMSProviderConfiguration;
|
|
17
|
+
/**
|
|
18
|
+
* Configuration of the master key.
|
|
19
|
+
*/
|
|
20
|
+
masterKey: AWSEncryptionKeyOptions;
|
|
21
|
+
} | {
|
|
22
|
+
keyAlias: string;
|
|
23
|
+
provider: "azure";
|
|
24
|
+
config: AzureKMSProviderConfiguration;
|
|
25
|
+
masterKey: AzureEncryptionKeyOptions;
|
|
26
|
+
} | {
|
|
27
|
+
keyAlias: string;
|
|
28
|
+
provider: "gcp";
|
|
29
|
+
config: GCPKMSProviderConfiguration;
|
|
30
|
+
masterKey: GCPEncryptionKeyOptions;
|
|
31
|
+
} | {
|
|
32
|
+
keyAlias: string;
|
|
33
|
+
provider: "kmip";
|
|
34
|
+
config: KMIPKMSProviderConfiguration;
|
|
35
|
+
masterKey: KMIPEncryptionKeyOptions;
|
|
36
|
+
} | {
|
|
37
|
+
keyAlias: string;
|
|
38
|
+
provider: "local";
|
|
39
|
+
config: LocalKMSProviderConfiguration;
|
|
40
|
+
};
|
|
41
|
+
export type MongoDbEncryptionConfig = {
|
|
42
|
+
kmsProviders: KMSProviderConfig[];
|
|
43
|
+
/**
|
|
44
|
+
* The Key Vault database name
|
|
45
|
+
* @default encryption
|
|
46
|
+
*/
|
|
47
|
+
keyVaultDb?: string;
|
|
48
|
+
/**
|
|
49
|
+
* The Key Vault database collection
|
|
50
|
+
* @default __keyVault
|
|
51
|
+
*/
|
|
52
|
+
keyVaultCollection?: string;
|
|
53
|
+
extraOptions?: AutoEncryptionExtraOptions;
|
|
54
|
+
};
|
|
55
|
+
type DataKey = {
|
|
56
|
+
dataKeyId: UUID;
|
|
57
|
+
dataKeyAlias: string;
|
|
58
|
+
};
|
|
59
|
+
export declare const buildSchemaMap: (schemas: EncryptionSchemas, dataKeys: DataKey[]) => Record<string, Document>;
|
|
60
|
+
/**
|
|
61
|
+
* Setup MongoDB Client-Side Field Level Encryption (CSFLE).
|
|
62
|
+
* @see https://www.mongodb.com/docs/manual/core/csfle
|
|
63
|
+
*/
|
|
64
|
+
export declare const setupMongoDbCSFLE: (config: MongoDbEncryptionConfig & {
|
|
65
|
+
mongodbUrl: string;
|
|
66
|
+
schemas?: EncryptionSchemas;
|
|
67
|
+
}) => Promise<AutoEncryptionOptions>;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=mongodbCSFLE.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongodbCSFLE.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/mongodbCSFLE.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,IAAI,EAEJ,KAAK,QAAQ,EACb,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAE/B,KAAK,qBAAqB,EAC3B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAoF,KAAK,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAG/J,KAAK,iBAAiB,GAClB;IACA;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAA;IACf;;OAEG;IACH,MAAM,EAAE,2BAA2B,CAAA;IACnC;;OAEG;IACH,SAAS,EAAE,uBAAuB,CAAA;CACnC,GAAG;IACF,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,6BAA6B,CAAC;IACtC,SAAS,EAAE,yBAAyB,CAAA;CACrC,GAAG;IACF,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,KAAK,CAAA;IACf,MAAM,EAAE,2BAA2B,CAAC;IACpC,SAAS,EAAE,uBAAuB,CAAA;CACnC,GAAG;IACF,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,4BAA4B,CAAC;IACrC,SAAS,EAAE,wBAAwB,CAAA;CACpC,GAAG;IACF,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,6BAA6B,CAAC;CACvC,CAAA;AAEH,MAAM,MAAM,uBAAuB,GAAG;IACpC,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;KAGC;IACD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,YAAY,CAAC,EAAE,0BAA0B,CAAA;CAC1C,CAAA;AAOD,KAAK,OAAO,GAAG;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAA;AAkFxD,eAAO,MAAM,cAAc,GAAI,SAAS,iBAAiB,EAAE,UAAU,OAAO,EAAE,6BAK7E,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,uBAAuB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,iBAAiB,CAAA;CAAE,KACpF,OAAO,CAAC,qBAAqB,CA8C/B,CAAA"}
|
|
@@ -0,0 +1,131 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.setupMongoDbCSFLE = exports.buildSchemaMap = void 0;
|
|
13
|
+
const mongodb_1 = require("mongodb");
|
|
14
|
+
const constants_1 = require("../../constants");
|
|
15
|
+
function ensureUniqueKeyAltNameIndex(db, config) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
yield db.collection(config.keyVaultCollection).createIndex({ keyAltNames: 1 }, {
|
|
18
|
+
unique: true,
|
|
19
|
+
partialFilterExpression: { keyAltNames: { $exists: true } },
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Ensure provided KMS Providers DEK keys exist in the key vault. If not, they are created.
|
|
25
|
+
*/
|
|
26
|
+
function ensureDataEncryptionKeys(clientEncryption, keyVaultDb, config) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const keys = [];
|
|
29
|
+
for (const kmsProvider of config.kmsProviders) {
|
|
30
|
+
const existingKey = yield keyVaultDb.collection(config.keyVaultCollection).findOne({
|
|
31
|
+
keyAltNames: kmsProvider.keyAlias,
|
|
32
|
+
});
|
|
33
|
+
if ((existingKey === null || existingKey === void 0 ? void 0 : existingKey._id) instanceof mongodb_1.Binary) {
|
|
34
|
+
keys.push({ dataKeyId: existingKey._id, dataKeyAlias: kmsProvider.keyAlias });
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const dataKeyId = yield clientEncryption.createDataKey(kmsProvider.provider, {
|
|
38
|
+
masterKey: "masterKey" in kmsProvider ? kmsProvider.masterKey : undefined,
|
|
39
|
+
keyAltNames: [kmsProvider.keyAlias],
|
|
40
|
+
});
|
|
41
|
+
console.log(`[MongoDB Encryption] Created new key with alias ${kmsProvider.keyAlias}`);
|
|
42
|
+
keys.push({ dataKeyId, dataKeyAlias: kmsProvider.keyAlias });
|
|
43
|
+
}
|
|
44
|
+
return keys;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Recursively resolve key aliases in an encryption schema to their corresponding key IDs.
|
|
49
|
+
*/
|
|
50
|
+
const resolveKeyAliases = (schema, dataKeys) => {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
if ("encrypt" in schema) {
|
|
53
|
+
if (!schema.encrypt.keyAlias) {
|
|
54
|
+
return schema;
|
|
55
|
+
}
|
|
56
|
+
const keyId = (_a = dataKeys.find(k => k.dataKeyAlias === schema.encrypt.keyAlias)) === null || _a === void 0 ? void 0 : _a.dataKeyId;
|
|
57
|
+
if (!keyId) {
|
|
58
|
+
throw new Error(`Key with alias ${schema.encrypt.keyAlias} could not be found in the Key Vault.`);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
encrypt: {
|
|
62
|
+
bsonType: schema.encrypt.bsonType,
|
|
63
|
+
algorithm: schema.encrypt.algorithm,
|
|
64
|
+
keyId: [keyId]
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const mappedSchema = {
|
|
69
|
+
bsonType: "object",
|
|
70
|
+
properties: Object.entries(schema.properties).reduce((acc, [property, config]) => {
|
|
71
|
+
acc[property] = resolveKeyAliases(config, dataKeys);
|
|
72
|
+
return acc;
|
|
73
|
+
}, {})
|
|
74
|
+
};
|
|
75
|
+
if (schema.encryptMetadata) {
|
|
76
|
+
const keyId = (_b = dataKeys.find(k => k.dataKeyAlias === schema.encryptMetadata.keyAlias)) === null || _b === void 0 ? void 0 : _b.dataKeyId;
|
|
77
|
+
if (!keyId) {
|
|
78
|
+
throw new Error(`Key with alias ${schema.encryptMetadata.keyAlias} could not be found in the Key Vault.`);
|
|
79
|
+
}
|
|
80
|
+
mappedSchema.encryptMetadata = { keyId: [keyId] };
|
|
81
|
+
}
|
|
82
|
+
return mappedSchema;
|
|
83
|
+
};
|
|
84
|
+
const buildSchemaMap = (schemas, dataKeys) => {
|
|
85
|
+
return Object.entries(schemas).reduce((acc, [key, schema]) => {
|
|
86
|
+
acc[key] = resolveKeyAliases(schema, dataKeys);
|
|
87
|
+
return acc;
|
|
88
|
+
}, {});
|
|
89
|
+
};
|
|
90
|
+
exports.buildSchemaMap = buildSchemaMap;
|
|
91
|
+
/**
|
|
92
|
+
* Setup MongoDB Client-Side Field Level Encryption (CSFLE).
|
|
93
|
+
* @see https://www.mongodb.com/docs/manual/core/csfle
|
|
94
|
+
*/
|
|
95
|
+
const setupMongoDbCSFLE = (config) => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
|
+
var _a, _b;
|
|
97
|
+
if (config.kmsProviders.length === 0) {
|
|
98
|
+
throw new Error('At least one KMS Provider is required when using MongoDB encryption');
|
|
99
|
+
}
|
|
100
|
+
const requiredConfig = {
|
|
101
|
+
kmsProviders: config.kmsProviders,
|
|
102
|
+
keyVaultDb: (_a = config.keyVaultDb) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_CONFIG.MONGODB_ENCRYPTION_CONFIG.keyVaultDb,
|
|
103
|
+
keyVaultCollection: (_b = config.keyVaultDb) !== null && _b !== void 0 ? _b : constants_1.DEFAULT_CONFIG.MONGODB_ENCRYPTION_CONFIG.keyVaultCollection,
|
|
104
|
+
};
|
|
105
|
+
const kmsProviders = requiredConfig.kmsProviders.reduce((acc, { provider, config }) => (Object.assign(Object.assign({}, acc), { [provider]: config })), {});
|
|
106
|
+
const keyVaultNamespace = `${requiredConfig.keyVaultDb}.${requiredConfig.keyVaultCollection}`;
|
|
107
|
+
const keyVaultClient = new mongodb_1.MongoClient(config.mongodbUrl, {
|
|
108
|
+
maxPoolSize: 1,
|
|
109
|
+
autoEncryption: {
|
|
110
|
+
keyVaultNamespace,
|
|
111
|
+
kmsProviders,
|
|
112
|
+
extraOptions: config.extraOptions
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
yield keyVaultClient.connect();
|
|
116
|
+
const keyVaultDb = keyVaultClient.db(requiredConfig.keyVaultDb);
|
|
117
|
+
yield ensureUniqueKeyAltNameIndex(keyVaultDb, requiredConfig);
|
|
118
|
+
const clientEncryption = new mongodb_1.ClientEncryption(keyVaultClient, {
|
|
119
|
+
keyVaultNamespace,
|
|
120
|
+
kmsProviders,
|
|
121
|
+
});
|
|
122
|
+
const dataKeys = yield ensureDataEncryptionKeys(clientEncryption, keyVaultDb, requiredConfig);
|
|
123
|
+
yield keyVaultClient.close();
|
|
124
|
+
return {
|
|
125
|
+
keyVaultNamespace,
|
|
126
|
+
kmsProviders,
|
|
127
|
+
schemaMap: config.schemas ? (0, exports.buildSchemaMap)(config.schemas, dataKeys) : undefined,
|
|
128
|
+
extraOptions: config.extraOptions
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
exports.setupMongoDbCSFLE = setupMongoDbCSFLE;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FastifyInstance } from 'fastify';
|
|
2
2
|
import { CorsConfig } from '../../';
|
|
3
3
|
import { Functions } from '../../features/functions/interface';
|
|
4
|
+
import { EncryptionSchemas } from '../../features/encryption/interface';
|
|
5
|
+
import { MongoDbEncryptionConfig } from './mongodbCSFLE';
|
|
4
6
|
type RegisterFunction = FastifyInstance['register'];
|
|
5
7
|
type RegisterPluginsParams = {
|
|
6
8
|
register: RegisterFunction;
|
|
@@ -8,6 +10,8 @@ type RegisterPluginsParams = {
|
|
|
8
10
|
jwtSecret: string;
|
|
9
11
|
functionsList: Functions;
|
|
10
12
|
corsConfig?: CorsConfig;
|
|
13
|
+
encryptionSchemas?: EncryptionSchemas;
|
|
14
|
+
mongodbEncryptionConfig?: MongoDbEncryptionConfig;
|
|
11
15
|
};
|
|
12
16
|
/**
|
|
13
17
|
* > Used to register all plugins
|
|
@@ -16,6 +20,6 @@ type RegisterPluginsParams = {
|
|
|
16
20
|
* @param jwtSecret -> connection jwt
|
|
17
21
|
* @tested
|
|
18
22
|
*/
|
|
19
|
-
export declare const registerPlugins: ({ register, mongodbUrl, jwtSecret, functionsList, corsConfig }: RegisterPluginsParams) => Promise<void>;
|
|
23
|
+
export declare const registerPlugins: ({ register, mongodbUrl, jwtSecret, functionsList, corsConfig, mongodbEncryptionConfig, encryptionSchemas }: RegisterPluginsParams) => Promise<void>;
|
|
20
24
|
export {};
|
|
21
25
|
//# sourceMappingURL=registerPlugins.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerPlugins.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/registerPlugins.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAOnC,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;
|
|
1
|
+
{"version":3,"file":"registerPlugins.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/registerPlugins.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAOnC,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AAEvE,OAAO,EAAqB,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAE3E,KAAK,gBAAgB,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;AAGnD,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,SAAS,CAAA;IACxB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,uBAAuB,CAAC,EAAE,uBAAuB,CAAA;CAClD,CAAA;AAQD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAU,4GAQnC,qBAAqB,kBAwBvB,CAAA"}
|
|
@@ -23,6 +23,7 @@ const controller_3 = require("../../auth/providers/custom-function/controller");
|
|
|
23
23
|
const controller_4 = require("../../auth/providers/local-userpass/controller");
|
|
24
24
|
const constants_1 = require("../../constants");
|
|
25
25
|
const plugin_1 = __importDefault(require("../../monitoring/plugin"));
|
|
26
|
+
const mongodbCSFLE_1 = require("./mongodbCSFLE");
|
|
26
27
|
/**
|
|
27
28
|
* > Used to register all plugins
|
|
28
29
|
* @param register -> the fastify register method
|
|
@@ -30,13 +31,15 @@ const plugin_1 = __importDefault(require("../../monitoring/plugin"));
|
|
|
30
31
|
* @param jwtSecret -> connection jwt
|
|
31
32
|
* @tested
|
|
32
33
|
*/
|
|
33
|
-
const registerPlugins = (_a) => __awaiter(void 0, [_a], void 0, function* ({ register, mongodbUrl, jwtSecret, functionsList, corsConfig }) {
|
|
34
|
+
const registerPlugins = (_a) => __awaiter(void 0, [_a], void 0, function* ({ register, mongodbUrl, jwtSecret, functionsList, corsConfig, mongodbEncryptionConfig, encryptionSchemas }) {
|
|
34
35
|
try {
|
|
35
36
|
const registersConfig = yield getRegisterConfig({
|
|
36
37
|
mongodbUrl,
|
|
37
38
|
jwtSecret,
|
|
38
39
|
corsConfig,
|
|
39
|
-
functionsList
|
|
40
|
+
functionsList,
|
|
41
|
+
mongodbEncryptionConfig,
|
|
42
|
+
encryptionSchemas
|
|
40
43
|
});
|
|
41
44
|
registersConfig.forEach(({ plugin, options, pluginName }) => {
|
|
42
45
|
try {
|
|
@@ -61,11 +64,14 @@ exports.registerPlugins = registerPlugins;
|
|
|
61
64
|
* @param jwtSecret -> connection jwt
|
|
62
65
|
* @testable
|
|
63
66
|
*/
|
|
64
|
-
const getRegisterConfig = (_a) => __awaiter(void 0, [_a], void 0, function* ({ mongodbUrl, jwtSecret, corsConfig }) {
|
|
67
|
+
const getRegisterConfig = (_a) => __awaiter(void 0, [_a], void 0, function* ({ mongodbUrl, jwtSecret, corsConfig, encryptionSchemas, mongodbEncryptionConfig, }) {
|
|
65
68
|
const corsOptions = corsConfig !== null && corsConfig !== void 0 ? corsConfig : {
|
|
66
69
|
origin: '*',
|
|
67
70
|
methods: ['POST', 'GET']
|
|
68
71
|
};
|
|
72
|
+
const autoEncryption = mongodbEncryptionConfig
|
|
73
|
+
? yield (0, mongodbCSFLE_1.setupMongoDbCSFLE)(Object.assign({ mongodbUrl, schemas: encryptionSchemas }, mongodbEncryptionConfig))
|
|
74
|
+
: undefined;
|
|
69
75
|
const baseConfig = [
|
|
70
76
|
{
|
|
71
77
|
pluginName: 'cors',
|
|
@@ -76,8 +82,24 @@ const getRegisterConfig = (_a) => __awaiter(void 0, [_a], void 0, function* ({ m
|
|
|
76
82
|
pluginName: 'fastifyMongodb',
|
|
77
83
|
plugin: mongodb_1.default,
|
|
78
84
|
options: {
|
|
85
|
+
url: mongodbUrl,
|
|
79
86
|
forceClose: true,
|
|
80
|
-
|
|
87
|
+
autoEncryption
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* When auto-encryption is active, add another MongoDB client with bypass for change streams.
|
|
92
|
+
* The $changeStream operator does not support automatic encryption, only decryption.
|
|
93
|
+
* @see https://www.mongodb.com/docs/manual/core/csfle/reference/supported-operations
|
|
94
|
+
*/
|
|
95
|
+
autoEncryption && {
|
|
96
|
+
pluginName: 'fastifyMongodb',
|
|
97
|
+
plugin: mongodb_1.default,
|
|
98
|
+
options: {
|
|
99
|
+
name: "changestream",
|
|
100
|
+
url: mongodbUrl,
|
|
101
|
+
forceClose: true,
|
|
102
|
+
autoEncryption: Object.assign(Object.assign({}, autoEncryption), { bypassAutoEncryption: true })
|
|
81
103
|
}
|
|
82
104
|
},
|
|
83
105
|
{
|
|
@@ -133,5 +155,5 @@ const getRegisterConfig = (_a) => __awaiter(void 0, [_a], void 0, function* ({ m
|
|
|
133
155
|
options: { basePath: '/monit' }
|
|
134
156
|
});
|
|
135
157
|
}
|
|
136
|
-
return baseConfig;
|
|
158
|
+
return baseConfig.filter(Boolean);
|
|
137
159
|
});
|
|
@@ -311,6 +311,8 @@ export type Operators = {
|
|
|
311
311
|
* @returns
|
|
312
312
|
*/
|
|
313
313
|
$regex: OperatorsFunction;
|
|
314
|
+
'%stringToOid': OperatorsFunction;
|
|
315
|
+
'%oidToString': OperatorsFunction;
|
|
314
316
|
};
|
|
315
317
|
export declare enum RulesOperators {
|
|
316
318
|
$exists = "$exists",
|
|
@@ -328,7 +330,9 @@ export declare enum RulesOperators {
|
|
|
328
330
|
$nin = "$nin",
|
|
329
331
|
$all = "$all",
|
|
330
332
|
$size = "$size",
|
|
331
|
-
$regex = "$regex"
|
|
333
|
+
$regex = "$regex",
|
|
334
|
+
'%stringToOid' = "%stringToOid",
|
|
335
|
+
'%oidToString' = "%oidToString"
|
|
332
336
|
}
|
|
333
337
|
export type RulesOperatorsInArray<T> = Partial<{
|
|
334
338
|
[KEY in keyof T]: Partial<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/interface.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,8 @@ var RulesOperators;
|
|
|
19
19
|
RulesOperators["$all"] = "$all";
|
|
20
20
|
RulesOperators["$size"] = "$size";
|
|
21
21
|
RulesOperators["$regex"] = "$regex";
|
|
22
|
+
RulesOperators["%stringToOid"] = "%stringToOid";
|
|
23
|
+
RulesOperators["%oidToString"] = "%oidToString";
|
|
22
24
|
})(RulesOperators || (exports.RulesOperators = RulesOperators = {}));
|
|
23
25
|
var RulesModes;
|
|
24
26
|
(function (RulesModes) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils/rules-matcher/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAe,MAAM,aAAa,CAAA;AAsDvE;;GAEG;AACH,QAAA,MAAM,iBAAiB,EAAE,iBAsNxB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,SAoDvB,CAAA;AAID,eAAe,iBAAiB,CAAA"}
|
|
@@ -4,10 +4,44 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.operators = void 0;
|
|
7
|
+
const bson_1 = require("bson");
|
|
7
8
|
const get_1 = __importDefault(require("lodash/get"));
|
|
8
|
-
const intersection_1 = __importDefault(require("lodash/intersection"));
|
|
9
9
|
const trimStart_1 = __importDefault(require("lodash/trimStart"));
|
|
10
10
|
const EMPTY_STRING_REGEXP = /^\s*$/;
|
|
11
|
+
const HEX_24_REGEXP = /^[a-fA-F0-9]{24}$/;
|
|
12
|
+
const toObjectIdHex = (value) => {
|
|
13
|
+
if (value instanceof bson_1.ObjectId) {
|
|
14
|
+
return value.toHexString();
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === 'string') {
|
|
17
|
+
if (!HEX_24_REGEXP.test(value) || !bson_1.ObjectId.isValid(value)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return new bson_1.ObjectId(value).toHexString();
|
|
21
|
+
}
|
|
22
|
+
if (!value || typeof value !== 'object') {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const maybeObjectId = value;
|
|
26
|
+
if (maybeObjectId._bsontype === 'ObjectId' && typeof maybeObjectId.toHexString === 'function') {
|
|
27
|
+
const hex = maybeObjectId.toHexString();
|
|
28
|
+
return HEX_24_REGEXP.test(hex) ? hex.toLowerCase() : null;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
const areSemanticallyEqual = (left, right) => {
|
|
33
|
+
const leftOid = toObjectIdHex(left);
|
|
34
|
+
const rightOid = toObjectIdHex(right);
|
|
35
|
+
if (leftOid || rightOid) {
|
|
36
|
+
return leftOid !== null && rightOid !== null && leftOid === rightOid;
|
|
37
|
+
}
|
|
38
|
+
return left === right;
|
|
39
|
+
};
|
|
40
|
+
const includesWithSemanticEquality = (value, candidate) => rulesMatcherUtils
|
|
41
|
+
.forceArray(candidate)
|
|
42
|
+
.some((item) => rulesMatcherUtils
|
|
43
|
+
.forceArray(value)
|
|
44
|
+
.some((sourceItem) => rulesMatcherUtils.forceArray(item).some((candidateItem) => areSemanticallyEqual(sourceItem, candidateItem))));
|
|
11
45
|
/**
|
|
12
46
|
* Defines a utility object named rulesMatcherUtils, which contains various helper functions used for processing rules and data in a rule-matching context.
|
|
13
47
|
*/
|
|
@@ -187,8 +221,8 @@ const rulesMatcherUtils = {
|
|
|
187
221
|
*/
|
|
188
222
|
exports.operators = {
|
|
189
223
|
$exists: (a, b) => !rulesMatcherUtils.isEmpty(a) === b,
|
|
190
|
-
$eq: (a, b) => a
|
|
191
|
-
$ne: (a, b) => a
|
|
224
|
+
$eq: (a, b) => areSemanticallyEqual(a, b),
|
|
225
|
+
$ne: (a, b) => !areSemanticallyEqual(a, b),
|
|
192
226
|
$gt: (a, b) => rulesMatcherUtils.forceNumber(a) > parseFloat(b),
|
|
193
227
|
$gte: (a, b) => rulesMatcherUtils.forceNumber(a) >= parseFloat(b),
|
|
194
228
|
$lt: (a, b) => rulesMatcherUtils.forceNumber(a) < parseFloat(b),
|
|
@@ -197,22 +231,23 @@ exports.operators = {
|
|
|
197
231
|
$strGte: (a, b) => String(a || '').length >= parseFloat(b),
|
|
198
232
|
$strLt: (a, b) => String(a || '').length < parseFloat(b),
|
|
199
233
|
$strLte: (a, b) => String(a || '').length <= parseFloat(b),
|
|
200
|
-
$in: (a, b) =>
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
.
|
|
204
|
-
|
|
205
|
-
.forceArray(b)
|
|
206
|
-
.some((c) => (0, intersection_1.default)(rulesMatcherUtils.forceArray(a), rulesMatcherUtils.forceArray(c))
|
|
207
|
-
.length),
|
|
208
|
-
$all: (a, b) => rulesMatcherUtils
|
|
209
|
-
.forceArray(b)
|
|
210
|
-
.every((c) => (0, intersection_1.default)(rulesMatcherUtils.forceArray(a), rulesMatcherUtils.forceArray(c))
|
|
211
|
-
.length),
|
|
234
|
+
$in: (a, b) => includesWithSemanticEquality(a, b),
|
|
235
|
+
$nin: (a, b) => !includesWithSemanticEquality(a, b),
|
|
236
|
+
$all: (a, b) => rulesMatcherUtils.forceArray(b).every((candidate) => rulesMatcherUtils
|
|
237
|
+
.forceArray(a)
|
|
238
|
+
.some((value) => rulesMatcherUtils.forceArray(candidate).some((item) => areSemanticallyEqual(value, item)))),
|
|
212
239
|
$size: (a, b) => Array.isArray(a) && a.length === parseFloat(b),
|
|
213
240
|
$regex: (a, b, opt) => rulesMatcherUtils
|
|
214
241
|
.forceArray(b)
|
|
215
|
-
.some((c) => (c instanceof RegExp ? c.test(a) : new RegExp(c, opt).test(a)))
|
|
242
|
+
.some((c) => (c instanceof RegExp ? c.test(a) : new RegExp(c, opt).test(a))),
|
|
243
|
+
'%stringToOid': (a, b) => {
|
|
244
|
+
const converted = toObjectIdHex(b);
|
|
245
|
+
return converted !== null && areSemanticallyEqual(a, converted);
|
|
246
|
+
},
|
|
247
|
+
'%oidToString': (a, b) => {
|
|
248
|
+
const converted = toObjectIdHex(b);
|
|
249
|
+
return converted !== null && areSemanticallyEqual(a, converted);
|
|
250
|
+
}
|
|
216
251
|
};
|
|
217
252
|
// export default operators
|
|
218
253
|
exports.default = rulesMatcherUtils;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowerforce/flowerbase",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.6-beta.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"scripts": {
|
|
15
15
|
"test": "npx jest",
|
|
16
16
|
"build": "rm -rf dist/ && tsc",
|
|
17
|
-
"start": "node dist/src/index.ts"
|
|
17
|
+
"start": "node dist/src/index.ts",
|
|
18
|
+
"tsc:noemit": "tsc --noEmit"
|
|
18
19
|
},
|
|
19
20
|
"keywords": [],
|
|
20
21
|
"author": "",
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"@fastify/swagger-ui": "^5.2.3",
|
|
31
32
|
"@fastify/websocket": "^11.2.0",
|
|
32
33
|
"bson": "^6.8.0",
|
|
34
|
+
"codemirror": "^5.65.16",
|
|
33
35
|
"dotenv": "^16.4.7",
|
|
34
36
|
"fastify": "^5.0.0",
|
|
35
37
|
"fastify-plugin": "^5.0.1",
|
package/src/auth/controller.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ObjectId } from 'bson'
|
|
2
2
|
import { FastifyInstance } from 'fastify'
|
|
3
|
-
import { AUTH_CONFIG, DB_NAME, DEFAULT_CONFIG } from '../constants'
|
|
3
|
+
import { AUTH_CONFIG, AUTH_DB_NAME, DB_NAME, DEFAULT_CONFIG } from '../constants'
|
|
4
4
|
import { StateManager } from '../state'
|
|
5
5
|
import { hashToken } from '../utils/crypto'
|
|
6
6
|
import { SessionCreatedDto } from './dtos'
|
|
@@ -23,11 +23,12 @@ type UnauthorizedSessionReply = typeof unauthorizedSessionError
|
|
|
23
23
|
export async function authController(app: FastifyInstance) {
|
|
24
24
|
const { authCollection, userCollection, refreshTokensCollection } = AUTH_CONFIG
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const authDb = app.mongo.client.db(AUTH_DB_NAME)
|
|
27
|
+
const customUserDb = app.mongo.client.db(DB_NAME)
|
|
27
28
|
const refreshTokenTtlMs = DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000
|
|
28
29
|
|
|
29
30
|
try {
|
|
30
|
-
await
|
|
31
|
+
await authDb.collection(refreshTokensCollection).createIndex(
|
|
31
32
|
{ expiresAt: 1 },
|
|
32
33
|
{ expireAfterSeconds: 0 }
|
|
33
34
|
)
|
|
@@ -36,7 +37,7 @@ export async function authController(app: FastifyInstance) {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
try {
|
|
39
|
-
await
|
|
40
|
+
await authDb.collection(authCollection).createIndex(
|
|
40
41
|
{ email: 1 },
|
|
41
42
|
{
|
|
42
43
|
unique: true
|
|
@@ -63,12 +64,12 @@ export async function authController(app: FastifyInstance) {
|
|
|
63
64
|
if (req.user.typ !== 'access') {
|
|
64
65
|
throw new Error('Access token required')
|
|
65
66
|
}
|
|
66
|
-
const authUser = await
|
|
67
|
+
const authUser = await authDb
|
|
67
68
|
.collection<Record<string, unknown>>(authCollection)
|
|
68
69
|
.findOne({ _id: ObjectId.createFromHexString(req.user.id) })
|
|
69
70
|
|
|
70
71
|
const customData = userCollection && AUTH_CONFIG.user_id_field
|
|
71
|
-
? await
|
|
72
|
+
? await customUserDb
|
|
72
73
|
.collection<Record<string, unknown>>(userCollection)
|
|
73
74
|
.findOne({ [AUTH_CONFIG.user_id_field]: req.user.id })
|
|
74
75
|
: null
|
|
@@ -117,7 +118,7 @@ export async function authController(app: FastifyInstance) {
|
|
|
117
118
|
}
|
|
118
119
|
const refreshToken = authHeader.slice('Bearer '.length).trim()
|
|
119
120
|
const refreshTokenHash = hashToken(refreshToken)
|
|
120
|
-
const storedToken = await
|
|
121
|
+
const storedToken = await authDb.collection(refreshTokensCollection).findOne({
|
|
121
122
|
tokenHash: refreshTokenHash,
|
|
122
123
|
revokedAt: null,
|
|
123
124
|
expiresAt: { $gt: new Date() }
|
|
@@ -127,7 +128,7 @@ export async function authController(app: FastifyInstance) {
|
|
|
127
128
|
return
|
|
128
129
|
}
|
|
129
130
|
|
|
130
|
-
const auth_user = await
|
|
131
|
+
const auth_user = await authDb
|
|
131
132
|
?.collection(authCollection)
|
|
132
133
|
.findOne({ _id: new this.mongo.ObjectId(req.user.sub) })
|
|
133
134
|
|
|
@@ -137,7 +138,7 @@ export async function authController(app: FastifyInstance) {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
const user = userCollection && AUTH_CONFIG.user_id_field
|
|
140
|
-
? (await
|
|
141
|
+
? (await customUserDb.collection(userCollection).findOne({ [AUTH_CONFIG.user_id_field]: req.user.sub }))
|
|
141
142
|
: {}
|
|
142
143
|
|
|
143
144
|
res.status(201)
|
|
@@ -175,7 +176,7 @@ export async function authController(app: FastifyInstance) {
|
|
|
175
176
|
const refreshTokenHash = hashToken(refreshToken)
|
|
176
177
|
const now = new Date()
|
|
177
178
|
const expiresAt = new Date(Date.now() + refreshTokenTtlMs)
|
|
178
|
-
const updateResult = await
|
|
179
|
+
const updateResult = await authDb.collection(refreshTokensCollection).findOneAndUpdate(
|
|
179
180
|
{ tokenHash: refreshTokenHash },
|
|
180
181
|
{
|
|
181
182
|
$set: {
|
|
@@ -197,7 +198,7 @@ export async function authController(app: FastifyInstance) {
|
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
if (userId && authCollection) {
|
|
200
|
-
await
|
|
201
|
+
await authDb.collection(authCollection).updateOne(
|
|
201
202
|
{ _id: userId },
|
|
202
203
|
{ $set: { lastLogoutAt: now } }
|
|
203
204
|
)
|
package/src/auth/plugins/jwt.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fastifyJwt from '@fastify/jwt'
|
|
2
2
|
import fp from 'fastify-plugin'
|
|
3
3
|
import { Document, ObjectId, WithId } from 'mongodb'
|
|
4
|
-
import { AUTH_CONFIG,
|
|
4
|
+
import { AUTH_CONFIG, AUTH_DB_NAME, DEFAULT_CONFIG } from '../../constants'
|
|
5
5
|
|
|
6
6
|
type Options = {
|
|
7
7
|
secret: string
|
|
@@ -51,7 +51,7 @@ export default fp(async function (fastify, opts: Options) {
|
|
|
51
51
|
return
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const db = fastify.mongo?.client?.db(
|
|
54
|
+
const db = fastify.mongo?.client?.db(AUTH_DB_NAME)
|
|
55
55
|
if (!db) {
|
|
56
56
|
fastify.log.warn('Mongo client unavailable while checking logout state')
|
|
57
57
|
return
|