diff --git a/__tests__/__mocks__/request.js b/__tests__/__mocks__/request.js index 7acf72febc..fcb75d5bc3 100644 --- a/__tests__/__mocks__/request.js +++ b/__tests__/__mocks__/request.js @@ -15,6 +15,9 @@ const fs = require('fs'); const CACHE_DIR = path.join(__dirname, '..', 'fixtures', 'request-cache'); +const authedPackages = require('../fixtures/authed-packages/config'); +const UNAUTHORIZED_LOC = path.join(__dirname, '..', 'fixtures', 'authed-packages', 'unauthorized.bin'); + function getRequestAlias(params: Object): string { const parts = url.parse(params.path); const pathname = cleanAlias(parts.pathname); @@ -32,6 +35,22 @@ function cleanAlias(str: string): string { .replace(/-+$/, ''); // remove trailing dashes } +function getAuthInfo(path: string): ?{token: string, registry: string} { + path = decodeURIComponent(path); + const pkgs = Object.keys(authedPackages); + const match = pkgs.find((pkgName) => path.endsWith(pkgName) || path.includes(pkgName + '/')); + return match ? authedPackages[match] : null; +} + +function requestFile(path: string, httpModule: Object, options: Object, callback?: ?Function): ClientRequest { + options.agent = null; + options.socketPath = null; + options.createConnection = (): ReadStream => { + return fs.createReadStream(path); + }; + return httpModule.request(options, callback); +} + class Request extends RealRequest { init(params: Object) { RealRequest.prototype.init.call(this, params); @@ -55,14 +74,21 @@ const httpMock = { // TODO better way to do this const httpModule = options.uri.href.startsWith('https:') ? https : http; + const {token, registry} = getAuthInfo(options.uri.path) || {}; + if (token && registry) { + if (!options.uri.href.startsWith(registry)) { + // request is being made to the wrong registry, token gets disclosed + throw new Error(`Wrong registry, expected ${registry} to be used.`); + } + if ((options.headers.authorization || '').split('Bearer ')[1] !== token) { + // token missing + return requestFile(UNAUTHORIZED_LOC, httpModule, options, callback); + } + } + if (allowCache && fs.existsSync(loc)) { // cached - options.agent = null; - options.socketPath = null; - options.createConnection = (): ReadStream => { - return fs.createReadStream(loc); - }; - return httpModule.request(options, callback); + return requestFile(loc, httpModule, options, callback); } else { // not cached const req = httpModule.request(options, callback); diff --git a/__tests__/commands/install.js b/__tests__/commands/install.js index 246021a166..4cf4302b1d 100644 --- a/__tests__/commands/install.js +++ b/__tests__/commands/install.js @@ -692,3 +692,12 @@ test.concurrent('lockfile should be created when missing even if integrity match expect(await fs.exists(path.join(config.cwd, 'yarn.lock'))); }); }); + +test.concurrent('install from authed private registry', (): Promise => { + return runInstall({noLockfile: true}, 'install-from-authed-private-registry', async (config) => { + assert.equal( + (await fs.readFile(path.join(config.cwd, 'node_modules', '@types', 'lodash', 'index.d.ts'))).split('\n')[0], + '// Type definitions for Lo-Dash 4.14', + ); + }); +}); diff --git a/__tests__/fixtures/authed-packages/config.js b/__tests__/fixtures/authed-packages/config.js new file mode 100644 index 0000000000..48af3f970c --- /dev/null +++ b/__tests__/fixtures/authed-packages/config.js @@ -0,0 +1,6 @@ +module.exports = { + '@types/lodash': { + registry: 'https://registry.yarnpkg.com/', + token: 'abc123' + } +}; diff --git a/__tests__/fixtures/authed-packages/unauthorized.bin b/__tests__/fixtures/authed-packages/unauthorized.bin new file mode 100644 index 0000000000..c632e9cfe3 --- /dev/null +++ b/__tests__/fixtures/authed-packages/unauthorized.bin @@ -0,0 +1,8 @@ +HTTP/1.1 401 OK +Date: Fri, 14 Oct 2016 21:05:22 GMT +Content-Type: application/json +Transfer-Encoding: chunked +Connection: keep-alive + +49 +{"error":"unauthorized","reason":"token missing"} diff --git a/__tests__/fixtures/install/install-from-authed-private-registry/.npmrc b/__tests__/fixtures/install/install-from-authed-private-registry/.npmrc new file mode 100644 index 0000000000..c86299f566 --- /dev/null +++ b/__tests__/fixtures/install/install-from-authed-private-registry/.npmrc @@ -0,0 +1,2 @@ +//registry.yarnpkg.com/:_authToken=abc123 +@types:registry=https://registry.yarnpkg.com/ diff --git a/__tests__/fixtures/install/install-from-authed-private-registry/package.json b/__tests__/fixtures/install/install-from-authed-private-registry/package.json new file mode 100644 index 0000000000..a02c5b41b4 --- /dev/null +++ b/__tests__/fixtures/install/install-from-authed-private-registry/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@types/lodash": "4.14.37" + } +}