mongodb 4.0.0 → 4.1.2

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 (246) hide show
  1. package/README.md +62 -30
  2. package/lib/bson.js +1 -0
  3. package/lib/bson.js.map +1 -1
  4. package/lib/bulk/common.js +53 -30
  5. package/lib/bulk/common.js.map +1 -1
  6. package/lib/bulk/ordered.js +3 -2
  7. package/lib/bulk/ordered.js.map +1 -1
  8. package/lib/bulk/unordered.js +3 -2
  9. package/lib/bulk/unordered.js.map +1 -1
  10. package/lib/change_stream.js +23 -13
  11. package/lib/change_stream.js.map +1 -1
  12. package/lib/cmap/auth/auth_provider.js +2 -1
  13. package/lib/cmap/auth/auth_provider.js.map +1 -1
  14. package/lib/cmap/auth/gssapi.js +5 -4
  15. package/lib/cmap/auth/gssapi.js.map +1 -1
  16. package/lib/cmap/auth/mongo_credentials.js +9 -5
  17. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  18. package/lib/cmap/auth/mongocr.js +2 -2
  19. package/lib/cmap/auth/mongocr.js.map +1 -1
  20. package/lib/cmap/auth/mongodb_aws.js +32 -32
  21. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  22. package/lib/cmap/auth/plain.js +1 -1
  23. package/lib/cmap/auth/plain.js.map +1 -1
  24. package/lib/cmap/auth/scram.js +15 -12
  25. package/lib/cmap/auth/scram.js.map +1 -1
  26. package/lib/cmap/auth/x509.js +2 -2
  27. package/lib/cmap/auth/x509.js.map +1 -1
  28. package/lib/cmap/command_monitoring_events.js +26 -10
  29. package/lib/cmap/command_monitoring_events.js.map +1 -1
  30. package/lib/cmap/commands.js +9 -5
  31. package/lib/cmap/commands.js.map +1 -1
  32. package/lib/cmap/connect.js +23 -9
  33. package/lib/cmap/connect.js.map +1 -1
  34. package/lib/cmap/connection.js +43 -46
  35. package/lib/cmap/connection.js.map +1 -1
  36. package/lib/cmap/connection_pool.js +113 -15
  37. package/lib/cmap/connection_pool.js.map +1 -1
  38. package/lib/cmap/connection_pool_events.js +3 -1
  39. package/lib/cmap/connection_pool_events.js.map +1 -1
  40. package/lib/cmap/errors.js +3 -3
  41. package/lib/cmap/errors.js.map +1 -1
  42. package/lib/cmap/message_stream.js +1 -1
  43. package/lib/cmap/message_stream.js.map +1 -1
  44. package/lib/cmap/metrics.js +62 -0
  45. package/lib/cmap/metrics.js.map +1 -0
  46. package/lib/cmap/stream_description.js +3 -1
  47. package/lib/cmap/stream_description.js.map +1 -1
  48. package/lib/cmap/wire_protocol/compression.js +22 -9
  49. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  50. package/lib/cmap/wire_protocol/shared.js +1 -1
  51. package/lib/cmap/wire_protocol/shared.js.map +1 -1
  52. package/lib/collection.js +23 -18
  53. package/lib/collection.js.map +1 -1
  54. package/lib/connection_string.js +76 -30
  55. package/lib/connection_string.js.map +1 -1
  56. package/lib/cursor/abstract_cursor.js +75 -68
  57. package/lib/cursor/abstract_cursor.js.map +1 -1
  58. package/lib/cursor/aggregation_cursor.js +47 -9
  59. package/lib/cursor/aggregation_cursor.js.map +1 -1
  60. package/lib/cursor/find_cursor.js +53 -13
  61. package/lib/cursor/find_cursor.js.map +1 -1
  62. package/lib/db.js +21 -14
  63. package/lib/db.js.map +1 -1
  64. package/lib/deps.js +16 -5
  65. package/lib/deps.js.map +1 -1
  66. package/lib/encrypter.js +5 -8
  67. package/lib/encrypter.js.map +1 -1
  68. package/lib/error.js +230 -34
  69. package/lib/error.js.map +1 -1
  70. package/lib/explain.js +2 -2
  71. package/lib/explain.js.map +1 -1
  72. package/lib/gridfs/download.js +22 -47
  73. package/lib/gridfs/download.js.map +1 -1
  74. package/lib/gridfs/index.js +4 -3
  75. package/lib/gridfs/index.js.map +1 -1
  76. package/lib/gridfs/upload.js +13 -21
  77. package/lib/gridfs/upload.js.map +1 -1
  78. package/lib/index.js +27 -2
  79. package/lib/index.js.map +1 -1
  80. package/lib/logger.js +3 -2
  81. package/lib/logger.js.map +1 -1
  82. package/lib/mongo_client.js +5 -8
  83. package/lib/mongo_client.js.map +1 -1
  84. package/lib/mongo_types.js.map +1 -1
  85. package/lib/operations/add_user.js +2 -3
  86. package/lib/operations/add_user.js.map +1 -1
  87. package/lib/operations/aggregate.js +12 -9
  88. package/lib/operations/aggregate.js.map +1 -1
  89. package/lib/operations/command.js +5 -7
  90. package/lib/operations/command.js.map +1 -1
  91. package/lib/operations/common_functions.js +1 -1
  92. package/lib/operations/common_functions.js.map +1 -1
  93. package/lib/operations/connect.js +3 -2
  94. package/lib/operations/connect.js.map +1 -1
  95. package/lib/operations/count.js +1 -1
  96. package/lib/operations/count.js.map +1 -1
  97. package/lib/operations/count_documents.js +1 -1
  98. package/lib/operations/count_documents.js.map +1 -1
  99. package/lib/operations/delete.js +5 -5
  100. package/lib/operations/delete.js.map +1 -1
  101. package/lib/operations/distinct.js +2 -2
  102. package/lib/operations/distinct.js.map +1 -1
  103. package/lib/operations/estimated_document_count.js +5 -1
  104. package/lib/operations/estimated_document_count.js.map +1 -1
  105. package/lib/operations/eval.js.map +1 -1
  106. package/lib/operations/execute_operation.js +31 -17
  107. package/lib/operations/execute_operation.js.map +1 -1
  108. package/lib/operations/find.js +13 -9
  109. package/lib/operations/find.js.map +1 -1
  110. package/lib/operations/find_and_modify.js +9 -9
  111. package/lib/operations/find_and_modify.js.map +1 -1
  112. package/lib/operations/indexes.js +8 -3
  113. package/lib/operations/indexes.js.map +1 -1
  114. package/lib/operations/insert.js +5 -3
  115. package/lib/operations/insert.js.map +1 -1
  116. package/lib/operations/is_capped.js +2 -1
  117. package/lib/operations/is_capped.js.map +1 -1
  118. package/lib/operations/list_collections.js +6 -3
  119. package/lib/operations/list_collections.js.map +1 -1
  120. package/lib/operations/map_reduce.js +1 -1
  121. package/lib/operations/map_reduce.js.map +1 -1
  122. package/lib/operations/operation.js +3 -1
  123. package/lib/operations/operation.js.map +1 -1
  124. package/lib/operations/options_operation.js +2 -1
  125. package/lib/operations/options_operation.js.map +1 -1
  126. package/lib/operations/profiling_level.js +4 -2
  127. package/lib/operations/profiling_level.js.map +1 -1
  128. package/lib/operations/set_profiling_level.js +4 -2
  129. package/lib/operations/set_profiling_level.js.map +1 -1
  130. package/lib/operations/update.js +12 -12
  131. package/lib/operations/update.js.map +1 -1
  132. package/lib/operations/validate_collection.js +6 -5
  133. package/lib/operations/validate_collection.js.map +1 -1
  134. package/lib/promise_provider.js +1 -1
  135. package/lib/promise_provider.js.map +1 -1
  136. package/lib/read_preference.js +8 -8
  137. package/lib/read_preference.js.map +1 -1
  138. package/lib/sdam/common.js +12 -10
  139. package/lib/sdam/common.js.map +1 -1
  140. package/lib/sdam/server.js +90 -25
  141. package/lib/sdam/server.js.map +1 -1
  142. package/lib/sdam/server_description.js +9 -4
  143. package/lib/sdam/server_description.js.map +1 -1
  144. package/lib/sdam/server_selection.js +10 -4
  145. package/lib/sdam/server_selection.js.map +1 -1
  146. package/lib/sdam/srv_polling.js +1 -1
  147. package/lib/sdam/srv_polling.js.map +1 -1
  148. package/lib/sdam/topology.js +42 -21
  149. package/lib/sdam/topology.js.map +1 -1
  150. package/lib/sdam/topology_description.js +7 -3
  151. package/lib/sdam/topology_description.js.map +1 -1
  152. package/lib/sessions.js +132 -31
  153. package/lib/sessions.js.map +1 -1
  154. package/lib/sort.js +3 -3
  155. package/lib/sort.js.map +1 -1
  156. package/lib/transactions.js +15 -7
  157. package/lib/transactions.js.map +1 -1
  158. package/lib/utils.js +60 -20
  159. package/lib/utils.js.map +1 -1
  160. package/mongodb.d.ts +523 -138
  161. package/mongodb.ts34.d.ts +480 -141
  162. package/package.json +44 -48
  163. package/src/bson.ts +1 -0
  164. package/src/bulk/common.ts +83 -43
  165. package/src/bulk/ordered.ts +4 -3
  166. package/src/bulk/unordered.ts +4 -3
  167. package/src/change_stream.ts +46 -29
  168. package/src/cmap/auth/auth_provider.ts +3 -2
  169. package/src/cmap/auth/gssapi.ts +15 -5
  170. package/src/cmap/auth/mongo_credentials.ts +22 -8
  171. package/src/cmap/auth/mongocr.ts +3 -3
  172. package/src/cmap/auth/mongodb_aws.ts +52 -39
  173. package/src/cmap/auth/plain.ts +2 -2
  174. package/src/cmap/auth/scram.ts +23 -13
  175. package/src/cmap/auth/x509.ts +3 -3
  176. package/src/cmap/command_monitoring_events.ts +36 -14
  177. package/src/cmap/commands.ts +12 -6
  178. package/src/cmap/connect.ts +42 -12
  179. package/src/cmap/connection.ts +54 -62
  180. package/src/cmap/connection_pool.ts +141 -20
  181. package/src/cmap/connection_pool_events.ts +8 -1
  182. package/src/cmap/errors.ts +3 -4
  183. package/src/cmap/message_stream.ts +2 -4
  184. package/src/cmap/metrics.ts +58 -0
  185. package/src/cmap/stream_description.ts +6 -1
  186. package/src/cmap/wire_protocol/compression.ts +26 -13
  187. package/src/cmap/wire_protocol/shared.ts +4 -2
  188. package/src/collection.ts +75 -70
  189. package/src/connection_string.ts +97 -34
  190. package/src/cursor/abstract_cursor.ts +141 -104
  191. package/src/cursor/aggregation_cursor.ts +34 -20
  192. package/src/cursor/find_cursor.ts +41 -21
  193. package/src/db.ts +19 -18
  194. package/src/deps.ts +110 -22
  195. package/src/encrypter.ts +6 -12
  196. package/src/error.ts +264 -48
  197. package/src/explain.ts +3 -3
  198. package/src/gridfs/download.ts +48 -53
  199. package/src/gridfs/index.ts +5 -4
  200. package/src/gridfs/upload.ts +32 -33
  201. package/src/index.ts +42 -4
  202. package/src/logger.ts +6 -3
  203. package/src/mongo_client.ts +20 -23
  204. package/src/mongo_types.ts +19 -20
  205. package/src/operations/add_user.ts +4 -5
  206. package/src/operations/aggregate.ts +18 -17
  207. package/src/operations/command.ts +7 -10
  208. package/src/operations/common_functions.ts +2 -3
  209. package/src/operations/connect.ts +4 -3
  210. package/src/operations/count.ts +2 -2
  211. package/src/operations/count_documents.ts +2 -2
  212. package/src/operations/delete.ts +8 -6
  213. package/src/operations/distinct.ts +5 -3
  214. package/src/operations/estimated_document_count.ts +5 -1
  215. package/src/operations/eval.ts +1 -1
  216. package/src/operations/execute_operation.ts +41 -20
  217. package/src/operations/find.ts +25 -16
  218. package/src/operations/find_and_modify.ts +12 -10
  219. package/src/operations/indexes.ts +39 -8
  220. package/src/operations/insert.ts +7 -4
  221. package/src/operations/is_capped.ts +3 -2
  222. package/src/operations/list_collections.ts +9 -6
  223. package/src/operations/map_reduce.ts +4 -2
  224. package/src/operations/operation.ts +7 -2
  225. package/src/operations/options_operation.ts +3 -2
  226. package/src/operations/profiling_level.ts +5 -3
  227. package/src/operations/set_profiling_level.ts +9 -3
  228. package/src/operations/update.ts +17 -13
  229. package/src/operations/validate_collection.ts +7 -6
  230. package/src/promise_provider.ts +2 -2
  231. package/src/read_preference.ts +11 -9
  232. package/src/sdam/common.ts +11 -9
  233. package/src/sdam/server.ts +168 -69
  234. package/src/sdam/server_description.ts +16 -4
  235. package/src/sdam/server_selection.ts +15 -7
  236. package/src/sdam/srv_polling.ts +2 -2
  237. package/src/sdam/topology.ts +67 -36
  238. package/src/sdam/topology_description.ts +11 -4
  239. package/src/sessions.ts +194 -37
  240. package/src/sort.ts +6 -4
  241. package/src/transactions.ts +18 -9
  242. package/src/utils.ts +73 -20
  243. package/HISTORY.md +0 -2993
  244. package/lib/operations/find_one.js +0 -34
  245. package/lib/operations/find_one.js.map +0 -1
  246. package/src/operations/find_one.ts +0 -43
