diff --git a/news/4601.bugfix b/news/4601.bugfix new file mode 100644 index 0000000000..cbb24473ca --- /dev/null +++ b/news/4601.bugfix @@ -0,0 +1 @@ +Fix regexp that checks valid URLs and improve tests [cekk] diff --git a/src/helpers/FormValidation/FormValidation.js b/src/helpers/FormValidation/FormValidation.js index 7c6d609f19..0c5fd28eac 100644 --- a/src/helpers/FormValidation/FormValidation.js +++ b/src/helpers/FormValidation/FormValidation.js @@ -65,7 +65,16 @@ const widgetValidation = { }, url: { isValidURL: (urlValue, urlObj, intlFunc) => { - const urlRegex = /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([_.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/gm; + var urlRegex = new RegExp( + '^(https?:\\/\\/)?' + // validate protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name + '((\\d{1,3}\\.){3}\\d{1,3}))|' + // validate OR ip (v4) address + '(localhost)' + // validate OR localhost address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // validate port and path + '(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string + '(\\#[-a-z\\d_]*)?$', // validate fragment locator + 'i', + ); const isValid = urlRegex.test(urlValue); return !isValid ? intlFunc(messages.isValidURL) : null; }, diff --git a/src/helpers/FormValidation/FormValidation.test.js b/src/helpers/FormValidation/FormValidation.test.js index 56da3a43a3..df25ac0038 100644 --- a/src/helpers/FormValidation/FormValidation.test.js +++ b/src/helpers/FormValidation/FormValidation.test.js @@ -5,6 +5,7 @@ const schema = { properties: { username: { title: 'Username', type: 'string', description: '' }, email: { title: 'Email', type: 'string', widget: 'email', description: '' }, + url: { title: 'url', type: 'string', widget: 'url', description: '' }, }, fieldsets: [ { id: 'default', title: 'FIXME: User Data', fields: ['username'] }, @@ -87,5 +88,45 @@ describe('FormValidation', () => { }), ).toEqual({}); }); + it('validates incorrect url', () => { + formData.url = 'foo'; + expect( + FormValidation.validateFieldsPerFieldset({ + schema, + formData, + formatMessage, + }), + ).toEqual({ url: [messages.isValidURL.defaultMessage] }); + }); + it('validates url', () => { + formData.url = 'https://plone.org/'; + expect( + FormValidation.validateFieldsPerFieldset({ + schema, + formData, + formatMessage, + }), + ).toEqual({}); + }); + it('validates url with ip', () => { + formData.url = 'http://127.0.0.1:8080/Plone'; + expect( + FormValidation.validateFieldsPerFieldset({ + schema, + formData, + formatMessage, + }), + ).toEqual({}); + }); + it('validates url with localhost', () => { + formData.url = 'http://localhost:8080/Plone'; + expect( + FormValidation.validateFieldsPerFieldset({ + schema, + formData, + formatMessage, + }), + ).toEqual({}); + }); }); });