From 5e4c32676017ae1e36186935367de00c2d092704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A1l=20Tom=C3=A1=C5=A1?= Date: Fri, 5 Jan 2018 10:08:14 +0100 Subject: [PATCH 1/6] Add possibility to match also private network URLs --- index.js | 5 +++-- test.js | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index e656f74..eaba873 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ const ipRegex = require('ip-regex'); const tlds = require('tlds'); module.exports = opts => { - opts = Object.assign({strict: true}, opts); + opts = Object.assign({strict: true, local: false}, opts); const protocol = `(?:(?:[a-z]+:)?//)${opts.strict ? '' : '?'}`; const auth = '(?:\\S+(?::\\S*)?@)?'; @@ -11,9 +11,10 @@ module.exports = opts => { const host = '(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)'; const domain = '(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*'; const tld = `(?:\\.${opts.strict ? '(?:[a-z\\u00a1-\\uffff]{2,})' : `(?:${tlds.sort((a, b) => b.length - a.length).join('|')})`})\\.?`; + const locals = opts.local ? host : 'localhost'; const port = '(?::\\d{2,5})?'; const path = '(?:[/?#][^\\s"]*)?'; - const regex = `(?:${protocol}|www\\.)${auth}(?:localhost|${ip}|${host}${domain}${tld})${port}${path}`; + const regex = `(?:${protocol}|www\\.)${auth}(?:${locals}|${ip}|${host}${domain}${tld})${port}${path}`; return opts.exact ? new RegExp(`(?:^${regex}$)`, 'i') : new RegExp(regex, 'ig'); }; diff --git a/test.js b/test.js index 525380c..86a7428 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ import test from 'ava'; -import m from './'; +import m from './index'; test('match exact URLs', t => { const fixtures = [ @@ -195,3 +195,23 @@ test('match using list of TLDs', t => { t.true(m({exact: true, strict: false}).test(x)); } }); + +const localUrlFixtures = [ + 'http://orgchart/index.php', + 'http://aplicakcepredpisy/index.php?tpl=pk_khika$book_id=1057', + 'http://forge/library/home/' +]; + +test('match local URLs', t => { + for (const x of localUrlFixtures) { + t.true(m({exact: true, local: true}).test(x)); + } +}); + +test('should not match local domains but localhost', t => { + t.true(m({exact: true}).test('http://localhost/')); + + for (const x of localUrlFixtures) { + t.false(m({exact: true}).test(x)); + } +}); From d10074ac2f1047a26e02ab700a4bd765f43b9ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A1l=20Tom=C3=A1=C5=A1?= Date: Fri, 5 Jan 2018 10:14:41 +0100 Subject: [PATCH 2/6] Update documentation for `local` option --- readme.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/readme.md b/readme.md index 38a1118..2805d28 100644 --- a/readme.md +++ b/readme.md @@ -29,6 +29,9 @@ urlRegex({exact: true}).test('http://github.com foo bar'); urlRegex({exact: true}).test('http://github.com'); //=> true +urlRegex({exact: true, local: true}).test('http://orgchart/index.php'); +//=> true + urlRegex({strict: false}).test('github.com foo bar'); //=> true @@ -62,6 +65,13 @@ Default: `true` Force URLs to start with a valid protocol or `www`. If set to `false` it'll match the TLD against a list of valid [TLDs](https://github.com/stephenmathieson/node-tlds). +##### local + +Type: `boolean`
+Default: `false` + +Allow also to test URLs with private network hosts. If set to `true` it'll match local URLs like `http://forge/library/home/` (without TLD). + ## Related From 64cca6bf96f708432897b793e1c6d85e4222febe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A1l=20Tom=C3=A1=C5=A1?= Date: Wed, 17 Jan 2018 14:37:59 +0100 Subject: [PATCH 3/6] Add test for local URLs to not match words in normal text --- test.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test.js b/test.js index 86a7428..68b1f68 100644 --- a/test.js +++ b/test.js @@ -215,3 +215,25 @@ test('should not match local domains but localhost', t => { t.false(m({exact: true}).test(x)); } }); + +test('should not match words or text as local URLs', t => { + const fixtures = [ + 'text', + 'text with more words, but still without URLs', + 'text without url and/or slash' + ]; + + for (const x of fixtures) { + t.false(m({strict: false, exact: false, local: true}).test(x)); + } +}); + +test('match local URLs in text', t => { + const fixtures = [ + 'text with local(http://orgchart/index.php) urls' + ]; + + for (const x of fixtures) { + t.true(m({strict: false, exact: false, local: true}).test(x)); + } +}); From 79cc73e8d3b884dc676f2d6d7d1c26e360dd0aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A1l=20Tom=C3=A1=C5=A1?= Date: Sun, 21 Jan 2018 23:15:33 +0100 Subject: [PATCH 4/6] Make mandatory protocol for local urls to distinguish simple words... --- index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index eaba873..92b08a9 100644 --- a/index.js +++ b/index.js @@ -5,16 +5,15 @@ const tlds = require('tlds'); module.exports = opts => { opts = Object.assign({strict: true, local: false}, opts); - const protocol = `(?:(?:[a-z]+:)?//)${opts.strict ? '' : '?'}`; + const protocol = '(?:(?:[a-z]+:)?//)'; const auth = '(?:\\S+(?::\\S*)?@)?'; const ip = ipRegex.v4().source; const host = '(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)'; const domain = '(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*'; const tld = `(?:\\.${opts.strict ? '(?:[a-z\\u00a1-\\uffff]{2,})' : `(?:${tlds.sort((a, b) => b.length - a.length).join('|')})`})\\.?`; - const locals = opts.local ? host : 'localhost'; const port = '(?::\\d{2,5})?'; const path = '(?:[/?#][^\\s"]*)?'; - const regex = `(?:${protocol}|www\\.)${auth}(?:${locals}|${ip}|${host}${domain}${tld})${port}${path}`; + const regex = `(?:(?:${protocol}${opts.strict ? '' : '?'}|www\\.)${auth}(?:localhost|${ip}|${host}${domain}${tld})${opts.local ? `|${protocol}${host}` : ''})${port}${path}`; return opts.exact ? new RegExp(`(?:^${regex}$)`, 'i') : new RegExp(regex, 'ig'); }; From 3ea01fb5a5db0f7b1073b53899cf9f92d8715edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A1l=20Tom=C3=A1=C5=A1?= Date: Thu, 22 Mar 2018 10:04:20 +0100 Subject: [PATCH 5/6] Move constant definition to the top of the file as suggested by the review. --- test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test.js b/test.js index 68b1f68..a32b5e4 100644 --- a/test.js +++ b/test.js @@ -1,6 +1,12 @@ import test from 'ava'; import m from './index'; +const localUrlFixtures = [ + 'http://orgchart/index.php', + 'http://aplicakcepredpisy/index.php?tpl=pk_khika$book_id=1057', + 'http://forge/library/home/' +]; + test('match exact URLs', t => { const fixtures = [ 'http://foo.com/blah_blah', @@ -196,12 +202,6 @@ test('match using list of TLDs', t => { } }); -const localUrlFixtures = [ - 'http://orgchart/index.php', - 'http://aplicakcepredpisy/index.php?tpl=pk_khika$book_id=1057', - 'http://forge/library/home/' -]; - test('match local URLs', t => { for (const x of localUrlFixtures) { t.true(m({exact: true, local: true}).test(x)); From 178874068bf230a7cc5c5a2baf0e33f31503f161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A1l=20Tom=C3=A1=C5=A1?= Date: Mon, 26 Mar 2018 10:50:11 +0200 Subject: [PATCH 6/6] Fixes eslint error - unicorn/import-index --- test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.js b/test.js index a32b5e4..e3d6f5c 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,5 @@ import test from 'ava'; -import m from './index'; +import m from '.'; const localUrlFixtures = [ 'http://orgchart/index.php',