mongodb 3.3.5 → 3.4.0

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.
Files changed (38) hide show
  1. package/HISTORY.md +36 -0
  2. package/lib/bulk/common.js +9 -4
  3. package/lib/bulk/ordered.js +9 -4
  4. package/lib/bulk/unordered.js +9 -4
  5. package/lib/collection.js +120 -36
  6. package/lib/core/auth/scram.js +42 -6
  7. package/lib/core/cmap/connection.js +220 -0
  8. package/lib/core/cmap/message_stream.js +181 -0
  9. package/lib/core/connection/apm.js +14 -16
  10. package/lib/core/connection/connect.js +39 -37
  11. package/lib/core/connection/connection.js +17 -1
  12. package/lib/core/connection/logger.js +9 -4
  13. package/lib/core/connection/msg.js +1 -1
  14. package/lib/core/connection/pool.js +26 -13
  15. package/lib/core/error.js +14 -2
  16. package/lib/core/sdam/monitoring.js +3 -0
  17. package/lib/core/sdam/server_selection.js +5 -4
  18. package/lib/core/sdam/srv_polling.js +1 -1
  19. package/lib/core/sdam/topology_description.js +7 -9
  20. package/lib/core/sessions.js +5 -8
  21. package/lib/core/uri_parser.js +48 -0
  22. package/lib/core/utils.js +1 -3
  23. package/lib/core/wireprotocol/command.js +12 -3
  24. package/lib/core/wireprotocol/compression.js +13 -13
  25. package/lib/db.js +3 -1
  26. package/lib/gridfs/grid_store.js +15 -8
  27. package/lib/gridfs-stream/download.js +5 -4
  28. package/lib/gridfs-stream/index.js +3 -2
  29. package/lib/gridfs-stream/upload.js +3 -3
  30. package/lib/mongo_client.js +35 -35
  31. package/lib/operations/command_v2.js +1 -3
  32. package/lib/operations/common_functions.js +1 -2
  33. package/lib/operations/connect.js +33 -3
  34. package/lib/operations/create_collection.js +1 -2
  35. package/lib/operations/db_ops.js +2 -4
  36. package/lib/operations/execute_operation.js +2 -1
  37. package/lib/operations/map_reduce.js +2 -1
  38. package/package.json +7 -6
