mongodb 6.5.0 → 6.6.0-dev.20240504.sha.2609953

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 (207) hide show
  1. package/README.md +9 -9
  2. package/lib/admin.js +9 -9
  3. package/lib/admin.js.map +1 -1
  4. package/lib/bson.js +33 -22
  5. package/lib/bson.js.map +1 -1
  6. package/lib/bulk/common.js +13 -12
  7. package/lib/bulk/common.js.map +1 -1
  8. package/lib/change_stream.js +28 -18
  9. package/lib/change_stream.js.map +1 -1
  10. package/lib/client-side-encryption/auto_encrypter.js +2 -2
  11. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  12. package/lib/client-side-encryption/client_encryption.js +6 -6
  13. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  14. package/lib/client-side-encryption/providers/aws.js +13 -10
  15. package/lib/client-side-encryption/providers/aws.js.map +1 -1
  16. package/lib/client-side-encryption/providers/azure.js +6 -3
  17. package/lib/client-side-encryption/providers/azure.js.map +1 -1
  18. package/lib/cmap/auth/aws_temporary_credentials.js +140 -0
  19. package/lib/cmap/auth/aws_temporary_credentials.js.map +1 -0
  20. package/lib/cmap/auth/gssapi.js +7 -6
  21. package/lib/cmap/auth/gssapi.js.map +1 -1
  22. package/lib/cmap/auth/mongodb_aws.js +8 -101
  23. package/lib/cmap/auth/mongodb_aws.js.map +1 -1
  24. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js +1 -1
  25. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js.map +1 -1
  26. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js +2 -1
  27. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js.map +1 -1
  28. package/lib/cmap/auth/mongodb_oidc/service_workflow.js +1 -1
  29. package/lib/cmap/auth/mongodb_oidc/service_workflow.js.map +1 -1
  30. package/lib/cmap/auth/scram.js +2 -2
  31. package/lib/cmap/auth/scram.js.map +1 -1
  32. package/lib/cmap/commands.js +24 -111
  33. package/lib/cmap/commands.js.map +1 -1
  34. package/lib/cmap/connect.js +4 -4
  35. package/lib/cmap/connect.js.map +1 -1
  36. package/lib/cmap/connection.js +61 -36
  37. package/lib/cmap/connection.js.map +1 -1
  38. package/lib/cmap/connection_pool.js +22 -13
  39. package/lib/cmap/connection_pool.js.map +1 -1
  40. package/lib/cmap/handshake/client_metadata.js +2 -2
  41. package/lib/cmap/handshake/client_metadata.js.map +1 -1
  42. package/lib/cmap/wire_protocol/compression.js +8 -8
  43. package/lib/cmap/wire_protocol/compression.js.map +1 -1
  44. package/lib/cmap/wire_protocol/on_demand/document.js +218 -0
  45. package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -0
  46. package/lib/cmap/wire_protocol/responses.js +184 -0
  47. package/lib/cmap/wire_protocol/responses.js.map +1 -0
  48. package/lib/collection.js +42 -38
  49. package/lib/collection.js.map +1 -1
  50. package/lib/connection_string.js +4 -6
  51. package/lib/connection_string.js.map +1 -1
  52. package/lib/cursor/abstract_cursor.js +76 -43
  53. package/lib/cursor/abstract_cursor.js.map +1 -1
  54. package/lib/cursor/aggregation_cursor.js +16 -33
  55. package/lib/cursor/aggregation_cursor.js.map +1 -1
  56. package/lib/cursor/find_cursor.js +36 -18
  57. package/lib/cursor/find_cursor.js.map +1 -1
  58. package/lib/cursor/run_command_cursor.js +3 -2
  59. package/lib/cursor/run_command_cursor.js.map +1 -1
  60. package/lib/db.js +15 -19
  61. package/lib/db.js.map +1 -1
  62. package/lib/deps.js +31 -26
  63. package/lib/deps.js.map +1 -1
  64. package/lib/encrypter.js +14 -5
  65. package/lib/encrypter.js.map +1 -1
  66. package/lib/error.js +4 -3
  67. package/lib/error.js.map +1 -1
  68. package/lib/gridfs/download.js +19 -14
  69. package/lib/gridfs/download.js.map +1 -1
  70. package/lib/gridfs/index.js.map +1 -1
  71. package/lib/gridfs/upload.js +6 -1
  72. package/lib/gridfs/upload.js.map +1 -1
  73. package/lib/index.js.map +1 -1
  74. package/lib/mongo_client.js +11 -7
  75. package/lib/mongo_client.js.map +1 -1
  76. package/lib/mongo_logger.js +3 -0
  77. package/lib/mongo_logger.js.map +1 -1
  78. package/lib/operations/aggregate.js +2 -1
  79. package/lib/operations/aggregate.js.map +1 -1
  80. package/lib/operations/command.js +1 -1
  81. package/lib/operations/command.js.map +1 -1
  82. package/lib/operations/create_collection.js +1 -1
  83. package/lib/operations/create_collection.js.map +1 -1
  84. package/lib/operations/delete.js +4 -3
  85. package/lib/operations/delete.js.map +1 -1
  86. package/lib/operations/drop.js +1 -1
  87. package/lib/operations/drop.js.map +1 -1
  88. package/lib/operations/execute_operation.js +23 -8
  89. package/lib/operations/execute_operation.js.map +1 -1
  90. package/lib/operations/find.js +4 -4
  91. package/lib/operations/find.js.map +1 -1
  92. package/lib/operations/get_more.js +2 -1
  93. package/lib/operations/get_more.js.map +1 -1
  94. package/lib/operations/indexes.js +29 -121
  95. package/lib/operations/indexes.js.map +1 -1
  96. package/lib/operations/insert.js +3 -3
  97. package/lib/operations/insert.js.map +1 -1
  98. package/lib/operations/kill_cursors.js +3 -1
  99. package/lib/operations/kill_cursors.js.map +1 -1
  100. package/lib/operations/list_collections.js +1 -1
  101. package/lib/operations/list_collections.js.map +1 -1
  102. package/lib/operations/list_databases.js +1 -1
  103. package/lib/operations/list_databases.js.map +1 -1
  104. package/lib/operations/operation.js.map +1 -1
  105. package/lib/operations/run_command.js +4 -2
  106. package/lib/operations/run_command.js.map +1 -1
  107. package/lib/operations/search_indexes/create.js.map +1 -1
  108. package/lib/operations/stats.js +1 -1
  109. package/lib/operations/stats.js.map +1 -1
  110. package/lib/operations/update.js +1 -1
  111. package/lib/operations/update.js.map +1 -1
  112. package/lib/sdam/common.js.map +1 -1
  113. package/lib/sdam/monitor.js +139 -42
  114. package/lib/sdam/monitor.js.map +1 -1
  115. package/lib/sdam/server.js +5 -15
  116. package/lib/sdam/server.js.map +1 -1
  117. package/lib/sdam/server_description.js +1 -0
  118. package/lib/sdam/server_description.js.map +1 -1
  119. package/lib/sdam/server_selection.js +1 -1
  120. package/lib/sdam/server_selection.js.map +1 -1
  121. package/lib/sdam/srv_polling.js +2 -1
  122. package/lib/sdam/srv_polling.js.map +1 -1
  123. package/lib/sdam/topology.js +67 -54
  124. package/lib/sdam/topology.js.map +1 -1
  125. package/lib/sdam/topology_description.js +10 -0
  126. package/lib/sdam/topology_description.js.map +1 -1
  127. package/lib/sessions.js +133 -93
  128. package/lib/sessions.js.map +1 -1
  129. package/lib/timeout.js +77 -0
  130. package/lib/timeout.js.map +1 -0
  131. package/lib/utils.js +61 -28
  132. package/lib/utils.js.map +1 -1
  133. package/mongodb.d.ts +150 -38
  134. package/package.json +17 -14
  135. package/src/admin.ts +9 -9
  136. package/src/bson.ts +14 -0
  137. package/src/bulk/common.ts +3 -2
  138. package/src/change_stream.ts +39 -30
  139. package/src/client-side-encryption/auto_encrypter.ts +2 -2
  140. package/src/client-side-encryption/client_encryption.ts +6 -6
  141. package/src/client-side-encryption/providers/aws.ts +17 -10
  142. package/src/client-side-encryption/providers/azure.ts +5 -3
  143. package/src/cmap/auth/aws_temporary_credentials.ts +169 -0
  144. package/src/cmap/auth/gssapi.ts +9 -11
  145. package/src/cmap/auth/mongodb_aws.ts +19 -126
  146. package/src/cmap/auth/mongodb_oidc/aws_service_workflow.ts +1 -1
  147. package/src/cmap/auth/mongodb_oidc/callback_lock_cache.ts +2 -1
  148. package/src/cmap/auth/mongodb_oidc/service_workflow.ts +1 -1
  149. package/src/cmap/auth/scram.ts +2 -2
  150. package/src/cmap/commands.ts +28 -132
  151. package/src/cmap/connect.ts +4 -4
  152. package/src/cmap/connection.ts +107 -43
  153. package/src/cmap/connection_pool.ts +32 -29
  154. package/src/cmap/handshake/client_metadata.ts +2 -5
  155. package/src/cmap/wire_protocol/compression.ts +11 -13
  156. package/src/cmap/wire_protocol/on_demand/document.ts +338 -0
  157. package/src/cmap/wire_protocol/responses.ts +237 -0
  158. package/src/collection.ts +87 -58
  159. package/src/connection_string.ts +9 -7
  160. package/src/cursor/abstract_cursor.ts +102 -38
  161. package/src/cursor/aggregation_cursor.ts +32 -34
  162. package/src/cursor/find_cursor.ts +33 -21
  163. package/src/cursor/list_search_indexes_cursor.ts +1 -1
  164. package/src/cursor/run_command_cursor.ts +3 -2
  165. package/src/db.ts +42 -21
  166. package/src/deps.ts +52 -40
  167. package/src/encrypter.ts +14 -5
  168. package/src/error.ts +9 -3
  169. package/src/gridfs/download.ts +19 -31
  170. package/src/gridfs/index.ts +2 -0
  171. package/src/gridfs/upload.ts +11 -8
  172. package/src/index.ts +13 -5
  173. package/src/mongo_client.ts +21 -15
  174. package/src/mongo_logger.ts +3 -0
  175. package/src/mongo_types.ts +1 -1
  176. package/src/operations/aggregate.ts +2 -1
  177. package/src/operations/command.ts +1 -1
  178. package/src/operations/create_collection.ts +7 -2
  179. package/src/operations/delete.ts +4 -3
  180. package/src/operations/drop.ts +1 -1
  181. package/src/operations/execute_operation.ts +29 -10
  182. package/src/operations/find.ts +13 -14
  183. package/src/operations/get_more.ts +9 -1
  184. package/src/operations/indexes.ts +103 -176
  185. package/src/operations/insert.ts +2 -2
  186. package/src/operations/kill_cursors.ts +3 -2
  187. package/src/operations/list_collections.ts +5 -1
  188. package/src/operations/list_databases.ts +1 -1
  189. package/src/operations/operation.ts +3 -0
  190. package/src/operations/run_command.ts +6 -4
  191. package/src/operations/search_indexes/create.ts +4 -1
  192. package/src/operations/stats.ts +1 -1
  193. package/src/operations/update.ts +7 -7
  194. package/src/sdam/common.ts +8 -2
  195. package/src/sdam/monitor.ts +178 -61
  196. package/src/sdam/server.ts +27 -20
  197. package/src/sdam/server_description.ts +8 -3
  198. package/src/sdam/server_selection.ts +2 -3
  199. package/src/sdam/srv_polling.ts +3 -2
  200. package/src/sdam/topology.ts +114 -117
  201. package/src/sdam/topology_description.ts +14 -4
  202. package/src/sessions.ts +168 -148
  203. package/src/timeout.ts +96 -0
  204. package/src/utils.ts +85 -32
  205. package/lib/operations/common_functions.js +0 -38
  206. package/lib/operations/common_functions.js.map +0 -1
  207. package/src/operations/common_functions.ts +0 -79
