mongodb 5.2.0 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/lib/admin.js +18 -0
  2. package/lib/admin.js.map +1 -1
  3. package/lib/bulk/common.js +28 -7
  4. package/lib/bulk/common.js.map +1 -1
  5. package/lib/cmap/auth/mongo_credentials.js +29 -2
  6. package/lib/cmap/auth/mongo_credentials.js.map +1 -1
  7. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js +5 -3
  8. package/lib/cmap/auth/mongodb_oidc/aws_service_workflow.js.map +1 -1
  9. package/lib/cmap/auth/mongodb_oidc/cache.js +28 -0
  10. package/lib/cmap/auth/mongodb_oidc/cache.js.map +1 -0
  11. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js +83 -0
  12. package/lib/cmap/auth/mongodb_oidc/callback_lock_cache.js.map +1 -0
  13. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js +138 -112
  14. package/lib/cmap/auth/mongodb_oidc/callback_workflow.js.map +1 -1
  15. package/lib/cmap/auth/mongodb_oidc/service_workflow.js +4 -2
  16. package/lib/cmap/auth/mongodb_oidc/service_workflow.js.map +1 -1
  17. package/lib/cmap/auth/mongodb_oidc/token_entry_cache.js +12 -56
  18. package/lib/cmap/auth/mongodb_oidc/token_entry_cache.js.map +1 -1
  19. package/lib/cmap/auth/mongodb_oidc.js +17 -13
  20. package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
  21. package/lib/cmap/command_monitoring_events.js +6 -0
  22. package/lib/cmap/command_monitoring_events.js.map +1 -1
  23. package/lib/cmap/connect.js +1 -0
  24. package/lib/cmap/connect.js.map +1 -1
  25. package/lib/cmap/connection.js +12 -12
  26. package/lib/cmap/connection.js.map +1 -1
  27. package/lib/cmap/connection_pool.js +7 -3
  28. package/lib/cmap/connection_pool.js.map +1 -1
  29. package/lib/cmap/connection_pool_events.js +28 -3
  30. package/lib/cmap/connection_pool_events.js.map +1 -1
  31. package/lib/cmap/handshake/client_metadata.js +173 -0
  32. package/lib/cmap/handshake/client_metadata.js.map +1 -0
  33. package/lib/cmap/wire_protocol/constants.js +2 -2
  34. package/lib/cmap/wire_protocol/shared.js +2 -2
  35. package/lib/cmap/wire_protocol/shared.js.map +1 -1
  36. package/lib/collection.js +3 -0
  37. package/lib/collection.js.map +1 -1
  38. package/lib/connection_string.js +48 -53
  39. package/lib/connection_string.js.map +1 -1
  40. package/lib/constants.js +11 -0
  41. package/lib/constants.js.map +1 -1
  42. package/lib/cursor/abstract_cursor.js +1 -0
  43. package/lib/cursor/abstract_cursor.js.map +1 -1
  44. package/lib/db.js +18 -0
  45. package/lib/db.js.map +1 -1
  46. package/lib/mongo_client.js +16 -0
  47. package/lib/mongo_client.js.map +1 -1
  48. package/lib/mongo_logger.js +258 -27
  49. package/lib/mongo_logger.js.map +1 -1
  50. package/lib/operations/add_user.js.map +1 -1
  51. package/lib/operations/find.js +0 -7
  52. package/lib/operations/find.js.map +1 -1
  53. package/lib/operations/run_command.js.map +1 -1
  54. package/lib/operations/stats.js.map +1 -1
  55. package/lib/operations/update.js.map +1 -1
  56. package/lib/sdam/srv_polling.js +1 -15
  57. package/lib/sdam/srv_polling.js.map +1 -1
  58. package/lib/sdam/topology.js.map +1 -1
  59. package/lib/utils.js +48 -35
  60. package/lib/utils.js.map +1 -1
  61. package/mongodb.d.ts +247 -47
  62. package/package.json +3 -3
  63. package/src/admin.ts +18 -0
  64. package/src/bulk/common.ts +28 -7
  65. package/src/change_stream.ts +1 -1
  66. package/src/cmap/auth/mongo_credentials.ts +35 -2
  67. package/src/cmap/auth/mongodb_oidc/aws_service_workflow.ts +6 -3
  68. package/src/cmap/auth/mongodb_oidc/cache.ts +27 -0
  69. package/src/cmap/auth/mongodb_oidc/callback_lock_cache.ts +107 -0
  70. package/src/cmap/auth/mongodb_oidc/callback_workflow.ts +208 -171
  71. package/src/cmap/auth/mongodb_oidc/service_workflow.ts +5 -3
  72. package/src/cmap/auth/mongodb_oidc/token_entry_cache.ts +17 -96
  73. package/src/cmap/auth/mongodb_oidc.ts +61 -37
  74. package/src/cmap/command_monitoring_events.ts +13 -1
  75. package/src/cmap/connect.ts +3 -1
  76. package/src/cmap/connection.ts +16 -13
  77. package/src/cmap/connection_pool.ts +14 -4
  78. package/src/cmap/connection_pool_events.ts +68 -6
  79. package/src/cmap/handshake/client_metadata.ts +272 -0
  80. package/src/cmap/wire_protocol/constants.ts +2 -2
  81. package/src/cmap/wire_protocol/shared.ts +2 -3
  82. package/src/collection.ts +6 -3
  83. package/src/connection_string.ts +55 -55
  84. package/src/constants.ts +11 -0
  85. package/src/cursor/abstract_cursor.ts +1 -0
  86. package/src/db.ts +18 -0
  87. package/src/index.ts +24 -6
  88. package/src/mongo_client.ts +50 -6
  89. package/src/mongo_logger.ts +363 -44
  90. package/src/operations/add_user.ts +8 -2
  91. package/src/operations/find.ts +0 -10
  92. package/src/operations/run_command.ts +40 -3
  93. package/src/operations/stats.ts +11 -2
  94. package/src/operations/update.ts +8 -4
  95. package/src/sdam/srv_polling.ts +1 -16
  96. package/src/sdam/topology.ts +1 -3
  97. package/src/utils.ts +54 -73
  98. package/lib/cmap/auth/mongodb_oidc/workflow.js +0 -3
  99. package/lib/cmap/auth/mongodb_oidc/workflow.js.map +0 -1
  100. package/src/cmap/auth/mongodb_oidc/workflow.ts +0 -21
