From 666401390125438ddc83f0b1ace38ac74a08aa50 Mon Sep 17 00:00:00 2001 From: Gyanesh Gouraw <160731216+gyaneshgouraw-okta@users.noreply.github.com> Date: Wed, 24 Apr 2024 17:28:06 +0530 Subject: [PATCH] Added new authorization_details parameter to support RAR requests (#997) Co-authored-by: Frederik Prijck --- src/auth/oauth.ts | 5 +++ test/auth/client-authentication.test.ts | 53 +++++++++++++++++++++++++ test/auth/fixtures/oauth.json | 11 +++++ test/auth/oauth.test.ts | 19 +++++++++ 4 files changed, 88 insertions(+) diff --git a/src/auth/oauth.ts b/src/auth/oauth.ts index 736a0a1ac..459881415 100644 --- a/src/auth/oauth.ts +++ b/src/auth/oauth.ts @@ -146,6 +146,11 @@ export interface PushedAuthorizationRequest extends ClientCredentials { */ code_challenge?: string; + /** + * A JSON stringified array of objects. It can carry fine-grained authorization data in OAuth messages as part of Rich Authorization Requests (RAR) {@link https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow/authorization-code-flow-with-rar | Reference} + */ + authorization_details?: string; + /** * Allow for any custom property to be sent to Auth0 */ diff --git a/test/auth/client-authentication.test.ts b/test/auth/client-authentication.test.ts index 24d6583fd..53000d469 100644 --- a/test/auth/client-authentication.test.ts +++ b/test/auth/client-authentication.test.ts @@ -152,3 +152,56 @@ describe('client-authentication', () => { }); }); }); + +describe('client-authentication for par endpoint', () => { + const path = jest.fn(); + const body = jest.fn(); + const headers = jest.fn(); + const clientAssertion = jest.fn(); + + beforeEach(() => { + async function handler(this: any, pathIn: unknown, bodyIn: string) { + const bodyParsed = Object.fromEntries(new URLSearchParams(bodyIn)); + path(pathIn); + body(bodyParsed); + headers(this.req.headers); + if ((bodyParsed as any).client_assertion) { + clientAssertion(await verify(bodyParsed.client_assertion, TEST_PUBLIC_KEY, verifyOpts)); + } + return { + data: { + request_uri: 'https://www.request.uri', + expires_in: 86400, + }, + }; + } + + nock(URL, { encodedQueryParams: true }).post('/oauth/par').reply(200, handler).persist(); + }); + + afterEach(() => { + nock.cleanAll(); + jest.clearAllMocks(); + }); + + it('should allow you to call with cliendId & clientSecret combination', async () => { + const auth0 = new AuthenticationClient({ + domain: 'tenant.auth0.com', + clientId, + clientSecret: 'foo', + }); + await auth0.oauth.pushedAuthorization({ + client_id: 'test-client-id', + response_type: 'code', + redirect_uri: 'https://example.com', + }); + expect(path).toHaveBeenCalledWith('/oauth/par'); + + expect(body).toHaveBeenCalledWith({ + client_id: 'test-client-id', + client_secret: 'foo', + redirect_uri: 'https://example.com', + response_type: 'code', + }); + }); +}); diff --git a/test/auth/fixtures/oauth.json b/test/auth/fixtures/oauth.json index 0c8e4ac6f..4489dd04f 100644 --- a/test/auth/fixtures/oauth.json +++ b/test/auth/fixtures/oauth.json @@ -167,5 +167,16 @@ "request_uri": "https://www.request.uri", "expires_in": 86400 } + }, + { + "scope": "https://test-domain.auth0.com", + "method": "POST", + "path": "/oauth/par", + "body": "client_id=test-client-id&response_type=code&redirect_uri=https%3A%2F%2Fexample.com&authorization_details=%5B%7B%22type%22%3A%22payment_initiation%22%2C%22actions%22%3A%5B%22write%22%5D%7D%5D&client_secret=test-client-secret", + "status": 200, + "response": { + "request_uri": "https://www.request.uri", + "expires_in": 86400 + } } ] diff --git a/test/auth/oauth.test.ts b/test/auth/oauth.test.ts index ec61fc9f3..052d809d8 100644 --- a/test/auth/oauth.test.ts +++ b/test/auth/oauth.test.ts @@ -328,6 +328,25 @@ describe('OAuth', () => { }, }); }); + + it('should send authorization_details when provided', async () => { + const oauth = new OAuth(opts); + await expect( + oauth.pushedAuthorization({ + client_id: 'test-client-id', + response_type: 'code', + redirect_uri: 'https://example.com', + authorization_details: JSON.stringify([ + { type: 'payment_initiation', actions: ['write'] }, + ]), + }) + ).resolves.toMatchObject({ + data: { + request_uri: 'https://www.request.uri', + expires_in: 86400, + }, + }); + }); }); });