package/src/bson.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import type { DeserializeOptions, SerializeOptions } from 'bson';
2
+ import { BSON } from 'bson';
2
3
 
3
4
  export {
4
5
  Binary,
5
6
  BSON,
7
+ BSONError,
6
8
  BSONRegExp,
7
9
  BSONSymbol,
8
10
  BSONType,
@@ -25,6 +27,18 @@ export {
25
27
  UUID
26
28
  } from 'bson';
27
29
 
30
+ export type BSONElement = BSON.OnDemand['BSONElement'];
31
+
32
+ export function parseToElementsToArray(bytes: Uint8Array, offset?: number): BSONElement[] {
33
+ const res = BSON.onDemand.parseToElements(bytes, offset);
34
+ return Array.isArray(res) ? res : [...res];
35
+ }
36
+
37
+ export const getInt32LE = BSON.onDemand.NumberUtils.getInt32LE;
38
+ export const getFloat64LE = BSON.onDemand.NumberUtils.getFloat64LE;
39
+ export const getBigInt64LE = BSON.onDemand.NumberUtils.getBigInt64LE;
40
+ export const toUTF8 = BSON.onDemand.ByteUtils.toUTF8;
41
+
28
42
  /**
29
43
  * BSON Serialization options.
30
44
  * @public
@@ -12,7 +12,6 @@ import {
12
12
  } from '../error';
13
13
  import type { Filter, OneOrMore, OptionalId, UpdateFilter, WithoutId } from '../mongo_types';
14
14
  import type { CollationOptions, CommandOperationOptions } from '../operations/command';
15
- import { maybeAddIdToDocuments } from '../operations/common_functions';
16
15
  import { DeleteOperation, type DeleteStatement, makeDeleteStatement } from '../operations/delete';
17
16
  import { executeOperation } from '../operations/execute_operation';
18
17
  import { InsertOperation } from '../operations/insert';
@@ -21,6 +20,7 @@ import { makeUpdateStatement, UpdateOperation, type UpdateStatement } from '../o
21
20
  import type { Server } from '../sdam/server';
22
21
  import type { Topology } from '../sdam/topology';
23
22
  import type { ClientSession } from '../sessions';
23
+ import { maybeAddIdToDocuments } from '../utils';
24
24
  import {
25
25
  applyRetryableWrites,
26
26
  type Callback,
@@ -589,6 +589,7 @@ function executeCommands(
589
589
  : null;
590
590
 
591
591
  if (operation != null) {
592
+ // eslint-disable-next-line github/no-then
592
593
  executeOperation(bulkOperation.s.collection.client, operation).then(
593
594
  result => resultHandler(undefined, result),
594
595
  error => resultHandler(error)
@@ -1224,7 +1225,7 @@ export abstract class BulkOperationBase {
1224
1225
  const finalOptions = { ...this.s.options, ...options };
1225
1226
  const operation = new BulkWriteShimOperation(this, finalOptions);
1226
1227
 
1227
- return executeOperation(this.s.collection.client, operation);
1228
+ return await executeOperation(this.s.collection.client, operation);
1228
1229
  }
1229
1230
 
1230
1231
  /**
@@ -19,7 +19,7 @@ import type { AggregateOptions } from './operations/aggregate';
19
19
  import type { CollationOptions, OperationParent } from './operations/command';
20
20
  import type { ReadPreference } from './read_preference';
21
21
  import type { ServerSessionId } from './sessions';
22
- import { filterOptions, getTopology, type MongoDBNamespace } from './utils';
22
+ import { filterOptions, getTopology, type MongoDBNamespace, squashError } from './utils';
23
23
 
24
24
  /** @internal */
25
25
  const kCursorStream = Symbol('cursorStream');
@@ -379,7 +379,7 @@ export interface ChangeStreamInvalidateDocument extends ChangeStreamDocumentComm
379
379
  /**
380
380
  * Only present when the `showExpandedEvents` flag is enabled.
381
381
  * @public
382
- * @see https://www.mongodb.com/docs/manual/reference/change-events/
382
+ * @see https://www.mongodb.com/docs/manual/reference/change-events/createIndexes/#mongodb-data-createIndexes
383
383
  */
384
384
  export interface ChangeStreamCreateIndexDocument
385
385
  extends ChangeStreamDocumentCommon,
@@ -392,7 +392,7 @@ export interface ChangeStreamCreateIndexDocument
392
392
  /**
393
393
  * Only present when the `showExpandedEvents` flag is enabled.
394
394
  * @public
395
- * @see https://www.mongodb.com/docs/manual/reference/change-events/
395
+ * @see https://www.mongodb.com/docs/manual/reference/change-events/dropIndexes/#mongodb-data-dropIndexes
396
396
  */
397
397
  export interface ChangeStreamDropIndexDocument
398
398
  extends ChangeStreamDocumentCommon,
@@ -405,7 +405,7 @@ export interface ChangeStreamDropIndexDocument
405
405
  /**
406
406
  * Only present when the `showExpandedEvents` flag is enabled.
407
407
  * @public
408
- * @see https://www.mongodb.com/docs/manual/reference/change-events/
408
+ * @see https://www.mongodb.com/docs/manual/reference/change-events/modify/#mongodb-data-modify
409
409
  */
410
410
  export interface ChangeStreamCollModDocument
411
411
  extends ChangeStreamDocumentCommon,
@@ -416,7 +416,7 @@ export interface ChangeStreamCollModDocument
416
416
 
417
417
  /**
418
418
  * @public
419
- * @see https://www.mongodb.com/docs/manual/reference/change-events/
419
+ * @see https://www.mongodb.com/docs/manual/reference/change-events/create/#mongodb-data-create
420
420
  */
421
421
  export interface ChangeStreamCreateDocument
422
422
  extends ChangeStreamDocumentCommon,
@@ -427,7 +427,7 @@ export interface ChangeStreamCreateDocument
427
427
 
428
428
  /**
429
429
  * @public
430
- * @see https://www.mongodb.com/docs/manual/reference/change-events/
430
+ * @see https://www.mongodb.com/docs/manual/reference/change-events/shardCollection/#mongodb-data-shardCollection
431
431
  */
432
432
  export interface ChangeStreamShardCollectionDocument
433
433
  extends ChangeStreamDocumentCommon,
@@ -439,7 +439,7 @@ export interface ChangeStreamShardCollectionDocument
439
439
 
440
440
  /**
441
441
  * @public
442
- * @see https://www.mongodb.com/docs/manual/reference/change-events/
442
+ * @see https://www.mongodb.com/docs/manual/reference/change-events/reshardCollection/#mongodb-data-reshardCollection
443
443
  */
444
444
  export interface ChangeStreamReshardCollectionDocument
445
445
  extends ChangeStreamDocumentCommon,
@@ -451,7 +451,7 @@ export interface ChangeStreamReshardCollectionDocument
451
451
 
452
452
  /**
453
453
  * @public
454
- * @see https://www.mongodb.com/docs/manual/reference/change-events/
454
+ * @see https://www.mongodb.com/docs/manual/reference/change-events/refineCollectionShardKey/#mongodb-data-refineCollectionShardKey
455
455
  */
456
456
  export interface ChangeStreamRefineCollectionShardKeyDocument
457
457
  extends ChangeStreamDocumentCommon,
@@ -676,8 +676,8 @@ export class ChangeStream<
676
676
  } catch (error) {
677
677
  try {
678
678
  await this.close();
679
- } catch {
680
- // We are not concerned with errors from close()
679
+ } catch (error) {
680
+ squashError(error);
681
681
  }
682
682
  throw error;
683
683
  }
