Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] v 7.3.0 when publishing to private rep You need to authorize this machine using 'npm adduser' #2453

Closed
sysmat opened this issue Jan 7, 2021 · 62 comments · Fixed by #2445
Labels
Bug thing that needs fixing Priority 1 high priority issue Release 7.x work is associated with a specific npm 7 release

Comments

@sysmat
Copy link

sysmat commented Jan 7, 2021

Current Behavior:

Can not publish(This command requires you to be logged in) but I adduser successfully

Expected Behavior:

  • it work with npm v 6

Steps To Reproduce:

registry=https://zelenjak.arnes.si/nexus/repository/ArnesGroupNPM/
//zelenjak.arnes.si/nexus/repository/ArnesNpm/:_authToken=NpmToken.XXXXXXXXX
  • in my package I have:
,
  "publishConfig": {
    "registry": "https://zelenjak.arnes.si/nexus/repository/ArnesNpm/"
  },
  • when running npm publish I got error:
npm ERR! code ENEEDAUTH
npm ERR! need auth This command requires you to be logged in.
npm ERR! need auth You need to authorize this machine using `npm adduser`

Environments:

  • Node: 12.6.0
  • npm: 7.3.0
  • OS: win32 x64
@sysmat sysmat added Bug thing that needs fixing Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release labels Jan 7, 2021
@ljharb
Copy link
Contributor

ljharb commented Jan 7, 2021

ArnesGroupNpm and ArnesNpm are different registries.

@sysmat
Copy link
Author

sysmat commented Jan 8, 2021

This is nexus:

  • ArnesGroupNpm is group repo(combining public and private) and it is for download
  • ArnesNpm is private hosted repo and used for upload
  • it works with npm 6
  • publishConfig has ArnesNpm and _authToken in .npmrc is for ArnesNpm

@ljharb
Copy link
Contributor

ljharb commented Jan 8, 2021

Ah, true - the publishConfig's registry is the one that's authed in npmrc.

@foxxyz
Copy link
Contributor

foxxyz commented Jan 10, 2021

Likely related to #2411. Try npm publish --registry <registry_url> as a workaround.

Fix underway in #2445.

@manuelottlik
Copy link

I am publishing my npm packages to my private npm registry via GitHub Actions and had the same issue.

Am I correct that this currently effects everyone that uses npm publish in CI to a private registry?

@foxxyz
Copy link
Contributor

foxxyz commented Jan 13, 2021

I am publishing my npm packages to my private npm registry via GitHub Actions and had the same issue.

Am I correct that this currently effects everyone that uses npm publish in CI to a private registry?

That's been my findings so far. I hope the CLI team fixes this quickly.

@wraithgar wraithgar added Priority 2 secondary priority issue and removed Needs Triage needs review for next steps labels Jan 21, 2021
@darcyclarke darcyclarke added this to the OSS - Sprint 23 milestone Jan 25, 2021
@mswaagman-godaddy
Copy link

#2445 did not fix it afaik. publishConfig seems to be ignored when publishing a package. Double checked if 7.5.3 would fix it, but does not appear to be the case.

@medianick
Copy link

Until a short while ago, I was seeing this very same issue with npm 7.5.1 when publishing to a private MyGet feed from our Jenkins system; despite a valid token in the .npmrc file it was still showing the ENEEDAUTH error and saying I needed to log in. @foxxyz's workaround of specifying the registry explicitly in the npm publish command resolved the problem. So, at least as of 7.5.1 the underlying issue has not been solved, and it sounds like 7.5.3 does not do so either, but at least our publishing can function again.

@linkej-autodesk
Copy link

We have the same problem with 7.5.4. using --registry did not fix it, unfortunately. I guess we'll stay at 6.x for now...

@grahaml
Copy link

grahaml commented Feb 24, 2021

FWIW using --registry as @medianick and @foxxyz mentioned has worked for me using GitLab's package registry. Just in case anyone else stumbles upon this thread and hasn't tried it yet.

# .npmrc
@myscope:registry=https://gitlab.mycompany.com/api/v4/packages/npm/
//gitlab.mycompany.com/api/v4/packages/npm/:_authToken=<valid_access_token>
$ npm publish --regsitry=https://gitlab.mycompany.com/api/v4/packages/npm/

