1
1
'use strict'
2
+ const fs = require ( 'fs' )
2
3
const npa = require ( 'npm-package-arg' )
3
4
const { URL } = require ( 'url' )
4
5
@@ -7,7 +8,8 @@ const { URL } = require('url')
7
8
const regKeyFromURI = ( uri , opts ) => {
8
9
const parsed = new URL ( uri )
9
10
// try to find a config key indicating we have auth for this registry
10
- // can be one of :_authToken, :_auth, or :_password and :username
11
+ // can be one of :_authToken, :_auth, :_password and :username, or
12
+ // :certfile and :keyfile
11
13
// We walk up the "path" until we're left with just //<host>[:<port>],
12
14
// stopping when we reach '//'.
13
15
let regKey = `//${ parsed . host } ${ parsed . pathname } `
@@ -26,7 +28,8 @@ const regKeyFromURI = (uri, opts) => {
26
28
const hasAuth = ( regKey , opts ) => (
27
29
opts [ `${ regKey } :_authToken` ] ||
28
30
opts [ `${ regKey } :_auth` ] ||
29
- opts [ `${ regKey } :username` ] && opts [ `${ regKey } :_password` ]
31
+ opts [ `${ regKey } :username` ] && opts [ `${ regKey } :_password` ] ||
32
+ opts [ `${ regKey } :certfile` ] && opts [ `${ regKey } :keyfile` ]
30
33
)
31
34
32
35
const sameHost = ( a , b ) => {
@@ -44,6 +47,17 @@ const getRegistry = opts => {
44
47
return scopeReg || opts . registry
45
48
}
46
49
50
+ const maybeReadFile = file => {
51
+ try {
52
+ return fs . readFileSync ( file , 'utf8' )
53
+ } catch ( er ) {
54
+ if ( er . code !== 'ENOENT' ) {
55
+ throw er
56
+ }
57
+ return null
58
+ }
59
+ }
60
+
47
61
const getAuth = ( uri , opts = { } ) => {
48
62
const { forceAuth } = opts
49
63
if ( ! uri ) {
@@ -59,6 +73,8 @@ const getAuth = (uri, opts = {}) => {
59
73
username : forceAuth . username ,
60
74
password : forceAuth . _password || forceAuth . password ,
61
75
auth : forceAuth . _auth || forceAuth . auth ,
76
+ certfile : forceAuth . certfile ,
77
+ keyfile : forceAuth . keyfile ,
62
78
} )
63
79
}
64
80
@@ -82,6 +98,8 @@ const getAuth = (uri, opts = {}) => {
82
98
[ `${ regKey } :username` ] : username ,
83
99
[ `${ regKey } :_password` ] : password ,
84
100
[ `${ regKey } :_auth` ] : auth ,
101
+ [ `${ regKey } :certfile` ] : certfile ,
102
+ [ `${ regKey } :keyfile` ] : keyfile ,
85
103
} = opts
86
104
87
105
return new Auth ( {
@@ -90,15 +108,19 @@ const getAuth = (uri, opts = {}) => {
90
108
auth,
91
109
username,
92
110
password,
111
+ certfile,
112
+ keyfile,
93
113
} )
94
114
}
95
115
96
116
class Auth {
97
- constructor ( { token, auth, username, password, scopeAuthKey } ) {
117
+ constructor ( { token, auth, username, password, scopeAuthKey, certfile , keyfile } ) {
98
118
this . scopeAuthKey = scopeAuthKey
99
119
this . token = null
100
120
this . auth = null
101
121
this . isBasicAuth = false
122
+ this . cert = null
123
+ this . key = null
102
124
if ( token ) {
103
125
this . token = token
104
126
} else if ( auth ) {
@@ -108,6 +130,15 @@ class Auth {
108
130
this . auth = Buffer . from ( `${ username } :${ p } ` , 'utf8' ) . toString ( 'base64' )
109
131
this . isBasicAuth = true
110
132
}
133
+ // mTLS may be used in conjunction with another auth method above
134
+ if ( certfile && keyfile ) {
135
+ const cert = maybeReadFile ( certfile , 'utf-8' )
136
+ const key = maybeReadFile ( keyfile , 'utf-8' )
137
+ if ( cert && key ) {
138
+ this . cert = cert
139
+ this . key = key
140
+ }
141
+ }
111
142
}
112
143
}
113
144
0 commit comments