Skip to content

Commit c219835

Browse files
Ensure to pass-trough options to TokenProvider (#938)
1 parent 3c4ac31 commit c219835

File tree

6 files changed

+40
-36
lines changed

6 files changed

+40
-36
lines changed

src/management/management-client-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface ManagementClientOptionsWithClientSecret extends ManagementClien
1717
export interface ManagementClientOptionsWithClientAssertion extends ManagementClientOptions {
1818
clientId: string;
1919
clientAssertionSigningKey: string;
20+
clientAssertionSigningAlg?: string;
2021
}
2122

2223
export type ManagementClientOptionsWithClientCredentials =

src/management/token-provider-middleware.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ export class TokenProviderMiddleware implements Middleware {
1818
};
1919
} else {
2020
this.tokenProvider = new TokenProvider({
21-
clientId: options.clientId,
22-
domain: options.domain,
21+
...options,
2322
audience: options.audience ?? `https://${options.domain}/api/v2/`,
2423
...{ clientSecret: (options as ManagementClientOptionsWithClientSecret).clientSecret },
2524
...{

src/management/token-provider.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,32 @@
11
import { AuthenticationClient } from '../auth/index.js';
22
import { TokenSet } from '../auth/oauth.js';
33
import { JSONApiResponse } from '../lib/models.js';
4+
import {
5+
ManagementClientOptionsWithClientAssertion,
6+
ManagementClientOptionsWithClientCredentials,
7+
ManagementClientOptionsWithClientSecret,
8+
} from './management-client-options.js';
49

510
const LEEWAY = 10 * 1000;
611

7-
interface BaseOptions {
8-
domain: string;
9-
audience: string;
10-
clientId: string;
11-
enableCache?: boolean;
12-
}
13-
1412
export class TokenProvider {
1513
private authenticationClient: AuthenticationClient;
1614
private expiresAt = 0;
1715
private accessToken = '';
1816
private pending: Promise<JSONApiResponse<TokenSet>> | undefined;
1917

20-
constructor(options: BaseOptions & { clientSecret: string });
21-
constructor(options: BaseOptions & { clientAssertionSigningKey: string });
22-
constructor(private options: any) {
23-
this.authenticationClient = new AuthenticationClient({
24-
clientId: options.clientId,
25-
domain: options.domain,
26-
clientSecret: options.clientSecret,
27-
clientAssertionSigningKey: options.clientAssertionSigningKey,
28-
});
18+
constructor(options: ManagementClientOptionsWithClientSecret & { audience: string });
19+
constructor(options: ManagementClientOptionsWithClientAssertion & { audience: string });
20+
constructor(
21+
private options: ManagementClientOptionsWithClientCredentials & { audience: string }
22+
) {
23+
this.authenticationClient = new AuthenticationClient(options);
2924
}
3025

3126
public async getAccessToken() {
32-
const disableCache = this.options.enableCache === false;
33-
if (disableCache || !this.accessToken || Date.now() > this.expiresAt - LEEWAY) {
27+
if (!this.accessToken || Date.now() > this.expiresAt - LEEWAY) {
3428
this.pending =
35-
(!disableCache && this.pending) ||
29+
this.pending ||
3630
this.authenticationClient.oauth.clientCredentialsGrant({
3731
audience: this.options.audience,
3832
});

test/management/token-provider-middleware.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import nock from 'nock';
22
import { jest } from '@jest/globals';
3-
import { RequestOpts, InitOverrideFunction } from '../../src/lib/index.js';
3+
import { RequestOpts, InitOverrideFunction, FetchAPI } from '../../src/lib/index.js';
44
import { BaseAPI } from '../../src/lib/runtime.js';
55
import { TokenProviderMiddleware } from '../../src/management/token-provider-middleware.js';
66

77
const domain = 'test-domain.auth0.com';
88

9+
const customFetch = jest
10+
.fn<FetchAPI>()
11+
.mockImplementation((url: URL | RequestInfo, init?: RequestInit) => fetch(url, init));
12+
913
const opts = {
1014
baseUrl: `https://${domain}`,
1115
clientId: 'test-client-id',
@@ -14,6 +18,7 @@ const opts = {
1418
parseError: async (response: Response) => {
1519
return new Error(`${response.status}`);
1620
},
21+
fetch: customFetch,
1722
};
1823

1924
export class TestClient extends BaseAPI {
@@ -87,4 +92,11 @@ describe('TokenProviderMiddleware', () => {
8792
})
8893
);
8994
});
95+
96+
it('should use custom fetch', async () => {
97+
await expect(
98+
clientSecretClient.testRequest({ path: '/foo', method: 'GET' })
99+
).resolves.toMatchObject({});
100+
expect(customFetch).toHaveBeenCalled();
101+
});
90102
});

test/management/token-provider.test.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import nock from 'nock';
22
import { jest } from '@jest/globals';
33
import { TokenProvider } from '../../src/management/token-provider.js';
4+
import { FetchAPI } from '../../src/lib/models.js';
45

56
const opts = {
67
domain: 'test-domain.auth0.com',
@@ -47,13 +48,6 @@ describe('TokenProvider', () => {
4748
expect(spy).toHaveBeenCalledTimes(1);
4849
});
4950

50-
it('should get a new access token if caching disabled', async () => {
51-
const tp = new TokenProvider({ ...opts, enableCache: false });
52-
expect(await tp.getAccessToken()).toBe('my-access-token');
53-
expect(await tp.getAccessToken()).toBe('my-access-token');
54-
expect(spy).toHaveBeenCalledTimes(2);
55-
});
56-
5751
it('should get a new access token if token expires', async () => {
5852
jest.useFakeTimers({ doNotFake: ['nextTick'] });
5953
const tp = new TokenProvider(opts);
@@ -93,12 +87,16 @@ describe('TokenProvider', () => {
9387
expect(spy).toHaveBeenCalledTimes(1);
9488
});
9589

96-
it('should not cache concurrent requests when caching disabled', async () => {
97-
const tp = new TokenProvider({ ...opts, enableCache: false });
98-
expect(
99-
await Promise.all([tp.getAccessToken(), tp.getAccessToken(), tp.getAccessToken()])
100-
).toEqual(['my-access-token', 'my-access-token', 'my-access-token']);
90+
it('should use a custom fetch', async () => {
91+
const customFetch = jest
92+
.fn<FetchAPI>()
93+
.mockImplementation((url: URL | RequestInfo, init?: RequestInit) => fetch(url, init));
10194

102-
expect(spy).toHaveBeenCalledTimes(3);
95+
const tp = new TokenProvider({
96+
...opts,
97+
fetch: customFetch as any,
98+
});
99+
expect(await tp.getAccessToken()).toBe('my-access-token');
100+
expect(customFetch).toHaveBeenCalled();
103101
});
104102
});

v4_MIGRATION_GUIDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Some method names have been changed to better align with the documentation.
129129
The following configuration options have changed:
130130

131131
- `scope` - The Management Client uses the Client Credentials grant which gets all the scopes granted to the application. So this is redundant and has been removed.
132-
- `tokenProvider.enableCache` - Use the `enableCache` option of the Management Client.
132+
- `tokenProvider.enableCache` - Each instance of the Management Client has its own cache, if you want a new cache you want to instantiate a new Management Client.
133133
- `tokenProvider.cacheTTLInSeconds` - Each instance of the Management Client only stores a single access token, so this functionality has been removed.
134134
- `proxy` - You should now provide an [HttpsAgent](https://nodejs.org/api/https.html#class-httpsagent) as the `agent` config.
135135
- `includeResponseHeaders` - This has been removed, all return types include the response headers by default.

0 commit comments

Comments
 (0)