Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mongodb with replicaSet and authSource connect but fail to perform query using a connectionString #6209

Closed
npjonath opened this issue Jun 5, 2020 · 9 comments

Comments

@npjonath
Copy link

npjonath commented Jun 5, 2020

Issue type:

[ ] question
[ x ] bug report
[ ] feature request
[ ] documentation issue

Database system/driver:

[ ] cordova
[ x ] mongodb
[ ] mssql
[ ] mysql / mariadb
[ ] oracle
[ ] postgres
[ ] cockroachdb
[ ] sqlite
[ ] sqljs
[ ] react-native
[ ] expo

TypeORM version:

[ x ] latest
[ ] @next
[ ] 0.x.x (or put your version here)

Steps to reproduce or a small repository showing the problem:
Hi,

I'm running on production with a mongo cluster (4.2) on kubernetes.
I try to setup a project with typeorm and run it in production. (note : It's running fine in local env without a replicaSet)

In production, by using a connectionString as url parameters, I got the following problems :

// This typeorm config don't work
{
              type: 'mongodb',
               entities: [__dirname + '/**/*.entity{.ts,.js}'],
               url: 'mongodb://api-scheduler:********@custom-mongodb-replicaset.mongo:27017/api-scheduler?replicaSet=rs-sched',
               useNewUrlParser: true,
               useUnifiedTopology: true,
               synchronize: true,
}

Error : MongoError: not authorized on api-scheduler?authSource=admin&replicaSet=rs-sched to execute command { find: "jobs", filter: { status: { $in: [ "NEW", "WAITING_UPLOAD", "READY_TO_INGEST" ] }, type: "UPDATE", retryCount: { $lt: 3 } }, limit: 1, returnKey: false, showRecordId: false, lsid: { id: UUID("d9b954dc-5d37-4403-8258-2c60bc3cac9a") }, $clusterTime: { clusterTime: Timestamp(1591372379, 38), signature: { hash: BinData(0, 7145026E7D24FD4BB0E0E1EFDA889D51DF4232F4), keyId: 6797378919558283275 } }, $db: "api-scheduler?authSource=admin&replicaSet=rs-sched" }

The strange things is in the $db name at the end of the error message, right ?

// This typeorm config is ok
{
              type: 'mongodb',
               entities: [__dirname + '/**/*.entity{.ts,.js}'],
               useUnifiedTopology: true,
               synchronize: true,
               host: 'custom-mongodb-replicaset.mongo',
               port: 27017,
               username: 'api-scheduler',
               password: '******',
               replicaSet: 'rs-sched',
               database: 'api-scheduler',
               authSource: 'admin'
}

Is there anyway to make it work properly with connectionString ?

@ballinette
Copy link

I can confirm we have the same issue.
It worked until version 0.2.24

@ballinette
Copy link

should it be a regression introduced by #5640 ?

@ballinette
Copy link

ballinette commented Jun 18, 2020

More investigations: I guess the issue is here: https://github.com/typeorm/typeorm/blob/master/src/driver/DriverUtils.ts#L65
Maybe this method should be refactored with some regexp treatments... 🤔

I'm not an expert with regular expressions and even less with the typeorm database urls formatting...

but something like that could work (probably needs some huge improvements) :

private static parseConnectionUrl(url: string) {
  const regexp = '^(?<type>[a-zA-Z]+):\\/\\/' +
                '((?<username>[^:@]+)(:(?<password>[^@]+))?@)?' +
                '(?<host>[^:/]+)(:(?<port>[^/]+))?' +
                '(\\/(?<database>[^?]+))?' +
                '(\\?(?<queryParams>.+))?$'
  const match = url.match(new RegExp(regexp));
  if (match.groups.port != undefined) {
    match.groups.port = parseInt(match.groups.port);
  }
  return match.groups || {};
}

with this regexp : https://regexper.com/#%5E%28%5Ba-zA-Z%5D%2B%29%3A%5C%2F%5C%2F%28%28%5B%5E%3A%40%5D%2B%29%28%3A%28%5B%5E%40%5D%2B%29%29%3F%40%29%3F%28%5B%5E%3A%2F%5D%2B%29%28%3A%28%5B%5E%2F%5D%2B%29%29%3F%28%5C%2F%28%5B%5E%3F%5D%2B%29%29%3F%28%5C%3F%28.%2B%29%29%3F%24'

@npjonath
Copy link
Author

npjonath commented Jun 19, 2020

@ballinette this regex don't match my example of connectionString (which is valid). missing the options part.

@ballinette
Copy link

sure, the queryParams should then be parsed to get all the options.
My sample code is only on first one-shot step, and I'm not sure it suits all settings combinations of all database types...

@npjonath
Copy link
Author

Any update of that point ? it make Typeorm not ready for production.

@danmana
Copy link
Contributor

danmana commented Jul 23, 2020

Related to #6389

Closed by #6390 (not included in any release yet ...)

Note that this just fixes the database name parsing, but does not pick up the query params as options, so DriverUtils.buildDriverOptions will not contain the query params.

As far as I can tell, this is not a problem as typeorm does not seem to expect it.
Typeorm only uses the result to get the database name (and credentials in a couple of places, which worked before).
The underlying Mongo driver parses the URL again when connecting, so it will pick up correctly the query params.

Though buildDriverOptions does not feel complete as it is now, it does seem to work.
As @ruscon mentioned, it would probably be a good idea to use something like https://github.com/vitaly-t/connection-string

@ismailyenigul
Copy link

I can confirm we have the same issue.
It worked until version 0.2.24

I had the same issue with the latest version and 0.2.24 also worked me.

@imnotjames
Copy link
Contributor

Is this still a problem - I think we fixed a lot of the connection string problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants