diff --git a/public/pages/Destinations/components/createDestinations/CustomWebhook/validate.js b/public/pages/Destinations/components/createDestinations/CustomWebhook/validate.js index bdf4a1dd..5c3d4c88 100644 --- a/public/pages/Destinations/components/createDestinations/CustomWebhook/validate.js +++ b/public/pages/Destinations/components/createDestinations/CustomWebhook/validate.js @@ -19,9 +19,23 @@ export const validateUrl = (value, allValues) => { const type = allValues.type; if (allValues[type].urlType !== URL_TYPE.FULL_URL) return; if (!value) return 'Required'; - const isValidUrl = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/.test( - value - ); + const regname = '((www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,4})'; + const ipv4 = '(((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'; + const h16 = '([0-9a-fA-F]{1,4})'; + const ls32 = `((${h16}:${h16})|${ipv4})`; + const ipv6 = `\\[(`+ + `((${h16}:){6}${ls32})|`+ + `(::(${h16}:){5}${ls32})|`+ + `(${h16}?::(${h16}:){4}${ls32})|`+ + `(((${h16}:){0,1}${h16})?::(${h16}:){3}${ls32})|`+ + `(((${h16}:){0,2}${h16})?::(${h16}:){2}${ls32})|`+ + `(((${h16}:){0,3}${h16})?::${h16}:${ls32})|`+ + `(((${h16}:){0,4}${h16})?::${ls32})|`+ + `(((${h16}:){0,5}${h16})?::${h16})|`+ + `((${h16}:){0,6}${h16})?::`+ + `)\\]`; + const regexUrl = `^https?:\\/\\/(${regname}|${ipv4}|${ipv6})(:[0-9]{1,5})?([/?#][-a-zA-Z0-9@:%_\\+.~#?&//=]*)?$`; + const isValidUrl = new RegExp(regexUrl).test(value); if (!isValidUrl) return 'Invalid URL'; }; diff --git a/public/pages/Destinations/components/createDestinations/CustomWebhook/validate.test.js b/public/pages/Destinations/components/createDestinations/CustomWebhook/validate.test.js new file mode 100644 index 00000000..0982bf4f --- /dev/null +++ b/public/pages/Destinations/components/createDestinations/CustomWebhook/validate.test.js @@ -0,0 +1,57 @@ +/* + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import { + validateUrl, +} from './validate'; + +import { URL_TYPE } from '../../../containers/CreateDestination/utils/constants'; + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('validateUrl', () => { + const typeFullUrl = {"type": "custom_webhook", "custom_webhook": { "urlType": URL_TYPE.FULL_URL }} + + test('returns Required if is empty', () => { + expect(validateUrl('', typeFullUrl)).toBe('Required'); + }); + + test('returns undefined if valid', () => { + expect(validateUrl('https://opendistro.github.io/for-elasticsearch/news.html', typeFullUrl)).toBeUndefined(); + expect(validateUrl("http://127.0.0.1:8080/", typeFullUrl)).toBeUndefined(); + expect(validateUrl("http://192.168.0.1/test.php?foo=bar&action=test", typeFullUrl)).toBeUndefined(); + expect(validateUrl("http://[2001:0db8:85a3:0000:0000:0000:0000:7344]", typeFullUrl)).toBeUndefined(); + expect(validateUrl("http://[2001:0db8:85a3:0:0:0:0:7344]", typeFullUrl)).toBeUndefined(); + expect(validateUrl("http://[2001:0db8:85a3::7344]", typeFullUrl)).toBeUndefined(); + expect(validateUrl("https://[::ff]", typeFullUrl)).toBeUndefined(); + expect(validateUrl("https://[2001:db8::ff00:42:8329]:443/?foo=bar", typeFullUrl)).toBeUndefined(); + expect(validateUrl("http://[64:ff9b::192.0.2.128]:80/", typeFullUrl)).toBeUndefined(); + }); + + test('returns error string if invalid', () => { + const invalidText = 'Invalid URL'; + expect(validateUrl("opendistro.github.io", typeFullUrl)).toBe(invalidText); + expect(validateUrl("https://opendistro.github/", typeFullUrl)).toBe(invalidText); + expect(validateUrl("127.0.0.1", typeFullUrl)).toBe(invalidText); + expect(validateUrl("http://127.0.0.1.1", typeFullUrl)).toBe(invalidText); + expect(validateUrl("http://127.0.0.256:8080/", typeFullUrl)).toBe(invalidText); + expect(validateUrl("ftp://127.0.0.1", typeFullUrl)).toBe(invalidText); + expect(validateUrl("2001:0db8:85a3:0000:0000:0000:0000:7344", typeFullUrl)).toBe(invalidText); + expect(validateUrl("http://2001:0db8:85a3:0000:0000:0000:0000:7344", typeFullUrl)).toBe(invalidText); + expect(validateUrl("http://[2001:0db8:85a3:0000:0r00:0000:0000:7344]", typeFullUrl)).toBe(invalidText); + }); +}); \ No newline at end of file