From 1a43960792c072cc1661cf1891d9dec4d86ca09e Mon Sep 17 00:00:00 2001 From: feywind <57276408+feywind@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:17:10 -0500 Subject: [PATCH 1/4] feat: add debug logging support --- package.json | 1 + src/auth/baseexternalclient.ts | 28 +++++++-- .../defaultawssecuritycredentialssupplier.ts | 39 +++++++++--- .../externalAccountAuthorizedUserClient.ts | 11 ++++ src/auth/oauth2client.ts | 60 +++++++++++++++---- src/auth/refreshclient.ts | 15 ++++- src/auth/stscredentials.ts | 17 +++++- src/auth/urlsubjecttokensupplier.ts | 14 ++++- 8 files changed, 151 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 2bc32c04..14965eac 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^6.1.1", "gcp-metadata": "^6.1.0", + "google-logging-utils": "next", "gtoken": "^7.0.0", "jws": "^4.0.0" }, diff --git a/src/auth/baseexternalclient.ts b/src/auth/baseexternalclient.ts index 26436979..03bf2f43 100644 --- a/src/auth/baseexternalclient.ts +++ b/src/auth/baseexternalclient.ts @@ -20,6 +20,8 @@ import { GaxiosResponse, } from 'gaxios'; import * as stream from 'stream'; +import {log as makeLog} from 'google-logging-utils'; +const log = makeLog('auth'); import {Credentials} from './credentials'; import {AuthClient, AuthClientOptions} from './authclient'; @@ -478,13 +480,19 @@ export abstract class BaseExternalAccountClient extends AuthClient { } else if (projectNumber) { // Preferable not to use request() to avoid retrial policies. const headers = await this.getRequestHeaders(); + const url = `${this.cloudResourceManagerURL.toString()}${projectNumber}`; + const request = { + headers, + url, + }; + log.info('getProjectId %j', request); const response = await this.transporter.request({ + ...request, ...BaseExternalAccountClient.RETRY_CONFIG, - headers, - url: `${this.cloudResourceManagerURL.toString()}${projectNumber}`, responseType: 'json', }); this.projectId = response.data.projectId; + log.info('getProjectId, id %s', this.projectId); return this.projectId; } return null; @@ -665,10 +673,8 @@ export abstract class BaseExternalAccountClient extends AuthClient { private async getImpersonatedAccessToken( token: string ): Promise { - const opts: GaxiosOptions = { - ...BaseExternalAccountClient.RETRY_CONFIG, + const request = { url: this.serviceAccountImpersonationUrl!, - method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, @@ -677,11 +683,23 @@ export abstract class BaseExternalAccountClient extends AuthClient { scope: this.getScopesArray(), lifetime: this.serviceAccountImpersonationLifetime + 's', }, + }; + log.info('getImpersonatedAccessToken %j', request); + const opts: GaxiosOptions = { + ...request, + ...BaseExternalAccountClient.RETRY_CONFIG, + method: 'POST', responseType: 'json', }; const response = await this.transporter.request(opts); const successResponse = response.data; + log.info( + 'getImpersonatedAccessToken success: %s, %s, %s', + successResponse.accessToken, + successResponse.expireTime, + response + ); return { access_token: successResponse.accessToken, // Convert from ISO format to timestamp. diff --git a/src/auth/defaultawssecuritycredentialssupplier.ts b/src/auth/defaultawssecuritycredentialssupplier.ts index 12d48d3f..7a413801 100644 --- a/src/auth/defaultawssecuritycredentialssupplier.ts +++ b/src/auth/defaultawssecuritycredentialssupplier.ts @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +import {log as makeLog} from 'google-logging-utils'; +const log = makeLog('auth'); + import {ExternalAccountSupplierContext} from './baseexternalclient'; import {Gaxios, GaxiosOptions} from 'gaxios'; import {Transporter} from '../transporters'; @@ -122,14 +125,19 @@ export class DefaultAwsSecurityCredentialsSupplier '"options.credential_source.region_url"' ); } + const request = { + url: this.regionUrl, + headers: metadataHeaders, + }; + log.info('getAwsRegion %j', request); const opts: GaxiosOptions = { + ...request, ...this.additionalGaxiosOptions, - url: this.regionUrl, method: 'GET', responseType: 'text', - headers: metadataHeaders, }; const response = await context.transporter.request(opts); + log.info('getAwsRegion is %s', response.data); // Remove last character. For example, if us-east-2b is returned, // the region would be us-east-2. return response.data.substr(0, response.data.length - 1); @@ -186,14 +194,19 @@ export class DefaultAwsSecurityCredentialsSupplier async #getImdsV2SessionToken( transporter: Transporter | Gaxios ): Promise { + const request = { + url: this.imdsV2SessionTokenUrl, + headers: {'x-aws-ec2-metadata-token-ttl-seconds': '300'}, + }; const opts: GaxiosOptions = { + ...request, ...this.additionalGaxiosOptions, - url: this.imdsV2SessionTokenUrl, method: 'PUT', responseType: 'text', - headers: {'x-aws-ec2-metadata-token-ttl-seconds': '300'}, }; + log.info('#getImdsV2SessionToken %j', request); const response = await transporter.request(opts); + log.info('#getImdsV2SessionToken is %s', response.data); return response.data; } @@ -213,14 +226,19 @@ export class DefaultAwsSecurityCredentialsSupplier '"options.credential_source.url"' ); } + const request = { + url: this.securityCredentialsUrl, + headers: headers, + }; + log.info('#getAwsRoleName %j', request); const opts: GaxiosOptions = { + ...request, ...this.additionalGaxiosOptions, - url: this.securityCredentialsUrl, method: 'GET', responseType: 'text', - headers: headers, }; const response = await transporter.request(opts); + log.info('#getAwsRoleName name is %s', response.data); return response.data; } @@ -238,12 +256,17 @@ export class DefaultAwsSecurityCredentialsSupplier headers: Headers, transporter: Transporter | Gaxios ): Promise { + const request = { + url: `${this.securityCredentialsUrl}/${roleName}`, + headers: headers, + }; + log.info('#retrieveAwsSecurityCredentials %j', request); const response = await transporter.request({ + ...request, ...this.additionalGaxiosOptions, - url: `${this.securityCredentialsUrl}/${roleName}`, responseType: 'json', - headers: headers, }); + log.info('#retrieveAwsSecurityCredentials %s', response.data); return response.data; } diff --git a/src/auth/externalAccountAuthorizedUserClient.ts b/src/auth/externalAccountAuthorizedUserClient.ts index 24a480c0..b80135c1 100644 --- a/src/auth/externalAccountAuthorizedUserClient.ts +++ b/src/auth/externalAccountAuthorizedUserClient.ts @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +import {log as makeLog} from 'google-logging-utils'; +const log = makeLog('auth'); + import {AuthClient, AuthClientOptions} from './authclient'; import {Headers} from './oauth2client'; import { @@ -124,16 +127,24 @@ class ExternalAccountAuthorizedUserHandler extends OAuthClientAuthHandler { // Apply OAuth client authentication. this.applyClientAuthenticationOptions(opts); + log.info('refreshToken %j', { + url: opts.url, + headers: opts.headers, + data: opts.data, + }); + try { const response = await this.transporter.request(opts); // Successful response. const tokenRefreshResponse = response.data; tokenRefreshResponse.res = response; + log.info('refreshToken response %j', tokenRefreshResponse); return tokenRefreshResponse; } catch (error) { // Translate error to OAuthError. if (error instanceof GaxiosError && error.response) { + log.error('refreshToken failed %j', error.response?.data); throw getErrorFromOAuthErrorResponse( error.response.data as OAuthErrorResponse, // Preserve other fields from the original error. diff --git a/src/auth/oauth2client.ts b/src/auth/oauth2client.ts index fb813a7f..44af6780 100644 --- a/src/auth/oauth2client.ts +++ b/src/auth/oauth2client.ts @@ -21,6 +21,8 @@ import { import * as querystring from 'querystring'; import * as stream from 'stream'; import * as formatEcdsa from 'ecdsa-sig-formatter'; +import {log as makeLog} from 'google-logging-utils'; +const log = makeLog('auth'); import {createCrypto, JwkCertificate, hasBrowserCrypto} from '../crypto/crypto'; import {BodyResponseCallback} from '../transporters'; @@ -708,14 +710,21 @@ export class OAuth2Client extends AuthClient { if (this.clientAuthentication === ClientAuthentication.ClientSecretPost) { values.client_secret = this._clientSecret; } - const res = await this.transporter.request({ - ...OAuth2Client.RETRY_CONFIG, - method: 'POST', + + const request = { url, data: querystring.stringify(values), headers, + }; + log.info('getTokenAsync %j', request); + + const res = await this.transporter.request({ + ...request, + ...OAuth2Client.RETRY_CONFIG, + method: 'POST', }); const tokens = res.data as Credentials; + log.info('getTokenAsync success %j', tokens); if (res.data && res.data.expires_in) { tokens.expiry_date = new Date().getTime() + res.data.expires_in * 1000; delete (tokens as CredentialRequest).expires_in; @@ -769,18 +778,24 @@ export class OAuth2Client extends AuthClient { grant_type: 'refresh_token', }; + const request = { + url, + data: querystring.stringify(data), + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + }; + log.info('refreshTokenNoCache %j', request); + let res: GaxiosResponse; try { // request for new token res = await this.transporter.request({ + ...request, ...OAuth2Client.RETRY_CONFIG, method: 'POST', - url, - data: querystring.stringify(data), - headers: {'Content-Type': 'application/x-www-form-urlencoded'}, }); - } catch (e) { + } catch (exc) { + const e = exc as Error; if ( e instanceof GaxiosError && e.message === 'invalid_grant' && @@ -789,11 +804,13 @@ export class OAuth2Client extends AuthClient { ) { e.message = JSON.stringify(e.response.data); } + log.error('refreshTokenNoCache failure %j', e.message); throw e; } const tokens = res.data as Credentials; + log.info('refreshTokenNoCache success %j', tokens); // TODO: de-duplicate this code from a few spots if (res.data && res.data.expires_in) { tokens.expiry_date = new Date().getTime() + res.data.expires_in * 1000; @@ -1002,12 +1019,17 @@ export class OAuth2Client extends AuthClient { url: this.getRevokeTokenURL(token).toString(), method: 'POST', }; + log.info('revokeToken %s', opts.url); if (callback) { - this.transporter - .request(opts) - .then(r => callback(null, r), callback); + this.transporter.request(opts).then(r => { + log.info('revokeToken success %s', r.data ?? ''); + callback(null, r); + }, callback); } else { - return this.transporter.request(opts); + return this.transporter.request(opts).then(r => { + log.info('revokeToken success %j', r.data); + return r; + }); } } @@ -1271,14 +1293,22 @@ export class OAuth2Client extends AuthClient { throw new Error(`Unsupported certificate format ${format}`); } try { + log.info('getFederatedSignonCertsAsync %s', url); res = await this.transporter.request({ ...OAuth2Client.RETRY_CONFIG, url, }); - } catch (e) { + log.info( + 'getFederatedSignonCertsAsync success %j %j', + res?.data, + res?.headers + ); + } catch (err) { + const e = err as Error; if (e instanceof Error) { e.message = `Failed to retrieve verification certificates: ${e.message}`; } + log.error('getFederatedSignonCertsAsync failed', e?.message); throw e; } @@ -1342,14 +1372,18 @@ export class OAuth2Client extends AuthClient { const url = this.endpoints.oauth2IapPublicKeyUrl.toString(); try { + log.info('getIapPublicKeysAsync %s', url); res = await this.transporter.request({ ...OAuth2Client.RETRY_CONFIG, url, }); - } catch (e) { + log.info('getIapPublicKeysAsync success %j', res.data); + } catch (err) { + const e = err as Error; if (e instanceof Error) { e.message = `Failed to retrieve verification certificates: ${e.message}`; } + log.error('getIapPublicKeysAsync failed', e?.message); throw e; } diff --git a/src/auth/refreshclient.ts b/src/auth/refreshclient.ts index 93c07d49..fe225e9f 100644 --- a/src/auth/refreshclient.ts +++ b/src/auth/refreshclient.ts @@ -20,6 +20,8 @@ import { OAuth2ClientOptions, } from './oauth2client'; import {stringify} from 'querystring'; +import {log as makeLog} from 'google-logging-utils'; +const log = makeLog('auth'); export const USER_REFRESH_ACCOUNT_TYPE = 'authorized_user'; @@ -80,13 +82,11 @@ export class UserRefreshClient extends OAuth2Client { } async fetchIdToken(targetAudience: string): Promise { - const res = await this.transporter.request({ - ...UserRefreshClient.RETRY_CONFIG, + const request = { url: this.endpoints.oauth2TokenUrl, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, - method: 'POST', data: stringify({ client_id: this._clientId, client_secret: this._clientSecret, @@ -94,8 +94,17 @@ export class UserRefreshClient extends OAuth2Client { refresh_token: this._refreshToken, target_audience: targetAudience, }), + }; + log.info('fetchIdToken %j', request); + + const res = await this.transporter.request({ + ...request, + ...UserRefreshClient.RETRY_CONFIG, + method: 'POST', }); + log.info('fetchIdToken success %s', res?.data?.id_token); + return res.data.id_token!; } diff --git a/src/auth/stscredentials.ts b/src/auth/stscredentials.ts index 291da246..597b5020 100644 --- a/src/auth/stscredentials.ts +++ b/src/auth/stscredentials.ts @@ -14,6 +14,8 @@ import {GaxiosError, GaxiosOptions, GaxiosResponse} from 'gaxios'; import * as querystring from 'querystring'; +import {log as makeLog} from 'google-logging-utils'; +const log = makeLog('auth'); import {DefaultTransporter, Transporter} from '../transporters'; import {Headers} from './oauth2client'; @@ -194,14 +196,20 @@ export class StsCredentials extends OAuthClientAuthHandler { // Inject additional STS headers if available. Object.assign(headers, additionalHeaders || {}); - const opts: GaxiosOptions = { - ...StsCredentials.RETRY_CONFIG, + const request = { url: this.tokenExchangeEndpoint.toString(), - method: 'POST', headers, data: querystring.stringify( values as unknown as querystring.ParsedUrlQueryInput ), + }; + + log.info('exchangeToken %j', request); + + const opts: GaxiosOptions = { + ...request, + ...StsCredentials.RETRY_CONFIG, + method: 'POST', responseType: 'json', }; // Apply OAuth client authentication. @@ -211,10 +219,13 @@ export class StsCredentials extends OAuthClientAuthHandler { const response = await this.transporter.request(opts); // Successful response. + log.info('exchangeToken success %j', response.data); const stsSuccessfulResponse = response.data; stsSuccessfulResponse.res = response; return stsSuccessfulResponse; } catch (error) { + log.error('exchangeToken failure %j', error); + // Translate error to OAuthError. if (error instanceof GaxiosError && error.response) { throw getErrorFromOAuthErrorResponse( diff --git a/src/auth/urlsubjecttokensupplier.ts b/src/auth/urlsubjecttokensupplier.ts index 9ae01f75..361ccad0 100644 --- a/src/auth/urlsubjecttokensupplier.ts +++ b/src/auth/urlsubjecttokensupplier.ts @@ -14,6 +14,8 @@ import {ExternalAccountSupplierContext} from './baseexternalclient'; import {GaxiosOptions} from 'gaxios'; +import {log as makeLog} from 'google-logging-utils'; +const log = makeLog('auth'); import { SubjectTokenFormatType, SubjectTokenJsonResponse, @@ -82,11 +84,16 @@ export class UrlSubjectTokenSupplier implements SubjectTokenSupplier { async getSubjectToken( context: ExternalAccountSupplierContext ): Promise { + const request = { + url: this.url, + headers: this.headers, + }; + log.info('getSubjectToken %j', request); + const opts: GaxiosOptions = { + ...request, ...this.additionalGaxiosOptions, - url: this.url, method: 'GET', - headers: this.headers, responseType: this.formatType, }; let subjectToken: string | undefined; @@ -99,10 +106,13 @@ export class UrlSubjectTokenSupplier implements SubjectTokenSupplier { subjectToken = response.data[this.subjectTokenFieldName]; } if (!subjectToken) { + log.error('getSubjectToken failed'); throw new Error( 'Unable to parse the subject_token from the credential_source URL' ); } + + log.info('getSubjectToken success %s', subjectToken); return subjectToken; } } From d0c9dff589aa9fba659a375f4ceb40324e1904ba Mon Sep 17 00:00:00 2001 From: feywind <57276408+feywind@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:45:29 -0500 Subject: [PATCH 2/4] build: add google-logging-utils in a temporary fashion --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 14965eac..a7e47c9a 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "devDependencies": { "@types/base64-js": "^1.2.5", "@types/chai": "^4.1.7", + "@types/debug": "^4.1.12", "@types/jws": "^3.1.0", "@types/mocha": "^9.0.0", "@types/mv": "^2.1.0", @@ -60,7 +61,6 @@ "nock": "^13.0.0", "null-loader": "^4.0.0", "pdfmake": "0.2.12", - "puppeteer": "^21.0.0", "sinon": "^18.0.0", "ts-loader": "^8.0.0", "typescript": "^5.1.6", From 37893f7462c2247e6af9a736767720e21665dbdb Mon Sep 17 00:00:00 2001 From: feywind <57276408+feywind@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:47:03 -0500 Subject: [PATCH 3/4] build: undo unintentional package.json changes --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a7e47c9a..14965eac 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "devDependencies": { "@types/base64-js": "^1.2.5", "@types/chai": "^4.1.7", - "@types/debug": "^4.1.12", "@types/jws": "^3.1.0", "@types/mocha": "^9.0.0", "@types/mv": "^2.1.0", @@ -61,6 +60,7 @@ "nock": "^13.0.0", "null-loader": "^4.0.0", "pdfmake": "0.2.12", + "puppeteer": "^21.0.0", "sinon": "^18.0.0", "ts-loader": "^8.0.0", "typescript": "^5.1.6", From bb258a02bec4b5731eb06b13be7fdc537d2859b1 Mon Sep 17 00:00:00 2001 From: feywind <57276408+feywind@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:50:01 -0500 Subject: [PATCH 4/4] fix: move makeLog calls into shared classes for the most part --- src/auth/authclient.ts | 2 ++ src/auth/baseexternalclient.ts | 10 +++---- .../defaultawssecuritycredentialssupplier.ts | 22 +++++++------- .../externalAccountAuthorizedUserClient.ts | 9 ++---- src/auth/oauth2client.ts | 30 +++++++++---------- src/auth/oauth2common.ts | 2 ++ src/auth/refreshclient.ts | 6 ++-- src/auth/stscredentials.ts | 8 ++--- src/auth/urlsubjecttokensupplier.ts | 8 ++--- 9 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/auth/authclient.ts b/src/auth/authclient.ts index b9de5c95..b56207fb 100644 --- a/src/auth/authclient.ts +++ b/src/auth/authclient.ts @@ -19,6 +19,7 @@ import {DefaultTransporter, Transporter} from '../transporters'; import {Credentials} from './credentials'; import {GetAccessTokenResponse, Headers} from './oauth2client'; import {OriginalAndCamel, originalOrCamelOptions} from '../util'; +import {log as makeLog} from 'google-logging-utils'; /** * Base auth configurations (e.g. from JWT or `.json` files) with conventional @@ -189,6 +190,7 @@ export abstract class AuthClient eagerRefreshThresholdMillis = DEFAULT_EAGER_REFRESH_THRESHOLD_MILLIS; forceRefreshOnFailure = false; universeDomain = DEFAULT_UNIVERSE; + log = makeLog('auth'); constructor(opts: AuthClientOptions = {}) { super(); diff --git a/src/auth/baseexternalclient.ts b/src/auth/baseexternalclient.ts index 03bf2f43..023af9f1 100644 --- a/src/auth/baseexternalclient.ts +++ b/src/auth/baseexternalclient.ts @@ -20,8 +20,6 @@ import { GaxiosResponse, } from 'gaxios'; import * as stream from 'stream'; -import {log as makeLog} from 'google-logging-utils'; -const log = makeLog('auth'); import {Credentials} from './credentials'; import {AuthClient, AuthClientOptions} from './authclient'; @@ -485,14 +483,14 @@ export abstract class BaseExternalAccountClient extends AuthClient { headers, url, }; - log.info('getProjectId %j', request); + this.log.info('getProjectId %j', request); const response = await this.transporter.request({ ...request, ...BaseExternalAccountClient.RETRY_CONFIG, responseType: 'json', }); this.projectId = response.data.projectId; - log.info('getProjectId, id %s', this.projectId); + this.log.info('getProjectId, id %s', this.projectId); return this.projectId; } return null; @@ -684,7 +682,7 @@ export abstract class BaseExternalAccountClient extends AuthClient { lifetime: this.serviceAccountImpersonationLifetime + 's', }, }; - log.info('getImpersonatedAccessToken %j', request); + this.log.info('getImpersonatedAccessToken %j', request); const opts: GaxiosOptions = { ...request, ...BaseExternalAccountClient.RETRY_CONFIG, @@ -694,7 +692,7 @@ export abstract class BaseExternalAccountClient extends AuthClient { const response = await this.transporter.request(opts); const successResponse = response.data; - log.info( + this.log.info( 'getImpersonatedAccessToken success: %s, %s, %s', successResponse.accessToken, successResponse.expireTime, diff --git a/src/auth/defaultawssecuritycredentialssupplier.ts b/src/auth/defaultawssecuritycredentialssupplier.ts index 7a413801..559d0001 100644 --- a/src/auth/defaultawssecuritycredentialssupplier.ts +++ b/src/auth/defaultawssecuritycredentialssupplier.ts @@ -12,15 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {log as makeLog} from 'google-logging-utils'; -const log = makeLog('auth'); - import {ExternalAccountSupplierContext} from './baseexternalclient'; import {Gaxios, GaxiosOptions} from 'gaxios'; import {Transporter} from '../transporters'; import {AwsSecurityCredentialsSupplier} from './awsclient'; import {AwsSecurityCredentials} from './awsrequestsigner'; import {Headers} from './oauth2client'; +import {log as makeLog} from 'google-logging-utils'; /** * Interface defining the AWS security-credentials endpoint response. @@ -85,6 +83,8 @@ export class DefaultAwsSecurityCredentialsSupplier private readonly imdsV2SessionTokenUrl?: string; private readonly additionalGaxiosOptions?: GaxiosOptions; + private log = makeLog('auth'); + /** * Instantiates a new DefaultAwsSecurityCredentialsSupplier using information * from the credential_source stored in the ADC file. @@ -129,7 +129,7 @@ export class DefaultAwsSecurityCredentialsSupplier url: this.regionUrl, headers: metadataHeaders, }; - log.info('getAwsRegion %j', request); + this.log.info('getAwsRegion %j', request); const opts: GaxiosOptions = { ...request, ...this.additionalGaxiosOptions, @@ -137,7 +137,7 @@ export class DefaultAwsSecurityCredentialsSupplier responseType: 'text', }; const response = await context.transporter.request(opts); - log.info('getAwsRegion is %s', response.data); + this.log.info('getAwsRegion is %s', response.data); // Remove last character. For example, if us-east-2b is returned, // the region would be us-east-2. return response.data.substr(0, response.data.length - 1); @@ -204,9 +204,9 @@ export class DefaultAwsSecurityCredentialsSupplier method: 'PUT', responseType: 'text', }; - log.info('#getImdsV2SessionToken %j', request); + this.log.info('#getImdsV2SessionToken %j', request); const response = await transporter.request(opts); - log.info('#getImdsV2SessionToken is %s', response.data); + this.log.info('#getImdsV2SessionToken is %s', response.data); return response.data; } @@ -230,7 +230,7 @@ export class DefaultAwsSecurityCredentialsSupplier url: this.securityCredentialsUrl, headers: headers, }; - log.info('#getAwsRoleName %j', request); + this.log.info('#getAwsRoleName %j', request); const opts: GaxiosOptions = { ...request, ...this.additionalGaxiosOptions, @@ -238,7 +238,7 @@ export class DefaultAwsSecurityCredentialsSupplier responseType: 'text', }; const response = await transporter.request(opts); - log.info('#getAwsRoleName name is %s', response.data); + this.log.info('#getAwsRoleName name is %s', response.data); return response.data; } @@ -260,13 +260,13 @@ export class DefaultAwsSecurityCredentialsSupplier url: `${this.securityCredentialsUrl}/${roleName}`, headers: headers, }; - log.info('#retrieveAwsSecurityCredentials %j', request); + this.log.info('#retrieveAwsSecurityCredentials %j', request); const response = await transporter.request({ ...request, ...this.additionalGaxiosOptions, responseType: 'json', }); - log.info('#retrieveAwsSecurityCredentials %s', response.data); + this.log.info('#retrieveAwsSecurityCredentials %s', response.data); return response.data; } diff --git a/src/auth/externalAccountAuthorizedUserClient.ts b/src/auth/externalAccountAuthorizedUserClient.ts index b80135c1..18b6cad4 100644 --- a/src/auth/externalAccountAuthorizedUserClient.ts +++ b/src/auth/externalAccountAuthorizedUserClient.ts @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {log as makeLog} from 'google-logging-utils'; -const log = makeLog('auth'); - import {AuthClient, AuthClientOptions} from './authclient'; import {Headers} from './oauth2client'; import { @@ -127,7 +124,7 @@ class ExternalAccountAuthorizedUserHandler extends OAuthClientAuthHandler { // Apply OAuth client authentication. this.applyClientAuthenticationOptions(opts); - log.info('refreshToken %j', { + this.log.info('refreshToken %j', { url: opts.url, headers: opts.headers, data: opts.data, @@ -139,12 +136,12 @@ class ExternalAccountAuthorizedUserHandler extends OAuthClientAuthHandler { // Successful response. const tokenRefreshResponse = response.data; tokenRefreshResponse.res = response; - log.info('refreshToken response %j', tokenRefreshResponse); + this.log.info('refreshToken response %j', tokenRefreshResponse); return tokenRefreshResponse; } catch (error) { // Translate error to OAuthError. if (error instanceof GaxiosError && error.response) { - log.error('refreshToken failed %j', error.response?.data); + this.log.error('refreshToken failed %j', error.response?.data); throw getErrorFromOAuthErrorResponse( error.response.data as OAuthErrorResponse, // Preserve other fields from the original error. diff --git a/src/auth/oauth2client.ts b/src/auth/oauth2client.ts index 44af6780..5e8f40e7 100644 --- a/src/auth/oauth2client.ts +++ b/src/auth/oauth2client.ts @@ -21,8 +21,6 @@ import { import * as querystring from 'querystring'; import * as stream from 'stream'; import * as formatEcdsa from 'ecdsa-sig-formatter'; -import {log as makeLog} from 'google-logging-utils'; -const log = makeLog('auth'); import {createCrypto, JwkCertificate, hasBrowserCrypto} from '../crypto/crypto'; import {BodyResponseCallback} from '../transporters'; @@ -716,7 +714,7 @@ export class OAuth2Client extends AuthClient { data: querystring.stringify(values), headers, }; - log.info('getTokenAsync %j', request); + this.log.info('getTokenAsync %j', request); const res = await this.transporter.request({ ...request, @@ -724,7 +722,7 @@ export class OAuth2Client extends AuthClient { method: 'POST', }); const tokens = res.data as Credentials; - log.info('getTokenAsync success %j', tokens); + this.log.info('getTokenAsync success %j', tokens); if (res.data && res.data.expires_in) { tokens.expiry_date = new Date().getTime() + res.data.expires_in * 1000; delete (tokens as CredentialRequest).expires_in; @@ -783,7 +781,7 @@ export class OAuth2Client extends AuthClient { data: querystring.stringify(data), headers: {'Content-Type': 'application/x-www-form-urlencoded'}, }; - log.info('refreshTokenNoCache %j', request); + this.log.info('refreshTokenNoCache %j', request); let res: GaxiosResponse; @@ -804,13 +802,13 @@ export class OAuth2Client extends AuthClient { ) { e.message = JSON.stringify(e.response.data); } - log.error('refreshTokenNoCache failure %j', e.message); + this.log.error('refreshTokenNoCache failure %j', e.message); throw e; } const tokens = res.data as Credentials; - log.info('refreshTokenNoCache success %j', tokens); + this.log.info('refreshTokenNoCache success %j', tokens); // TODO: de-duplicate this code from a few spots if (res.data && res.data.expires_in) { tokens.expiry_date = new Date().getTime() + res.data.expires_in * 1000; @@ -1019,15 +1017,15 @@ export class OAuth2Client extends AuthClient { url: this.getRevokeTokenURL(token).toString(), method: 'POST', }; - log.info('revokeToken %s', opts.url); + this.log.info('revokeToken %s', opts.url); if (callback) { this.transporter.request(opts).then(r => { - log.info('revokeToken success %s', r.data ?? ''); + this.log.info('revokeToken success %s', r.data ?? ''); callback(null, r); }, callback); } else { return this.transporter.request(opts).then(r => { - log.info('revokeToken success %j', r.data); + this.log.info('revokeToken success %j', r.data); return r; }); } @@ -1293,12 +1291,12 @@ export class OAuth2Client extends AuthClient { throw new Error(`Unsupported certificate format ${format}`); } try { - log.info('getFederatedSignonCertsAsync %s', url); + this.log.info('getFederatedSignonCertsAsync %s', url); res = await this.transporter.request({ ...OAuth2Client.RETRY_CONFIG, url, }); - log.info( + this.log.info( 'getFederatedSignonCertsAsync success %j %j', res?.data, res?.headers @@ -1308,7 +1306,7 @@ export class OAuth2Client extends AuthClient { if (e instanceof Error) { e.message = `Failed to retrieve verification certificates: ${e.message}`; } - log.error('getFederatedSignonCertsAsync failed', e?.message); + this.log.error('getFederatedSignonCertsAsync failed', e?.message); throw e; } @@ -1372,18 +1370,18 @@ export class OAuth2Client extends AuthClient { const url = this.endpoints.oauth2IapPublicKeyUrl.toString(); try { - log.info('getIapPublicKeysAsync %s', url); + this.log.info('getIapPublicKeysAsync %s', url); res = await this.transporter.request({ ...OAuth2Client.RETRY_CONFIG, url, }); - log.info('getIapPublicKeysAsync success %j', res.data); + this.log.info('getIapPublicKeysAsync success %j', res.data); } catch (err) { const e = err as Error; if (e instanceof Error) { e.message = `Failed to retrieve verification certificates: ${e.message}`; } - log.error('getIapPublicKeysAsync failed', e?.message); + this.log.error('getIapPublicKeysAsync failed', e?.message); throw e; } diff --git a/src/auth/oauth2common.ts b/src/auth/oauth2common.ts index 19f4fe8e..0d02e754 100644 --- a/src/auth/oauth2common.ts +++ b/src/auth/oauth2common.ts @@ -14,6 +14,7 @@ import {GaxiosOptions} from 'gaxios'; import * as querystring from 'querystring'; +import {log as makeLog} from 'google-logging-utils'; import {Crypto, createCrypto} from '../crypto/crypto'; @@ -69,6 +70,7 @@ export interface ClientAuthentication { */ export abstract class OAuthClientAuthHandler { private crypto: Crypto; + log = makeLog('auth'); /** * Instantiates an OAuth client authentication handler. diff --git a/src/auth/refreshclient.ts b/src/auth/refreshclient.ts index fe225e9f..998b4391 100644 --- a/src/auth/refreshclient.ts +++ b/src/auth/refreshclient.ts @@ -20,8 +20,6 @@ import { OAuth2ClientOptions, } from './oauth2client'; import {stringify} from 'querystring'; -import {log as makeLog} from 'google-logging-utils'; -const log = makeLog('auth'); export const USER_REFRESH_ACCOUNT_TYPE = 'authorized_user'; @@ -95,7 +93,7 @@ export class UserRefreshClient extends OAuth2Client { target_audience: targetAudience, }), }; - log.info('fetchIdToken %j', request); + this.log.info('fetchIdToken %j', request); const res = await this.transporter.request({ ...request, @@ -103,7 +101,7 @@ export class UserRefreshClient extends OAuth2Client { method: 'POST', }); - log.info('fetchIdToken success %s', res?.data?.id_token); + this.log.info('fetchIdToken success %s', res?.data?.id_token); return res.data.id_token!; } diff --git a/src/auth/stscredentials.ts b/src/auth/stscredentials.ts index 597b5020..a6aff436 100644 --- a/src/auth/stscredentials.ts +++ b/src/auth/stscredentials.ts @@ -14,8 +14,6 @@ import {GaxiosError, GaxiosOptions, GaxiosResponse} from 'gaxios'; import * as querystring from 'querystring'; -import {log as makeLog} from 'google-logging-utils'; -const log = makeLog('auth'); import {DefaultTransporter, Transporter} from '../transporters'; import {Headers} from './oauth2client'; @@ -204,7 +202,7 @@ export class StsCredentials extends OAuthClientAuthHandler { ), }; - log.info('exchangeToken %j', request); + this.log.info('exchangeToken %j', request); const opts: GaxiosOptions = { ...request, @@ -219,12 +217,12 @@ export class StsCredentials extends OAuthClientAuthHandler { const response = await this.transporter.request(opts); // Successful response. - log.info('exchangeToken success %j', response.data); + this.log.info('exchangeToken success %j', response.data); const stsSuccessfulResponse = response.data; stsSuccessfulResponse.res = response; return stsSuccessfulResponse; } catch (error) { - log.error('exchangeToken failure %j', error); + this.log.error('exchangeToken failure %j', error); // Translate error to OAuthError. if (error instanceof GaxiosError && error.response) { diff --git a/src/auth/urlsubjecttokensupplier.ts b/src/auth/urlsubjecttokensupplier.ts index 361ccad0..6771488e 100644 --- a/src/auth/urlsubjecttokensupplier.ts +++ b/src/auth/urlsubjecttokensupplier.ts @@ -15,7 +15,6 @@ import {ExternalAccountSupplierContext} from './baseexternalclient'; import {GaxiosOptions} from 'gaxios'; import {log as makeLog} from 'google-logging-utils'; -const log = makeLog('auth'); import { SubjectTokenFormatType, SubjectTokenJsonResponse, @@ -61,6 +60,7 @@ export class UrlSubjectTokenSupplier implements SubjectTokenSupplier { private readonly formatType: SubjectTokenFormatType; private readonly subjectTokenFieldName?: string; private readonly additionalGaxiosOptions?: GaxiosOptions; + private readonly log = makeLog('auth'); /** * Instantiates a URL subject token supplier. @@ -88,7 +88,7 @@ export class UrlSubjectTokenSupplier implements SubjectTokenSupplier { url: this.url, headers: this.headers, }; - log.info('getSubjectToken %j', request); + this.log.info('getSubjectToken %j', request); const opts: GaxiosOptions = { ...request, @@ -106,13 +106,13 @@ export class UrlSubjectTokenSupplier implements SubjectTokenSupplier { subjectToken = response.data[this.subjectTokenFieldName]; } if (!subjectToken) { - log.error('getSubjectToken failed'); + this.log.error('getSubjectToken failed'); throw new Error( 'Unable to parse the subject_token from the credential_source URL' ); } - log.info('getSubjectToken success %s', subjectToken); + this.log.info('getSubjectToken success %s', subjectToken); return subjectToken; } }