Skip to content

Commit 095c6c2

Browse files
Add a property to .
1 parent 59af7cf commit 095c6c2

File tree

2 files changed

+137
-1
lines changed

2 files changed

+137
-1
lines changed

lib/model.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ const minimize = require('./helpers/minimize');
6969
const MongooseBulkSaveIncompleteError = require('./error/bulkSaveIncompleteError');
7070
const ObjectExpectedError = require('./error/objectExpected');
7171
const decorateBulkWriteResult = require('./helpers/model/decorateBulkWriteResult');
72+
const { ClientEncryption } = require('mongodb');
7273

7374
const modelCollectionSymbol = Symbol('mongoose#Model#collection');
7475
const modelDbSymbol = Symbol('mongoose#Model#db');
@@ -4880,6 +4881,29 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
48804881
return model;
48814882
};
48824883

4884+
Model.clientEncryption = function clientEncryption() {
4885+
/** @type(import('mongodb').MongoClient) */
4886+
const client = this.collection?.conn?.client;
4887+
4888+
if (!client) return null;
4889+
4890+
const autoEncryptionOptions = client.options.autoEncryption;
4891+
4892+
if (!autoEncryptionOptions) return null;
4893+
4894+
const {
4895+
keyVaultNamespace,
4896+
keyVaultClient,
4897+
kmsProviders,
4898+
credentialProviders,
4899+
proxyOptions,
4900+
tlsOptions
4901+
} = autoEncryptionOptions;
4902+
return new ClientEncryption(keyVaultClient ?? client,
4903+
{ keyVaultNamespace, kmsProviders, credentialProviders, proxyOptions, tlsOptions }
4904+
);
4905+
};
4906+
48834907
/**
48844908
* Update this model to use the new connection, including updating all internal
48854909
* references and creating a new `Collection` instance using the new connection.

test/encryption/encryption.test.js

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ describe('encryption integration tests', () => {
12681268
});
12691269
});
12701270

1271-
describe('Encryption can be configured on the default mongoose connection', function() {
1271+
describe.only('Encryption can be configured on the default mongoose connection', function() {
12721272
afterEach(async function() {
12731273
mongoose.deleteModel('Schema');
12741274
await mongoose.disconnect();
@@ -1307,4 +1307,116 @@ describe('encryption integration tests', () => {
13071307
assert.deepEqual(doc.a, 2);
13081308
});
13091309
});
1310+
1311+
describe('Key Vault API', function() {
1312+
describe('No FLE configured', function() {
1313+
it('returns `null`', async function() {
1314+
const connection = mongoose.createConnection();
1315+
const model = connection.model('Name', { age: String });
1316+
1317+
await connection.openUri(process.env.MONGOOSE_TEST_URI);
1318+
1319+
assert.equal(model.clientEncryption(), null);
1320+
});
1321+
});
1322+
1323+
describe('Client not connected', function() {
1324+
it('returns `null`', async function() {
1325+
const connection = mongoose.createConnection();
1326+
const model = connection.model('Name', { age: String });
1327+
1328+
assert.equal(model.clientEncryption(), null);
1329+
});
1330+
});
1331+
1332+
describe('auto encryption enabled for a collection', function() {
1333+
let connection;
1334+
let model;
1335+
beforeEach(async function() {
1336+
connection = createConnection();
1337+
model = connection.model('Model1', new Schema({
1338+
a: {
1339+
type: String,
1340+
encrypt: {
1341+
keyId
1342+
}
1343+
}
1344+
}, {
1345+
encryptionType: 'queryableEncryption'
1346+
}));
1347+
1348+
await connection.openUri(process.env.MONGOOSE_TEST_URI, {
1349+
dbName: 'db', autoEncryption: {
1350+
keyVaultNamespace: 'keyvault.datakeys',
1351+
kmsProviders: { local: { key: LOCAL_KEY } },
1352+
extraOptions: {
1353+
cryptdSharedLibRequired: true,
1354+
cryptSharedLibPath: process.env.CRYPT_SHARED_LIB_PATH
1355+
}
1356+
}
1357+
});
1358+
});
1359+
1360+
afterEach(async function() {
1361+
await connection.close();
1362+
});
1363+
1364+
it('returns a client encryption object', async function() {
1365+
assert.ok(model.clientEncryption() instanceof mdb.ClientEncryption);
1366+
});
1367+
1368+
it('the client encryption is usable as a key vault', async function() {
1369+
const clientEncryption = model.clientEncryption();
1370+
const dataKey = await clientEncryption.createDataKey('local');
1371+
const keys = await clientEncryption.getKeys().toArray();
1372+
1373+
assert.ok(keys.length > 0);
1374+
1375+
const key = keys.find(
1376+
({ _id }) => _id.toString() === dataKey.toString()
1377+
);
1378+
1379+
assert.ok(key);
1380+
});
1381+
1382+
it('uses the same keyvaultNamespace', async function() {
1383+
assert.equal(model.clientEncryption()._keyVaultNamespace, 'keyvault.datakeys');
1384+
});
1385+
1386+
it('uses the same kms providers', async function() {
1387+
assert.deepEqual(model.clientEncryption()._kmsProviders, { local: { key: LOCAL_KEY } });
1388+
});
1389+
1390+
it('uses the same proxy options', async function() {
1391+
const options = model.collection.conn.client.options.autoEncryption;
1392+
options.proxyOptions = { name: 'bailey' };
1393+
assert.deepEqual(model.clientEncryption()._proxyOptions, { name: 'bailey' });
1394+
});
1395+
1396+
it('uses the same TLS options', async function() {
1397+
const options = model.collection.conn.client.options.autoEncryption;
1398+
options.tlsOptions = {
1399+
tlsCAFile: 'some file'
1400+
};
1401+
assert.deepEqual(model.clientEncryption()._tlsOptions, {
1402+
tlsCAFile: 'some file'
1403+
});
1404+
});
1405+
1406+
it.skip('uses the same credentialProviders', async function() {
1407+
const options = model.collection.conn.client.options.autoEncryption;
1408+
const credentialProviders = {
1409+
aws: async() => {}
1410+
};
1411+
options.credentialProviders = credentialProviders;
1412+
assert.equal(model.clientEncryption()._credentialProviders, credentialProviders);
1413+
});
1414+
1415+
it('uses the underlying MongoClient as the keyvault client', async function() {
1416+
const options = model.collection.conn.client.options.autoEncryption;
1417+
assert.ok(model.clientEncryption()._client === options.keyVaultClient, 'client not the same');
1418+
assert.equal(model.clientEncryption()._keyVaultClient, options.keyVaultClient, 'keyvault client not the same');
1419+
});
1420+
});
1421+
});
13101422
});

0 commit comments

Comments
 (0)