diff --git a/package-lock.json b/package-lock.json index 61644eb4a..2d6d30bd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1474,11 +1474,11 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/auth0": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/auth0/-/auth0-3.7.0.tgz", - "integrity": "sha512-Ai1T+ltEvcoZdIKbZ5TnLHMkioKxU/j01ZsDWKx55/toqFJXOWypw37kQNdqvHgteFGE142k4MjSt5u1wlOi3A==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/auth0/-/auth0-3.7.2.tgz", + "integrity": "sha512-8XwCi5e0CC08A4+l3eTmx/arXjGUlXrLd6/LUBvQfedmI8w4jiNc9pd7dyBUgR00EzhcbcrdNEQo5jkU3hMIJg==", "dependencies": { - "axios": "^0.27.2", + "axios": "^1.6.2", "form-data": "^3.0.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.0.1", @@ -1527,12 +1527,13 @@ } }, "node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/axios/node_modules/form-data": { @@ -2886,9 +2887,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "funding": [ { "type": "individual", @@ -5512,6 +5513,11 @@ "node": ">= 8" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -8132,11 +8138,11 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "auth0": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/auth0/-/auth0-3.7.0.tgz", - "integrity": "sha512-Ai1T+ltEvcoZdIKbZ5TnLHMkioKxU/j01ZsDWKx55/toqFJXOWypw37kQNdqvHgteFGE142k4MjSt5u1wlOi3A==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/auth0/-/auth0-3.7.2.tgz", + "integrity": "sha512-8XwCi5e0CC08A4+l3eTmx/arXjGUlXrLd6/LUBvQfedmI8w4jiNc9pd7dyBUgR00EzhcbcrdNEQo5jkU3hMIJg==", "requires": { - "axios": "^0.27.2", + "axios": "^1.6.2", "form-data": "^3.0.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.0.1", @@ -8171,12 +8177,13 @@ "dev": true }, "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" }, "dependencies": { "form-data": { @@ -9246,9 +9253,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" }, "for-each": { "version": "0.3.3", @@ -11168,6 +11175,11 @@ "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", "dev": true }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", diff --git a/src/context/yaml/handlers/clientGrants.ts b/src/context/yaml/handlers/clientGrants.ts index aa5422908..d864f66ad 100644 --- a/src/context/yaml/handlers/clientGrants.ts +++ b/src/context/yaml/handlers/clientGrants.ts @@ -17,10 +17,17 @@ async function parse(context: YAMLContext): Promise { } async function dump(context: YAMLContext): Promise { - const { clientGrants, clients } = context.assets; + let { clientGrants, clients } = context.assets; if (!clientGrants) return { clientGrants: null }; + if (clients === undefined) { + clients = await context.mgmtClient.clients.getAll({ + paginate: true, + include_totals: true, + }); + } + // Convert client_id to the client name for readability return { clientGrants: clientGrants.map((grant) => { diff --git a/src/context/yaml/index.ts b/src/context/yaml/index.ts index 17c5e7bd2..715c4ccc6 100644 --- a/src/context/yaml/index.ts +++ b/src/context/yaml/index.ts @@ -7,6 +7,7 @@ import { wrapArrayReplaceMarkersInQuotes, Auth0, } from '../../tools'; +import pagedClient from '../../tools/auth0/client'; import log from '../../logger'; import { isFile, toConfigFn, stripIdentifiers, formatResults, recordsSorter } from '../../utils'; @@ -29,7 +30,7 @@ export default class YAMLContext { this.configFile = config.AUTH0_INPUT_FILE; this.config = config; this.mappings = config.AUTH0_KEYWORD_REPLACE_MAPPINGS || {}; - this.mgmtClient = mgmtClient + this.mgmtClient = pagedClient(mgmtClient); this.disableKeywordReplacement = false; //@ts-ignore because the assets property gets filled out throughout diff --git a/test/context/yaml/clientGrants.test.js b/test/context/yaml/clientGrants.test.js index e513d9a3e..43d9fb4eb 100644 --- a/test/context/yaml/clientGrants.test.js +++ b/test/context/yaml/clientGrants.test.js @@ -40,11 +40,58 @@ describe('#YAML context client grants', () => { it('should dump client grants', async () => { const context = new Context({ AUTH0_INPUT_FILE: './test.yml' }, mockMgmtClient()); const clientGrants = [ - { audience: 'https://test.myapp.com/api/v1', client_id: 'My M2M', scope: ['update:account'] }, + { + audience: 'https://test.myapp.com/api/v1', + client_id: 'client-id', + scope: ['update:account'], + }, ]; context.assets.clientGrants = clientGrants; const dumped = await handler.dump(context); expect(dumped).to.deep.equal({ clientGrants }); }); + + it('should dump client grants and replace client ID with client name if clients in assets', async () => { + const context = new Context({ AUTH0_INPUT_FILE: './test.yml' }, mockMgmtClient()); + const clientGrants = [ + { + audience: 'https://test.myapp.com/api/v1', + client_id: 'client-id-1', + scope: ['update:account'], + }, + ]; + context.assets.clientGrants = clientGrants; + context.assets.clients = [{ client_id: 'client-id-1', name: 'Client 1' }]; + + const dumped = await handler.dump(context); + const expected = (() => { + const ret = clientGrants; + ret[0].client_id = 'Client 1'; + return { clientGrants: ret }; + })(); + expect(dumped).to.deep.equal(expected); + }); + + it('should dump client grants and replace client ID with client name even if clients not in assets', async () => { + const mockMgmt = mockMgmtClient(); + mockMgmt.clients.getAll = () => [[{ client_id: 'client-id-1', name: 'Client 1' }]]; + const context = new Context({ AUTH0_INPUT_FILE: './test.yml' }, mockMgmt); + const clientGrants = [ + { + audience: 'https://test.myapp.com/api/v1', + client_id: 'client-id-1', + scope: ['update:account'], + }, + ]; + context.assets.clientGrants = clientGrants; + + const dumped = await handler.dump(context); + const expected = (() => { + const ret = clientGrants; + ret[0].client_id = 'Client 1'; + return { clientGrants: ret }; + })(); + expect(dumped).to.deep.equal(expected); + }); });