diff --git a/README.md b/README.md index 69f55b9b8..7be62f2ce 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,20 @@ For example, for production, use `datasources.production.json` as follows (for e For more information on setting data source configurations for different environments, see [Environment-specific configuration](https://loopback.io/doc/en/lb3/Environment-specific-configuration.html#data-source-configuration). +### Using the mongodb+srv protocol +MongoDB supports a protocol called `mongodb+srv` for connecting to replica sets without having to give the hostname of every server in the replica set. +To use `mongodb+srv` as the protocol set the `protocol` connection property in the datasource.json to `mongodb+srv`. For example: + +```javascript +"mydb": { + "host": "myserver", + "database": "test", + "protocol": "mongodb+srv", + "connector": "mongodb" +} +``` +Note: the port is not specified when using the `mongodb+srv` protocol and will be ignored if given. + ## Security Considerations MongoDB Driver allows the `$where` operator to pass in JavaScript to execute on the Driver which can be used for NoSQL Injection. See [MongoDB: Server-side JavaScript](https://docs.mongodb.com/manual/core/server-side-javascript/) for more on this MongoDB feature. diff --git a/lib/mongodb.js b/lib/mongodb.js index 165d63582..3f7ed3dc8 100644 --- a/lib/mongodb.js +++ b/lib/mongodb.js @@ -57,6 +57,11 @@ function generateMongoDBURL(options) { options.port = options.port || 27017; options.database = options.database || options.db || 'test'; var username = options.username || options.user; + var portUrl = ''; + // only include port if not using mongodb+srv + if (options.protocol !== 'mongodb+srv') { + portUrl = ':' + options.port; + } if (username && options.password) { return ( options.protocol + @@ -66,8 +71,7 @@ function generateMongoDBURL(options) { options.password + '@' + options.hostname + - ':' + - options.port + + portUrl + '/' + options.database ); @@ -76,8 +80,7 @@ function generateMongoDBURL(options) { options.protocol + '://' + options.hostname + - ':' + - options.port + + portUrl + '/' + options.database ); diff --git a/test/mongodb.test.js b/test/mongodb.test.js index af69dc6e5..1cf2bedb8 100644 --- a/test/mongodb.test.js +++ b/test/mongodb.test.js @@ -3074,6 +3074,60 @@ describe('mongodb connector', function() { module.generateMongoDBURL.should.be.an.instanceOf(Function); }); + describe('Test generateMongoDBURL function', function() { + var module = require('../'); + context('should return correct mongodb url ', function() { + it('when only passing in database', function() { + var options = { + database: 'fakeDatabase', + }; + module.generateMongoDBURL(options).should.be.eql('mongodb://127.0.0.1:27017/fakeDatabase'); + }); + it('when protocol is mongodb and no username/password', function() { + var options = { + protocol: 'mongodb', + hostname: 'fakeHostname', + port: 9999, + database: 'fakeDatabase', + }; + module.generateMongoDBURL(options).should.be.eql('mongodb://fakeHostname:9999/fakeDatabase'); + }); + it('when protocol is mongodb and has username/password', function() { + var options = { + protocol: 'mongodb', + hostname: 'fakeHostname', + port: 9999, + database: 'fakeDatabase', + username: 'fakeUsername', + password: 'fakePassword', + }; + module.generateMongoDBURL(options).should.be.eql('mongodb://fakeUsername:fakePassword@fakeHostname:9999/fakeDatabase'); + }); + it('when protocol is mongodb+srv and no username/password', function() { + var options = { + protocol: 'mongodb+srv', + hostname: 'fakeHostname', + port: 9999, + database: 'fakeDatabase', + }; + // mongodb+srv url should not have the port in it + module.generateMongoDBURL(options).should.be.eql('mongodb+srv://fakeHostname/fakeDatabase'); + }); + it('when protocol is mongodb+srv and has username/password', function() { + var options = { + protocol: 'mongodb+srv', + hostname: 'fakeHostname', + port: 9999, + database: 'fakeDatabase', + username: 'fakeUsername', + password: 'fakePassword', + }; + // mongodb+srv url should not have the port in it + module.generateMongoDBURL(options).should.be.eql('mongodb+srv://fakeUsername:fakePassword@fakeHostname/fakeDatabase'); + }); + }); + }); + context('fieldsArrayToObj', function() { var fieldsArrayToObj = require('../').fieldsArrayToObj; it('should export the fieldsArrayToObj function', function() {