diff --git a/docs/configuring-the-deploy-cli.md b/docs/configuring-the-deploy-cli.md index 015a7a30..822da1ae 100644 --- a/docs/configuring-the-deploy-cli.md +++ b/docs/configuring-the-deploy-cli.md @@ -114,6 +114,10 @@ Array of strings. Dictates which resource types to _only_ manage, bi-directional Cannot be used simultaneously with `AUTH0_EXCLUDED`. +### `AUTH0_INCLUDE_THIRD_PARTY_CLIENTS` + +Boolean. Third-party clients are excluded from export and import operations by default. Enable this option to include them. This is useful when you have Dynamic Client Registration (DCR) enabled and need to directly manage third-party clients. Default: `false`. + ### `AUTH0_KEYWORD_REPLACE_MAPPINGS` Mapping of specific keywords to facilities dynamic replacement. See also: [keyword replacement](keyword-replacement.md). @@ -155,10 +159,6 @@ Provides ability to exclude any unwanted properties from management. String. Separate value from audience value while retrieving an access token for management API. Useful when default Management API endpoints are not publicly exposed. -### `AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS` - -Boolean. When enabled, excludes third-party clients from being managed. Only first-party clients will be included in export and import operations. This is useful when you have Dynamic Client Registration (DCR) enabled and you have a lot of third-party clients in your tenant. Default: `false`. - ### `AUTH0_EXCLUDED_RULES` Array of strings. Excludes the management of specific rules by ID. **Note:** This configuration may be subject to deprecation in the future. See: [excluding resources from management](excluding-from-management.md). diff --git a/docs/excluding-from-management.md b/docs/excluding-from-management.md index d0614ae0..b6f70faa 100644 --- a/docs/excluding-from-management.md +++ b/docs/excluding-from-management.md @@ -55,18 +55,6 @@ Some resource types support exclusions of individual resource by name. This is p > ⚠️ **NOTE:** Excluding resources by ID is being considered for deprecation in future major versions. See the [resource exclusion proposal](https://github.com/auth0/auth0-deploy-cli/issues/451) for more details. -### Excluding third-party clients - -You can also exclude all third-party clients at once using the `AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS` configuration option. When enabled, only first-party clients will be included in export and import operations. This is useful when you have Dynamic Client Registration (DCR) enabled and you have a lot of third-party clients in your tenant. - -```json -{ - "AUTH0_DOMAIN": "example-site.us.auth0.com", - "AUTH0_CLIENT_ID": "", - "AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS": true -} -``` - ## Omitted vs excluded vs empty The above sections pertain to exclusion which forcefully ignore configurations bi-directionally. It is worth noting similar but very different concepts: “omissions” and “empty” states. diff --git a/src/tools/auth0/handlers/clients.ts b/src/tools/auth0/handlers/clients.ts index d1e6c9b8..41b221ea 100644 --- a/src/tools/auth0/handlers/clients.ts +++ b/src/tools/auth0/handlers/clients.ts @@ -323,9 +323,9 @@ export default class ClientHandler extends DefaultAPIHandler { const excludedClients = (assets.exclude && assets.exclude.clients) || []; - const excludeThirdPartyClients = - this.config('AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS') === 'true' || - this.config('AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS') === true; + const includeThirdPartyClients = + this.config('AUTH0_INCLUDE_THIRD_PARTY_CLIENTS') === 'true' || + this.config('AUTH0_INCLUDE_THIRD_PARTY_CLIENTS') === true; const { del, update, create, conflicts } = await this.calcChanges(assets); @@ -337,14 +337,14 @@ export default class ClientHandler extends DefaultAPIHandler { * Filter out: * - The client used to access Auth0 Management API * - Clients in the exclusion list - * - Third-party clients when AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS is enabled + * - Third-party clients when AUTH0_INCLUDE_THIRD_PARTY_CLIENTS is not enabled */ const filterClients = (list: Client[]): Client[] => list.filter( (item) => item.client_id !== currentClient && !excludedClients.includes(item.name) && - (!excludeThirdPartyClients || item.is_first_party) + (includeThirdPartyClients || item.is_first_party || item.is_first_party == null) ); // Sanitize client fields @@ -420,15 +420,15 @@ export default class ClientHandler extends DefaultAPIHandler { async getType() { if (this.existing) return this.existing; - const excludeThirdPartyClients = - this.config('AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS') === 'true' || - this.config('AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS') === true; + const includeThirdPartyClients = + this.config('AUTH0_INCLUDE_THIRD_PARTY_CLIENTS') === 'true' || + this.config('AUTH0_INCLUDE_THIRD_PARTY_CLIENTS') === true; const clients = await paginate(this.client.clients.getAll, { paginate: true, include_totals: true, is_global: false, - ...(excludeThirdPartyClients && { is_first_party: true }), + ...(!includeThirdPartyClients && { is_first_party: true }), }); const sanitizedClients = this.sanitizeCrossOriginAuth(clients); diff --git a/src/types.ts b/src/types.ts index e1081a35..d1f643f3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -64,8 +64,8 @@ export type Config = { AUTH0_INPUT_FILE: string; AUTH0_ALLOW_DELETE: boolean; AUTH0_EXCLUDED?: AssetTypes[]; - AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS?: boolean; AUTH0_INCLUDED_ONLY?: AssetTypes[]; + AUTH0_INCLUDE_THIRD_PARTY_CLIENTS?: boolean; AUTH0_PRESERVE_KEYWORDS: boolean; EXTENSION_SECRET: string; AUTH0_ACCESS_TOKEN?: string; diff --git a/test/tools/auth0/handlers/clients.tests.js b/test/tools/auth0/handlers/clients.tests.js index e9671d80..b26cfdff 100644 --- a/test/tools/auth0/handlers/clients.tests.js +++ b/test/tools/auth0/handlers/clients.tests.js @@ -375,7 +375,7 @@ describe('#clients handler', () => { expect(wasCreateCalled).to.be.equal(true); }); - it('should ignore third-party clients if AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS is true', async () => { + it('should ignore third-party clients by default', async () => { let wasCreateCalled = false; const thirdPartyClient = { name: 'Third-Party Client', @@ -403,25 +403,13 @@ describe('#clients handler', () => { pool, }; - const testConfig = function (key) { - return testConfig.data && testConfig.data[key]; - }; - testConfig.data = { - AUTH0_CLIENT_ID: 'client_id', - AUTH0_ALLOW_DELETE: true, - AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS: true, - }; - - const handler = new clients.default({ - client: pageClient(auth0), - config: testConfig, - }); + const handler = new clients.default({ client: pageClient(auth0), config }); const stageFn = Object.getPrototypeOf(handler).processChanges; await stageFn.apply(handler, [{ clients: [thirdPartyClient] }]); expect(wasCreateCalled).to.be.equal(false); }); - it('should include third-party clients if AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS is false', async () => { + it('should include third-party clients if AUTH0_INCLUDE_THIRD_PARTY_CLIENTS is true', async () => { let wasCreateCalled = false; const thirdPartyClient = { name: 'Third-Party Client', @@ -448,7 +436,7 @@ describe('#clients handler', () => { testConfig.data = { AUTH0_CLIENT_ID: 'client_id', AUTH0_ALLOW_DELETE: true, - AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS: false, + AUTH0_INCLUDE_THIRD_PARTY_CLIENTS: true, }; const handler = new clients.default({ @@ -460,7 +448,32 @@ describe('#clients handler', () => { expect(wasCreateCalled).to.be.equal(true); }); - it('should get clients with is_first_party when AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS is enabled', async () => { + it('should get clients with is_first_party by default', async () => { + const getAllParams = []; + const auth0 = { + clients: { + getAll: (params) => { + getAllParams.push(params); + return mockPagedData(params, 'clients', [ + { name: 'first party client', client_id: 'first-party-client-id' }, + ]); + }, + }, + pool, + }; + + const handler = new clients.default({ client: pageClient(auth0), config }); + await handler.getType(); + + expect(getAllParams.length).to.be.greaterThan(0); + const firstCallParams = getAllParams[0]; + expect(firstCallParams).to.be.an('object'); + expect(firstCallParams.is_first_party).to.equal(true); + expect(firstCallParams.include_totals).to.equal(true); + expect(firstCallParams.is_global).to.equal(false); + }); + + it('should omit the is_first_party client parameter if AUTH0_INCLUDE_THIRD_PART_CLIENTS is true', async () => { const getAllParams = []; const auth0 = { clients: { @@ -480,7 +493,7 @@ describe('#clients handler', () => { testConfig.data = { AUTH0_CLIENT_ID: 'client_id', AUTH0_ALLOW_DELETE: true, - AUTH0_EXCLUDE_THIRD_PARTY_CLIENTS: true, + AUTH0_INCLUDE_THIRD_PARTY_CLIENTS: true, }; const handler = new clients.default({ client: pageClient(auth0), config: testConfig }); @@ -489,7 +502,7 @@ describe('#clients handler', () => { expect(getAllParams.length).to.be.greaterThan(0); const firstCallParams = getAllParams[0]; expect(firstCallParams).to.be.an('object'); - expect(firstCallParams.is_first_party).to.equal(true); + expect(firstCallParams.is_first_party).to.equal(undefined); expect(firstCallParams.include_totals).to.equal(true); expect(firstCallParams.is_global).to.equal(false); });