@@ -703,8 +703,8 @@ export class ChangeStream<
703
703
  } catch (error) {
704
704
  try {
705
705
  await this.close();
706
- } catch {
707
- // We are not concerned with errors from close()
706
+ } catch (error) {
707
+ squashError(error);
708
708
  }
709
709
  throw error;
710
710
  }
@@ -731,8 +731,8 @@ export class ChangeStream<
731
731
  } catch (error) {
732
732
  try {
733
733
  await this.close();
734
- } catch {
735
- // We are not concerned with errors from close()
734
+ } catch (error) {
735
+ squashError(error);
736
736
  }
737
737
  throw error;
738
738
  }
@@ -754,8 +754,8 @@ export class ChangeStream<
754
754
  } finally {
755
755
  try {
756
756
  await this.close();
757
- } catch {
758
- // we're not concerned with errors from close()
757
+ } catch (error) {
758
+ squashError(error);
759
759
  }
760
760
  }
761
761
  }
@@ -867,7 +867,8 @@ export class ChangeStream<
867
867
  private _closeEmitterModeWithError(error: AnyError): void {
868
868
  this.emit(ChangeStream.ERROR, error);
869
869
 
870
- this.close().catch(() => null);
870
+ // eslint-disable-next-line github/no-then
871
+ this.close().then(undefined, squashError);
871
872
  }
