Skip to content

Commit dfd34ad

Browse files
committed
Merge branch 'COMPASS-9546-open-diagram' of https://github.com/mongodb-js/compass into COMPASS-9546-open-diagram
2 parents f658ed2 + 7e6a8a4 commit dfd34ad

File tree

11 files changed

+104
-50
lines changed

11 files changed

+104
-50
lines changed

.evergreen/functions.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ functions:
731731
test-web-sandbox-atlas-cloud:
732732
- command: shell.exec
733733
# It can take a very long time for Atlas cluster to get deployed
734-
timeout_secs: 2400
734+
timeout_secs: 3600 # 1 hour
735735
params:
736736
working_dir: src
737737
shell: bash
@@ -746,6 +746,9 @@ functions:
746746
MCLI_ORG_ID: ${e2e_tests_mcli_org_id}
747747
MCLI_PROJECT_ID: ${e2e_tests_mcli_project_id}
748748
MCLI_OPS_MANAGER_URL: ${e2e_tests_mcli_ops_manager_url}
749+
# CCS connection / op running time is slower than allowed timeouts
750+
COMPASS_E2E_MOCHA_TIMEOUT: '720000' # 12 min
751+
COMPASS_E2E_WEBDRIVER_WAITFOR_TIMEOUT: '360000' # 6 min
749752
script: |
750753
set -e
751754
# Load environment variables

THIRD-PARTY-NOTICES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
The following third-party software is used by and included in **Mongodb Compass**.
2-
This document was automatically generated on Mon Jul 21 2025.
2+
This document was automatically generated on Tue Jul 22 2025.
33

44
## List of dependencies
55

configs/webpack-config-compass/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ const sharedIgnoreWarnings: NonNullable<Configuration['ignoreWarnings']> = [
4545
/the request of a dependency is an expression/,
4646
// Optional, platform-specific dependencies (mostly from driver)
4747
/Module not found.+?(mongo_crypt_v1.(dll|so|dylib)|@mongodb-js\/zstd|aws-crt|gcp-metadata)/,
48+
// Optional, comes from emotion trying to (safely) use react apis that we
49+
// don't have in React 17
50+
/export 'useInsertionEffect'/,
4851
];
4952

