mongodb 3.6.5 → 3.6.9

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.
@@ -0,0 +1,163 @@
1
+ 'use strict';
2
+ const MongoClient = require('./mongo_client');
3
+ const BSON = require('./core/connection/utils').retrieveBSON();
4
+ const MongoError = require('./core/error').MongoError;
5
+
6
+ try {
7
+ require.resolve('mongodb-client-encryption');
8
+ } catch (err) {
9
+ throw new MongoError(
10
+ 'Auto-encryption requested, but the module is not installed. ' +
11
+ 'Please add `mongodb-client-encryption` as a dependency of your project'
12
+ );
13
+ }
14
+
15
+ const mongodbClientEncryption = require('mongodb-client-encryption');
16
+ if (typeof mongodbClientEncryption.extension !== 'function') {
17
+ throw new MongoError(
18
+ 'loaded version of `mongodb-client-encryption` does not have property `extension`. ' +
19
+ 'Please make sure you are loading the correct version of `mongodb-client-encryption`'
20
+ );
21
+ }
22
+ const AutoEncrypter = mongodbClientEncryption.extension(require('../index')).AutoEncrypter;
23
+
24
+ const kInternalClient = Symbol('internalClient');
25
+
26
+ class Encrypter {
27
+ /**
28
+ * @param {MongoClient} client
29
+ * @param {{autoEncryption: import('./mongo_client').AutoEncryptionOptions, bson: object}} options
30
+ */
31
+ constructor(client, options) {
32
+ this.bypassAutoEncryption = !!options.autoEncryption.bypassAutoEncryption;
33
+ this.needsConnecting = false;
34
+
35
+ if (options.maxPoolSize === 0 && options.autoEncryption.keyVaultClient == null) {
36
+ options.autoEncryption.keyVaultClient = client;
37
+ } else if (options.autoEncryption.keyVaultClient == null) {
38
+ options.autoEncryption.keyVaultClient = this.getInternalClient(client);
39
+ }
40
+
41
+ if (this.bypassAutoEncryption) {
42
+ options.autoEncryption.metadataClient = undefined;
43
+ } else if (options.maxPoolSize === 0) {
44
+ options.autoEncryption.metadataClient = client;
45
+ } else {
46
+ options.autoEncryption.metadataClient = this.getInternalClient(client);
47
+ }
48
+
49
+ options.autoEncryption.bson = Encrypter.makeBSON(options);
50
+
51
+ this.autoEncrypter = new AutoEncrypter(client, options.autoEncryption);
52
+ }
53
+
54
+ getInternalClient(client) {
55
+ if (!this[kInternalClient]) {
56
+ const clonedOptions = {};
57
+
58
+ for (const key of Object.keys(client.s.options)) {
59
+ if (
60
+ ['autoEncryption', 'minPoolSize', 'servers', 'caseTranslate', 'dbName'].indexOf(key) !==
61
+ -1
62
+ )
63
+ continue;
64
+ clonedOptions[key] = client.s.options[key];
65
+ }
66
+
67
+ clonedOptions.minPoolSize = 0;
68
+
69
+ const allEvents = [
70
+ // APM
71
+ 'commandStarted',
72
+ 'commandSucceeded',
73
+ 'commandFailed',
74
+
75
+ // SDAM
76
+ 'serverOpening',
77
+ 'serverClosed',
78
+ 'serverDescriptionChanged',
79
+ 'serverHeartbeatStarted',
80
+ 'serverHeartbeatSucceeded',
81
+ 'serverHeartbeatFailed',
82
+ 'topologyOpening',
83
+ 'topologyClosed',
84
+ 'topologyDescriptionChanged',
85
+
86
+ // Legacy
87
+ 'joined',
88
+ 'left',
89
+ 'ping',
90
+ 'ha',
91
+
92
+ // CMAP
93
+ 'connectionPoolCreated',
94
+ 'connectionPoolClosed',
95
+ 'connectionCreated',
96
+ 'connectionReady',
97
+ 'connectionClosed',
98
+ 'connectionCheckOutStarted',
99
+ 'connectionCheckOutFailed',
100
+ 'connectionCheckedOut',
101
+ 'connectionCheckedIn',
102
+ 'connectionPoolCleared'
103
+ ];
104
+
105
+ this[kInternalClient] = new MongoClient(client.s.url, clonedOptions);
106
+
107
+ for (const eventName of allEvents) {
108
+ for (const listener of client.listeners(eventName)) {
109
+ this[kInternalClient].on(eventName, listener);
110
+ }
111
+ }
112
+
113
+ client.on('newListener', (eventName, listener) => {
114
+ this[kInternalClient].on(eventName, listener);
115
+ });
116
+
117
+ this.needsConnecting = true;
118
+ }
119
+ return this[kInternalClient];
120
+ }
121
+
122
+ connectInternalClient(callback) {
123
+ if (this.needsConnecting) {
124
+ this.needsConnecting = false;
125
+ return this[kInternalClient].connect(callback);
126
+ }
127
+
128
+ return callback();
129
+ }
130
+
131
+ close(client, force, callback) {
132
+ this.autoEncrypter.teardown(e => {
133
+ if (this[kInternalClient] && client !== this[kInternalClient]) {
134
+ return this[kInternalClient].close(force, callback);
135
+ }
136
+ callback(e);
137
+ });
138
+ }
139
+
140
+ static makeBSON(options) {
141
+ return (
142
+ (options || {}).bson ||
143
+ new BSON([
144
+ BSON.Binary,
145
+ BSON.Code,
146
+ BSON.DBRef,
147
+ BSON.Decimal128,
148
+ BSON.Double,
149
+ BSON.Int32,
150
+ BSON.Long,
151
+ BSON.Map,
152
+ BSON.MaxKey,
153
+ BSON.MinKey,
154
+ BSON.ObjectId,
155
+ BSON.BSONRegExp,
156
+ BSON.Symbol,
157
+ BSON.Timestamp
158
+ ])
159
+ );
160
+ }
161
+ }
162
+
163
+ module.exports = { Encrypter };
@@ -284,6 +284,7 @@ function checkDone(_this, callback) {
284
284
  return __handleError(_this, error, callback);
285
285
  }
