diff --git a/lib/clients.js b/lib/clients.js index a66defe..2d9e7aa 100644 --- a/lib/clients.js +++ b/lib/clients.js @@ -4,17 +4,17 @@ let url = require('url') function insecureURL (uri) { if (uri.protocol === 'https:') return false - // allow localhost, 10.* and 192.* clients for testing - if (uri.host === 'localhost') return false - if (/\.local$/.test(uri.host)) return false - if (uri.host.match(/^(10\.|192\.)/)) return false + // allow non-https localhost, 10.*, 127.*, and 192.* clients for testing + if (/^localhost(?:[:]\d+)?$/.test(uri.host)) return false + if (/\.local(?:[:]\d+)?$/.test(uri.host)) return false + if (uri.host.match(/^(10|127|192)\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:[:]\d+)?$/)) return false return true } function validateURL (uri) { let u = url.parse(uri) if (!u.protocol) throw new Error('Invalid URL') - if (insecureURL(u)) throw new Error('Unsupported callback URL. Clients have to use HTTPS.') + if (insecureURL(u)) throw new Error('Unsupported callback URL. Clients have to use HTTPS for non-local addresses.') return uri } diff --git a/test/clients.js b/test/clients.js index 33fd57f..a57e15c 100644 --- a/test/clients.js +++ b/test/clients.js @@ -8,22 +8,38 @@ describe('clients', () => { describe('secure URLs', () => { [ {uri: 'https://heroku.com'}, + {uri: 'https://heroku.com:8080/foo'}, {uri: 'http://localhost'}, + {uri: 'http://localhost:8080/foo'}, {uri: 'http://foo.local'}, + {uri: 'http://foo.local/foo'}, {uri: 'http://10.0.0.1'}, - {uri: 'http://192.168.0.1'} + {uri: 'http://10.0.0.1:8080/foo'}, + {uri: 'http://127.0.0.1'}, + {uri: 'http://127.0.0.1:8080/foo'}, + {uri: 'http://192.168.0.1'}, + {uri: 'http://192.168.0.1:8080/foo'} ].forEach(test => { - it(test.uri, () => { + it('passes when secure (' + test.uri + ')', () => { clients.validateURL(test.uri) }) }) + }) - it('fails when insecure', () => { - expect(() => clients.validateURL('http://heroku.com'), 'to error', 'Unsupported callback URL. Clients have to use HTTPS.') + describe('insecure URLs', () => { + [ + {uri: 'http://heroku.com'}, + {uri: 'http://10.foo.com'}, + {uri: 'http://127.foo.com'}, + {uri: 'http://192.foo.com'} + ].forEach(test => { + it('fails when insecure (' + test.uri + ')', () => { + expect(() => clients.validateURL(test.uri), 'to error', 'Unsupported callback URL. Clients have to use HTTPS for non-local addresses.') + }) }) + }) - it('fails when invalid', () => { - expect(() => clients.validateURL('foo'), 'to error', 'Invalid URL') - }) + it('fails when invalid', () => { + expect(() => clients.validateURL('foo'), 'to error', 'Invalid URL') }) })