@avezina-ubik
Copy link

We have the same problem with 7.5.4. using --registry did not fix it, unfortunately. I guess we'll stay at 6.x for now...

Same here using 7.6.0 and gitlab.com as private registry.

It seems that the publish command does not support a --registry argument though: https://docs.npmjs.com/cli/v7/commands/npm-publish

@foxxyz
Copy link
Contributor

foxxyz commented Mar 1, 2021

It seems that the publish command does not support a --registry argument though: https://docs.npmjs.com/cli/v7/commands/npm-publish

I'd argue this should be documented better, but I believe the --registry argument is a global one that can be used on any npm command, as detailed in the last paragraph under "Description" on the "registry" page.

@avezina-ubik
Copy link

It seems that the publish command does not support a --registry argument though: https://docs.npmjs.com/cli/v7/commands/npm-publish

I'd argue this should be documented better, but I believe the --registry argument is a global one that can be used on any npm command, as detailed in the last paragraph under "Description" on the "registry" page.

It's a bit hard to understand indeed, but let's not start a debate about documentation.

I managed to get it published using npm 6.14.4 and the --registry flag.

@lolopinto
Copy link

when is this being fixed? I upgraded my npm from 6.* to 7.* and I'm running into this.

i'm trying to publish into a private github package. The suggestion to use --registry isn't working for me because I'm trying to publish a dist subfolder and apparently that combo together doesn't work.

@beltekylevi
Copy link

beltekylevi commented Jan 5, 2022

tested with node@14.16.1, npm@8.3.0, and GitHub Packages

