From a30c81745a300209d6f348427b3093780a5bbf97 Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Fri, 11 Mar 2016 16:10:44 -0800 Subject: [PATCH] Add URI encoding to mongo auth parameters The mongodb driver requires auth values be URI encoded: https://github.com/mongodb/node-mongodb-native/commit/044063097dc4dd5e6cf3a3574c555fec7559d38b This uses node's built-in url module to encode the auth portion, by parsing and re-formatting it, which causes special characters to get URI encoded properly: https://nodejs.org/api/url.html#url_escaped_characters This is all a bit silly since mongodb just takes our passed uri, and runs it through the same url parser again, but not before explicitly erroring on '@' characters in the uri. This is similiar to #148 (reverted by #297), but with much less code, and hopefully less breakage. Also, note that `uri_decode_auth` is no longer needed. That was removed in the above referenced node-mongodb-native commit. I've tested this on usernames and passwords with @, !, +, and a space. Presumably this would also work with usernames and passwords that are already URI encoded (since parseUrl will simply unescape it, and formatUrl will escape it again). --- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index d3d2bc7e..74143547 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -1,6 +1,7 @@ import MongoCollection from './MongoCollection'; import MongoSchemaCollection from './MongoSchemaCollection'; +import {parse as parseUrl, format as formatUrl} from 'url'; let mongodb = require('mongodb'); let MongoClient = mongodb.MongoClient; @@ -25,7 +26,11 @@ export class MongoStorageAdapter { return this.connectionPromise; } - this.connectionPromise = MongoClient.connect(this._uri, this._options).then(database => { + // parsing and re-formatting causes the auth value (if there) to get URI + // encoded + const encodedUri = formatUrl(parseUrl(this._uri)); + + this.connectionPromise = MongoClient.connect(encodedUri, this._options).then(database => { this.database = database; }); return this.connectionPromise;