diff --git a/cli/init.js b/cli/init.js index ac9399106..02487309a 100644 --- a/cli/init.js +++ b/cli/init.js @@ -13,7 +13,7 @@ module.exports = (args) => { const dir = path.resolve(root, project); return fs.readdir(root).then(files => { - if (!files.includes(project)) { + if (files.indexOf(project) === -1) { throw new Error(`${project} is an invalid template name`); } diff --git a/lib/relay.js b/lib/relay.js index 785f21c77..0dab653ea 100644 --- a/lib/relay.js +++ b/lib/relay.js @@ -79,13 +79,22 @@ function responseHandler(filterRules, config) { const parsed = parse(result); const auth = parsed.auth; - // put the token in the authorization header instead of on the URL - // if it's there. - if (auth && !auth.includes(':')) { - headers.authorization = `token ${auth}`; - // then strip from the url - delete parsed.auth; - result = format(parsed); + if (auth) { + // if URL contains basic auth, + // remove authorization header to prefer auth on the URL. + if (auth.includes(':')) { + delete headers.authorization; + } + + // if URL contains token auth, + // put the token in the authorization header + // instead of on the URL. + else { + headers.authorization = `token ${auth}`; + // then strip from the url + delete parsed.auth; + result = format(parsed); + } } // if the request is all good - and at this point it is, we'll check diff --git a/package.json b/package.json index c2ef40008..4ee2cfe03 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "start": "node lib", "dev": "node lib | ./node_modules/.bin/bunyan", "es5ify": "babel --ignore=node_modules . -d .", - "test": "CI=1 tap -R spec test/**/*.test.js --timeout 60 2>&1 | ./node_modules/.bin/bunyan", + "test": "CI=1 tap -R spec test/**/*.test.js --timeout 60", "lint": "eslint cli/*.js lib/**/*.js", "check-tests": "! grep 'test.only' test/**/*.test.js -n", "cover": "tap test/**/*.test.js --timeout 60 --cov --coverage-report=lcov", diff --git a/test/fixtures/client/filters-https.json b/test/fixtures/client/filters-https.json index f8e79e254..ed5982890 100644 --- a/test/fixtures/client/filters-https.json +++ b/test/fixtures/client/filters-https.json @@ -25,6 +25,18 @@ ] }, + { + "path": "/echo-headers/github", + "method": "POST", + "origin": "http://githubToken@localhost:${originPort}" + }, + + { + "path": "/echo-headers/bitbucket", + "method": "POST", + "origin": "http://bitbucketUser:bitbucketPassword@localhost:${originPort}" + }, + { "path": "/echo-headers", "method": "POST", diff --git a/test/fixtures/client/filters.json b/test/fixtures/client/filters.json index ce063297a..b503e8971 100644 --- a/test/fixtures/client/filters.json +++ b/test/fixtures/client/filters.json @@ -25,6 +25,18 @@ ] }, + { + "path": "/echo-headers/github", + "method": "POST", + "origin": "http://githubToken@localhost:${originPort}" + }, + + { + "path": "/echo-headers/bitbucket", + "method": "POST", + "origin": "http://bitbucketUser:bitbucketPassword@localhost:${originPort}" + }, + { "path": "/echo-headers", "method": "POST", diff --git a/test/fixtures/server/filters.json b/test/fixtures/server/filters.json index bbb064067..90eeddf78 100644 --- a/test/fixtures/server/filters.json +++ b/test/fixtures/server/filters.json @@ -13,7 +13,7 @@ }, { - "path": "/echo-headers", + "path": "/echo-headers/:param?", "method": "POST", "origin": "http://localhost:${originPort}" }, diff --git a/test/functional/server-client.test.js b/test/functional/server-client.test.js index 9bdff9fc0..a963b26c3 100644 --- a/test/functional/server-client.test.js +++ b/test/functional/server-client.test.js @@ -35,7 +35,7 @@ test('proxy requests originating from behind the broker server', t => { // wait for the client to successfully connect to the server and identify itself server.io.on('connection', socket => { socket.on('identify', token => { - t.plan(12); + t.plan(16); t.test('successfully broker POST', t => { const url = `http://localhost:${serverPort}/broker/${token}/echo-body`; @@ -176,8 +176,34 @@ test('proxy requests originating from behind the broker server', t => { t.test('content-length is set without chunked http', t => { const url = `http://localhost:${serverPort}/broker/${token}/echo-headers`; - request({ url, method: 'get' }, (err, res) => { - t.ok(res.headers['Content-Length'], 'found content-length header'); + request({ url, method: 'post'}, (err, res) => { + t.ok(res.headers['content-length'], 'found content-length header'); + t.end(); + }); + }); + + t.test('auth header is replaced when url contains token', t => { + const url = `http://localhost:${serverPort}/broker/${token}/echo-headers/github`; + const headers = {Authorization: 'broker auth'}; + request({ url, method: 'post', headers }, (err, res) => { + const responseBody = JSON.parse(res.body); + t.equal(res.statusCode, 200, '200 statusCode'); + t.equal(responseBody.authorization, 'token githubToken', + 'auth header was replaced by github token'); + t.end(); + }); + }); + + t.test('auth header is is replaced when url contains basic auth', t => { + const url = `http://localhost:${serverPort}/broker/${token}/echo-headers/bitbucket`; + const headers = {}; + request({ url, method: 'post', headers }, (err, res) => { + const responseBody = JSON.parse(res.body); + t.equal(res.statusCode, 200, '200 statusCode'); + const auth = responseBody.authorization.replace('Basic ', ''); + const encodedAuth = Buffer.from(auth, 'base64').toString('utf-8'); + t.equal(encodedAuth, 'bitbucketUser:bitbucketPassword', + 'auth header is set correctly'); t.end(); }); }); diff --git a/test/utils.js b/test/utils.js index 7dab78ce0..f1c2db927 100644 --- a/test/utils.js +++ b/test/utils.js @@ -26,7 +26,7 @@ echoServer.post('/echo-body/:param?', (req, res) => { res.send(req.body); }); -echoServer.post('/echo-headers', (req, res) => { +echoServer.post('/echo-headers/:param?', (req, res) => { res.json(req.headers); });