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
3 changes: 3 additions & 0 deletions configs/webpack-config-compass/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const sharedIgnoreWarnings: NonNullable<Configuration['ignoreWarnings']> = [
/the request of a dependency is an expression/,
// Optional, platform-specific dependencies (mostly from driver)
/Module not found.+?(mongo_crypt_v1.(dll|so|dylib)|@mongodb-js\/zstd|aws-crt|gcp-metadata)/,
// Optional, comes from emotion trying to (safely) use react apis that we
// don't have in React 17
/export 'useInsertionEffect'/,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by, was really noisy in webpack logs and we know it's okay to ignore

];

const sharedResolveOptions = (
Expand Down
63 changes: 32 additions & 31 deletions packages/compass-web/scripts/electron-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,15 @@ class AtlasCloudAuthenticator {
* @returns {Promise<string[]>}
*/
async #getCloudSessionCookies() {
const cloudHostCookies = await session.defaultSession.cookies.get({
domain: CLOUD_CONFIG_VARIANTS === 'local' ? 'localhost' : 'mongodb.com',
});
return cloudHostCookies.map((cookie) => {
return `${cookie.name}=${cookie.value}`;
});
const tld = CLOUD_CONFIG_VARIANTS === 'local' ? 'localhost' : 'mongodb.com';
const cloudHostCookies = (await session.defaultSession.cookies.get({}))
.filter((cookie) => {
return cookie.domain?.endsWith(tld) ?? true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah, yeah, I was mostly going off of types here, I think for proxy purposes it's easier to include the ones that don't have any value there just in case

})
.map((cookie) => {
return `${cookie.name}=${cookie.value}`;
});
return cloudHostCookies;
}

/**
Expand All @@ -135,18 +138,10 @@ class AtlasCloudAuthenticator {
}

async #fetch(path, init) {
let csrfHeaders;
if (
init?.method &&
/^(GET|HEAD|OPTIONS|TRACE)$/i.test(init.method) === false
) {
csrfHeaders = await this.#getCSRFHeaders();
}
return electronFetch(`${CLOUD_ORIGIN}${path}`, {
...init,
headers: {
...init?.headers,
...csrfHeaders,
},
}).then(handleRes);
}
Expand All @@ -159,17 +154,6 @@ class AtlasCloudAuthenticator {
return new URL(url, 'http://localhost').pathname.startsWith('/v2/');
}

async #getCSRFHeaders() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by, we moved this logic to the client some time ago and forgot to remove this

const projectId = await this.getProjectId();
const { csrfToken, csrfTime } = await this.#fetch(
`/v2/${projectId}/params`
);
return {
...(csrfToken && { 'X-CSRF-Token': csrfToken }),
...(csrfTime && { 'X-CSRF-Time': csrfTime }),
};
}

async getCloudHeaders(hostSubdomain = '') {
const cookie = (await this.#getCloudSessionCookies()).join('; ');
return {
Expand Down Expand Up @@ -319,16 +303,33 @@ expressProxy.use(
return req;
},
userResHeaderDecorator(headers, _req, res) {
// Cloud backend will try to always set auth cookies on requests, but we
// can't really meaningfully store those in the browser (__secure- ones
// would be ignored anyways), so to avoid polluting storage, we just not
// allow the set-cookie header to propagate
delete headers['set-cookie'];

if (isSignedOutRedirect(headers.location)) {
res.statusCode = 403;
return {};
}

// When cloud session expires, cloud backend will send a new set of
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another drive-by, should make sure we're not logged out as often in sandbox

// session cookies to make sure that "active" client stays signed in. As
// these proxy requests are not going through the electron fetch, we can
// end up in a situation where electron still keeps the old session
// cookies instead on new ones. When we receive set-cookie header in the
// proxy, we will copy the cookies to the electron session to make sure
// that both are in sync with electron storage that we use as source of
// truth for cookies when creating the fetch request
if (headers['set-cookie']) {
const parsedCookies = headers['set-cookie'].map((cookieStr) => {
const [cookie, ...options] = cookieStr.split(';').map((keyVal) => {
return keyVal.split('=');
});
const domain = options.find((opt) => {
return opt[0] === 'Domain';
});
return { name: cookie[0], value: cookie[1], domain: domain[1] };
});
session.defaultSession.cookies.set(parsedCookies);
}
delete headers['set-cookie'];

return headers;
},
})
Expand Down
Loading