Default to https: for urls with no scheme

This commit is contained in:
Pavel Djundik 2018-05-23 16:50:59 +03:00
parent 42344302de
commit 97dfdbf7c0
4 changed files with 46 additions and 35 deletions

View file

@ -1,6 +1,24 @@
"use strict"; "use strict";
const linkify = require("linkify-it")() const LinkifyIt = require("linkify-it");
LinkifyIt.prototype.normalize = function normalize(match) {
if (!match.schema) {
match.schema = "https:";
match.url = "https://" + match.url;
}
if (match.schema === "//") {
match.schema = "https:";
match.url = "https:" + match.url;
}
if (match.schema === "mailto:" && !/^mailto:/i.test(match.url)) {
match.url = "mailto:" + match.url;
}
};
const linkify = LinkifyIt()
.tlds(require("tlds")) .tlds(require("tlds"))
.tlds("onion", true); .tlds("onion", true);
@ -25,18 +43,11 @@ function findLinks(text) {
return []; return [];
} }
return matches.map((url) => { return matches.map((url) => ({
// Prefix protocol to protocol-aware urls start: url.index,
if (url.schema === "//") { end: url.lastIndex,
url.url = `http:${url.url}`; link: url.url,
} }));
return {
start: url.index,
end: url.lastIndex,
link: url.url,
};
});
} }
module.exports = findLinks; module.exports = findLinks;

View file