@@ -1,5 +1,12 @@
1
1
  import Denque = require('denque');
2
- import { MongoError, AnyError, isResumableError, MongoDriverError } from './error';
2
+ import {
3
+ MongoError,
4
+ AnyError,
5
+ isResumableError,
6
+ MongoRuntimeError,
7
+ MongoAPIError,
8
+ MongoChangeStreamError
9
+ } from './error';
3
10
  import { AggregateOperation, AggregateOptions } from './operations/aggregate';
4
11
  import {
5
12
  maxWireVersion,
@@ -191,9 +198,9 @@ export type ChangeStreamEvents = {
191
198
  * Creates a new Change Stream instance. Normally created using {@link Collection#watch|Collection.watch()}.
192
199
  * @public
193
200
  */
194
- export class ChangeStream<TSchema extends Document = Document> extends TypedEventEmitter<
195
- ChangeStreamEvents
196
- > {
201
+ export class ChangeStream<
202
+ TSchema extends Document = Document
203
+ > extends TypedEventEmitter<ChangeStreamEvents> {
197
204
  pipeline: Document[];
198
205
  options: ChangeStreamOptions;
199
206
  parent: MongoClient | Db | Collection;
@@ -203,7 +210,7 @@ export class ChangeStream<TSchema extends Document = Document> extends TypedEven
203
210
  cursor?: ChangeStreamCursor<TSchema>;
204
211
  streamOptions?: CursorStreamOptions;
205
212
  /** @internal */
206
- [kResumeQueue]: Denque;
213
+ [kResumeQueue]: Denque<Callback<ChangeStreamCursor<TSchema>>>;
207
214
  /** @internal */
208
215
  [kCursorStream]?: Readable;
209
216
  /** @internal */
@@ -259,8 +266,8 @@ export class ChangeStream<TSchema extends Document = Document> extends TypedEven
259
266
  } else if (parent instanceof MongoClient) {
260
267
  this.type = CHANGE_DOMAIN_TYPES.CLUSTER;
261
268
  } else {
262
- throw new MongoDriverError(
263
- 'parent provided to ChangeStream constructor is not an instance of Collection, Db, or MongoClient'
269
+ throw new MongoChangeStreamError(
270
+ 'Parent provided to ChangeStream constructor must be an instance of Collection, Db, or MongoClient'
264
271
  );
265
272
  }
266
273
 
@@ -364,7 +371,7 @@ export class ChangeStream<TSchema extends Document = Document> extends TypedEven
364
371
  */
365
372
  stream(options?: CursorStreamOptions): Readable {
366
373
  this.streamOptions = options;
367
- if (!this.cursor) throw new MongoDriverError(NO_CURSOR_ERROR);
374
+ if (!this.cursor) throw new MongoChangeStreamError(NO_CURSOR_ERROR);
368
375
  return this.cursor.stream(options);
369
376
  }
370
377
 
@@ -487,15 +494,11 @@ export class ChangeStreamCursor<TSchema extends Document = Document> extends Abs
487
494
  }
488
495
 
489
496
  _initialize(session: ClientSession, callback: Callback<ExecutionResult>): void {
490
- const aggregateOperation = new AggregateOperation(
491
- { s: { namespace: this.namespace } },
492
- this.pipeline,
493
- {
494
- ...this.cursorOptions,
495
- ...this.options,
496
- session
497
- }
498
- );
497
+ const aggregateOperation = new AggregateOperation(this.namespace, this.pipeline, {
498
+ ...this.cursorOptions,
499
+ ...this.options,
500
+ session
501
+ });
499
502
 
500
503
  executeOperation(this.topology, aggregateOperation, (err, response) => {
501
504
  if (err || response == null) {
@@ -545,8 +548,9 @@ const CHANGE_STREAM_EVENTS = [
545
548
 
546
549
  function setIsEmitter<TSchema>(changeStream: ChangeStream<TSchema>): void {
547
550
  if (changeStream[kMode] === 'iterator') {
548
- throw new MongoDriverError(
549
- 'Cannot use ChangeStream as an EventEmitter after using as an iterator'
551
+ // TODO(NODE-3485): Replace with MongoChangeStreamModeError
552
+ throw new MongoAPIError(
553
+ 'ChangeStream cannot be used as an EventEmitter after being used as an iterator'
550
554
  );
551
555
  }
552
556
  changeStream[kMode] = 'emitter';
@@ -554,8 +558,9 @@ function setIsEmitter<TSchema>(changeStream: ChangeStream<TSchema>): void {
554
558
 
555
559
  function setIsIterator<TSchema>(changeStream: ChangeStream<TSchema>): void {
556
560
  if (changeStream[kMode] === 'emitter') {
557
- throw new MongoDriverError(
558
- 'Cannot use ChangeStream as iterator after using as an EventEmitter'
561
+ // TODO(NODE-3485): Replace with MongoChangeStreamModeError
562
+ throw new MongoAPIError(
563
+ 'ChangeStream cannot be used as an iterator after being used as an EventEmitter'
559
564
  );
560
565
  }
561
566
  changeStream[kMode] = 'iterator';
@@ -632,7 +637,8 @@ function waitForTopologyConnected(
632
637
  }
633
638
 
634
639
  if (calculateDurationInMs(start) > timeout) {
635
- return callback(new MongoDriverError('Timed out waiting for connection'));
640
+ // TODO(NODE-3497): Replace with MongoNetworkTimeoutError
641
+ return callback(new MongoRuntimeError('Timed out waiting for connection'));
636
642
  }
637
643
 
638
644
  waitForTopologyConnected(topology, options, callback);
@@ -678,17 +684,23 @@ function processNewChange<TSchema>(
678
684
  callback?: Callback<ChangeStreamDocument<TSchema>>
679
685
  ) {
680
686
  if (changeStream[kClosed]) {
681
- if (callback) callback(new MongoDriverError(CHANGESTREAM_CLOSED_ERROR));
687
+ // TODO(NODE-3485): Replace with MongoChangeStreamClosedError
688
+ if (callback) callback(new MongoAPIError(CHANGESTREAM_CLOSED_ERROR));
682
689
  return;
683
690
  }
684
691
 
685
692
  // a null change means the cursor has been notified, implicitly closing the change stream
686
693
  if (change == null) {
687
- return closeWithError(changeStream, new MongoDriverError(CHANGESTREAM_CLOSED_ERROR), callback);
694
+ // TODO(NODE-3485): Replace with MongoChangeStreamClosedError
695
+ return closeWithError(changeStream, new MongoRuntimeError(CHANGESTREAM_CLOSED_ERROR), callback);
688
696
  }
689
697
 
690
698
  if (change && !change._id) {
691
- return closeWithError(changeStream, new MongoDriverError(NO_RESUME_TOKEN_ERROR), callback);
699
+ return closeWithError(
700
+ changeStream,
701
+ new MongoChangeStreamError(NO_RESUME_TOKEN_ERROR),
702
+ callback
703
+ );
692
704
  }
693
705
 
694
706
  // cache the resume token
@@ -712,7 +724,8 @@ function processError<TSchema>(
712
724
 
713
725
  // If the change stream has been closed explicitly, do not process error.
714
726
  if (changeStream[kClosed]) {
715
- if (callback) callback(new MongoDriverError(CHANGESTREAM_CLOSED_ERROR));
727
+ // TODO(NODE-3485): Replace with MongoChangeStreamClosedError
728
+ if (callback) callback(new MongoAPIError(CHANGESTREAM_CLOSED_ERROR));
716
729
  return;
717
730
  }
718
731
 
@@ -772,7 +785,8 @@ function processError<TSchema>(
772
785
  */
773
786
  function getCursor<T>(changeStream: ChangeStream<T>, callback: Callback<ChangeStreamCursor<T>>) {
774
787
  if (changeStream[kClosed]) {
775
- callback(new MongoDriverError(CHANGESTREAM_CLOSED_ERROR));
788
+ // TODO(NODE-3485): Replace with MongoChangeStreamClosedError
789
+ callback(new MongoAPIError(CHANGESTREAM_CLOSED_ERROR));
776
790
  return;
777
791
  }
778
792
 
@@ -795,13 +809,16 @@ function getCursor<T>(changeStream: ChangeStream<T>, callback: Callback<ChangeSt
795
809
  function processResumeQueue<TSchema>(changeStream: ChangeStream<TSchema>, err?: Error) {
796
810
  while (changeStream[kResumeQueue].length) {
797
811
  const request = changeStream[kResumeQueue].pop();
812
+ if (!request) break; // Should never occur but TS can't use the length check in the while condition
813
+
798
814
  if (!err) {
799
815
  if (changeStream[kClosed]) {
800
- request(new MongoDriverError(CHANGESTREAM_CLOSED_ERROR));
816
+ // TODO(NODE-3485): Replace with MongoChangeStreamClosedError
817
+ request(new MongoAPIError(CHANGESTREAM_CLOSED_ERROR));
801
818
  return;
802
819
  }
803
820
  if (!changeStream.cursor) {
804
- request(new MongoDriverError(NO_CURSOR_ERROR));
821
+ request(new MongoChangeStreamError(NO_CURSOR_ERROR));
805
822
  return;
806
823
  }
807
824
  }
@@ -3,7 +3,7 @@ import type { Connection, ConnectionOptions } from '../connection';
3
3
  import type { MongoCredentials } from './mongo_credentials';
4
4
  import type { HandshakeDocument } from '../connect';
5
5
  import type { ClientMetadataOptions, Callback } from '../../utils';
6
- import { MongoDriverError } from '../../error';
6
+ import { MongoRuntimeError } from '../../error';
7
7
 
8
8
  export type AuthContextOptions = ConnectionOptions & ClientMetadataOptions;
9
9
 
@@ -54,6 +54,7 @@ export class AuthProvider {
54
54
  * @param callback - The callback to return the result from the authentication
55
55
  */
56
56
  auth(context: AuthContext, callback: Callback): void {
57
- callback(new MongoDriverError('`auth` method must be overridden by subclass'));
57
+ // TODO(NODE-3483): Replace this with MongoMethodOverrideError
58
+ callback(new MongoRuntimeError('`auth` method must be overridden by subclass'));
58
59
  }
59
60
  }
@@ -1,5 +1,11 @@
1
1
  import { AuthProvider, AuthContext } from './auth_provider';
2
- import { MongoDriverError, MongoError } from '../../error';
2
+ import {
3
+ MongoRuntimeError,
4
+ MongoInvalidArgumentError,
5
+ MongoMissingCredentialsError,
6
+ MongoError,
7
+ MongoMissingDependencyError
8
+ } from '../../error';
3
9
  import { Kerberos, KerberosClient } from '../../deps';
4
10
  import { Callback, ns } from '../../utils';
5
11
  import type { Document } from '../../bson';
@@ -15,7 +21,10 @@ import * as dns from 'dns';
15
21
  export class GSSAPI extends AuthProvider {
16
22
  auth(authContext: AuthContext, callback: Callback): void {
17
23
  const { connection, credentials } = authContext;
18
- if (credentials == null) return callback(new MongoDriverError('credentials required'));
24
+ if (credentials == null)
25
+ return callback(
26
+ new MongoMissingCredentialsError('Credentials required for GSSAPI authentication')
27
+ );
19
28
  const { username } = credentials;
20
29
  function externalCommand(
21
30
  command: Document,
@@ -25,7 +34,7 @@ export class GSSAPI extends AuthProvider {
25
34
  }
26
35
  makeKerberosClient(authContext, (err, client) => {
27
36
  if (err) return callback(err);
28
- if (client == null) return callback(new MongoDriverError('gssapi client missing'));
37
+ if (client == null) return callback(new MongoMissingDependencyError('GSSAPI client missing'));
29
38
  client.step('', (err, payload) => {
30
39
  if (err) return callback(err);
31
40
 
@@ -66,7 +75,7 @@ function makeKerberosClient(authContext: AuthContext, callback: Callback<Kerbero
66
75
  const { credentials } = authContext;
67
76
  if (!hostAddress || typeof hostAddress.host !== 'string' || !credentials) {
68
77
  return callback(
69
- new MongoDriverError('Connection must have host and port and credentials defined.')
78
+ new MongoInvalidArgumentError('Connection must have host and port and credentials defined.')
70
79
  );
71
80
  }
72
81
 
@@ -97,7 +106,8 @@ function makeKerberosClient(authContext: AuthContext, callback: Callback<Kerbero
97
106
  }
98
107
 
99
108
  initializeClient(spn, initOptions, (err: string, client: KerberosClient): void => {
100
- if (err) return callback(new MongoDriverError(err));
109
+ // TODO(NODE-3483)
110
+ if (err) return callback(new MongoRuntimeError(err));
101
111
  callback(undefined, client);
102
112
  });
103
113
  }
@@ -1,7 +1,7 @@
1
1
  // Resolves the default auth mechanism according to
2
2
 
3
3
  import type { Document } from '../../bson';
4
- import { MongoDriverError } from '../../error';
4
+ import { MongoAPIError, MongoMissingCredentialsError } from '../../error';
5
5
  import { AuthMechanism } from './defaultAuthProviders';
6
6
 
7
7
  // https://github.com/mongodb/specifications/blob/master/source/auth/auth.rst
@@ -25,6 +25,14 @@ function getDefaultAuthMechanism(ismaster?: Document): AuthMechanism {
25
25
  return AuthMechanism.MONGODB_CR;
26
26
  }
27
27
 
28
+ /** @public */
29
+ export interface AuthMechanismProperties extends Document {
30
+ SERVICE_NAME?: string;
31
+ SERVICE_REALM?: string;
32
+ CANONICALIZE_HOST_NAME?: boolean;
33
+ AWS_SESSION_TOKEN?: string;
34
+ }
35
+
28
36
  /** @public */
29
37
  export interface MongoCredentialsOptions {
30
38
  username: string;
@@ -32,7 +40,7 @@ export interface MongoCredentialsOptions {
32
40
  source: string;
33
41
  db?: string;
34
42
  mechanism?: AuthMechanism;
35
- mechanismProperties: Document;
43
+ mechanismProperties: AuthMechanismProperties;
36
44
  }
37
45
 
38
46
  /**
@@ -49,7 +57,7 @@ export class MongoCredentials {
49
57
  /** The method used to authenticate */
50
58
  readonly mechanism: AuthMechanism;
51
59
  /** Special properties used by some types of auth mechanisms */
52
- readonly mechanismProperties: Document;
60
+ readonly mechanismProperties: AuthMechanismProperties;
53
61
 
54
62
  constructor(options: MongoCredentialsOptions) {
55
63
  this.username = options.username;
@@ -70,7 +78,10 @@ export class MongoCredentials {
70
78
  this.password = process.env.AWS_SECRET_ACCESS_KEY;
71
79
  }
72
80
 
73
- if (!this.mechanismProperties.AWS_SESSION_TOKEN && process.env.AWS_SESSION_TOKEN) {
81
+ if (
82
+ this.mechanismProperties.AWS_SESSION_TOKEN == null &&
83
+ process.env.AWS_SESSION_TOKEN != null
84
+ ) {
74
85
  this.mechanismProperties = {
75
86
  ...this.mechanismProperties,
76
87
  AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN
@@ -122,7 +133,7 @@ export class MongoCredentials {
122
133
  this.mechanism === AuthMechanism.MONGODB_SCRAM_SHA256) &&
123
134
  !this.username
124
135
  ) {
125
- throw new MongoDriverError(`Username required for mechanism '${this.mechanism}'`);
136
+ throw new MongoMissingCredentialsError(`Username required for mechanism '${this.mechanism}'`);
126
137
  }
127
138
 
128
139
  if (
@@ -131,14 +142,16 @@ export class MongoCredentials {
131
142
  this.mechanism === AuthMechanism.MONGODB_X509
132
143
  ) {
133
144
  if (this.source != null && this.source !== '$external') {
134
- throw new MongoDriverError(
145
+ // TODO(NODE-3485): Replace this with a MongoAuthValidationError
146
+ throw new MongoAPIError(
135
147
  `Invalid source '${this.source}' for mechanism '${this.mechanism}' specified.`
136
148
  );
137
149
  }
138
150
  }
139
151
 
140
152
  if (this.mechanism === AuthMechanism.MONGODB_PLAIN && this.source == null) {
141
- throw new MongoDriverError('PLAIN Authentication Mechanism needs an auth source');
153
+ // TODO(NODE-3485): Replace this with a MongoAuthValidationError
154
+ throw new MongoAPIError('PLAIN Authentication Mechanism needs an auth source');
142
155
  }
143
156
 
144
157
  if (this.mechanism === AuthMechanism.MONGODB_X509 && this.password != null) {
@@ -146,7 +159,8 @@ export class MongoCredentials {
146
159
  Reflect.set(this, 'password', undefined);
147
160
  return;
148
161
  }
149
- throw new MongoDriverError(`Password not allowed for mechanism MONGODB-X509`);
162
+ // TODO(NODE-3485): Replace this with a MongoAuthValidationError
163
+ throw new MongoAPIError(`Password not allowed for mechanism MONGODB-X509`);
150
164
  }
151
165
  }
152
166
 
@@ -1,13 +1,13 @@
1
1
  import * as crypto from 'crypto';
2
2
  import { AuthProvider, AuthContext } from './auth_provider';
3
3
  import { Callback, ns } from '../../utils';
4
- import { MongoDriverError } from '../../error';
4
+ import { MongoMissingCredentialsError } from '../../error';
5
5
 
6
6
  export class MongoCR extends AuthProvider {
7
7
  auth(authContext: AuthContext, callback: Callback): void {
8
8
  const { connection, credentials } = authContext;
9
9
  if (!credentials) {
10
- return callback(new MongoDriverError('AuthContext must provide credentials.'));
10
+ return callback(new MongoMissingCredentialsError('AuthContext must provide credentials.'));
11
11
  }
12
12
  const username = credentials.username;
13
13
  const password = credentials.password;
@@ -24,7 +24,7 @@ export class MongoCR extends AuthProvider {
24
24
  let md5 = crypto.createHash('md5');
25
25
 
26
26
  // Generate keys used for authentication
27
- md5.update(username + ':mongo:' + password, 'utf8');
27
+ md5.update(`${username}:mongo:${password}`, 'utf8');
28
28
  const hash_password = md5.digest('hex');
29
29
 
30
30
  // Final key
@@ -4,12 +4,17 @@ import * as url from 'url';
4
4
  import * as BSON from '../../bson';
5
5
  import { AuthProvider, AuthContext } from './auth_provider';
6
6
  import { MongoCredentials } from './mongo_credentials';
7
- import { MongoDriverError } from '../../error';
7
+ import {
8
+ MongoRuntimeError,
9
+ MongoMissingCredentialsError,
10
+ MongoCompatibilityError
11
+ } from '../../error';
8
12
  import { maxWireVersion, Callback, ns } from '../../utils';
9
13
  import type { BSONSerializeOptions } from '../../bson';
10
14
 
11
15
  import { aws4 } from '../../deps';
12
16
  import { AuthMechanism } from './defaultAuthProviders';
17
+ import type { Binary } from 'bson';
13
18
 
14
19
  const ASCII_N = 110;
15
20
  const AWS_RELATIVE_URI = 'http://169.254.170.2';
@@ -32,7 +37,7 @@ export class MongoDBAWS extends AuthProvider {
32
37
  auth(authContext: AuthContext, callback: Callback): void {
33
38
  const { connection, credentials } = authContext;
34
39
  if (!credentials) {
35
- return callback(new MongoDriverError('AuthContext must provide credentials.'));
40
+ return callback(new MongoMissingCredentialsError('AuthContext must provide credentials.'));
36
41
  }
37
42
 
38
43
  if ('kModuleError' in aws4) {
@@ -42,7 +47,9 @@ export class MongoDBAWS extends AuthProvider {
42
47
 
43
48
  if (maxWireVersion(connection) < 9) {
44
49
  callback(
45
- new MongoDriverError('MONGODB-AWS authentication requires MongoDB version 4.4 or later')
50
+ new MongoCompatibilityError(
51
+ 'MONGODB-AWS authentication requires MongoDB version 4.4 or later'
52
+ )
46
53
  );
47
54
  return;
48
55
  }
@@ -58,10 +65,19 @@ export class MongoDBAWS extends AuthProvider {
58
65
  return;
59
66
  }
60
67
 
61
- const username = credentials.username;
62
- const password = credentials.password;
68
+ const accessKeyId = credentials.username;
69
+ const secretAccessKey = credentials.password;
70
+ const sessionToken = credentials.mechanismProperties.AWS_SESSION_TOKEN;
71
+
72
+ // If all three defined, include sessionToken, else include username and pass, else no credentials
73
+ const awsCredentials =
74
+ accessKeyId && secretAccessKey && sessionToken
75
+ ? { accessKeyId, secretAccessKey, sessionToken }
76
+ : accessKeyId && secretAccessKey
77
+ ? { accessKeyId, secretAccessKey }
78
+ : undefined;
79
+
63
80
  const db = credentials.source;
64
- const token = credentials.mechanismProperties.AWS_SESSION_TOKEN;
65
81
  crypto.randomBytes(32, (err, nonce) => {
66
82
  if (err) {
67
83
  callback(err);
@@ -77,24 +93,30 @@ export class MongoDBAWS extends AuthProvider {
77
93
  connection.command(ns(`${db}.$cmd`), saslStart, undefined, (err, res) => {
78
94
  if (err) return callback(err);
79
95
 
80
- const serverResponse = BSON.deserialize(res.payload.buffer, bsonOptions);
96
+ const serverResponse = BSON.deserialize(res.payload.buffer, bsonOptions) as {
97
+ s: Binary;
98
+ h: string;
99
+ };
81
100
  const host = serverResponse.h;
82
101
  const serverNonce = serverResponse.s.buffer;
83
102
  if (serverNonce.length !== 64) {
84
103
  callback(
85
- new MongoDriverError(`Invalid server nonce length ${serverNonce.length}, expected 64`)
104
+ // TODO(NODE-3483)
105
+ new MongoRuntimeError(`Invalid server nonce length ${serverNonce.length}, expected 64`)
86
106
  );
87
107
 
88
108
  return;
89
109
  }
90
110
 
91
111
  if (serverNonce.compare(nonce, 0, nonce.length, 0, nonce.length) !== 0) {
92
- callback(new MongoDriverError('Server nonce does not begin with client nonce'));
112
+ // TODO(NODE-3483)
113
+ callback(new MongoRuntimeError('Server nonce does not begin with client nonce'));
93
114
  return;
94
115
  }
95
116
 
96
117
  if (host.length < 1 || host.length > 255 || host.indexOf('..') !== -1) {
97
- callback(new MongoDriverError(`Server returned an invalid host: "${host}"`));
118
+ // TODO(NODE-3483)
119
+ callback(new MongoRuntimeError(`Server returned an invalid host: "${host}"`));
98
120
  return;
99
121
  }
100
122
 
@@ -114,18 +136,15 @@ export class MongoDBAWS extends AuthProvider {
114
136
  path: '/',
115
137
  body
116
138
  },
117
- {
118
- accessKeyId: username,
119
- secretAccessKey: password,
120
- token
121
- }
139
+ awsCredentials
122
140
  );
123
141
 
124
- const authorization = options.headers.Authorization;
125
- const date = options.headers['X-Amz-Date'];
126
- const payload: AWSSaslContinuePayload = { a: authorization, d: date };
127
- if (token) {
128
- payload.t = token;
142
+ const payload: AWSSaslContinuePayload = {
143
+ a: options.headers.Authorization,
144
+ d: options.headers['X-Amz-Date']
145
+ };
146
+ if (sessionToken) {
147
+ payload.t = sessionToken;
129
148
  }
130
149
 
131
150
  const saslContinue = {
@@ -140,16 +159,20 @@ export class MongoDBAWS extends AuthProvider {
140
159
  }
141
160
  }
142
161
 
143
- interface AWSCredentials {
162
+ interface AWSTempCredentials {
144
163
  AccessKeyId?: string;
145
164
  SecretAccessKey?: string;
146
165
  Token?: string;
166
+ RoleArn?: string;
167
+ Expiration?: Date;
147
168
  }
148
169
 
149
170
  function makeTempCredentials(credentials: MongoCredentials, callback: Callback<MongoCredentials>) {
150
- function done(creds: AWSCredentials) {
171
+ function done(creds: AWSTempCredentials) {
151
172
  if (!creds.AccessKeyId || !creds.SecretAccessKey || !creds.Token) {
152
- callback(new MongoDriverError('Could not obtain temporary MONGODB-AWS credentials'));
173
+ callback(
174
+ new MongoMissingCredentialsError('Could not obtain temporary MONGODB-AWS credentials')
175
+ );
153
176
  return;
154
177
  }
155
178
 
@@ -172,6 +195,7 @@ function makeTempCredentials(credentials: MongoCredentials, callback: Callback<M
172
195
  if (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {
173
196
  request(
174
197
  `${AWS_RELATIVE_URI}${process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}`,
198
+ undefined,
175
199
  (err, res) => {
176
200
  if (err) return callback(err);
177
201
  done(res);
@@ -228,27 +252,15 @@ interface RequestOptions {
228
252
  headers?: http.OutgoingHttpHeaders;
229
253
  }
230
254
 
231
- function request(uri: string, callback: Callback): void;
232
- function request(uri: string, options: RequestOptions, callback: Callback): void;
233
- function request(uri: string, _options: RequestOptions | Callback, _callback?: Callback) {
234
- let options = _options as RequestOptions;
235
- if ('function' === typeof _options) {
236
- options = {};
237
- }
238
-
239
- let callback: Callback = _options as Callback;
240
- if (_callback) {
241
- callback = _callback;
242
- }
243
-
244
- options = Object.assign(
255
+ function request(uri: string, _options: RequestOptions | undefined, callback: Callback) {
256
+ const options = Object.assign(
245
257
  {
246
258
  method: 'GET',
247
259
  timeout: 10000,
248
260
  json: true
249
261
  },
250
262
  url.parse(uri),
251
- options
263
+ _options
252
264
  );
253
265
 
254
266
  const req = http.request(options, res => {
@@ -266,7 +278,8 @@ function request(uri: string, _options: RequestOptions | Callback, _callback?: C
266
278
  const parsed = JSON.parse(data);
267
279
  callback(undefined, parsed);
268
280
  } catch (err) {
269
- callback(new MongoDriverError(`Invalid JSON response: "${data}"`));
281
+ // TODO(NODE-3483)
282
+ callback(new MongoRuntimeError(`Invalid JSON response: "${data}"`));
270
283
  }
271
284
  });
272
285
  });
@@ -1,13 +1,13 @@
1
1
  import { Binary } from '../../bson';
2
2
  import { AuthProvider, AuthContext } from './auth_provider';
3
- import { MongoDriverError } from '../../error';
3
+ import { MongoMissingCredentialsError } from '../../error';
4
4
  import { Callback, ns } from '../../utils';
5
5
 
6
6
  export class Plain extends AuthProvider {
7
7
  auth(authContext: AuthContext, callback: Callback): void {
8
8
  const { connection, credentials } = authContext;
9
9
  if (!credentials) {
10
- return callback(new MongoDriverError('AuthContext must provide credentials.'));
10
+ return callback(new MongoMissingCredentialsError('AuthContext must provide credentials.'));
11
11
  }
12
12
  const username = credentials.username;
13
13
  const password = credentials.password;