set publish registry in package.json
(I think this is replaceable with npm publish --registry=https://npm.pkg.github.com/)

"publishConfig": {
  "registry": "https://npm.pkg.github.com/"
}

.npmrc content

//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
always-auth=true

The NODE_AUTH_TOKEN environment variable must be set to a GitHub PAT with write:packages scope.

@dgr-m
Copy link

dgr-m commented Jan 12, 2022

I checked the source code behind the npm publish command and it turns out that the only possible way to prevent this is to explicitly pass any credentials through the command line as arguments.

if (!dryRun) {
  const resolved = npa.resolve(manifest.name, manifest.version)
  const registry = npmFetch.pickRegistry(resolved, opts)
  const creds = this.npm.config.getCredentialsByURI(registry)
  if (!creds.token && !creds.username) {
    throw Object.assign(new Error('This command requires you to be logged in.'), {
      code: 'ENEEDAUTH',
    })
  }
  await otplease(opts, opts => libpub(manifest, tarballData, opts))
}

The problem is in this line:

const creds = this.npm.config.getCredentialsByURI(registry)

It checks the config for certain credential properties (eg. _authToken), but only the config from the cli.
Defaults, user .npmrc, project .npmrc, etc are all ignored.

getCredentialsByURI (uri) {
  const nerfed = nerfDart(uri)
  const creds = {}

  const email = this.get(`${nerfed}:email`) || this.get('email')
  if (email)
    creds.email = email

  const tokenReg = this.get(`${nerfed}:_authToken`) ||
    this.get(`${nerfed}:_authtoken`) ||
    this.get(`${nerfed}:-authtoken`) ||
    nerfed === nerfDart(this.get('registry')) && this.get('_authToken')
  
  ...
}

get (key, where) {
  if (!this.loaded)
    throw new Error('call config.load() before reading values')
  return this[_get](key, where)
}
// we need to get values sometimes, so use this internal one to do so
// while in the process of loading.
[_get] (key, where = null) {
  if (where !== null && !confTypes.has(where)) {
    throw new Error('invalid config location param: ' + where)
  }
  const { data, source } = this.data.get(where || 'cli')
  return where === null || hasOwnProperty(data, key) ? data[key] : undefined
}

Notice data is retrieved using the where arg (one of default builtin global user project env cli) which defaults to cli when none is provided (which is the case for getCredentialsByURI)

@sharkymcdongles
Copy link

I checked the source code behind the npm publish command and it turns out that the only possible way to prevent this is to explicitly pass any credentials through the command line as arguments.

if (!dryRun) {
  const resolved = npa.resolve(manifest.name, manifest.version)
  const registry = npmFetch.pickRegistry(resolved, opts)
  const creds = this.npm.config.getCredentialsByURI(registry)
  if (!creds.token && !creds.username) {
    throw Object.assign(new Error('This command requires you to be logged in.'), {
      code: 'ENEEDAUTH',
    })
  }
  await otplease(opts, opts => libpub(manifest, tarballData, opts))
}

The problem is in this line:

const creds = this.npm.config.getCredentialsByURI(registry)

It checks the config for certain credential properties (eg. _authToken), but only the config from the cli. Defaults, user .npmrc, project .npmrc, etc are all ignored.

getCredentialsByURI (uri) {
  const nerfed = nerfDart(uri)
  const creds = {}

  const email = this.get(`${nerfed}:email`) || this.get('email')
  if (email)
    creds.email = email

  const tokenReg = this.get(`${nerfed}:_authToken`) ||
    this.get(`${nerfed}:_authtoken`) ||
    this.get(`${nerfed}:-authtoken`) ||
    nerfed === nerfDart(this.get('registry')) && this.get('_authToken')
  
  ...
}

get (key, where) {
  if (!this.loaded)
    throw new Error('call config.load() before reading values')
  return this[_get](key, where)
}
// we need to get values sometimes, so use this internal one to do so
// while in the process of loading.
[_get] (key, where = null) {
  if (where !== null && !confTypes.has(where)) {
    throw new Error('invalid config location param: ' + where)
  }
  const { data, source } = this.data.get(where || 'cli')
  return where === null || hasOwnProperty(data, key) ? data[key] : undefined
}

Notice data is retrieved using the where arg (one of default builtin global user project env cli) which defaults to cli when none is provided (which is the case for getCredentialsByURI)

Can you give an example of what the npm publish command would look like when passing auth as arguments? I don't see this documented anywhere at all.

@darcyclarke darcyclarke added Priority 1 high priority issue and removed Priority 2 secondary priority issue labels Jan 17, 2022
@coroiu
Copy link

coroiu commented Jan 27, 2022

I had this issue on Gitlab with node 16.4.2 and npm 7.18.1 and solved it by pointing to the .npmrc using npm publish --userconfig [.npmrc path]. No need to point out the registry directly

@radoslawgrochowski
Copy link

@coroiu Could you share your .npmrc?

@NiklasPor
Copy link

This one is also stopping us from publishing with Node 16. We just switched to a Node 14 image for our publish pipeline step.

@jonathaff
Copy link

jonathaff commented Feb 7, 2022

@radoslawgrochowski I followed @coroiu tip and it works for me, nexus 3.37, gitlab 14.6, node 16.13 and npm 8.1. Here is my setup:

~/.npmrc content, created after read this thread https://clavinjune.dev/en/blogs/npm-login-not-working/

registry=https://nexus.my.repo/repository/npm-all-releases
//nexus.my.repo/repository/internal-npm-releases/:_auth={{ base64 of username:password redacted here }}

Publish command
npm publish --userconfig=~/.npmrc --registry=https://nexus.my.repo/repository/internal-npm-releases/

@moha-akb
Copy link

moha-akb commented Feb 8, 2022

Same problem for me.
Tried most of solutions, and finally this worked for me:

(Not logged in globaly)
./.npmrc

registry="https://npm.pkg.github.com/"
//npm.pkg.github.com/:_authToken=YOUR_AUTH_TOKEN
save-exact=true

run command:
npm publish --regsitry=https://npm.pkg.github.com/ --userconfig=./.npmrc

Note: for the most of the failed tries, registry=... was missing in .npmrc

@ghost
Copy link

ghost commented Feb 21, 2022

This is still an issue with node v16.14.0 and npm v8.3.1. Worked fine with node 14.x and npm 5.x.

@ljharb
Copy link
Contributor

ljharb commented Feb 21, 2022

@budgecode what about npm v8.5.1?

@radoslawgrochowski
Copy link

@radoslawgrochowski I followed @coroiu tip and it works for me, nexus 3.37, gitlab 14.6, node 16.13 and npm 8.1. Here is my setup:

~/.npmrc content, created after read this thread https://clavinjune.dev/en/blogs/npm-login-not-working/

registry=https://nexus.my.repo/repository/npm-all-releases
//nexus.my.repo/repository/internal-npm-releases/:_auth={{ base64 of username:password redacted here }}

Publish command npm publish --userconfig=~/.npmrc --registry=https://nexus.my.repo/repository/internal-npm-releases/

Thanks, first solution that works for me :)

