11import type { CSFLECollectionTracker } from './csfle-collection-tracker' ;
2- import { CSFLECollectionTrackerImpl } from './csfle-collection-tracker' ;
32import { expect } from 'chai' ;
4- import type { DataService } from './data-service' ;
3+ import type { DataService , DataServiceImpl } from './data-service' ;
54import type { AutoEncryptionOptions , MongoClient } from 'mongodb' ;
6- import { UUID } from 'bson' ;
5+ import type { Binary } from 'bson' ;
76import connect from './connect' ;
87
98describe ( 'CSFLECollectionTracker' , function ( ) {
109 const DECRYPTED_KEYS = Symbol . for ( '@@mdb.decryptedKeys' ) ;
11- const SOME_UUID1 = new UUID (
12- '00000000-0000-4000-8000-000000000001'
13- ) . toBinary ( ) ;
14- const SOME_UUID2 = new UUID (
15- '00000000-0000-4000-8000-000000000002'
16- ) . toBinary ( ) ;
1710 const ALGO_DET = 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' ;
1811
1912 let dataService : DataService ;
@@ -33,8 +26,22 @@ describe('CSFLECollectionTracker', function () {
3326 } ) ;
3427
3528 async function createTracker (
36- autoEncryption : AutoEncryptionOptions = { }
37- ) : Promise < [ CSFLECollectionTracker , DataService ] > {
29+ autoEncryption :
30+ | AutoEncryptionOptions
31+ | ( ( keys : [ Binary , Binary ] ) => AutoEncryptionOptions ) = { }
32+ ) : Promise < [ CSFLECollectionTracker , DataService , Binary , Binary ] > {
33+ if ( typeof autoEncryption === 'function' ) {
34+ // This autoEncryption config depends on the keys, so we first need
35+ // to set up the keys with one DataService instance,
36+ // then create the 'real' DataService instance.
37+ const [ , tempDataService , someKey1 , someKey2 ] = await createTracker ( { } ) ;
38+ await tempDataService . disconnect ( ) ;
39+ const [ tracker , dataService ] = await createTracker (
40+ autoEncryption ( [ someKey1 , someKey2 ] )
41+ ) ;
42+ return [ tracker , dataService , someKey1 , someKey2 ] ;
43+ }
44+
3845 const dataService = await connect ( {
3946 connectionString : 'mongodb://localhost:27018' ,
4047 fleOptions : {
@@ -43,16 +50,21 @@ describe('CSFLECollectionTracker', function () {
4350 kmsProviders : { local : { key : 'A' . repeat ( 128 ) } } ,
4451 keyVaultNamespace : `${ dbName } .kv` ,
4552 extraOptions : {
46- csflePath : process . env . COMPASS_CRYPT_LIBRARY_PATH ,
53+ // @ts -expect-error next driver release has types
54+ cryptSharedLibPath : process . env . COMPASS_CRYPT_LIBRARY_PATH ,
4755 } ,
4856 ...autoEncryption ,
4957 } ,
5058 } ,
5159 } ) ;
52- const crudClient = ( dataService as any ) . _initializedClient ( 'CRUD' ) ;
60+ // It can be useful to have one or two pre-defined keys in the key vault.
61+ const someKey1 = ( await dataService . createDataKey ( 'local' ) ) as Binary ;
62+ const someKey2 = ( await dataService . createDataKey ( 'local' ) ) as Binary ;
5363 return [
54- new CSFLECollectionTrackerImpl ( dataService , crudClient ) ,
64+ ( dataService as DataServiceImpl ) . getCSFLECollectionTracker ( ) ,
5565 dataService ,
66+ someKey1 ,
67+ someKey2 ,
5668 ] ;
5769 }
5870
@@ -134,7 +146,7 @@ describe('CSFLECollectionTracker', function () {
134146
135147 context ( 'with client-side FLE1 schema info' , function ( ) {
136148 beforeEach ( async function ( ) {
137- [ tracker , dataService ] = await createTracker ( {
149+ [ tracker , dataService ] = await createTracker ( ( [ SOME_UUID1 ] ) => ( {
138150 schemaMap : {
139151 [ `${ dbName } .test1` ] : {
140152 properties : {
@@ -168,7 +180,7 @@ describe('CSFLECollectionTracker', function () {
168180 } ,
169181 } ,
170182 } ,
171- } ) ;
183+ } ) ) ;
172184 } ) ;
173185
174186 it ( 'correctly returns whether updates are allowed' , async function ( ) {
@@ -190,16 +202,18 @@ describe('CSFLECollectionTracker', function () {
190202
191203 context ( 'with client-side FLE2 schema info' , function ( ) {
192204 beforeEach ( async function ( ) {
193- [ tracker , dataService ] = await createTracker ( {
194- encryptedFieldsMap : {
195- [ `${ dbName } .test2` ] : {
196- fields : [ { path : 'a' , keyId : SOME_UUID1 , bsonType : 'string' } ] ,
197- } ,
198- [ `${ dbName } .test3` ] : {
199- fields : [ { path : 'n.a' , keyId : SOME_UUID2 , bsonType : 'string' } ] ,
205+ [ tracker , dataService ] = await createTracker (
206+ ( [ SOME_UUID1 , SOME_UUID2 ] ) => ( {
207+ encryptedFieldsMap : {
208+ [ `${ dbName } .test2` ] : {
209+ fields : [ { path : 'a' , keyId : SOME_UUID1 , bsonType : 'string' } ] ,
210+ } ,
211+ [ `${ dbName } .test3` ] : {
212+ fields : [ { path : 'n.a' , keyId : SOME_UUID2 , bsonType : 'string' } ] ,
213+ } ,
200214 } ,
201- } ,
202- } ) ;
215+ } )
216+ ) ;
203217 } ) ;
204218
205219 it ( 'correctly returns whether updates are allowed' , async function ( ) {
@@ -220,12 +234,15 @@ describe('CSFLECollectionTracker', function () {
220234 } ) ;
221235
222236 context ( 'with server-side FLE1 schema info' , function ( ) {
237+ let SOME_UUID1 ;
223238 beforeEach ( async function ( ) {
224- [ tracker , dataService ] = await createTracker ( ) ;
225- const crudClient : MongoClient = ( dataService as any ) . _initializedClient (
226- 'CRUD'
227- ) ;
228- await crudClient . db ( dbName ) . createCollection ( 'test1' , {
239+ [ tracker , dataService , SOME_UUID1 ] = await createTracker ( ) ;
240+ // TODO: This might/should be the CRUD client, but that doesn't
241+ // work -- https://jira.mongodb.org/browse/MONGOCRYPT-436 tracks this.
242+ const metadataClient : MongoClient = (
243+ dataService as any
244+ ) . _initializedClient ( 'META' ) ;
245+ await metadataClient . db ( dbName ) . createCollection ( 'test1' , {
229246 validator : {
230247 $jsonSchema : {
231248 properties : {
@@ -235,7 +252,7 @@ describe('CSFLECollectionTracker', function () {
235252 } ,
236253 } ) ;
237254
238- await crudClient . db ( dbName ) . createCollection ( 'test2' , {
255+ await metadataClient . db ( dbName ) . createCollection ( 'test2' , {
239256 validator : {
240257 $jsonSchema : {
241258 properties : {
@@ -251,7 +268,7 @@ describe('CSFLECollectionTracker', function () {
251268 } ,
252269 } ) ;
253270
254- await crudClient . db ( dbName ) . createCollection ( 'test3' , {
271+ await metadataClient . db ( dbName ) . createCollection ( 'test3' , {
255272 validator : {
256273 $jsonSchema : {
257274 properties : {
@@ -290,18 +307,22 @@ describe('CSFLECollectionTracker', function () {
290307 } ) ;
291308
292309 context ( 'with server-side FLE2 schema info' , function ( ) {
310+ let SOME_UUID1 , SOME_UUID2 ;
293311 beforeEach ( async function ( ) {
294- [ tracker , dataService ] = await createTracker ( ) ;
295- const crudClient : MongoClient = ( dataService as any ) . _initializedClient (
296- 'CRUD'
297- ) ;
298- await crudClient . db ( dbName ) . createCollection ( 'test2' , {
312+ [ tracker , dataService , SOME_UUID1 , SOME_UUID2 ] = await createTracker ( ) ;
313+ // Creating the collections needs to be done through the non-FLE-aware
314+ // client here, because newer libmongocrypt versions also fetch
315+ // collection infos when doing createCollection commands.
316+ const metaDataClient : MongoClient = (
317+ dataService as any
318+ ) . _initializedClient ( 'META' ) ;
319+ await metaDataClient . db ( dbName ) . createCollection ( 'test2' , {
299320 encryptedFields : {
300321 fields : [ { path : 'a' , keyId : SOME_UUID1 , bsonType : 'string' } ] ,
301322 } ,
302323 } ) ;
303324
304- await crudClient . db ( dbName ) . createCollection ( 'test3' , {
325+ await metaDataClient . db ( dbName ) . createCollection ( 'test3' , {
305326 encryptedFields : {
306327 fields : [ { path : 'n.a' , keyId : SOME_UUID2 , bsonType : 'string' } ] ,
307328 } ,
@@ -360,7 +381,7 @@ describe('CSFLECollectionTracker', function () {
360381 dataService . findOneAndUpdate (
361382 `${ dbName } .test2` ,
362383 { } ,
363- { $set : { a : 2 } } ,
384+ { $set : { a : '2' } } ,
364385 { } ,
365386 resolve
366387 ) ;
@@ -384,7 +405,7 @@ describe('CSFLECollectionTracker', function () {
384405 dataService . findOneAndUpdate (
385406 `${ dbName } .test2` ,
386407 { } ,
387- { $set : { a : 2 } } ,
408+ { $set : { a : '2' } } ,
388409 { } ,
389410 resolve
390411 ) ;
@@ -419,14 +440,18 @@ describe('CSFLECollectionTracker', function () {
419440 } ) ;
420441
421442 context ( 'with client-side and server-side FLE2 schema info' , function ( ) {
443+ let SOME_UUID2 ;
444+
422445 beforeEach ( async function ( ) {
423- [ tracker , dataService ] = await createTracker ( {
424- encryptedFieldsMap : {
425- [ `${ dbName } .test3` ] : {
426- fields : [ { path : 'n.a' , keyId : SOME_UUID2 , bsonType : 'string' } ] ,
446+ [ tracker , dataService , SOME_UUID2 ] = await createTracker (
447+ ( [ SOME_UUID2 ] ) => ( {
448+ encryptedFieldsMap : {
449+ [ `${ dbName } .test3` ] : {
450+ fields : [ { path : 'n.a' , keyId : SOME_UUID2 , bsonType : 'string' } ] ,
451+ } ,
427452 } ,
428- } ,
429- } ) ;
453+ } )
454+ ) ;
430455 const crudClient : MongoClient = ( dataService as any ) . _initializedClient (
431456 'CRUD'
432457 ) ;
0 commit comments