@@ -6,8 +6,13 @@ import { promisify } from 'util';
6
6
import { MongoCredentials } from '../../src/cmap/auth/mongo_credentials' ;
7
7
import { AUTH_MECHS_AUTH_SRC_EXTERNAL , AuthMechanism } from '../../src/cmap/auth/providers' ;
8
8
import { parseOptions , resolveSRVRecord } from '../../src/connection_string' ;
9
- import { MongoDriverError , MongoInvalidArgumentError , MongoParseError } from '../../src/error' ;
10
- import { MongoOptions } from '../../src/mongo_client' ;
9
+ import {
10
+ MongoAPIError ,
11
+ MongoDriverError ,
12
+ MongoInvalidArgumentError ,
13
+ MongoParseError
14
+ } from '../../src/error' ;
15
+ import { MongoClient , MongoOptions } from '../../src/mongo_client' ;
11
16
12
17
describe ( 'Connection String' , function ( ) {
13
18
it ( 'should not support auth passed with user' , function ( ) {
@@ -89,6 +94,37 @@ describe('Connection String', function () {
89
94
expect ( options . credentials . source ) . to . equal ( '$external' ) ;
90
95
} ) ;
91
96
97
+ it ( 'should omit credentials option when the only authSource is provided' , function ( ) {
98
+ let options = parseOptions ( `mongodb://a/?authSource=someDb` ) ;
99
+ expect ( options ) . to . not . have . property ( 'credentials' ) ;
100
+ options = parseOptions ( `mongodb+srv://a/?authSource=someDb` ) ;
101
+ expect ( options ) . to . not . have . property ( 'credentials' ) ;
102
+ } ) ;
103
+
104
+ it ( 'should omit credentials and not throw a MongoAPIError if the only auth related option is authSource' , async ( ) => {
105
+ // The error we're looking to **not** see is
106
+ // `new MongoInvalidArgumentError('No AuthProvider for ${credentials.mechanism} defined.')`
107
+ // in `prepareHandshakeDocument` and/or `performInitialHandshake`.
108
+ // Neither function is exported currently but if I did export them because of the inlined callbacks
109
+ // I think I would need to mock quite a bit of internals to get down to that layer.
110
+ // My thinking is I can lean on server selection failing for th unit tests to assert we at least don't get an error related to auth.
111
+ const client = new MongoClient ( 'mongodb://localhost:123/?authSource=someDb' , {
112
+ serverSelectionTimeoutMS : 500
113
+ } ) ;
114
+
115
+ let thrownError : Error ;
116
+ try {
117
+ // relies on us not running a mongod on port 123, fairly likely assumption
118
+ await client . connect ( ) ;
119
+ } catch ( error ) {
120
+ thrownError = error ;
121
+ }
122
+
123
+ // We should fail to connect, not fail to find an auth provider thus we should not find a MongoAPIError
124
+ expect ( thrownError ) . to . not . be . instanceOf ( MongoAPIError ) ;
125
+ expect ( client . options ) . to . not . have . a . property ( 'credentials' ) ;
126
+ } ) ;
127
+
92
128
it ( 'should parse a numeric authSource with variable width' , function ( ) {
93
129
const options = parseOptions ( 'mongodb://test@localhost/?authSource=0001' ) ;
94
130
expect ( options . credentials . source ) . to . equal ( '0001' ) ;
@@ -334,5 +370,21 @@ describe('Connection String', function () {
334
370
expect ( options ) . property ( 'credentials' ) . to . equal ( credentials ) ;
335
371
expect ( options ) . to . have . nested . property ( 'credentials.source' , 'admin' ) ;
336
372
} ) ;
373
+
374
+ it ( 'should retain specified authSource with no provided credentials' , async function ( ) {
375
+ makeStub ( 'authSource=thisShouldBeAuthSource' ) ;
376
+ const credentials = { } ;
377
+ const options = {
378
+ credentials,
379
+ srvHost : 'test.mock.test.build.10gen.cc' ,
380
+ srvServiceName : 'mongodb' ,
381
+ userSpecifiedAuthSource : false
382
+ } as MongoOptions ;
383
+
384
+ await resolveSRVRecordAsync ( options as any ) ;
385
+ expect ( options ) . to . have . nested . property ( 'credentials.username' , '' ) ;
386
+ expect ( options ) . to . have . nested . property ( 'credentials.mechanism' , 'DEFAULT' ) ;
387
+ expect ( options ) . to . have . nested . property ( 'credentials.source' , 'thisShouldBeAuthSource' ) ;
388
+ } ) ;
337
389
} ) ;
338
390
} ) ;
0 commit comments