Skip to content

Commit

Permalink
fix: correctly handle nerf-darted env vars
Browse files Browse the repository at this point in the history
fixes npm#64

Preserve them verbatim since:

1. The URI path may be case sensitive
2. The URI may have underscores that should not be dasherized
3. The "_" sub-key prefix should not be dasherized
4. The sub-key should not be downcased (i.e. npm-registry-fetch expects
   `...:_authToken`, not `...:_authtoken`

This will allow you to successfully use env vars to control registry
auth, e.g.

```
env npm_config_//reg.example/UP_CASE/:_authToken=secret npm install
```

Although Windows env variable lookups are case insensitive, key retrieval/
iteration is case preserving, so we can reliably get the originally set key.
  • Loading branch information
jenseng committed Aug 9, 2022
1 parent deb1001 commit 6592c0d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 26 deletions.
14 changes: 5 additions & 9 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,11 @@ class Config {
if (!/^npm_config_/i.test(envKey) || envVal === '') {
continue
}
const key = envKey.slice('npm_config_'.length)
.replace(/(?!^)_/g, '-') // don't replace _ at the start of the key
.toLowerCase()
let key = envKey.slice('npm_config_'.length)
if (!key.startsWith('//')) { // don't normalize nerf-darted keys
key = key.replace(/(?!^)_/g, '-') // don't replace _ at the start of the key
.toLowerCase()
}
conf[key] = envVal
}
this[_loadObject](conf, 'env', 'environment')
Expand Down Expand Up @@ -693,8 +695,6 @@ class Config {
this.delete(`_password`, 'user')
this.delete(`username`, 'user')
}
this.delete(`${nerfed}:-authtoken`, 'user')
this.delete(`${nerfed}:_authtoken`, 'user')
this.delete(`${nerfed}:_authToken`, 'user')
this.delete(`${nerfed}:_auth`, 'user')
this.delete(`${nerfed}:_password`, 'user')
Expand Down Expand Up @@ -734,8 +734,6 @@ class Config {
// send auth if we have it, only to the URIs under the nerf dart.
this.delete(`${nerfed}:always-auth`, 'user')

this.delete(`${nerfed}:-authtoken`, 'user')
this.delete(`${nerfed}:_authtoken`, 'user')
this.delete(`${nerfed}:email`, 'user')
if (certfile && keyfile) {
this.set(`${nerfed}:certfile`, certfile, 'user')
Expand Down Expand Up @@ -783,8 +781,6 @@ class Config {
}

const tokenReg = this.get(`${nerfed}:_authToken`) ||
this.get(`${nerfed}:_authtoken`) ||
this.get(`${nerfed}:-authtoken`) ||
nerfed === nerfDart(this.get('registry')) && this.get('_authToken')

if (tokenReg) {
Expand Down
16 changes: 0 additions & 16 deletions tap-snapshots/test/index.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,6 @@ exports[`test/index.js TAP credentials management nerfed_authToken > other regis
Object {}
`

exports[`test/index.js TAP credentials management nerfed_lcAuthToken > default registry 1`] = `
Object {
"token": "0bad1de4",
}
`

exports[`test/index.js TAP credentials management nerfed_lcAuthToken > default registry after set 1`] = `
Object {
"token": "0bad1de4",
}
`

exports[`test/index.js TAP credentials management nerfed_lcAuthToken > other registry 1`] = `
Object {}
`

exports[`test/index.js TAP credentials management nerfed_mtls > default registry 1`] = `
Object {
"certfile": "/path/to/cert",
Expand Down
36 changes: 35 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,41 @@ loglevel = yolo
'should return true once again now that values is retrieved from defaults')
})

t.test('normalize config env keys', async t => {
const env = {
npm_config_bAr: 'bAr env',
NPM_CONFIG_FOO: 'FOO env',
'npm_config_//reg.example/UP_CASE/:username': 'ME',
'npm_config_//reg.example/UP_CASE/:_password': 'Shhhh!',
'NPM_CONFIG_//reg.example/UP_CASE/:_authToken': 'sEcReT',
}
const config = new Config({
npmPath: `${path}/npm`,
env,
argv,
cwd: `${path}/project`,

shorthands,
definitions,
})

await config.load()

t.strictSame({
bar: config.get('bar'),
foo: config.get('foo'),
'//reg.example/UP_CASE/:username': config.get('//reg.example/UP_CASE/:username'),
'//reg.example/UP_CASE/:_password': config.get('//reg.example/UP_CASE/:_password'),
'//reg.example/UP_CASE/:_authToken': config.get('//reg.example/UP_CASE/:_authToken'),
}, {
bar: 'bAr env',
foo: 'FOO env',
'//reg.example/UP_CASE/:username': 'ME',
'//reg.example/UP_CASE/:_password': 'Shhhh!',
'//reg.example/UP_CASE/:_authToken': 'sEcReT',
})
})

t.test('do not double-load project/user config', async t => {
const env = {
npm_config_foo: 'from-env',
Expand Down Expand Up @@ -615,7 +650,6 @@ t.test('raise error if reading ca file error other than ENOENT', async t => {
t.test('credentials management', async t => {
const fixtures = {
nerfed_authToken: { '.npmrc': '//registry.example/:_authToken = 0bad1de4' },
nerfed_lcAuthToken: { '.npmrc': '//registry.example/:_authtoken = 0bad1de4' },
nerfed_userpass: {
'.npmrc': `//registry.example/:username = hello
//registry.example/:_password = ${Buffer.from('world').toString('base64')}
Expand Down

0 comments on commit 6592c0d

Please sign in to comment.