diff --git a/src/auth/base-auth-api.ts b/src/auth/base-auth-api.ts index 027245dbf..3f7c6f6e6 100644 --- a/src/auth/base-auth-api.ts +++ b/src/auth/base-auth-api.ts @@ -92,6 +92,7 @@ export class BaseAuthAPI extends BaseAPI { clientSecret?: string; clientAssertionSigningKey?: string; clientAssertionSigningAlg?: string; + agent?: unknown; constructor(options: AuthenticationClientOptions) { super({ @@ -107,6 +108,7 @@ export class BaseAuthAPI extends BaseAPI { this.clientSecret = options.clientSecret; this.clientAssertionSigningKey = options.clientAssertionSigningKey; this.clientAssertionSigningAlg = options.clientAssertionSigningAlg; + this.agent = options.agent; } /** @@ -122,6 +124,7 @@ export class BaseAuthAPI extends BaseAPI { clientSecret: this.clientSecret, clientAssertionSigningKey: this.clientAssertionSigningKey, clientAssertionSigningAlg: this.clientAssertionSigningAlg, + agent: this.agent, }); } } diff --git a/src/auth/client-authentication.ts b/src/auth/client-authentication.ts index 8af14bcac..d15d99d96 100644 --- a/src/auth/client-authentication.ts +++ b/src/auth/client-authentication.ts @@ -17,6 +17,7 @@ interface AddClientAuthenticationOptions { clientAssertionSigningKey?: string; clientAssertionSigningAlg?: string; clientSecret?: string; + agent?: unknown; } /** @@ -26,7 +27,6 @@ interface AddClientAuthenticationOptions { * Adds `client_assertion` and `client_assertion_type` for Private Key JWT token endpoint auth method. * * If `clientAssertionSigningKey` is provided it takes precedent over `clientSecret` . - * Also skips `client_secret` & `clientAssertionSigningKey` if request(domain) is of mTLS type */ export const addClientAuthentication = async ({ payload, @@ -35,6 +35,7 @@ export const addClientAuthentication = async ({ clientAssertionSigningKey, clientAssertionSigningAlg, clientSecret, + agent, }: AddClientAuthenticationOptions): Promise> => { const cid = payload.client_id || clientId; if (clientAssertionSigningKey && !payload.client_assertion) { @@ -57,16 +58,18 @@ export const addClientAuthentication = async ({ if ( (!payload.client_secret || payload.client_secret.trim().length === 0) && (!payload.client_assertion || payload.client_assertion.trim().length === 0) && - !isMTLSRequest(domain) + !isMTLSRequest(agent) ) { - throw new Error('The client_secret or client_assertion field is required.'); + throw new Error( + 'The client_secret or client_assertion field is required, or it should be mTLS request.' + ); } return payload; }; /** - * Checks if domain name starts with mTLS keyword for mTLS requests + * Checks if the request has agent property provided */ -const isMTLSRequest = (domain: string): boolean => { - return domain.toLowerCase().startsWith('mtls'); +const isMTLSRequest = (agent: unknown): boolean => { + return typeof agent === 'undefined' ? false : true; }; diff --git a/test/auth/client-authentication.test.ts b/test/auth/client-authentication.test.ts index cadb359a5..15538f747 100644 --- a/test/auth/client-authentication.test.ts +++ b/test/auth/client-authentication.test.ts @@ -111,7 +111,9 @@ describe('client-authentication', () => { auth0.oauth.clientCredentialsGrant({ audience: 'my-api', }) - ).rejects.toThrow('The client_secret or client_assertion field is required.'); + ).rejects.toThrow( + 'The client_secret or client_assertion field is required, or it should be mTLS request.' + ); }); it('should allow you to pass your own client assertion', async () => { @@ -235,10 +237,13 @@ describe('mTLS-authentication', () => { jest.clearAllMocks(); }); - it('should do client credentials grant without client secret or assertion', async () => { + it('should do client credentials grant without client secret or assertion & only with agent', async () => { const auth0 = new AuthenticationClient({ domain: 'mtls.tenant.auth0.com', clientId, + agent: { + options: { key: 'my-key', cert: 'my-cert' }, + }, }); await auth0.oauth.clientCredentialsGrant({ audience: 'my-api', diff --git a/test/auth/oauth.test.ts b/test/auth/oauth.test.ts index 0e0cbaa7e..24ca8d13d 100644 --- a/test/auth/oauth.test.ts +++ b/test/auth/oauth.test.ts @@ -310,7 +310,9 @@ describe('OAuth', () => { response_type: 'code', redirect_uri: 'https://example.com', } as PushedAuthorizationRequest) - ).rejects.toThrow('The client_secret or client_assertion field is required.'); + ).rejects.toThrow( + 'The client_secret or client_assertion field is required, or it should be mTLS request.' + ); }); it('should return the par response', async () => {