872
873
 
873
874
  /** @internal */
@@ -931,17 +932,21 @@ export class ChangeStream<
931
932
 
932
933
  if (isResumableError(changeStreamError, this.cursor.maxWireVersion)) {
933
934
  this._endStream();
934
- this.cursor.close().catch(() => null);
935
+ // eslint-disable-next-line github/no-then
936
+ this.cursor.close().then(undefined, squashError);
935
937
 
936
938
  const topology = getTopology(this.parent);
937
- topology.selectServer(
938
- this.cursor.readPreference,
939
- { operationName: 'reconnect topology in change stream' },
940
- serverSelectionError => {
941
- if (serverSelectionError) return this._closeEmitterModeWithError(changeStreamError);
942
- this.cursor = this._createChangeStreamCursor(this.cursor.resumeOptions);
943
- }
944
- );
939
+ topology
940
+ .selectServer(this.cursor.readPreference, {
941
+ operationName: 'reconnect topology in change stream'
942
+ })
943
+ // eslint-disable-next-line github/no-then
944
+ .then(
945
+ () => {
946
+ this.cursor = this._createChangeStreamCursor(this.cursor.resumeOptions);
947
+ },
948
+ () => this._closeEmitterModeWithError(changeStreamError)
949
+ );
945
950
  } else {
946
951
  this._closeEmitterModeWithError(changeStreamError);
947
952
  }
