Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

Commit 81b5b45

Browse files
tprobinsonmbroadst
authored andcommitted
fix(uri_parser): uri-encoded auth handling
Change options and auth handling to leverage parsed URI object
1 parent 29455ca commit 81b5b45

File tree

1 file changed

+22
-39
lines changed

1 file changed

+22
-39
lines changed

lib/uri_parser.js

+22-39
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function matchesParentDomain(srvAddress, parentDomain) {
2727
}
2828

2929
/**
30-
* Lookup an `mongodb+srv` connection string, combine the parts and reparse it as a normal
30+
* Lookup a `mongodb+srv` connection string, combine the parts and reparse it as a normal
3131
* connection string.
3232
*
3333
* @param {string} uri The connection string to parse
@@ -50,8 +50,9 @@ function parseSrvConnectionString(uri, options, callback) {
5050
return callback(new MongoParseError(`Ports not accepted with '${PROTOCOL_MONGODB_SRV}' URIs`));
5151
}
5252

53-
let srvAddress = `_mongodb._tcp.${result.host}`;
54-
dns.resolveSrv(srvAddress, (err, addresses) => {
53+
// Resolve the SRV record and use the result as the list of hosts to connect to.
54+
const lookupAddress = result.host;
55+
dns.resolveSrv(`_mongodb._tcp.${lookupAddress}`, (err, addresses) => {
5556
if (err) return callback(err);
5657

5758
if (addresses.length === 0) {
@@ -66,36 +67,20 @@ function parseSrvConnectionString(uri, options, callback) {
6667
}
6768
}
6869

69-
let base = result.auth ? `mongodb://${result.auth}@` : `mongodb://`;
70-
let connectionStrings = addresses.map(
71-
(address, i) =>
72-
i === 0 ? `${base}${address.name}:${address.port}` : `${address.name}:${address.port}`
73-
);
74-
75-
let connectionString = `${connectionStrings.join(',')}/`;
76-
let connectionStringOptions = [];
77-
78-
// Add the default database if needed
79-
if (result.path) {
80-
let defaultDb = result.path.slice(1);
81-
if (defaultDb.indexOf('?') !== -1) {
82-
defaultDb = defaultDb.slice(0, defaultDb.indexOf('?'));
83-
}
84-
85-
connectionString += defaultDb;
86-
}
70+
// Convert the original URL to a non-SRV URL.
71+
result.protocol = 'mongodb';
72+
result.host = addresses.map(address => `${address.name}:${address.port}`).join(',');
8773

88-
// Default to SSL true
89-
if (!options.ssl && (!result.search || result.query['ssl'] == null)) {
90-
connectionStringOptions.push('ssl=true');
91-
}
92-
93-
// Keep original uri options
94-
if (result.search) {
95-
connectionStringOptions.push(result.search.replace('?', ''));
74+
// Default to SSL true if it's not specified.
75+
if (
76+
!('ssl' in options) &&
77+
(!result.search || !('ssl' in result.query) || result.query.ssl === null)
78+
) {
79+
result.query.ssl = true;
9680
}
9781

98-
dns.resolveTxt(result.host, (err, record) => {
82+
// Resolve TXT record and add options from there if they exist.
83+
dns.resolveTxt(lookupAddress, (err, record) => {
9984
if (err) {
10085
if (err.code !== 'ENODATA') {
10186
return callback(err);
@@ -108,23 +93,21 @@ function parseSrvConnectionString(uri, options, callback) {
10893
return callback(new MongoParseError('Multiple text records not allowed'));
10994
}
11095

111-
record = record[0];
112-
record = record.length > 1 ? record.join('') : record[0];
113-
if (record.indexOf('authSource') === -1 && record.indexOf('replicaSet') === -1) {
96+
record = qs.parse(record[0].join(''));
97+
if (Object.keys(record).some(key => key !== 'authSource' && key !== 'replicaSet')) {
11498
return callback(
11599
new MongoParseError('Text record must only set `authSource` or `replicaSet`')
116100
);
117101
}
118102

119-
connectionStringOptions.push(record);
103+
Object.assign(result.query, record);
120104
}
121105

122-
// Add any options to the connection string
123-
if (connectionStringOptions.length) {
124-
connectionString += `?${connectionStringOptions.join('&')}`;
125-
}
106+
// Set completed options back into the URL object.
107+
result.search = qs.stringify(result.query);
126108

127-
parseConnectionString(connectionString, options, callback);
109+
const finalString = URL.format(result);
110+
parseConnectionString(finalString, options, callback);
128111
});
129112
});
130113
}

0 commit comments

Comments
 (0)