1 var url = require('url')
2 var base64 = require('./base64')
4 var decodeBase64 = base64.decodeBase64
5 var encodeBase64 = base64.encodeBase64
7 var tokenKey = ':_authToken'
8 var userKey = ':username'
9 var passwordKey = ':_password'
11 module.exports = function () {
14 if (arguments.length >= 2) {
15 checkUrl = arguments[0]
16 options = arguments[1]
17 } else if (typeof arguments[0] === 'string') {
18 checkUrl = arguments[0]
20 options = arguments[0]
22 options = options || {}
23 options.npmrc = options.npmrc || require('rc')('npm', {registry: 'https://registry.npmjs.org/'})
24 checkUrl = checkUrl || options.npmrc.registry
25 return getRegistryAuthInfo(checkUrl, options) || getLegacyAuthInfo(options.npmrc)
28 function getRegistryAuthInfo (checkUrl, options) {
29 var parsed = url.parse(checkUrl, false, true)
32 while (pathname !== '/' && parsed.pathname !== pathname) {
33 pathname = parsed.pathname || '/'
35 var regUrl = '//' + parsed.host + pathname.replace(/\/$/, '')
36 var authInfo = getAuthInfoForUrl(regUrl, options.npmrc)
41 // break if not recursive
42 if (!options.recursive) {
43 return /\/$/.test(checkUrl)
45 : getRegistryAuthInfo(url.resolve(checkUrl, '.'), options)
48 parsed.pathname = url.resolve(normalizePath(pathname), '..') || '/'
54 function getLegacyAuthInfo (npmrc) {
59 var token = replaceEnvironmentVariable(npmrc._auth)
61 return {token: token, type: 'Basic'}
64 function normalizePath (path) {
65 return path[path.length - 1] === '/' ? path : path + '/'
68 function getAuthInfoForUrl (regUrl, npmrc) {
69 // try to get bearer token
70 var bearerAuth = getBearerToken(npmrc[regUrl + tokenKey] || npmrc[regUrl + '/' + tokenKey])
75 // try to get basic token
76 var username = npmrc[regUrl + userKey] || npmrc[regUrl + '/' + userKey]
77 var password = npmrc[regUrl + passwordKey] || npmrc[regUrl + '/' + passwordKey]
78 var basicAuth = getTokenForUsernameAndPassword(username, password)
86 function replaceEnvironmentVariable (token) {
87 return token.replace(/^\$\{?([^}]*)\}?$/, function (fullMatch, envVar) {
88 return process.env[envVar]
92 function getBearerToken (tok) {
97 // check if bearer token is set as environment variable
98 var token = replaceEnvironmentVariable(tok)
100 return {token: token, type: 'Bearer'}
103 function getTokenForUsernameAndPassword (username, password) {
104 if (!username || !password) {
108 // passwords are base64 encoded, so we need to decode it
109 // See https://github.com/npm/npm/blob/v3.10.6/lib/config/set-credentials-by-uri.js#L26
110 var pass = decodeBase64(replaceEnvironmentVariable(password))
112 // a basic auth token is base64 encoded 'username:password'
113 // See https://github.com/npm/npm/blob/v3.10.6/lib/config/get-credentials-by-uri.js#L70
114 var token = encodeBase64(username + ':' + pass)
116 // we found a basicToken token so let's exit the loop