286
286
  _this.emit('finish', filesDoc);
287
+ _this.emit('close');
287
288
  });
288
289
 
289
290
  return true;
@@ -71,97 +71,131 @@ const validOptions = require('./operations/connect').validOptions;
71
71
  * @property {string} [platform] Optional platform information
72
72
  */
73
73
 
74
+ /**
75
+ * @public
76
+ * @typedef AutoEncryptionOptions
77
+ * @property {MongoClient} [keyVaultClient] A `MongoClient` used to fetch keys from a key vault
78
+ * @property {string} [keyVaultNamespace] The namespace where keys are stored in the key vault
79
+ * @property {object} [kmsProviders] Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.
80
+ * @property {object} [schemaMap] A map of namespaces to a local JSON schema for encryption
81
+ *
82
+ * > **NOTE**: Supplying options.schemaMap provides more security than relying on JSON Schemas obtained from the server.
83
+ * > It protects against a malicious server advertising a false JSON Schema, which could trick the client into sending decrypted data that should be encrypted.
84
+ * > Schemas supplied in the schemaMap only apply to configuring automatic encryption for client side encryption.
85
+ * > Other validation rules in the JSON schema will not be enforced by the driver and will result in an error.
86
+ *
87
+ * @property {object} [options] An optional hook to catch logging messages from the underlying encryption engine
88
+ * @property {object} [extraOptions]
89
+ * @property {boolean} [bypassAutoEncryption]
90
+ */
91
+
92
+ /**
93
+ * @typedef {object} MongoClientOptions
94
+ * @property {number} [poolSize] (**default**: 5) The maximum size of the individual server pool
95
+ * @property {boolean} [ssl] (**default**: false) Enable SSL connection. *deprecated* use `tls` variants
96
+ * @property {boolean} [sslValidate] (**default**: false) Validate mongod server certificate against Certificate Authority
97
+ * @property {buffer} [sslCA] (**default**: undefined) SSL Certificate store binary buffer *deprecated* use `tls` variants
98
+ * @property {buffer} [sslCert] (**default**: undefined) SSL Certificate binary buffer *deprecated* use `tls` variants
99
+ * @property {buffer} [sslKey] (**default**: undefined) SSL Key file binary buffer *deprecated* use `tls` variants
100
+ * @property {string} [sslPass] (**default**: undefined) SSL Certificate pass phrase *deprecated* use `tls` variants
101
+ * @property {buffer} [sslCRL] (**default**: undefined) SSL Certificate revocation list binary buffer *deprecated* use `tls` variants
102
+ * @property {boolean|function} [checkServerIdentity] (**default**: true) Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function. *deprecated* use `tls` variants
103
+ * @property {boolean} [tls] (**default**: false) Enable TLS connections
104
+ * @property {boolean} [tlsInsecure] (**default**: false) Relax TLS constraints, disabling validation
105
+ * @property {string} [tlsCAFile] A path to file with either a single or bundle of certificate authorities to be considered trusted when making a TLS connection
106
+ * @property {string} [tlsCertificateKeyFile] A path to the client certificate file or the client private key file; in the case that they both are needed, the files should be concatenated
107
+ * @property {string} [tlsCertificateKeyFilePassword] The password to decrypt the client private key to be used for TLS connections
108
+ * @property {boolean} [tlsAllowInvalidCertificates] Specifies whether or not the driver should error when the server’s TLS certificate is invalid
109
+ * @property {boolean} [tlsAllowInvalidHostnames] Specifies whether or not the driver should error when there is a mismatch between the server’s hostname and the hostname specified by the TLS certificate
110
+ * @property {boolean} [autoReconnect] (**default**: true) Enable autoReconnect for single server instances
111
+ * @property {boolean} [noDelay] (**default**: true) TCP Connection no delay
112
+ * @property {boolean} [keepAlive] (**default**: true) TCP Connection keep alive enabled
113
+ * @property {number} [keepAliveInitialDelay] (**default**: 120000) The number of milliseconds to wait before initiating keepAlive on the TCP socket
114
+ * @property {number} [connectTimeoutMS] (**default**: 10000) How long to wait for a connection to be established before timing out
115
+ * @property {number} [socketTimeoutMS] (**default**: 0) How long a send or receive on a socket can take before timing out
116
+ * @property {number} [family] Version of IP stack. Can be 4, 6 or null (default). If null, will attempt to connect with IPv6, and will fall back to IPv4 on failure
117
+ * @property {number} [reconnectTries] (**default**: 30) Server attempt to reconnect #times
118
+ * @property {number} [reconnectInterval] (**default**: 1000) Server will wait # milliseconds between retries
119
+ * @property {boolean} [ha] (**default**: true) Control if high availability monitoring runs for Replicaset or Mongos proxies
120
+ * @property {number} [haInterval] (**default**: 10000) The High availability period for replicaset inquiry
121
+ * @property {string} [replicaSet] (**default**: undefined) The Replicaset set name
122
+ * @property {number} [secondaryAcceptableLatencyMS] (**default**: 15) Cutoff latency point in MS for Replicaset member selection
123
+ * @property {number} [acceptableLatencyMS] (**default**: 15) Cutoff latency point in MS for Mongos proxies selection
124
+ * @property {boolean} [connectWithNoPrimary] (**default**: false) Sets if the driver should connect even if no primary is available
125
+ * @property {string} [authSource] (**default**: undefined) Define the database to authenticate against
126
+ * @property {(number|string)} [w] **Deprecated** The write concern. Use writeConcern instead.
127
+ * @property {number} [wtimeout] **Deprecated** The write concern timeout. Use writeConcern instead.
128
+ * @property {boolean} [j] (**default**: false) **Deprecated** Specify a journal write concern. Use writeConcern instead.
129
+ * @property {boolean} [fsync] (**default**: false) **Deprecated** Specify a file sync write concern. Use writeConcern instead.
130
+ * @property {object|WriteConcern} [writeConcern] Specify write concern settings.
131
+ * @property {boolean} [forceServerObjectId] (**default**: false) Force server to assign _id values instead of driver
132
+ * @property {boolean} [serializeFunctions] (**default**: false) Serialize functions on any object
133
+ * @property {Boolean} [ignoreUndefined] (**default**: false) Specify if the BSON serializer should ignore undefined fields
134
+ * @property {boolean} [raw] (**default**: false) Return document results as raw BSON buffers
135
+ * @property {number} [bufferMaxEntries] (**default**: -1) Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited
136
+ * @property {(ReadPreference|string)} [readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST)
137
+ * @property {object} [pkFactory] A primary key factory object for generation of custom _id keys
138
+ * @property {object} [promiseLibrary] A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
139
+ * @property {object} [readConcern] Specify a read concern for the collection (only MongoDB 3.2 or higher supported)
140
+ * @property {ReadConcernLevel} [readConcern.level] (**default**: {Level: 'local'}) Specify a read concern level for the collection operations (only MongoDB 3.2 or higher supported)
141
+ * @property {number} [maxStalenessSeconds] (**default**: undefined) The max staleness to secondary reads (values under 10 seconds cannot be guaranteed)
142
+ * @property {string} [loggerLevel] (**default**: undefined) The logging level (error/warn/info/debug)
143
+ * @property {object} [logger] (**default**: undefined) Custom logger object
144
+ * @property {boolean} [promoteValues] (**default**: true) Promotes BSON values to native types where possible, set to false to only receive wrapper types
145
+ * @property {boolean} [promoteBuffers] (**default**: false) Promotes Binary BSON values to native Node Buffers
146
+ * @property {boolean} [promoteLongs] (**default**: true) Promotes long values to number if they fit inside the 53 bits resolution
147
+ * @property {boolean} [domainsEnabled] (**default**: false) Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit
148
+ * @property {object} [validateOptions] (**default**: false) Validate MongoClient passed in options for correctness
149
+ * @property {string} [appname] (**default**: undefined) The name of the application that created this MongoClient instance. MongoDB 3.4 and newer will print this value in the server log upon establishing each connection. It is also recorded in the slow query log and profile collections
150
+ * @property {string} [options.auth.user] (**default**: undefined) The username for auth
151
+ * @property {string} [options.auth.password] (**default**: undefined) The password for auth
152
+ * @property {string} [authMechanism] An authentication mechanism to use for connection authentication, see the {@link https://docs.mongodb.com/manual/reference/connection-string/#urioption.authMechanism|authMechanism} reference for supported options.
153
+ * @property {object} [compression] Type of compression to use: snappy or zlib
154
+ * @property {array} [readPreferenceTags] Read preference tags
155
+ * @property {number} [numberOfRetries] (**default**: 5) The number of retries for a tailable cursor
156
+ * @property {boolean} [auto_reconnect] (**default**: true) Enable auto reconnecting for single server instances
157
+ * @property {boolean} [monitorCommands] (**default**: false) Enable command monitoring for this client
158
+ * @property {number} [minSize] If present, the connection pool will be initialized with minSize connections, and will never dip below minSize connections
159
+ * @property {boolean} [useNewUrlParser] (**default**: true) Determines whether or not to use the new url parser. Enables the new, spec-compliant, url parser shipped in the core driver. This url parser fixes a number of problems with the original parser, and aims to outright replace that parser in the near future. Defaults to true, and must be explicitly set to false to use the legacy url parser.
160
+ * @property {boolean} [useUnifiedTopology] Enables the new unified topology layer
161
+ * @property {number} [localThresholdMS] (**default**: 15) **Only applies to the unified topology** The size of the latency window for selecting among multiple suitable servers
162
+ * @property {number} [serverSelectionTimeoutMS] (**default**: 30000) **Only applies to the unified topology** How long to block for server selection before throwing an error
163
+ * @property {number} [heartbeatFrequencyMS] (**default**: 10000) **Only applies to the unified topology** The frequency with which topology updates are scheduled
164
+ * @property {number} [maxPoolSize] (**default**: 10) **Only applies to the unified topology** The maximum number of connections that may be associated with a pool at a given time. This includes in use and available connections.
165
+ * @property {number} [minPoolSize] (**default**: 0) **Only applies to the unified topology** The minimum number of connections that MUST exist at any moment in a single connection pool.
166
+ * @property {number} [maxIdleTimeMS] **Only applies to the unified topology** The maximum amount of time a connection should remain idle in the connection pool before being marked idle. The default is infinity.
167
+ * @property {number} [waitQueueTimeoutMS] (**default**: 0) **Only applies to the unified topology** The maximum amount of time operation execution should wait for a connection to become available. The default is 0 which means there is no limit.
168
+ * @property {AutoEncryptionOptions} [autoEncryption] Optionally enable client side auto encryption.
169
+ *
170
+ * > Automatic encryption is an enterprise only feature that only applies to operations on a collection. Automatic encryption is not supported for operations on a database or view, and operations that are not bypassed will result in error
171
+ * > (see [libmongocrypt: Auto Encryption Allow-List](https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#libmongocrypt-auto-encryption-allow-list)). To bypass automatic encryption for all operations, set bypassAutoEncryption=true in AutoEncryptionOpts.
172
+ * >
173
+ * > Automatic encryption requires the authenticated user to have the [listCollections privilege action](https://docs.mongodb.com/manual/reference/command/listCollections/#dbcmd.listCollections).
174
+ * >
175
+ * > If a MongoClient with a limited connection pool size (i.e a non-zero maxPoolSize) is configured with AutoEncryptionOptions, a separate internal MongoClient is created if any of the following are true:
176
+ * > - AutoEncryptionOptions.keyVaultClient is not passed.
177
+ * > - AutoEncryptionOptions.bypassAutomaticEncryption is false.
178
+ * > If an internal MongoClient is created, it is configured with the same options as the parent MongoClient except minPoolSize is set to 0 and AutoEncryptionOptions is omitted.
179
+ *
180
+ * @property {DriverInfoOptions} [driverInfo] Allows a wrapping driver to amend the client metadata generated by the driver to include information about the wrapping driver
181
+ * @property {boolean} [directConnection] (**default**: false) Enable directConnection
182
+ * @property {function} [callback] The command result callback
183
+ */
184
+
74
185
  /**
75
186
  * Creates a new MongoClient instance
76
- * @class
187
+ * @constructor
188
+ * @extends {EventEmitter}
77
189
  * @param {string} url The connection URI string
78
- * @param {object} [options] Optional settings
79
- * @param {number} [options.poolSize=5] The maximum size of the individual server pool
80
- * @param {boolean} [options.ssl=false] Enable SSL connection. *deprecated* use `tls` variants
81
- * @param {boolean} [options.sslValidate=false] Validate mongod server certificate against Certificate Authority
82
- * @param {buffer} [options.sslCA=undefined] SSL Certificate store binary buffer *deprecated* use `tls` variants
83
- * @param {buffer} [options.sslCert=undefined] SSL Certificate binary buffer *deprecated* use `tls` variants
84
- * @param {buffer} [options.sslKey=undefined] SSL Key file binary buffer *deprecated* use `tls` variants
85
- * @param {string} [options.sslPass=undefined] SSL Certificate pass phrase *deprecated* use `tls` variants
86
- * @param {buffer} [options.sslCRL=undefined] SSL Certificate revocation list binary buffer *deprecated* use `tls` variants
87
- * @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function. *deprecated* use `tls` variants
88
- * @param {boolean} [options.tls=false] Enable TLS connections
89
- * @param {boolean} [options.tlsInsecure=false] Relax TLS constraints, disabling validation
90
- * @param {string} [options.tlsCAFile] A path to file with either a single or bundle of certificate authorities to be considered trusted when making a TLS connection
91
- * @param {string} [options.tlsCertificateKeyFile] A path to the client certificate file or the client private key file; in the case that they both are needed, the files should be concatenated
92
- * @param {string} [options.tlsCertificateKeyFilePassword] The password to decrypt the client private key to be used for TLS connections
93
- * @param {boolean} [options.tlsAllowInvalidCertificates] Specifies whether or not the driver should error when the server’s TLS certificate is invalid
94
- * @param {boolean} [options.tlsAllowInvalidHostnames] Specifies whether or not the driver should error when there is a mismatch between the server’s hostname and the hostname specified by the TLS certificate
95
- * @param {boolean} [options.autoReconnect=true] Enable autoReconnect for single server instances
96
- * @param {boolean} [options.noDelay=true] TCP Connection no delay
97
- * @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
98
- * @param {number} [options.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
99
- * @param {number} [options.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
100
- * @param {number} [options.socketTimeoutMS=0] How long a send or receive on a socket can take before timing out
101
- * @param {number} [options.family] Version of IP stack. Can be 4, 6 or null (default).
102
- * If null, will attempt to connect with IPv6, and will fall back to IPv4 on failure
103
- * @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
104
- * @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
105
- * @param {boolean} [options.ha=true] Control if high availability monitoring runs for Replicaset or Mongos proxies
106
- * @param {number} [options.haInterval=10000] The High availability period for replicaset inquiry
107
- * @param {string} [options.replicaSet=undefined] The Replicaset set name
108
- * @param {number} [options.secondaryAcceptableLatencyMS=15] Cutoff latency point in MS for Replicaset member selection
109
- * @param {number} [options.acceptableLatencyMS=15] Cutoff latency point in MS for Mongos proxies selection
110
- * @param {boolean} [options.connectWithNoPrimary=false] Sets if the driver should connect even if no primary is available
111
- * @param {string} [options.authSource=undefined] Define the database to authenticate against
112
- * @param {(number|string)} [options.w] **Deprecated** The write concern. Use writeConcern instead.
113
- * @param {number} [options.wtimeout] **Deprecated** The write concern timeout. Use writeConcern instead.
114
- * @param {boolean} [options.j=false] **Deprecated** Specify a journal write concern. Use writeConcern instead.
115
- * @param {boolean} [options.fsync=false] **Deprecated** Specify a file sync write concern. Use writeConcern instead.
116
- * @param {object|WriteConcern} [options.writeConcern] Specify write concern settings.
117
- * @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver
118
- * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object
119
- * @param {Boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields
120
- * @param {boolean} [options.raw=false] Return document results as raw BSON buffers
121
- * @param {number} [options.bufferMaxEntries=-1] Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited
122
- * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST)
123
- * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys
124
- * @param {object} [options.promiseLibrary] A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
125
- * @param {object} [options.readConcern] Specify a read concern for the collection (only MongoDB 3.2 or higher supported)
126
- * @param {ReadConcernLevel} [options.readConcern.level='local'] Specify a read concern level for the collection operations (only MongoDB 3.2 or higher supported)
127
- * @param {number} [options.maxStalenessSeconds=undefined] The max staleness to secondary reads (values under 10 seconds cannot be guaranteed)
128
- * @param {string} [options.loggerLevel=undefined] The logging level (error/warn/info/debug)
129
- * @param {object} [options.logger=undefined] Custom logger object
130
- * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types
131
- * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers
132
- * @param {boolean} [options.promoteLongs=true] Promotes long values to number if they fit inside the 53 bits resolution
133
- * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit
134
- * @param {object} [options.validateOptions=false] Validate MongoClient passed in options for correctness
135
- * @param {string} [options.appname=undefined] The name of the application that created this MongoClient instance. MongoDB 3.4 and newer will print this value in the server log upon establishing each connection. It is also recorded in the slow query log and profile collections
136
- * @param {string} [options.auth.user=undefined] The username for auth
137
- * @param {string} [options.auth.password=undefined] The password for auth
138
- * @param {string} [options.authMechanism] An authentication mechanism to use for connection authentication, see the {@link https://docs.mongodb.com/manual/reference/connection-string/#urioption.authMechanism|authMechanism} reference for supported options.
139
- * @param {object} [options.compression] Type of compression to use: snappy or zlib
140
- * @param {array} [options.readPreferenceTags] Read preference tags
141
- * @param {number} [options.numberOfRetries=5] The number of retries for a tailable cursor
142
- * @param {boolean} [options.auto_reconnect=true] Enable auto reconnecting for single server instances
143
- * @param {boolean} [options.monitorCommands=false] Enable command monitoring for this client
144
- * @param {number} [options.minSize] If present, the connection pool will be initialized with minSize connections, and will never dip below minSize connections
145
- * @param {boolean} [options.useNewUrlParser=true] Determines whether or not to use the new url parser. Enables the new, spec-compliant, url parser shipped in the core driver. This url parser fixes a number of problems with the original parser, and aims to outright replace that parser in the near future. Defaults to true, and must be explicitly set to false to use the legacy url parser.
146
- * @param {boolean} [options.useUnifiedTopology] Enables the new unified topology layer
147
- * @param {Number} [options.localThresholdMS=15] **Only applies to the unified topology** The size of the latency window for selecting among multiple suitable servers
148
- * @param {Number} [options.serverSelectionTimeoutMS=30000] **Only applies to the unified topology** How long to block for server selection before throwing an error
149
- * @param {Number} [options.heartbeatFrequencyMS=10000] **Only applies to the unified topology** The frequency with which topology updates are scheduled
150
- * @param {number} [options.maxPoolSize=10] **Only applies to the unified topology** The maximum number of connections that may be associated with a pool at a given time. This includes in use and available connections.
151
- * @param {number} [options.minPoolSize=0] **Only applies to the unified topology** The minimum number of connections that MUST exist at any moment in a single connection pool.
152
- * @param {number} [options.maxIdleTimeMS] **Only applies to the unified topology** The maximum amount of time a connection should remain idle in the connection pool before being marked idle. The default is infinity.
153
- * @param {number} [options.waitQueueTimeoutMS=0] **Only applies to the unified topology** The maximum amount of time operation execution should wait for a connection to become available. The default is 0 which means there is no limit.
154
- * @param {AutoEncrypter~AutoEncryptionOptions} [options.autoEncryption] Optionally enable client side auto encryption
155
- * @param {DriverInfoOptions} [options.driverInfo] Allows a wrapping driver to amend the client metadata generated by the driver to include information about the wrapping driver
156
- * @param {boolean} [options.directConnection=false] Enable directConnection
157
- * @param {MongoClient~connectCallback} [callback] The command result callback
158
- * @return {MongoClient} a MongoClient instance
190
+ * @param {MongoClientOptions} [options] Optional settings
159
191
  */
