diff --git a/packages/contentful--app-scripts/src/utils.test.ts b/packages/contentful--app-scripts/src/utils.test.ts index 1372b6b66..8d314c1bb 100644 --- a/packages/contentful--app-scripts/src/utils.test.ts +++ b/packages/contentful--app-scripts/src/utils.test.ts @@ -70,6 +70,31 @@ describe('isValidIpAddress', () => { const result = isValidNetwork('*'); assert.strictEqual(result, false); }); + + it('returns true for a domain with a TLD longer than 6 characters', () => { + // .hosting is 7 chars — previously rejected by the {2,6} limit. + // Customers using long gTLDs (e.g. akzonobel.hosting) were blocked from + // uploading custom apps even though the address is perfectly valid. + const result = isValidNetwork('qa-gql-gateway.akzonobel.hosting'); + assert.strictEqual(result, true); + }); + + it('returns true for a wildcard domain with a TLD longer than 6 characters', () => { + const result = isValidNetwork('*.akzonobel.hosting'); + assert.strictEqual(result, true); + }); + + it('returns true for a domain with a TLD at the maximum DNS label length of 63 characters', () => { + const maxLengthTld = 'a'.repeat(63); + const result = isValidNetwork(`example.${maxLengthTld}`); + assert.strictEqual(result, true); + }); + + it('returns false for a domain with a TLD exceeding the maximum DNS label length of 63 characters', () => { + const tooLongTld = 'a'.repeat(64); + const result = isValidNetwork(`example.${tooLongTld}`); + assert.strictEqual(result, false); + }); }); describe('removeProtocolFromUrl', () => { diff --git a/packages/contentful--app-scripts/src/utils.ts b/packages/contentful--app-scripts/src/utils.ts index f90057661..f170c859e 100644 --- a/packages/contentful--app-scripts/src/utils.ts +++ b/packages/contentful--app-scripts/src/utils.ts @@ -37,10 +37,10 @@ export const isValidNetwork = (address: string): boolean => { '(?:' + // Start of the non-capturing group for domain names '(?:\\*\\.)' + // Matches wildcard domains like *.example.com '(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)' + // Matches a single subdomain - '[a-zA-Z]{2,6}' + // Matches the top-level domain (TLD) + '[a-zA-Z]{2,63}' + // Matches the top-level domain (TLD). Upper bound of 63 follows RFC 1035 §2.3.4, which defines the maximum length of a single DNS label. ICANN began delegating long gTLDs (e.g. .hosting, .international) from 2012 onwards, making the previous limit of 6 too restrictive. '|' + // OR '(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+' + // Matches standard domains with one or more subdomains - '[a-zA-Z]{2,6}' + // Matches the top-level domain (TLD) + '[a-zA-Z]{2,63}' + // Matches the top-level domain (TLD). Upper bound of 63 follows RFC 1035 §2.3.4, which defines the maximum length of a single DNS label. ICANN began delegating long gTLDs (e.g. .hosting, .international) from 2012 onwards, making the previous limit of 6 too restrictive. ')|' + // End of the non-capturing group for domain names, OR '(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}' + // Matches the first three octets of an IPv4 address '(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|' + // Matches the last octet of an IPv4 address