diff --git a/EXAMPLES.md b/EXAMPLES.md index 63b9b2e37..ad61d9470 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -136,17 +136,20 @@ Refer mTLS documentation for more info - [Link](https://auth0.com/docs/get-start ```js import { AuthenticationClient } from 'auth0'; +const { Agent } = require('undici'); const auth = new AuthenticationClient({ - domain: 'mtls.{YOUR_TENANT_AND REGION}.auth0.com', + domain: '{YOUR_TENANT_AND REGION}.auth0.com', clientId: '{YOUR_CLIENT_ID}', - agent: new https.Agent({ ... }), + agent: new Agent({ + connect: { cert: 'your_cert', key: 'your_key' }, + }), + useMTLS: true, }); const { data: tokens } = await auth.oauth.clientCredentialsGrant({ audience: 'you-api', }); - ``` ## Management Client diff --git a/src/auth/base-auth-api.ts b/src/auth/base-auth-api.ts index 3f7c6f6e6..eca70332d 100644 --- a/src/auth/base-auth-api.ts +++ b/src/auth/base-auth-api.ts @@ -22,6 +22,7 @@ export interface AuthenticationClientOptions extends ClientOptions { clientAssertionSigningAlg?: string; idTokenSigningAlg?: string; // default 'RS256' clockTolerance?: number; // default 60s, + useMTLS?: boolean; } interface AuthApiErrorResponse { @@ -92,7 +93,7 @@ export class BaseAuthAPI extends BaseAPI { clientSecret?: string; clientAssertionSigningKey?: string; clientAssertionSigningAlg?: string; - agent?: unknown; + useMTLS?: boolean; constructor(options: AuthenticationClientOptions) { super({ @@ -108,7 +109,7 @@ export class BaseAuthAPI extends BaseAPI { this.clientSecret = options.clientSecret; this.clientAssertionSigningKey = options.clientAssertionSigningKey; this.clientAssertionSigningAlg = options.clientAssertionSigningAlg; - this.agent = options.agent; + this.useMTLS = options.useMTLS; } /** @@ -124,7 +125,7 @@ export class BaseAuthAPI extends BaseAPI { clientSecret: this.clientSecret, clientAssertionSigningKey: this.clientAssertionSigningKey, clientAssertionSigningAlg: this.clientAssertionSigningAlg, - agent: this.agent, + useMTLS: this.useMTLS, }); } } diff --git a/src/auth/client-authentication.ts b/src/auth/client-authentication.ts index d15d99d96..9d28f3439 100644 --- a/src/auth/client-authentication.ts +++ b/src/auth/client-authentication.ts @@ -17,7 +17,7 @@ interface AddClientAuthenticationOptions { clientAssertionSigningKey?: string; clientAssertionSigningAlg?: string; clientSecret?: string; - agent?: unknown; + useMTLS?: boolean; } /** @@ -35,7 +35,7 @@ export const addClientAuthentication = async ({ clientAssertionSigningKey, clientAssertionSigningAlg, clientSecret, - agent, + useMTLS, }: AddClientAuthenticationOptions): Promise> => { const cid = payload.client_id || clientId; if (clientAssertionSigningKey && !payload.client_assertion) { @@ -58,7 +58,7 @@ export const addClientAuthentication = async ({ if ( (!payload.client_secret || payload.client_secret.trim().length === 0) && (!payload.client_assertion || payload.client_assertion.trim().length === 0) && - !isMTLSRequest(agent) + !useMTLS ) { throw new Error( 'The client_secret or client_assertion field is required, or it should be mTLS request.' @@ -66,10 +66,3 @@ export const addClientAuthentication = async ({ } return payload; }; - -/** - * Checks if the request has agent property provided - */ -const isMTLSRequest = (agent: unknown): boolean => { - return typeof agent === 'undefined' ? false : true; -}; diff --git a/src/auth/oauth.ts b/src/auth/oauth.ts index e6e1eb7b0..caaa583bf 100644 --- a/src/auth/oauth.ts +++ b/src/auth/oauth.ts @@ -6,6 +6,7 @@ import { } from '../lib/runtime.js'; import { BaseAuthAPI, AuthenticationClientOptions, grant } from './base-auth-api.js'; import { IDTokenValidateOptions, IDTokenValidator } from './id-token-validator.js'; +import { mtlsPrefix } from '../utils.js'; export interface TokenSet { /** @@ -271,7 +272,10 @@ export interface TokenExchangeGrantRequest { export class OAuth extends BaseAuthAPI { private idTokenValidator: IDTokenValidator; constructor(options: AuthenticationClientOptions) { - super(options); + super({ + ...options, + domain: options.useMTLS ? `${mtlsPrefix}.` + options.domain : options.domain, + }); this.idTokenValidator = new IDTokenValidator(options); } diff --git a/src/lib/runtime.ts b/src/lib/runtime.ts index bfcf5ccbe..fd519d81e 100644 --- a/src/lib/runtime.ts +++ b/src/lib/runtime.ts @@ -73,7 +73,7 @@ export class BaseAPI { method: context.method, headers, body: context.body, - agent: this.configuration.agent, + dispatcher: this.configuration.agent, }; const overriddenInit: RequestInit = { diff --git a/src/management/management-client-options.ts b/src/management/management-client-options.ts index 933062afb..2ef993a00 100644 --- a/src/management/management-client-options.ts +++ b/src/management/management-client-options.ts @@ -12,12 +12,14 @@ export interface ManagementClientOptionsWithToken extends ManagementClientOption export interface ManagementClientOptionsWithClientSecret extends ManagementClientOptions { clientId: string; clientSecret: string; + useMTLS?: boolean; } export interface ManagementClientOptionsWithClientAssertion extends ManagementClientOptions { clientId: string; clientAssertionSigningKey: string; clientAssertionSigningAlg?: string; + useMTLS?: boolean; } export type ManagementClientOptionsWithClientCredentials = diff --git a/src/utils.ts b/src/utils.ts index 906f20ead..6e668746c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,3 +10,8 @@ export const generateClientInfo = () => ({ node: process.version.replace('v', ''), }, }); + +/** + * @private + */ +export const mtlsPrefix = 'mtls'; diff --git a/test/auth/client-authentication.test.ts b/test/auth/client-authentication.test.ts index 15538f747..807bf06b5 100644 --- a/test/auth/client-authentication.test.ts +++ b/test/auth/client-authentication.test.ts @@ -239,11 +239,12 @@ describe('mTLS-authentication', () => { it('should do client credentials grant without client secret or assertion & only with agent', async () => { const auth0 = new AuthenticationClient({ - domain: 'mtls.tenant.auth0.com', + domain: 'tenant.auth0.com', clientId, agent: { options: { key: 'my-key', cert: 'my-cert' }, }, + useMTLS: true, }); await auth0.oauth.clientCredentialsGrant({ audience: 'my-api',