/
opt
/
canhelp
/
node_modules
/
google-auth-library
/
build
/
src
/
auth
/
/opt/canhelp/node_modules/google-auth-library/build/src/auth
mkdir
upload
Name
Size
Mode
Actions
authclient.d.ts
10764
0644
edit
dl
rm
authclient.js
11247
0644
edit
dl
rm
awsclient.d.ts
5315
0644
edit
dl
rm
awsclient.js
7556
0644
edit
dl
rm
awsrequestsigner.d.ts
1626
0644
edit
dl
rm
awsrequestsigner.js
9442
0644
edit
dl
rm
baseexternalclient.d.ts
13020
0644
edit
dl
rm
baseexternalclient.js
20857
0644
edit
dl
rm
certificatesubjecttokensupplier.d.ts
2202
0644
edit
dl
rm
certificatesubjecttokensupplier.js
10619
0644
edit
dl
rm
computeclient.d.ts
1359
0644
edit
dl
rm
computeclient.js
4497
0644
edit
dl
rm
credentials.d.ts
2359
0644
edit
dl
rm
credentials.js
704
0644
edit
dl
rm
defaultawssecuritycredentialssupplier.d.ts
3795
0644
edit
dl
rm
defaultawssecuritycredentialssupplier.js
9330
0644
edit
dl
rm
downscopedclient.d.ts
6693
0644
edit
dl
rm
downscopedclient.js
12353
0644
edit
dl
rm
envDetect.d.ts
363
0644
edit
dl
rm
envDetect.js
2831
0644
edit
dl
rm
executable-response.d.ts
4489
0644
edit
dl
rm
executable-response.js
7519
0644
edit
dl
rm
externalAccountAuthorizedUserClient.d.ts
3173
0644
edit
dl
rm
externalAccountAuthorizedUserClient.js
10005
0644
edit
dl
rm
externalclient.d.ts
1528
0644
edit
dl
rm
externalclient.js
3048
0644
edit
dl
rm
filesubjecttokensupplier.d.ts
1608
0644
edit
dl
rm
filesubjecttokensupplier.js
3515
0644
edit
dl
rm
googleauth.d.ts
23574
0644
edit
dl
rm
googleauth.js
36374
0644
edit
dl
rm
iam.d.ts
623
0644
edit
dl
rm
iam.js
1373
0644
edit
dl
rm
identitypoolclient.d.ts
5626
0644
edit
dl
rm
identitypoolclient.js
6775
0644
edit
dl
rm
idtokenclient.d.ts
938
0644
edit
dl
rm
idtokenclient.js
2106
0644
edit
dl
rm
impersonated.d.ts
5687
0644
edit
dl
rm
impersonated.js
8654
0644
edit
dl
rm
jwtaccess.d.ts
2336
0644
edit
dl
rm
jwtaccess.js
7213
0644
edit
dl
rm
jwtclient.d.ts
5122
0644
edit
dl
rm
jwtclient.js
11256
0644
edit
dl
rm
loginticket.d.ts
5367
0644
edit
dl
rm
loginticket.js
1795
0644
edit
dl
rm
oauth2client.d.ts
25326
0644
edit
dl
rm
oauth2client.js
33662
0644
edit
dl
rm
oauth2common.d.ts
4094
0644
edit
dl
rm
oauth2common.js
8080
0644
edit
dl
rm
passthrough.d.ts
1097
0644
edit
dl
rm
passthrough.js
1842
0644
edit
dl
rm
pluggable-auth-client.d.ts
5485
0644
edit
dl
rm
pluggable-auth-client.js
10002
0644
edit
dl
rm
pluggable-auth-handler.d.ts
2109
0644
edit
dl
rm
pluggable-auth-handler.js
7260
0644
edit
dl
rm
refreshclient.d.ts
3436
0644
edit
dl
rm
refreshclient.js
6650
0644
edit
dl
rm
stscredentials.d.ts
5261
0644
edit
dl
rm
stscredentials.js
4738
0644
edit
dl
rm
urlsubjecttokensupplier.d.ts
2186
0644
edit
dl
rm
urlsubjecttokensupplier.js
2859
0644
edit
dl
rm
Edit:
/opt/canhelp/node_modules/google-auth-library/build/src/auth/oauth2client.js
(33662B)
"use strict"; // Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. Object.defineProperty(exports, "__esModule", { value: true }); exports.OAuth2Client = exports.ClientAuthentication = exports.CertificateFormat = exports.CodeChallengeMethod = void 0; const gaxios_1 = require("gaxios"); const querystring = require("querystring"); const stream = require("stream"); const formatEcdsa = require("ecdsa-sig-formatter"); const util_1 = require("../util"); const crypto_1 = require("../crypto/crypto"); const authclient_1 = require("./authclient"); const loginticket_1 = require("./loginticket"); var CodeChallengeMethod; (function (CodeChallengeMethod) { CodeChallengeMethod["Plain"] = "plain"; CodeChallengeMethod["S256"] = "S256"; })(CodeChallengeMethod || (exports.CodeChallengeMethod = CodeChallengeMethod = {})); var CertificateFormat; (function (CertificateFormat) { CertificateFormat["PEM"] = "PEM"; CertificateFormat["JWK"] = "JWK"; })(CertificateFormat || (exports.CertificateFormat = CertificateFormat = {})); /** * The client authentication type. Supported values are basic, post, and none. * https://datatracker.ietf.org/doc/html/rfc7591#section-2 */ var ClientAuthentication; (function (ClientAuthentication) { ClientAuthentication["ClientSecretPost"] = "ClientSecretPost"; ClientAuthentication["ClientSecretBasic"] = "ClientSecretBasic"; ClientAuthentication["None"] = "None"; })(ClientAuthentication || (exports.ClientAuthentication = ClientAuthentication = {})); class OAuth2Client extends authclient_1.AuthClient { redirectUri; certificateCache = {}; certificateExpiry = null; certificateCacheFormat = CertificateFormat.PEM; refreshTokenPromises = new Map(); endpoints; issuers; clientAuthentication; // TODO: refactor tests to make this private _clientId; // TODO: refactor tests to make this private _clientSecret; refreshHandler; /** * An OAuth2 Client for Google APIs. * * @param options The OAuth2 Client Options. Passing an `clientId` directly is **@DEPRECATED**. * @param clientSecret **@DEPRECATED**. Provide a {@link OAuth2ClientOptions `OAuth2ClientOptions`} object in the first parameter instead. * @param redirectUri **@DEPRECATED**. Provide a {@link OAuth2ClientOptions `OAuth2ClientOptions`} object in the first parameter instead. */ constructor(options = {}, /** * @deprecated - provide a {@link OAuth2ClientOptions `OAuth2ClientOptions`} object in the first parameter instead */ clientSecret, /** * @deprecated - provide a {@link OAuth2ClientOptions `OAuth2ClientOptions`} object in the first parameter instead */ redirectUri) { super(typeof options === 'object' ? options : {}); if (typeof options !== 'object') { options = { clientId: options, clientSecret, redirectUri, }; } this._clientId = options.clientId || options.client_id; this._clientSecret = options.clientSecret || options.client_secret; this.redirectUri = options.redirectUri || options.redirect_uris?.[0]; this.endpoints = { tokenInfoUrl: 'https://oauth2.googleapis.com/tokeninfo', oauth2AuthBaseUrl: 'https://accounts.google.com/o/oauth2/v2/auth', oauth2TokenUrl: 'https://oauth2.googleapis.com/token', oauth2RevokeUrl: 'https://oauth2.googleapis.com/revoke', oauth2FederatedSignonPemCertsUrl: 'https://www.googleapis.com/oauth2/v1/certs', oauth2FederatedSignonJwkCertsUrl: 'https://www.googleapis.com/oauth2/v3/certs', oauth2IapPublicKeyUrl: 'https://www.gstatic.com/iap/verify/public_key', ...options.endpoints, }; this.clientAuthentication = options.clientAuthentication || ClientAuthentication.ClientSecretPost; this.issuers = options.issuers || [ 'accounts.google.com', 'https://accounts.google.com', this.universeDomain, ]; } /** * @deprecated use instance's {@link OAuth2Client.endpoints} */ static GOOGLE_TOKEN_INFO_URL = 'https://oauth2.googleapis.com/tokeninfo'; /** * Clock skew - five minutes in seconds */ static CLOCK_SKEW_SECS_ = 300; /** * The default max Token Lifetime is one day in seconds */ static DEFAULT_MAX_TOKEN_LIFETIME_SECS_ = 86400; /** * Generates URL for consent page landing. * @param opts Options. * @return URL to consent page. */ generateAuthUrl(opts = {}) { if (opts.code_challenge_method && !opts.code_challenge) { throw new Error('If a code_challenge_method is provided, code_challenge must be included.'); } opts.response_type = opts.response_type || 'code'; opts.client_id = opts.client_id || this._clientId; opts.redirect_uri = opts.redirect_uri || this.redirectUri; // Allow scopes to be passed either as array or a string if (Array.isArray(opts.scope)) { opts.scope = opts.scope.join(' '); } const rootUrl = this.endpoints.oauth2AuthBaseUrl.toString(); return (rootUrl + '?' + querystring.stringify(opts)); } generateCodeVerifier() { // To make the code compatible with browser SubtleCrypto we need to make // this method async. throw new Error('generateCodeVerifier is removed, please use generateCodeVerifierAsync instead.'); } /** * Convenience method to automatically generate a code_verifier, and its * resulting SHA256. If used, this must be paired with a S256 * code_challenge_method. * * For a full example see: * https://github.com/googleapis/google-auth-library-nodejs/blob/main/samples/oauth2-codeVerifier.js */ async generateCodeVerifierAsync() { // base64 encoding uses 6 bits per character, and we want to generate128 // characters. 6*128/8 = 96. const crypto = (0, crypto_1.createCrypto)(); const randomString = crypto.randomBytesBase64(96); // The valid characters in the code_verifier are [A-Z]/[a-z]/[0-9]/ // "-"/"."/"_"/"~". Base64 encoded strings are pretty close, so we're just // swapping out a few chars. const codeVerifier = randomString .replace(/\+/g, '~') .replace(/=/g, '_') .replace(/\//g, '-'); // Generate the base64 encoded SHA256 const unencodedCodeChallenge = await crypto.sha256DigestBase64(codeVerifier); // We need to use base64UrlEncoding instead of standard base64 const codeChallenge = unencodedCodeChallenge .split('=')[0] .replace(/\+/g, '-') .replace(/\//g, '_'); return { codeVerifier, codeChallenge }; } getToken(codeOrOptions, callback) { const options = typeof codeOrOptions === 'string' ? { code: codeOrOptions } : codeOrOptions; if (callback) { this.getTokenAsync(options).then(r => callback(null, r.tokens, r.res), e => callback(e, null, e.response)); } else { return this.getTokenAsync(options); } } async getTokenAsync(options) { const url = this.endpoints.oauth2TokenUrl.toString(); const headers = new Headers(); const values = { client_id: options.client_id || this._clientId, code_verifier: options.codeVerifier, code: options.code, grant_type: 'authorization_code', redirect_uri: options.redirect_uri || this.redirectUri, }; if (this.clientAuthentication === ClientAuthentication.ClientSecretBasic) { const basic = Buffer.from(`${this._clientId}:${this._clientSecret}`); headers.set('authorization', `Basic ${basic.toString('base64')}`); } if (this.clientAuthentication === ClientAuthentication.ClientSecretPost) { values.client_secret = this._clientSecret; } const opts = { ...OAuth2Client.RETRY_CONFIG, method: 'POST', url, data: new URLSearchParams((0, util_1.removeUndefinedValuesInObject)(values)), headers, }; authclient_1.AuthClient.setMethodName(opts, 'getTokenAsync'); const res = await this.transporter.request(opts); const tokens = res.data; if (res.data && res.data.expires_in) { tokens.expiry_date = new Date().getTime() + res.data.expires_in * 1000; delete tokens.expires_in; } this.emit('tokens', tokens); return { tokens, res }; } /** * Refreshes the access token. * @param refresh_token Existing refresh token. * @private */ async refreshToken(refreshToken) { if (!refreshToken) { return this.refreshTokenNoCache(refreshToken); } // If a request to refresh using the same token has started, // return the same promise. if (this.refreshTokenPromises.has(refreshToken)) { return this.refreshTokenPromises.get(refreshToken); } const p = this.refreshTokenNoCache(refreshToken).then(r => { this.refreshTokenPromises.delete(refreshToken); return r; }, e => { this.refreshTokenPromises.delete(refreshToken); throw e; }); this.refreshTokenPromises.set(refreshToken, p); return p; } async refreshTokenNoCache(refreshToken) { if (!refreshToken) { throw new Error('No refresh token is set.'); } const url = this.endpoints.oauth2TokenUrl.toString(); const data = { refresh_token: refreshToken, client_id: this._clientId, client_secret: this._clientSecret, grant_type: 'refresh_token', }; let res; try { const opts = { ...OAuth2Client.RETRY_CONFIG, method: 'POST', url, data: new URLSearchParams((0, util_1.removeUndefinedValuesInObject)(data)), }; authclient_1.AuthClient.setMethodName(opts, 'refreshTokenNoCache'); // request for new token res = await this.transporter.request(opts); } catch (e) { if (e instanceof gaxios_1.GaxiosError && e.message === 'invalid_grant' && e.response?.data && /ReAuth/i.test(e.response.data.error_description)) { e.message = JSON.stringify(e.response.data); } throw e; } const tokens = res.data; // 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; delete tokens.expires_in; } this.emit('tokens', tokens); return { tokens, res }; } refreshAccessToken(callback) { if (callback) { this.refreshAccessTokenAsync().then(r => callback(null, r.credentials, r.res), callback); } else { return this.refreshAccessTokenAsync(); } } async refreshAccessTokenAsync() { const r = await this.refreshToken(this.credentials.refresh_token); const tokens = r.tokens; tokens.refresh_token = this.credentials.refresh_token; this.credentials = tokens; return { credentials: this.credentials, res: r.res }; } getAccessToken(callback) { if (callback) { this.getAccessTokenAsync().then(r => callback(null, r.token, r.res), callback); } else { return this.getAccessTokenAsync(); } } async getAccessTokenAsync() { const shouldRefresh = !this.credentials.access_token || this.isTokenExpiring(); if (shouldRefresh) { if (!this.credentials.refresh_token) { if (this.refreshHandler) { const refreshedAccessToken = await this.processAndValidateRefreshHandler(); if (refreshedAccessToken?.access_token) { this.setCredentials(refreshedAccessToken); return { token: this.credentials.access_token }; } } else { throw new Error('No refresh token or refresh handler callback is set.'); } } const r = await this.refreshAccessTokenAsync(); if (!r.credentials || (r.credentials && !r.credentials.access_token)) { throw new Error('Could not refresh access token.'); } return { token: r.credentials.access_token, res: r.res }; } else { return { token: this.credentials.access_token }; } } /** * The main authentication interface. It takes an optional url which when * present is the endpoint being accessed, and returns a Promise which * resolves with authorization header fields. * * In OAuth2Client, the result has the form: * { authorization: 'Bearer <access_token_value>' } */ async getRequestHeaders(url) { const headers = (await this.getRequestMetadataAsync(url)).headers; return headers; } async getRequestMetadataAsync(url) { url; const thisCreds = this.credentials; if (!thisCreds.access_token && !thisCreds.refresh_token && !this.apiKey && !this.refreshHandler) { throw new Error('No access, refresh token, API key or refresh handler callback is set.'); } if (thisCreds.access_token && !this.isTokenExpiring()) { thisCreds.token_type = thisCreds.token_type || 'Bearer'; const headers = new Headers({ authorization: thisCreds.token_type + ' ' + thisCreds.access_token, }); return { headers: this.addSharedMetadataHeaders(headers) }; } // If refreshHandler exists, call processAndValidateRefreshHandler(). if (this.refreshHandler) { const refreshedAccessToken = await this.processAndValidateRefreshHandler(); if (refreshedAccessToken?.access_token) { this.setCredentials(refreshedAccessToken); const headers = new Headers({ authorization: 'Bearer ' + this.credentials.access_token, }); return { headers: this.addSharedMetadataHeaders(headers) }; } } if (this.apiKey) { return { headers: new Headers({ 'X-Goog-Api-Key': this.apiKey }) }; } let r = null; let tokens = null; try { r = await this.refreshToken(thisCreds.refresh_token); tokens = r.tokens; } catch (err) { const e = err; if (e.response && (e.response.status === 403 || e.response.status === 404)) { e.message = `Could not refresh access token: ${e.message}`; } throw e; } const credentials = this.credentials; credentials.token_type = credentials.token_type || 'Bearer'; tokens.refresh_token = credentials.refresh_token; this.credentials = tokens; const headers = new Headers({ authorization: credentials.token_type + ' ' + tokens.access_token, }); return { headers: this.addSharedMetadataHeaders(headers), res: r.res }; } /** * Generates an URL to revoke the given token. * @param token The existing token to be revoked. * * @deprecated use instance method {@link OAuth2Client.getRevokeTokenURL} */ static getRevokeTokenUrl(token) { return new OAuth2Client().getRevokeTokenURL(token).toString(); } /** * Generates a URL to revoke the given token. * * @param token The existing token to be revoked. */ getRevokeTokenURL(token) { const url = new URL(this.endpoints.oauth2RevokeUrl); url.searchParams.append('token', token); return url; } revokeToken(token, callback) { const opts = { ...OAuth2Client.RETRY_CONFIG, url: this.getRevokeTokenURL(token).toString(), method: 'POST', }; authclient_1.AuthClient.setMethodName(opts, 'revokeToken'); if (callback) { this.transporter .request(opts) .then(r => callback(null, r), callback); } else { return this.transporter.request(opts); } } revokeCredentials(callback) { if (callback) { this.revokeCredentialsAsync().then(res => callback(null, res), callback); } else { return this.revokeCredentialsAsync(); } } async revokeCredentialsAsync() { const token = this.credentials.access_token; this.credentials = {}; if (token) { return this.revokeToken(token); } else { throw new Error('No access token to revoke.'); } } request(opts, callback) { if (callback) { this.requestAsync(opts).then(r => callback(null, r), e => { return callback(e, e.response); }); } else { return this.requestAsync(opts); } } async requestAsync(opts, reAuthRetried = false) { try { const r = await this.getRequestMetadataAsync(); opts.headers = gaxios_1.Gaxios.mergeHeaders(opts.headers); this.addUserProjectAndAuthHeaders(opts.headers, r.headers); if (this.apiKey) { opts.headers.set('X-Goog-Api-Key', this.apiKey); } return await this.transporter.request(opts); } catch (e) { const res = e.response; if (res) { const statusCode = res.status; // Retry the request for metadata if the following criteria are true: // - We haven't already retried. It only makes sense to retry once. // - The response was a 401 or a 403 // - The request didn't send a readableStream // - An access_token and refresh_token were available, but either no // expiry_date was available or the forceRefreshOnFailure flag is set. // The absent expiry_date case can happen when developers stash the // access_token and refresh_token for later use, but the access_token // fails on the first try because it's expired. Some developers may // choose to enable forceRefreshOnFailure to mitigate time-related // errors. // Or the following criteria are true: // - We haven't already retried. It only makes sense to retry once. // - The response was a 401 or a 403 // - The request didn't send a readableStream // - No refresh_token was available // - An access_token and a refreshHandler callback were available, but // either no expiry_date was available or the forceRefreshOnFailure // flag is set. The access_token fails on the first try because it's // expired. Some developers may choose to enable forceRefreshOnFailure // to mitigate time-related errors. const mayRequireRefresh = this.credentials && this.credentials.access_token && this.credentials.refresh_token && (!this.credentials.expiry_date || this.forceRefreshOnFailure); const mayRequireRefreshWithNoRefreshToken = this.credentials && this.credentials.access_token && !this.credentials.refresh_token && (!this.credentials.expiry_date || this.forceRefreshOnFailure) && this.refreshHandler; const isReadableStream = res.config.data instanceof stream.Readable; const isAuthErr = statusCode === 401 || statusCode === 403; if (!reAuthRetried && isAuthErr && !isReadableStream && mayRequireRefresh) { await this.refreshAccessTokenAsync(); return this.requestAsync(opts, true); } else if (!reAuthRetried && isAuthErr && !isReadableStream && mayRequireRefreshWithNoRefreshToken) { const refreshedAccessToken = await this.processAndValidateRefreshHandler(); if (refreshedAccessToken?.access_token) { this.setCredentials(refreshedAccessToken); } return this.requestAsync(opts, true); } } throw e; } } verifyIdToken(options, callback) { // This function used to accept two arguments instead of an options object. // Check the types to help users upgrade with less pain. // This check can be removed after a 2.0 release. if (callback && typeof callback !== 'function') { throw new Error('This method accepts an options object as the first parameter, which includes the idToken, audience, and maxExpiry.'); } if (callback) { this.verifyIdTokenAsync(options).then(r => callback(null, r), callback); } else { return this.verifyIdTokenAsync(options); } } async verifyIdTokenAsync(options) { if (!options.idToken) { throw new Error('The verifyIdToken method requires an ID Token'); } const response = await this.getFederatedSignonCertsAsync(); const login = await this.verifySignedJwtWithCertsAsync(options.idToken, response.certs, options.audience, this.issuers, options.maxExpiry); return login; } /** * Obtains information about the provisioned access token. Especially useful * if you want to check the scopes that were provisioned to a given token. * * @param accessToken Required. The Access Token for which you want to get * user info. */ async getTokenInfo(accessToken) { const { data } = await this.transporter.request({ ...OAuth2Client.RETRY_CONFIG, method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded;charset=UTF-8', authorization: `Bearer ${accessToken}`, }, url: this.endpoints.tokenInfoUrl.toString(), }); const info = Object.assign({ expiry_date: new Date().getTime() + data.expires_in * 1000, scopes: data.scope.split(' '), }, data); delete info.expires_in; delete info.scope; return info; } getFederatedSignonCerts(callback) { if (callback) { this.getFederatedSignonCertsAsync().then(r => callback(null, r.certs, r.res), callback); } else { return this.getFederatedSignonCertsAsync(); } } async getFederatedSignonCertsAsync() { const nowTime = new Date().getTime(); const format = (0, crypto_1.hasBrowserCrypto)() ? CertificateFormat.JWK : CertificateFormat.PEM; if (this.certificateExpiry && nowTime < this.certificateExpiry.getTime() && this.certificateCacheFormat === format) { return { certs: this.certificateCache, format }; } let res; let url; switch (format) { case CertificateFormat.PEM: url = this.endpoints.oauth2FederatedSignonPemCertsUrl.toString(); break; case CertificateFormat.JWK: url = this.endpoints.oauth2FederatedSignonJwkCertsUrl.toString(); break; default: throw new Error(`Unsupported certificate format ${format}`); } try { const opts = { ...OAuth2Client.RETRY_CONFIG, url, }; authclient_1.AuthClient.setMethodName(opts, 'getFederatedSignonCertsAsync'); res = await this.transporter.request(opts); } catch (e) { if (e instanceof Error) { e.message = `Failed to retrieve verification certificates: ${e.message}`; } throw e; } const cacheControl = res?.headers.get('cache-control'); let cacheAge = -1; if (cacheControl) { const maxAge = /max-age=(?<maxAge>[0-9]+)/.exec(cacheControl)?.groups ?.maxAge; if (maxAge) { // Cache results with max-age (in seconds) cacheAge = Number(maxAge) * 1000; // milliseconds } } let certificates = {}; switch (format) { case CertificateFormat.PEM: certificates = res.data; break; case CertificateFormat.JWK: for (const key of res.data.keys) { certificates[key.kid] = key; } break; default: throw new Error(`Unsupported certificate format ${format}`); } const now = new Date(); this.certificateExpiry = cacheAge === -1 ? null : new Date(now.getTime() + cacheAge); this.certificateCache = certificates; this.certificateCacheFormat = format; return { certs: certificates, format, res }; } getIapPublicKeys(callback) { if (callback) { this.getIapPublicKeysAsync().then(r => callback(null, r.pubkeys, r.res), callback); } else { return this.getIapPublicKeysAsync(); } } async getIapPublicKeysAsync() { let res; const url = this.endpoints.oauth2IapPublicKeyUrl.toString(); try { const opts = { ...OAuth2Client.RETRY_CONFIG, url, }; authclient_1.AuthClient.setMethodName(opts, 'getIapPublicKeysAsync'); res = await this.transporter.request(opts); } catch (e) { if (e instanceof Error) { e.message = `Failed to retrieve verification certificates: ${e.message}`; } throw e; } return { pubkeys: res.data, res }; } verifySignedJwtWithCerts() { // To make the code compatible with browser SubtleCrypto we need to make // this method async. throw new Error('verifySignedJwtWithCerts is removed, please use verifySignedJwtWithCertsAsync instead.'); } /** * Verify the id token is signed with the correct certificate * and is from the correct audience. * @param jwt The jwt to verify (The ID Token in this case). * @param certs The array of certs to test the jwt against. * @param requiredAudience The audience to test the jwt against. * @param issuers The allowed issuers of the jwt (Optional). * @param maxExpiry The max expiry the certificate can be (Optional). * @return Returns a promise resolving to LoginTicket on verification. */ async verifySignedJwtWithCertsAsync(jwt, certs, requiredAudience, issuers, maxExpiry) { const crypto = (0, crypto_1.createCrypto)(); if (!maxExpiry) { maxExpiry = OAuth2Client.DEFAULT_MAX_TOKEN_LIFETIME_SECS_; } const segments = jwt.split('.'); if (segments.length !== 3) { throw new Error('Wrong number of segments in token: ' + jwt); } const signed = segments[0] + '.' + segments[1]; let signature = segments[2]; let envelope; let payload; try { envelope = JSON.parse(crypto.decodeBase64StringUtf8(segments[0])); } catch (err) { if (err instanceof Error) { err.message = `Can't parse token envelope: ${segments[0]}': ${err.message}`; } throw err; } if (!envelope) { throw new Error("Can't parse token envelope: " + segments[0]); } try { payload = JSON.parse(crypto.decodeBase64StringUtf8(segments[1])); } catch (err) { if (err instanceof Error) { err.message = `Can't parse token payload '${segments[0]}`; } throw err; } if (!payload) { throw new Error("Can't parse token payload: " + segments[1]); } if (!Object.prototype.hasOwnProperty.call(certs, envelope.kid)) { // If this is not present, then there's no reason to attempt verification throw new Error('No pem found for envelope: ' + JSON.stringify(envelope)); } const cert = certs[envelope.kid]; if (envelope.alg === 'ES256') { signature = formatEcdsa.joseToDer(signature, 'ES256').toString('base64'); } const verified = await crypto.verify(cert, signed, signature); if (!verified) { throw new Error('Invalid token signature: ' + jwt); } if (!payload.iat) { throw new Error('No issue time in token: ' + JSON.stringify(payload)); } if (!payload.exp) { throw new Error('No expiration time in token: ' + JSON.stringify(payload)); } const iat = Number(payload.iat); if (isNaN(iat)) throw new Error('iat field using invalid format'); const exp = Number(payload.exp); if (isNaN(exp)) throw new Error('exp field using invalid format'); const now = new Date().getTime() / 1000; if (exp >= now + maxExpiry) { throw new Error('Expiration time too far in future: ' + JSON.stringify(payload)); } const earliest = iat - OAuth2Client.CLOCK_SKEW_SECS_; const latest = exp + OAuth2Client.CLOCK_SKEW_SECS_; if (now < earliest) { throw new Error('Token used too early, ' + now + ' < ' + earliest + ': ' + JSON.stringify(payload)); } if (now > latest) { throw new Error('Token used too late, ' + now + ' > ' + latest + ': ' + JSON.stringify(payload)); } if (issuers && issuers.indexOf(payload.iss) < 0) { throw new Error('Invalid issuer, expected one of [' + issuers + '], but got ' + payload.iss); } // Check the audience matches if we have one if (typeof requiredAudience !== 'undefined' && requiredAudience !== null) { const aud = payload.aud; let audVerified = false; // If the requiredAudience is an array, check if it contains token // audience if (requiredAudience.constructor === Array) { audVerified = requiredAudience.indexOf(aud) > -1; } else { audVerified = aud === requiredAudience; } if (!audVerified) { throw new Error('Wrong recipient, payload audience != requiredAudience'); } } return new loginticket_1.LoginTicket(envelope, payload); } /** * Returns a promise that resolves with AccessTokenResponse type if * refreshHandler is defined. * If not, nothing is returned. */ async processAndValidateRefreshHandler() { if (this.refreshHandler) { const accessTokenResponse = await this.refreshHandler(); if (!accessTokenResponse.access_token) { throw new Error('No access token is returned by the refreshHandler callback.'); } return accessTokenResponse; } return; } /** * Returns true if a token is expired or will expire within * eagerRefreshThresholdMillismilliseconds. * If there is no expiry time, assumes the token is not expired or expiring. */ isTokenExpiring() { const expiryDate = this.credentials.expiry_date; return expiryDate ? expiryDate <= new Date().getTime() + this.eagerRefreshThresholdMillis : false; } } exports.OAuth2Client = OAuth2Client; //# sourceMappingURL=oauth2client.js.map
Save
cmd:
run