From 3e2c58f565a02ba58450b54fcbcec5f0bca84ec4 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 8 Feb 2022 15:59:45 -0500 Subject: [PATCH 01/14] fix parsing of read preference tags --- src/connection_string.ts | 24 +++++++++++++----------- test/unit/connection_string.test.ts | 19 ++++++++++++++----- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index 54a9ab3fed9..6fd4bb72d29 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -228,7 +228,7 @@ function toRecord(value: string): Record { return record; } -class CaseInsensitiveMap extends Map { +class CaseInsensitiveMap extends Map { constructor(entries: Array<[string, any]> = []) { super(entries.map(([k, v]) => [k.toLowerCase(), v])); } @@ -262,7 +262,7 @@ export function parseOptions( const mongoOptions = Object.create(null); mongoOptions.hosts = isSRV ? [] : hosts.map(HostAddress.fromString); - const urlOptions = new CaseInsensitiveMap(); + const urlOptions = new CaseInsensitiveMap(); if (url.pathname !== '/' && url.pathname !== '') { const dbName = decodeURIComponent( @@ -326,13 +326,16 @@ export function parseOptions( for (const key of allKeys) { const values = []; if (objectOptions.has(key)) { - values.push(objectOptions.get(key)); + const options = [objectOptions.get(key)].flat(); + values.push(...options); } if (urlOptions.has(key)) { - values.push(...urlOptions.get(key)); + const options = urlOptions.get(key) ?? []; + values.push(...options); } if (DEFAULT_OPTIONS.has(key)) { - values.push(DEFAULT_OPTIONS.get(key)); + const options = [DEFAULT_OPTIONS.get(key)].flat(); + values.push(...options); } allOptions.set(key, values); } @@ -478,12 +481,11 @@ export function parseOptions( throw new MongoParseError('Can only specify both of proxy username/password or neither'); } - if ( - urlOptions.get('proxyHost')?.length > 1 || - urlOptions.get('proxyPort')?.length > 1 || - urlOptions.get('proxyUsername')?.length > 1 || - urlOptions.get('proxyPassword')?.length > 1 - ) { + const proxyOptions = ['proxyHost', 'proxyPort', 'proxyUsername', 'proxyPassword'].map( + key => urlOptions.get(key) ?? [] + ); + + if (proxyOptions.some(options => options.length > 1)) { throw new MongoParseError( 'Proxy options cannot be specified multiple times in the connection string' ); diff --git a/test/unit/connection_string.test.ts b/test/unit/connection_string.test.ts index 9de26fd23b5..8328910d8f7 100644 --- a/test/unit/connection_string.test.ts +++ b/test/unit/connection_string.test.ts @@ -46,11 +46,20 @@ describe('Connection String', function () { expect(options.hosts[0].port).to.equal(27017); }); - it('should parse multiple readPreferenceTags', function () { - const options = parseOptions( - 'mongodb://hostname?readPreferenceTags=bar:foo&readPreferenceTags=baz:bar' - ); - expect(options.readPreference.tags).to.deep.equal([{ bar: 'foo' }, { baz: 'bar' }]); + context('readPreferenceTags', function () { + it('should parse multiple readPreferenceTags when passed in the uri', () => { + const options = parseOptions( + 'mongodb://hostname?readPreferenceTags=bar:foo&readPreferenceTags=baz:bar' + ); + expect(options.readPreference.tags).to.deep.equal([{ bar: 'foo' }, { baz: 'bar' }]); + }); + + it('should parse multiple readPreferenceTags when passed in options object', () => { + const options = parseOptions('mongodb://hostname?', { + readPreferenceTags: [{ bar: 'foo' }, { baz: 'bar' }] + }); + expect(options.readPreference.tags).to.deep.equal([{ bar: 'foo' }, { baz: 'bar' }]); + }); }); it('should parse boolean values', function () { From ae98239fb8fd4a61d29040e4cafb521f51cff7cb Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 9 Feb 2022 09:43:46 -0500 Subject: [PATCH 02/14] refactor the parsing a bit --- src/connection_string.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index 6fd4bb72d29..35a996844ee 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -326,7 +326,9 @@ export function parseOptions( for (const key of allKeys) { const values = []; if (objectOptions.has(key)) { - const options = [objectOptions.get(key)].flat(); + const options = Array.isArray(objectOptions.get(key)) + ? objectOptions.get(key) + : [objectOptions.get(key)]; values.push(...options); } if (urlOptions.has(key)) { @@ -334,7 +336,9 @@ export function parseOptions( values.push(...options); } if (DEFAULT_OPTIONS.has(key)) { - const options = [DEFAULT_OPTIONS.get(key)].flat(); + const options = Array.isArray(DEFAULT_OPTIONS.get(key)) + ? DEFAULT_OPTIONS.get(key) + : [DEFAULT_OPTIONS.get(key)]; values.push(...options); } allOptions.set(key, values); From c9c0b56fe33f835b92e00eacecfd038a057ecdf0 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 9 Feb 2022 14:15:58 -0500 Subject: [PATCH 03/14] clean up logic when flattening options object --- src/connection_string.ts | 29 +++++++++------------ test/unit/assorted/uri_options.spec.test.ts | 6 ++--- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index 35a996844ee..5ef29e49f85 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -204,6 +204,13 @@ function getUint(name: string, value: unknown): number { return parsedValue; } + +function toArray(value: T): T[]; +function toArray(value: T[]): T[]; +function toArray(value: T | T[]): T[] { + return Array.isArray(value) ? value : [value]; +} + function toRecord(value: string): Record { const record = Object.create(null); const keyValuePairs = value.split(','); @@ -324,23 +331,11 @@ export function parseOptions( ]); for (const key of allKeys) { - const values = []; - if (objectOptions.has(key)) { - const options = Array.isArray(objectOptions.get(key)) - ? objectOptions.get(key) - : [objectOptions.get(key)]; - values.push(...options); - } - if (urlOptions.has(key)) { - const options = urlOptions.get(key) ?? []; - values.push(...options); - } - if (DEFAULT_OPTIONS.has(key)) { - const options = Array.isArray(DEFAULT_OPTIONS.get(key)) - ? DEFAULT_OPTIONS.get(key) - : [DEFAULT_OPTIONS.get(key)]; - values.push(...options); - } + const values = [objectOptions, urlOptions, DEFAULT_OPTIONS].flatMap(optionsObject => { + const options = optionsObject.get(key) ?? []; + return toArray(options); + }); + allOptions.set(key, values); } diff --git a/test/unit/assorted/uri_options.spec.test.ts b/test/unit/assorted/uri_options.spec.test.ts index 49b4fd2cc92..f7f25db0a16 100644 --- a/test/unit/assorted/uri_options.spec.test.ts +++ b/test/unit/assorted/uri_options.spec.test.ts @@ -28,10 +28,7 @@ describe('URI option spec tests', function () { 'tlsDisableCertificateRevocationCheck can be set to true', 'tlsDisableCertificateRevocationCheck can be set to false', 'tlsDisableOCSPEndpointCheck can be set to true', - 'tlsDisableOCSPEndpointCheck can be set to false', - - // TODO(NODE-3813): read preference tag issue: parsing rack:1 as rack:true - 'Valid read preference options are parsed correctly' + 'tlsDisableOCSPEndpointCheck can be set to false' ]; const testsThatDoNotThrowOnWarn = [ @@ -60,6 +57,7 @@ describe('URI option spec tests', function () { for (const test of suite.tests) { it(`${test.description}`, function () { + console.error(test); if (skipTests.includes(test.description)) { return this.skip(); } From 4295b5a1eb704141ac581289d318291c7ed91788 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 9 Feb 2022 14:19:45 -0500 Subject: [PATCH 04/14] remove console.error --- test/unit/assorted/uri_options.spec.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/assorted/uri_options.spec.test.ts b/test/unit/assorted/uri_options.spec.test.ts index f7f25db0a16..8d965a54c03 100644 --- a/test/unit/assorted/uri_options.spec.test.ts +++ b/test/unit/assorted/uri_options.spec.test.ts @@ -57,7 +57,6 @@ describe('URI option spec tests', function () { for (const test of suite.tests) { it(`${test.description}`, function () { - console.error(test); if (skipTests.includes(test.description)) { return this.skip(); } From 3fe640d4e1516477e4b0ea60a5f3b9fe104717be Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 9 Feb 2022 14:17:24 -0500 Subject: [PATCH 05/14] fix implicit type conversion issue in options parser --- src/connection_string.ts | 30 ++++++++++++++++-------------- test/tools/uri_spec_runner.ts | 6 ++++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index 5ef29e49f85..ed015c53fe6 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -204,13 +204,24 @@ function getUint(name: string, value: unknown): number { return parsedValue; } - function toArray(value: T): T[]; function toArray(value: T[]): T[]; function toArray(value: T | T[]): T[] { return Array.isArray(value) ? value : [value]; } +function parseType(value: string): number | boolean | string { + try { + return getBoolean('', value); + } catch { + try { + return getInt('', value); + } catch { + return value; + } + } +} + function toRecord(value: string): Record { const record = Object.create(null); const keyValuePairs = value.split(','); @@ -219,18 +230,7 @@ function toRecord(value: string): Record { if (value == null) { throw new MongoParseError('Cannot have undefined values in key value pairs'); } - try { - // try to get a boolean - record[key] = getBoolean('', value); - } catch { - try { - // try to get a number - record[key] = getInt('', value); - } catch { - // keep value as a string - record[key] = value; - } - } + record[key] = value; } return record; } @@ -632,7 +632,9 @@ export const OPTIONS = { target: 'credentials', transform({ options, values: [value] }): MongoCredentials { if (typeof value === 'string') { - value = toRecord(value); + value = Object.fromEntries( + Object.entries(toRecord(value)).map(([key, value]) => [key, parseType(value)]) + ); } if (!isRecord(value)) { throw new MongoParseError('AuthMechanismProperties must be an object'); diff --git a/test/tools/uri_spec_runner.ts b/test/tools/uri_spec_runner.ts index 8a3fbecdd46..e5a9342dbad 100644 --- a/test/tools/uri_spec_runner.ts +++ b/test/tools/uri_spec_runner.ts @@ -221,6 +221,12 @@ export function executeUriValidationTest( .to.have.nested.property(expectedProp) .deep.equal(optionValue); break; + case 'maxStalenessSeconds': + expectedProp = 'readPreference.maxStalenessSeconds'; + expect(options, `${errorMessage} ${optionKey} -> ${expectedProp}`) + .to.have.nested.property(expectedProp) + .deep.equal(optionValue); + break; //** WRITE CONCERN OPTIONS **/ case 'w': From d23b27f06e455db5548462777bf10a3de3841b7b Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Thu, 10 Feb 2022 11:17:07 -0500 Subject: [PATCH 06/14] Refactor toArray to use OneOrMore utility type --- src/connection_string.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index ed015c53fe6..dd602ab6b1c 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -3,6 +3,7 @@ import * as fs from 'fs'; import ConnectionString from 'mongodb-connection-string-url'; import { URLSearchParams } from 'url'; +import type { OneOrMore } from '.'; import type { Document } from './bson'; import { MongoCredentials } from './cmap/auth/mongo_credentials'; import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './cmap/auth/providers'; @@ -204,9 +205,8 @@ function getUint(name: string, value: unknown): number { return parsedValue; } -function toArray(value: T): T[]; -function toArray(value: T[]): T[]; -function toArray(value: T | T[]): T[] { +/** Wrap a single value in an array if the value is not an array */ +function toArray(value: OneOrMore): T[] { return Array.isArray(value) ? value : [value]; } From 43a6a3db11e2398f46fd68694d02b3ba7174b14b Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Thu, 10 Feb 2022 13:52:25 -0500 Subject: [PATCH 07/14] Validate authMechanismProperties --- src/connection_string.ts | 62 ++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index dd602ab6b1c..de2121ae7c4 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -185,8 +185,22 @@ const FALSEHOODS = new Set(['false', 'f', '0', 'n', 'no', '-1']); function getBoolean(name: string, value: unknown): boolean { if (typeof value === 'boolean') return value; const valueString = String(value).toLowerCase(); - if (TRUTHS.has(valueString)) return true; - if (FALSEHOODS.has(valueString)) return false; + if (TRUTHS.has(valueString)) { + if (valueString !== 'true') { + emitWarning( + `deprecated value for ${name} : ${valueString} - please update to ${name} : true instead` + ); + } + return true; + } + if (FALSEHOODS.has(valueString)) { + if (valueString !== 'false') { + emitWarning( + `deprecated value for ${name} : ${valueString} - please update to ${name} : false instead` + ); + } + return false; + } throw new MongoParseError(`Expected ${name} to be stringified boolean value, got: ${value}`); } @@ -210,29 +224,35 @@ function toArray(value: OneOrMore): T[] { return Array.isArray(value) ? value : [value]; } -function parseType(value: string): number | boolean | string { - try { - return getBoolean('', value); - } catch { - try { - return getInt('', value); - } catch { - return value; - } - } -} - -function toRecord(value: string): Record { - const record = Object.create(null); +function* parseObjectString(value: string) { const keyValuePairs = value.split(','); for (const keyValue of keyValuePairs) { const [key, value] = keyValue.split(':'); if (value == null) { throw new MongoParseError('Cannot have undefined values in key value pairs'); } - record[key] = value; + + yield [key, value]; + } +} + +function* parseAuthMechanismParameters(stringValue: string) { + const validKeys = [ + 'SERVICE_NAME', + 'SERVICE_REALM', + 'CANONICALIZE_HOST_NAME', + 'AWS_SESSION_TOKEN' + ]; + + for (const [key, value] of parseObjectString(stringValue)) { + if (validKeys.includes(key)) { + if (key === 'CANONICALIZE_HOST_NAME') { + yield [key, getBoolean(key, value)]; + } else { + yield [key, value]; + } + } } - return record; } class CaseInsensitiveMap extends Map { @@ -632,9 +652,7 @@ export const OPTIONS = { target: 'credentials', transform({ options, values: [value] }): MongoCredentials { if (typeof value === 'string') { - value = Object.fromEntries( - Object.entries(toRecord(value)).map(([key, value]) => [key, parseType(value)]) - ); + value = Object.fromEntries(parseAuthMechanismParameters(value)); } if (!isRecord(value)) { throw new MongoParseError('AuthMechanismProperties must be an object'); @@ -968,7 +986,7 @@ export const OPTIONS = { for (const tag of values) { const readPreferenceTag: TagSet = Object.create(null); if (typeof tag === 'string') { - for (const [k, v] of Object.entries(toRecord(tag))) { + for (const [k, v] of parseObjectString(tag)) { readPreferenceTag[k] = v; } } From f48e47737c64688e92006184a56cd09be7ac47f5 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Thu, 10 Feb 2022 14:20:56 -0500 Subject: [PATCH 08/14] rename parseobjectstring --- src/connection_string.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index de2121ae7c4..f042e7d5dca 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -224,7 +224,7 @@ function toArray(value: OneOrMore): T[] { return Array.isArray(value) ? value : [value]; } -function* parseObjectString(value: string) { +function* entriesFromString(value: string) { const keyValuePairs = value.split(','); for (const keyValue of keyValuePairs) { const [key, value] = keyValue.split(':'); @@ -244,7 +244,7 @@ function* parseAuthMechanismParameters(stringValue: string) { 'AWS_SESSION_TOKEN' ]; - for (const [key, value] of parseObjectString(stringValue)) { + for (const [key, value] of entriesFromString(stringValue)) { if (validKeys.includes(key)) { if (key === 'CANONICALIZE_HOST_NAME') { yield [key, getBoolean(key, value)]; @@ -986,7 +986,7 @@ export const OPTIONS = { for (const tag of values) { const readPreferenceTag: TagSet = Object.create(null); if (typeof tag === 'string') { - for (const [k, v] of parseObjectString(tag)) { + for (const [k, v] of entriesFromString(tag)) { readPreferenceTag[k] = v; } } From b8b8a0393d08cbdab9259b9fcb35e9bae6894ec5 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Thu, 10 Feb 2022 16:48:02 -0500 Subject: [PATCH 09/14] create authMechanismProperties object as Object.null --- src/connection_string.ts | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index f042e7d5dca..5c98f90981e 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -236,25 +236,6 @@ function* entriesFromString(value: string) { } } -function* parseAuthMechanismParameters(stringValue: string) { - const validKeys = [ - 'SERVICE_NAME', - 'SERVICE_REALM', - 'CANONICALIZE_HOST_NAME', - 'AWS_SESSION_TOKEN' - ]; - - for (const [key, value] of entriesFromString(stringValue)) { - if (validKeys.includes(key)) { - if (key === 'CANONICALIZE_HOST_NAME') { - yield [key, getBoolean(key, value)]; - } else { - yield [key, value]; - } - } - } -} - class CaseInsensitiveMap extends Map { constructor(entries: Array<[string, any]> = []) { super(entries.map(([k, v]) => [k.toLowerCase(), v])); @@ -652,7 +633,26 @@ export const OPTIONS = { target: 'credentials', transform({ options, values: [value] }): MongoCredentials { if (typeof value === 'string') { - value = Object.fromEntries(parseAuthMechanismParameters(value)); + const validKeys = [ + 'SERVICE_NAME', + 'SERVICE_REALM', + 'CANONICALIZE_HOST_NAME', + 'AWS_SESSION_TOKEN' + ]; + + const properties = Object.create(null); + + for (const [key, _value] of entriesFromString(value)) { + if (validKeys.includes(key)) { + if (key === 'CANONICALIZE_HOST_NAME') { + properties[key] = getBoolean(key, _value); + } else { + properties[key] = _value; + } + } + } + + value = properties; } if (!isRecord(value)) { throw new MongoParseError('AuthMechanismProperties must be an object'); From aa5fda74e1424cb645d2596b8aba143646bfc710 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Fri, 11 Feb 2022 11:19:23 -0500 Subject: [PATCH 10/14] use emitwarningonce instead of emitwarning --- src/connection_string.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index 5c98f90981e..d710d1105a6 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -28,7 +28,7 @@ import { AnyOptions, Callback, DEFAULT_PK_FACTORY, - emitWarning, + emitWarningOnce, HostAddress, isRecord, makeClientMetadata, @@ -187,7 +187,7 @@ function getBoolean(name: string, value: unknown): boolean { const valueString = String(value).toLowerCase(); if (TRUTHS.has(valueString)) { if (valueString !== 'true') { - emitWarning( + emitWarningOnce( `deprecated value for ${name} : ${valueString} - please update to ${name} : true instead` ); } @@ -195,7 +195,7 @@ function getBoolean(name: string, value: unknown): boolean { } if (FALSEHOODS.has(valueString)) { if (valueString !== 'false') { - emitWarning( + emitWarningOnce( `deprecated value for ${name} : ${valueString} - please update to ${name} : false instead` ); } From 98fb89e0c91f48f22e8d53fadb4e0c537703ac13 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Fri, 11 Feb 2022 12:09:05 -0500 Subject: [PATCH 11/14] Address PR comments --- src/connection_string.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index d710d1105a6..12ea0c0286b 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -28,6 +28,7 @@ import { AnyOptions, Callback, DEFAULT_PK_FACTORY, + emitWarning, emitWarningOnce, HostAddress, isRecord, @@ -640,19 +641,21 @@ export const OPTIONS = { 'AWS_SESSION_TOKEN' ]; - const properties = Object.create(null); + const mechanismProperties = Object.create(null); for (const [key, _value] of entriesFromString(value)) { if (validKeys.includes(key)) { if (key === 'CANONICALIZE_HOST_NAME') { - properties[key] = getBoolean(key, _value); + mechanismProperties[key] = getBoolean(key, _value); } else { - properties[key] = _value; + mechanismProperties[key] = _value; } } } - value = properties; + return MongoCredentials.merge(options.credentials, { + mechanismProperties + }); } if (!isRecord(value)) { throw new MongoParseError('AuthMechanismProperties must be an object'); From 98b1448673d31a6299e9eb078c960cb53a4c9516 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Fri, 11 Feb 2022 13:19:57 -0500 Subject: [PATCH 12/14] Update import --- src/connection_string.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index 12ea0c0286b..5555b1dbd07 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -3,7 +3,6 @@ import * as fs from 'fs'; import ConnectionString from 'mongodb-connection-string-url'; import { URLSearchParams } from 'url'; -import type { OneOrMore } from '.'; import type { Document } from './bson'; import { MongoCredentials } from './cmap/auth/mongo_credentials'; import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './cmap/auth/providers'; @@ -20,6 +19,7 @@ import { ServerApi, ServerApiVersion } from './mongo_client'; +import type { OneOrMore } from './mongo_types'; import { PromiseProvider } from './promise_provider'; import { ReadConcern, ReadConcernLevel } from './read_concern'; import { ReadPreference, ReadPreferenceMode } from './read_preference'; From 9edcfe6f4cde02bbd1669984c581933fa9132d6c Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Fri, 11 Feb 2022 13:30:25 -0500 Subject: [PATCH 13/14] Add lint rule to prevent '.' imports --- .eslintrc.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.eslintrc.json b/.eslintrc.json index e0215ff9882..bc8863df6dd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -59,6 +59,17 @@ "global" ], "@typescript-eslint/no-explicit-any": "off", + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": ".", + "message": "Please import directly from the relevant file instead." + } + ] + } + ], "no-restricted-syntax": [ "error", { From 54c5560a473728343dee1eb42486ec9a8a19abfe Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Fri, 11 Feb 2022 15:11:41 -0500 Subject: [PATCH 14/14] revert new logic when parsing authMechanismProperties --- src/connection_string.ts | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/connection_string.ts b/src/connection_string.ts index 5555b1dbd07..8aa44bc1951 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -632,24 +632,15 @@ export const OPTIONS = { }, authMechanismProperties: { target: 'credentials', - transform({ options, values: [value] }): MongoCredentials { - if (typeof value === 'string') { - const validKeys = [ - 'SERVICE_NAME', - 'SERVICE_REALM', - 'CANONICALIZE_HOST_NAME', - 'AWS_SESSION_TOKEN' - ]; - + transform({ options, values: [optionValue] }): MongoCredentials { + if (typeof optionValue === 'string') { const mechanismProperties = Object.create(null); - for (const [key, _value] of entriesFromString(value)) { - if (validKeys.includes(key)) { - if (key === 'CANONICALIZE_HOST_NAME') { - mechanismProperties[key] = getBoolean(key, _value); - } else { - mechanismProperties[key] = _value; - } + for (const [key, value] of entriesFromString(optionValue)) { + try { + mechanismProperties[key] = getBoolean(key, value); + } catch { + mechanismProperties[key] = value; } } @@ -657,10 +648,10 @@ export const OPTIONS = { mechanismProperties }); } - if (!isRecord(value)) { + if (!isRecord(optionValue)) { throw new MongoParseError('AuthMechanismProperties must be an object'); } - return MongoCredentials.merge(options.credentials, { mechanismProperties: value }); + return MongoCredentials.merge(options.credentials, { mechanismProperties: optionValue }); } }, authSource: {