mongodb 3.5.9 → 3.6.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 (73) hide show
  1. package/HISTORY.md +110 -18
  2. package/lib/admin.js +1 -0
  3. package/lib/bulk/common.js +48 -4
  4. package/lib/change_stream.js +7 -3
  5. package/lib/cmap/connection.js +9 -6
  6. package/lib/collection.js +61 -84
  7. package/lib/core/auth/auth_provider.js +29 -132
  8. package/lib/core/auth/defaultAuthProviders.js +2 -2
  9. package/lib/core/auth/gssapi.js +69 -219
  10. package/lib/core/auth/mongo_credentials.js +29 -3
  11. package/lib/core/auth/mongocr.js +6 -12
  12. package/lib/core/auth/mongodb_aws.js +256 -0
  13. package/lib/core/auth/plain.js +5 -12
  14. package/lib/core/auth/scram.js +229 -212
  15. package/lib/core/auth/x509.js +25 -16
  16. package/lib/core/connection/connect.js +97 -161
  17. package/lib/core/connection/connection.js +71 -3
  18. package/lib/core/connection/pool.js +2 -2
  19. package/lib/core/cursor.js +30 -39
  20. package/lib/core/error.js +82 -8
  21. package/lib/core/sdam/common.js +8 -0
  22. package/lib/core/sdam/monitor.js +240 -79
  23. package/lib/core/sdam/server.js +82 -17
  24. package/lib/core/sdam/server_description.js +47 -2
  25. package/lib/core/sdam/topology.js +43 -32
  26. package/lib/core/sdam/topology_description.js +21 -3
  27. package/lib/core/sessions.js +14 -16
  28. package/lib/core/topologies/mongos.js +18 -6
  29. package/lib/core/topologies/read_preference.js +71 -7
  30. package/lib/core/topologies/replset.js +4 -4
  31. package/lib/core/topologies/server.js +1 -1
  32. package/lib/core/topologies/shared.js +39 -16
  33. package/lib/core/uri_parser.js +41 -6
  34. package/lib/core/utils.js +30 -0
  35. package/lib/core/wireprotocol/command.js +2 -10
  36. package/lib/core/wireprotocol/constants.js +2 -2
  37. package/lib/core/wireprotocol/query.js +4 -0
  38. package/lib/cursor.js +0 -1
  39. package/lib/db.js +7 -6
  40. package/lib/error.js +6 -1
  41. package/lib/gridfs-stream/download.js +13 -2
  42. package/lib/mongo_client.js +6 -4
  43. package/lib/operations/collection_ops.js +1 -22
  44. package/lib/operations/command.js +2 -3
  45. package/lib/operations/command_v2.js +8 -7
  46. package/lib/operations/common_functions.js +3 -0
  47. package/lib/operations/connect.js +11 -14
  48. package/lib/operations/create_collection.js +37 -52
  49. package/lib/operations/create_indexes.js +91 -35
  50. package/lib/operations/db_ops.js +1 -2
  51. package/lib/operations/find.js +9 -3
  52. package/lib/operations/find_and_modify.js +17 -0
  53. package/lib/operations/find_one_and_delete.js +5 -0
  54. package/lib/operations/find_one_and_replace.js +13 -0
  55. package/lib/operations/find_one_and_update.js +13 -0
  56. package/lib/operations/geo_haystack_search.js +2 -2
  57. package/lib/operations/map_reduce.js +3 -3
  58. package/lib/operations/operation.js +2 -1
  59. package/lib/operations/re_index.js +22 -17
  60. package/lib/operations/replace_one.js +11 -4
  61. package/lib/operations/run_command.js +19 -0
  62. package/lib/operations/update_many.js +5 -0
  63. package/lib/operations/update_one.js +5 -0
  64. package/lib/operations/validate_collection.js +1 -2
  65. package/lib/topologies/mongos.js +1 -1
  66. package/lib/topologies/replset.js +1 -1
  67. package/lib/topologies/server.js +1 -1
  68. package/lib/topologies/topology_base.js +4 -4
  69. package/lib/utils.js +18 -60
  70. package/lib/write_concern.js +10 -0
  71. package/package.json +2 -2
  72. package/lib/core/auth/sspi.js +0 -131
  73. package/lib/operations/create_index.js +0 -92
package/lib/collection.js CHANGED
@@ -5,7 +5,6 @@ const deprecateOptions = require('./utils').deprecateOptions;
5
5
  const checkCollectionName = require('./utils').checkCollectionName;
6
6
  const ObjectID = require('./core').BSON.ObjectID;
7
7
  const MongoError = require('./core').MongoError;
8
- const toError = require('./utils').toError;
9
8
  const normalizeHintField = require('./utils').normalizeHintField;
10
9
  const decorateCommand = require('./utils').decorateCommand;
11
10
  const decorateWithCollation = require('./utils').decorateWithCollation;
@@ -16,7 +15,6 @@ const unordered = require('./bulk/unordered');
16
15
  const ordered = require('./bulk/ordered');
17
16
  const ChangeStream = require('./change_stream');
18
17
  const executeLegacyOperation = require('./utils').executeLegacyOperation;
19
- const resolveReadPreference = require('./utils').resolveReadPreference;
20
18
  const WriteConcern = require('./write_concern');
21
19
  const ReadConcern = require('./read_concern');
22
20
  const MongoDBNamespace = require('./utils').MongoDBNamespace;
@@ -24,7 +22,6 @@ const AggregationCursor = require('./aggregation_cursor');
24
22
  const CommandCursor = require('./command_cursor');
25
23
 
26
24
  // Operations
27
- const checkForAtomicOperators = require('./operations/collection_ops').checkForAtomicOperators;
28
25
  const ensureIndex = require('./operations/collection_ops').ensureIndex;
29
26
  const group = require('./operations/collection_ops').group;
30
27
  const parallelCollectionScan = require('./operations/collection_ops').parallelCollectionScan;
@@ -35,7 +32,6 @@ const updateDocuments = require('./operations/common_functions').updateDocuments
35
32
  const AggregateOperation = require('./operations/aggregate');
36
33
  const BulkWriteOperation = require('./operations/bulk_write');
37
34
  const CountDocumentsOperation = require('./operations/count_documents');
38
- const CreateIndexOperation = require('./operations/create_index');
39
35
  const CreateIndexesOperation = require('./operations/create_indexes');
40
36
  const DeleteManyOperation = require('./operations/delete_many');
41
37
  const DeleteOneOperation = require('./operations/delete_one');
@@ -278,7 +274,7 @@ Object.defineProperty(Collection.prototype, 'hint', {
278
274
  }
279
275
  });
280
276
 
281
- const DEPRECATED_FIND_OPTIONS = ['maxScan', 'fields', 'snapshot'];
277
+ const DEPRECATED_FIND_OPTIONS = ['maxScan', 'fields', 'snapshot', 'oplogReplay'];
282
278
 
283
279
  /**
284
280
  * Creates a cursor for a query that can be used to iterate over results from MongoDB
@@ -313,6 +309,7 @@ const DEPRECATED_FIND_OPTIONS = ['maxScan', 'fields', 'snapshot'];
313
309
  * @param {number} [options.maxAwaitTimeMS] The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Requires `tailable` and `awaitData` to be true
314
310
  * @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.
315
311
  * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
312
+ * @param {boolean} [options.allowDiskUse] Enables writing to temporary files on the server.
316
313
  * @param {ClientSession} [options.session] optional session to use for this operation
317
314
  * @throws {MongoError}
318
315
  * @return {Cursor}
@@ -399,7 +396,7 @@ Collection.prototype.find = deprecateOptions(
399
396
  newOptions.slaveOk = options.slaveOk != null ? options.slaveOk : this.s.db.slaveOk;
400
397
 
401
398
  // Add read preference if needed
402
- newOptions.readPreference = resolveReadPreference(this, newOptions);
399
+ newOptions.readPreference = ReadPreference.resolve(this, newOptions);
403
400
 
404
401
  // Set slave ok to true if read preference different from primary
405
402
  if (
@@ -422,6 +419,10 @@ Collection.prototype.find = deprecateOptions(
422
419
  query: selector
423
420
  };
424
421
 
422
+ if (typeof options.allowDiskUse === 'boolean') {
423
+ findCommand.allowDiskUse = options.allowDiskUse;
424
+ }
425
+
425
426
  // Ensure we use the right await data option
426
427
  if (typeof newOptions.awaitdata === 'boolean') {
427
428
  newOptions.awaitData = newOptions.awaitdata;
@@ -744,14 +745,6 @@ Collection.prototype.insert = deprecate(function(docs, options, callback) {
744
745
  */
