Skip to content

Commit

Permalink
Add a test for installing private packages requiring authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
KidkArolis committed Nov 16, 2016
1 parent f54d8b6 commit c9978b7
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 6 deletions.
38 changes: 32 additions & 6 deletions __tests__/__mocks__/request.js
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions __tests__/commands/install.js
Expand Up @@ -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<void> => {
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',
);
});
});
6 changes: 6 additions & 0 deletions __tests__/fixtures/authed-packages/config.js
@@ -0,0 +1,6 @@
module.exports = {
'@types/lodash': {
registry: 'https://registry.yarnpkg.com/',
token: 'abc123'
}
};
8 changes: 8 additions & 0 deletions __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"}
@@ -0,0 +1,2 @@
//registry.yarnpkg.com/:_authToken=abc123
@types:registry=https://registry.yarnpkg.com/
@@ -0,0 +1,5 @@
{
"dependencies": {
"@types/lodash": "4.14.37"
}
}

0 comments on commit c9978b7

Please sign in to comment.