Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import type {
import { createConnectionAttempt } from 'mongodb-data-service';
import { UUID } from 'bson';
import { assign, cloneDeep, isEqual, merge } from 'lodash';
import type { PreferencesAccess } from 'compass-preferences-model/provider';
import {
proxyPreferenceToProxyOptions,
type PreferencesAccess,
} from 'compass-preferences-model/provider';
import { getNotificationTriggers } from '../components/connection-status-notifications';
import { openToast, showConfirmation } from '@mongodb-js/compass-components';
import { adjustConnectionOptionsBeforeConnect } from '@mongodb-js/connection-form';
Expand Down Expand Up @@ -1588,6 +1591,9 @@ export const connect = (

const connectionAttempt = createConnectionAttempt({
logger: log.unbound,
proxyOptions: proxyPreferenceToProxyOptions(
preferences.getPreferences().proxy
),
connectFn,
});

Expand Down
1 change: 0 additions & 1 deletion packages/data-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
"@mongodb-js/devtools-connect": "^3.2.5",
"@mongodb-js/devtools-proxy-support": "^0.3.6",
"bson": "^6.7.0",
"compass-preferences-model": "^2.27.0",
"lodash": "^4.17.21",
"mongodb": "^6.8.0",
"mongodb-build-info": "^1.7.2",
Expand Down
32 changes: 20 additions & 12 deletions packages/data-service/src/connect-mongo-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@ describe('connectMongoClient', function () {
describe('prepareOIDCOptions', function () {
it('defaults allowedFlows to "auth-code"', async function () {
const options = prepareOIDCOptions({
connectionString: 'mongodb://localhost:27017',
connectionOptions: {
connectionString: 'mongodb://localhost:27017',
},
});

expect(await (options.oidc.allowedFlows as any)()).to.deep.equal([
Expand All @@ -285,9 +287,11 @@ describe('prepareOIDCOptions', function () {

it('does not override allowedFlows when set', async function () {
const options = prepareOIDCOptions({
connectionString: 'mongodb://localhost:27017',
oidc: {
allowedFlows: ['auth-code', 'device-auth'],
connectionOptions: {
connectionString: 'mongodb://localhost:27017',
oidc: {
allowedFlows: ['auth-code', 'device-auth'],
},
},
});
expect(await (options.oidc.allowedFlows as any)()).to.deep.equal([
Expand All @@ -299,9 +303,11 @@ describe('prepareOIDCOptions', function () {
it('maps ALLOWED_HOSTS on the authMechanismProperties (non-url) when enableUntrustedEndpoints is true', function () {
function actual(connectionString: string) {
return prepareOIDCOptions({
connectionString,
oidc: {
enableUntrustedEndpoints: true,
connectionOptions: {
connectionString,
oidc: {
enableUntrustedEndpoints: true,
},
},
}).authMechanismProperties;
}
Expand Down Expand Up @@ -341,20 +347,22 @@ describe('prepareOIDCOptions', function () {

it('does not set ALLOWED_HOSTS on the authMechanismProperties (non-url) when enableUntrustedEndpoints is not set', function () {
const options = prepareOIDCOptions({
connectionString: 'mongodb://localhost:27017',
connectionOptions: {
connectionString: 'mongodb://localhost:27017',
},
});

expect(options.authMechanismProperties).to.deep.equal({});
});

it('passes through a signal argument', function () {
const signal = AbortSignal.abort();
const options = prepareOIDCOptions(
{
const options = prepareOIDCOptions({
connectionOptions: {
connectionString: 'mongodb://localhost:27017',
},
signal
);
signal,
});

expect(options.oidc.signal).to.equal(signal);
});
Expand Down
40 changes: 24 additions & 16 deletions packages/data-service/src/connect-mongo-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ import {
hookLogger as hookProxyLogger,
createAgent,
} from '@mongodb-js/devtools-proxy-support';
import type { Tunnel } from '@mongodb-js/devtools-proxy-support';
import type {
DevtoolsProxyOptions,
Tunnel,
} from '@mongodb-js/devtools-proxy-support';
import EventEmitter from 'events';
import ConnectionString from 'mongodb-connection-string-url';
import _ from 'lodash';

import { redactConnectionOptions, redactConnectionString } from './redact';
import type { ConnectionOptions } from './connection-options';
import {
getCurrentApplicationProxyOptions,
getTunnelOptions,
waitForTunnelError,
} from './ssh-tunnel-helpers';
import { getTunnelOptions, waitForTunnelError } from './ssh-tunnel-helpers';
import { runCommand } from './run-command';
import type { UnboundDataServiceImplLogger } from './logger';
import { debug as _debug } from './logger';
Expand Down Expand Up @@ -65,11 +64,17 @@ function matchingAllowedHosts(
return [...new Set(suffixes)];
}

export function prepareOIDCOptions(
connectionOptions: Readonly<ConnectionOptions>,
signal?: AbortSignal,
reauthenticationHandler?: ReauthenticationHandler
): Required<
export function prepareOIDCOptions({
connectionOptions,
proxyOptions = {},
signal,
reauthenticationHandler,
}: {
connectionOptions: Readonly<ConnectionOptions>;
proxyOptions?: DevtoolsProxyOptions;
signal?: AbortSignal;
reauthenticationHandler?: ReauthenticationHandler;
}): Required<
Pick<
DevtoolsConnectOptions,
'oidc' | 'authMechanismProperties' | 'applyProxyToOIDC'
Expand Down Expand Up @@ -108,7 +113,7 @@ export function prepareOIDCOptions(
options.applyProxyToOIDC = true;
} else {
options.oidc.customHttpOptions = {
agent: createAgent(getCurrentApplicationProxyOptions()),
agent: createAgent(proxyOptions),
};
}

Expand All @@ -119,6 +124,7 @@ export function prepareOIDCOptions(

export async function connectMongoClientDataService({
connectionOptions,
proxyOptions = {},
setupListeners,
signal,
logger,
Expand All @@ -127,6 +133,7 @@ export async function connectMongoClientDataService({
reauthenticationHandler,
}: {
connectionOptions: Readonly<ConnectionOptions>;
proxyOptions?: Readonly<DevtoolsProxyOptions>;
setupListeners: (client: MongoClient) => void;
signal?: AbortSignal;
logger?: UnboundDataServiceImplLogger;
Expand All @@ -147,11 +154,12 @@ export async function connectMongoClientDataService({
redactConnectionOptions(connectionOptions)
);

const oidcOptions = prepareOIDCOptions(
const oidcOptions = prepareOIDCOptions({
connectionOptions,
proxyOptions,
signal,
reauthenticationHandler
);
reauthenticationHandler,
});

const url = connectionOptions.connectionString;
const options: DevtoolsConnectOptions = {
Expand Down Expand Up @@ -189,7 +197,7 @@ export async function connectMongoClientDataService({
// If connectionOptions.sshTunnel is not defined, the tunnel
// will also be undefined.
const tunnel = createSocks5Tunnel(
getTunnelOptions(connectionOptions),
getTunnelOptions(connectionOptions, proxyOptions),
'generate-credentials',
'mongodb://'
);
Expand Down
9 changes: 8 additions & 1 deletion packages/data-service/src/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,28 @@ import type { ConnectionOptions } from './connection-options';
import type { DataService } from './data-service';
import type { DataServiceImplLogger } from './logger';
import { DataServiceImpl } from './data-service';
import type { DevtoolsProxyOptions } from '@mongodb-js/devtools-proxy-support';

export default async function connect({
connectionOptions,
proxyOptions,
signal,
logger,
productName,
productDocsLink,
}: {
connectionOptions: ConnectionOptions;
proxyOptions?: DevtoolsProxyOptions;
signal?: AbortSignal;
logger?: DataServiceImplLogger;
productName?: string;
productDocsLink?: string;
}): Promise<DataService> {
const dataService = new DataServiceImpl(connectionOptions, logger);
const dataService = new DataServiceImpl(
connectionOptions,
logger,
proxyOptions
);
await dataService.connect({
signal,
productName,
Expand Down
9 changes: 9 additions & 0 deletions packages/data-service/src/connection-attempt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { UnboundDataServiceImplLogger } from './logger';
import connect from './connect';
import type { DataService } from './data-service';
import type { ConnectionOptions } from './connection-options';
import type { DevtoolsProxyOptions } from '@mongodb-js/devtools-proxy-support';

const { mongoLogId } = createLogger('CONNECTION-ATTEMPT');

Expand All @@ -18,16 +19,20 @@ export class ConnectionAttempt {
_connectFn: typeof connect;
_dataService: DataService | null = null;
_logger: UnboundDataServiceImplLogger;
_proxyOptions: DevtoolsProxyOptions | undefined;

constructor({
connectFn,
logger,
proxyOptions,
}: {
connectFn: typeof connect;
logger: UnboundDataServiceImplLogger;
proxyOptions?: DevtoolsProxyOptions;
}) {
this._logger = logger;
this._connectFn = connectFn;
this._proxyOptions = proxyOptions;
this._abortController = new AbortController();
}

Expand Down Expand Up @@ -61,6 +66,7 @@ export class ConnectionAttempt {
connectionOptions,
signal: this._abortController.signal,
logger: this._logger,
proxyOptions: this._proxyOptions,
});
return this._dataService;
} catch (err) {
Expand Down Expand Up @@ -127,13 +133,16 @@ export class ConnectionAttempt {

export function createConnectionAttempt({
logger,
proxyOptions,
connectFn = connect,
}: {
logger: UnboundDataServiceImplLogger;
proxyOptions: DevtoolsProxyOptions;
connectFn?: typeof connect;
}): ConnectionAttempt {
return new ConnectionAttempt({
logger,
proxyOptions,
connectFn,
});
}
11 changes: 9 additions & 2 deletions packages/data-service/src/data-service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { Tunnel } from '@mongodb-js/devtools-proxy-support';
import type {
DevtoolsProxyOptions,
Tunnel,
} from '@mongodb-js/devtools-proxy-support';
import { EventEmitter } from 'events';
import { ExplainVerbosity, ClientEncryption } from 'mongodb';
import type {
Expand Down Expand Up @@ -926,6 +929,7 @@ function op<T extends unknown[], K>(

class DataServiceImpl extends WithLogContext implements DataService {
private readonly _connectionOptions: Readonly<ConnectionOptions>;
private readonly _proxyOptions: Readonly<DevtoolsProxyOptions>;
private _isConnecting = false;
private _mongoClientConnectionOptions?: {
url: string;
Expand Down Expand Up @@ -970,11 +974,13 @@ class DataServiceImpl extends WithLogContext implements DataService {

constructor(
connectionOptions: Readonly<ConnectionOptions>,
logger?: DataServiceImplLogger
logger?: DataServiceImplLogger,
proxyOptions?: DevtoolsProxyOptions
) {
super();
this._id = id++;
this._connectionOptions = connectionOptions;
this._proxyOptions = proxyOptions ?? {};
const logComponent = 'COMPASS-DATA-SERVICE';
const logCtx = `Connection ${this._id}`;
this._logger = {
Expand Down Expand Up @@ -1465,6 +1471,7 @@ class DataServiceImpl extends WithLogContext implements DataService {
const [metadataClient, crudClient, tunnel, state, connectionOptions] =
await connectMongoClient({
connectionOptions: this._connectionOptions,
proxyOptions: this._proxyOptions,
setupListeners: this._setupListeners.bind(this),
signal,
logger: this._unboundLogger,
Expand Down
15 changes: 3 additions & 12 deletions packages/data-service/src/ssh-tunnel-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import type {
DevtoolsProxyOptions,
Tunnel,
} from '@mongodb-js/devtools-proxy-support';
import {
defaultPreferencesInstance,
proxyPreferenceToProxyOptions,
} from 'compass-preferences-model';

export async function waitForTunnelError(
tunnel: Tunnel | undefined
Expand All @@ -16,17 +12,12 @@ export async function waitForTunnelError(
});
}

export function getCurrentApplicationProxyOptions() {
return proxyPreferenceToProxyOptions(
defaultPreferencesInstance.getPreferences().proxy
);
}

export function getTunnelOptions(
connectionOptions: ConnectionOptions
connectionOptions: ConnectionOptions,
appLevelProxyOptions: DevtoolsProxyOptions
): DevtoolsProxyOptions {
if (connectionOptions.useApplicationLevelProxy) {
return getCurrentApplicationProxyOptions();
return appLevelProxyOptions;
}
if (connectionOptions.sshTunnel) {
const {
Expand Down
Loading