diff --git a/.all-contributorsrc b/.all-contributorsrc
index a1ffc17..56b7d7d 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -429,6 +429,17 @@
"contributions": [
"platform"
]
+ },
+ {
+ "login": "k3nsei",
+ "name": "Piotr Stępniewski",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/190422?v=4",
+ "profile": "https://github.com/k3nsei",
+ "contributions": [
+ "bug",
+ "code",
+ "test"
+ ]
}
],
"skipCi": true
diff --git a/README.md b/README.md
index ef78eb4..0adb5bc 100644
--- a/README.md
+++ b/README.md
@@ -134,14 +134,16 @@ Thanks goes to these wonderful people
Anand Chowdhary ⚠️ 🐛 💻 |
Nicolas Goutay 💻 |
Tyler Krupicka 💻 ⚠️ |
+
+
Stefano Moia 💻 |
Ilaï Deutel 📦 |
+ Piotr Stępniewski 🐛 💻 ⚠️ |
-
This project follows the
diff --git a/src/repo/github.js b/src/repo/github.js
index bde0e93..c1d297b 100644
--- a/src/repo/github.js
+++ b/src/repo/github.js
@@ -1,6 +1,7 @@
const url = require('url')
const pify = require('pify')
const request = pify(require('request'))
+const { parseHttpUrl, isValidHttpUrl } = require('../util/url')
/**
* Get the host based on public or enterprise GitHub.
@@ -93,7 +94,7 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) {
.then(res => {
const body = JSON.parse(res.body)
- let profile = body.blog || body.html_url
+ let profile = isValidHttpUrl(body.blog) ? body.blog : body.html_url
// Check for authentication required
if (
@@ -112,7 +113,7 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) {
)
}
- profile = profile.startsWith('http') ? profile : `http://${profile}`
+ profile = parseHttpUrl(profile)
return {
login: body.login,
diff --git a/src/util/__tests__/url.js b/src/util/__tests__/url.js
new file mode 100644
index 0000000..50ff6d4
--- /dev/null
+++ b/src/util/__tests__/url.js
@@ -0,0 +1,49 @@
+import url from '../url';
+
+test(`Result of protocol validation should be true`, () => {
+ expect(url.isHttpProtocol('http:')).toBe(true)
+ expect(url.isHttpProtocol('https:')).toBe(true)
+})
+
+test(`Result of protocol validation should be false`, () => {
+ expect(url.isHttpProtocol('ftp:')).toBe(false)
+})
+
+test(`Result of url validation should be true`, () => {
+ expect(url.isValidHttpUrl('https://api.github.com/users/octocat')).toBe(true)
+})
+
+test(`Result of url validation should be false when url uses wrong protocol`, () => {
+ expect(url.isValidHttpUrl('git://git@github.com:all-contributors/all-contributors-cli.git')).toBe(false)
+})
+
+test(`Result of url validation should be false when input isn't url`, () => {
+ expect(url.isValidHttpUrl('github-octocat')).toBe(false)
+})
+
+test(`Result of parsed url should be equal`, () => {
+ const input = 'https://api.github.com/users/octocat'
+ const expected = 'https://api.github.com/users/octocat'
+ expect(url.parseHttpUrl(input)).toBe(expected)
+})
+
+test(`Result of parsed url without protocol should be equal`, () => {
+ const input = 'example.com'
+ const expected = 'http://example.com/'
+ expect(url.parseHttpUrl(input)).toBe(expected)
+})
+
+test(`Throw an error when parsed input isn't a string`, () => {
+ const input = 123
+ expect(url.parseHttpUrl.bind(null, input)).toThrowError('input must be a string')
+})
+
+test(`Throw an error when parsed url has wrong protocol`, () => {
+ const input = 'ftp://domain.xyz'
+ expect(url.parseHttpUrl.bind(null, input)).toThrowError('Provided URL has an invalid protocol')
+})
+
+test(`Throw an error when parsed input isn't a URL`, () => {
+ const input = 'some string'
+ expect(url.parseHttpUrl.bind(null, input)).toThrowError('Invalid URL: http://some string')
+})
diff --git a/src/util/index.js b/src/util/index.js
index a58592d..9cb5314 100644
--- a/src/util/index.js
+++ b/src/util/index.js
@@ -3,4 +3,5 @@ module.exports = {
contributionTypes: require('./contribution-types'),
git: require('./git'),
markdown: require('./markdown'),
+ url: require('./url'),
}
diff --git a/src/util/url.js b/src/util/url.js
new file mode 100644
index 0000000..348cbdd
--- /dev/null
+++ b/src/util/url.js
@@ -0,0 +1,33 @@
+function isHttpProtocol(input) {
+ return new RegExp('^https?\\:?$').test(input)
+}
+
+function isValidHttpUrl(input) {
+ try {
+ const url = new URL(input)
+
+ return isHttpProtocol(url.protocol)
+ } catch (e) {
+ return false
+ }
+}
+
+function parseHttpUrl(input) {
+ if (typeof input !== 'string') {
+ throw new TypeError('input must be a string')
+ }
+
+ const url = new URL(new RegExp('^\\w+\\:\\/\\/').test(input) ? input : `http://${input}`)
+
+ if (!isHttpProtocol(url.protocol)) {
+ throw new TypeError('Provided URL has an invalid protocol')
+ }
+
+ return url.toString()
+}
+
+module.exports = {
+ isHttpProtocol,
+ isValidHttpUrl,
+ parseHttpUrl
+}