From b9db67546873f40b981947006fcca56b0931bf8c Mon Sep 17 00:00:00 2001 From: Ian Taylor Date: Mon, 30 Jan 2017 16:16:37 -0800 Subject: [PATCH] Fix registry auth comparison when registry urls and request urls have explicit vs implied port numbers --- .../registries/is-request-to-registry.js | 46 +++++++++++++++++++ src/registries/is-request-to-registry.js | 28 +++++++++++ src/registries/npm-registry.js | 3 +- 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 __tests__/registries/is-request-to-registry.js create mode 100644 src/registries/is-request-to-registry.js diff --git a/__tests__/registries/is-request-to-registry.js b/__tests__/registries/is-request-to-registry.js new file mode 100644 index 0000000000..dd4e92de1d --- /dev/null +++ b/__tests__/registries/is-request-to-registry.js @@ -0,0 +1,46 @@ +/* @flow */ +/* eslint yarn-internal/warn-language: 0 */ + +import isRequestToRegistry from '../../src/registries/is-request-to-registry.js'; + +test('isRequestToRegistry functional test', () => { + expect(isRequestToRegistry( + 'http://foo.bar:80/foo/bar/baz', + 'http://foo.bar/foo/', + )).toBe(true); + + expect(isRequestToRegistry( + 'http://foo.bar/foo/bar/baz', + 'http://foo.bar/foo/', + )).toBe(true); + + expect(isRequestToRegistry( + 'https://foo.bar:443/foo/bar/baz', + 'https://foo.bar/foo/', + )).toBe(true); + + expect(isRequestToRegistry( + 'https://foo.bar/foo/bar/baz', + 'https://foo.bar:443/foo/', + )).toBe(true); + + expect(isRequestToRegistry( + 'http://foo.bar:80/foo/bar/baz', + 'https://foo.bar/foo/', + )).toBe(false); + + expect(isRequestToRegistry( + 'http://foo.bar/blah/whatever/something', + 'http://foo.bar/foo/', + )).toBe(false); + + expect(isRequestToRegistry( + 'https://wrong.thing/foo/bar/baz', + 'https://foo.bar/foo/', + )).toBe(false); + + expect(isRequestToRegistry( + 'https://foo.bar:1337/foo/bar/baz', + 'https://foo.bar/foo/', + )).toBe(false); +}); diff --git a/src/registries/is-request-to-registry.js b/src/registries/is-request-to-registry.js new file mode 100644 index 0000000000..c6748bada4 --- /dev/null +++ b/src/registries/is-request-to-registry.js @@ -0,0 +1,28 @@ +/* @flow */ + +import url from 'url'; + +export default function isRequestToRegistry(requestUrl: string, registry: string): boolean { + const requestParsed = url.parse(requestUrl); + const registryParsed = url.parse(registry); + const requestPort = getPortOrDefaultPort(requestParsed.port, requestParsed.protocol); + const registryPort = getPortOrDefaultPort(registryParsed.port, registryParsed.protocol); + const requestPath = requestParsed.path || ''; + const registryPath = registryParsed.path || ''; + + return (requestParsed.protocol === registryParsed.protocol) && + (requestParsed.hostname === registryParsed.hostname) && + (requestPort === registryPort) && + requestPath.startsWith(registryPath); +} + +function getPortOrDefaultPort(port: ?string, protocol: ?string): ?string { + const defaultPort = !port; + if (defaultPort && protocol === 'https:') { + return '443'; + } + if (defaultPort && protocol === 'http:') { + return '80'; + } + return port; +} diff --git a/src/registries/npm-registry.js b/src/registries/npm-registry.js index 16c213c49b..8c182ce039 100644 --- a/src/registries/npm-registry.js +++ b/src/registries/npm-registry.js @@ -9,6 +9,7 @@ import NpmResolver from '../resolvers/registries/npm-resolver.js'; import envReplace from '../util/env-replace.js'; import Registry from './base-registry.js'; import {addSuffix, removePrefix} from '../util/misc'; +import isRequestToRegistry from './is-request-to-registry.js'; const defaults = require('defaults'); const userHome = require('user-home'); @@ -58,7 +59,7 @@ export default class NpmRegistry extends Registry { || removePrefix(requestUrl, registry)[0] === '@'; const headers = {}; - if (this.token || (alwaysAuth && requestUrl.startsWith(registry))) { + if (this.token || (alwaysAuth && isRequestToRegistry(requestUrl, registry))) { const authorization = this.getAuth(pathname); if (authorization) { headers.authorization = authorization;