diff --git a/README.md b/README.md index 34fe002f06..7078f78cce 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ variable. For detailed instructions for each of our supported platforms, please --tlsCertificateSelector [arg] TLS Certificate in system store (Windows and macOS only) --tlsCRLFile [arg] Specifies the .pem file that contains the Certificate Revocation List --tlsDisabledProtocols [arg] Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2] + --tlsUseSystemCA Load the operating system trusted certificate list API version options: diff --git a/package-lock.json b/package-lock.json index 07e77bd93e..2ed8b82bdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7826,9 +7826,9 @@ "dev": true }, "boxednode": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/boxednode/-/boxednode-1.10.5.tgz", - "integrity": "sha512-J3mwm+GgMJE7YuOwalIudnRPgu2TsnJieTLP7QD+bDX1mYP4nsCgvujyjhP/++k9SE6ICIB+9y9RJKvesqCVTw==", + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/boxednode/-/boxednode-1.10.6.tgz", + "integrity": "sha512-XTKdOp0VNg+iXcK1ZqmE5HgweTBxhQZhFVBxlAmhieaPJ5KLF/SKNEfxvbrYllluSMaFc0lvuZdLXADx15YA2Q==", "dev": true, "requires": { "@pkgjs/nv": "^0.1.0", @@ -7900,9 +7900,9 @@ "dev": true }, "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -8745,12 +8745,11 @@ } }, "cli-progress": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.9.1.tgz", - "integrity": "sha512-AXxiCe2a0Lm0VN+9L0jzmfQSkcZm5EYspfqXKaSIQKqIk+0hnkZ3/v1E9B39mkD6vYhKih3c/RPsJBSwq9O99Q==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.10.0.tgz", + "integrity": "sha512-kLORQrhYCAtUPLZxqsAt2YJGOvRdt34+O6jl5cQGb7iF3dM55FQZlTR+rQyIK9JUcO9bBMwZsTlND+3dmFU2Cw==", "dev": true, "requires": { - "colors": "^1.1.2", "string-width": "^4.2.0" } }, @@ -14908,9 +14907,9 @@ "dev": true }, "gyp-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gyp-parser/-/gyp-parser-1.0.2.tgz", - "integrity": "sha512-fIngnMoqriCvgGLzs0fDSo8DpJlyjVuGJ3GW2CTDER28dObnlr6MpJvxNUdksiHOuDdDjyL0reDzogLXs9Ykow==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gyp-parser/-/gyp-parser-1.0.3.tgz", + "integrity": "sha512-nUQ9gCahY2JA1EhYzHbR4buVVhQaCDPqpq3Zp3CHCeM7ZmXerdMRDjtlBLTSmje79i97Bqaw8ga1ZwsrUeXDkQ==", "dev": true }, "handlebars": { @@ -17016,9 +17015,9 @@ } }, "keyv": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.4.tgz", - "integrity": "sha512-vqNHbAc8BBsxk+7QBYLW0Y219rWcClspR6WSeoHYKG5mnsSoOH+BL1pWq02DDCVdvvuUny5rkBlzMRzoqc+GIg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz", + "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==", "dev": true, "requires": { "json-buffer": "3.0.1" diff --git a/package.json b/package.json index b4dda5aa78..5c7c07deb7 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "@typescript-eslint/parser": "^4.28.4", "aws-sdk": "^2.674.0", "axios": "^0.21.1", - "boxednode": "^1.10.5", + "boxednode": "^1.10.6", "browserify": "^16.5.0", "chai": "^4.2.0", "command-exists": "^1.2.9", diff --git a/packages/build/src/compile/signable-compiler.ts b/packages/build/src/compile/signable-compiler.ts index d94cb203da..6100feafad 100644 --- a/packages/build/src/compile/signable-compiler.ts +++ b/packages/build/src/compile/signable-compiler.ts @@ -73,6 +73,10 @@ export class SignableCompiler { path: await findModulePath('service-provider-server', 'os-dns-native'), requireRegexp: /\bos_dns_native\.node$/ }; + // Warning! Until https://jira.mongodb.org/browse/MONGOSH-990, + // packages/service-provider-server *also* has a copy of these. + // We use the versions included in packages/cli-repl here, so these + // should be kept in sync! const winCAAddon = process.platform === 'win32' ? { path: await findModulePath('cli-repl', 'win-export-certificate-and-key'), requireRegexp: /\bwin_export_cert\.node$/ diff --git a/packages/cli-repl/README.md b/packages/cli-repl/README.md index 0c8fb13bbc..3e5e23014f 100644 --- a/packages/cli-repl/README.md +++ b/packages/cli-repl/README.md @@ -41,6 +41,7 @@ CLI interface for [MongoDB Shell][mongosh], an extension to Node.js REPL with Mo --tlsAllowInvalidCertificates Allow connections to servers with invalid certificates --tlsCertificateSelector [arg] TLS Certificate in system store (Windows and macOS only) --tlsDisabledProtocols [arg] Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2] + --tlsUseSystemCA Load the operating system trusted certificate list API version options: diff --git a/packages/cli-repl/package-lock.json b/packages/cli-repl/package-lock.json index 66441bde9a..553cf8e6d5 100644 --- a/packages/cli-repl/package-lock.json +++ b/packages/cli-repl/package-lock.json @@ -455,21 +455,13 @@ } }, "macos-export-certificate-and-key": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/macos-export-certificate-and-key/-/macos-export-certificate-and-key-1.0.2.tgz", - "integrity": "sha512-QTMdyHSxxHAQ/q4H/oBZpEQHKsrSdC0KMYmkhfCbvs9DQY3rIsV6AW6nNzBn30TmBrzaM5EqDT5fhJkhhCdf/A==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/macos-export-certificate-and-key/-/macos-export-certificate-and-key-1.1.1.tgz", + "integrity": "sha512-J2g0dJRLG3DghmdCkbJnif/zPmSylj6ql//xBYff5allzNlHPnWxRoyho9XznBYLbPJw4jZlKjMO69jtV8VC7Q==", "optional": true, "requires": { "bindings": "^1.5.0", - "node-addon-api": "^1.1.0" - }, - "dependencies": { - "node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "optional": true - } + "node-addon-api": "^4.3.0" } }, "md5": { @@ -550,9 +542,15 @@ } }, "node-addon-api": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", - "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "optional": true + }, + "node-forge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz", + "integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==", "optional": true }, "pretty-bytes": { @@ -635,13 +633,14 @@ } }, "win-export-certificate-and-key": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/win-export-certificate-and-key/-/win-export-certificate-and-key-1.0.4.tgz", - "integrity": "sha512-txsQkCibcGQ1/q8A1EWMxF6Y3KT/KhEnRWJmeM6U4fPTbRal7mW4d03JJoL2zpvTpENiqvs5W1wppX+suSxm/g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/win-export-certificate-and-key/-/win-export-certificate-and-key-1.1.1.tgz", + "integrity": "sha512-wvF1DKlbt/PLOSdnKzIqv0Ipj+87n2VYOJFbkqBoN7l3l244reT7Lf6+Dnu86bYVWoVpq3ZZG417OLNHFnkP6A==", "optional": true, "requires": { "bindings": "^1.5.0", - "node-addon-api": "^3.1.0" + "node-addon-api": "^4.3.0", + "node-forge": "^1.2.1" } }, "yargs-parser": { diff --git a/packages/cli-repl/package.json b/packages/cli-repl/package.json index 9611dda9d0..fa00efcf1b 100644 --- a/packages/cli-repl/package.json +++ b/packages/cli-repl/package.json @@ -82,8 +82,8 @@ "moment": "^2.29.1" }, "optionalDependencies": { - "macos-export-certificate-and-key": "^1.0.2", - "win-export-certificate-and-key": "^1.0.4", + "macos-export-certificate-and-key": "^1.1.1", + "win-export-certificate-and-key": "^1.1.1", "get-console-process-list": "^1.0.4" } } diff --git a/packages/cli-repl/src/arg-mapper.ts b/packages/cli-repl/src/arg-mapper.ts index 9ee24d85bc..cb4ddaaefc 100644 --- a/packages/cli-repl/src/arg-mapper.ts +++ b/packages/cli-repl/src/arg-mapper.ts @@ -1,5 +1,5 @@ import { CommonErrors, MongoshInvalidInputError, MongoshUnimplementedError } from '@mongosh/errors'; -import { CliOptions, MongoClientOptions } from '@mongosh/service-provider-server'; +import { CliOptions, DevtoolsConnectOptions } from '@mongosh/service-provider-server'; import setValue from 'lodash.set'; /** @@ -29,6 +29,7 @@ const MAPPINGS = { tlsCRLFile: 'sslCRL', tlsCertificateKeyFile: 'tlsCertificateKeyFile', tlsCertificateKeyFilePassword: 'tlsCertificateKeyFilePassword', + tlsUseSystemCA: 'useSystemCA', username: 'auth.username', verbose: { opt: 'loggerLevel', val: 'debug' } }; @@ -45,8 +46,8 @@ function isExistingMappingKey(key: string, options: CliOptions): key is keyof ty * * @returns {} The driver options. */ -function mapCliToDriver(options: CliOptions): MongoClientOptions { - const nodeOptions: MongoClientOptions = {}; +function mapCliToDriver(options: CliOptions): DevtoolsConnectOptions { + const nodeOptions: DevtoolsConnectOptions = {}; for (const cliOption of Object.keys(MAPPINGS)) { if (isExistingMappingKey(cliOption, options)) { const mapping = MAPPINGS[cliOption as keyof typeof MAPPINGS]; diff --git a/packages/cli-repl/src/arg-parser.ts b/packages/cli-repl/src/arg-parser.ts index 29dfc6f572..4ca7caef65 100644 --- a/packages/cli-repl/src/arg-parser.ts +++ b/packages/cli-repl/src/arg-parser.ts @@ -69,6 +69,7 @@ const OPTIONS = { 'tlsAllowInvalidCertificates', 'tlsAllowInvalidHostnames', 'tlsFIPSMode', + 'tlsUseSystemCA', 'verbose', 'version' ], diff --git a/packages/cli-repl/src/cli-repl.ts b/packages/cli-repl/src/cli-repl.ts index e032477d58..146d864043 100644 --- a/packages/cli-repl/src/cli-repl.ts +++ b/packages/cli-repl/src/cli-repl.ts @@ -2,7 +2,7 @@ import { MongoshInternalError, MongoshRuntimeError, MongoshWarning } from '@mong import { redactURICredentials } from '@mongosh/history'; import i18n from '@mongosh/i18n'; import { bson, AutoEncryptionOptions } from '@mongosh/service-provider-core'; -import { CliOptions, CliServiceProvider, MongoClientOptions } from '@mongosh/service-provider-server'; +import { CliOptions, CliServiceProvider, DevtoolsConnectOptions } from '@mongosh/service-provider-server'; import { SnippetManager } from '@mongosh/snippet-manager'; import { Editor } from '@mongosh/editor'; import { redactSensitiveData } from '@mongosh/history'; @@ -159,10 +159,10 @@ class CliRepl implements MongoshIOProvider { * information, external editor, and finally start the repl. * * @param {string} driverUri - The driver URI. - * @param {MongoClientOptions} driverOptions - The driver options. + * @param {DevtoolsConnectOptions} driverOptions - The driver options. */ // eslint-disable-next-line complexity - async start(driverUri: string, driverOptions: MongoClientOptions): Promise { + async start(driverUri: string, driverOptions: DevtoolsConnectOptions): Promise { const { version } = require('../package.json'); await this.verifyNodeVersion(); @@ -451,9 +451,9 @@ class CliRepl implements MongoshIOProvider { * Connect to the cluster. * * @param {string} driverUri - The driver URI. - * @param {MongoClientOptions} driverOptions - The driver options. + * @param {DevtoolsConnectOptions} driverOptions - The driver options. */ - async connect(driverUri: string, driverOptions: MongoClientOptions): Promise { + async connect(driverUri: string, driverOptions: DevtoolsConnectOptions): Promise { if (!this.cliOptions.nodb && !this.cliOptions.quiet) { this.output.write(i18n.__(CONNECTING) + '\t\t' + this.clr(redactURICredentials(driverUri), 'mongosh:uri') + '\n'); } @@ -523,11 +523,11 @@ class CliRepl implements MongoshIOProvider { /** * Is the password missing from the options? * - * @param {MongoClientOptions} driverOptions - The driver options. + * @param {DevtoolsConnectOptions} driverOptions - The driver options. * * @returns {boolean} If the password is missing. */ - isPasswordMissingOptions(driverOptions: MongoClientOptions): boolean { + isPasswordMissingOptions(driverOptions: DevtoolsConnectOptions): boolean { return !!( driverOptions.auth && driverOptions.auth.username && @@ -556,7 +556,7 @@ class CliRepl implements MongoshIOProvider { * object is present with a truthy username. This is required by the driver, e.g. * in the case of password-less Kerberos authentication. */ - ensurePasswordFieldIsPresentInAuth(driverOptions: MongoClientOptions): void { + ensurePasswordFieldIsPresentInAuth(driverOptions: DevtoolsConnectOptions): void { if (driverOptions.auth && driverOptions.auth.username && !('password' in driverOptions.auth)) { driverOptions.auth.password = undefined; } @@ -566,7 +566,7 @@ class CliRepl implements MongoshIOProvider { * Require the user to enter a password. * * @param {string} driverUrl - The driver URI. - * @param {MongoClientOptions} driverOptions - The driver options. + * @param {DevtoolsConnectOptions} driverOptions - The driver options. */ async requirePassword(): Promise { const passwordPromise = askpassword({ diff --git a/packages/cli-repl/src/constants.ts b/packages/cli-repl/src/constants.ts index eb3893dd69..40d20d4344 100644 --- a/packages/cli-repl/src/constants.ts +++ b/packages/cli-repl/src/constants.ts @@ -53,6 +53,7 @@ export const USAGE = ` --tlsCertificateSelector [arg] ${i18n.__('cli-repl.args.tlsCertificateSelector')} --tlsCRLFile [arg] ${i18n.__('cli-repl.args.tlsCRLFile')} --tlsDisabledProtocols [arg] ${i18n.__('cli-repl.args.tlsDisabledProtocols')} + --tlsUseSystemCA ${i18n.__('cli-repl.args.tlsUseSystemCA')} ${clr(i18n.__('cli-repl.args.apiVersionOptions'), 'mongosh:section-header')} diff --git a/packages/cli-repl/test/e2e-tls.spec.ts b/packages/cli-repl/test/e2e-tls.spec.ts index 2d299d8376..e6d95f0cca 100644 --- a/packages/cli-repl/test/e2e-tls.spec.ts +++ b/packages/cli-repl/test/e2e-tls.spec.ts @@ -2,7 +2,7 @@ import { assert, expect } from 'chai'; import { promises as fs } from 'fs'; import path from 'path'; import { skipIfEnvServerVersion, startTestServer } from '../../../testing/integration-testing-hooks'; -import { useTmpdir, setTemporaryHomeDirectory } from './repl-helpers'; +import { useTmpdir, setTemporaryHomeDirectory, readReplLogfile } from './repl-helpers'; import { TestShell } from './test-shell'; import { promisify } from 'util'; import rimraf from 'rimraf'; @@ -54,6 +54,33 @@ describe('e2e TLS', () => { }); function registerTlsTests({ tlsMode: serverTlsModeOption, tlsModeValue: serverTlsModeValue, tlsCertificateFile: serverTlsCertificateKeyFileOption, tlsCaFile: serverTlsCAFileOption }) { + let homedir: string; + let env: Record; + let logBasePath: string; + const tmpdir = useTmpdir(); + + before(function() { + const homeInfo = setTemporaryHomeDirectory(); + homedir = homeInfo.homedir; + env = homeInfo.env; + + if (process.platform === 'win32') { + logBasePath = path.resolve(homedir, 'local', 'mongodb', 'mongosh'); + } else { + logBasePath = path.resolve(homedir, '.mongodb', 'mongosh'); + } + }); + + after(async function() { + try { + await promisify(rimraf)(homedir); + } catch (err) { + // On Windows in CI, this can fail with EPERM for some reason. + // If it does, just log the error instead of failing all tests. + console.error('Could not remove fake home directory:', err); + } + }); + context('connecting without client cert to server with valid cert', () => { after(async() => { // mlaunch has some trouble interpreting all the server options correctly, @@ -156,14 +183,82 @@ describe('e2e TLS', () => { expect(result.state).to.equal('exit'); shell.assertContainsOutput('certificate revoked'); }); + + it('works with system CA on Linux with SSL_CERT_DIR', async function() { + if (process.platform !== 'linux') { + return this.skip(); + } + await fs.mkdir(path.join(tmpdir.path, 'certs'), { recursive: true }); + await fs.copyFile(CA_CERT, path.join(tmpdir.path, 'certs', 'somefilename.crt')); + const shell = TestShell.start({ + args: [ + `${await server.connectionString()}?serverSelectionTimeoutMS=1500`, + '--tls', '--tlsUseSystemCA' + ], + env: { + ...env, + SSL_CERT_DIR: path.join(tmpdir.path, 'certs') + ':/nonexistent/other/path' + } + }); + + const prompt = await shell.waitForPromptOrExit(); + expect(prompt.state).to.equal('prompt'); + + const logPath = path.join(logBasePath, `${shell.logId}_log`); + const logContents = await readReplLogfile(logPath); + expect(logContents.find(line => line.id === 1_000_000_049).attr.asyncFallbackError) + .to.equal(null); // Ensure that system CA loading happened asynchronously. + }); + + it('works with system CA on Linux with SSL_CERT_FILE', async function() { + if (process.platform !== 'linux') { + return this.skip(); + } + await fs.mkdir(path.join(tmpdir.path, 'certs'), { recursive: true }); + await fs.copyFile(CA_CERT, path.join(tmpdir.path, 'certs', 'somefilename.crt')); + const shell = TestShell.start({ + args: [ + `${await server.connectionString()}?serverSelectionTimeoutMS=1500`, + '--tls', '--tlsUseSystemCA' + ], + env: { + ...env, + SSL_CERT_FILE: path.join(tmpdir.path, 'certs', 'somefilename.crt') + } + }); + + const prompt = await shell.waitForPromptOrExit(); + expect(prompt.state).to.equal('prompt'); + + const logPath = path.join(logBasePath, `${shell.logId}_log`); + const logContents = await readReplLogfile(logPath); + expect(logContents.find(line => line.id === 1_000_000_049).attr.asyncFallbackError) + .to.equal(null); // Ensure that system CA loading happened asynchronously. + }); + + it('fails on macOS/Windows with system CA', async function() { + // No good way to programmatically add certs to the system CA from our tests. + if (process.platform !== 'darwin' && process.platform !== 'win32') { + return this.skip(); + } + const shell = TestShell.start({ + args: [ + `${await server.connectionString()}?serverSelectionTimeoutMS=1500`, + '--tls', '--tlsUseSystemCA' + ], + env + }); + + const prompt = await shell.waitForPromptOrExit(); + expect(prompt.state).to.equal('exit'); + + const logPath = path.join(logBasePath, `${shell.logId}_log`); + const logContents = await readReplLogfile(logPath); + expect(logContents.find(line => line.id === 1_000_000_049)).to.exist; + }); }); context('connecting with client cert to server with valid cert', () => { - const tmpdir = useTmpdir(); - let homedir: string; - let env: Record; - let logBasePath: string; - after(async function() { const shell = TestShell.start({ args: [ @@ -178,13 +273,6 @@ describe('e2e TLS', () => { await shell.waitForExit(); await TestShell.cleanup.call(this); - try { - await promisify(rimraf)(homedir); - } catch (err) { - // On Windows in CI, this can fail with EPERM for some reason. - // If it does, just log the error instead of failing all tests. - console.error('Could not remove fake home directory:', err); - } }); const server = startTestServer( @@ -199,15 +287,6 @@ describe('e2e TLS', () => { if (process.env.MONGOSH_TEST_FORCE_API_STRICT) { return this.skip(); // createUser is unversioned } - const homeInfo = setTemporaryHomeDirectory(); - homedir = homeInfo.homedir; - env = homeInfo.env; - - if (process.platform === 'win32') { - logBasePath = path.resolve(homedir, 'local', 'mongodb', 'mongosh'); - } else { - logBasePath = path.resolve(homedir, '.mongodb', 'mongosh'); - } /* connect with cert to create user */ const shell = TestShell.start({ args: [ diff --git a/packages/i18n/src/locales/en_US.ts b/packages/i18n/src/locales/en_US.ts index 46dc816386..ed0be3d782 100644 --- a/packages/i18n/src/locales/en_US.ts +++ b/packages/i18n/src/locales/en_US.ts @@ -44,6 +44,7 @@ const translations: Catalog = { tlsCertificateSelector: 'TLS Certificate in system store (Windows and macOS only)', tlsCRLFile: 'Specifies the .pem file that contains the Certificate Revocation List', tlsDisabledProtocols: 'Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2]', + tlsUseSystemCA: 'Load the operating system trusted certificate list', apiVersionOptions: 'API version options:', apiVersion: 'Specifies the API version to connect with', apiStrict: 'Use strict API version mode', diff --git a/packages/logging/package-lock.json b/packages/logging/package-lock.json index 68bc7be525..16d5745bee 100644 --- a/packages/logging/package-lock.json +++ b/packages/logging/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@mongodb-js/devtools-connect": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-1.2.3.tgz", - "integrity": "sha512-lbfzwwVppHN2IZvKBNuGT3IKEpKYcK2z1jLk8lTicmJALImwTIZoAFlTCriYlJJFEF3SsU9If7n4yCB0urXEAQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-1.2.4.tgz", + "integrity": "sha512-y2P3rU6FgH05GthJvNenfj5qQJuFAtWafHKI3oqiq11jhhAvJJc7PLP+L8BASMUDViaGOxO/n7QWDfP2e95UFA==", "requires": { "os-dns-native": "^1.2.0", "resolve-mongodb-srv": "^1.1.1", diff --git a/packages/logging/package.json b/packages/logging/package.json index e8c8a0a1a6..fb80ec7c98 100644 --- a/packages/logging/package.json +++ b/packages/logging/package.json @@ -17,7 +17,7 @@ "node": ">=12.4.0" }, "dependencies": { - "@mongodb-js/devtools-connect": "^1.2.3", + "@mongodb-js/devtools-connect": "^1.2.4", "@mongosh/errors": "0.0.0-dev.0", "@mongosh/history": "0.0.0-dev.0", "@mongosh/types": "0.0.0-dev.0", diff --git a/packages/logging/src/setup-logger-and-telemetry.ts b/packages/logging/src/setup-logger-and-telemetry.ts index b85041721c..00280e487b 100644 --- a/packages/logging/src/setup-logger-and-telemetry.ts +++ b/packages/logging/src/setup-logger-and-telemetry.ts @@ -390,4 +390,6 @@ export function setupLoggerAndTelemetry( }); // NB: mongoLogId(1_000_000_045) is used in cli-repl itself + // NB: mongoLogId(1_000_000_034) through mongoLogId(1_000_000_042) are used in devtools-connect + // NB: mongoLogId(1_000_000_049) is used in devtools-connect } diff --git a/packages/node-runtime-worker-thread/src/index.ts b/packages/node-runtime-worker-thread/src/index.ts index 16d2adeb08..00507be913 100644 --- a/packages/node-runtime-worker-thread/src/index.ts +++ b/packages/node-runtime-worker-thread/src/index.ts @@ -2,13 +2,13 @@ /* ^^^ we test the dist directly, so isntanbul can't calculate the coverage correctly */ import { ChildProcess, spawn, SpawnOptionsWithoutStdio } from 'child_process'; -import { MongoClientOptions } from '@mongosh/service-provider-core'; +import type { DevtoolsConnectOptions } from '@mongosh/service-provider-server'; import { Runtime, RuntimeEvaluationListener, RuntimeEvaluationResult } from '@mongosh/browser-runtime-core'; -import { MongoshBus } from '@mongosh/types'; +import type { MongoshBus } from '@mongosh/types'; import path from 'path'; import { EventEmitter, once } from 'events'; import { kill } from './spawn-child-from-source'; @@ -48,7 +48,7 @@ function parseStderrToError(str: string): Error | null { class WorkerRuntime implements Runtime { private initOptions: { uri: string; - driverOptions: MongoClientOptions; + driverOptions: DevtoolsConnectOptions; cliOptions: { nodb?: boolean }; spawnOptions: SpawnOptionsWithoutStdio; }; @@ -74,7 +74,7 @@ class WorkerRuntime implements Runtime { constructor( uri: string, - driverOptions: MongoClientOptions = {}, + driverOptions: DevtoolsConnectOptions = {}, cliOptions: { nodb?: boolean } = {}, spawnOptions: SpawnOptionsWithoutStdio = {}, eventEmitter: MongoshBus = new EventEmitter() diff --git a/packages/node-runtime-worker-thread/src/worker-runtime.ts b/packages/node-runtime-worker-thread/src/worker-runtime.ts index 2cd805b02d..dac12ec952 100644 --- a/packages/node-runtime-worker-thread/src/worker-runtime.ts +++ b/packages/node-runtime-worker-thread/src/worker-runtime.ts @@ -8,14 +8,16 @@ import { RuntimeEvaluationResult } from '@mongosh/browser-runtime-core'; import { ElectronRuntime } from '@mongosh/browser-runtime-electron'; -import { - MongoClientOptions, +import type { ServiceProvider } from '@mongosh/service-provider-core'; -import { CompassServiceProvider } from '@mongosh/service-provider-server'; +import { + CompassServiceProvider, + DevtoolsConnectOptions +} from '@mongosh/service-provider-server'; import { exposeAll, createCaller } from './rpc'; import { serializeEvaluationResult } from './serializer'; -import { MongoshBus } from '@mongosh/types'; +import type { MongoshBus } from '@mongosh/types'; import { Lock, UNLOCKED } from './lock'; import { runInterruptible, InterruptHandle } from 'interruptor'; @@ -73,7 +75,7 @@ const messageBus: MongoshBus = Object.assign( export type WorkerRuntime = Runtime & { init( uri: string, - driverOptions?: MongoClientOptions, + driverOptions?: DevtoolsConnectOptions, cliOptions?: { nodb?: boolean } ): Promise; @@ -83,7 +85,7 @@ export type WorkerRuntime = Runtime & { const workerRuntime: WorkerRuntime = { async init( uri: string, - driverOptions: MongoClientOptions = {}, + driverOptions: DevtoolsConnectOptions = {}, cliOptions: { nodb?: boolean } = {} ) { // XXX The types here work out fine, and tsc accepts this code diff --git a/packages/service-provider-server/package-lock.json b/packages/service-provider-server/package-lock.json index 8af9a257fe..4c8ea67246 100644 --- a/packages/service-provider-server/package-lock.json +++ b/packages/service-provider-server/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@mongodb-js/devtools-connect": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-1.2.3.tgz", - "integrity": "sha512-lbfzwwVppHN2IZvKBNuGT3IKEpKYcK2z1jLk8lTicmJALImwTIZoAFlTCriYlJJFEF3SsU9If7n4yCB0urXEAQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-1.2.4.tgz", + "integrity": "sha512-y2P3rU6FgH05GthJvNenfj5qQJuFAtWafHKI3oqiq11jhhAvJJc7PLP+L8BASMUDViaGOxO/n7QWDfP2e95UFA==", "requires": { "os-dns-native": "^1.2.0", "resolve-mongodb-srv": "^1.1.1", diff --git a/packages/service-provider-server/package.json b/packages/service-provider-server/package.json index 9f0f0c31eb..063bdb7745 100644 --- a/packages/service-provider-server/package.json +++ b/packages/service-provider-server/package.json @@ -38,7 +38,7 @@ ] }, "dependencies": { - "@mongodb-js/devtools-connect": "^1.2.3", + "@mongodb-js/devtools-connect": "^1.2.4", "@mongosh/errors": "0.0.0-dev.0", "@mongosh/service-provider-core": "0.0.0-dev.0", "@mongosh/types": "0.0.0-dev.0", diff --git a/packages/service-provider-server/src/cli-service-provider.ts b/packages/service-provider-server/src/cli-service-provider.ts index 0de8de183f..548cc693c0 100644 --- a/packages/service-provider-server/src/cli-service-provider.ts +++ b/packages/service-provider-server/src/cli-service-provider.ts @@ -79,7 +79,7 @@ import { AutoEncryptionOptions } from '@mongosh/service-provider-core'; -import { connectMongoClient } from '@mongodb-js/devtools-connect'; +import { connectMongoClient, DevtoolsConnectOptions } from '@mongodb-js/devtools-connect'; import { MongoshCommandFailed, MongoshInternalError } from '@mongosh/errors'; import type { MongoshBus } from '@mongosh/types'; import { ensureMongoNodeNativePatchesAreApplied } from './mongodb-patches'; @@ -123,7 +123,7 @@ type ExtraConnectionInfo = ReturnType & { fcv?: string }; const DEFAULT_DRIVER_OPTIONS: MongoClientOptions = Object.freeze({ }); -function processDriverOptions(opts: MongoClientOptions): MongoClientOptions { +function processDriverOptions(opts: DevtoolsConnectOptions): DevtoolsConnectOptions { return { ...DEFAULT_DRIVER_OPTIONS, ...opts }; } @@ -151,7 +151,7 @@ class CliServiceProvider extends ServiceProviderCore implements ServiceProvider static async connect( this: typeof CliServiceProvider, uri: string, - driverOptions: MongoClientOptions = {}, + driverOptions: DevtoolsConnectOptions = {}, cliOptions: { nodb?: boolean } = {}, bus: MongoshBus = new EventEmitter() // TODO: Change VSCode to pass all arguments, then remove defaults ): Promise { @@ -182,7 +182,7 @@ class CliServiceProvider extends ServiceProviderCore implements ServiceProvider public readonly initialDb: string; public mongoClient: MongoClient; // public for testing private readonly uri?: ConnectionString; - private currentClientOptions: MongoClientOptions; + private currentClientOptions: DevtoolsConnectOptions; private dbcache: WeakMap>; public baseCmdOptions: OperationOptions; // public for testing public fle: FLE | undefined; @@ -217,7 +217,7 @@ class CliServiceProvider extends ServiceProviderCore implements ServiceProvider } catch { /* not empty */ } } - async getNewConnection(uri: string, options: MongoClientOptions = {}): Promise { + async getNewConnection(uri: string, options: DevtoolsConnectOptions = {}): Promise { const connectionString = new ConnectionString(uri); const clientOptions = processDriverOptions(options); const mongoClient = await connectMongoClient( @@ -1167,3 +1167,4 @@ class CliServiceProvider extends ServiceProviderCore implements ServiceProvider } export default CliServiceProvider; +export { DevtoolsConnectOptions }; diff --git a/packages/service-provider-server/src/compass/compass-service-provider.ts b/packages/service-provider-server/src/compass/compass-service-provider.ts index 3c0b5c60a2..ac680c2152 100644 --- a/packages/service-provider-server/src/compass/compass-service-provider.ts +++ b/packages/service-provider-server/src/compass/compass-service-provider.ts @@ -1,6 +1,6 @@ -import CliServiceProvider from '../cli-service-provider'; +import CliServiceProvider, { DevtoolsConnectOptions } from '../cli-service-provider'; import { MongoClient } from 'mongodb'; -import { ReplPlatform, MongoClientOptions } from '@mongosh/service-provider-core'; +import { ReplPlatform } from '@mongosh/service-provider-core'; import ConnectionString from 'mongodb-connection-string-url'; import { EventEmitter } from 'events'; @@ -26,7 +26,7 @@ class CompassServiceProvider extends CliServiceProvider { constructor( mongoClient: MongoClient, bus: EventEmitter, - driverOptions?: MongoClientOptions, + driverOptions?: DevtoolsConnectOptions, uri?: ConnectionString ) { super(mongoClient, bus, driverOptions, uri); diff --git a/packages/service-provider-server/src/index.ts b/packages/service-provider-server/src/index.ts index 52b1b3e0bb..966a9a1656 100644 --- a/packages/service-provider-server/src/index.ts +++ b/packages/service-provider-server/src/index.ts @@ -1,4 +1,4 @@ -import CliServiceProvider from './cli-service-provider'; +import CliServiceProvider, { DevtoolsConnectOptions } from './cli-service-provider'; import CompassServiceProvider from './compass/compass-service-provider'; import { DEFAULT_DB, CliOptions, generateUri, MongoClientOptions } from '@mongosh/service-provider-core'; export { @@ -8,5 +8,5 @@ export { CliOptions, generateUri, MongoClientOptions, - MongoClientOptions as NodeOptions // TODO: Update VSCode to use MongoClientOptions + DevtoolsConnectOptions }; diff --git a/packages/types/package-lock.json b/packages/types/package-lock.json index 43730eb475..09b93e011a 100644 --- a/packages/types/package-lock.json +++ b/packages/types/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@mongodb-js/devtools-connect": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-1.2.3.tgz", - "integrity": "sha512-lbfzwwVppHN2IZvKBNuGT3IKEpKYcK2z1jLk8lTicmJALImwTIZoAFlTCriYlJJFEF3SsU9If7n4yCB0urXEAQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-1.2.4.tgz", + "integrity": "sha512-y2P3rU6FgH05GthJvNenfj5qQJuFAtWafHKI3oqiq11jhhAvJJc7PLP+L8BASMUDViaGOxO/n7QWDfP2e95UFA==", "requires": { "os-dns-native": "^1.2.0", "resolve-mongodb-srv": "^1.1.1", diff --git a/packages/types/package.json b/packages/types/package.json index 062079f9a7..5291545acf 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -32,6 +32,6 @@ "unitTestsOnly": true }, "dependencies": { - "@mongodb-js/devtools-connect": "^1.2.3" + "@mongodb-js/devtools-connect": "^1.2.4" } }