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

Commit e58a4f1

Browse files
authored
feat: detect registry-scoped certfile and keyfile options (#69)
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.
1 parent 98eb307 commit e58a4f1

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

lib/index.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,9 +698,11 @@ class Config {
698698
this.delete(`${nerfed}:_password`, 'user')
699699
this.delete(`${nerfed}:username`, 'user')
700700
this.delete(`${nerfed}:email`, 'user')
701+
this.delete(`${nerfed}:certfile`, 'user')
702+
this.delete(`${nerfed}:keyfile`, 'user')
701703
}
702704

703-
setCredentialsByURI (uri, { token, username, password, email }) {
705+
setCredentialsByURI (uri, { token, username, password, email, certfile, keyfile }) {
704706
const nerfed = nerfDart(uri)
705707
const def = nerfDart(this.get('registry'))
706708

@@ -733,6 +735,11 @@ class Config {
733735
this.delete(`${nerfed}:-authtoken`, 'user')
734736
this.delete(`${nerfed}:_authtoken`, 'user')
735737
this.delete(`${nerfed}:email`, 'user')
738+
if (certfile && keyfile) {
739+
this.set(`${nerfed}:certfile`, certfile, 'user')
740+
this.set(`${nerfed}:keyfile`, keyfile, 'user')
741+
// cert/key may be used in conjunction with other credentials, thus no `else`
742+
}
736743
if (token) {
737744
this.set(`${nerfed}:_authToken`, token, 'user')
738745
this.delete(`${nerfed}:_password`, 'user')
@@ -750,7 +757,7 @@ class Config {
750757
// protects against shoulder-hacks if password is memorable, I guess?
751758
const encoded = Buffer.from(password, 'utf8').toString('base64')
752759
this.set(`${nerfed}:_password`, encoded, 'user')
753-
} else {
760+
} else if (!certfile || !keyfile) {
754761
throw new Error('No credentials to set.')
755762
}
756763
}
@@ -765,6 +772,14 @@ class Config {
765772
creds.email = email
766773
}
767774

775+
const certfileReg = this.get(`${nerfed}:certfile`)
776+
const keyfileReg = this.get(`${nerfed}:keyfile`)
777+
if (certfileReg && keyfileReg) {
778+
creds.certfile = certfileReg
779+
creds.keyfile = keyfileReg
780+
// cert/key may be used in conjunction with other credentials, thus no `return`
781+
}
782+
768783
const tokenReg = this.get(`${nerfed}:_authToken`) ||
769784
this.get(`${nerfed}:_authtoken`) ||
770785
this.get(`${nerfed}:-authtoken`) ||

tap-snapshots/test/index.js.test.cjs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,72 @@ exports[`test/index.js TAP credentials management nerfed_lcAuthToken > other reg
125125
Object {}
126126
`
127127

128+
exports[`test/index.js TAP credentials management nerfed_mtls > default registry 1`] = `
129+
Object {
130+
"certfile": "/path/to/cert",
131+
"keyfile": "/path/to/key",
132+
}
133+
`
134+
135+
exports[`test/index.js TAP credentials management nerfed_mtls > default registry after set 1`] = `
136+
Object {
137+
"certfile": "/path/to/cert",
138+
"keyfile": "/path/to/key",
139+
}
140+
`
141+
142+
exports[`test/index.js TAP credentials management nerfed_mtls > other registry 1`] = `
143+
Object {}
144+
`
145+
146+
exports[`test/index.js TAP credentials management nerfed_mtlsAuthToken > default registry 1`] = `
147+
Object {
148+
"certfile": "/path/to/cert",
149+
"keyfile": "/path/to/key",
150+
"token": "0bad1de4",
151+
}
152+
`
153+
154+
exports[`test/index.js TAP credentials management nerfed_mtlsAuthToken > default registry after set 1`] = `
155+
Object {
156+
"certfile": "/path/to/cert",
157+
"keyfile": "/path/to/key",
158+
"token": "0bad1de4",
159+
}
160+
`
161+
162+
exports[`test/index.js TAP credentials management nerfed_mtlsAuthToken > other registry 1`] = `
163+
Object {}
164+
`
165+
166+
exports[`test/index.js TAP credentials management nerfed_mtlsUserPass > default registry 1`] = `
167+
Object {
168+
"auth": "aGVsbG86d29ybGQ=",
169+
"certfile": "/path/to/cert",
170+
"email": "[email protected]",
171+
"keyfile": "/path/to/key",
172+
"password": "world",
173+
"username": "hello",
174+
}
175+
`
176+
177+
exports[`test/index.js TAP credentials management nerfed_mtlsUserPass > default registry after set 1`] = `
178+
Object {
179+
"auth": "aGVsbG86d29ybGQ=",
180+
"certfile": "/path/to/cert",
181+
"email": "[email protected]",
182+
"keyfile": "/path/to/key",
183+
"password": "world",
184+
"username": "hello",
185+
}
186+
`
187+
188+
exports[`test/index.js TAP credentials management nerfed_mtlsUserPass > other registry 1`] = `
189+
Object {
190+
"email": "[email protected]",
191+
}
192+
`
193+
128194
exports[`test/index.js TAP credentials management nerfed_userpass > default registry 1`] = `
129195
Object {
130196
"auth": "aGVsbG86d29ybGQ=",

test/index.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,20 @@ t.test('credentials management', async t => {
625625
nerfed_auth: { // note: does not load, because we don't do _auth per reg
626626
'.npmrc': `//registry.example/:_auth = ${Buffer.from('hello:world').toString('base64')}`,
627627
},
628+
nerfed_mtls: { '.npmrc': `//registry.example/:certfile = /path/to/cert
629+
//registry.example/:keyfile = /path/to/key`,
630+
},
631+
nerfed_mtlsAuthToken: { '.npmrc': `//registry.example/:_authToken = 0bad1de4
632+
//registry.example/:certfile = /path/to/cert
633+
//registry.example/:keyfile = /path/to/key`,
634+
},
635+
nerfed_mtlsUserPass: { '.npmrc': `//registry.example/:username = hello
636+
//registry.example/:_password = ${Buffer.from('world').toString('base64')}
637+
//registry.example/:email = [email protected]
638+
//registry.example/:always-auth = "false"
639+
//registry.example/:certfile = /path/to/cert
640+
//registry.example/:keyfile = /path/to/key`,
641+
},
628642
def_userpass: {
629643
'.npmrc': `username = hello
630644
_password = ${Buffer.from('world').toString('base64')}
@@ -712,14 +726,14 @@ always-auth = true`,
712726
}
713727

714728
// need both or none of user/pass
715-
if (!d.token && (!d.username || !d.password)) {
729+
if (!d.token && (!d.username || !d.password) && (!d.certfile || !d.keyfile)) {
716730
t.throws(() => c.setCredentialsByURI(defReg, d))
717731
} else {
718732
c.setCredentialsByURI(defReg, d)
719733
t.matchSnapshot(c.getCredentialsByURI(defReg), 'default registry after set')
720734
}
721735

722-
if (!o.token && (!o.username || !o.password)) {
736+
if (!o.token && (!o.username || !o.password) && (!o.certfile || !o.keyfile)) {
723737
t.throws(() => c.setCredentialsByURI(otherReg, o), {}, { otherReg, o })
724738
} else {
725739
c.setCredentialsByURI(otherReg, o)

0 commit comments

Comments
 (0)