Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

Commit

Permalink
feat: detect registry-scoped certfile and keyfile options (#69)
Browse files Browse the repository at this point in the history
RFC: npm/rfcs#591

See also: npm/npm-registry-fetch#125

By itself this change doesn't do much, but it enables us to resolve
npm/cli#4765 and surface these options anywhere
else they may be needed.
  • Loading branch information
jenseng authored Jul 18, 2022
1 parent 98eb307 commit e58a4f1
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
19 changes: 17 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -698,9 +698,11 @@ class Config {
this.delete(`${nerfed}:_password`, 'user')
this.delete(`${nerfed}:username`, 'user')
this.delete(`${nerfed}:email`, 'user')
this.delete(`${nerfed}:certfile`, 'user')
this.delete(`${nerfed}:keyfile`, 'user')
}

setCredentialsByURI (uri, { token, username, password, email }) {
setCredentialsByURI (uri, { token, username, password, email, certfile, keyfile }) {
const nerfed = nerfDart(uri)
const def = nerfDart(this.get('registry'))

Expand Down Expand Up @@ -733,6 +735,11 @@ class Config {
this.delete(`${nerfed}:-authtoken`, 'user')
this.delete(`${nerfed}:_authtoken`, 'user')
this.delete(`${nerfed}:email`, 'user')
if (certfile && keyfile) {
this.set(`${nerfed}:certfile`, certfile, 'user')
this.set(`${nerfed}:keyfile`, keyfile, 'user')
// cert/key may be used in conjunction with other credentials, thus no `else`
}
if (token) {
this.set(`${nerfed}:_authToken`, token, 'user')
this.delete(`${nerfed}:_password`, 'user')
Expand All @@ -750,7 +757,7 @@ class Config {
// protects against shoulder-hacks if password is memorable, I guess?
const encoded = Buffer.from(password, 'utf8').toString('base64')
this.set(`${nerfed}:_password`, encoded, 'user')
} else {
} else if (!certfile || !keyfile) {
throw new Error('No credentials to set.')
}
}
Expand All @@ -765,6 +772,14 @@ class Config {
creds.email = email
}

const certfileReg = this.get(`${nerfed}:certfile`)
const keyfileReg = this.get(`${nerfed}:keyfile`)
if (certfileReg && keyfileReg) {
creds.certfile = certfileReg
creds.keyfile = keyfileReg
// cert/key may be used in conjunction with other credentials, thus no `return`
}

const tokenReg = this.get(`${nerfed}:_authToken`) ||
this.get(`${nerfed}:_authtoken`) ||
this.get(`${nerfed}:-authtoken`) ||
Expand Down
66 changes: 66 additions & 0 deletions tap-snapshots/test/index.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,72 @@ exports[`test/index.js TAP credentials management nerfed_lcAuthToken > other reg
Object {}
`

exports[`test/index.js TAP credentials management nerfed_mtls > default registry 1`] = `
Object {
"certfile": "/path/to/cert",
"keyfile": "/path/to/key",
}
`

exports[`test/index.js TAP credentials management nerfed_mtls > default registry after set 1`] = `
Object {
"certfile": "/path/to/cert",
"keyfile": "/path/to/key",
}
`

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

exports[`test/index.js TAP credentials management nerfed_mtlsAuthToken > default registry 1`] = `
Object {
"certfile": "/path/to/cert",
"keyfile": "/path/to/key",
"token": "0bad1de4",
}
`

exports[`test/index.js TAP credentials management nerfed_mtlsAuthToken > default registry after set 1`] = `
Object {
"certfile": "/path/to/cert",
"keyfile": "/path/to/key",
"token": "0bad1de4",
}
`

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

exports[`test/index.js TAP credentials management nerfed_mtlsUserPass > default registry 1`] = `
Object {
"auth": "aGVsbG86d29ybGQ=",
"certfile": "/path/to/cert",
"email": "[email protected]",
"keyfile": "/path/to/key",
"password": "world",
"username": "hello",
}
`

exports[`test/index.js TAP credentials management nerfed_mtlsUserPass > default registry after set 1`] = `
Object {
"auth": "aGVsbG86d29ybGQ=",
"certfile": "/path/to/cert",
"email": "[email protected]",
"keyfile": "/path/to/key",
"password": "world",
"username": "hello",
}
`

exports[`test/index.js TAP credentials management nerfed_mtlsUserPass > other registry 1`] = `
Object {
"email": "[email protected]",
}
`

exports[`test/index.js TAP credentials management nerfed_userpass > default registry 1`] = `
Object {
"auth": "aGVsbG86d29ybGQ=",
Expand Down
18 changes: 16 additions & 2 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,20 @@ t.test('credentials management', async t => {
nerfed_auth: { // note: does not load, because we don't do _auth per reg
'.npmrc': `//registry.example/:_auth = ${Buffer.from('hello:world').toString('base64')}`,
},
nerfed_mtls: { '.npmrc': `//registry.example/:certfile = /path/to/cert
//registry.example/:keyfile = /path/to/key`,
},
nerfed_mtlsAuthToken: { '.npmrc': `//registry.example/:_authToken = 0bad1de4
//registry.example/:certfile = /path/to/cert
//registry.example/:keyfile = /path/to/key`,
},
nerfed_mtlsUserPass: { '.npmrc': `//registry.example/:username = hello
//registry.example/:_password = ${Buffer.from('world').toString('base64')}
//registry.example/:email = [email protected]
//registry.example/:always-auth = "false"
//registry.example/:certfile = /path/to/cert
//registry.example/:keyfile = /path/to/key`,
},
def_userpass: {
'.npmrc': `username = hello
_password = ${Buffer.from('world').toString('base64')}
Expand Down Expand Up @@ -712,14 +726,14 @@ always-auth = true`,
}

// need both or none of user/pass
if (!d.token && (!d.username || !d.password)) {
if (!d.token && (!d.username || !d.password) && (!d.certfile || !d.keyfile)) {
t.throws(() => c.setCredentialsByURI(defReg, d))
} else {
c.setCredentialsByURI(defReg, d)
t.matchSnapshot(c.getCredentialsByURI(defReg), 'default registry after set')
}

if (!o.token && (!o.username || !o.password)) {
if (!o.token && (!o.username || !o.password) && (!o.certfile || !o.keyfile)) {
t.throws(() => c.setCredentialsByURI(otherReg, o), {}, { otherReg, o })
} else {
c.setCredentialsByURI(otherReg, o)
Expand Down

0 comments on commit e58a4f1

Please sign in to comment.