@wickkidd
Copy link

+1 on it working when using registry and userconfig cli args. Like others, I didn't have to change my .npmrc from the format I used prior to npm v8. That said, the only thing I actually had to change was to pass the the userconfig arg.

@wraithgar
Copy link
Member

It does look like this was due to configuration changes in npm7/8. publishConfig is being properly applied during publishes, and registry and scope-specific configs are working as expected in the latest npm.

If folks are still experiencing issues publishing to private registries, please open individual tickets so that we can triage and debug your specific config setup.

@pfeileon
Copy link

I checked the source code behind the npm publish command and it turns out that the only possible way to prevent this is to explicitly pass any credentials through the command line as arguments.

if (!dryRun) {
  const resolved = npa.resolve(manifest.name, manifest.version)
  const registry = npmFetch.pickRegistry(resolved, opts)
  const creds = this.npm.config.getCredentialsByURI(registry)
  if (!creds.token && !creds.username) {
    throw Object.assign(new Error('This command requires you to be logged in.'), {
      code: 'ENEEDAUTH',
    })
  }
  await otplease(opts, opts => libpub(manifest, tarballData, opts))
}

The problem is in this line:

const creds = this.npm.config.getCredentialsByURI(registry)

It checks the config for certain credential properties (eg. _authToken), but only the config from the cli. Defaults, user .npmrc, project .npmrc, etc are all ignored.

getCredentialsByURI (uri) {
  const nerfed = nerfDart(uri)
  const creds = {}

  const email = this.get(`${nerfed}:email`) || this.get('email')
  if (email)
    creds.email = email

  const tokenReg = this.get(`${nerfed}:_authToken`) ||
    this.get(`${nerfed}:_authtoken`) ||
    this.get(`${nerfed}:-authtoken`) ||
    nerfed === nerfDart(this.get('registry')) && this.get('_authToken')
  
  ...
}

get (key, where) {
  if (!this.loaded)
    throw new Error('call config.load() before reading values')
  return this[_get](key, where)
}
// we need to get values sometimes, so use this internal one to do so
// while in the process of loading.
[_get] (key, where = null) {
  if (where !== null && !confTypes.has(where)) {
    throw new Error('invalid config location param: ' + where)
  }
  const { data, source } = this.data.get(where || 'cli')
  return where === null || hasOwnProperty(data, key) ? data[key] : undefined
}

Notice data is retrieved using the where arg (one of default builtin global user project env cli) which defaults to cli when none is provided (which is the case for getCredentialsByURI)

@wraithgar So this is now called a configuration change?

Sounds like manager talk to me: After more than a year people have found workarounds or learned to live with version 6 anyway, just close the issue and let them file an issue for their "individual" problem, which most won't do or only do after another few months. 👎

@wraithgar
Copy link
Member

I'm sorry that you feel this way, but the issue here originally was that publishConfig was not being properly applied during publish. That has been fixed. It is very likely you either have a separate issue or a config mismatch. The new issue template is designed to help us triage and debug these things. Comments in a closed issue are generally not a good place for that.

As for the config, the data objects are cumulative. The internal [_get] only limits to the where if it was requested. Otherwise it returns the value

return where === null || hasOwnProperty(data, key) ? data[key] : undefined

config.get('sign-git-tag') will return the config value as it was derived and set through all of the various config locations. config.get('sign-git-tag', 'cli') will return the config value as it was set on cli parameters. If you don't give a where, it pulls from the internal cli data object, which includes the total data of the config. The internal data has all of the config items in it as non-enumerable properties. This is how the config works under the hood. That's how you can see things like this if you look at it in a repl