160
192
  function MongoClient(url, options) {
161
193
  if (!(this instanceof MongoClient)) return new MongoClient(url, options);
162
194
  // Set up event emitter
163
195
  EventEmitter.call(this);
164
196
 
197
+ if (options && options.autoEncryption) require('./encrypter'); // Does CSFLE lib check
198
+
165
199
  // The internal state
166
200
  this.s = {
167
201
  url: url,
@@ -268,13 +302,13 @@ MongoClient.prototype.close = function(force, callback) {
268
302
  }
269
303
 
270
304
  client.topology.close(force, err => {
271
- const autoEncrypter = client.topology.s.options.autoEncrypter;
272
- if (!autoEncrypter) {
273
- completeClose(err);
274
- return;
305
+ const encrypter = client.topology.s.options.encrypter;
306
+ if (encrypter) {
307
+ return encrypter.close(client, force, err2 => {
308
+ completeClose(err || err2);
309
+ });
275
310
  }
276
-
277
- autoEncrypter.teardown(force, err2 => completeClose(err || err2));
311
+ completeClose(err);
278
312
  });
279
313
  });
280
314
  };
@@ -351,86 +385,7 @@ MongoClient.prototype.isConnected = function(options) {
351
385
  * @method
352
386
  * @static
353
387
  * @param {string} url The connection URI string
354
- * @param {object} [options] Optional settings
355
- * @param {number} [options.poolSize=5] The maximum size of the individual server pool
356
- * @param {boolean} [options.ssl=false] Enable SSL connection. *deprecated* use `tls` variants
357
- * @param {boolean} [options.sslValidate=false] Validate mongod server certificate against Certificate Authority
358
- * @param {buffer} [options.sslCA=undefined] SSL Certificate store binary buffer *deprecated* use `tls` variants
359
- * @param {buffer} [options.sslCert=undefined] SSL Certificate binary buffer *deprecated* use `tls` variants
360
- * @param {buffer} [options.sslKey=undefined] SSL Key file binary buffer *deprecated* use `tls` variants
361
- * @param {string} [options.sslPass=undefined] SSL Certificate pass phrase *deprecated* use `tls` variants
362
- * @param {buffer} [options.sslCRL=undefined] SSL Certificate revocation list binary buffer *deprecated* use `tls` variants
363
- * @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function. *deprecated* use `tls` variants
364
- * @param {boolean} [options.tls=false] Enable TLS connections
365
- * @param {boolean} [options.tlsInsecure=false] Relax TLS constraints, disabling validation
366
- * @param {string} [options.tlsCAFile] A path to file with either a single or bundle of certificate authorities to be considered trusted when making a TLS connection
367
- * @param {string} [options.tlsCertificateKeyFile] A path to the client certificate file or the client private key file; in the case that they both are needed, the files should be concatenated
368
- * @param {string} [options.tlsCertificateKeyFilePassword] The password to decrypt the client private key to be used for TLS connections
369
- * @param {boolean} [options.tlsAllowInvalidCertificates] Specifies whether or not the driver should error when the server’s TLS certificate is invalid
370
- * @param {boolean} [options.tlsAllowInvalidHostnames] Specifies whether or not the driver should error when there is a mismatch between the server’s hostname and the hostname specified by the TLS certificate
371
- * @param {boolean} [options.autoReconnect=true] Enable autoReconnect for single server instances
372
- * @param {boolean} [options.noDelay=true] TCP Connection no delay
373
- * @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
374
- * @param {number} [options.keepAliveInitialDelay=120000] The number of milliseconds to wait before initiating keepAlive on the TCP socket
375
- * @param {number} [options.connectTimeoutMS=10000] How long to wait for a connection to be established before timing out
376
- * @param {number} [options.socketTimeoutMS=0] How long a send or receive on a socket can take before timing out
377
- * @param {number} [options.family] Version of IP stack. Can be 4, 6 or null (default).
378
- * If null, will attempt to connect with IPv6, and will fall back to IPv4 on failure
379
- * @param {number} [options.reconnectTries=30] Server attempt to reconnect #times
380
- * @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries
381
- * @param {boolean} [options.ha=true] Control if high availability monitoring runs for Replicaset or Mongos proxies
382
- * @param {number} [options.haInterval=10000] The High availability period for replicaset inquiry
383
- * @param {string} [options.replicaSet=undefined] The Replicaset set name
384
- * @param {number} [options.secondaryAcceptableLatencyMS=15] Cutoff latency point in MS for Replicaset member selection
385
- * @param {number} [options.acceptableLatencyMS=15] Cutoff latency point in MS for Mongos proxies selection
386
- * @param {boolean} [options.connectWithNoPrimary=false] Sets if the driver should connect even if no primary is available
387
- * @param {string} [options.authSource=undefined] Define the database to authenticate against
388
- * @param {(number|string)} [options.w] **Deprecated** The write concern. Use writeConcern instead.
389
- * @param {number} [options.wtimeout] **Deprecated** The write concern timeout. Use writeConcern instead.
390
- * @param {boolean} [options.j=false] **Deprecated** Specify a journal write concern. Use writeConcern instead.
391
- * @param {boolean} [options.fsync=false] **Deprecated** Specify a file sync write concern. Use writeConcern instead.
392
- * @param {object|WriteConcern} [options.writeConcern] Specify write concern settings.
393
- * @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver
394
- * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object
395
- * @param {Boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields
396
- * @param {boolean} [options.raw=false] Return document results as raw BSON buffers
397
- * @param {number} [options.bufferMaxEntries=-1] Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited
398
- * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST)
399
- * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys
400
- * @param {object} [options.promiseLibrary] A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
401
- * @param {object} [options.readConcern] Specify a read concern for the collection (only MongoDB 3.2 or higher supported)
402
- * @param {ReadConcernLevel} [options.readConcern.level='local'] Specify a read concern level for the collection operations (only MongoDB 3.2 or higher supported)
403
- * @param {number} [options.maxStalenessSeconds=undefined] The max staleness to secondary reads (values under 10 seconds cannot be guaranteed)
404
- * @param {string} [options.loggerLevel=undefined] The logging level (error/warn/info/debug)
405
- * @param {object} [options.logger=undefined] Custom logger object
406
- * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types
407
- * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers
408
- * @param {boolean} [options.promoteLongs=true] Promotes long values to number if they fit inside the 53 bits resolution
409
- * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit
410
- * @param {object} [options.validateOptions=false] Validate MongoClient passed in options for correctness
411
- * @param {string} [options.appname=undefined] The name of the application that created this MongoClient instance. MongoDB 3.4 and newer will print this value in the server log upon establishing each connection. It is also recorded in the slow query log and profile collections
412
- * @param {string} [options.auth.user=undefined] The username for auth
413
- * @param {string} [options.auth.password=undefined] The password for auth
414
- * @param {string} [options.authMechanism] An authentication mechanism to use for connection authentication, see the {@link https://docs.mongodb.com/manual/reference/connection-string/#urioption.authMechanism|authMechanism} reference for supported options.
415
- * @param {object} [options.compression] Type of compression to use: snappy or zlib
416
- * @param {array} [options.readPreferenceTags] Read preference tags
417
- * @param {number} [options.numberOfRetries=5] The number of retries for a tailable cursor
418
- * @param {boolean} [options.auto_reconnect=true] Enable auto reconnecting for single server instances
419
- * @param {boolean} [options.monitorCommands=false] Enable command monitoring for this client
420
- * @param {number} [options.minSize] If present, the connection pool will be initialized with minSize connections, and will never dip below minSize connections
421
- * @param {boolean} [options.directConnection=false] Enable directConnection
422
- * @param {boolean} [options.useNewUrlParser=true] Determines whether or not to use the new url parser. Enables the new, spec-compliant, url parser shipped in the core driver. This url parser fixes a number of problems with the original parser, and aims to outright replace that parser in the near future. Defaults to true, and must be explicitly set to false to use the legacy url parser.
423
- * @param {boolean} [options.useUnifiedTopology] Enables the new unified topology layer
424
- * @param {Number} [options.localThresholdMS=15] **Only applies to the unified topology** The size of the latency window for selecting among multiple suitable servers
425
- * @param {Number} [options.serverSelectionTimeoutMS=30000] **Only applies to the unified topology** How long to block for server selection before throwing an error
426
- * @param {Number} [options.heartbeatFrequencyMS=10000] **Only applies to the unified topology** The frequency with which topology updates are scheduled
427
- * @param {number} [options.maxPoolSize=10] **Only applies to the unified topology** The maximum number of connections that may be associated with a pool at a given time. This includes in use and available connections.
428
- * @param {number} [options.minPoolSize=0] **Only applies to the unified topology** The minimum number of connections that MUST exist at any moment in a single connection pool.
429
- * @param {number} [options.maxIdleTimeMS] **Only applies to the unified topology** The maximum amount of time a connection should remain idle in the connection pool before being marked idle. The default is infinity.
430
- * @param {number} [options.waitQueueTimeoutMS=0] **Only applies to the unified topology** The maximum amount of time operation execution should wait for a connection to become available. The default is 0 which means there is no limit.
431
- * @param {AutoEncrypter~AutoEncryptionOptions} [options.autoEncryption] Optionally enable client side auto encryption
432
- * @param {DriverInfoOptions} [options.driverInfo] Allows a wrapping driver to amend the client metadata generated by the driver to include information about the wrapping driver
433
- * @param {MongoClient~connectCallback} [callback] The command result callback
388
+ * @param {MongoClientOptions} [options] Optional settings
434
389
  * @return {Promise<MongoClient>} returns Promise if no callback passed
435
390
  */
436
391
  MongoClient.connect = function(url, options, callback) {
@@ -70,31 +70,6 @@ class BulkWriteOperation extends OperationBase {
70
70
  return callback(err, null);
71
71
  }
72
72
 
73
- r.insertedCount = r.nInserted;
74
- r.matchedCount = r.nMatched;
75
- r.modifiedCount = r.nModified || 0;
76
- r.deletedCount = r.nRemoved;
77
- r.upsertedCount = r.getUpsertedIds().length;
78
- r.upsertedIds = {};
79
- r.insertedIds = {};
80
-
81
- // Update the n
82
- r.n = r.insertedCount;
83
-
84
- // Inserted documents
85
- const inserted = r.getInsertedIds();
86
- // Map inserted ids
87
- for (let i = 0; i < inserted.length; i++) {
88
- r.insertedIds[inserted[i].index] = inserted[i]._id;
89
- }
90
-
91
- // Upserted documents
92
- const upserted = r.getUpsertedIds();
93
- // Map upserted ids
94
- for (let i = 0; i < upserted.length; i++) {
95
- r.upsertedIds[upserted[i].index] = upserted[i]._id;
96
- }
97
-
98
73
  // Return the results
99
74
  callback(null, r);
100
75
  });
@@ -16,7 +16,6 @@ const emitDeprecationWarning = require('../utils').emitDeprecationWarning;
16
16
  const emitWarningOnce = require('../utils').emitWarningOnce;
17
17
  const fs = require('fs');
18
18
  const WriteConcern = require('../write_concern');
19
- const BSON = require('../core/connection/utils').retrieveBSON();
20
19
  const CMAP_EVENT_NAMES = require('../cmap/events').CMAP_EVENT_NAMES;
21
20
 
22
21
  let client;
@@ -496,58 +495,9 @@ function createTopology(mongoClient, topologyType, options, callback) {
496
495
 
497
496
  // determine CSFLE support
498
497
  if (options.autoEncryption != null) {
499
- let AutoEncrypter;
500
- try {
501
- require.resolve('mongodb-client-encryption');
502
- } catch (err) {
503
- callback(
504
- new MongoError(
505
- 'Auto-encryption requested, but the module is not installed. Please add `mongodb-client-encryption` as a dependency of your project'
506
- )
507
- );
508
- return;
509
- }
510
-
511
- try {
512
- let mongodbClientEncryption = require('mongodb-client-encryption');
513
- if (typeof mongodbClientEncryption.extension !== 'function') {
514
- callback(
515
- new MongoError(
516
- 'loaded version of `mongodb-client-encryption` does not have property `extension`. Please make sure you are loading the correct version of `mongodb-client-encryption`'
517
- )
518
- );
519
- }
520
- AutoEncrypter = mongodbClientEncryption.extension(require('../../index')).AutoEncrypter;
521
- } catch (err) {
522
- callback(err);
523
- return;
524
- }
525
-
526
- const mongoCryptOptions = Object.assign(
527
- {
528
- bson:
529
- options.bson ||
530
- new BSON([
531
- BSON.Binary,
532
- BSON.Code,
533
- BSON.DBRef,
534
- BSON.Decimal128,
535
- BSON.Double,
536
- BSON.Int32,
537
- BSON.Long,
538
- BSON.Map,
539
- BSON.MaxKey,
540
- BSON.MinKey,
541
- BSON.ObjectId,
542
- BSON.BSONRegExp,
543
- BSON.Symbol,
544
- BSON.Timestamp
545
- ])
546
- },
547
- options.autoEncryption
548
- );
549
-
550
- options.autoEncrypter = new AutoEncrypter(mongoClient, mongoCryptOptions);
498
+ const Encrypter = require('../encrypter').Encrypter;
499
+ options.encrypter = new Encrypter(mongoClient, options);
500
+ options.autoEncrypter = options.encrypter.autoEncrypter;
551
501
  }
552
502
 
553
503
  // Create the topology
@@ -585,7 +535,10 @@ function createTopology(mongoClient, topologyType, options, callback) {
585
535
  return;
586
536
  }
587
537
 
588
- callback(undefined, topology);
538
+ options.encrypter.connectInternalClient(error => {
539
+ if (error) return callback(error);
540
+ callback(undefined, topology);
541
+ });
589
542
  });
590
543
  });
591
544
 
@@ -616,7 +569,7 @@ function createUnifiedOptions(finalOptions, options) {
616
569
  'mongos_options'
617
570
  ];
618
571
  const noMerge = ['readconcern', 'compression', 'autoencryption'];
619
- const skip = ['w', 'wtimeout', 'j', 'journal', 'fsync', 'writeConcern'];
572
+ const skip = ['w', 'wtimeout', 'j', 'journal', 'fsync', 'writeconcern'];
620
573
 
621
574
  for (const name in options) {
622
575
  if (skip.indexOf(name.toLowerCase()) !== -1) {
@@ -20,6 +20,9 @@ class FindOperation extends OperationBase {
20
20
  // copied from `CommandOperationV2`, to be subclassed in the future
21
21
  this.server = server;
22
22
 
23
+ // updates readPreference if setReadPreference was called on the cursor
24
+ this.readPreference = ReadPreference.resolve(this, this.options);
25
+
23
26
  if (typeof this.cmd.allowDiskUse !== 'undefined' && maxWireVersion(server) < 4) {
24
27
  callback(new MongoError('The `allowDiskUse` option is not supported on MongoDB < 3.2'));
25
28
  return;