745
746
  Collection.prototype.updateOne = function(filter, update, options, callback) {
746
747
  if (typeof options === 'function') (callback = options), (options = {});
747
- options = options || {};
748
-
749
- const err = checkForAtomicOperators(update);
750
- if (err) {
751
- if (typeof callback === 'function') return callback(err);
752
- return this.s.promiseLibrary.reject(err);
753
- }
754
-
755
748
  options = Object.assign({}, options);
756
749
 
757
750
  // Add ignoreUndefined
@@ -760,9 +753,11 @@ Collection.prototype.updateOne = function(filter, update, options, callback) {
760
753
  options.ignoreUndefined = this.s.options.ignoreUndefined;
761
754
  }
762
755
 
763
- const updateOneOperation = new UpdateOneOperation(this, filter, update, options);
764
-
765
- return executeOperation(this.s.topology, updateOneOperation, callback);
756
+ return executeOperation(
757
+ this.s.topology,
758
+ new UpdateOneOperation(this, filter, update, options),
759
+ callback
760
+ );
766
761
  };
767
762
 
768
763
  /**
@@ -795,9 +790,11 @@ Collection.prototype.replaceOne = function(filter, doc, options, callback) {
795
790
  options.ignoreUndefined = this.s.options.ignoreUndefined;
796
791
  }
797
792
 
798
- const replaceOneOperation = new ReplaceOneOperation(this, filter, doc, options);
799
-
800
- return executeOperation(this.s.topology, replaceOneOperation, callback);
793
+ return executeOperation(
794
+ this.s.topology,
795
+ new ReplaceOneOperation(this, filter, doc, options),
796
+ callback
797
+ );
801
798
  };
802
799
 
803
800
  /**
@@ -823,14 +820,6 @@ Collection.prototype.replaceOne = function(filter, doc, options, callback) {
823
820
  */
824
821
  Collection.prototype.updateMany = function(filter, update, options, callback) {
825
822
  if (typeof options === 'function') (callback = options), (options = {});
826
- options = options || {};
827
-
828
- const err = checkForAtomicOperators(update);
829
- if (err) {
830
- if (typeof callback === 'function') return callback(err);
831
- return this.s.promiseLibrary.reject(err);
832
- }
833
-
834
823
  options = Object.assign({}, options);
835
824
 
836
825
  // Add ignoreUndefined
@@ -839,9 +828,11 @@ Collection.prototype.updateMany = function(filter, update, options, callback) {
839
828
  options.ignoreUndefined = this.s.options.ignoreUndefined;
840
829
  }
841
830
 
842
- const updateManyOperation = new UpdateManyOperation(this, filter, update, options);
843
-
844
- return executeOperation(this.s.topology, updateManyOperation, callback);
831
+ return executeOperation(
832
+ this.s.topology,
833
+ new UpdateManyOperation(this, filter, update, options),
834
+ callback
835
+ );
845
836
  };
846
837
 
847
838
  /**
@@ -913,6 +904,7 @@ Collection.prototype.update = deprecate(function(selector, update, options, call
913
904
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
914
905
  * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
915
906
  * @param {ClientSession} [options.session] optional session to use for this operation
907
+ * @param {string|object} [options.hint] optional index hint for optimizing the filter query
916
908
  * @param {Collection~deleteWriteOpCallback} [callback] The command result callback
917
909
  * @return {Promise} returns Promise if no callback passed
918
910
  */
