Install from private repo fails using cafile and strict-ssl when encountering repository dependency

(Christoph Werner) #1

What I Wanted to Do

I wanted to configure a project via .npmrc so it installs dependencies from a private repository instead of the public npm registry.

In order to do so, i added a few lines of configuration to my .npmrc:

_auth = *********
registry = https://internal/artifactory/api/npm/npm/
cafile = /path/to/cert-path.pem
always-auth = true
strict-ssl = true

The private artifactory instance has an npm feed/repository, which is available at https://internal/artifactory/api/npm/npm/. It also has an SSL certificate provided by GlobalSign. In order to get strict-ssl = true working, i had to export all certificates on the certification path up to the GlobalSign CA root certificate as .pem files, concatenate them to a single file the order from leaf to root and use that as the cafile.

Now, when running npm install without any repository dependencies in my dependency tree, everything is splendid. However, once npm install encounters a repository dependency, things break.

What Happened Instead

When encountering a repository dependency in the dependency tree, npm install fails.

In our case, from the lint-staged@8.0.4 dependencies is the culprit. When running npm i with this in the dependency tree, install fails:

npm ERR! request to failed, reason: unable to get local issuer certificate

logfile shows this:

7093 verbose stack FetchError: request to failed, reason: unable to get local issuer certificate
7093 verbose stack     at ClientRequest.req.on.err (/usr/lib/node_modules/npm/node_modules/node-fetch-npm/src/index.js:68:14)
7093 verbose stack     at ClientRequest.emit (events.js:182:13)
7093 verbose stack     at TLSSocket.socketErrorListener (_http_client.js:382:9)
7093 verbose stack     at TLSSocket.emit (events.js:182:13)
7093 verbose stack     at emitErrorNT (internal/streams/destroy.js:82:8)
7093 verbose stack     at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
7093 verbose stack     at process._tickCallback (internal/process/next_tick.js:63:19)
7094 verbose cwd /path/to/website
7095 verbose Linux 4.4.0-43-Microsoft
7096 verbose argv "/usr/bin/node" "/usr/bin/npm" "i"
7097 verbose node v10.2.1
7098 verbose npm  v6.2.0
7101 error request to failed, reason: unable to get local issuer certificate
7102 verbose exit [ 1, true ]

Reproduction Steps

Have a private feed, point npm to it via .npmrc, set strict-ssl to true, provide the certificate chain as cafile, run npm i with repository dependencies (in our case: from GitHub) in the dependency tree.

Platform Info

$ npm --versions
{ 'paderbornjs-website': '1.0.0',
  npm: '6.2.0',
  ares: '1.14.0',
  cldr: '33.0',
  http_parser: '2.8.0',
  icu: '61.1',
  modules: '64',
  napi: '3',
  nghttp2: '1.29.0',
  node: '10.2.1',
  openssl: '1.1.0h',
  tz: '2018c',
  unicode: '10.0',
  uv: '1.20.3',
  v8: '6.6.346.32-node.8',
  zlib: '1.2.11' }
$ node -p process.platform