From 63e51b8ed68df9c45c2dd7a8424549fd7ef99c32 Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Fri, 7 Oct 2022 15:38:48 +0100 Subject: [PATCH 1/3] Add option to include response headers in the result --- src/Auth0RestClient.js | 34 ++++++++++++++++++++-- src/management/BaseManager.js | 1 + src/management/index.js | 2 ++ test/auth0-rest-client.tests.js | 32 ++++++++++++++++++++ test/management/management-client.tests.js | 28 ++++++++++++++++++ 5 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/Auth0RestClient.js b/src/Auth0RestClient.js index 79aacded3..92080714b 100644 --- a/src/Auth0RestClient.js +++ b/src/Auth0RestClient.js @@ -27,7 +27,7 @@ class Auth0RestClient { this.wrappedProvider = function (method, args) { if (!this.provider) { - return this.restClient[method](...args); + return this._request(method, args); } let callback; @@ -39,7 +39,7 @@ class Auth0RestClient { .getAccessToken() .then((access_token) => { this.restClient.options.headers['Authorization'] = `Bearer ${access_token}`; - return this.restClient[method](...args); + return this._request(method, args); }) .catch((err) => { if (callback) { @@ -50,6 +50,36 @@ class Auth0RestClient { }; } + _request(method, args) { + if (!this.options.includeResponseHeaders) { + return this.restClient[method](...args); + } + + let callback; + // Handle the case where the promise variant is called without any args + // client.get() -> client.get({}, callback) + if (!args || !args.length) { + args = [{}]; + } + // Handle the case where an undefined placeholder is defined for callback + // client.get(params, undefined) -> client.get(params, callback) + if (typeof args[args.length - 1] === 'undefined') { + args.pop(); + } + if (typeof args[args.length - 1] === 'function') { + callback = args.pop(); + } + return new Promise((resolve, reject) => { + this.restClient[method](...args, (err, data, headers) => { + const payload = { data, headers }; + if (err) { + (callback && callback(err)) || reject(err); + } + (callback && callback(null, payload)) || resolve(payload); + }); + }); + } + getAll(...args) { return this.wrappedProvider('getAll', args); } diff --git a/src/management/BaseManager.js b/src/management/BaseManager.js index 93ec257f9..94bb9dd93 100644 --- a/src/management/BaseManager.js +++ b/src/management/BaseManager.js @@ -25,6 +25,7 @@ class BaseManager { errorFormatter: { message: 'message', name: 'error' }, headers: options.headers, query: { repeatParams: false }, + includeResponseHeaders: options.includeResponseHeaders, }; const usersAuth0RestClient = new Auth0RestClient( diff --git a/src/management/index.js b/src/management/index.js index 99b1365b9..cfde5b3eb 100644 --- a/src/management/index.js +++ b/src/management/index.js @@ -90,6 +90,7 @@ class ManagementClient { * @param {boolean} [options.retry.enabled=true] Enabled or Disable Retry Policy functionality. * @param {number} [options.retry.maxRetries=10] Retry failed requests X times. * @param {object} [options.headers] Additional headers that will be added to the outgoing requests. + * @param {object} [options.includeResponseHeaders] Include the response headers in the payload in the format `{ data, headers }` */ constructor(options) { if (!options || typeof options !== 'object') { @@ -147,6 +148,7 @@ class ManagementClient { } managerOptions.retry = options.retry; + managerOptions.includeResponseHeaders = options.includeResponseHeaders; /** * Simple abstraction for performing CRUD operations on the diff --git a/test/auth0-rest-client.tests.js b/test/auth0-rest-client.tests.js index a44df6e7c..82d6df444 100644 --- a/test/auth0-rest-client.tests.js +++ b/test/auth0-rest-client.tests.js @@ -228,4 +228,36 @@ describe('Auth0RestClient', () => { done(); }); }); + + it('should include response headers in promise response', async function () { + nock(API_URL).get('/some-resource').reply(200, { data: 'value' }, { foo: 'bar' }); + + const options = { + includeResponseHeaders: true, + headers: {}, + }; + + const client = new Auth0RestClient(`${API_URL}/some-resource`, options, this.providerMock); + const { data, headers } = await client.getAll(); + expect(data).to.deep.equal({ data: 'value' }); + expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + nock.cleanAll(); + }); + + it('should include response headers in callback response', function (done) { + nock(API_URL).get('/some-resource').reply(200, { data: 'value' }, { foo: 'bar' }); + + const options = { + includeResponseHeaders: true, + headers: {}, + }; + + const client = new Auth0RestClient(`${API_URL}/some-resource`, options, this.providerMock); + client.getAll((err, { data, headers }) => { + expect(data).to.deep.equal({ data: 'value' }); + expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + nock.cleanAll(); + done(); + }); + }); }); diff --git a/test/management/management-client.tests.js b/test/management/management-client.tests.js index 78c4d89ae..5e15bf8cb 100644 --- a/test/management/management-client.tests.js +++ b/test/management/management-client.tests.js @@ -940,5 +940,33 @@ describe('ManagementClient', () => { expect(this.client.users.assignRoles.called).ok; this.client.users.assignRoles.reset(); }); + + it('should include response headers in response', async function () { + const config = Object.assign({}, withTokenConfig, { includeResponseHeaders: true }); + this.client = new ManagementClient(config); + + nock('https://auth0-node-sdk.auth0.com') + .get(`/api/v2/users`) + .reply(200, { data: 'value' }, { foo: 'bar' }); + + const { data, headers } = await this.client.users.getAll(); + expect(data).to.deep.equal({ data: 'value' }); + expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + nock.cleanAll(); + }); + + it('should include response headers in response for shorthand method', async function () { + const config = Object.assign({}, withTokenConfig, { includeResponseHeaders: true }); + this.client = new ManagementClient(config); + + nock('https://auth0-node-sdk.auth0.com') + .get(`/api/v2/users`) + .reply(200, { data: 'value' }, { foo: 'bar' }); + + const { data, headers } = await this.client.getUsers(); + expect(data).to.deep.equal({ data: 'value' }); + expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + nock.cleanAll(); + }); }); }); From 8c24c303007ac7fac49e2305db5cbe1be5c3c91c Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Fri, 7 Oct 2022 16:05:43 +0100 Subject: [PATCH 2/3] Fix node 8 tests --- test/auth0-rest-client.tests.js | 8 ++++---- test/management/management-client.tests.js | 12 ++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/test/auth0-rest-client.tests.js b/test/auth0-rest-client.tests.js index 82d6df444..707bd2457 100644 --- a/test/auth0-rest-client.tests.js +++ b/test/auth0-rest-client.tests.js @@ -230,7 +230,7 @@ describe('Auth0RestClient', () => { }); it('should include response headers in promise response', async function () { - nock(API_URL).get('/some-resource').reply(200, { data: 'value' }, { foo: 'bar' }); + nock(API_URL).get('/some-resource').reply(200, { data: 'value' }); const options = { includeResponseHeaders: true, @@ -240,12 +240,12 @@ describe('Auth0RestClient', () => { const client = new Auth0RestClient(`${API_URL}/some-resource`, options, this.providerMock); const { data, headers } = await client.getAll(); expect(data).to.deep.equal({ data: 'value' }); - expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + expect(headers).to.deep.equal({ 'content-type': 'application/json' }); nock.cleanAll(); }); it('should include response headers in callback response', function (done) { - nock(API_URL).get('/some-resource').reply(200, { data: 'value' }, { foo: 'bar' }); + nock(API_URL).get('/some-resource').reply(200, { data: 'value' }); const options = { includeResponseHeaders: true, @@ -255,7 +255,7 @@ describe('Auth0RestClient', () => { const client = new Auth0RestClient(`${API_URL}/some-resource`, options, this.providerMock); client.getAll((err, { data, headers }) => { expect(data).to.deep.equal({ data: 'value' }); - expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + expect(headers).to.deep.equal({ 'content-type': 'application/json' }); nock.cleanAll(); done(); }); diff --git a/test/management/management-client.tests.js b/test/management/management-client.tests.js index 5e15bf8cb..8b38001af 100644 --- a/test/management/management-client.tests.js +++ b/test/management/management-client.tests.js @@ -945,13 +945,11 @@ describe('ManagementClient', () => { const config = Object.assign({}, withTokenConfig, { includeResponseHeaders: true }); this.client = new ManagementClient(config); - nock('https://auth0-node-sdk.auth0.com') - .get(`/api/v2/users`) - .reply(200, { data: 'value' }, { foo: 'bar' }); + nock('https://auth0-node-sdk.auth0.com').get(`/api/v2/users`).reply(200, { data: 'value' }); const { data, headers } = await this.client.users.getAll(); expect(data).to.deep.equal({ data: 'value' }); - expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + expect(headers).to.deep.equal({ 'content-type': 'application/json' }); nock.cleanAll(); }); @@ -959,13 +957,11 @@ describe('ManagementClient', () => { const config = Object.assign({}, withTokenConfig, { includeResponseHeaders: true }); this.client = new ManagementClient(config); - nock('https://auth0-node-sdk.auth0.com') - .get(`/api/v2/users`) - .reply(200, { data: 'value' }, { foo: 'bar' }); + nock('https://auth0-node-sdk.auth0.com').get(`/api/v2/users`).reply(200, { data: 'value' }); const { data, headers } = await this.client.getUsers(); expect(data).to.deep.equal({ data: 'value' }); - expect(headers).to.deep.equal({ foo: 'bar', 'content-type': 'application/json' }); + expect(headers).to.deep.equal({ 'content-type': 'application/json' }); nock.cleanAll(); }); }); From 12fa40c5bcab0312080200b3efb95bd683b74ad9 Mon Sep 17 00:00:00 2001 From: Rita Zerrizuela Date: Sun, 9 Oct 2022 20:18:03 -0300 Subject: [PATCH 3/3] Update src/management/index.js --- src/management/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/management/index.js b/src/management/index.js index cfde5b3eb..36cfd7865 100644 --- a/src/management/index.js +++ b/src/management/index.js @@ -90,7 +90,7 @@ class ManagementClient { * @param {boolean} [options.retry.enabled=true] Enabled or Disable Retry Policy functionality. * @param {number} [options.retry.maxRetries=10] Retry failed requests X times. * @param {object} [options.headers] Additional headers that will be added to the outgoing requests. - * @param {object} [options.includeResponseHeaders] Include the response headers in the payload in the format `{ data, headers }` + * @param {object} [options.includeResponseHeaders] Include the response headers in the payload in the format `{ data, headers }`. */ constructor(options) { if (!options || typeof options !== 'object') {