diff --git a/auth.js b/auth.js index fafea54..80aed9c 100644 --- a/auth.js +++ b/auth.js @@ -27,6 +27,21 @@ const hasAuth = (regKey, opts) => ( opts[`${regKey}:username`] && opts[`${regKey}:_password`] ) +const sameHost = (a, b) => { + const parsedA = new URL(a) + const parsedB = new URL(b) + return parsedA.host === parsedB.host +} + +const getRegistry = opts => { + const { spec } = opts + const { scope: specScope, subSpec } = spec ? npa(spec) : {} + const subSpecScope = subSpec && subSpec.scope + const scope = subSpec ? subSpecScope : specScope + const scopeReg = scope && opts[`${scope}:registry`] + return scopeReg || opts.registry +} + const getAuth = (uri, opts = {}) => { const { forceAuth } = opts if (!uri) @@ -44,19 +59,19 @@ const getAuth = (uri, opts = {}) => { }) } - // no auth for this URI - if (!regKey && opts.spec) { - // If making a tarball request to a different base URI than the - // registry where we logged in, but the same auth SHOULD be sent - // to that artifact host, then we track where it was coming in from, - // and warn the user if we get a 4xx error on it. - const { spec } = opts - const { scope: specScope, subSpec } = npa(spec) - const subSpecScope = subSpec && subSpec.scope - const scope = subSpec ? subSpecScope : specScope - const scopeReg = scope && opts[`${scope}:registry`] - const scopeAuthKey = scopeReg && regKeyFromURI(scopeReg, opts) - return new Auth({ scopeAuthKey }) + // no auth for this URI, but might have it for the registry + if (!regKey) { + const registry = getRegistry(opts) + if (registry && uri !== registry && sameHost(uri, registry)) + return getAuth(registry, opts) + else if (registry !== opts.registry) { + // If making a tarball request to a different base URI than the + // registry where we logged in, but the same auth SHOULD be sent + // to that artifact host, then we track where it was coming in from, + // and warn the user if we get a 4xx error on it. + const scopeAuthKey = regKeyFromURI(registry, opts) + return new Auth({ scopeAuthKey }) + } } const { diff --git a/test/auth.js b/test/auth.js index 87f3f8c..a64394e 100644 --- a/test/auth.js +++ b/test/auth.js @@ -428,3 +428,33 @@ t.test('scopeAuthKey tests', t => { t.end() }) + +t.test('registry host matches, path does not, send auth', t => { + const opts = { + '@other-scope:registry': 'https://other-scope-registry.com/other/scope/', + '//other-scope-registry.com/other/scope/:_authToken': 'cafebad', + '@scope:registry': 'https://scope-host.com/scope/host/', + '//scope-host.com/scope/host/:_authToken': 'c0ffee', + registry: 'https://registry.example.com/some/path/', + } + const uri = 'https://scope-host.com/blahblah/bloobloo/foo.tgz' + t.same(getAuth(uri, { ...opts, spec: '@scope/foo' }), { + scopeAuthKey: null, + token: 'c0ffee', + auth: null, + isBasicAuth: false, + }) + t.same(getAuth(uri, { ...opts, spec: '@other-scope/foo' }), { + scopeAuthKey: '//other-scope-registry.com/other/scope/', + token: null, + auth: null, + isBasicAuth: false, + }) + t.same(getAuth(uri, { ...opts, registry: 'https://scope-host.com/scope/host/' }), { + scopeAuthKey: null, + token: 'c0ffee', + auth: null, + isBasicAuth: false, + }) + t.end() +})