@@ -957,16 +962,20 @@ export class ChangeStream<
957
962
  if (!isResumableError(changeStreamError, this.cursor.maxWireVersion)) {
958
963
  try {
959
964
  await this.close();
960
- } catch {
961
- // ignore errors from close
965
+ } catch (error) {
966
+ squashError(error);
962
967
  }
963
968
  throw changeStreamError;
964
969
  }
965
970
 
966
- await this.cursor.close().catch(() => null);
971
+ try {
972
+ await this.cursor.close();
973
+ } catch (error) {
974
+ squashError(error);
975
+ }
967
976
  const topology = getTopology(this.parent);
968
977
  try {
969
- await topology.selectServerAsync(this.cursor.readPreference, {
978
+ await topology.selectServer(this.cursor.readPreference, {
970
979
  operationName: 'reconnect topology in change stream'
971
980
  });
972
981
  this.cursor = this._createChangeStreamCursor(this.cursor.resumeOptions);
@@ -467,7 +467,7 @@ export class AutoEncrypter {
467
467
  proxyOptions: this._proxyOptions,
468
468
  tlsOptions: this._tlsOptions
469
469
  });
470
- return stateMachine.execute<Document>(this, context);
470
+ return await stateMachine.execute<Document>(this, context);
471
471
  }
472
472
 
473
473
  /**
@@ -502,7 +502,7 @@ export class AutoEncrypter {
502
502
  * the original ones.
503
503
  */
504
504
  async askForKMSCredentials(): Promise<KMSProviders> {
505
- return refreshKMSCredentials(this._kmsProviders);
505
+ return await refreshKMSCredentials(this._kmsProviders);
506
506
  }
507
507
 
508
508
  /**
@@ -315,7 +315,7 @@ export class ClientEncryption {
315
315
  this._keyVaultNamespace
316
316
  );
317
317
 
318
- return this._keyVaultClient
318
+ return await this._keyVaultClient
319
319
  .db(dbName)
320
320
  .collection<DataKey>(collectionName)
321
321
  .deleteOne({ _id }, { writeConcern: { w: 'majority' } });
@@ -364,7 +364,7 @@ export class ClientEncryption {
364
364
  this._keyVaultNamespace
365
365
  );
366
366
 
367
- return this._keyVaultClient
367
+ return await this._keyVaultClient
368
368
  .db(dbName)
369
369
  .collection<DataKey>(collectionName)
370
370
  .findOne({ _id }, { readConcern: { level: 'majority' } });
@@ -391,7 +391,7 @@ export class ClientEncryption {
391
391
  this._keyVaultNamespace
392
392
  );
393
393
 
394
- return this._keyVaultClient
394
+ return await this._keyVaultClient
395
395
  .db(dbName)
396
396
  .collection<DataKey>(collectionName)
397
397
  .findOne({ keyAltNames: keyAltName }, { readConcern: { level: 'majority' } });
@@ -589,7 +589,7 @@ export class ClientEncryption {
589
589
  * ```
590
590
  */
591
591
  async encrypt(value: unknown, options: ClientEncryptionEncryptOptions): Promise<Binary> {
592
- return this._encrypt(value, false, options);
592
+ return await this._encrypt(value, false, options);
593
593
  }
594
594
 
595
595
  /**
@@ -614,7 +614,7 @@ export class ClientEncryption {
614
614
  expression: Document,
615
615
  options: ClientEncryptionEncryptOptions
616
616
  ): Promise<Binary> {
617
- return this._encrypt(expression, true, options);
617
+ return await this._encrypt(expression, true, options);
618
618
  }
619
619
 
620
620
  /**
@@ -654,7 +654,7 @@ export class ClientEncryption {
654
654
  * the original ones.
655
655
  */
656
656
  async askForKMSCredentials(): Promise<KMSProviders> {
657
- return refreshKMSCredentials(this._kmsProviders);
657
+ return await refreshKMSCredentials(this._kmsProviders);
658
658
  }
659
659
 
660
660
  static get libmongocryptVersion() {
@@ -1,20 +1,27 @@
1
- import { getAwsCredentialProvider } from '../../deps';
1
+ import { AWSSDKCredentialProvider } from '../../cmap/auth/aws_temporary_credentials';
2
2
  import { type KMSProviders } from '.';
3
3
 
4
4
  /**
5
5
  * @internal
6
6
  */
7
7
  export async function loadAWSCredentials(kmsProviders: KMSProviders): Promise<KMSProviders> {
8
- const credentialProvider = getAwsCredentialProvider();
8
+ const credentialProvider = new AWSSDKCredentialProvider();
9
9
 
10
- if ('kModuleError' in credentialProvider) {
11
- return kmsProviders;
12
- }
10
+ // We shouldn't ever receive a response from the AWS SDK that doesn't have a `SecretAccessKey`
11
+ // or `AccessKeyId`. However, TS says these fields are optional. We provide empty strings
12
+ // and let libmongocrypt error if we're unable to fetch the required keys.
13
+ const {
14
+ SecretAccessKey = '',
15
+ AccessKeyId = '',
16
+ Token
17
+ } = await credentialProvider.getCredentials();
18
+ const aws: NonNullable<KMSProviders['aws']> = {
19
+ secretAccessKey: SecretAccessKey,
20
+ accessKeyId: AccessKeyId
21
+ };
22
+ // the AWS session token is only required for temporary credentials so only attach it to the
23
+ // result if it's present in the response from the aws sdk
24
+ Token != null && (aws.sessionToken = Token);
13
25
 
14
- const { fromNodeProviderChain } = credentialProvider;
15
- const provider = fromNodeProviderChain();
16
- // The state machine is the only place calling this so it will
17
- // catch if there is a rejection here.
18
- const aws = await provider();
19
26
  return { ...kmsProviders, aws };
20
27
  }
@@ -148,13 +148,15 @@ export async function fetchAzureKMSToken(
148
148
  options: AzureKMSRequestOptions = {}
149
149
  ): Promise<AzureTokenCacheEntry> {
150
150
  const { headers, url } = prepareRequest(options);
151
- const response = await get(url, { headers }).catch(error => {
151
+ try {
152
+ const response = await get(url, { headers });
153
+ return await parseResponse(response);
154
+ } catch (error) {
152
155
  if (error instanceof MongoCryptKMSRequestNetworkTimeoutError) {
153
156
  throw new MongoCryptAzureKMSRequestError(`[Azure KMS] ${error.message}`);
154
157
  }
155
158
  throw error;
156
- });
157
- return parseResponse(response);
159
+ }
158
160
  }
159
161
 
160
162
  /**
@@ -0,0 +1,169 @@
1
+ import { type AWSCredentials, getAwsCredentialProvider } from '../../deps';
2
+ import { MongoAWSError } from '../../error';
3
+ import { request } from '../../utils';
4
+
5
+ const AWS_RELATIVE_URI = 'http://169.254.170.2';
6
+ const AWS_EC2_URI = 'http://169.254.169.254';
7
+ const AWS_EC2_PATH = '/latest/meta-data/iam/security-credentials';
8
+
9
+ /**
10
+ * @internal
11
+ * This interface matches the final result of fetching temporary credentials manually, outlined
12
+ * in the spec [here](https://github.com/mongodb/specifications/blob/master/source/auth/auth.md#ec2-endpoint).
13
+ *
14
+ * When we use the AWS SDK, we map the response from the SDK to conform to this interface.
15
+ */
16
+ export interface AWSTempCredentials {
17
+ AccessKeyId?: string;
18
+ SecretAccessKey?: string;
19
+ Token?: string;
20
+ RoleArn?: string;
21
+ Expiration?: Date;
22
+ }
23
+
24
+ /**
25
+ * @internal
26
+ *
27
+ * Fetches temporary AWS credentials.
28
+ */
29
+ export abstract class AWSTemporaryCredentialProvider {
30
+ abstract getCredentials(): Promise<AWSTempCredentials>;
31
+ private static _awsSDK: ReturnType<typeof getAwsCredentialProvider>;
32
+ protected static get awsSDK() {
33
+ AWSTemporaryCredentialProvider._awsSDK ??= getAwsCredentialProvider();
34
+ return AWSTemporaryCredentialProvider._awsSDK;
35
+ }
36
+
37
+ static get isAWSSDKInstalled(): boolean {
38
+ return !('kModuleError' in AWSTemporaryCredentialProvider.awsSDK);
39
+ }
40
+ }
41
+
42
+ /** @internal */
43
+ export class AWSSDKCredentialProvider extends AWSTemporaryCredentialProvider {
44
+ private _provider?: () => Promise<AWSCredentials>;
45
+ /**
46
+ * The AWS SDK caches credentials automatically and handles refresh when the credentials have expired.
47
+ * To ensure this occurs, we need to cache the `provider` returned by the AWS sdk and re-use it when fetching credentials.
48
+ */
49
+ private get provider(): () => Promise<AWSCredentials> {
50
+ if ('kModuleError' in AWSTemporaryCredentialProvider.awsSDK) {
51
+ throw AWSTemporaryCredentialProvider.awsSDK.kModuleError;
52
+ }
53
+ if (this._provider) {
54
+ return this._provider;
55
+ }
56
+ let { AWS_STS_REGIONAL_ENDPOINTS = '', AWS_REGION = '' } = process.env;
57
+ AWS_STS_REGIONAL_ENDPOINTS = AWS_STS_REGIONAL_ENDPOINTS.toLowerCase();
58
+ AWS_REGION = AWS_REGION.toLowerCase();
59
+
60
+ /** The option setting should work only for users who have explicit settings in their environment, the driver should not encode "defaults" */
61
+ const awsRegionSettingsExist =
62
+ AWS_REGION.length !== 0 && AWS_STS_REGIONAL_ENDPOINTS.length !== 0;
63
+
64
+ /**
65
+ * The following regions use the global AWS STS endpoint, sts.amazonaws.com, by default
66
+ * https://docs.aws.amazon.com/sdkref/latest/guide/feature-sts-regionalized-endpoints.html
67
+ */
68
+ const LEGACY_REGIONS = new Set([
69
+ 'ap-northeast-1',
70
+ 'ap-south-1',
71
+ 'ap-southeast-1',
72
+ 'ap-southeast-2',
73
+ 'aws-global',
74
+ 'ca-central-1',
75
+ 'eu-central-1',
76
+ 'eu-north-1',
77
+ 'eu-west-1',
78
+ 'eu-west-2',
79
+ 'eu-west-3',
80
+ 'sa-east-1',
81
+ 'us-east-1',
82
+ 'us-east-2',
83
+ 'us-west-1',
84
+ 'us-west-2'
85
+ ]);
86
+ /**
87
+ * If AWS_STS_REGIONAL_ENDPOINTS is set to regional, users are opting into the new behavior of respecting the region settings
88
+ *
89
+ * If AWS_STS_REGIONAL_ENDPOINTS is set to legacy, then "old" regions need to keep using the global setting.
90
+ * Technically the SDK gets this wrong, it reaches out to 'sts.us-east-1.amazonaws.com' when it should be 'sts.amazonaws.com'.
91
+ * That is not our bug to fix here. We leave that up to the SDK.
92
+ */
93
+ const useRegionalSts =
94
+ AWS_STS_REGIONAL_ENDPOINTS === 'regional' ||
95
+ (AWS_STS_REGIONAL_ENDPOINTS === 'legacy' && !LEGACY_REGIONS.has(AWS_REGION));
96
+
97
+ this._provider =
98
+ awsRegionSettingsExist && useRegionalSts
99
+ ? AWSTemporaryCredentialProvider.awsSDK.fromNodeProviderChain({
100
+ clientConfig: { region: AWS_REGION }
101
+ })
102
+ : AWSTemporaryCredentialProvider.awsSDK.fromNodeProviderChain();
103
+
104
+ return this._provider;
105
+ }
106
+
107
+ override async getCredentials(): Promise<AWSTempCredentials> {
108
+ /*
109
+ * Creates a credential provider that will attempt to find credentials from the
110
+ * following sources (listed in order of precedence):
111
+ *
112
+ * - Environment variables exposed via process.env
113
+ * - SSO credentials from token cache
114
+ * - Web identity token credentials
115
+ * - Shared credentials and config ini files
116
+ * - The EC2/ECS Instance Metadata Service
117
+ */
118
+ try {
119
+ const creds = await this.provider();
120
+ return {
121
+ AccessKeyId: creds.accessKeyId,
122
+ SecretAccessKey: creds.secretAccessKey,
123
+ Token: creds.sessionToken,
124
+ Expiration: creds.expiration
125
+ };
126
+ } catch (error) {
127
+ throw new MongoAWSError(error.message, { cause: error });
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * @internal
134
+ * Fetches credentials manually (without the AWS SDK), as outlined in the [Obtaining Credentials](https://github.com/mongodb/specifications/blob/master/source/auth/auth.md#obtaining-credentials)
135
+ * section of the Auth spec.
136
+ */
137
+ export class LegacyAWSTemporaryCredentialProvider extends AWSTemporaryCredentialProvider {
138
+ override async getCredentials(): Promise<AWSTempCredentials> {
139
+ // If the environment variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
140
+ // is set then drivers MUST assume that it was set by an AWS ECS agent
141
+ if (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {
142
+ return await request(
143
+ `${AWS_RELATIVE_URI}${process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}`
144
+ );
145
+ }
146
+
147
+ // Otherwise assume we are on an EC2 instance
148
+
149
+ // get a token
150
+ const token = await request(`${AWS_EC2_URI}/latest/api/token`, {
151
+ method: 'PUT',
152
+ json: false,
153
+ headers: { 'X-aws-ec2-metadata-token-ttl-seconds': 30 }
154
+ });
155
+
156
+ // get role name
157
+ const roleName = await request(`${AWS_EC2_URI}/${AWS_EC2_PATH}`, {
158
+ json: false,
159
+ headers: { 'X-aws-ec2-metadata-token': token }
160
+ });
161
+
162
+ // get temp credentials
163
+ const creds = await request(`${AWS_EC2_URI}/${AWS_EC2_PATH}/${roleName}`, {
164
+ headers: { 'X-aws-ec2-metadata-token': token }
165
+ });
166
+
167
+ return creds;
168
+ }
169
+ }
@@ -29,14 +29,12 @@ type MechanismProperties = {
29
29
  async function externalCommand(
30
30
  connection: Connection,
31
31
  command: ReturnType<typeof saslStart> | ReturnType<typeof saslContinue>
32
- ): Promise<{ payload: string; conversationId: any }> {
33
- return connection.command(ns('$external.$cmd'), command, undefined) as Promise<{
34
- payload: string;
35
- conversationId: any;
36
- }>;
32
+ ): Promise<{ payload: string; conversationId: number }> {
33
+ const response = await connection.command(ns('$external.$cmd'), command);
34
+ return response as { payload: string; conversationId: number };
37
35
  }
38
36
 
39
- let krb: typeof Kerberos;
37
+ let krb: Kerberos;
40
38
 
41
39
  export class GSSAPI extends AuthProvider {
42
40
  override async auth(authContext: AuthContext): Promise<void> {
@@ -104,7 +102,7 @@ async function makeKerberosClient(authContext: AuthContext): Promise<KerberosCli
104
102
  spn = `${spn}@${mechanismProperties.SERVICE_REALM}`;
105
103
  }
106
104
 
107
- return initializeClient(spn, initOptions);
105
+ return await initializeClient(spn, initOptions);
108
106
  }
109
107
 
110
108
  function saslStart(payload: string) {
@@ -138,14 +136,14 @@ async function negotiate(
138
136
  throw error;
139
137
  }
140
138
  // Adjust number of retries and call step again
141
- return negotiate(client, retries - 1, payload);
139
+ return await negotiate(client, retries - 1, payload);
142
140
  }
143
141
  }
144
142
 
145
143
  async function finalize(client: KerberosClient, user: string, payload: string): Promise<string> {
146
144
  // GSS Client Unwrap
147
145
  const response = await client.unwrap(payload);
148
- return client.wrap(response || '', { user });
146
+ return await client.wrap(response || '', { user });
149
147
  }
150
148
 
151
149
  export async function performGSSAPICanonicalizeHostName(
@@ -174,12 +172,12 @@ export async function performGSSAPICanonicalizeHostName(
174
172
  // This can error as ptr records may not exist for all ips. In this case
175
173
  // fallback to a cname lookup as dns.lookup() does not return the
176
174
  // cname.
177
- return resolveCname(host);
175
+ return await resolveCname(host);
178
176
  }
179
177
  } else {
180
178
  // The case for forward is just to resolve the cname as dns.lookup()
181
179
  // will not return it.
182
- return resolveCname(host);
180
+ return await resolveCname(host);
183
181
  }
184
182
  }
185
183