Skip to content

Commit

Permalink
feat: support wildcard domains with regex [MONET-2345] (#2155)
Browse files Browse the repository at this point in the history
* feat: support wildcard domains with regex

* feat: update regex
  • Loading branch information
cemreyuksel authored Oct 2, 2024
1 parent 3ea8f13 commit 80f5e87
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 13 deletions.
46 changes: 36 additions & 10 deletions packages/contentful--app-scripts/src/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ describe('isValidIpAddress', () => {
assert.strictEqual(result, true);
});

it('returns true for a wildcard domain address', () => {
const result = isValidNetwork('*.cloudflare.com');
assert.strictEqual(result, true);
});

it('returns true for a valid domain', () => {
const result = isValidNetwork('google.com');
assert.strictEqual(result, true);
Expand Down Expand Up @@ -44,6 +49,27 @@ describe('isValidIpAddress', () => {
const result = isValidNetwork('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:443');
assert.strictEqual(result, true);
});

it('returns false for an invalid wildcard domain address', () => {
const result = isValidNetwork('*.128.0.1');
assert.strictEqual(result, false);
});

it('returns false for invalid wildcard domain address', () => {
const result = isValidNetwork('*.com');
assert.strictEqual(result, false);
});

it('returns false for invalid wildcard domain address', () => {
const result = isValidNetwork('*.too.example.com');
assert.strictEqual(result, false);
});

it('returns false for invalid wildcard domain address', () => {
const result = isValidNetwork('*');
assert.strictEqual(result, false);
});

});

describe('removeProtocolFromUrl', () => {
Expand Down Expand Up @@ -125,7 +151,7 @@ describe('get actions from manifest', () => {
fs.readFileSync.returns(
JSON.stringify({
actions: [actionMock],
}),
})
);

const result = getEntityFromManifest('actions');
Expand All @@ -145,7 +171,7 @@ describe('get actions from manifest', () => {
fs.readFileSync.returns(
JSON.stringify({
actions: [mockAction],
}),
})
);

const result = getEntityFromManifest('actions');
Expand All @@ -159,7 +185,7 @@ describe('get actions from manifest', () => {
fs.readFileSync.returns(
JSON.stringify({
actions: [actionMock],
}),
})
);

const result = getEntityFromManifest('actions');
Expand All @@ -178,7 +204,7 @@ describe('get actions from manifest', () => {
allowNetworks: ['412.1.1.1'],
},
],
}),
})
);

getEntityFromManifest('actions');
Expand Down Expand Up @@ -206,7 +232,7 @@ describe('get functions from manifest', () => {
path: 'functions/mock.js',
entryFile: './functions/mock.ts',
allowNetworks: ['127.0.0.1', 'some.domain.tld'],
accepts: ["graphql.field.mapping", "graphql.query", 'appevent.filter']
accepts: ['graphql.field.mapping', 'graphql.query', 'appevent.filter'],
};
// eslint-disable-next-line no-unused-vars
const { entryFile: _, ...resultMock } = functionMock;
Expand Down Expand Up @@ -252,7 +278,7 @@ describe('get functions from manifest', () => {
fs.readFileSync.returns(
JSON.stringify({
functions: [functionMock],
}),
})
);

const result = getEntityFromManifest('functions');
Expand All @@ -272,7 +298,7 @@ describe('get functions from manifest', () => {
fs.readFileSync.returns(
JSON.stringify({
functions: [mockFn],
}),
})
);

const result = getEntityFromManifest('functions');
Expand All @@ -286,7 +312,7 @@ describe('get functions from manifest', () => {
fs.readFileSync.returns(
JSON.stringify({
functions: [functionMock],
}),
})
);

const result = getEntityFromManifest('functions');
Expand All @@ -305,7 +331,7 @@ describe('get functions from manifest', () => {
allowNetworks: ['412.1.1.1'],
},
],
}),
})
);

getEntityFromManifest('functions');
Expand All @@ -324,7 +350,7 @@ describe('get functions from manifest', () => {
accepts: ['webhooks.rest'],
},
],
}),
})
);

getEntityFromManifest('functions');
Expand Down
21 changes: 18 additions & 3 deletions packages/contentful--app-scripts/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,24 @@ export const throwValidationException = (subject: string, message?: string, deta
throw new TypeError(message);
};

export const isValidNetwork = (address: string) => {
const addressRegex =
/^(?:localhost|(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(\[(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}\]|(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}))(?::\d{1,5})?$/;
export const isValidNetwork = (address: string): boolean => {
// Regular expression to validate network addresses
const addressRegex = new RegExp(
'^(?:' + // Start of the non-capturing group for the entire address
'(?:' + // 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)
'|' + // 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)
')|' + // 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
'(\\[(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}\\]' + // Matches IPv6 addresses in square brackets
'|(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4})' + // Matches IPv6 addresses without square brackets
')(?::\\d{1,5})?$' // Matches an optional port number (1 to 5 digits)
);
return addressRegex.test(address);
};

Expand Down

0 comments on commit 80f5e87

Please sign in to comment.