@@ -118,12 +118,15 @@ class AtlasCloudAuthenticator {
118
118
* @returns {Promise<string[]> }
119
119
*/
120
120
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 ;
127
130
}
128
131
129
132
/**
@@ -135,18 +138,10 @@ class AtlasCloudAuthenticator {
135
138
}
136
139
137
140
async #fetch( path , init ) {
138
- let csrfHeaders ;
139
- if (
140
- init ?. method &&
141
- / ^ ( G E T | H E A D | O P T I O N S | T R A C E ) $ / i. test ( init . method ) === false
142
- ) {
143
- csrfHeaders = await this . #getCSRFHeaders( ) ;
144
- }
145
141
return electronFetch ( `${ CLOUD_ORIGIN } ${ path } ` , {
146
142
...init ,
147
143
headers : {
148
144
...init ?. headers ,
149
- ...csrfHeaders ,
150
145
} ,
151
146
} ) . then ( handleRes ) ;
152
147
}
@@ -159,17 +154,6 @@ class AtlasCloudAuthenticator {
159
154
return new URL ( url , 'http://localhost' ) . pathname . startsWith ( '/v2/' ) ;
160
155
}
161
156
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
-
173
157
async getCloudHeaders ( hostSubdomain = '' ) {
174
158
const cookie = ( await this . #getCloudSessionCookies( ) ) . join ( '; ' ) ;
175
159
return {
@@ -319,16 +303,33 @@ expressProxy.use(
319
303
return req ;
320
304
} ,
321
305
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
-
328
306
if ( isSignedOutRedirect ( headers . location ) ) {
329
307
res . statusCode = 403 ;
330
308
return { } ;
331
309
}
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
+
332
333
return headers ;
333
334
} ,
334
335
} )
0 commit comments