diff --git a/web/cashtab/src/components/Tokens/CreateTokenForm.js b/web/cashtab/src/components/Tokens/CreateTokenForm.js --- a/web/cashtab/src/components/Tokens/CreateTokenForm.js +++ b/web/cashtab/src/components/Tokens/CreateTokenForm.js @@ -597,7 +597,7 @@ newTokenDocumentUrlIsValid === null || newTokenDocumentUrlIsValid ? '' - : 'Document URL cannot exceed 68 characters' + : 'Document URL cannot exceed 68 characters and must be a valid URL' } > { + expect(isValidTokenDocumentUrl('https://google.com')).toBe(true); + }); + it(`Accepts a domain input with http protocol as ${currency.tokenTicker} token document URL`, () => { + expect(isValidTokenDocumentUrl('http://test.com')).toBe(true); + }); + it(`Accepts a domain input with a primary and secondary top level domain as ${currency.tokenTicker} token document URL`, () => { + expect(isValidTokenDocumentUrl('http://test.co.uk')).toBe(true); + }); + it(`Accepts a domain input with just a subdomain as ${currency.tokenTicker} token document URL`, () => { + expect(isValidTokenDocumentUrl('www.test.co.uk')).toBe(true); + }); + it(`Rejects a domain input with no top level domain, protocol or subdomain ${currency.tokenTicker} token document URL`, () => { + expect(isValidTokenDocumentUrl('mywebsite')).toBe(false); + }); + it(`Rejects a domain input as numbers ${currency.tokenTicker} token document URL`, () => { + expect(isValidTokenDocumentUrl(12345)).toBe(false); + }); it(`Correctly validates token stats for token created before the ${currency.ticker} fork`, () => { expect(isValidTokenStats(stStatsValid)).toBe(true); }); diff --git a/web/cashtab/src/utils/validation.js b/web/cashtab/src/utils/validation.js --- a/web/cashtab/src/utils/validation.js +++ b/web/cashtab/src/utils/validation.js @@ -86,10 +86,25 @@ }; export const isValidTokenDocumentUrl = tokenDocumentUrl => { + function validURL(str) { + var pattern = new RegExp( + '^(https?:\\/\\/)?' + // protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name + '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path + '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string + '(\\#[-a-z\\d_]*)?$', + 'i', + ); // fragment locator + return !!pattern.test(str); + } + return ( - typeof tokenDocumentUrl === 'string' && - tokenDocumentUrl.length >= 0 && - tokenDocumentUrl.length < 68 + (typeof tokenDocumentUrl === 'string' && + tokenDocumentUrl.length >= 0 && + tokenDocumentUrl.length < 68 && + validURL(tokenDocumentUrl)) || + tokenDocumentUrl === '' ); };