11const fs = require ( 'fs-extra' )
22const path = require ( 'path' )
33
4+ const ini = require ( 'ini' )
45const minimist = require ( 'minimist' )
56const LRU = require ( 'lru-cache' )
67
@@ -154,6 +155,38 @@ class PackageManager {
154155 return this . _registry
155156 }
156157
158+ async getAuthToken ( ) {
159+ // get npmrc (https://docs.npmjs.com/configuring-npm/npmrc.html#files)
160+ const possibleRcPaths = [
161+ path . resolve ( this . context , '.npmrc' ) ,
162+ path . resolve ( require ( 'os' ) . homedir ( ) , '.npmrc' )
163+ ]
164+ if ( process . env . PREFIX ) {
165+ possibleRcPaths . push ( path . resolve ( process . env . PREFIX , '/etc/npmrc' ) )
166+ }
167+ // there's also a '/path/to/npm/npmrc', skipped for simplicity of implementation
168+
169+ let npmConfig = { }
170+ for ( const loc of possibleRcPaths ) {
171+ if ( fs . existsSync ( loc ) ) {
172+ try {
173+ // the closer config file (the one with lower index) takes higher precedence
174+ npmConfig = Object . assign ( { } , ini . parse ( fs . readFileSync ( loc , 'utf-8' ) ) , npmConfig )
175+ } catch ( e ) {
176+ // in case of file permission issues, etc.
177+ }
178+ }
179+ }
180+
181+ const registry = await this . getRegistry ( )
182+ const registryWithoutProtocol = registry
183+ . replace ( / h t t p s ? : / , '' ) // remove leading protocol
184+ . replace ( / ( [ ^ / ] ) $ / , '$1/' ) // ensure ending with slash
185+ const authTokenKey = `${ registryWithoutProtocol } :_authToken`
186+
187+ return npmConfig [ authTokenKey ]
188+ }
189+
157190 async setRegistryEnvs ( ) {
158191 const registry = await this . getRegistry ( )
159192
@@ -204,6 +237,7 @@ class PackageManager {
204237 // https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
205238 async getMetadata ( packageName , { full = false } = { } ) {
206239 const registry = await this . getRegistry ( )
240+ const authToken = await this . getAuthToken ( )
207241
208242 const metadataKey = `${ this . bin } -${ registry } -${ packageName } `
209243 let metadata = metadataCache . get ( metadataKey )
@@ -217,6 +251,10 @@ class PackageManager {
217251 headers . Accept = 'application/vnd.npm.install-v1+json'
218252 }
219253
254+ if ( authToken ) {
255+ headers . Authorization = `Bearer ${ authToken } `
256+ }
257+
220258 const url = `${ registry . replace ( / \/ $ / g, '' ) } /${ packageName } `
221259 try {
222260 metadata = ( await request . get ( url , { headers } ) ) . body
0 commit comments