@@ -7,7 +7,11 @@ import type { Callback } from '../utils';
7
7
  import { CommandOperation, CommandOperationOptions } from './command';
8
8
  import { Aspect, defineAspects } from './operation';
9
9
 
10
- /** @public */
10
+ /**
11
+ * @public
12
+ * @deprecated the `collStats` operation will be removed in the next major release. Please
13
+ * use an aggregation pipeline with the [`$collStats`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/collStats/) stage instead
14
+ */
11
15
  export interface CollStatsOptions extends CommandOperationOptions {
12
16
  /** Divide the returned sizes by scale value. */
13
17
  scale?: number;
@@ -77,6 +81,8 @@ export class DbStatsOperation extends CommandOperation<Document> {
77
81
  }
78
82
 
79
83
  /**
84
+ * @deprecated the `collStats` operation will be removed in the next major release. Please
85
+ * use an aggregation pipeline with the [`$collStats`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/collStats/) stage instead
80
86
  * @public
81
87
  * @see https://www.mongodb.com/docs/manual/reference/command/collStats/
82
88
  */
@@ -130,7 +136,10 @@ export interface CollStats extends Document {
130
136
  scaleFactor: number;
131
137
  }
132
138
 
133
- /** @public */
139
+ /**
140
+ * @public
141
+ * @deprecated This type is only used for the deprecated `collStats` operation and will be removed in the next major release.
142
+ */
134
143
  export interface WiredTigerData extends Document {
135
144
  LSM: {
136
145
  'bloom filter false positives': number;
@@ -1,6 +1,7 @@
1
- import type { Document, ObjectId } from '../bson';
1
+ import type { Document } from '../bson';
2
2
  import type { Collection } from '../collection';
3
3
  import { MongoCompatibilityError, MongoInvalidArgumentError, MongoServerError } from '../error';
4
+ import type { InferIdType } from '../mongo_types';
4
5
  import type { Server } from '../sdam/server';
5
6
  import type { ClientSession } from '../sessions';
6
7
  import { Callback, hasAtomicOperators, MongoDBNamespace } from '../utils';
@@ -23,8 +24,11 @@ export interface UpdateOptions extends CommandOperationOptions {
23
24
  let?: Document;
24
25
  }
25
26
 
26
- /** @public */
27
- export interface UpdateResult {
27
+ /**
28
+ * @public
29
+ * `TSchema` is the schema of the collection
30
+ */
31
+ export interface UpdateResult<TSchema extends Document = Document> {
28
32
  /** Indicates whether this write result was acknowledged. If not, then all other members of this result will be undefined */
29
33
  acknowledged: boolean;
30
34
  /** The number of documents that matched the filter */
@@ -34,7 +38,7 @@ export interface UpdateResult {
34
38
  /** The number of documents that were upserted */
35
39
  upsertedCount: number;
36
40
  /** The identifier of the inserted document if an upsert took place */
37
- upsertedId: ObjectId;
41
+ upsertedId: InferIdType<TSchema> | null;
38
42
  }
39
43
 
40
44
  /** @public */
@@ -3,22 +3,7 @@ import { clearTimeout, setTimeout } from 'timers';
3
3
 
4
4
  import { MongoRuntimeError } from '../error';
5
5
  import { TypedEventEmitter } from '../mongo_types';
6
- import { HostAddress } from '../utils';
7
-
8
- /**
9
- * Determines whether a provided address matches the provided parent domain in order
10
- * to avoid certain attack vectors.
11
- *
12
- * @param srvAddress - The address to check against a domain
13
- * @param parentDomain - The domain to check the provided address against
14
- * @returns Whether the provided address matches the parent domain
15
- */
16
- function matchesParentDomain(srvAddress: string, parentDomain: string): boolean {
17
- const regex = /^.*?\./;
18
- const srv = `.${srvAddress.replace(regex, '')}`;
19
- const parent = `.${parentDomain.replace(regex, '')}`;
20
- return srv.endsWith(parent);
21
- }
6
+ import { HostAddress, matchesParentDomain } from '../utils';
22
7
 
23
8
  /**
24
9
  * @internal
@@ -5,6 +5,7 @@ import type { BSONSerializeOptions, Document } from '../bson';
5
5
  import type { MongoCredentials } from '../cmap/auth/mongo_credentials';
6
6
  import type { ConnectionEvents, DestroyOptions } from '../cmap/connection';
7
7
  import type { CloseOptions, ConnectionPoolEvents } from '../cmap/connection_pool';
8
+ import type { ClientMetadata } from '../cmap/handshake/client_metadata';
8
9
  import { DEFAULT_OPTIONS, FEATURE_FLAGS } from '../connection_string';
9
10
  import {
10
11
  CLOSE,
@@ -37,7 +38,6 @@ import type { ClientSession } from '../sessions';
37
38
  import type { Transaction } from '../transactions';
38
39
  import {
39
40
  Callback,
40
- ClientMetadata,
41
41
  EventEmitterWithState,
42
42
  HostAddress,
43
43
  List,
@@ -138,7 +138,6 @@ export interface TopologyOptions extends BSONSerializeOptions, ServerOptions {
138
138
  /** The name of the replica set to connect to */
139
139
  replicaSet?: string;
140
140
  srvHost?: string;
141
- /** @internal */
142
141
  srvPoller?: SrvPoller;
143
142
  /** Indicates that a client should directly connect to a node without attempting to discover its topology type */
144
143
  directConnection: boolean;
@@ -146,7 +145,6 @@ export interface TopologyOptions extends BSONSerializeOptions, ServerOptions {
146
145
  metadata: ClientMetadata;
147
146
  /** MongoDB server API version */
148
147
  serverApi?: ServerApi;
149
- /** @internal */
150
148
  [featureFlag: symbol]: any;
151
149
  }
152
150
 
package/src/utils.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import * as crypto from 'crypto';
2
2
  import type { SrvRecord } from 'dns';
3
- import * as os from 'os';
4
3
  import { URL } from 'url';
5
4
 
6
5
  import { Document, ObjectId, resolveBSONOptions } from './bson';
@@ -20,7 +19,7 @@ import {
20
19
  MongoRuntimeError
21
20
  } from './error';
22
21
  import type { Explain } from './explain';
23
- import type { MongoClient, MongoOptions } from './mongo_client';
22
+ import type { MongoClient } from './mongo_client';
24
23
  import type { CommandOperationOptions, OperationParent } from './operations/command';
25
24
  import type { Hint, OperationOptions } from './operations/operation';
26
25
  import { ReadConcern } from './read_concern';
@@ -59,6 +58,23 @@ export const ByteUtils = {
59
58
  }
60
59
  };
61
60
 
61
+ /**
62
+ * Determines if a connection's address matches a user provided list
63
+ * of domain wildcards.
64
+ */
65
+ export function hostMatchesWildcards(host: string, wildcards: string[]): boolean {
66
+ for (const wildcard of wildcards) {
67
+ if (
68
+ host === wildcard ||
69
+ (wildcard.startsWith('*.') && host?.endsWith(wildcard.substring(2, wildcard.length))) ||
70
+ (wildcard.startsWith('*/') && host?.endsWith(wildcard.substring(2, wildcard.length)))
71
+ ) {
72
+ return true;
73
+ }
74
+ }
75
+ return false;
76
+ }
77
+
62
78
  /**
63
79
  * Throws if collectionName is not a valid mongodb collection namespace.
64
80
  * @internal
@@ -513,77 +529,6 @@ export function makeStateMachine(stateTable: StateTable): StateTransitionFunctio
513
529
  };
514
530
  }
515
531
 
516
- /**
517
- * @public
518
- * @see https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.rst#hello-command
519
- */
520
- export interface ClientMetadata {
521
- driver: {
522
- name: string;
523
- version: string;
524
- };
525
- os: {
526
- type: string;
527
- name: NodeJS.Platform;
528
- architecture: string;
529
- version: string;
530
- };
531
- platform: string;
532
- application?: {
533
- name: string;
534
- };
535
- }
536
-
537
- /** @public */
538
- export interface ClientMetadataOptions {
539
- driverInfo?: {
540
- name?: string;
541
- version?: string;
542
- platform?: string;
543
- };
544
- appName?: string;
545
- }
546
-
547
- // eslint-disable-next-line @typescript-eslint/no-var-requires
548
- const NODE_DRIVER_VERSION = require('../package.json').version;
549
-
550
- export function makeClientMetadata(
551
- options: Pick<MongoOptions, 'appName' | 'driverInfo'>
552
- ): ClientMetadata {
553
- const name = options.driverInfo.name ? `nodejs|${options.driverInfo.name}` : 'nodejs';
554
- const version = options.driverInfo.version
555
- ? `${NODE_DRIVER_VERSION}|${options.driverInfo.version}`
556
- : NODE_DRIVER_VERSION;
557
- const platform = options.driverInfo.platform
558
- ? `Node.js ${process.version}, ${os.endianness()}|${options.driverInfo.platform}`
559
- : `Node.js ${process.version}, ${os.endianness()}`;
560
-
561
- const metadata: ClientMetadata = {
562
- driver: {
563
- name,
564
- version
565
- },
566
- os: {
567
- type: os.type(),
568
- name: process.platform,
569
- architecture: process.arch,
570
- version: os.release()
571
- },
572
- platform
573
- };
574
-
575
- if (options.appName) {
576
- // MongoDB requires the appName not exceed a byte length of 128
577
- const name =
578
- Buffer.byteLength(options.appName, 'utf8') <= 128
579
- ? options.appName
580
- : Buffer.from(options.appName, 'utf8').subarray(0, 128).toString('utf8');
581
- metadata.application = { name };
582
- }
583
-
584
- return metadata;
585
- }
586
-
587
532
  /** @internal */
588
533
  export function now(): number {
589
534
  const hrtime = process.hrtime();
@@ -1083,6 +1028,16 @@ export class HostAddress {
1083
1028
  static fromSrvRecord({ name, port }: SrvRecord): HostAddress {
1084
1029
  return HostAddress.fromHostPort(name, port);
1085
1030
  }
1031
+
1032
+ toHostPort(): { host: string; port: number } {
1033
+ if (this.socketPath) {
1034
+ return { host: this.socketPath, port: 0 };
1035
+ }
1036
+
1037
+ const host = this.host ?? '';
1038
+ const port = this.port ?? 0;
1039
+ return { host, port };
1040
+ }
1086
1041
  }
1087
1042
 
1088
1043
  export const DEFAULT_PK_FACTORY = {
@@ -1277,3 +1232,29 @@ export function parseUnsignedInteger(value: unknown): number | null {
1277
1232
 
1278
1233
  return parsedInt != null && parsedInt >= 0 ? parsedInt : null;
1279
1234
  }
1235
+
1236
+ /**
1237
+ * Determines whether a provided address matches the provided parent domain.
1238
+ *
1239
+ * If a DNS server were to become compromised SRV records would still need to
1240
+ * advertise addresses that are under the same domain as the srvHost.
1241
+ *
1242
+ * @param address - The address to check against a domain
1243
+ * @param srvHost - The domain to check the provided address against
1244
+ * @returns Whether the provided address matches the parent domain
1245
+ */
1246
+ export function matchesParentDomain(address: string, srvHost: string): boolean {
1247
+ // Remove trailing dot if exists on either the resolved address or the srv hostname
1248
+ const normalizedAddress = address.endsWith('.') ? address.slice(0, address.length - 1) : address;
1249
+ const normalizedSrvHost = srvHost.endsWith('.') ? srvHost.slice(0, srvHost.length - 1) : srvHost;
1250
+
1251
+ const allCharacterBeforeFirstDot = /^.*?\./;
1252
+ // Remove all characters before first dot
1253
+ // Add leading dot back to string so
1254
+ // an srvHostDomain = '.trusted.site'
1255
+ // will not satisfy an addressDomain that endsWith '.fake-trusted.site'
1256
+ const addressDomain = `.${normalizedAddress.replace(allCharacterBeforeFirstDot, '')}`;
1257
+ const srvHostDomain = `.${normalizedSrvHost.replace(allCharacterBeforeFirstDot, '')}`;
1258
+
1259
+ return addressDomain.endsWith(srvHostDomain);
1260
+ }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=workflow.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../../../src/cmap/auth/mongodb_oidc/workflow.ts"],"names":[],"mappings":""}
@@ -1,21 +0,0 @@
1
- import type { Document } from 'bson';
2
-
3
- import type { Connection } from '../../connection';
4
- import type { MongoCredentials } from '../mongo_credentials';
5
-
6
- export interface Workflow {
7
- /**
8
- * All device workflows must implement this method in order to get the access
9
- * token and then call authenticate with it.
10
- */
11
- execute(
12
- connection: Connection,
13
- credentials: MongoCredentials,
14
- reauthenticate?: boolean
15
- ): Promise<Document>;
16
-
17
- /**
18
- * Get the document to add for speculative authentication.
19
- */
20
- speculativeAuth(): Promise<Document>;
21
- }