package/HISTORY.md CHANGED
@@ -2,6 +2,42 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ <a name="3.4.0"></a>
6
+ # [3.4.0](https://github.com/mongodb/node-mongodb-native/compare/v3.3.5...v3.4.0) (2019-12-10)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **bulk:** use operation index from input to report operation error ([f713b13](https://github.com/mongodb/node-mongodb-native/commit/f713b13))
12
+ * **command:** only add TransientTransactionError label when in a transaction ([478d714](https://github.com/mongodb/node-mongodb-native/commit/478d714))
13
+ * **compression:** recalculate opcode after determine OP_COMPRESSED ([022f51b](https://github.com/mongodb/node-mongodb-native/commit/022f51b))
14
+ * **connect:** connect with family 0 instead of family 4 ([db07366](https://github.com/mongodb/node-mongodb-native/commit/db07366))
15
+ * **connection:** timed out connections should not be half closed ([850f4f5](https://github.com/mongodb/node-mongodb-native/commit/850f4f5))
16
+ * **cursor:** call `initialize` after session support check ([e50c51a](https://github.com/mongodb/node-mongodb-native/commit/e50c51a))
17
+ * **encryption:** autoEncryption must error on mongodb < 4.2 ([c274615](https://github.com/mongodb/node-mongodb-native/commit/c274615))
18
+ * **encryption:** do not attempt to merge autoEncryption options ([e27fdf9](https://github.com/mongodb/node-mongodb-native/commit/e27fdf9))
19
+ * **encryption:** encryption uses smaller batch size ([cb78e69](https://github.com/mongodb/node-mongodb-native/commit/cb78e69))
20
+ * **encryption:** respect bypassAutoEncryption ([e927499](https://github.com/mongodb/node-mongodb-native/commit/e927499))
21
+ * **encryption:** respect user bson options when using autoEncryption ([cb7a3f7](https://github.com/mongodb/node-mongodb-native/commit/cb7a3f7))
22
+ * add calculated duration to server as `roundTripTime` ([cb107a8](https://github.com/mongodb/node-mongodb-native/commit/cb107a8))
23
+ * **mongodb+srv:** respect overriding SRV-provided properties ([ea83360](https://github.com/mongodb/node-mongodb-native/commit/ea83360))
24
+ * **pool:** flush workItems after next tick to avoid dupe selection ([3ec49e5](https://github.com/mongodb/node-mongodb-native/commit/3ec49e5))
25
+ * **pool:** support a `drain` event for use with unified topology ([da931ea](https://github.com/mongodb/node-mongodb-native/commit/da931ea))
26
+ * **scram:** verify server digest, ensuring mutual authentication ([806cd62](https://github.com/mongodb/node-mongodb-native/commit/806cd62))
27
+ * **srv-poller:** always provide a valid number for `intervalMS` ([afb125f](https://github.com/mongodb/node-mongodb-native/commit/afb125f))
28
+ * **topology:** correct logic for checking for sessions support ([8d157c8](https://github.com/mongodb/node-mongodb-native/commit/8d157c8))
29
+ * **topology:** don't drain iteration timers on server selection ([fed6a57](https://github.com/mongodb/node-mongodb-native/commit/fed6a57))
30
+
31
+
32
+ ### Features
33
+
34
+ * add `MessageStream` for streamed wire protocol messaging ([8c44044](https://github.com/mongodb/node-mongodb-native/commit/8c44044))
35
+ * introduce a modern `Connection` replacement for CMAP ([7890e48](https://github.com/mongodb/node-mongodb-native/commit/7890e48))
36
+ * support connection establishment cancellation ([2014b7b](https://github.com/mongodb/node-mongodb-native/commit/2014b7b))
37
+ * support driver info for drivers wrapping the node driver ([1b6670b](https://github.com/mongodb/node-mongodb-native/commit/1b6670b))
38
+
39
+
40
+
5
41
  <a name="3.3.5"></a>
6
42
  ## [3.3.5](https://github.com/mongodb/node-mongodb-native/compare/v3.3.4...v3.3.5) (2019-11-26)
7
43
 
@@ -749,11 +749,15 @@ class BulkOperationBase {
749
749
 
750
750
  // Handle to the bson serializer, used to calculate running sizes
751
751
  const bson = topology.bson;
752
-
753
752
  // Set max byte size
754
753
  const isMaster = topology.lastIsMaster();
755
- const maxBatchSizeBytes =
754
+
755
+ // If we have autoEncryption on, batch-splitting must be done on 2mb chunks, but single documents
756
+ // over 2mb are still allowed
757
+ const usingAutoEncryption = !!(topology.s.options && topology.s.options.autoEncrypter);
758
+ const maxBsonObjectSize =
756
759
  isMaster && isMaster.maxBsonObjectSize ? isMaster.maxBsonObjectSize : 1024 * 1024 * 16;
760
+ const maxBatchSizeBytes = usingAutoEncryption ? 1024 * 1024 * 2 : maxBsonObjectSize;
757
761
  const maxWriteBatchSize =
758
762
  isMaster && isMaster.maxWriteBatchSize ? isMaster.maxWriteBatchSize : 1000;
759
763
 
@@ -805,8 +809,9 @@ class BulkOperationBase {
805
809
  // Write concern
806
810
  writeConcern: writeConcern,
807
811
  // Max batch size options
808
- maxBatchSizeBytes: maxBatchSizeBytes,
809
- maxWriteBatchSize: maxWriteBatchSize,
812
+ maxBsonObjectSize,
813
+ maxBatchSizeBytes,
814
+ maxWriteBatchSize,
810
815
  maxKeySize,
811
816
  // Namespace
812
817
  namespace: namespace,
@@ -27,8 +27,8 @@ function addToOperationsList(bulkOperation, docType, document) {
27
27
  });
28
28
 
29
29
  // Throw error if the doc is bigger than the max BSON size
30
- if (bsonSize >= bulkOperation.s.maxBatchSizeBytes)
31
- throw toError('document is larger than the maximum size ' + bulkOperation.s.maxBatchSizeBytes);
30
+ if (bsonSize >= bulkOperation.s.maxBsonObjectSize)
31
+ throw toError('document is larger than the maximum size ' + bulkOperation.s.maxBsonObjectSize);
32
32
 
33
33
  // Create a new batch object if we don't have a current one
34
34
  if (bulkOperation.s.currentBatch == null)
@@ -38,9 +38,14 @@ function addToOperationsList(bulkOperation, docType, document) {
38
38
 
39
39
  // Check if we need to create a new batch
40
40
  if (
41
+ // New batch if we exceed the max batch op size
41
42
  bulkOperation.s.currentBatchSize + 1 >= bulkOperation.s.maxWriteBatchSize ||
42
- bulkOperation.s.currentBatchSizeBytes + maxKeySize + bsonSize >=
43
- bulkOperation.s.maxBatchSizeBytes ||
43
+ // New batch if we exceed the maxBatchSizeBytes. Only matters if batch already has a doc,
44
+ // since we can't sent an empty batch
45
+ (bulkOperation.s.currentBatchSize > 0 &&
46
+ bulkOperation.s.currentBatchSizeBytes + maxKeySize + bsonSize >=
47
+ bulkOperation.s.maxBatchSizeBytes) ||
48
+ // New batch if the new op does not have the same op type as the current batch
44
49
  bulkOperation.s.currentBatch.batchType !== docType
45
50
  ) {
46
51
  // Save the batch to the execution stack
@@ -26,8 +26,8 @@ function addToOperationsList(bulkOperation, docType, document) {
26
26
  ignoreUndefined: false
27
27
  });
28
28
  // Throw error if the doc is bigger than the max BSON size
29
- if (bsonSize >= bulkOperation.s.maxBatchSizeBytes)
30
- throw toError('document is larger than the maximum size ' + bulkOperation.s.maxBatchSizeBytes);
29
+ if (bsonSize >= bulkOperation.s.maxBsonObjectSize)
30
+ throw toError('document is larger than the maximum size ' + bulkOperation.s.maxBsonObjectSize);
31
31
  // Holds the current batch
32
32
  bulkOperation.s.currentBatch = null;
33
33
  // Get the right type of batch
@@ -47,9 +47,14 @@ function addToOperationsList(bulkOperation, docType, document) {
47
47
 
48
48
  // Check if we need to create a new batch
49
49
  if (
50
+ // New batch if we exceed the max batch op size
50
51
  bulkOperation.s.currentBatch.size + 1 >= bulkOperation.s.maxWriteBatchSize ||
51
- bulkOperation.s.currentBatch.sizeBytes + maxKeySize + bsonSize >=
52
- bulkOperation.s.maxBatchSizeBytes ||
52
+ // New batch if we exceed the maxBatchSizeBytes. Only matters if batch already has a doc,
53
+ // since we can't sent an empty batch
54
+ (bulkOperation.s.currentBatch.size > 0 &&
55
+ bulkOperation.s.currentBatch.sizeBytes + maxKeySize + bsonSize >=
56
+ bulkOperation.s.maxBatchSizeBytes) ||
57
+ // New batch if the new op does not have the same op type as the current batch
53
58
  bulkOperation.s.currentBatch.batchType !== docType
54
59
  ) {
55
60
  // Save the batch to the execution stack
package/lib/collection.js CHANGED
@@ -99,12 +99,6 @@ const mergeKeys = ['ignoreUndefined'];
99
99
  /**
100
100
  * Create a new Collection instance (INTERNAL TYPE, do not instantiate directly)
101
101
  * @class
102
- * @property {string} collectionName Get the collection name.
103
- * @property {string} namespace Get the full collection namespace.
104
- * @property {object} writeConcern The current write concern values.
105
- * @property {object} readConcern The current read concern values.
106
- * @property {object} hint Get current index hint for collection.
107
- * @return {Collection} a Collection instance.
108
102
  */
109
103
  function Collection(db, topology, dbName, name, pkFactory, options) {
110
104
  checkCollectionName(name);
@@ -178,6 +172,12 @@ function Collection(db, topology, dbName, name, pkFactory, options) {
178
172
  };
179
173
  }
180
174
 
175
+ /**
176
+ * The name of the database this collection belongs to
177
+ * @member {string} dbName
178
+ * @memberof Collection#
179
+ * @readonly
180
+ */
181
181
  Object.defineProperty(Collection.prototype, 'dbName', {
182
182
  enumerable: true,
183
183
  get: function() {
@@ -185,6 +185,12 @@ Object.defineProperty(Collection.prototype, 'dbName', {
185
185
  }
186
186
  });
187
187
 
188
+ /**
189
+ * The name of this collection
190
+ * @member {string} collectionName
191
+ * @memberof Collection#
192
+ * @readonly
193
+ */
188
194
  Object.defineProperty(Collection.prototype, 'collectionName', {
189
195
  enumerable: true,
190
196
  get: function() {
@@ -192,6 +198,12 @@ Object.defineProperty(Collection.prototype, 'collectionName', {
192
198
  }
193
199
  });
194
200
 
201
+ /**
202
+ * The namespace of this collection, in the format `${this.dbName}.${this.collectionName}`
203
+ * @member {string} namespace
204
+ * @memberof Collection#
205
+ * @readonly
206
+ */
195
207
  Object.defineProperty(Collection.prototype, 'namespace', {
196
208
  enumerable: true,
197
209
  get: function() {
@@ -199,6 +211,13 @@ Object.defineProperty(Collection.prototype, 'namespace', {
199
211
  }
200
212
  });
201
213
 
214
+ /**
215
+ * The current readConcern of the collection. If not explicitly defined for
216
+ * this collection, will be inherited from the parent DB
217
+ * @member {ReadConcern} [readConcern]
218
+ * @memberof Collection#
219
+ * @readonly
220
+ */
202
221
  Object.defineProperty(Collection.prototype, 'readConcern', {
203
222
  enumerable: true,
204
223
  get: function() {
@@ -209,6 +228,13 @@ Object.defineProperty(Collection.prototype, 'readConcern', {
209
228
  }
210
229
  });
211
230
 
231
+ /**
232
+ * The current readPreference of the collection. If not explicitly defined for
233
+ * this collection, will be inherited from the parent DB
234
+ * @member {ReadPreference} [readPreference]
235
+ * @memberof Collection#
236
+ * @readonly
237
+ */
212
238
  Object.defineProperty(Collection.prototype, 'readPreference', {
213
239
  enumerable: true,
214
240
  get: function() {
@@ -220,6 +246,13 @@ Object.defineProperty(Collection.prototype, 'readPreference', {
220
246
  }
221
247
  });
222
248
 
249
+ /**
250
+ * The current writeConcern of the collection. If not explicitly defined for
251
+ * this collection, will be inherited from the parent DB
252
+ * @member {WriteConcern} [writeConcern]
253
+ * @memberof Collection#
254
+ * @readonly
255
+ */
223
256
  Object.defineProperty(Collection.prototype, 'writeConcern', {
224
257
  enumerable: true,
225
258
  get: function() {
@@ -231,7 +264,9 @@ Object.defineProperty(Collection.prototype, 'writeConcern', {
231
264
  });
232
265
 
233
266
  /**
234
- * @ignore
267
+ * The current index hint for the collection
268
+ * @member {object} [hint]
269
+ * @memberof Collection#
235
270
  */
236
271
  Object.defineProperty(Collection.prototype, 'hint', {
237
272
  enumerable: true,
@@ -260,6 +295,7 @@ const DEPRECATED_FIND_OPTIONS = ['maxScan', 'fields', 'snapshot'];
260
295
  * @param {boolean} [options.snapshot=false] DEPRECATED: Snapshot query.
261
296
  * @param {boolean} [options.timeout=false] Specify if the cursor can timeout.
262
297
  * @param {boolean} [options.tailable=false] Specify if the cursor is tailable.
298
+ * @param {boolean} [options.awaitData=false] Specify if the cursor is a a tailable-await cursor. Requires `tailable` to be true
263
299
  * @param {number} [options.batchSize=1000] Set the batchSize for the getMoreCommand when iterating over the query results.
264
300
  * @param {boolean} [options.returnKey=false] Only return the index key.
265
301
  * @param {number} [options.maxScan] DEPRECATED: Limit the number of items to scan.
@@ -274,6 +310,8 @@ const DEPRECATED_FIND_OPTIONS = ['maxScan', 'fields', 'snapshot'];
274
310
  * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
275
311
  * @param {boolean} [options.partial=false] Specify if the cursor should return partial results when querying against a sharded system
276
312
  * @param {number} [options.maxTimeMS] Number of milliseconds to wait before aborting the query.
313
+ * @param {number} [options.maxAwaitTimeMS] The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Requires `taiable` and `awaitData` to be true
314
+ * @param {boolean} [options.noCursorTimeout] The server normally times out idle cursors after an inactivity period (10 minutes) to prevent excess memory use. Set this option to prevent that.
277
315
  * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
278
316
  * @param {ClientSession} [options.session] optional session to use for this operation
279
317
  * @throws {MongoError}
@@ -451,12 +489,14 @@ Collection.prototype.find = deprecateOptions(
451
489
  * @method
452
490
  * @param {object} doc Document to insert.
453
491
  * @param {object} [options] Optional settings.
492
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
493
+ * @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver.
454
494
  * @param {(number|string)} [options.w] The write concern.
455
495
  * @param {number} [options.wtimeout] The write concern timeout.
456
496
  * @param {boolean} [options.j=false] Specify a journal write concern.
497
+ * @param {boolean} [options.checkKeys=true] If true, will throw if bson documents start with `$` or include a `.` in any key value
457
498
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
458
- * @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver.
459
- * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
499
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
460
500
  * @param {ClientSession} [options.session] optional session to use for this operation
461
501
  * @param {Collection~insertOneWriteOpCallback} [callback] The command result callback
462
502
  * @return {Promise} returns Promise if no callback passed
@@ -484,13 +524,15 @@ Collection.prototype.insertOne = function(doc, options, callback) {
484
524
  * @method
485
525
  * @param {object[]} docs Documents to insert.
486
526
  * @param {object} [options] Optional settings.
527
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
528
+ * @param {boolean} [options.ordered=true] If true, when an insert fails, don't execute the remaining writes. If false, continue with remaining inserts when one fails.
529
+ * @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver.
487
530
  * @param {(number|string)} [options.w] The write concern.
488
531
  * @param {number} [options.wtimeout] The write concern timeout.
489
532
  * @param {boolean} [options.j=false] Specify a journal write concern.
533
+ * @param {boolean} [options.checkKeys=true] If true, will throw if bson documents start with `$` or include a `.` in any key value
490
534
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
491
- * @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver.
492
- * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
493
- * @param {boolean} [options.ordered=true] If true, when an insert fails, don't execute the remaining writes. If false, continue with remaining inserts when one fails.
535
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
494
536
  * @param {ClientSession} [options.session] optional session to use for this operation
495
537
  * @param {Collection~insertWriteOpCallback} [callback] The command result callback
496
538
  * @return {Promise} returns Promise if no callback passed
@@ -549,13 +591,15 @@ Collection.prototype.insertMany = function(docs, options, callback) {
549
591
  * @method
550
592
  * @param {object[]} operations Bulk operations to perform.
551
593
  * @param {object} [options] Optional settings.
594
+ * @param {boolean} [options.ordered=true] Execute write operation in ordered or unordered fashion.
595
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
552
596
  * @param {object[]} [options.arrayFilters] Determines which array elements to modify for update operation in MongoDB 3.6 or higher.
553
597
  * @param {(number|string)} [options.w] The write concern.
554
598
  * @param {number} [options.wtimeout] The write concern timeout.
555
599
  * @param {boolean} [options.j=false] Specify a journal write concern.
600
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
556
601
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
557
- * @param {boolean} [options.ordered=true] Execute write operation in ordered or unordered fashion.
558
- * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
602
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
559
603
  * @param {ClientSession} [options.session] optional session to use for this operation
560
604
  * @param {Collection~bulkWriteOpCallback} [callback] The command result callback
561
605
  * @return {Promise} returns Promise if no callback passed
@@ -589,24 +633,24 @@ Collection.prototype.bulkWrite = function(operations, options, callback) {
589
633
 
590
634
  /**
591
635
  * @typedef {Object} Collection~insertWriteOpResult
592
- * @property {Number} insertedCount The total amount of documents inserted.
636
+ * @property {number} insertedCount The total amount of documents inserted.
593
637
  * @property {object[]} ops All the documents inserted using insertOne/insertMany/replaceOne. Documents contain the _id field if forceServerObjectId == false for insertOne/insertMany
594
638
  * @property {Object.<Number, ObjectId>} insertedIds Map of the index of the inserted document to the id of the inserted document.
595
639
  * @property {object} connection The connection object used for the operation.
596
640
  * @property {object} result The raw command result object returned from MongoDB (content might vary by server version).
597
- * @property {Number} result.ok Is 1 if the command executed correctly.
598
- * @property {Number} result.n The total count of documents inserted.
641
+ * @property {number} result.ok Is 1 if the command executed correctly.
642
+ * @property {number} result.n The total count of documents inserted.
599
643
  */
600
644
 
601
645
  /**
602
646
  * @typedef {Object} Collection~insertOneWriteOpResult
603
- * @property {Number} insertedCount The total amount of documents inserted.
647
+ * @property {number} insertedCount The total amount of documents inserted.
604
648
  * @property {object[]} ops All the documents inserted using insertOne/insertMany/replaceOne. Documents contain the _id field if forceServerObjectId == false for insertOne/insertMany
605
649
  * @property {ObjectId} insertedId The driver generated ObjectId for the insert operation.
606
650
  * @property {object} connection The connection object used for the operation.
607
651
  * @property {object} result The raw command result object returned from MongoDB (content might vary by server version).
608
- * @property {Number} result.ok Is 1 if the command executed correctly.
609
- * @property {Number} result.n The total count of documents inserted.
652
+ * @property {number} result.ok Is 1 if the command executed correctly.
653
+ * @property {number} result.n The total count of documents inserted.
610
654
  */
611
655
 
612
656
  /**
@@ -666,7 +710,7 @@ Collection.prototype.insert = deprecate(function(docs, options, callback) {
666
710
  * @property {Number} upsertedCount The number of documents upserted.
667
711
  * @property {Object} upsertedId The upserted id.
668
712
  * @property {ObjectId} upsertedId._id The upserted _id returned from the server.
669
- * @property {Object} message
713
+ * @property {Object} message The raw msg response wrapped in an internal class
670
714
  * @property {object[]} [ops] In a response to {@link Collection#replaceOne replaceOne}, contains the new value of the document on the server. This is the same document that was originally passed in, and is only here for legacy purposes.
671
715
  */
672
716
 
@@ -683,14 +727,18 @@ Collection.prototype.insert = deprecate(function(docs, options, callback) {
683
727
  * @param {object} filter The Filter used to select the document to update
684
728
  * @param {object} update The update operations to be applied to the document
685
729
  * @param {object} [options] Optional settings.
686
- * @param {boolean} [options.upsert=false] Update operation is an upsert.
730
+ * @param {Array} [options.arrayFilters] optional list of array filters referenced in filtered positional operators
731
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
732
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
733
+ * @param {object} [options.hint] An optional hint for query optimization. See the {@link https://docs.mongodb.com/manual/reference/command/update/#update-command-hint|update command} reference for more information.
734
+ * @param {boolean} [options.upsert=false] When true, creates a new document if no document matches the query..
687
735
  * @param {(number|string)} [options.w] The write concern.
688
736
  * @param {number} [options.wtimeout] The write concern timeout.
689
737
  * @param {boolean} [options.j=false] Specify a journal write concern.
690
- * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
691
- * @param {Array} [options.arrayFilters] optional list of array filters referenced in filtered positional operators
738
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
739
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
740
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
692
741
  * @param {ClientSession} [options.session] optional session to use for this operation
693
- * @param {object} [options.hint] An optional hint for query optimization. See the {@link https://docs.mongodb.com/manual/reference/command/update/#update-command-hint|update command} reference for more information.
694
742
  * @param {Collection~updateWriteOpCallback} [callback] The command result callback
695
743
  * @return {Promise} returns Promise if no callback passed
696
744
  */
@@ -723,13 +771,17 @@ Collection.prototype.updateOne = function(filter, update, options, callback) {
723
771
  * @param {object} filter The Filter used to select the document to replace
724
772
  * @param {object} doc The Document that replaces the matching document
725
773
  * @param {object} [options] Optional settings.
726
- * @param {boolean} [options.upsert=false] Update operation is an upsert.
774
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
775
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
776
+ * @param {object} [options.hint] An optional hint for query optimization. See the {@link https://docs.mongodb.com/manual/reference/command/update/#update-command-hint|update command} reference for more information.
777
+ * @param {boolean} [options.upsert=false] When true, creates a new document if no document matches the query.
727
778
  * @param {(number|string)} [options.w] The write concern.
728
779
  * @param {number} [options.wtimeout] The write concern timeout.
729
780
  * @param {boolean} [options.j=false] Specify a journal write concern.
730
- * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
781
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
782
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
783
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
731
784
  * @param {ClientSession} [options.session] optional session to use for this operation
732
- * @param {object} [options.hint] An optional hint for query optimization. See the {@link https://docs.mongodb.com/manual/reference/command/update/#update-command-hint|update command} reference for more information.
733
785
  * @param {Collection~updateWriteOpCallback} [callback] The command result callback
734
786
  * @return {Promise<Collection~updateWriteOpResult>} returns Promise if no callback passed
735
787
  */
@@ -754,13 +806,18 @@ Collection.prototype.replaceOne = function(filter, doc, options, callback) {
754
806
  * @param {object} filter The Filter used to select the documents to update
755
807
  * @param {object} update The update operations to be applied to the documents
756
808
  * @param {object} [options] Optional settings.
757
- * @param {boolean} [options.upsert=false] Update operation is an upsert.
809
+ * @param {Array} [options.arrayFilters] optional list of array filters referenced in filtered positional operators
810
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
811
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
812
+ * @param {object} [options.hint] An optional hint for query optimization. See the {@link https://docs.mongodb.com/manual/reference/command/update/#update-command-hint|update command} reference for more information.
813
+ * @param {boolean} [options.upsert=false] When true, creates a new document if no document matches the query..
758
814
  * @param {(number|string)} [options.w] The write concern.
759
815
  * @param {number} [options.wtimeout] The write concern timeout.
760
816
  * @param {boolean} [options.j=false] Specify a journal write concern.
761
- * @param {Array} [options.arrayFilters] optional list of array filters referenced in filtered positional operators
817
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
818
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
819
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
762
820
  * @param {ClientSession} [options.session] optional session to use for this operation
763
- * @param {object} [options.hint] An optional hint for query optimization. See the {@link https://docs.mongodb.com/manual/reference/command/update/#update-command-hint|update command} reference for more information.
764
821
  * @param {Collection~updateWriteOpCallback} [callback] The command result callback
765
822
  * @return {Promise<Collection~updateWriteOpResult>} returns Promise if no callback passed
766
823
  */
@@ -837,7 +894,7 @@ Collection.prototype.update = deprecate(function(selector, update, options, call
837
894
  */
838
895
 
839
896
  /**
840
- * The callback format for inserts
897
+ * The callback format for deletes
841
898
  * @callback Collection~deleteWriteOpCallback
842
899
  * @param {MongoError} error An error instance representing the error during the execution.
843
900
  * @param {Collection~deleteWriteOpResult} result The result object if the command was executed successfully.
@@ -848,9 +905,13 @@ Collection.prototype.update = deprecate(function(selector, update, options, call
848
905
  * @method
849
906
  * @param {object} filter The Filter used to select the document to remove
850
907
  * @param {object} [options] Optional settings.
908
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
851
909
  * @param {(number|string)} [options.w] The write concern.
852
910
  * @param {number} [options.wtimeout] The write concern timeout.
853
911
  * @param {boolean} [options.j=false] Specify a journal write concern.
912
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
913
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
914
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
854
915
  * @param {ClientSession} [options.session] optional session to use for this operation
855
916
  * @param {Collection~deleteWriteOpCallback} [callback] The command result callback
856
917
  * @return {Promise} returns Promise if no callback passed
@@ -877,9 +938,13 @@ Collection.prototype.removeOne = Collection.prototype.deleteOne;
877
938
  * @method
878
939
  * @param {object} filter The Filter used to select the documents to remove
879
940
  * @param {object} [options] Optional settings.
941
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
880
942
  * @param {(number|string)} [options.w] The write concern.
881
943
  * @param {number} [options.wtimeout] The write concern timeout.
882
944
  * @param {boolean} [options.j=false] Specify a journal write concern.
945
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
946
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
947
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
883
948
  * @param {ClientSession} [options.session] optional session to use for this operation
884
949
  * @param {Collection~deleteWriteOpCallback} [callback] The command result callback
885
950
  * @return {Promise} returns Promise if no callback passed
@@ -906,6 +971,7 @@ Collection.prototype.removeMany = Collection.prototype.deleteMany;
906
971
  * @method
907
972
  * @param {object} selector The selector for the update operation.
908
973
  * @param {object} [options] Optional settings.
974
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
909
975
  * @param {(number|string)} [options.w] The write concern.
910
976
  * @param {number} [options.wtimeout] The write concern timeout.
911
977
  * @param {boolean} [options.j=false] Specify a journal write concern.
@@ -1414,6 +1480,7 @@ Collection.prototype.indexInformation = function(options, callback) {
1414
1480
  * @method
1415
1481
  * @param {object} [query={}] The query for the count.
1416
1482
  * @param {object} [options] Optional settings.
1483
+ * @param {object} [options.collation] Specify collation settings for operation. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
1417
1484
  * @param {boolean} [options.limit] The limit of documents to count.
1418
1485
  * @param {boolean} [options.skip] The number of documents to skip for the count.
1419
1486
  * @param {string} [options.hint] An index name hint for the query.
@@ -1510,6 +1577,7 @@ Collection.prototype.countDocuments = function(query, options, callback) {
1510
1577
  * @param {object} [options] Optional settings.
1511
1578
  * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
1512
1579
  * @param {number} [options.maxTimeMS] Number of milliseconds to wait before aborting the query.
1580
+ * @param {object} [options.collation] Specify collation settings for operation. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
1513
1581
  * @param {ClientSession} [options.session] optional session to use for this operation
1514
1582
  * @param {Collection~resultCallback} [callback] The command result callback
1515
1583
  * @return {Promise} returns Promise if no callback passed
@@ -1582,9 +1650,13 @@ Collection.prototype.stats = function(options, callback) {
1582
1650
  * @method
1583
1651
  * @param {object} filter The Filter used to select the document to remove
1584
1652
  * @param {object} [options] Optional settings.
1653
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
1585
1654
  * @param {object} [options.projection] Limits the fields to return for all matching documents.
1586
1655
  * @param {object} [options.sort] Determines which document the operation modifies if the query selects multiple documents.
1587
1656
  * @param {number} [options.maxTimeMS] The maximum amount of time to allow the query to run.
1657
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
1658
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
1659
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
1588
1660
  * @param {ClientSession} [options.session] optional session to use for this operation
1589
1661
  * @param {Collection~findAndModifyCallback} [callback] The collection result callback
1590
1662
  * @return {Promise<Collection~findAndModifyWriteOpResultObject>} returns Promise if no callback passed
@@ -1609,11 +1681,16 @@ Collection.prototype.findOneAndDelete = function(filter, options, callback) {
1609
1681
  * @param {object} filter The Filter used to select the document to replace
1610
1682
  * @param {object} replacement The Document that replaces the matching document
1611
1683
  * @param {object} [options] Optional settings.
1684
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
1685
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
1686
+ * @param {number} [options.maxTimeMS] The maximum amount of time to allow the query to run.
1612
1687
  * @param {object} [options.projection] Limits the fields to return for all matching documents.
1613
1688
  * @param {object} [options.sort] Determines which document the operation modifies if the query selects multiple documents.
1614
- * @param {number} [options.maxTimeMS] The maximum amount of time to allow the query to run.
1615
1689
  * @param {boolean} [options.upsert=false] Upsert the document if it does not exist.
1616
1690
  * @param {boolean} [options.returnOriginal=true] When false, returns the updated document rather than the original. The default is true.
1691
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
1692
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
1693
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
1617
1694
  * @param {ClientSession} [options.session] optional session to use for this operation
1618
1695
  * @param {Collection~findAndModifyCallback} [callback] The collection result callback
1619
1696
  * @return {Promise<Collection~findAndModifyWriteOpResultObject>} returns Promise if no callback passed
@@ -1652,13 +1729,18 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options,
1652
1729
  * @param {object} filter The Filter used to select the document to update
1653
1730
  * @param {object} update Update operations to be performed on the document
1654
1731
  * @param {object} [options] Optional settings.
1732
+ * @param {Array} [options.arrayFilters] optional list of array filters referenced in filtered positional operators
1733
+ * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
1734
+ * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
1735
+ * @param {number} [options.maxTimeMS] The maximum amount of time to allow the query to run.
1655
1736
  * @param {object} [options.projection] Limits the fields to return for all matching documents.
1656
1737
  * @param {object} [options.sort] Determines which document the operation modifies if the query selects multiple documents.
1657
- * @param {number} [options.maxTimeMS] The maximum amount of time to allow the query to run.
1658
1738
  * @param {boolean} [options.upsert=false] Upsert the document if it does not exist.
1659
1739
  * @param {boolean} [options.returnOriginal=true] When false, returns the updated document rather than the original. The default is true.
1740
+ * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
1741
+ * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
1742
+ * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
1660
1743
  * @param {ClientSession} [options.session] optional session to use for this operation
1661
- * @param {Array} [options.arrayFilters] optional list of array filters referenced in filtered positional operators
1662
1744
  * @param {Collection~findAndModifyCallback} [callback] The collection result callback
1663
1745
  * @return {Promise<Collection~findAndModifyWriteOpResultObject>} returns Promise if no callback passed
1664
1746
  */
@@ -1770,11 +1852,13 @@ Collection.prototype.findAndRemove = deprecate(function(query, sort, options, ca
1770
1852
  * @param {object} [pipeline=[]] Array containing all the aggregation framework commands for the execution.
1771
1853
  * @param {object} [options] Optional settings.
1772
1854
  * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
1855
+ * @param {number} [options.batchSize=1000] The number of documents to return per batch. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
1773
1856
  * @param {object} [options.cursor] Return the query as cursor, on 2.6 > it returns as a real cursor on pre 2.6 it returns as an emulated cursor.
1774
- * @param {number} [options.cursor.batchSize=1000] The number of documents to return per batch. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
1857
+ * @param {number} [options.cursor.batchSize=1000] Deprecated. Use `options.batchSize`
1775
1858
  * @param {boolean} [options.explain=false] Explain returns the aggregation execution plan (requires mongodb 2.6 >).
1776
1859
  * @param {boolean} [options.allowDiskUse=false] allowDiskUse lets the server know if it can use disk to store temporary results for the aggregation (requires mongodb 2.6 >).
1777
1860
  * @param {number} [options.maxTimeMS] maxTimeMS specifies a cumulative time limit in milliseconds for processing operations on the cursor. MongoDB interrupts the operation at the earliest following interrupt point.
1861
+ * @param {number} [options.maxAwaitTimeMS] The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query.
1778
1862
  * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
1779
1863
  * @param {boolean} [options.raw=false] Return document results as raw BSON buffers.
1780
1864
  * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
@@ -19,7 +19,6 @@ try {
19
19
  var parsePayload = function(payload) {
20
20
  var dict = {};
21
21
  var parts = payload.split(',');
22
-
23
22
  for (var i = 0; i < parts.length; i++) {
24
23
  var valueParts = parts[i].split('=');
25
24
  dict[valueParts[0]] = valueParts[1];
@@ -105,6 +104,23 @@ function HI(data, salt, iterations, cryptoMethod) {
105
104
  return saltedData;
106
105
  }
107
106
 
107
+ function compareDigest(lhs, rhs) {
108
+ if (lhs.length !== rhs.length) {
109
+ return false;
110
+ }
111
+
112
+ if (typeof crypto.timingSafeEqual === 'function') {
113
+ return crypto.timingSafeEqual(lhs, rhs);
114
+ }
115
+
116
+ let result = 0;
117
+ for (let i = 0; i < lhs.length; i++) {
118
+ result |= lhs[i] ^ rhs[i];
119
+ }
120
+
121
+ return result === 0;
122
+ }
123
+
108
124
  /**
109
125
  * Creates a new ScramSHA authentication mechanism
110
126
  * @class
@@ -179,9 +195,19 @@ class ScramSHA extends AuthProvider {
179
195
 
180
196
  const payload = Buffer.isBuffer(r.payload) ? new Binary(r.payload) : r.payload;
181
197
  const dict = parsePayload(payload.value());
198
+
182
199
  const iterations = parseInt(dict.i, 10);
200
+ if (iterations && iterations < 4096) {
201
+ callback(new MongoError(`Server returned an invalid iteration count ${iterations}`), false);
202
+ return;
203
+ }
204
+
183
205
  const salt = dict.s;
184
206
  const rnonce = dict.r;
207
+ if (rnonce.startsWith('nonce')) {
208
+ callback(new MongoError(`Server returned an invalid nonce: ${rnonce}`), false);
209
+ return;
210
+ }
185
211
 
186
212
  // Set up start of proof
187
213
  const withoutProof = `c=biws,r=${rnonce}`;
@@ -192,18 +218,17 @@ class ScramSHA extends AuthProvider {
192
218
  cryptoMethod
193
219
  );
194
220
 
195
- if (iterations && iterations < 4096) {
196
- const error = new MongoError(`Server returned an invalid iteration count ${iterations}`);
197
- return callback(error, false);
198
- }
199
-
200
221
  const clientKey = HMAC(cryptoMethod, saltedPassword, 'Client Key');
222
+ const serverKey = HMAC(cryptoMethod, saltedPassword, 'Server Key');
201
223
  const storedKey = H(cryptoMethod, clientKey);
202
224
  const authMessage = [firstBare, payload.value().toString('base64'), withoutProof].join(',');
203
225
 
204
226
  const clientSignature = HMAC(cryptoMethod, storedKey, authMessage);
205
227
  const clientProof = `p=${xor(clientKey, clientSignature)}`;
206
228
  const clientFinal = [withoutProof, clientProof].join(',');
229
+
230
+ const serverSignature = HMAC(cryptoMethod, serverKey, authMessage);
231
+
207
232
  const saslContinueCmd = {
208
233
  saslContinue: 1,
209
234
  conversationId: r.conversationId,
@@ -211,6 +236,17 @@ class ScramSHA extends AuthProvider {
211
236
  };
212
237
 
213
238
  sendAuthCommand(connection, `${db}.$cmd`, saslContinueCmd, (err, r) => {
239
+ if (r && typeof r.ok === 'number' && r.ok === 0) {
240
+ callback(err, r);
241
+ return;
242
+ }
243
+
244
+ const parsedResponse = parsePayload(r.payload.value());
245
+ if (!compareDigest(Buffer.from(parsedResponse.v, 'base64'), serverSignature)) {
246
+ callback(new MongoError('Server returned an invalid signature'));
247
+ return;
248
+ }
249
+
214
250
  if (!r || r.done !== false) {
215
251
  return callback(err, r);
216
252
  }