diff --git a/.all-contributorsrc b/.all-contributorsrc index e437ad7..efc7524 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -381,6 +381,16 @@ "code" ] }, + { + "login": "tylerkrupicka", + "name": "Tyler Krupicka", + "avatar_url": "https://avatars1.githubusercontent.com/u/5761061?s=460&v=4", + "profile": "https://github.com/tylerkrupicka", + "contributions": [ + "code", + "test" + ] + }, { "login": "smoia", "name": "Stefano Moia", diff --git a/README.md b/README.md index fbec6fb..1fe5261 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ -- [ all-contributors-cli ](#all-contributors-cli) - - [The problem](#the-problem) - - [This solution](#this-solution) - - [Using the all-contributors-cli](#using-the-all-contributors-cli) - - [Contributors ✨](#contributors-) - - [LICENSE](#license) +- [The problem](#the-problem) +- [This solution](#this-solution) +- [Using the all-contributors-cli](#using-the-all-contributors-cli) +- [Contributors ✨](#contributors-%e2%9c%a8) +- [LICENSE](#license) @@ -130,6 +129,7 @@ Thanks goes to these wonderful people
Fabrizio

🐛 💻
Marcelo Alves

💻
Nicolas Goutay

💻 +
Tyler Krupicka

💻 ⚠️
Stefano Moia

💻 diff --git a/src/repo/__tests__/github.js b/src/repo/__tests__/github.js index e43bf62..52a1592 100644 --- a/src/repo/__tests__/github.js +++ b/src/repo/__tests__/github.js @@ -85,6 +85,21 @@ test('Throw error when non existent username is provided', async () => { ) }) +test('Throw error when missing enterprise authentication', async () => { + const username = 'notauthenticated' + nock('http://github.myhost.com:3000/api/v3') + .get(`/users/${username}`) + .reply(401, { + message: 'Must authenticate to access this API.', + documentation_url: 'https://developer.github.com/enterprise/2.17/v3', + }) + await expect( + getUserInfo(username, 'http://github.myhost.com:3000'), + ).rejects.toThrow( + `Missing authentication for GitHub API. Did you set PRIVATE_TOKEN?`, + ) +}) + test('handle github errors', async () => { nock('https://api.github.com') .get('/users/nodisplayname') @@ -174,7 +189,7 @@ test('append http when no absolute link is provided', async () => { }) test('retrieve user from a different github registry', async () => { - nock('http://api.github.myhost.com:3000') + nock('http://github.myhost.com:3000/api/v3') .get('/users/nodisplayname') .reply(200, { login: 'nodisplayname', diff --git a/src/repo/github.js b/src/repo/github.js index b306965..6cb8272 100644 --- a/src/repo/github.js +++ b/src/repo/github.js @@ -1,6 +1,27 @@ +const url = require('url') const pify = require('pify') const request = pify(require('request')) +/** + * Get the host based on public or enterprise GitHub. + * https://developer.github.com/enterprise/2.17/v3/#current-version + * + * @param {String} hostname - Hostname from config. + * @returns {String} - Host for GitHub API. + */ +function getApiHost(hostname) { + if (!hostname) { + hostname = 'https://github.com' + } + + if (hostname !== 'https://github.com') { + // Assume Github Enterprise + return url.resolve(hostname, '/api/v3') + } + + return hostname.replace(/:\/\//, '://api.') +} + function getRequestHeaders(optionalPrivateToken = '') { const requestHeaders = { 'User-Agent': 'request', @@ -27,10 +48,10 @@ function getNextLink(link) { return nextLink.split(';')[0].slice(1, -1) } -function getContributorsPage(url, optionalPrivateToken) { +function getContributorsPage(githubUrl, optionalPrivateToken) { return request .get({ - url, + url: githubUrl, headers: getRequestHeaders(optionalPrivateToken), }) .then(res => { @@ -55,18 +76,13 @@ function getContributorsPage(url, optionalPrivateToken) { } const getUserInfo = function(username, hostname, optionalPrivateToken) { - /* eslint-disable complexity */ - if (!hostname) { - hostname = 'https://github.com' - } - if (!username) { throw new Error( `No login when adding a contributor. Please specify a username.`, ) } - const root = hostname.replace(/:\/\//, '://api.') + const root = getApiHost(hostname) return request .get({ url: `${root}/users/${username}`, @@ -77,6 +93,16 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) { let profile = body.blog || body.html_url + // Check for authentication required + if ( + (!profile && body.message.includes('Must authenticate')) || + res.statusCode === 401 + ) { + throw new Error( + `Missing authentication for GitHub API. Did you set PRIVATE_TOKEN?`, + ) + } + // Github throwing specific errors as 200... if (!profile && body.message) { throw new Error( @@ -96,13 +122,9 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) { } const getContributors = function(owner, name, hostname, optionalPrivateToken) { - if (!hostname) { - hostname = 'https://github.com' - } - - const root = hostname.replace(/:\/\//, '://api.') - const url = `${root}/repos/${owner}/${name}/contributors?per_page=100` - return getContributorsPage(url, optionalPrivateToken) + const root = getApiHost(hostname) + const contributorsUrl = `${root}/repos/${owner}/${name}/contributors?per_page=100` + return getContributorsPage(contributorsUrl, optionalPrivateToken) } module.exports = {