@@ -97,11 +97,6 @@ function throwIfAINotEnabled(atlasService: typeof AtlasService) {
9797 }
9898}
9999
100- function throwIfRequiredEnvNotSet ( atlasService : typeof AtlasService ) {
101- // These class properties will throw on access if missing
102- return void ( atlasService [ 'clientId' ] && atlasService [ 'issuer' ] ) ;
103- }
104-
105100const AI_MAX_REQUEST_SIZE = 10000 ;
106101
107102const AI_MIN_SAMPLE_DOCUMENTS = 1 ;
@@ -119,6 +114,15 @@ export function getTrackingUserInfo(userInfo: AtlasUserInfo) {
119114 } ;
120115}
121116
117+ export type AtlasServiceConfig = {
118+ atlasApiBaseUrl : string ;
119+ atlasLogin : {
120+ clientId : string ;
121+ issuer : string ;
122+ } ;
123+ authPortalUrl : string ;
124+ } ;
125+
122126export class AtlasService {
123127 private constructor ( ) {
124128 // singleton
@@ -153,46 +157,7 @@ export class AtlasService {
153157
154158 private static ipcMain : Pick < typeof ipcMain , 'handle' > = ipcMain ;
155159
156- private static get clientId ( ) {
157- const clientId =
158- process . env . COMPASS_CLIENT_ID_OVERRIDE || process . env . COMPASS_CLIENT_ID ;
159- if ( ! clientId ) {
160- throw new Error ( 'COMPASS_CLIENT_ID is required' ) ;
161- }
162- return clientId ;
163- }
164-
165- private static get issuer ( ) {
166- const issuer =
167- process . env . COMPASS_OIDC_ISSUER_OVERRIDE ||
168- process . env . COMPASS_OIDC_ISSUER ;
169- if ( ! issuer ) {
170- throw new Error ( 'COMPASS_OIDC_ISSUER is required' ) ;
171- }
172- return issuer ;
173- }
174-
175- private static get apiBaseUrl ( ) {
176- const apiBaseUrl =
177- process . env . COMPASS_ATLAS_SERVICE_BASE_URL_OVERRIDE ||
178- process . env . COMPASS_ATLAS_SERVICE_BASE_URL ;
179- if ( ! apiBaseUrl ) {
180- throw new Error (
181- 'No AI Query endpoint to fetch. Please set the environment variable `COMPASS_ATLAS_SERVICE_BASE_URL`'
182- ) ;
183- }
184- return apiBaseUrl ;
185- }
186-
187- private static get authPortalUrl ( ) {
188- const authPortalUrl =
189- process . env . COMPASS_ATLAS_AUTH_PORTAL_URL_OVERRIDE ||
190- process . env . COMPASS_ATLAS_AUTH_PORTAL_URL ;
191- if ( ! authPortalUrl ) {
192- throw new Error ( 'COMPASS_ATLAS_AUTH_PORTAL_URL is required' ) ;
193- }
194- return authPortalUrl ;
195- }
160+ private static config : AtlasServiceConfig ;
196161
197162 private static openExternal ( ...args : Parameters < typeof shell . openExternal > ) {
198163 return shell ?. openExternal ( ...args ) ;
@@ -215,7 +180,7 @@ export class AtlasService {
215180 if ( data . result === 'redirecting' ) {
216181 const { res, status, location } = data ;
217182 res . statusCode = status ;
218- const redirectUrl = new URL ( this . authPortalUrl ) ;
183+ const redirectUrl = new URL ( this . config . authPortalUrl ) ;
219184 redirectUrl . searchParams . set ( 'fromURI' , location ) ;
220185 res . setHeader ( 'Location' , redirectUrl . toString ( ) ) ;
221186 res . end ( ) ;
@@ -238,7 +203,8 @@ export class AtlasService {
238203 ) ;
239204 }
240205
241- static init ( ) : Promise < void > {
206+ static init ( config : AtlasServiceConfig ) : Promise < void > {
207+ this . config = config ;
242208 return ( this . initPromise ??= ( async ( ) => {
243209 ipcExpose (
244210 'AtlasService' ,
@@ -259,7 +225,8 @@ export class AtlasService {
259225 log . info (
260226 mongoLogId ( 1_001_000_210 ) ,
261227 'AtlasService' ,
262- 'Atlas service initialized'
228+ 'Atlas service initialized' ,
229+ { config : this . config }
263230 ) ;
264231 const serializedState = await this . secretStore . getItem ( SECRET_STORE_KEY ) ;
265232 this . setupPlugin ( serializedState ) ;
@@ -286,7 +253,6 @@ export class AtlasService {
286253 } : { signal ?: AbortSignal } = { } ) {
287254 throwIfAborted ( signal ) ;
288255 throwIfNetworkTrafficDisabled ( ) ;
289- throwIfRequiredEnvNotSet ( this ) ;
290256
291257 if ( ! this . plugin ) {
292258 throw new Error (
@@ -295,7 +261,10 @@ export class AtlasService {
295261 }
296262
297263 return this . plugin . mongoClientOptions . authMechanismProperties . REQUEST_TOKEN_CALLBACK (
298- { clientId : this . clientId , issuer : this . issuer } ,
264+ {
265+ clientId : this . config . atlasLogin . clientId ,
266+ issuer : this . config . atlasLogin . issuer ,
267+ } ,
299268 {
300269 // Required driver specific stuff
301270 version : 0 ,
@@ -348,7 +317,6 @@ export class AtlasService {
348317 this . signInPromise = ( async ( ) => {
349318 throwIfAborted ( signal ) ;
350319 throwIfNetworkTrafficDisabled ( ) ;
351- throwIfRequiredEnvNotSet ( this ) ;
352320
353321 log . info ( mongoLogId ( 1_001_000_218 ) , 'AtlasService' , 'Starting sign in' ) ;
354322
@@ -411,9 +379,9 @@ export class AtlasService {
411379 this . currentUser = null ;
412380 this . oidcPluginLogger . emit ( 'atlas-service-signed-out' ) ;
413381 // Open Atlas sign out page to end the browser session created for sign in
414- void this . openExternal (
415- 'https://account.mongodb.com/account/login? signedOut= true'
416- ) ;
382+ const signOutUrl = new URL ( this . config . authPortalUrl ) ;
383+ signOutUrl . searchParams . set ( ' signedOut' , ' true') ;
384+ void this . openExternal ( signOutUrl . toString ( ) ) ;
417385 track ( 'Atlas Sign Out' , getTrackingUserInfo ( userInfo ) ) ;
418386 }
419387
@@ -441,18 +409,20 @@ export class AtlasService {
441409 } : { signal ?: AbortSignal } = { } ) : Promise < AtlasUserInfo > {
442410 throwIfAborted ( signal ) ;
443411 throwIfNetworkTrafficDisabled ( ) ;
444- throwIfRequiredEnvNotSet ( this ) ;
445412
446413 this . currentUser ??= await ( async ( ) => {
447414 const token = await this . maybeGetToken ( { signal } ) ;
448415
449- const res = await this . fetch ( `${ this . issuer } /v1/userinfo` , {
450- headers : {
451- Authorization : `Bearer ${ token ?? '' } ` ,
452- Accept : 'application/json' ,
453- } ,
454- signal : signal as NodeFetchAbortSignal | undefined ,
455- } ) ;
416+ const res = await this . fetch (
417+ `${ this . config . atlasLogin . issuer } /v1/userinfo` ,
418+ {
419+ headers : {
420+ Authorization : `Bearer ${ token ?? '' } ` ,
421+ Accept : 'application/json' ,
422+ } ,
423+ signal : signal as NodeFetchAbortSignal | undefined ,
424+ }
425+ ) ;
456426
457427 await throwIfNotOk ( res ) ;
458428
@@ -495,10 +465,9 @@ export class AtlasService {
495465 } = { } ) {
496466 throwIfAborted ( signal ) ;
497467 throwIfNetworkTrafficDisabled ( ) ;
498- throwIfRequiredEnvNotSet ( this ) ;
499468
500- const url = new URL ( `${ this . issuer } /v1/introspect` ) ;
501- url . searchParams . set ( 'client_id' , this . clientId ) ;
469+ const url = new URL ( `${ this . config . atlasLogin . issuer } /v1/introspect` ) ;
470+ url . searchParams . set ( 'client_id' , this . config . atlasLogin . clientId ) ;
502471
503472 tokenType ??= 'accessToken' ;
504473
@@ -530,10 +499,9 @@ export class AtlasService {
530499 } = { } ) : Promise < void > {
531500 throwIfAborted ( signal ) ;
532501 throwIfNetworkTrafficDisabled ( ) ;
533- throwIfRequiredEnvNotSet ( this ) ;
534502
535- const url = new URL ( `${ this . issuer } /v1/revoke` ) ;
536- url . searchParams . set ( 'client_id' , this . clientId ) ;
503+ const url = new URL ( `${ this . config . atlasLogin . issuer } /v1/revoke` ) ;
504+ url . searchParams . set ( 'client_id' , this . config . atlasLogin . clientId ) ;
537505
538506 tokenType ??= 'accessToken' ;
539507
@@ -574,7 +542,6 @@ export class AtlasService {
574542 throwIfAborted ( signal ) ;
575543 throwIfNetworkTrafficDisabled ( ) ;
576544 throwIfAINotEnabled ( this ) ;
577- throwIfRequiredEnvNotSet ( this ) ;
578545
579546 let msgBody = JSON . stringify ( {
580547 userInput,
@@ -605,7 +572,7 @@ export class AtlasService {
605572 const token = await this . maybeGetToken ( { signal } ) ;
606573
607574 const res = await this . fetch (
608- `${ this . apiBaseUrl } /ai/api/v1/mql-aggregation` ,
575+ `${ this . config . atlasApiBaseUrl } /ai/api/v1/mql-aggregation` ,
609576 {
610577 signal : signal as NodeFetchAbortSignal | undefined ,
611578 method : 'POST' ,
@@ -644,7 +611,6 @@ export class AtlasService {
644611 throwIfAborted ( signal ) ;
645612 throwIfNetworkTrafficDisabled ( ) ;
646613 throwIfAINotEnabled ( this ) ;
647- throwIfRequiredEnvNotSet ( this ) ;
648614
649615 let msgBody = JSON . stringify ( {
650616 userInput,
@@ -674,15 +640,18 @@ export class AtlasService {
674640
675641 const token = await this . maybeGetToken ( { signal } ) ;
676642
677- const res = await this . fetch ( `${ this . apiBaseUrl } /ai/api/v1/mql-query` , {
678- signal : signal as NodeFetchAbortSignal | undefined ,
679- method : 'POST' ,
680- headers : {
681- Authorization : `Bearer ${ token ?? '' } ` ,
682- 'Content-Type' : 'application/json' ,
683- } ,
684- body : msgBody ,
685- } ) ;
643+ const res = await this . fetch (
644+ `${ this . config . atlasApiBaseUrl } /ai/api/v1/mql-query` ,
645+ {
646+ signal : signal as NodeFetchAbortSignal | undefined ,
647+ method : 'POST' ,
648+ headers : {
649+ Authorization : `Bearer ${ token ?? '' } ` ,
650+ 'Content-Type' : 'application/json' ,
651+ } ,
652+ body : msgBody ,
653+ }
654+ ) ;
686655
687656 await throwIfNotOk ( res ) ;
688657
0 commit comments