Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #165 from xemle/honor-npmrc-cafile-property-0.17
Browse files Browse the repository at this point in the history
Honor npmrc cafile property 0.17
  • Loading branch information
guybedford authored Aug 3, 2017
2 parents ed37580 + 5b74504 commit 4a4f117
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 14 deletions.
12 changes: 8 additions & 4 deletions lib/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ function decodeCredentials(str) {
exports.decodeCredentials = decodeCredentials;

// given options for request, add the auth header / option as appropriate
function injectRequestOptions(requestOptions, auth) {
if (!auth)
return requestOptions;
function injectRequestOptions(requestOptions, registryInfo) {
registryInfo = registryInfo || {};
var auth = registryInfo.auth || {};
if (auth.username)
requestOptions.auth = {
user: auth.username,
Expand All @@ -30,6 +30,10 @@ function injectRequestOptions(requestOptions, auth) {
requestOptions.headers = requestOptions.headers || {};
requestOptions.headers.authorization = 'Bearer ' + auth.token;
}
if (registryInfo.ca)
requestOptions.agentOptions = {
ca: registryInfo.ca
};
return requestOptions;
}
exports.injectRequestOptions = injectRequestOptions;
Expand Down Expand Up @@ -84,7 +88,7 @@ function configureCredentials(registry, _auth, ui) {
.then(function() {
return asp(request)(injectRequestOptions({
uri: registry
}, _auth));
}, {auth: _auth}));
})
.then(function(res) {
if (res.statusCode == 401)
Expand Down
9 changes: 6 additions & 3 deletions lib/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ var NPMLocation = function(options, ui) {
// only alwaysAuth when the registryURL is not the defaultRegistry
// otherwise we just auth for scopes
var authData;
var ca;
if (this.registryURL() != defaultRegistry || scope) {
authData = scope && npmrc.getAuth(url);
ca = npmrc.getCa();

if (!authData) {
if (options.authToken)
Expand All @@ -93,7 +95,8 @@ var NPMLocation = function(options, ui) {

return {
url: url,
auth: authData
auth: authData,
ca: ca
};
}
};
Expand Down Expand Up @@ -193,7 +196,7 @@ NPMLocation.prototype = {
headers: lookupCache ? {
'if-none-match': lookupCache.eTag
} : {}
}, registryInfo.auth)).then(function(res) {
}, registryInfo)).then(function(res) {
if (res.statusCode == 304)
return { versions: lookupCache.versions,
latest: lookupCache.latest };
Expand Down Expand Up @@ -363,7 +366,7 @@ NPMLocation.prototype = {
uri: tarball,
headers: { 'accept': 'application/octet-stream' },
strictSSL: self.strictSSL
}, registryInfo.auth))
}, registryInfo))
.on('response', function(npmRes) {

if (npmRes.statusCode != 200)
Expand Down
12 changes: 12 additions & 0 deletions lib/npmrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ Npmrc.prototype.getAuth = function(registry) {
};
};

Npmrc.prototype.getCa = function(registry) {
if (!registry)
registry = this.getRegistry();

if (!this.initialized)
this.init();

var cafile = getOption(this.contents, 'cafile', registry);
if (cafile)
return fs.readFileSync(cafile);
};

Npmrc.prototype.getRegistry = function(scope) {
if (!this.initialized)
this.init();
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"homepage": "https://github.com/jspm/npm",
"devDependencies": {
"istanbul": "0.3.21",
"mocha": "2.3.3",
"unexpected": "9.16.0",
"unexpected-mitm": "7.7.3"
"mocha": "^3.4.2",
"unexpected": "^10.29.0",
"unexpected-mitm": "^10.0.0"
}
}
24 changes: 20 additions & 4 deletions test/auth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ describe('lib/auth', function () {
});
it('should inject BasicAuth options into request options', function () {
requestOptions = auth.injectRequestOptions(requestOptions, {
username: 'foo',
password: 'bar'
auth: {
username: 'foo',
password: 'bar'
}
})
return expect(requestOptions, 'to satisfy', {
auth: {
Expand All @@ -110,7 +112,9 @@ describe('lib/auth', function () {
});
it('should inject auth tokens into request options', function () {
requestOptions = auth.injectRequestOptions(requestOptions, {
token: 'foobar'
auth: {
token: 'foobar'
}
})
return expect(requestOptions, 'to satisfy', {
headers: {
Expand All @@ -123,7 +127,9 @@ describe('lib/auth', function () {
'X-Custom-Header': 'helloworld'
};
requestOptions = auth.injectRequestOptions(requestOptions, {
token: 'foobar'
auth: {
token: 'foobar'
}
})
return expect(requestOptions, 'to satisfy', {
headers: {
Expand All @@ -132,6 +138,16 @@ describe('lib/auth', function () {
}
});
});
it('should inject certificate options into request options', function () {
requestOptions = auth.injectRequestOptions(requestOptions, {
ca: '-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----'
})
return expect(requestOptions, 'to satisfy', {
agentOptions: {
ca: '-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----'
}
});
});
});
describe('configureCredentials', function () {
it('token based authentication chosen', function () {
Expand Down
1 change: 1 addition & 0 deletions test/mocha.opts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
--reporter spec
test/auth.spec.js
test/npmrc.spec.js
80 changes: 80 additions & 0 deletions test/npmrc.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
var expect = require('unexpected')
.clone()
.use(require('unexpected-mitm'));
var Npmrc = require('../lib/npmrc');
var fs = require('fs');
var path = require('path');


function extend(a, b) {
for (var p in b)
a[p] = b[p];
return a;
}

function FileMock(path) {
this.path = path;
};

FileMock.prototype.write = function(content) {
fs.writeFileSync(this.path, content);
return this;
};

FileMock.prototype.unlink = function() {
fs.unlinkSync(this.path);
};

describe('lib/npmrc', function () {

describe('getCa()', function () {
var _jspmConfigPath;
var npmrc;

beforeEach(function() {
_jspmConfigPath = process.env.jspmConfigPath;
npmrc = new Npmrc();
});

afterEach(function() {
if (_jspmConfigPath)
process.env.jspmConfigPath = _jspmConfigPath;
});

it('should honor cafile property', function () {
var npmrcFile;
var caFile;
var ca;

delete process.env.jspmConfigPath;
caFile = new FileMock(path.resolve(process.cwd(), 'ca.crt'))
.write('ca certificate');
npmrcFile = new FileMock(path.resolve(process.cwd(), '.npmrc'))
.write('cafile=' + caFile.path);


var ca = npmrc.getCa();


caFile.unlink();
npmrcFile.unlink();
return expect(ca, 'when decoded as', 'utf-8', 'to equal', 'ca certificate');
});

it('should have empty ca', function () {
var npmrcFile;
var ca;

delete process.env.jspmConfigPath;
npmrcFile = new FileMock(path.resolve(process.cwd(), '.npmrc'))
.write('# empty config');


var ca = npmrc.getCa();


npmrcFile.unlink();
return expect(ca, 'to be undefined');
});
});
});

0 comments on commit 4a4f117

Please sign in to comment.