Skip to content
This repository was archived by the owner on Nov 20, 2025. It is now read-only.

Commit ba58e3b

Browse files
author
Benjamin E. Coe
authored
refactor!: getOptions() no longer accepts GoogleAuthOptions (#749)
1 parent 9f31ed7 commit ba58e3b

File tree

8 files changed

+86
-47
lines changed

8 files changed

+86
-47
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,22 @@ Before making your API call, you must be sure the API you're calling has been en
4646

4747
Rather than manually creating an OAuth2 client, JWT client, or Compute client, the auth library can create the correct credential type for you, depending upon the environment your code is running under.
4848

49-
For example, a JWT auth client will be created when your code is running on your local developer machine, and a Compute client will be created when the same code is running on Google Cloud Platform. If you need a specific set of scopes, you can pass those in the form of a string or an array into the `auth.getClient` method.
49+
For example, a JWT auth client will be created when your code is running on your local developer machine, and a Compute client will be created when the same code is running on Google Cloud Platform. If you need a specific set of scopes, you can pass those in the form of a string or an array to the `GoogleAuth` constructor.
5050

5151
The code below shows how to retrieve a default credential type, depending upon the runtime environment.
5252

5353
```js
54-
const {auth} = require('google-auth-library');
54+
const {GoogleAuth} = require('google-auth-library');
5555

5656
/**
5757
* Instead of specifying the type of client you'd like to use (JWT, OAuth2, etc)
5858
* this library will automatically choose the right client based on the environment.
5959
*/
6060
async function main() {
61-
const client = await auth.getClient({
61+
const auth = new GoogleAuth({
6262
scopes: 'https://www.googleapis.com/auth/cloud-platform'
6363
});
64+
const client = await auth.getClient();
6465
const projectId = await auth.getProjectId();
6566
const url = `https://www.googleapis.com/dns/v1/projects/${projectId}`;
6667
const res = await client.request({ url });
@@ -168,6 +169,7 @@ main().catch(console.error);
168169
```
169170

170171
#### Handling token events
172+
171173
This library will automatically obtain an `access_token`, and automatically refresh the `access_token` if a `refresh_token` is present. The `refresh_token` is only returned on the [first authorization](https://github.com/googleapis/google-api-nodejs-client/issues/750#issuecomment-304521450), so if you want to make sure you store it safely. An easy way to make sure you always store the most recent tokens is to use the `tokens` event:
172174

173175
```js

samples/adc.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616
/**
1717
* Import the GoogleAuth library, and create a new GoogleAuth client.
1818
*/
19-
const {auth} = require('google-auth-library');
19+
const {GoogleAuth} = require('google-auth-library');
2020

2121
/**
2222
* Acquire a client, and make a request to an API that's enabled by default.
2323
*/
2424
async function main() {
25-
const client = await auth.getClient({
25+
const auth = new GoogleAuth({
2626
scopes: 'https://www.googleapis.com/auth/cloud-platform',
2727
});
28+
const client = await auth.getClient();
2829
const projectId = await auth.getProjectId();
2930
const url = `https://www.googleapis.com/dns/v1/projects/${projectId}`;
3031
const res = await client.request({url});

samples/credentials.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
/**
1717
* Import the GoogleAuth library, and create a new GoogleAuth client.
1818
*/
19-
const {auth} = require('google-auth-library');
19+
const {GoogleAuth} = require('google-auth-library');
2020

2121
/**
2222
* This sample demonstrates passing a `credentials` object directly into the
@@ -33,13 +33,14 @@ async function main() {
3333
this sample.
3434
`);
3535
}
36-
const client = await auth.getClient({
36+
const auth = new GoogleAuth({
3737
credentials: {
3838
client_email: clientEmail,
3939
private_key: privateKey,
4040
},
4141
scopes: 'https://www.googleapis.com/auth/cloud-platform',
4242
});
43+
const client = await auth.getClient();
4344
const projectId = await auth.getProjectId();
4445
const url = `https://www.googleapis.com/dns/v1/projects/${projectId}`;
4546
const res = await client.request({url});

samples/headers.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
/**
1717
* Import the GoogleAuth library, and create a new GoogleAuth client.
1818
*/
19-
const {auth} = require('google-auth-library');
19+
const {GoogleAuth} = require('google-auth-library');
2020
const fetch = require('node-fetch');
2121

2222
/**
@@ -25,14 +25,15 @@ const fetch = require('node-fetch');
2525
* node-fetch, but you could use any HTTP client you like.
2626
*/
2727
async function main() {
28+
// create auth instance with custom scopes.
29+
const auth = new GoogleAuth({
30+
scopes: 'https://www.googleapis.com/auth/cloud-platform',
31+
});
2832
const projectId = await auth.getProjectId();
2933
const url = `https://www.googleapis.com/dns/v1/projects/${projectId}`;
3034

3135
// obtain an authenticated client
32-
const client = await auth.getClient({
33-
scopes: 'https://www.googleapis.com/auth/cloud-platform',
34-
});
35-
36+
const client = await auth.getClient();
3637
// Use the client to get authenticated request headers
3738
const headers = await client.getRequestHeaders();
3839
console.log('Headers:');

samples/keepalive.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@
2323
/**
2424
* Import the GoogleAuth library, and create a new GoogleAuth client.
2525
*/
26-
const {auth} = require('google-auth-library');
26+
const {GoogleAuth} = require('google-auth-library');
2727
const https = require('https');
2828

2929
/**
3030
* Acquire a client, and make a request to an API that's enabled by default.
3131
*/
3232
async function main() {
33-
const client = await auth.getClient({
33+
const auth = new GoogleAuth({
3434
scopes: 'https://www.googleapis.com/auth/cloud-platform',
3535
});
36+
const client = await auth.getClient();
3637
const projectId = await auth.getProjectId();
3738
const url = `https://www.googleapis.com/dns/v1/projects/${projectId}`;
3839

samples/keyfile.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
/**
1717
* Import the GoogleAuth library, and create a new GoogleAuth client.
1818
*/
19-
const {auth} = require('google-auth-library');
19+
const {GoogleAuth} = require('google-auth-library');
2020

2121
/**
2222
* Acquire a client, and make a request to an API that's enabled by default.
@@ -25,10 +25,11 @@ async function main(
2525
// Full path to the sevice account credential
2626
keyFile = process.env.GOOGLE_APPLICATION_CREDENTIALS
2727
) {
28-
const client = await auth.getClient({
28+
const auth = new GoogleAuth({
2929
keyFile: keyFile,
3030
scopes: 'https://www.googleapis.com/auth/cloud-platform',
3131
});
32+
const client = await auth.getClient();
3233
const projectId = await auth.getProjectId();
3334
const url = `https://www.googleapis.com/dns/v1/projects/${projectId}`;
3435
const res = await client.request({url});

src/auth/googleauth.ts

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export interface CredentialCallback {
4646
(err: Error | null, result?: UserRefreshClient | JWT): void;
4747
}
4848

49+
interface DeprecatedGetClientOptions {}
50+
4951
export interface ADCCallback {
5052
(
5153
err: Error | null,
@@ -441,7 +443,6 @@ export class GoogleAuth {
441443
'Must pass in a JSON object containing the Google auth settings.'
442444
);
443445
}
444-
this.jsonContent = json;
445446
options = options || {};
446447
if (json.type === 'authorized_user') {
447448
client = new UserRefreshClient(options);
@@ -453,6 +454,33 @@ export class GoogleAuth {
453454
return client;
454455
}
455456

457+
/**
458+
* Return a JWT or UserRefreshClient from JavaScript object, caching both the
459+
* object used to instantiate and the client.
460+
* @param json The input object.
461+
* @param options The JWT or UserRefresh options for the client
462+
* @returns JWT or UserRefresh Client with data
463+
*/
464+
private _cacheClientFromJSON(
465+
json: JWTInput,
466+
options?: RefreshOptions
467+
): JWT | UserRefreshClient {
468+
let client: UserRefreshClient | JWT;
469+
// create either a UserRefreshClient or JWT client.
470+
options = options || {};
471+
if (json.type === 'authorized_user') {
472+
client = new UserRefreshClient(options);
473+
} else {
474+
(options as JWTOptions).scopes = this.scopes;
475+
client = new JWT(options);
476+
}
477+
client.fromJSON(json);
478+
// cache both raw data used to instantiate client and client itself.
479+
this.jsonContent = json;
480+
this.cachedCredential = client;
481+
return this.cachedCredential;
482+
}
483+
456484
/**
457485
* Create a credentials instance using the given input stream.
458486
* @param inputStream The input stream.
@@ -508,7 +536,7 @@ export class GoogleAuth {
508536
.on('end', () => {
509537
try {
510538
const data = JSON.parse(s);
511-
const r = this.fromJSON(data, options);
539+
const r = this._cacheClientFromJSON(data, options);
512540
return resolve(r);
513541
} catch (err) {
514542
return reject(err);
@@ -682,27 +710,19 @@ export class GoogleAuth {
682710
* Automatically obtain a client based on the provided configuration. If no
683711
* options were passed, use Application Default Credentials.
684712
*/
685-
async getClient(options?: GoogleAuthOptions) {
713+
async getClient(options?: DeprecatedGetClientOptions) {
686714
if (options) {
687-
this.keyFilename =
688-
options.keyFilename || options.keyFile || this.keyFilename;
689-
this.scopes = options.scopes || this.scopes;
690-
this.jsonContent = options.credentials || this.jsonContent;
691-
this.clientOptions = options.clientOptions;
715+
throw new Error(
716+
'Passing options to getClient is forbidden in v5.0.0. Use new GoogleAuth(opts) instead.'
717+
);
692718
}
693719
if (!this.cachedCredential) {
694720
if (this.jsonContent) {
695-
this.cachedCredential = await this.fromJSON(
696-
this.jsonContent,
697-
this.clientOptions
698-
);
721+
this._cacheClientFromJSON(this.jsonContent, this.clientOptions);
699722
} else if (this.keyFilename) {
700723
const filePath = path.resolve(this.keyFilename);
701724
const stream = fs.createReadStream(filePath);
702-
this.cachedCredential = await this.fromStreamAsync(
703-
stream,
704-
this.clientOptions
705-
);
725+
await this.fromStreamAsync(stream, this.clientOptions);
706726
} else {
707727
await this.getApplicationDefaultAsync(this.clientOptions);
708728
}

test/test.googleauth.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,16 @@ describe('googleauth', () => {
231231
});
232232
});
233233

234+
it('fromJson should not overwrite previous client configuration', async () => {
235+
const auth = new GoogleAuth({keyFilename: './test/fixtures/private.json'});
236+
auth.fromJSON({
237+
client_email: 'batman@example.com',
238+
private_key: 'abc123',
239+
});
240+
const client = (await auth.getClient()) as JWT;
241+
assert.strictEqual(client.email, 'hello@youarecool.com');
242+
});
243+
234244
it('fromAPIKey should error given an invalid api key', () => {
235245
assert.throws(() => {
236246
// Test verifies invalid parameter tests, which requires cast to any.
@@ -1124,7 +1134,7 @@ describe('googleauth', () => {
11241134

11251135
it('should use jsonContent if available', async () => {
11261136
const json = createJwtJSON();
1127-
auth.fromJSON(json);
1137+
const auth = new GoogleAuth({credentials: json});
11281138
// We know this returned a cached result if a nock scope isn't required
11291139
const body = await auth.getCredentials();
11301140
assert.notStrictEqual(body, null);
@@ -1138,10 +1148,8 @@ describe('googleauth', () => {
11381148
});
11391149

11401150
it('should error when invalid keyFilename passed to getClient', async () => {
1141-
await assertRejects(
1142-
auth.getClient({keyFilename: './funky/fresh.json'}),
1143-
/ENOENT: no such file or directory/
1144-
);
1151+
const auth = new GoogleAuth({keyFilename: './funky/fresh.json'});
1152+
await assertRejects(auth.getClient(), /ENOENT: no such file or directory/);
11451153
});
11461154

11471155
it('should accept credentials to get a client', async () => {
@@ -1165,21 +1173,24 @@ describe('googleauth', () => {
11651173
it('should allow passing scopes to get a client', async () => {
11661174
const scopes = ['http://examples.com/is/a/scope'];
11671175
const keyFilename = './test/fixtures/private.json';
1168-
const client = (await auth.getClient({scopes, keyFilename})) as JWT;
1176+
const auth = new GoogleAuth({scopes, keyFilename});
1177+
const client = (await auth.getClient()) as JWT;
11691178
assert.strictEqual(client.scopes, scopes);
11701179
});
11711180

11721181
it('should allow passing a scope to get a client', async () => {
11731182
const scopes = 'http://examples.com/is/a/scope';
11741183
const keyFilename = './test/fixtures/private.json';
1175-
const client = (await auth.getClient({scopes, keyFilename})) as JWT;
1184+
const auth = new GoogleAuth({scopes, keyFilename});
1185+
const client = (await auth.getClient()) as JWT;
11761186
assert.strictEqual(client.scopes, scopes);
11771187
});
11781188

11791189
it('should allow passing a scope to get a Compute client', async () => {
11801190
const scopes = ['http://examples.com/is/a/scope'];
11811191
const nockScopes = [nockIsGCE(), createGetProjectIdNock()];
1182-
const client = (await auth.getClient({scopes})) as Compute;
1192+
const auth = new GoogleAuth({scopes});
1193+
const client = (await auth.getClient()) as Compute;
11831194
assert.strictEqual(client.scopes, scopes);
11841195
nockScopes.forEach(x => x.done());
11851196
});
@@ -1348,13 +1359,6 @@ describe('googleauth', () => {
13481359
assert.strictEqual(count, 0);
13491360
});
13501361

1351-
it('should pass options to the JWT constructor via getClient', async () => {
1352-
const subject = 'science!';
1353-
const auth = new GoogleAuth({keyFilename: './test/fixtures/private.json'});
1354-
const client = (await auth.getClient({clientOptions: {subject}})) as JWT;
1355-
assert.strictEqual(client.subject, subject);
1356-
});
1357-
13581362
it('should pass options to the JWT constructor via constructor', async () => {
13591363
const subject = 'science!';
13601364
const auth = new GoogleAuth({
@@ -1373,4 +1377,12 @@ describe('googleauth', () => {
13731377
/Unable to detect a Project Id in the current environment/
13741378
);
13751379
});
1380+
1381+
it('should throw if options are passed to getClient()', async () => {
1382+
const auth = new GoogleAuth();
1383+
await assertRejects(
1384+
auth.getClient({hello: 'world'}),
1385+
/Passing options to getClient is forbidden in v5.0.0/
1386+
);
1387+
});
13761388
});

0 commit comments

Comments
 (0)