5053
const sharedResolveOptions = (

docs/tracking-plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
> the tracking plan for the specific Compass version you can use the following
77
> URL: `https://github.com/mongodb-js/compass/blob/<compass version>/docs/tracking-plan.md`
88
9-
Generated on Mon, Jul 21, 2025
9+
Generated on Tue, Jul 22, 2025
1010

1111
## Table of Contents
1212

packages/compass-app-stores/src/stores/instance-store.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,13 @@ export function createInstancesStore(
101101
> = {},
102102
{ connectionId }: { connectionId?: string } = {}
103103
) => {
104-
let isFirstRun: boolean | undefined;
105-
106104
try {
107105
if (!connectionId) {
108106
throw new Error('No connectionId provided');
109107
}
110108
const instance =
111109
instancesManager.getMongoDBInstanceForConnection(connectionId);
112110
const dataService = connections.getDataServiceForConnection(connectionId);
113-
isFirstRun = instance.status === 'initial';
114111
await instance.refresh({
115112
dataService,
116113
...refreshOptions,
@@ -123,7 +120,7 @@ export function createInstancesStore(
123120
{
124121
message: (err as Error).message,
125122
connectionId: connectionId,
126-
isFirstRun,
123+
isFirstRun: refreshOptions.firstRun,
127124
}
128125
);
129126
// The `instance.refresh` method is catching all expected errors: we treat
@@ -137,7 +134,7 @@ export function createInstancesStore(
137134
// place for the user to see the error. This is a very rare case, but we
138135
// don't want to leave the user without any indication that something went
139136
// wrong and so we show an toast with the error message
140-
if (isFirstRun) {
137+
if (refreshOptions.firstRun) {
141138
const { name, message } = err as Error;
142139
openToast('instance-refresh-failed', {
143140
title: 'Failed to retrieve server info',
@@ -359,6 +356,7 @@ export function createInstancesStore(
359356
{
360357
fetchDatabases: true,
361358
fetchDbStats: true,
359+
firstRun: true,
362360
},
363361
{
364362
connectionId: instanceConnectionId,

packages/compass-e2e-tests/tests/logging.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,17 @@ describe('Logging and Telemetry integration', function () {
417417
)}`
418418
);
419419
});
420+
421+
it('only calls instance info for a connection once', function () {
422+
expect(
423+
logs.filter((v) => {
424+
return (
425+
v.c === 'COMPASS-DATA-SERVICE' &&
426+
v.msg.startsWith('Running instance')
427+
);
428+
})
429+
).to.have.lengthOf(1);
430+
});
420431
});
421432
});
422433

packages/compass-indexes/src/components/indexes-toolbar/indexes-toolbar.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('IndexesToolbar Component', function () {
4444
onCreateSearchIndexClick={() => {}}
4545
namespace=""
4646
showAtlasSearchLink={false}
47+
serverVersion={'8.0.11'}
4748
{...props}
4849
/>
4950
</PreferencesProvider>

packages/compass-indexes/src/components/indexes-toolbar/indexes-toolbar.tsx

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
SegmentedControlOption,
2222
} from '@mongodb-js/compass-components';
2323
import { useConnectionInfo } from '@mongodb-js/compass-connections/provider';
24+
import semver from 'semver';
2425

2526
import type { RootState } from '../../modules';
2627
import { createSearchIndexOpened } from '../../modules/search-indexes';
@@ -53,6 +54,19 @@ const createIndexButtonContainerStyles = css({
5354
width: 'fit-content',
5455
});
5556

57+
const MIN_SEARCH_INDEX_MANAGEMENT_SERVER_VERSION = '6.0.7';
58+
59+
const serverSupportsSearchIndexManagement = (serverVersion: string) => {
60+
try {
61+
return semver.gte(
62+
serverVersion,
63+
MIN_SEARCH_INDEX_MANAGEMENT_SERVER_VERSION
64+
);
65+
} catch {
66+
return false;
67+
}
68+
};
69+
5670
type IndexesToolbarProps = {
5771
namespace: string;
5872
indexView: IndexView;
@@ -62,6 +76,7 @@ type IndexesToolbarProps = {
6276
isRefreshing: boolean;
6377
onRefreshIndexes: () => void;
6478
onIndexViewChanged: (newView: IndexView) => void;
79+
serverVersion: string;
6580
// connected:
6681
isReadonlyView: boolean;
6782
isWritable: boolean;
@@ -88,6 +103,7 @@ export const IndexesToolbar: React.FunctionComponent<IndexesToolbarProps> = ({
88103
isSearchIndexesSupported,
89104
onRefreshIndexes,
90105
onIndexViewChanged,
106+
serverVersion,
91107
readOnly, // preferences readOnly.
92108
}) => {
93109
const isSearchManagementActive = usePreference('enableAtlasSearchIndexes');
@@ -188,16 +204,27 @@ export const IndexesToolbar: React.FunctionComponent<IndexesToolbarProps> = ({
188204
</SegmentedControlOption>
189205
}
190206
>
191-
<p>
192-
Atlas Search index management in Compass is only available
193-
for Atlas local deployments and clusters running MongoDB
194-
6.0.7 or newer.
195-
</p>
196-
<p>
197-
For clusters running an earlier version of MongoDB, you
198-
can manage your Atlas Search indexes from the Atlas web
199-
Ul, with the CLI, or with the Administration API.
200-
</p>
207+
{serverSupportsSearchIndexManagement(serverVersion) ? (
208+
<p>
209+
Unable to fetch search indexes. This can occur when your
210+
cluster does not support search indexes or the request
211+
to list search indexes failed.
212+
</p>
213+
) : (
214+
<>
215+
<p>
216+
Atlas Search index management in Compass is only
217+
available for Atlas local deployments and clusters
218+
running MongoDB 6.0.7 or newer.
219+
</p>
220+
<p>
221+
For clusters running an earlier version of MongoDB,
222+
you can manage your Atlas Search indexes from the
223+
Atlas web Ul, with the CLI, or with the Administration
224+
API.
225+
</p>
226+
</>
227+
)}
201228
</Tooltip>
202229
)}
203230
{isSearchIndexesSupported && (

packages/compass-web/scripts/electron-proxy.js

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,15 @@ class AtlasCloudAuthenticator {
118118
* @returns {Promise<string[]>}
119119
*/
120120
async #getCloudSessionCookies() {
121-
const cloudHostCookies = await session.defaultSession.cookies.get({
122-
domain: CLOUD_CONFIG_VARIANTS === 'local' ? 'localhost' : 'mongodb.com',
123-
});
124-
return cloudHostCookies.map((cookie) => {
125-
return `${cookie.name}=${cookie.value}`;
126-
});
121+
const tld = CLOUD_CONFIG_VARIANTS === 'local' ? 'localhost' : 'mongodb.com';
122+
const cloudHostCookies = (await session.defaultSession.cookies.get({}))
123+
.filter((cookie) => {
124+
return cookie.domain?.endsWith(tld) ?? true;
125+
})
126+
.map((cookie) => {
127+
return `${cookie.name}=${cookie.value}`;
128+
});
129+
return cloudHostCookies;
127130
}
128131

129132
/**
@@ -135,18 +138,10 @@ class AtlasCloudAuthenticator {
135138
}
136139

137140
async #fetch(path, init) {
138-
let csrfHeaders;
139-
if (
140-
init?.method &&
141-
/^(GET|HEAD|OPTIONS|TRACE)$/i.test(init.method) === false
142-
) {
143-
csrfHeaders = await this.#getCSRFHeaders();
144-
}
145141
return electronFetch(`${CLOUD_ORIGIN}${path}`, {
146142
...init,
147143
headers: {
148144
...init?.headers,
149-
...csrfHeaders,
150145
},
151146
}).then(handleRes);
152147
}
@@ -159,17 +154,6 @@ class AtlasCloudAuthenticator {
159154
return new URL(url, 'http://localhost').pathname.startsWith('/v2/');
160155
}
161156

162-
async #getCSRFHeaders() {
163-
const projectId = await this.getProjectId();
164-
const { csrfToken, csrfTime } = await this.#fetch(
165-
`/v2/${projectId}/params`
166-
);
167-
return {
168-
...(csrfToken && { 'X-CSRF-Token': csrfToken }),
169-
...(csrfTime && { 'X-CSRF-Time': csrfTime }),
170-
};
171-
}
172-
173157
async getCloudHeaders(hostSubdomain = '') {
174158
const cookie = (await this.#getCloudSessionCookies()).join('; ');
175159
return {
@@ -319,16 +303,33 @@ expressProxy.use(
319303
return req;
320304
},
321305
userResHeaderDecorator(headers, _req, res) {
322-
// Cloud backend will try to always set auth cookies on requests, but we
323-
// can't really meaningfully store those in the browser (__secure- ones
324-
// would be ignored anyways), so to avoid polluting storage, we just not
325-
// allow the set-cookie header to propagate
326-
delete headers['set-cookie'];
327-
328306
if (isSignedOutRedirect(headers.location)) {
329307
res.statusCode = 403;
330308
return {};
331309
}
310+
311+
// When cloud session expires, cloud backend will send a new set of
312+
// session cookies to make sure that "active" client stays signed in. As
313+
// these proxy requests are not going through the electron fetch, we can
314+
// end up in a situation where electron still keeps the old session
315+
// cookies instead on new ones. When we receive set-cookie header in the
316+
// proxy, we will copy the cookies to the electron session to make sure
317+
// that both are in sync with electron storage that we use as source of
318+
// truth for cookies when creating the fetch request
319+
if (headers['set-cookie']) {
320+
const parsedCookies = headers['set-cookie'].map((cookieStr) => {
321+
const [cookie, ...options] = cookieStr.split(';').map((keyVal) => {
322+
return keyVal.split('=');
323+
});
324+
const domain = options.find((opt) => {
325+
return opt[0] === 'Domain';
326+
});
327+
return { name: cookie[0], value: cookie[1], domain: domain[1] };
328+
});
329+
session.defaultSession.cookies.set(parsedCookies);
330+
}
331+
delete headers['set-cookie'];
332+
332333
return headers;
333334
},
334335
})

packages/instance-model/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ declare class MongoDBInstance extends MongoDBInstanceProps {
123123
fetchCollections?: boolean;
124124
fetchCollInfo?: boolean;
125125
fetchCollStats?: boolean;
126+
firstRun?: boolean;
126127
}): Promise<void>;
127128
getNamespace(opts: {
128129
dataService: Pick<DataService, 'instance' | 'getCurrentTopologyType'>;

0 commit comments

Comments
 (0)