diff --git a/src/auth/googleauth.ts b/src/auth/googleauth.ts index b4f6cf15..aca320ac 100644 --- a/src/auth/googleauth.ts +++ b/src/auth/googleauth.ts @@ -185,13 +185,6 @@ export class GoogleAuth { private scopes?: string | string[]; private clientOptions: AuthClientOptions = {}; - /** - * The cached universe domain. - * - * @see {@link GoogleAuth.getUniverseDomain} - */ - #universeDomain?: string = undefined; - /** * Export DefaultTransporter as a static property of the class. */ @@ -220,7 +213,6 @@ export class GoogleAuth { if (opts.universeDomain) { this.clientOptions.universeDomain = opts.universeDomain; - this.#universeDomain = opts.universeDomain; } } @@ -315,9 +307,13 @@ export class GoogleAuth { return this._findProjectIdPromise; } - async #getUniverseFromMetadataServer() { - if (!(await this._checkIsGCE())) return; - + /** + * Retrieves a universe domain from the metadata server via + * {@link gcpMetadata.universe}. + * + * @returns a universe domain + */ + async getUniverseDomainFromMetadataServer(): Promise { let universeDomain: string; try { @@ -338,17 +334,18 @@ export class GoogleAuth { * Retrieves, caches, and returns the universe domain in the following order * of precedence: * - The universe domain in {@link GoogleAuth.clientOptions} - * - {@link gcpMetadata.universe} + * - An existing or ADC {@link AuthClient}'s universe domain + * - {@link gcpMetadata.universe}, if {@link Compute} client * * @returns The universe domain */ async getUniverseDomain(): Promise { - this.#universeDomain ??= originalOrCamelOptions(this.clientOptions).get( + let universeDomain = originalOrCamelOptions(this.clientOptions).get( 'universe_domain' ); - this.#universeDomain ??= await this.#getUniverseFromMetadataServer(); + universeDomain ??= (await this.getClient()).universeDomain; - return this.#universeDomain || DEFAULT_UNIVERSE; + return universeDomain; } /** @@ -438,7 +435,8 @@ export class GoogleAuth { if (await this._checkIsGCE()) { // set universe domain for Compute client if (!originalOrCamelOptions(options).get('universe_domain')) { - options.universeDomain = await this.getUniverseDomain(); + options.universeDomain = + await this.getUniverseDomainFromMetadataServer(); } (options as ComputeOptions).scopes = this.getAnyScopes(); @@ -622,11 +620,8 @@ export class GoogleAuth { } // Create source client for impersonation - const sourceClient = new UserRefreshClient( - json.source_credentials.client_id, - json.source_credentials.client_secret, - json.source_credentials.refresh_token - ); + const sourceClient = new UserRefreshClient(); + sourceClient.fromJSON(json.source_credentials); if (json.service_account_impersonation_url?.length > 256) { /** @@ -652,6 +647,7 @@ export class GoogleAuth { const targetScopes = this.getAnyScopes() ?? []; const client = new Impersonated({ + ...json, delegates: json.delegates ?? [], sourceClient: sourceClient, targetPrincipal: targetPrincipal, @@ -672,6 +668,10 @@ export class GoogleAuth { ): JSONClient { let client: JSONClient; + // user's preferred universe domain + const preferredUniverseDomain = + originalOrCamelOptions(options).get('universe_domain'); + if (json.type === USER_REFRESH_ACCOUNT_TYPE) { client = new UserRefreshClient(options); client.fromJSON(json); @@ -694,6 +694,11 @@ export class GoogleAuth { this.setGapicJWTValues(client); client.fromJSON(json); } + + if (preferredUniverseDomain) { + client.universeDomain = preferredUniverseDomain; + } + return client; } diff --git a/src/auth/jwtclient.ts b/src/auth/jwtclient.ts index 9e12b23c..31c41dbd 100644 --- a/src/auth/jwtclient.ts +++ b/src/auth/jwtclient.ts @@ -321,6 +321,7 @@ export class JWT extends OAuth2Client implements IdTokenProvider { this.keyId = json.private_key_id; this.projectId = json.project_id; this.quotaProjectId = json.quota_project_id; + this.universeDomain = json.universe_domain || this.universeDomain; } /** diff --git a/src/auth/refreshclient.ts b/src/auth/refreshclient.ts index 816be6e5..a53f1b1d 100644 --- a/src/auth/refreshclient.ts +++ b/src/auth/refreshclient.ts @@ -114,6 +114,7 @@ export class UserRefreshClient extends OAuth2Client { this._refreshToken = json.refresh_token; this.credentials.refresh_token = json.refresh_token; this.quotaProjectId = json.quota_project_id; + this.universeDomain = json.universe_domain || this.universeDomain; } /** diff --git a/test/fixtures/private2.json b/test/fixtures/private2.json index 88ab26e0..9aecf271 100644 --- a/test/fixtures/private2.json +++ b/test/fixtures/private2.json @@ -4,5 +4,6 @@ "client_email": "goodbye@youarecool.com", "client_id": "client456", "type": "service_account", - "project_id": "my-awesome-project" -} \ No newline at end of file + "project_id": "my-awesome-project", + "universe_domain": "my-universe" +} diff --git a/test/test.googleauth.ts b/test/test.googleauth.ts index 93609af7..ff3d5bcd 100644 --- a/test/test.googleauth.ts +++ b/test/test.googleauth.ts @@ -1568,6 +1568,20 @@ describe('googleauth', () => { assert.equal(await auth.getUniverseDomain(), universeDomain); }); + it('should get the universe from ADC', async () => { + mockEnvVar( + 'GOOGLE_APPLICATION_CREDENTIALS', + './test/fixtures/private2.json' + ); + const {universe_domain} = JSON.parse( + fs.readFileSync('./test/fixtures/private2.json', 'utf-8') + ); + + assert(universe_domain); + assert.notEqual(universe_domain, DEFAULT_UNIVERSE); + assert.equal(await auth.getUniverseDomain(), universe_domain); + }); + it('should use the metadata service if on GCP', async () => { const universeDomain = 'my.universe.com'; const scope = nockIsGCE({universeDomain});