@ -22,7 +22,7 @@ describe("findLinks", () => {
const expected = [{ const expected = [{
start: 0, start: 0,
end: 24, end: 24,
link: "http://www.nooooooooooooooo.com", link: "https://www.nooooooooooooooo.com",
}]; }];
const actual = findLinks(input); const actual = findLinks(input);
@ -46,7 +46,7 @@ describe("findLinks", () => {
it("should find urls in strings starting with www", () => { it("should find urls in strings starting with www", () => {
const input = "use www.duckduckgo.com for privacy reasons"; const input = "use www.duckduckgo.com for privacy reasons";
const expected = [{ const expected = [{
link: "http://www.duckduckgo.com", link: "https://www.duckduckgo.com",
start: 4, start: 4,
end: 22, end: 22,
}]; }];
@ -94,7 +94,7 @@ describe("findLinks", () => {
it("should handle multiple www. correctly", () => { it("should handle multiple www. correctly", () => {
const input = "www.www.test.com"; const input = "www.www.test.com";
const expected = [{ const expected = [{
link: "http://www.www.test.com", link: "https://www.www.test.com",
start: 0, start: 0,
end: 16, end: 16,
}]; }];
@ -107,15 +107,15 @@ describe("findLinks", () => {
it("should find domains without www. but valid tld", () => { it("should find domains without www. but valid tld", () => {
const input = "google.com google.lv google.museum"; const input = "google.com google.lv google.museum";
const expected = [{ const expected = [{
link: "http://google.com", link: "https://google.com",
start: 0, start: 0,
end: 10, end: 10,
}, { }, {
link: "http://google.lv", link: "https://google.lv",
start: 11, start: 11,
end: 20, end: 20,
}, { }, {
link: "http://google.museum", link: "https://google.museum",
start: 21, start: 21,
end: 34, end: 34,
}]; }];
@ -128,7 +128,7 @@ describe("findLinks", () => {
it("should find .onion domains", () => { it("should find .onion domains", () => {
const input = "facebookcorewwwi.onion/test?url"; const input = "facebookcorewwwi.onion/test?url";
const expected = [{ const expected = [{
link: "http://facebookcorewwwi.onion/test?url", link: "https://facebookcorewwwi.onion/test?url",
start: 0, start: 0,
end: 31, end: 31,
}]; }];
@ -228,11 +228,11 @@ describe("findLinks", () => {
start: 0, start: 0,
end: 22, end: 22,
}, { }, {
link: "http://www.google.com", link: "https://www.google.com",
start: 25, start: 25,
end: 39, end: 39,
}, { }, {
link: "http://google.com", link: "https://google.com",
start: 42, start: 42,
end: 52, end: 52,
}]; }];
@ -247,7 +247,7 @@ describe("findLinks", () => {
const expected = [{ const expected = [{
start: 0, start: 0,
end: 15, end: 15,
link: "http://www.example.com", link: "https://www.example.com",
}]; }];
const actual = findLinks(input); const actual = findLinks(input);
@ -258,7 +258,7 @@ describe("findLinks", () => {
const expected2 = [{ const expected2 = [{
start: 0, start: 0,
end: 15, end: 15,
link: "http://www.example.com", link: "https://www.example.com",
}, { }, {
start: 16, start: 16,
end: 57, end: 57,
@ -275,7 +275,7 @@ describe("findLinks", () => {
const expected = [{ const expected = [{
start: 0, start: 0,
end: 15, end: 15,
link: "http://www.example.com", link: "https://www.example.com",
}, { }, {
start: 16, start: 16,
end: 29, end: 29,
@ -294,7 +294,7 @@ describe("findLinks", () => {
it("should add protocol to protocol-aware urls", () => { it("should add protocol to protocol-aware urls", () => {
const input = "//example.com"; const input = "//example.com";
const expected = [{ const expected = [{
link: "http://example.com", link: "https://example.com",
start: 0, start: 0,
end: 13, end: 13,
}]; }];

View file

@ -7,7 +7,7 @@ describe("parse Handlebars helper", () => {
it("should not introduce xss", () => { it("should not introduce xss", () => {
const testCases = [{ const testCases = [{
input: "<img onerror='location.href=\"//youtube.com\"'>", input: "<img onerror='location.href=\"//youtube.com\"'>",
expected: "&lt;img onerror&#x3D;&#x27;location.href&#x3D;&quot;<a href=\"http://youtube.com\" target=\"_blank\" rel=\"noopener\">//youtube.com</a>&quot;&#x27;&gt;", expected: "&lt;img onerror&#x3D;&#x27;location.href&#x3D;&quot;<a href=\"https://youtube.com\" target=\"_blank\" rel=\"noopener\">//youtube.com</a>&quot;&#x27;&gt;",
}, { }, {
input: '#&">bug', input: '#&">bug',
expected: '<span class="inline-channel" role="button" tabindex="0" data-chan="#&amp;&quot;&gt;bug">#&amp;&quot;&gt;bug</span>', expected: '<span class="inline-channel" role="button" tabindex="0" data-chan="#&amp;&quot;&gt;bug">#&amp;&quot;&gt;bug</span>',
@ -41,7 +41,7 @@ describe("parse Handlebars helper", () => {
}, { }, {
input: "www.nooooooooooooooo.com", input: "www.nooooooooooooooo.com",
expected: expected:
'<a href="http://www.nooooooooooooooo.com" target="_blank" rel="noopener">' + '<a href="https://www.nooooooooooooooo.com" target="_blank" rel="noopener">' +
"www.nooooooooooooooo.com" + "www.nooooooooooooooo.com" +
"</a>", "</a>",
}, { }, {
@ -56,7 +56,7 @@ describe("parse Handlebars helper", () => {
input: "use www.duckduckgo.com for privacy reasons", input: "use www.duckduckgo.com for privacy reasons",
expected: expected:
"use " + "use " +
'<a href="http://www.duckduckgo.com" target="_blank" rel="noopener">' + '<a href="https://www.duckduckgo.com" target="_blank" rel="noopener">' +
"www.duckduckgo.com" + "www.duckduckgo.com" +
"</a>" + "</a>" +
" for privacy reasons", " for privacy reasons",
@ -101,7 +101,7 @@ describe("parse Handlebars helper", () => {
input: "abc (www.example.com)", input: "abc (www.example.com)",
expected: expected:
"abc (" + "abc (" +
'<a href="http://www.example.com" target="_blank" rel="noopener">' + '<a href="https://www.example.com" target="_blank" rel="noopener">' +
"www.example.com" + "www.example.com" +
"</a>" + "</a>" +
")", ")",
@ -114,7 +114,7 @@ describe("parse Handlebars helper", () => {
}, { }, {
input: "www.example.com/Test_(Page)", input: "www.example.com/Test_(Page)",
expected: expected:
'<a href="http://www.example.com/Test_(Page)" target="_blank" rel="noopener">' + '<a href="https://www.example.com/Test_(Page)" target="_blank" rel="noopener">' +
"www.example.com/Test_(Page)" + "www.example.com/Test_(Page)" +
"</a>", "</a>",
}]; }];

View file

@ -380,14 +380,14 @@ describe("Link plugin", function() {
link(this.irc, this.network.channels[0], message); link(this.irc, this.network.channels[0], message);
this.irc.once("msg:preview", function(data) { this.irc.once("msg:preview", function(data) {
expect(data.preview.link).to.equal("http://localhost:9002"); expect(data.preview.link).to.equal("https://localhost:9002");
done(); done();
}); });
}); });
it("should de-duplicate links", function(done) { it("should de-duplicate links", function(done) {
const message = this.irc.createMessage({ const message = this.irc.createMessage({
text: "//localhost:9002 http://localhost:9002 http://localhost:9002", text: "//localhost:9002 https://localhost:9002 https://localhost:9002",
}); });
link(this.irc, this.network.channels[0], message); link(this.irc, this.network.channels[0], message);
@ -397,12 +397,12 @@ describe("Link plugin", function() {
head: "", head: "",
body: "", body: "",
thumb: "", thumb: "",
link: "http://localhost:9002", link: "https://localhost:9002",
shown: true, shown: true,
}]); }]);
this.irc.once("msg:preview", function(data) { this.irc.once("msg:preview", function(data) {
expect(data.preview.link).to.equal("http://localhost:9002"); expect(data.preview.link).to.equal("https://localhost:9002");
done(); done();
}); });
}); });