From 4c073f32fa8cf5ef804791f042c90a18ec95ec11 Mon Sep 17 00:00:00 2001 From: kushalshit27 <43465488+kushalshit27@users.noreply.github.com> Date: Mon, 16 Jun 2025 17:48:05 +0530 Subject: [PATCH 1/7] feat: add deprecation warnings for custom domain fields and enhance schema --- src/tools/auth0/handlers/customDomains.ts | 53 +++++++++++++---------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/tools/auth0/handlers/customDomains.ts b/src/tools/auth0/handlers/customDomains.ts index 19954165..8145d4fa 100644 --- a/src/tools/auth0/handlers/customDomains.ts +++ b/src/tools/auth0/handlers/customDomains.ts @@ -1,6 +1,7 @@ import { CustomDomain } from 'auth0'; import DefaultAPIHandler, { order } from './default'; import { Asset, Assets } from '../../../types'; +import log from '../../../logger'; export const schema = { type: 'array', @@ -18,6 +19,17 @@ export const schema = { status: { type: 'string', enum: ['pending_verification', 'ready', 'disabled', 'pending'] }, type: { type: 'string', enum: ['auth0_managed_certs', 'self_managed_certs'] }, verification: { type: 'object' }, + tls_policy: { + type: 'string', + description: 'Custom domain TLS policy. Must be `recommended`, includes TLS 1.2.', + defaultValue: 'recommended', + }, + domain_metadata: { + type: 'object', + description: 'Domain metadata associated with the custom domain.', + defaultValue: undefined, + maxProperties: 10, + }, }, required: ['domain', 'type'], }, @@ -31,10 +43,13 @@ export default class CustomDomainsHadnler extends DefaultAPIHandler { ...config, type: 'customDomains', id: 'custom_domain_id', - identifiers: ['domain'], + identifiers: ['custom_domain_id', 'domain'], stripCreateFields: ['status', 'primary', 'verification'], + stripUpdateFields: ['status', 'primary', 'verification', 'type', 'domain'], functions: { delete: (args) => this.client.customDomains.delete({ id: args.custom_domain_id }), + update: (args, data) => + this.client.customDomains.update({ id: args.custom_domain_id }, data), }, }); } @@ -71,29 +86,21 @@ export default class CustomDomainsHadnler extends DefaultAPIHandler { const { customDomains } = assets; if (!customDomains) return; - const changes = await this.calcChanges(assets).then((changes) => { - const changesWithoutUpdates = { - ...changes, - create: changes.create.map((customDomainToCreate) => { - const newCustomDomain = { ...customDomainToCreate }; - if (customDomainToCreate.custom_client_ip_header === null) { - delete newCustomDomain.custom_client_ip_header; - } - return newCustomDomain; - }), - delete: changes.del.map((deleteToMake) => { - const deleteWithSDKCompatibleID = { - ...deleteToMake, - id: deleteToMake.custom_domain_id, - }; - delete deleteWithSDKCompatibleID['custom_domain_id']; - return deleteWithSDKCompatibleID; - }), - update: [], //Do not perform custom domain updates because not supported by SDK - }; - return changesWithoutUpdates; - }); + // Deprecation warnings for custom domains + if (customDomains.some((customDomain) => customDomain.primary != null)) { + log.warn( + 'The "primary" field is deprecated and may be removed in future versions for "customDomains"' + ); + } + + if (customDomains.some((customDomain) => 'verification_method' in customDomain)) { + log.warn( + 'The "verification_method" field is deprecated and may be removed in future versions for "customDomains"' + ); + } + + const changes = await this.calcChanges(assets); await super.processChanges(assets, changes); } From b2c007beeb8678cad9984151e428d417b1e565b3 Mon Sep 17 00:00:00 2001 From: kushalshit27 <43465488+kushalshit27@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:12:36 +0530 Subject: [PATCH 2/7] feat: remove deprecation warning for verification_method field in custom domains --- src/tools/auth0/handlers/customDomains.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tools/auth0/handlers/customDomains.ts b/src/tools/auth0/handlers/customDomains.ts index 8145d4fa..0e395261 100644 --- a/src/tools/auth0/handlers/customDomains.ts +++ b/src/tools/auth0/handlers/customDomains.ts @@ -45,7 +45,14 @@ export default class CustomDomainsHadnler extends DefaultAPIHandler { id: 'custom_domain_id', identifiers: ['custom_domain_id', 'domain'], stripCreateFields: ['status', 'primary', 'verification'], - stripUpdateFields: ['status', 'primary', 'verification', 'type', 'domain'], + stripUpdateFields: [ + 'status', + 'primary', + 'verification', + 'type', + 'domain', + 'verification_method', + ], functions: { delete: (args) => this.client.customDomains.delete({ id: args.custom_domain_id }), update: (args, data) => @@ -94,12 +101,6 @@ export default class CustomDomainsHadnler extends DefaultAPIHandler { ); } - if (customDomains.some((customDomain) => 'verification_method' in customDomain)) { - log.warn( - 'The "verification_method" field is deprecated and may be removed in future versions for "customDomains"' - ); - } - const changes = await this.calcChanges(assets); await super.processChanges(assets, changes); From 3088a6816ecc90ec40d94bbab8dcb1b7acbf92b3 Mon Sep 17 00:00:00 2001 From: kushalshit27 <43465488+kushalshit27@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:15:04 +0530 Subject: [PATCH 3/7] feat: add deprecation warning for verification_method field in custom domains --- src/tools/auth0/handlers/customDomains.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/auth0/handlers/customDomains.ts b/src/tools/auth0/handlers/customDomains.ts index 0e395261..01dea160 100644 --- a/src/tools/auth0/handlers/customDomains.ts +++ b/src/tools/auth0/handlers/customDomains.ts @@ -101,6 +101,12 @@ export default class CustomDomainsHadnler extends DefaultAPIHandler { ); } + if (customDomains.some((customDomain) => 'verification_method' in customDomain)) { + log.warn( + 'The "verification_method" field is deprecated and may be removed in future versions for "customDomains"' + ); + } + const changes = await this.calcChanges(assets); await super.processChanges(assets, changes); From bd88d81b449727f54708ecbe118ee4b2247951a1 Mon Sep 17 00:00:00 2001 From: kushalshit27 <43465488+kushalshit27@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:19:12 +0530 Subject: [PATCH 4/7] feat: add custom domains configuration with auth0 managed certificates --- examples/directory/custom-domains/custom-domains.json | 9 +++++++++ examples/yaml/tenant.yaml | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 examples/directory/custom-domains/custom-domains.json diff --git a/examples/directory/custom-domains/custom-domains.json b/examples/directory/custom-domains/custom-domains.json new file mode 100644 index 00000000..8289485d --- /dev/null +++ b/examples/directory/custom-domains/custom-domains.json @@ -0,0 +1,9 @@ +[ + { + "domain": "my_domain.com", + "type": "auth0_managed_certs", + "domain_metadata": { + "myKey": "value" + } + } +] \ No newline at end of file diff --git a/examples/yaml/tenant.yaml b/examples/yaml/tenant.yaml index 234a83f6..b180ea68 100644 --- a/examples/yaml/tenant.yaml +++ b/examples/yaml/tenant.yaml @@ -272,3 +272,10 @@ networkACLs: scope: 'authentication' match: geo_country_codes: ['US', 'CA'] + +customDomains: + - domain: my_domain.com + type: auth0_managed_certs + domain_metadata: + myKey: value + From d841edb978c70224a4d0eedee8d7d56d91d0cdb0 Mon Sep 17 00:00:00 2001 From: kushalshit27 <43465488+kushalshit27@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:55:16 +0530 Subject: [PATCH 5/7] Fix comment formatting and add update tests for customDomains handler - Standardize TypeScript ignore comments with proper spacing - Standardize inline comment formatting with consistent spacing - Add comprehensive test coverage for custom domain update functionality --- .../auth0/handlers/customDomains.test.ts | 273 +++++++++++++++++- 1 file changed, 262 insertions(+), 11 deletions(-) diff --git a/test/tools/auth0/handlers/customDomains.test.ts b/test/tools/auth0/handlers/customDomains.test.ts index e6a89ef9..793afdce 100644 --- a/test/tools/auth0/handlers/customDomains.test.ts +++ b/test/tools/auth0/handlers/customDomains.test.ts @@ -37,7 +37,7 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ client: auth0ApiClientMock }); const data = await handler.load(); @@ -65,7 +65,7 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ client: auth0ApiClientMock }); const data = await handler.getType(); @@ -95,7 +95,7 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ client: auth0ApiClientMock }); const data = await handler.load(); @@ -133,7 +133,7 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ config: () => {}, client: auth0ApiClientMock as unknown as Auth0APIClient, @@ -173,7 +173,7 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ config: () => {}, client: auth0ApiClientMock as unknown as Auth0APIClient, @@ -210,7 +210,7 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ config: (key) => { return { AUTH0_ALLOW_DELETE: true }[key]; @@ -219,7 +219,7 @@ describe('#customDomains handler', () => { }); await handler.processChanges({ customDomains: [] }); - expect(didUpdateFunctionGetCalled).to.equal(false); //The update function should not be called + expect(didUpdateFunctionGetCalled).to.equal(false); // The update function should not be called expect(didDeleteFunctionGetCalled).to.equal(true); expect(didCreateFunctionGetCalled).to.equal(false); }); @@ -249,7 +249,7 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ config: (key) => { return { AUTH0_ALLOW_DELETE: false }[key]; @@ -258,7 +258,7 @@ describe('#customDomains handler', () => { }); await handler.processChanges({ customDomains: [] }); - expect(didUpdateFunctionGetCalled).to.equal(false); //The update function should not be called + expect(didUpdateFunctionGetCalled).to.equal(false); // The update function should not be called expect(didDeleteFunctionGetCalled).to.equal(false); expect(didCreateFunctionGetCalled).to.equal(false); }); @@ -288,15 +288,266 @@ describe('#customDomains handler', () => { }), }; - //@ts-ignore + // @ts-ignore const handler = new customDomainsHandler({ config: () => {}, client: auth0ApiClientMock as unknown as Auth0APIClient, }); await handler.processChanges({ customDomains: [] }); - expect(didUpdateFunctionGetCalled).to.equal(false); //The update function should not be called + expect(didUpdateFunctionGetCalled).to.equal(false); // The update function should not be called expect(didDeleteFunctionGetCalled).to.equal(false); expect(didCreateFunctionGetCalled).to.equal(false); }); + + // Update Functionality Tests + it('should update custom domains when changes exist', async () => { + let didUpdateFunctionGetCalled = false; + + const existingCustomDomain = { + custom_domain_id: 'cd_123', + domain: 'existing.example.com', + type: 'auth0_managed_certs', + status: 'ready', + tls_policy: 'recommended', + }; + + const updatedCustomDomain = { + custom_domain_id: 'cd_123', + domain: 'existing.example.com', + type: 'auth0_managed_certs', + tls_policy: 'recommended', + domain_metadata: { environment: 'production' }, + }; + + const auth0ApiClientMock = { + customDomains: { + getAll: async () => ({ data: [existingCustomDomain] }), + create: async () => {}, + update: async (args, data) => { + didUpdateFunctionGetCalled = true; + expect(args).to.deep.equal({ id: 'cd_123' }); + expect(data).to.deep.equal({ + tls_policy: 'recommended', + domain_metadata: { environment: 'production' }, + }); + return { data: updatedCustomDomain }; + }, + delete: async () => {}, + }, + pool: new PromisePoolExecutor({ + concurrencyLimit: 3, + frequencyLimit: 8, + frequencyWindow: 1000, // 1 sec + }), + }; + + // @ts-ignore + const handler = new customDomainsHandler({ + config: () => {}, + client: auth0ApiClientMock as unknown as Auth0APIClient, + }); + + await handler.processChanges({ customDomains: [updatedCustomDomain] }); + + expect(didUpdateFunctionGetCalled).to.equal(true); + }); + + it('should call update with correct parameters and strip update fields', async () => { + let updateCallData = null; + + const existingCustomDomain = { + domain: 'test.example.com', + type: 'auth0_managed_certs', + status: 'ready', + }; + + const updatedCustomDomainWithExtraFields = { + domain: 'test.example.com', // should be stripped + type: 'auth0_managed_certs', // should be stripped + status: 'ready', // should be stripped + primary: true, // should be stripped + verification: { method: 'cname' }, // should be stripped + verification_method: 'cname', // should be stripped + tls_policy: 'recommended', // should NOT be stripped + domain_metadata: { key: 'value' }, // should NOT be stripped + }; + + const auth0ApiClientMock = { + customDomains: { + getAll: async () => ({ data: [existingCustomDomain] }), + create: async () => {}, + update: async (args, data) => { + updateCallData = data; + return { data: {} }; + }, + delete: async () => {}, + }, + pool: new PromisePoolExecutor({ + concurrencyLimit: 3, + frequencyLimit: 8, + frequencyWindow: 1000, // 1 sec + }), + }; + + // @ts-ignore + const handler = new customDomainsHandler({ + config: () => {}, + client: auth0ApiClientMock as unknown as Auth0APIClient, + }); + + await handler.processChanges({ customDomains: [updatedCustomDomainWithExtraFields] }); + + // Verify that stripped fields are not present + expect(updateCallData).to.not.have.property('domain'); + expect(updateCallData).to.not.have.property('type'); + expect(updateCallData).to.not.have.property('status'); + expect(updateCallData).to.not.have.property('primary'); + expect(updateCallData).to.not.have.property('verification'); + expect(updateCallData).to.not.have.property('verification_method'); + + // Verify that allowed fields are present + expect(updateCallData).to.have.property('tls_policy', 'recommended'); + expect(updateCallData).to.have.property('domain_metadata'); + expect(updateCallData.domain_metadata).to.deep.equal({ key: 'value' }); + }); + + // New Schema Fields Tests + it('should handle domain_metadata in custom domains', async () => { + let didCreateFunctionGetCalled = false; + let createCallArgs = null; + + const customDomainWithMetadata = { + domain: 'metadata.example.com', + type: 'auth0_managed_certs', + domain_metadata: { + environment: 'test', + team: 'engineering', + cost_center: '12345', + }, + }; + + const auth0ApiClientMock = { + customDomains: { + getAll: async () => ({ data: [] }), + create: async (args) => { + didCreateFunctionGetCalled = true; + createCallArgs = args; + return { data: customDomainWithMetadata }; + }, + update: async () => {}, + delete: async () => {}, + }, + pool: new PromisePoolExecutor({ + concurrencyLimit: 3, + frequencyLimit: 8, + frequencyWindow: 1000, // 1 sec + }), + }; + + // @ts-ignore + const handler = new customDomainsHandler({ + config: () => {}, + client: auth0ApiClientMock as unknown as Auth0APIClient, + }); + + await handler.processChanges({ customDomains: [customDomainWithMetadata] }); + + expect(didCreateFunctionGetCalled).to.equal(true); + expect(createCallArgs).to.have.property('domain_metadata'); + expect(createCallArgs.domain_metadata).to.deep.equal({ + environment: 'test', + team: 'engineering', + cost_center: '12345', + }); + }); + + it('should create custom domains with tls_policy field', async () => { + let didCreateFunctionGetCalled = false; + let createCallArgs = null; + + const customDomainWithTlsPolicy = { + domain: 'tls.example.com', + type: 'auth0_managed_certs', + tls_policy: 'recommended', + }; + + const auth0ApiClientMock = { + customDomains: { + getAll: async () => ({ data: [] }), + create: async (args) => { + didCreateFunctionGetCalled = true; + createCallArgs = args; + return { data: customDomainWithTlsPolicy }; + }, + update: async () => {}, + delete: async () => {}, + }, + pool: new PromisePoolExecutor({ + concurrencyLimit: 3, + frequencyLimit: 8, + frequencyWindow: 1000, // 1 sec + }), + }; + + // @ts-ignore + const handler = new customDomainsHandler({ + config: () => {}, + client: auth0ApiClientMock as unknown as Auth0APIClient, + }); + + await handler.processChanges({ customDomains: [customDomainWithTlsPolicy] }); + + expect(didCreateFunctionGetCalled).to.equal(true); + expect(createCallArgs).to.have.property('tls_policy', 'recommended'); + }); + + it('should support both tls_policy and domain_metadata together', async () => { + let didCreateFunctionGetCalled = false; + let createCallArgs = null; + + const customDomainWithBothFields = { + domain: 'combined.example.com', + type: 'auth0_managed_certs', + tls_policy: 'recommended', + domain_metadata: { + environment: 'production', + owner: 'platform-team', + }, + }; + + const auth0ApiClientMock = { + customDomains: { + getAll: async () => ({ data: [] }), + create: async (args) => { + didCreateFunctionGetCalled = true; + createCallArgs = args; + return { data: customDomainWithBothFields }; + }, + update: async () => {}, + delete: async () => {}, + }, + pool: new PromisePoolExecutor({ + concurrencyLimit: 3, + frequencyLimit: 8, + frequencyWindow: 1000, // 1 sec + }), + }; + + // @ts-ignore + const handler = new customDomainsHandler({ + config: () => {}, + client: auth0ApiClientMock as unknown as Auth0APIClient, + }); + + await handler.processChanges({ customDomains: [customDomainWithBothFields] }); + + expect(didCreateFunctionGetCalled).to.equal(true); + expect(createCallArgs).to.have.property('tls_policy', 'recommended'); + expect(createCallArgs).to.have.property('domain_metadata'); + expect(createCallArgs.domain_metadata).to.deep.equal({ + environment: 'production', + owner: 'platform-team', + }); + }); }); From dfc1b66cc0cc14d3b34264dd8a696c3edab518a3 Mon Sep 17 00:00:00 2001 From: kushalshit27 <43465488+kushalshit27@users.noreply.github.com> Date: Wed, 18 Jun 2025 11:41:31 +0530 Subject: [PATCH 6/7] feat: add tls_policy to custom domains configuration --- examples/directory/custom-domains/custom-domains.json | 1 + examples/yaml/tenant.yaml | 1 + src/tools/auth0/handlers/customDomains.ts | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/directory/custom-domains/custom-domains.json b/examples/directory/custom-domains/custom-domains.json index 8289485d..5301be7b 100644 --- a/examples/directory/custom-domains/custom-domains.json +++ b/examples/directory/custom-domains/custom-domains.json @@ -2,6 +2,7 @@ { "domain": "my_domain.com", "type": "auth0_managed_certs", + "tls_policy": "recommended", "domain_metadata": { "myKey": "value" } diff --git a/examples/yaml/tenant.yaml b/examples/yaml/tenant.yaml index b180ea68..99821d89 100644 --- a/examples/yaml/tenant.yaml +++ b/examples/yaml/tenant.yaml @@ -276,6 +276,7 @@ networkACLs: customDomains: - domain: my_domain.com type: auth0_managed_certs + tls_policy: 'recommended' domain_metadata: myKey: value diff --git a/src/tools/auth0/handlers/customDomains.ts b/src/tools/auth0/handlers/customDomains.ts index 01dea160..d84365d4 100644 --- a/src/tools/auth0/handlers/customDomains.ts +++ b/src/tools/auth0/handlers/customDomains.ts @@ -44,7 +44,7 @@ export default class CustomDomainsHadnler extends DefaultAPIHandler { type: 'customDomains', id: 'custom_domain_id', identifiers: ['custom_domain_id', 'domain'], - stripCreateFields: ['status', 'primary', 'verification'], + stripCreateFields: ['status', 'primary', 'verification', 'certificate'], stripUpdateFields: [ 'status', 'primary', @@ -52,6 +52,7 @@ export default class CustomDomainsHadnler extends DefaultAPIHandler { 'type', 'domain', 'verification_method', + 'certificate', ], functions: { delete: (args) => this.client.customDomains.delete({ id: args.custom_domain_id }), From 1e339108bd0f707c0b69d8bf992b4c5c354214f7 Mon Sep 17 00:00:00 2001 From: kushalshit27 <43465488+kushalshit27@users.noreply.github.com> Date: Wed, 18 Jun 2025 16:09:07 +0530 Subject: [PATCH 7/7] feat: add verification_method to custom domains schema --- src/tools/auth0/handlers/customDomains.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/auth0/handlers/customDomains.ts b/src/tools/auth0/handlers/customDomains.ts index d84365d4..4e33d27b 100644 --- a/src/tools/auth0/handlers/customDomains.ts +++ b/src/tools/auth0/handlers/customDomains.ts @@ -30,6 +30,11 @@ export const schema = { defaultValue: undefined, maxProperties: 10, }, + verification_method: { + type: 'string', + description: 'Custom domain verification method. Must be `txt`.', + defaultValue: 'txt', + }, }, required: ['domain', 'type'], },