> config.data.get('cli').data
Object <Object <Object <Object <Complex prototype>>>> {}
> Object.hasOwnProperty(config.data.get('cli'), 'sign-git-tag')
false
> config.data.get('cli').data['sign-git-tag']
true

This is not an attempt at ignoring the issue. If there is a bug we really do want to fix it. Please do open new issues and fill out the information requested so we can properly triage it.

@pfeileon
Copy link

So what you're saying is that @sysmat 's issue is resolved?
Because from my understanding authentication still doesn't work without changing the CLI command which might be out of reach if you use semantic-release or similar.

@wraithgar
Copy link
Member

Yes their issue is resolved. publishConfig with a nerfed _authToken works and has tests. The other issue appears to be with scoped registries and the old _auth token which has another open issue that is being worked on now #3573

This is why it's so important to have separate issues for things. I know that on the surface these all feel like the same issue but they're not, and mixing them up in the comments slows down the debugging and triage process.

We really are doing our best to fix issues, and the things we're asking for are in the interest of getting bugs fixed, I promise. Thank you for your attention to these issues and please continue to try to debug, and open issues if there are new bugs.

@asotog
Copy link

asotog commented Jun 2, 2022

Hi all,

I'm still experiencing this issue when running npm publish:

npm notice 
npm ERR! code ENEEDAUTH
npm ERR! need auth This command requires you to be logged in to MY_PRIVATE_NEXUS_REGISTRY_URL
npm ERR! need auth You need to authorize this machine using `npm adduser`

npm ERR! A complete log of this run can be found in:

node -v
v16.14.1
npm -v
8.5.0

I spent whole afternoon until I go to a lower version, in my case I tried node 12, node v12.22.9 (npm v6.14.15), and it worked again

@asotog
Copy link

asotog commented Jun 2, 2022

Just found this command:

 npm adduser --registry=REGISTRY_URL

and use the right user, then was complaining about other information related to nexus which this helped me https://blog.katastros.com/a?ID=01750-614d5a39-d787-4987-89bb-0b2f03210e1f

@matthias-ccri
Copy link

Coming here from npm 8.15.1 using beachball. It turns out there was a discrepancy between the configurations --- a trailing slash. This discrepancy only produced an error starting in npm 7.3.0. In 7.2.0 and before, npm worked.

In beachball.config.js the registry lacked a trailing slash, but in the CI job's npm config registry command, there was a trailing slash. As a result beachball issued a command without the trailing slash (the command is visible in the job output), and npm threw a ENEEDAUTH.

Note: the ENEEDAUTH is not from the server; it's from npm itself, when npm thinks it needs auth info, but can't find it.

@adjenks
Copy link

adjenks commented Aug 10, 2022

Just found this command:

 npm adduser --registry=REGISTRY_URL

and use the right user, then was complaining about other information related to nexus which this helped me https://blog.katastros.com/a?ID=01750-614d5a39-d787-4987-89bb-0b2f03210e1f

I was using nexus and your link saved me. This is what got me:

If you still can’t send after logging in, check the Realms setting of npm nexus, put npm Bearer Token Reaim into Active, and save

I couldn't imagine that nexus would not have that on by default so I never thought to check.

@l3ender
Copy link

l3ender commented Dec 28, 2022

Though not directly related to the adduser issue, I stumbled on this post facing npm publish issues after updating to node 16 (npm 8.19.3). I'm posting here as it may help someone else.

We build our library and then publish as follows:

-> npm publish dist/my-library

npm ERR! code 128
npm ERR! An unknown git error occurred
npm ERR! command git --no-replace-objects ls-remote ssh://git@github.com/dist/my-library.git
npm ERR! ERROR: Repository not found.
npm ERR! fatal: Could not read from remote repository.
npm ERR!
npm ERR! Please make sure you have the correct access rights
npm ERR! and the repository exists.

After updating to node 16, it appears the trailing slash on the path is required. Without it, npm tries to use an SSH URL, as observed in the failed output.

The solution was to use the path with a trailing slash:

npm publish dist/my-library/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Priority 1 high priority issue Release 7.x work is associated with a specific npm 7 release
Projects
None yet
Development

Successfully merging a pull request may close this issue.