@@ -12,6 +12,7 @@ const pkg = require('../../../package.json');
1212const processConnectionOptions = require ( '../../helpers/processConnectionOptions' ) ;
1313const setTimeout = require ( '../../helpers/timers' ) . setTimeout ;
1414const utils = require ( '../../utils' ) ;
15+ const Schema = require ( '../../schema' ) ;
1516
1617/**
1718 * A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) connection implementation.
@@ -320,6 +321,16 @@ NativeConnection.prototype.createClient = async function createClient(uri, optio
320321 } ;
321322 }
322323
324+ const { schemaMap, encryptedFieldsMap } = this . _buildEncryptionSchemas ( ) ;
325+
326+ if ( Object . keys ( schemaMap ) . length > 0 ) {
327+ options . autoEncryption . schemaMap = schemaMap ;
328+ }
329+
330+ if ( Object . keys ( encryptedFieldsMap ) . length > 0 ) {
331+ options . autoEncryption . encryptedFieldsMap = encryptedFieldsMap ;
332+ }
333+
323334 this . readyState = STATES . connecting ;
324335 this . _connectionString = uri ;
325336
@@ -343,6 +354,55 @@ NativeConnection.prototype.createClient = async function createClient(uri, optio
343354 return this ;
344355} ;
345356
357+ /**
358+ * Given a connection, which may or may not have encrypted models, build
359+ * a schemaMap and/or an encryptedFieldsMap for the connection, combining all models
360+ * into a single schemaMap and encryptedFields map.
361+ *
362+ * @returns a copy of the options object with a schemaMap and/or an encryptedFieldsMap added to the options' autoEncryption
363+ * options.
364+ */
365+ NativeConnection . prototype . _buildEncryptionSchemas = function ( ) {
366+ const qeMappings = { } ;
367+ const csfleMappings = { } ;
368+
369+ // If discriminators are configured for the collection, there might be multiple models
370+ // pointing to the same namespace. For this scenario, we merge all the schemas for each namespace
371+ // into a single schema.
372+ // Notably, this doesn't allow for discriminators to declare multiple values on the same fields.
373+ for ( const model of Object . values ( this . models ) ) {
374+ const { schema, collection : { collectionName } } = model ;
375+ const namespace = `${ this . $dbName } .${ collectionName } ` ;
376+ if ( schema . encryptionType ( ) === 'csfle' ) {
377+ csfleMappings [ namespace ] ??= new Schema ( { } , { encryptionType : 'csfle' } ) ;
378+ csfleMappings [ namespace ] . add ( schema ) ;
379+ } else if ( schema . encryptionType ( ) === 'queryableEncryption' ) {
380+ qeMappings [ namespace ] ??= new Schema ( { } , { encryptionType : 'queryableEncryption' } ) ;
381+ qeMappings [ namespace ] . add ( schema ) ;
382+ }
383+ }
384+
385+ const schemaMap = Object . entries ( csfleMappings ) . reduce (
386+ ( schemaMap , [ namespace , schema ] ) => {
387+ schemaMap [ namespace ] = schema . _buildSchemaMap ( ) ;
388+ return schemaMap ;
389+ } ,
390+ { }
391+ ) ;
392+
393+ const encryptedFieldsMap = Object . entries ( qeMappings ) . reduce (
394+ ( encryptedFieldsMap , [ namespace , schema ] ) => {
395+ encryptedFieldsMap [ namespace ] = schema . _buildEncryptedFields ( ) ;
396+ return encryptedFieldsMap ;
397+ } ,
398+ { }
399+ ) ;
400+
401+ return {
402+ schemaMap, encryptedFieldsMap
403+ } ;
404+ } ;
405+
346406/*!
347407 * ignore
348408 */
0 commit comments