@@ -946,6 +938,7 @@ Collection.prototype.removeOne = Collection.prototype.deleteOne;
946
938
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
947
939
  * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
948
940
  * @param {ClientSession} [options.session] optional session to use for this operation
941
+ * @param {string|object} [options.hint] optional index hint for optimizing the filter query
949
942
  * @param {Collection~deleteWriteOpCallback} [callback] The command result callback
950
943
  * @return {Promise} returns Promise if no callback passed
951
944
  */
@@ -1206,6 +1199,7 @@ Collection.prototype.isCapped = function(options, callback) {
1206
1199
  * @param {object} [options.partialFilterExpression] Creates a partial index based on the given filter object (MongoDB 3.2 or higher)
1207
1200
  * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
1208
1201
  * @param {ClientSession} [options.session] optional session to use for this operation
1202
+ * @param {(number|string)} [options.commitQuorum] (MongoDB 4.4. or higher) Specifies how many data-bearing members of a replica set, including the primary, must complete the index builds successfully before the primary marks the indexes as ready. This option accepts the same values for the "w" field in a write concern plus "votingMembers", which indicates all voting data-bearing nodes.
1209
1203
  * @param {Collection~resultCallback} [callback] The command result callback
1210
1204
  * @return {Promise} returns Promise if no callback passed
1211
1205
  * @example
@@ -1232,14 +1226,14 @@ Collection.prototype.createIndex = function(fieldOrSpec, options, callback) {
1232
1226
  if (typeof options === 'function') (callback = options), (options = {});
1233
1227
  options = options || {};
1234
1228
 
1235
- const createIndexOperation = new CreateIndexOperation(
1236
- this.s.db,
1229
+ const createIndexesOperation = new CreateIndexesOperation(
1230
+ this,
1237
1231
  this.collectionName,
1238
1232
  fieldOrSpec,
1239
1233
  options
1240
1234
  );
1241
1235
 
1242
- return executeOperation(this.s.topology, createIndexOperation, callback);
1236
+ return executeOperation(this.s.topology, createIndexesOperation, callback);
1243
1237
  };
1244
1238
 
1245
1239
  /**
@@ -1260,6 +1254,7 @@ Collection.prototype.createIndex = function(fieldOrSpec, options, callback) {
1260
1254
  * @param {Collection~IndexDefinition[]} indexSpecs An array of index specifications to be created
1261
1255
  * @param {Object} [options] Optional settings
1262
1256
  * @param {ClientSession} [options.session] optional session to use for this operation
1257
+ * @param {(number|string)} [options.commitQuorum] (MongoDB 4.4. or higher) Specifies how many data-bearing members of a replica set, including the primary, must complete the index builds successfully before the primary marks the indexes as ready. This option accepts the same values for the "w" field in a write concern plus "votingMembers", which indicates all voting data-bearing nodes.
1263
1258
  * @param {Collection~resultCallback} [callback] The command result callback
1264
1259
  * @return {Promise} returns Promise if no callback passed
1265
1260
  * @example
@@ -1284,9 +1279,15 @@ Collection.prototype.createIndexes = function(indexSpecs, options, callback) {
1284
1279
  if (typeof options === 'function') (callback = options), (options = {});
1285
1280
 
1286
1281
  options = options ? Object.assign({}, options) : {};
1282
+
1287
1283
  if (typeof options.maxTimeMS !== 'number') delete options.maxTimeMS;
1288
1284
 
1289
- const createIndexesOperation = new CreateIndexesOperation(this, indexSpecs, options);
1285
+ const createIndexesOperation = new CreateIndexesOperation(
1286
+ this,
1287
+ this.collectionName,
1288
+ indexSpecs,
1289
+ options
1290
+ );
1290
1291
 
1291
1292
  return executeOperation(this.s.topology, createIndexesOperation, callback);
1292
1293
  };
@@ -1353,19 +1354,20 @@ Collection.prototype.dropAllIndexes = deprecate(
1353
1354
  * Reindex all indexes on the collection
1354
1355
  * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
1355
1356
  * @method
1357
+ * @deprecated use db.command instead
1356
1358
  * @param {Object} [options] Optional settings
1357
1359
  * @param {ClientSession} [options.session] optional session to use for this operation
1358
1360
  * @param {Collection~resultCallback} [callback] The command result callback
1359
1361
  * @return {Promise} returns Promise if no callback passed
1360
1362
  */
1361
- Collection.prototype.reIndex = function(options, callback) {
1363
+ Collection.prototype.reIndex = deprecate(function(options, callback) {
1362
1364
  if (typeof options === 'function') (callback = options), (options = {});
1363
1365
  options = options || {};
1364
1366
 
1365
1367
  const reIndexOperation = new ReIndexOperation(this, options);
1366
1368
 
1367
1369
  return executeOperation(this.s.topology, reIndexOperation, callback);
1368
- };
1370
+ }, 'collection.reIndex is deprecated. Use db.command instead.');
1369
1371
 
1370
1372
  /**
1371
1373
  * Get the list of all indexes information for the collection.
@@ -1665,13 +1667,11 @@ Collection.prototype.findOneAndDelete = function(filter, options, callback) {
1665
1667
  if (typeof options === 'function') (callback = options), (options = {});
1666
1668
  options = options || {};
1667
1669
 
1668
- // Basic validation
1669
- if (filter == null || typeof filter !== 'object')
1670
- throw toError('filter parameter must be an object');
1671
-
1672
- const findOneAndDeleteOperation = new FindOneAndDeleteOperation(this, filter, options);
1673
-
1674
- return executeOperation(this.s.topology, findOneAndDeleteOperation, callback);
1670
+ return executeOperation(
1671
+ this.s.topology,
1672
+ new FindOneAndDeleteOperation(this, filter, options),
1673
+ callback
1674
+ );
1675
1675
  };
1676
1676
 
1677
1677
  /**
@@ -1683,6 +1683,7 @@ Collection.prototype.findOneAndDelete = function(filter, options, callback) {
1683
1683
  * @param {object} [options] Optional settings.
1684
1684
  * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
1685
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 {string|object} [options.hint] An optional index to use for this operation
1686
1687
  * @param {number} [options.maxTimeMS] The maximum amount of time to allow the query to run.
1687
1688
  * @param {object} [options.projection] Limits the fields to return for all matching documents.
1688
1689
  * @param {object} [options.sort] Determines which document the operation modifies if the query selects multiple documents.
@@ -1699,27 +1700,11 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options,
1699
1700
  if (typeof options === 'function') (callback = options), (options = {});
1700
1701
  options = options || {};
1701
1702
 
1702
- // Basic validation
1703
- if (filter == null || typeof filter !== 'object')
1704
- throw toError('filter parameter must be an object');
1705
- if (replacement == null || typeof replacement !== 'object')
1706
- throw toError('replacement parameter must be an object');
1707
-
1708
- // Check that there are no atomic operators
1709
- const keys = Object.keys(replacement);
1710
-
1711
- if (keys[0] && keys[0][0] === '$') {
1712
- throw toError('The replacement document must not contain atomic operators.');
1713
- }
1714
-
1715
- const findOneAndReplaceOperation = new FindOneAndReplaceOperation(
1716
- this,
1717
- filter,
1718
- replacement,
1719
- options
1703
+ return executeOperation(
1704
+ this.s.topology,
1705
+ new FindOneAndReplaceOperation(this, filter, replacement, options),
1706
+ callback
1720
1707
  );
1721
-
1722
- return executeOperation(this.s.topology, findOneAndReplaceOperation, callback);
1723
1708
  };
1724
1709
 
1725
1710
  /**
@@ -1732,6 +1717,7 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options,
1732
1717
  * @param {Array} [options.arrayFilters] optional list of array filters referenced in filtered positional operators
1733
1718
  * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
1734
1719
  * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
1720
+ * @param {string|object} [options.hint] An optional index to use for this operation
1735
1721
  * @param {number} [options.maxTimeMS] The maximum amount of time to allow the query to run.
1736
1722
  * @param {object} [options.projection] Limits the fields to return for all matching documents.
1737
1723
  * @param {object} [options.sort] Determines which document the operation modifies if the query selects multiple documents.
@@ -1740,7 +1726,7 @@ Collection.prototype.findOneAndReplace = function(filter, replacement, options,
1740
1726
  * @param {boolean} [options.checkKeys=false] If true, will throw if bson documents start with `$` or include a `.` in any key value
1741
1727
  * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
1742
1728
  * @param {boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
1743
- * @param {ClientSession} [options.session] optional session to use for this operation
1729
+ * @param {ClientSession} [options.session] An ptional session to use for this operation
1744
1730
  * @param {Collection~findAndModifyCallback} [callback] The collection result callback
1745
1731
  * @return {Promise<Collection~findAndModifyWriteOpResultObject>} returns Promise if no callback passed
1746
1732
  */
@@ -1748,21 +1734,11 @@ Collection.prototype.findOneAndUpdate = function(filter, update, options, callba
1748
1734
  if (typeof options === 'function') (callback = options), (options = {});
1749
1735
  options = options || {};
1750
1736
 
1751
- // Basic validation
1752
- if (filter == null || typeof filter !== 'object')
1753
- throw toError('filter parameter must be an object');
1754
- if (update == null || typeof update !== 'object')
1755
- throw toError('update parameter must be an object');
1756
-
1757
- const err = checkForAtomicOperators(update);
1758
- if (err) {
1759
- if (typeof callback === 'function') return callback(err);
1760
- return this.s.promiseLibrary.reject(err);
1761
- }
1762
-
1763
- const findOneAndUpdateOperation = new FindOneAndUpdateOperation(this, filter, update, options);
1764
-
1765
- return executeOperation(this.s.topology, findOneAndUpdateOperation, callback);
1737
+ return executeOperation(
1738
+ this.s.topology,
1739
+ new FindOneAndUpdateOperation(this, filter, update, options),
1740
+ callback
1741
+ );
1766
1742
  };
1767
1743
 
1768
1744
  /**
@@ -1864,7 +1840,7 @@ Collection.prototype.findAndRemove = deprecate(function(query, sort, options, ca
1864
1840
  * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
1865
1841
  * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
1866
1842
  * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
1867
- * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
1843
+ * @param {object} [options.collation] Specify collation settings for operation. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
1868
1844
  * @param {string} [options.comment] Add a comment to an aggregation command
1869
1845
  * @param {string|object} [options.hint] Add an index selection hint to an aggregation command
1870
1846
  * @param {ClientSession} [options.session] optional session to use for this operation
@@ -1978,7 +1954,7 @@ Collection.prototype.parallelCollectionScan = deprecate(function(options, callba
1978
1954
 
1979
1955
  options = Object.assign({}, options);
1980
1956
  // Ensure we have the right read preference inheritance
1981
- options.readPreference = resolveReadPreference(this, options);
1957
+ options.readPreference = ReadPreference.resolve(this, options);
1982
1958
 
1983
1959
  // Add a promiseLibrary
1984
1960
  options.promiseLibrary = this.s.promiseLibrary;
@@ -2009,8 +1985,9 @@ Collection.prototype.parallelCollectionScan = deprecate(function(options, callba
2009
1985
  * @param {ClientSession} [options.session] optional session to use for this operation
2010
1986
  * @param {Collection~resultCallback} [callback] The command result callback
2011
1987
  * @return {Promise} returns Promise if no callback passed
1988
+ * @deprecated See {@link https://docs.mongodb.com/manual/geospatial-queries/|geospatial queries docs} for current geospatial support
2012
1989
  */
2013
- Collection.prototype.geoHaystackSearch = function(x, y, options, callback) {
1990
+ Collection.prototype.geoHaystackSearch = deprecate(function(x, y, options, callback) {
2014
1991
  const args = Array.prototype.slice.call(arguments, 2);
2015
1992
  callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
2016
1993
  options = args.length ? args.shift() || {} : {};
@@ -2018,7 +1995,7 @@ Collection.prototype.geoHaystackSearch = function(x, y, options, callback) {
2018
1995
  const geoHaystackSearchOperation = new GeoHaystackSearchOperation(this, x, y, options);
2019
1996
 
2020
1997
  return executeOperation(this.s.topology, geoHaystackSearchOperation, callback);
2021
- };
1998
+ }, 'geoHaystackSearch is deprecated, and will be removed in a future version.');
2022
1999
 
2023
2000
  /**
2024
2001
  * Run a group command across a collection
@@ -1,158 +1,55 @@
1
1
  'use strict';
2
2
 
3
- const MongoError = require('../error').MongoError;
4
-
5
3
  /**
6
- * Creates a new AuthProvider, which dictates how to authenticate for a given
7
- * mechanism.
8
- * @class
4
+ * Context used during authentication
5
+ *
6
+ * @property {Connection} connection The connection to authenticate
7
+ * @property {MongoCredentials} credentials The credentials to use for authentication
8
+ * @property {object} options The options passed to the `connect` method
9
+ * @property {object?} response The response of the initial handshake
10
+ * @property {Buffer?} nonce A random nonce generated for use in an authentication conversation
9
11
  */
12
+ class AuthContext {
13
+ constructor(connection, credentials, options) {
14
+ this.connection = connection;
15
+ this.credentials = credentials;
16
+ this.options = options;
17
+ }
18
+ }
19
+
10
20
  class AuthProvider {
11
21
  constructor(bson) {
12
22
  this.bson = bson;
13
- this.authStore = [];
14
- }
15
-
16
- /**
17
- * Authenticate
18
- * @method
19
- * @param {SendAuthCommand} sendAuthCommand Writes an auth command directly to a specific connection
20
- * @param {Connection[]} connections Connections to authenticate using this authenticator
21
- * @param {MongoCredentials} credentials Authentication credentials
22
- * @param {authResultCallback} callback The callback to return the result from the authentication
23
- */
24
- auth(sendAuthCommand, connections, credentials, callback) {
25
- // Total connections
26
- let count = connections.length;
27
-
28
- if (count === 0) {
29
- callback(null, null);
30
- return;
31
- }
32
-
33
- // Valid connections
34
- let numberOfValidConnections = 0;
35
- let errorObject = null;
36
-
37
- const execute = connection => {
38
- this._authenticateSingleConnection(sendAuthCommand, connection, credentials, (err, r) => {
39
- // Adjust count
40
- count = count - 1;
41
-
42
- // If we have an error
43
- if (err) {
44
- errorObject = new MongoError(err);
45
- } else if (r && (r.$err || r.errmsg)) {
46
- errorObject = new MongoError(r);
47
- } else {
48
- numberOfValidConnections = numberOfValidConnections + 1;
49
- }
50
-
51
- // Still authenticating against other connections.
52
- if (count !== 0) {
53
- return;
54
- }
55
-
56
- // We have authenticated all connections
57
- if (numberOfValidConnections > 0) {
58
- // Store the auth details
59
- this.addCredentials(credentials);
60
- // Return correct authentication
61
- callback(null, true);
62
- } else {
63
- if (errorObject == null) {
64
- errorObject = new MongoError(`failed to authenticate using ${credentials.mechanism}`);
65
- }
66
- callback(errorObject, false);
67
- }
68
- });
69
- };
70
-
71
- const executeInNextTick = _connection => process.nextTick(() => execute(_connection));
72
-
73
- // For each connection we need to authenticate
74
- while (connections.length > 0) {
75
- executeInNextTick(connections.shift());
76
- }
77
23
  }
78
24
 
79
25
  /**
80
- * Implementation of a single connection authenticating. Is meant to be overridden.
81
- * Will error if called directly
82
- * @ignore
26
+ * Prepare the handshake document before the initial handshake.
27
+ *
28
+ * @param {object} handshakeDoc The document used for the initial handshake on a connection
29
+ * @param {AuthContext} authContext Context for authentication flow
30
+ * @param {function} callback
83
31
  */
84
- _authenticateSingleConnection(/*sendAuthCommand, connection, credentials, callback*/) {
85
- throw new Error('_authenticateSingleConnection must be overridden');
32
+ prepare(handshakeDoc, context, callback) {
33
+ callback(undefined, handshakeDoc);
86
34
  }
87
35
 
88
36
  /**
89
- * Adds credentials to store only if it does not exist
90
- * @param {MongoCredentials} credentials credentials to add to store
91
- */
92
- addCredentials(credentials) {
93
- const found = this.authStore.some(cred => cred.equals(credentials));
94
-
95
- if (!found) {
96
- this.authStore.push(credentials);
97
- }
98
- }
99
-
100
- /**
101
- * Re authenticate pool
102
- * @method
103
- * @param {SendAuthCommand} sendAuthCommand Writes an auth command directly to a specific connection
104
- * @param {Connection[]} connections Connections to authenticate using this authenticator
37
+ * Authenticate
38
+ *
39
+ * @param {AuthContext} context A shared context for authentication flow
105
40
  * @param {authResultCallback} callback The callback to return the result from the authentication
106
41
  */
107
- reauthenticate(sendAuthCommand, connections, callback) {
108
- const authStore = this.authStore.slice(0);
109
- let count = authStore.length;
110
- if (count === 0) {
111
- return callback(null, null);
112
- }
113
-
114
- for (let i = 0; i < authStore.length; i++) {
115
- this.auth(sendAuthCommand, connections, authStore[i], function(err) {
116
- count = count - 1;
117
- if (count === 0) {
118
- callback(err, null);
119
- }
120
- });
121
- }
122
- }
123
-
124
- /**
125
- * Remove credentials that have been previously stored in the auth provider
126
- * @method
127
- * @param {string} source Name of database we are removing authStore details about
128
- * @return {object}
129
- */
130
- logout(source) {
131
- this.authStore = this.authStore.filter(credentials => credentials.source !== source);
42
+ auth(context, callback) {
43
+ callback(new TypeError('`auth` method must be overridden by subclass'));
132
44
  }
133
45
  }
134
46
 
135
47
  /**
136
- * A function that writes authentication commands to a specific connection
137
- * @callback SendAuthCommand
138
- * @param {Connection} connection The connection to write to
139
- * @param {Command} command A command with a toBin method that can be written to a connection
140
- * @param {AuthWriteCallback} callback Callback called when command response is received
141
- */
142
-
143
- /**
144
- * A callback for a specific auth command
145
- * @callback AuthWriteCallback
146
- * @param {Error} err If command failed, an error from the server
147
- * @param {object} r The response from the server
148
- */
149
-
150
- /**
151
- * This is a result from an authentication strategy
48
+ * This is a result from an authentication provider
152
49
  *
153
50
  * @callback authResultCallback
154
51
  * @param {error} error An error object. Set to null if no error present
155
52
  * @param {boolean} result The result of the authentication process
156
53
  */
157
54
 
158
- module.exports = { AuthProvider };
55
+ module.exports = { AuthContext, AuthProvider };
@@ -4,9 +4,9 @@ const MongoCR = require('./mongocr');
4
4
  const X509 = require('./x509');
5
5
  const Plain = require('./plain');
6
6
  const GSSAPI = require('./gssapi');
7
- const SSPI = require('./sspi');
8
7
  const ScramSHA1 = require('./scram').ScramSHA1;
9
8
  const ScramSHA256 = require('./scram').ScramSHA256;
9
+ const MongoDBAWS = require('./mongodb_aws');
10
10
 
11
11
  /**
12
12
  * Returns the default authentication providers.
@@ -16,11 +16,11 @@ const ScramSHA256 = require('./scram').ScramSHA256;
16
16
  */
17
17
  function defaultAuthProviders(bson) {
18
18
  return {
19
+ 'mongodb-aws': new MongoDBAWS(bson),
19
20
  mongocr: new MongoCR(bson),
20
21
  x509: new X509(bson),
21
22
  plain: new Plain(bson),
22
23
  gssapi: new GSSAPI(bson),
23
- sspi: new SSPI(bson),
24
24
  'scram-sha-1': new ScramSHA1(bson),
25
25
  'scram-sha-256': new ScramSHA256(bson)
26
26
  };