index.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. var url = require('url')
  2. var base64 = require('./base64')
  3. var decodeBase64 = base64.decodeBase64
  4. var encodeBase64 = base64.encodeBase64
  5. var tokenKey = ':_authToken'
  6. var userKey = ':username'
  7. var passwordKey = ':_password'
  8. module.exports = function getRegistryAuthInfo(registryUrl, opts) {
  9. var options = opts || {}
  10. var npmrc = require('rc')('npm', {registry: 'https://registry.npmjs.org/'})
  11. var parsed = url.parse(registryUrl || npmrc.registry, false, true)
  12. var pathname
  13. while (pathname !== '/') {
  14. pathname = parsed.pathname || '/'
  15. var regUrl = '//' + parsed.host + pathname.replace(/\/$/, '')
  16. var authInfo = getAuthInfoForUrl(regUrl, npmrc)
  17. if (authInfo) {
  18. return authInfo
  19. }
  20. // break if not recursive
  21. if (!options.recursive) {
  22. return undefined
  23. }
  24. parsed.pathname = url.resolve(normalizePath(pathname), '..') || '/'
  25. }
  26. return undefined
  27. }
  28. function normalizePath(path) {
  29. return path[path.length - 1] === '/' ? path : path + '/'
  30. }
  31. function getAuthInfoForUrl(regUrl, npmrc) {
  32. // try to get bearer token
  33. var bearerAuth = getBearerToken(npmrc[regUrl + tokenKey] || npmrc[regUrl + '/' + tokenKey])
  34. if (bearerAuth) {
  35. return bearerAuth
  36. }
  37. // try to get basic token
  38. var username = npmrc[regUrl + userKey] || npmrc[regUrl + '/' + userKey]
  39. var password = npmrc[regUrl + passwordKey] || npmrc[regUrl + '/' + passwordKey]
  40. var basicAuth = getTokenForUsernameAndPassword(username, password)
  41. if (basicAuth) {
  42. return basicAuth
  43. }
  44. return undefined
  45. }
  46. function getBearerToken(tok) {
  47. if (!tok) {
  48. return undefined
  49. }
  50. // check if bearer token
  51. var token = tok.replace(/^\$\{?([^}]*)\}?$/, function (fullMatch, envVar) {
  52. return process.env[envVar]
  53. })
  54. return {token: token, type: 'Bearer'}
  55. }
  56. function getTokenForUsernameAndPassword(username, password) {
  57. if (!username || !password) {
  58. return undefined
  59. }
  60. // passwords are base64 encoded, so we need to decode it
  61. // See https://github.com/npm/npm/blob/v3.10.6/lib/config/set-credentials-by-uri.js#L26
  62. var pass = decodeBase64(password)
  63. // a basic auth token is base64 encoded 'username:password'
  64. // See https://github.com/npm/npm/blob/v3.10.6/lib/config/get-credentials-by-uri.js#L70
  65. var token = encodeBase64(username + ':' + pass)
  66. // we found a basicToken token so let's exit the loop
  67. return {
  68. token: token,
  69. type: 'Basic',
  70. password: pass,
  71. username: username
  72. }
  73. }