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.
- package/README.md +62 -30
- package/lib/bson.js +1 -0
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +53 -30
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/ordered.js +3 -2
- package/lib/bulk/ordered.js.map +1 -1
- package/lib/bulk/unordered.js +3 -2
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +23 -13
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/auth_provider.js +2 -1
- package/lib/cmap/auth/auth_provider.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +5 -4
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +9 -5
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongocr.js +2 -2
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +32 -32
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/plain.js +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/scram.js +15 -12
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +2 -2
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +26 -10
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +9 -5
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +23 -9
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +43 -46
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +113 -15
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/connection_pool_events.js +3 -1
- package/lib/cmap/connection_pool_events.js.map +1 -1
- package/lib/cmap/errors.js +3 -3
- package/lib/cmap/errors.js.map +1 -1
- package/lib/cmap/message_stream.js +1 -1
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/metrics.js +62 -0
- package/lib/cmap/metrics.js.map +1 -0
- package/lib/cmap/stream_description.js +3 -1
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +22 -9
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/shared.js +1 -1
- package/lib/cmap/wire_protocol/shared.js.map +1 -1
- package/lib/collection.js +23 -18
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +76 -30
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +75 -68
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +47 -9
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +53 -13
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +21 -14
- package/lib/db.js.map +1 -1
- package/lib/deps.js +16 -5
- package/lib/deps.js.map +1 -1
- package/lib/encrypter.js +5 -8
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +230 -34
- package/lib/error.js.map +1 -1
- package/lib/explain.js +2 -2
- package/lib/explain.js.map +1 -1
- package/lib/gridfs/download.js +22 -47
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +4 -3
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +13 -21
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +27 -2
- package/lib/index.js.map +1 -1
- package/lib/logger.js +3 -2
- package/lib/logger.js.map +1 -1
- package/lib/mongo_client.js +5 -8
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/add_user.js +2 -3
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/aggregate.js +12 -9
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/command.js +5 -7
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/common_functions.js +1 -1
- package/lib/operations/common_functions.js.map +1 -1
- package/lib/operations/connect.js +3 -2
- package/lib/operations/connect.js.map +1 -1
- package/lib/operations/count.js +1 -1
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/count_documents.js +1 -1
- package/lib/operations/count_documents.js.map +1 -1
- package/lib/operations/delete.js +5 -5
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js +2 -2
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/estimated_document_count.js +5 -1
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/eval.js.map +1 -1
- package/lib/operations/execute_operation.js +31 -17
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +13 -9
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +9 -9
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/indexes.js +8 -3
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +5 -3
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js +2 -1
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/list_collections.js +6 -3
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/map_reduce.js +1 -1
- package/lib/operations/map_reduce.js.map +1 -1
- package/lib/operations/operation.js +3 -1
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js +2 -1
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js +4 -2
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/set_profiling_level.js +4 -2
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/update.js +12 -12
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js +6 -5
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/promise_provider.js +1 -1
- package/lib/promise_provider.js.map +1 -1
- package/lib/read_preference.js +8 -8
- package/lib/read_preference.js.map +1 -1
- package/lib/sdam/common.js +12 -10
- package/lib/sdam/common.js.map +1 -1
- package/lib/sdam/server.js +90 -25
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +9 -4
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +10 -4
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +1 -1
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +42 -21
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +7 -3
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +132 -31
- package/lib/sessions.js.map +1 -1
- package/lib/sort.js +3 -3
- package/lib/sort.js.map +1 -1
- package/lib/transactions.js +15 -7
- package/lib/transactions.js.map +1 -1
- package/lib/utils.js +60 -20
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +523 -138
- package/mongodb.ts34.d.ts +480 -141
- package/package.json +44 -48
- package/src/bson.ts +1 -0
- package/src/bulk/common.ts +83 -43
- package/src/bulk/ordered.ts +4 -3
- package/src/bulk/unordered.ts +4 -3
- package/src/change_stream.ts +46 -29
- package/src/cmap/auth/auth_provider.ts +3 -2
- package/src/cmap/auth/gssapi.ts +15 -5
- package/src/cmap/auth/mongo_credentials.ts +22 -8
- package/src/cmap/auth/mongocr.ts +3 -3
- package/src/cmap/auth/mongodb_aws.ts +52 -39
- package/src/cmap/auth/plain.ts +2 -2
- package/src/cmap/auth/scram.ts +23 -13
- package/src/cmap/auth/x509.ts +3 -3
- package/src/cmap/command_monitoring_events.ts +36 -14
- package/src/cmap/commands.ts +12 -6
- package/src/cmap/connect.ts +42 -12
- package/src/cmap/connection.ts +54 -62
- package/src/cmap/connection_pool.ts +141 -20
- package/src/cmap/connection_pool_events.ts +8 -1
- package/src/cmap/errors.ts +3 -4
- package/src/cmap/message_stream.ts +2 -4
- package/src/cmap/metrics.ts +58 -0
- package/src/cmap/stream_description.ts +6 -1
- package/src/cmap/wire_protocol/compression.ts +26 -13
- package/src/cmap/wire_protocol/shared.ts +4 -2
- package/src/collection.ts +75 -70
- package/src/connection_string.ts +97 -34
- package/src/cursor/abstract_cursor.ts +141 -104
- package/src/cursor/aggregation_cursor.ts +34 -20
- package/src/cursor/find_cursor.ts +41 -21
- package/src/db.ts +19 -18
- package/src/deps.ts +110 -22
- package/src/encrypter.ts +6 -12
- package/src/error.ts +264 -48
- package/src/explain.ts +3 -3
- package/src/gridfs/download.ts +48 -53
- package/src/gridfs/index.ts +5 -4
- package/src/gridfs/upload.ts +32 -33
- package/src/index.ts +42 -4
- package/src/logger.ts +6 -3
- package/src/mongo_client.ts +20 -23
- package/src/mongo_types.ts +19 -20
- package/src/operations/add_user.ts +4 -5
- package/src/operations/aggregate.ts +18 -17
- package/src/operations/command.ts +7 -10
- package/src/operations/common_functions.ts +2 -3
- package/src/operations/connect.ts +4 -3
- package/src/operations/count.ts +2 -2
- package/src/operations/count_documents.ts +2 -2
- package/src/operations/delete.ts +8 -6
- package/src/operations/distinct.ts +5 -3
- package/src/operations/estimated_document_count.ts +5 -1
- package/src/operations/eval.ts +1 -1
- package/src/operations/execute_operation.ts +41 -20
- package/src/operations/find.ts +25 -16
- package/src/operations/find_and_modify.ts +12 -10
- package/src/operations/indexes.ts +39 -8
- package/src/operations/insert.ts +7 -4
- package/src/operations/is_capped.ts +3 -2
- package/src/operations/list_collections.ts +9 -6
- package/src/operations/map_reduce.ts +4 -2
- package/src/operations/operation.ts +7 -2
- package/src/operations/options_operation.ts +3 -2
- package/src/operations/profiling_level.ts +5 -3
- package/src/operations/set_profiling_level.ts +9 -3
- package/src/operations/update.ts +17 -13
- package/src/operations/validate_collection.ts +7 -6
- package/src/promise_provider.ts +2 -2
- package/src/read_preference.ts +11 -9
- package/src/sdam/common.ts +11 -9
- package/src/sdam/server.ts +168 -69
- package/src/sdam/server_description.ts +16 -4
- package/src/sdam/server_selection.ts +15 -7
- package/src/sdam/srv_polling.ts +2 -2
- package/src/sdam/topology.ts +67 -36
- package/src/sdam/topology_description.ts +11 -4
- package/src/sessions.ts +194 -37
- package/src/sort.ts +6 -4
- package/src/transactions.ts +18 -9
- package/src/utils.ts +73 -20
- package/HISTORY.md +0 -2993
- package/lib/operations/find_one.js +0 -34
- package/lib/operations/find_one.js.map +0 -1
- package/src/operations/find_one.ts +0 -43
package/src/change_stream.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import Denque = require('denque');
|
|
2
|
-
import {
|
|
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<
|
|
195
|
-
|
|
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
|
|
263
|
-
'
|
|
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
|
|
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
|
-
|
|
492
|
-
this.
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
549
|
-
|
|
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
|
-
|
|
558
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 {
|
|
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
|
-
|
|
57
|
+
// TODO(NODE-3483): Replace this with MongoMethodOverrideError
|
|
58
|
+
callback(new MongoRuntimeError('`auth` method must be overridden by subclass'));
|
|
58
59
|
}
|
|
59
60
|
}
|
package/src/cmap/auth/gssapi.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { AuthProvider, AuthContext } from './auth_provider';
|
|
2
|
-
import {
|
|
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)
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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:
|
|
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:
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
package/src/cmap/auth/mongocr.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
|
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 {
|
|
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
|
|
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
|
|
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
|
|
62
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
|
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:
|
|
171
|
+
function done(creds: AWSTempCredentials) {
|
|
151
172
|
if (!creds.AccessKeyId || !creds.SecretAccessKey || !creds.Token) {
|
|
152
|
-
callback(
|
|
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)
|
|
232
|
-
|
|
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
|
-
|
|
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
|
-
|
|
281
|
+
// TODO(NODE-3483)
|
|
282
|
+
callback(new MongoRuntimeError(`Invalid JSON response: "${data}"`));
|
|
270
283
|
}
|
|
271
284
|
});
|
|
272
285
|
});
|
package/src/cmap/auth/plain.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Binary } from '../../bson';
|
|
2
2
|
import { AuthProvider, AuthContext } from './auth_provider';
|
|
3
|
-
import {
|
|
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
|
|
10
|
+
return callback(new MongoMissingCredentialsError('AuthContext must provide credentials.'));
|
|
11
11
|
}
|
|
12
12
|
const username = credentials.username;
|
|
13
13
|
const password = credentials.password;
|